Skip to content

Commit e6f75ca

Browse files
authored
fix: simplify outputDirParam handling (#483)
1 parent a6b3005 commit e6f75ca

File tree

11 files changed

+94
-33
lines changed

11 files changed

+94
-33
lines changed

packages/amplify-codegen-e2e-tests/src/__tests__/datastore-modelgen-android.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createNewProjectDir, DEFAULT_ANDROID_CONFIG } from '@aws-amplify/amplify-codegen-e2e-core';
22
import { deleteAmplifyProject, testCodegenModels } from '../codegen-tests-base';
3+
import * as path from 'path';
34

45
const schema = 'modelgen/model_gen_schema_with_aws_scalars.graphql';
56

@@ -19,6 +20,6 @@ describe('Datastore Modelgen tests - Android', () => {
1920
});
2021

2122
it('Should generate files at overridden output path', async () => {
22-
await testCodegenModels(DEFAULT_ANDROID_CONFIG, projectRoot, schema, 'app/src/main/guava');
23+
await testCodegenModels(DEFAULT_ANDROID_CONFIG, projectRoot, schema, path.join('app', 'src', 'main', 'guava'));
2324
});
2425
});

packages/amplify-codegen-e2e-tests/src/__tests__/datastore-modelgen-flutter.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createNewProjectDir, DEFAULT_FLUTTER_CONFIG } from '@aws-amplify/amplify-codegen-e2e-core';
22
import { deleteAmplifyProject, testCodegenModels } from '../codegen-tests-base';
3+
import * as path from 'path';
34

45
const schema = 'modelgen/model_gen_schema_with_aws_scalars.graphql';
56

@@ -19,6 +20,6 @@ describe('Datastore Modelgen tests - Flutter', () => {
1920
});
2021

2122
it(`should generate files at overridden location`, async () => {
22-
await testCodegenModels(DEFAULT_FLUTTER_CONFIG, projectRoot, schema, 'lib/blueprints');
23+
await testCodegenModels(DEFAULT_FLUTTER_CONFIG, projectRoot, schema, path.join('lib', 'blueprints'));
2324
});
2425
});

packages/amplify-codegen-e2e-tests/src/__tests__/datastore-modelgen-ios.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createNewProjectDir, DEFAULT_IOS_CONFIG } from '@aws-amplify/amplify-codegen-e2e-core';
22
import { deleteAmplifyProject, testCodegenModels } from '../codegen-tests-base';
3+
import * as path from 'path';
34

45
const schema = 'modelgen/model_gen_schema_with_aws_scalars.graphql';
56

@@ -19,6 +20,6 @@ describe('Datastore Modelgen tests - iOS', () => {
1920
});
2021

2122
it(`should generate files at overridden location`, async () => {
22-
await testCodegenModels(DEFAULT_IOS_CONFIG, projectRoot, schema, 'amplification/manufactured/models');
23+
await testCodegenModels(DEFAULT_IOS_CONFIG, projectRoot, schema, path.join('amplification', 'manufactured', 'models'));
2324
});
2425
});

packages/amplify-codegen-e2e-tests/src/__tests__/datastore-modelgen-js.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createNewProjectDir, DEFAULT_JS_CONFIG } from '@aws-amplify/amplify-codegen-e2e-core';
22
import { deleteAmplifyProject, testCodegenModels } from '../codegen-tests-base';
3+
import * as path from 'path';
34

45
const schema = 'modelgen/model_gen_schema_with_aws_scalars.graphql';
56

@@ -19,6 +20,6 @@ describe('Datastore Modelgen tests - JS', () => {
1920
});
2021

2122
it(`should generate files at desired location and not delete src files`, async () => {
22-
await testCodegenModels(DEFAULT_JS_CONFIG, projectRoot, schema, 'src/backmodels');
23+
await testCodegenModels(DEFAULT_JS_CONFIG, projectRoot, schema, path.join('src', 'backmodels'));
2324
});
2425
});

packages/amplify-codegen-e2e-tests/src/codegen-tests-base/datastore-modelgen.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@ export async function testCodegenModels(config: AmplifyFrontendConfig, projectRo
2929
// pre-existing file should still exist
3030
expect(existsSync(userSourceCodePath)).toBe(true);
3131
// datastore models are generated at correct location
32-
expect(isNotEmptyDir(outputDir ? outputDir : path.join(projectRoot, config.modelgenDir))).toBe(true);
32+
const dirToCheck = outputDir
33+
? path.join(projectRoot, outputDir)
34+
: path.join(projectRoot, config.modelgenDir);
35+
expect(isNotEmptyDir(dirToCheck)).toBe(true);
3336
}

packages/amplify-codegen/commands/codegen/models.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
const codeGen = require('../../src');
22
const { exitOnNextTick } = require('amplify-cli-core');
3+
const getOutputDirParam = require('../../src/utils/getOutputDirParam');
4+
35
const featureName = 'models';
46

