Skip to content

Commit

Permalink
feat: add init prompts for Gen2 (#13849)
Browse files Browse the repository at this point in the history
* feat: add warning to init

* feat: add prompt to init

* feat: only prompt on new project

* feat: add guide to Gen2

* refactor: change to use process exit

* Update packages/amplify-cli/src/init-steps/preInitMigrationWarning.ts

Co-authored-by: Amplifiyer <[email protected]>

* refactor: rename to gen2Recommendation

* refactor: combine gen2Recommendation to preInitSetup

* feat: remove goodbye message

* test: fix init.test

* test: add unit test for preInitSetup

* chore: rename to getPreInitSetup

* feat: change verbiage

* chore: update unit test

* feat: add whyContinueWithGen1 to stack metadata

* fix: verify verify_versions_match

* fix: verify verify_versions_match

* feat: bump versions

* feat: bump versions

* feat: bump versions

* chore: rename to recommendGen2

* chore: rename to recommendGen2 in test

* revert .sh format

* chore: rename and not export preInitSetup

* fix: export gen2Recommandation and preInitSetup for test

* fix: set inital answer for pick

* Revert "fix: set inital answer for pick"

This reverts commit 7ecde5c.

* Revert "Revert "fix: set inital answer for pick""

This reverts commit d8fa624.

* fix: preInitSetup.test

* fix: e2e test by adding isCI

* chore: upgrade node-pty

* Revert "fix: e2e test by adding isCI"

This reverts commit 71b204c.

* test: add prompt to e2e

* fix: set default value for whyContinueWithGen1

* fix: projectConfig undefined and remove default choice

* fix: preInitSetup.test.ts

* fix: add default choice back

* fix: remove prompts from migration test

* test: move new prompt from v12

* test: move new prompt from initJSProjectWithProfile

* Revert "test: move new prompt from initJSProjectWithProfile"

This reverts commit eeb6f71.

* test: move new prompts from initJSProjectWithProfile

* chore: change recommendGen2

* test: fix preInitSetup unit test

* test: add includeGen2RecommendationPrompt

* test: add includeGen2RecommendationPrompt to migration-2

* test: remove prompts from initAndroidProjectWithProfileV12

---------

Co-authored-by: 0.618 <[email protected]>
Co-authored-by: Amplifiyer <[email protected]>
  • Loading branch information
3 people authored Sep 20, 2024
1 parent a644a1f commit 7ab8fae
Show file tree
Hide file tree
Showing 19 changed files with 223 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .circleci/local_publish_helpers_codebuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ function checkPackageVersionsInLocalNpmRegistry {

if [[ $cli_internal_version != $cli_version ]]; then
echo "Versions did not match."
echo "Manual fix: add a proper conventional commit that touches the amplify-cli-npm package to correct its version bump. For example https://github.com/aws-amplify/amplify-cli/commit/6f14792d1db424aa428ec4836fed7d6dd5cccfd0"
echo "Manual fix: add a proper conventional commit that touches the amplify-cli-npm package to correct its version bump. For example https://github.com/aws-amplify/amplify-cli/pull/13759/commits/15dcd96feae925ff26ca51abfb4a0477890af745"
exit 1
else
echo "Versions matched."
Expand Down
2 changes: 1 addition & 1 deletion packages/amplify-cli-npm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ export const install = async (): Promise<void> => {
return binary.install();
};

// force version bump to 12.12.0
// force version bump to 12.13.0
6 changes: 4 additions & 2 deletions packages/amplify-cli/src/__tests__/commands/init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { execSync } from 'child_process';
import { ensureDir, existsSync, readFileSync, readJSON, readdirSync } from 'fs-extra';
import { sync } from 'which';
import { preInitSetup } from '../../init-steps/preInitSetup';
import { getPreInitSetup } from '../../init-steps/preInitSetup';
import { analyzeProject } from '../../init-steps/s0-analyzeProject';
import { initFrontend } from '../../init-steps/s1-initFrontend';
import { scaffoldProjectHeadless } from '../../init-steps/s8-scaffoldHeadless';
Expand Down Expand Up @@ -137,7 +137,9 @@ describe('amplify init:', () => {
},
},
};
await preInitSetup(context as unknown as $TSContext);
const recommendGen2 = true;
const step = getPreInitSetup(!recommendGen2);
await step(context as unknown as $TSContext);
expect(execSync).toBeCalledWith(`git ls-remote ${appUrl}`, { stdio: 'ignore' });
expect(execSync).toBeCalledWith(`git clone ${appUrl} .`, { stdio: 'inherit' });
expect(execSync).toBeCalledWith('yarn install', { stdio: 'inherit' });
Expand Down
95 changes: 95 additions & 0 deletions packages/amplify-cli/src/__tests__/init-steps/preInitSetup.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { $TSContext } from '@aws-amplify/amplify-cli-core';
import { printer, prompter } from '@aws-amplify/amplify-prompts';
import { getPreInitSetup, preInitSetup, gen2Recommendation } from '../../init-steps/preInitSetup';
import { isNewProject } from '../../init-steps/s0-analyzeProject';

// Mock dependencies
jest.mock('@aws-amplify/amplify-cli-core', () => ({
...(jest.requireActual('@aws-amplify/amplify-cli-core') as {}),
FeatureFlags: {
getBoolean: jest.fn(),
getNumber: jest.fn(),
isInitialized: jest.fn().mockReturnValue(true),
ensureDefaultFeatureFlags: jest.fn(),
},
getPackageManager: jest.fn(),
}));

jest.mock('@aws-amplify/amplify-prompts', () => ({
printer: {
warn: jest.fn(),
},
prompter: {
confirmContinue: jest.fn(),
pick: jest.fn(),
},
}));

jest.mock('../../init-steps/s0-analyzeProject', () => ({
isNewProject: jest.fn(),
}));

describe('preInitSetup', () => {
it('should return preInitSetupBasic when isHeadless is true', () => {
const result = getPreInitSetup(false);
expect(result).toBe(preInitSetup);
});

it('should return a function when isHeadless is false', () => {
const result = getPreInitSetup(false);
expect(typeof result).toBe('function');
});
});

describe('gen2Recommendation', () => {
let context;

beforeEach(() => {
context = { exeInfo: {} } as $TSContext;
});

afterEach(() => {
jest.clearAllMocks();
});

it('should recommend using Gen 2 for new projects', async () => {
const isNewProjectMock = jest.mocked(isNewProject);
isNewProjectMock.mockReturnValue(true);

const confirmContinueMock = jest.mocked(prompter.confirmContinue);
confirmContinueMock.mockResolvedValue(true);

const pickMock = jest.mocked(prompter.pick);
pickMock.mockResolvedValue('I am a current Gen 1 user');

await gen2Recommendation(context);

expect(require('@aws-amplify/amplify-prompts').printer.warn).toHaveBeenCalledWith(
'For new projects, we recommend starting with AWS Amplify Gen 2, our new code-first developer experience. Get started at https://docs.amplify.aws/react/start/quickstart/',
);
expect(confirmContinueMock).toHaveBeenCalledWith('Do you want to continue with Amplify Gen 1?');
expect(pickMock).toHaveBeenCalledWith(
'Why would you like to use Amplify Gen 1?',
[
'I am a current Gen 1 user',
'Gen 2 is missing features I need from Gen 1',
'I find the Gen 1 CLI easier to use',
'Prefer not to answer',
],
{ initial: 3 },
);
expect(context.exeInfo.projectConfig).toEqual({ whyContinueWithGen1: 'I am a current Gen 1 user' });
});

it('should return the context for existing projects', async () => {
const isNewProjectMock = jest.mocked(isNewProject);
isNewProjectMock.mockReturnValue(false);

const result = await gen2Recommendation(context);

expect(result).toEqual(context);
expect(printer.warn).not.toHaveBeenCalled();
expect(prompter.confirmContinue).not.toHaveBeenCalled();
expect(prompter.pick).not.toHaveBeenCalled();
});
});
7 changes: 4 additions & 3 deletions packages/amplify-cli/src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { constructInputParams } from '../amplify-service-helper';
import { Context } from '../domain/context';
import { raisePostEnvAddEvent } from '../execution-manager';
import { postInitSetup } from '../init-steps/postInitSetup';
import { preInitSetup } from '../init-steps/preInitSetup';
import { getPreInitSetup } from '../init-steps/preInitSetup';
import { analyzeProject, analyzeProjectHeadless } from '../init-steps/s0-analyzeProject';
import { initFrontend } from '../init-steps/s1-initFrontend';
import { initProviders } from '../init-steps/s2-initProviders';
Expand All @@ -18,11 +18,12 @@ const constructExeInfo = (context: $TSContext): void => {
};
};

const recommendGen2 = true;
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
const runStrategy = (quickstart: boolean) =>
quickstart
? [preInitSetup, analyzeProjectHeadless, scaffoldProjectHeadless, onHeadlessSuccess]
: [preInitSetup, analyzeProject, initFrontend, initProviders, onSuccess, postInitSetup];
? [getPreInitSetup(!recommendGen2), analyzeProjectHeadless, scaffoldProjectHeadless, onHeadlessSuccess]
: [getPreInitSetup(recommendGen2), analyzeProject, initFrontend, initProviders, onSuccess, postInitSetup];

/**
* entry point for the init command
Expand Down
3 changes: 1 addition & 2 deletions packages/amplify-cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,5 +257,4 @@ export const executeAmplifyCommand = async (context: Context): Promise<void> =>
}
};

// bump version to 12.12.0
//
// bump version to 12.13.0
49 changes: 49 additions & 0 deletions packages/amplify-cli/src/init-steps/preInitSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ import { execSync } from 'child_process';
import * as fs from 'fs-extra';
import * as url from 'url';
import { generateLocalEnvInfoFile } from './s9-onSuccess';
import { printer, prompter } from '@aws-amplify/amplify-prompts';
import { isNewProject } from './s0-analyzeProject';

export const getPreInitSetup = (recommendGen2: boolean) => {
if (recommendGen2) {
return async (context) => {
await gen2Recommendation(context);
await preInitSetup(context);
};
} else {
return preInitSetup;
}
};

/**
* Executes before init
Expand All @@ -22,6 +35,42 @@ export const preInitSetup = async (context: $TSContext): Promise<$TSContext> =>
return context;
};

/**
* recommend using Gen 2 or continue with Gen 1.
* ask for why they are using Gen 1 and store the answer in project-config
*/
export const gen2Recommendation = async (context: $TSContext): Promise<$TSContext> => {
if (!isNewProject(context)) {
return context;
}
printer.warn(
'For new projects, we recommend starting with AWS Amplify Gen 2, our new code-first developer experience. Get started at https://docs.amplify.aws/react/start/quickstart/',
);

const continueWithGen1 = await prompter.confirmContinue('Do you want to continue with Amplify Gen 1?');

if (!continueWithGen1) {
process.exit(0);
}

const whyContinueWithGen1 = await prompter.pick(
'Why would you like to use Amplify Gen 1?',
[
'I am a current Gen 1 user',
'Gen 2 is missing features I need from Gen 1',
'I find the Gen 1 CLI easier to use',
'Prefer not to answer',
],
{ initial: 3 },
);

context.exeInfo.projectConfig = {
whyContinueWithGen1,
};

return context;
};