57
module.exports = {
68
name: featureName,
79
run: async context => {
810
try {
9-
await codeGen.generateModels(context);
11+
await codeGen.generateModels(context, getOutputDirParam(context, false));
1012
} catch (ex) {
1113
context.print.info(ex.message);
1214
console.log(ex.stack);
Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
const generateModels = require('./models');
2-
const path = require('path');
2+
const getOutputDirParam = require('../utils/getOutputDirParam');
33

44
async function generateModelIntrospection(context) {
5-
// Verify override path flag is provided
6-
const outputDirParam = context.parameters?.options?.['output-dir'];
7-
if ( !outputDirParam || typeof(outputDirParam) !== 'string' ) {
8-
throw new Error('Expected --output-dir flag with value to be set for model introspection command.');
9-
}
10-
const outputDirPath = path.isAbsolute(outputDirParam) ? outputDirParam : path.join(context.amplify.getEnvInfo().projectPath, outputDirParam);
11-
await generateModels(context, outputDirPath, true);
5+
await generateModels(context, getOutputDirParam(context, true), true);
126
}
137

148
module.exports = generateModelIntrospection;

packages/amplify-codegen/src/commands/models.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const readNumericFeatureFlag = key => {
4444
}
4545
};
4646

47-
async function generateModels(context, outputDirPath = null, isIntrospection = false) {
47+
async function generateModels(context, overrideOutputDir = null, isIntrospection = false) {
4848
// steps:
4949
// 1. Load the schema and validate using transformer
5050
// 2. get all the directives supported by transformer
@@ -77,11 +77,7 @@ async function generateModels(context, outputDirPath = null, isIntrospection = f
7777

7878
const schemaContent = loadSchema(apiResourcePath);
7979

80-
const outputDirParam = context.parameters?.options?.['output-dir'];
81-
if ( !outputDirPath && outputDirParam && typeof(outputDirParam) !== 'string' ) {
82-
throw new Error('Expected provided --output-dir flag to be given output location as input.');
83-
}
84-
const outputPath = outputDirPath ?? outputDirParam ?? path.join(projectRoot, getModelOutputPath(context));
80+
const baseOutputDir = path.join(projectRoot, getModelOutputPath(context))
8581
const schema = parse(schemaContent);
8682
const projectConfig = context.amplify.getProjectConfig();
8783

@@ -118,7 +114,7 @@ async function generateModels(context, outputDirPath = null, isIntrospection = f
118114

119115
const handleListNullabilityTransparently = readFeatureFlag('codegen.handleListNullabilityTransparently');
120116
const appsyncLocalConfig = await appSyncDataStoreCodeGen.preset.buildGeneratesSection({
121-
baseOutputDir: outputPath,
117+
baseOutputDir,
122118
schema,
123119
config: {
124120
target: isIntrospection ? 'introspection' : (platformToLanguageMap[projectConfig.frontend] || projectConfig.frontend),
@@ -133,6 +129,7 @@ async function generateModels(context, outputDirPath = null, isIntrospection = f
133129
transformerVersion,
134130
dartUpdateAmplifyCoreDependency,
135131
respectPrimaryKeyAttributesOnConnectionField,
132+
overrideOutputDir, // This needs to live under `config` in order for the GraphQL types to work out.
136133
},
137134
});
138135

@@ -160,7 +157,7 @@ async function generateModels(context, outputDirPath = null, isIntrospection = f
160157

161158
generateEslintIgnore(context);
162159

163-
context.print.info(`Successfully generated models. Generated models can be found in ${outputPath}`);
160+
context.print.info(`Successfully generated models. Generated models can be found in ${overrideOutputDir ?? baseOutputDir}`);
164161
}
165162

166163
async function validateSchema(context) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const path = require('path');
2+
3+
/**
4+
* Retrieve the output directory parameter from the command line. Throws on invalid value,
5+
* or if isRequired is set and the flag isn't in the options. Returns null on optional and not defined.
6+
* @param context the CLI invocation context
7+
* @param isRequired whether or not the flag is required
8+
* @returns the absolute path to the output directory
9+
*/
10+
function getOutputDirParam(context, isRequired) {
11+
const outputDirParam = context.parameters?.options?.['output-dir'];
12+
if ( isRequired && !outputDirParam ) {
13+
throw new Error('Expected --output-dir flag to be set');
14+
}
15+
if ( !outputDirParam ) {
16+
return null;
17+
}
18+
return path.isAbsolute(outputDirParam) ? outputDirParam : path.join(context.amplify.getEnvInfo().projectPath, outputDirParam);
19+
}
20+
21+
module.exports = getOutputDirParam;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const getOutputDirParam = require('../../src/utils/getOutputDirParam');
2+
const path = require('path');
3+
4+
const PROJECT_PATH = path.join(__dirname, 'project');
5+
6+
describe('getOutputDirParam', () => {
7+
const createContextWithOptions = (options) => ({
8+
amplify: {
9+
getEnvInfo: () => ({
10+
projectPath: PROJECT_PATH
11+
}),
12+
},
13+
...(options ? { parameters: { options } } : {})
14+
});
15+
16+
it('should throw on missing flag when required is set', () => {
17+
const context = createContextWithOptions(null);
18+
expect(() => getOutputDirParam(context, true)).toThrowErrorMatchingInlineSnapshot('"Expected --output-dir flag to be set"');
19+
});
20+
21+
it('should not throw on missing flag when required is not set', () => {
22+
const context = createContextWithOptions(null);
23+
expect(() => getOutputDirParam(context, false)).not.toThrowError();
24+
});
25+
26+
it('should return for relative path set independent of whether is required', () => {
27+
const context = createContextWithOptions({ 'output-dir': path.join('src', 'models') });
28+
expect(getOutputDirParam(context, true)).toEqual(path.join(PROJECT_PATH, 'src', 'models'));
29+
expect(getOutputDirParam(context, false)).toEqual(path.join(PROJECT_PATH, 'src', 'models'));
30+
});
31+
32+
it('should return for absolute path set independent of whether is required', () => {
33+
const context = createContextWithOptions({ 'output-dir': path.join(PROJECT_PATH, 'src', 'models') });
34+
expect(getOutputDirParam(context, true)).toEqual(path.join(PROJECT_PATH, 'src', 'models'));
35+
expect(getOutputDirParam(context, false)).toEqual(path.join(PROJECT_PATH, 'src', 'models'));
36+
});
37+
});

0 commit comments

Comments
 (0)