/**
* Checks whether a url is a valid remote github repository
*
Expand Down
3 changes: 2 additions & 1 deletion packages/amplify-cli/src/init-steps/s0-analyzeProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export const analyzeProject = async (context: $TSContext): Promise<$TSContext> =
const setProjectConfig = (context: $TSContext, projectName: string): void => {
context.exeInfo.isNewProject = isNewProject(context);
context.exeInfo.projectConfig = {
...context.exeInfo.projectConfig,
projectName,
version: amplifyCLIConstants.CURRENT_PROJECT_CONFIG_VERSION,
};
Expand Down Expand Up @@ -325,7 +326,7 @@ const isNewEnv = (envName: string): boolean => {
return !allEnvs.includes(envName);
};

const isNewProject = (context: $TSContext): boolean => {
export const isNewProject = (context: $TSContext): boolean => {
let newProject = true;
const projectPath = process.cwd();
const projectConfigFilePath = context.amplify.pathManager.getProjectConfigFilePath(projectPath);
Expand Down
2 changes: 1 addition & 1 deletion packages/amplify-e2e-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"jest-environment-node": "^26.6.2",
"lodash": "^4.17.21",
"node-fetch": "^2.6.7",
"node-pty": "beta",
"node-pty": "^1.0.0",
"retimer": "2.0.0",
"rimraf": "^3.0.0",
"semver": "^7.5.4",
Expand Down
33 changes: 32 additions & 1 deletion packages/amplify-e2e-core/src/init/initProjectHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const defaultSettings = {
providerConfig: undefined,
permissionsBoundaryArn: undefined,
includeUsageDataPrompt: true,
includeGen2RecommendationPrompt: true,
testingWithLatestCodebase: false,
};

Expand Down Expand Up @@ -59,7 +60,17 @@ export function initJSProjectWithProfile(cwd: string, settings?: Partial<typeof
stripColors: true,
env,
disableCIDetection: s.disableCIDetection,
})
});

if (s.includeGen2RecommendationPrompt) {
chain
.wait('Do you want to continue with Amplify Gen 1?')
.sendYes()
.wait('Why would you like to use Amplify Gen 1?')
.sendCarriageReturn();
}

chain
.wait('Enter a name for the project')
.sendLine(s.name)
.wait('Initialize the project with the above configuration?')
Expand Down Expand Up @@ -115,6 +126,10 @@ export function initAndroidProjectWithProfile(cwd: string, settings: Partial<typ
stripColors: true,
env,
})
.wait('Do you want to continue with Amplify Gen 1?')
.sendYes()
.wait('Why would you like to use Amplify Gen 1?')
.sendCarriageReturn()
.wait('Enter a name for the project')
.sendLine(s.name)
.wait('Initialize the project with the above configuration?')
Expand Down Expand Up @@ -171,6 +186,10 @@ export function initIosProjectWithProfile(cwd: string, settings: Record<string,
stripColors: true,
env,
})
.wait('Do you want to continue with Amplify Gen 1?')
.sendYes()
.wait('Why would you like to use Amplify Gen 1?')
.sendCarriageReturn()
.wait('Enter a name for the project')
.sendLine(s.name)
.wait('Initialize the project with the above configuration?')
Expand Down Expand Up @@ -205,6 +224,10 @@ export function initIosProjectWithXcode(cwd: string): Promise<void> {
cwd,
stripColors: true,
})
.wait('Do you want to continue with Amplify Gen 1?')
.sendYes()
.wait('Why would you like to use Amplify Gen 1?')
.sendCarriageReturn()
.wait('Enter a name for the project')
.sendCarriageReturn()
.wait('Initialize the project with the above configuration?')
Expand Down Expand Up @@ -237,6 +260,10 @@ export function initFlutterProjectWithProfile(cwd: string, settings: Record<stri

return new Promise((resolve, reject) => {
const chain = spawn(getCLIPath(), ['init'], { cwd, stripColors: true })
.wait('Do you want to continue with Amplify Gen 1?')
.sendYes()
.wait('Why would you like to use Amplify Gen 1?')
.sendCarriageReturn()
.wait('Enter a name for the project')
.sendLine(s.name)
.wait('Initialize the project with the above configuration?')
Expand Down Expand Up @@ -286,6 +313,10 @@ export function initProjectWithAccessKey(
CLI_DEV_INTERNAL_DISABLE_AMPLIFY_APP_CREATION: '1',
},
})
.wait('Do you want to continue with Amplify Gen 1?')
.sendYes()
.wait('Why would you like to use Amplify Gen 1?')
.sendCarriageReturn()
.wait('Enter a name for the project')
.sendLine(s.name)
.wait('Initialize the project with the above configuration?')
Expand Down
4 changes: 4 additions & 0 deletions packages/amplify-e2e-core/src/utils/pinpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ export function initProjectForPinpoint(cwd: string): Promise<void> {
CLI_DEV_INTERNAL_DISABLE_AMPLIFY_APP_CREATION: '1',
},
})
.wait('Do you want to continue with Amplify Gen 1?')
.sendYes()
.wait('Why would you like to use Amplify Gen 1?')
.sendCarriageReturn()
.wait('Enter a name for the project')
.sendLine(settings.name)
.wait('Initialize the project with the above configuration?')
Expand Down
2 changes: 1 addition & 1 deletion packages/amplify-e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"lodash": "^4.17.21",
"moment": "^2.24.0",
"node-fetch": "^2.6.7",
"node-pty": "beta",
"node-pty": "^1.0.0",
"rimraf": "^3.0.0",
"title-case": "^3.0.3",
"upper-case": "^2.0.2",
Expand Down
4 changes: 4 additions & 0 deletions packages/amplify-e2e-tests/src/init-special-cases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ async function initWorkflow(cwd: string, settings: { accessKeyId: string; secret
CLI_DEV_INTERNAL_DISABLE_AMPLIFY_APP_CREATION: '1',
},
})
.wait('Do you want to continue with Amplify Gen 1?')
.sendYes()
.wait('Why would you like to use Amplify Gen 1?')
.sendCarriageReturn()
.wait('Enter a name for the project')
.sendCarriageReturn()
.wait('Initialize the project with the above configuration?')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('amplify key force push', () => {
await initJSProjectWithProfile(projRoot, {
name: 'gqlkeytwomigration',
includeUsageDataPrompt: false,
includeGen2RecommendationPrompt: false,
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('amplify key force push', () => {
await initJSProjectWithProfile(projRoot, {
name: 'gqlkeymigration',
includeUsageDataPrompt: false,
includeGen2RecommendationPrompt: false,
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ describe('v12: amplify migration test auth', () => {

describe('...uses user groups and role mappings', () => {
it('...maintains correct role mapping when updated with latest version', async () => {
await initJSProjectWithProfile(projRoot1, { name: 'authTest', disableAmplifyAppCreation: false });
await initJSProjectWithProfile(projRoot1, {
name: 'authTest',
disableAmplifyAppCreation: false,
includeGen2RecommendationPrompt: false,
});
await addAuthWithGroups(projRoot1);
await amplifyPushAuth(projRoot1);

Expand Down
Loading

0 comments on commit 7ab8fae

Please sign in to comment.