From 90a261279215b9dd571118514522d8fc21ee29dc Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Tue, 10 Sep 2024 01:23:53 +1000 Subject: [PATCH] Added --non-interactive and --force support when --id is not passed to eas init command (#1983) * Added --non-interactive and --force support when --id is not passed to eas init command * Removed id dependency from init command flags * Bump undici from 5.19.1 to 5.26.3 Bumps [undici](https://github.com/nodejs/undici) from 5.19.1 to 5.26.3. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v5.19.1...v5.26.3) --- updated-dependencies: - dependency-name: undici dependency-type: indirect ... Signed-off-by: dependabot[bot] * Revert "Bump undici from 5.19.1 to 5.26.3" * Apply suggestions from code review Co-authored-by: Szymon Dziedzic * Fixed initializeWithoutExplicitIDAsync not being used * Require force flag to use default account when no account name is specified in non-interactive mode * Changed error message when user has access to multiple accounts in non-interactive mode * Added changelog entry * Update CHANGELOG.md Co-authored-by: Szymon Dziedzic --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ryan Button <56656890+RyanButton@users.noreply.github.com> Co-authored-by: Szymon Dziedzic --- CHANGELOG.md | 2 + packages/eas-cli/src/commands/project/init.ts | 77 +++++++++++++------ 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b8f6d3036..e046f8adcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ This is the log of notable changes to EAS CLI and related packages. ### ๐ŸŽ‰ New features +- Add `--non-interactive` and `--force` support when `--id` is not passed to the `eas init` command. ([#1983](https://github.com/expo/eas-cli/pull/1983) by [@mymattcarroll](https://github.com/mymattcarroll)) + ### ๐Ÿ› Bug fixes ### ๐Ÿงน Chores diff --git a/packages/eas-cli/src/commands/project/init.ts b/packages/eas-cli/src/commands/project/init.ts index 2ca850cbba..43f43807a0 100644 --- a/packages/eas-cli/src/commands/project/init.ts +++ b/packages/eas-cli/src/commands/project/init.ts @@ -8,6 +8,7 @@ import { getProjectDashboardUrl } from '../../build/utils/url'; import EasCommand from '../../commandUtils/EasCommand'; import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient'; import { saveProjectIdToAppConfigAsync } from '../../commandUtils/context/contextUtils/getProjectIdAsync'; +import { EASNonInteractiveFlag } from '../../commandUtils/flags'; import { AppPrivacy, Role } from '../../graphql/generated'; import { AppMutation } from '../../graphql/mutations/AppMutation'; import { AppQuery } from '../../graphql/queries/AppQuery'; @@ -33,14 +34,10 @@ export default class ProjectInit extends EasCommand { description: 'ID of the EAS project to link', }), force: Flags.boolean({ - description: 'Whether to overwrite any existing project ID', - dependsOn: ['id'], - }), - // this is the same as EASNonInteractiveFlag but with the dependsOn - 'non-interactive': Flags.boolean({ - description: 'Run the command in non-interactive mode.', - dependsOn: ['id'], + description: + 'Whether to create a new project/link an existing project without additional prompts or overwrite any existing project ID when running with --id flag', }), + ...EASNonInteractiveFlag, }; static override contextDefinition = { @@ -216,10 +213,11 @@ export default class ProjectInit extends EasCommand { }); } - private static async initializeWithInteractiveSelectionAsync( + private static async initializeWithoutExplicitIDAsync( graphqlClient: ExpoGraphqlClient, actor: Actor, - projectDir: string + projectDir: string, + { force, nonInteractive }: InitializeMethodOptions ): Promise { const exp = getPrivateExpoConfig(projectDir); const existingProjectId = exp.extra?.eas?.projectId; @@ -245,6 +243,20 @@ export default class ProjectInit extends EasCommand { if (!accountName) { if (allAccounts.length === 1) { accountName = allAccounts[0].name; + } else if (nonInteractive) { + if (!force) { + throw new Error( + `There are multiple accounts that you have access to: ${allAccounts + .map(a => a.name) + .join( + ', ' + )}. Explicitly set the owner property in your app config or run this command with the --force flag to proceed with a default account: ${ + allAccounts[0].name + }.` + ); + } + accountName = allAccounts[0].name; + Log.log(`Using default account ${accountName} for non-interactive and force mode`); } else { const choices = ProjectInit.getAccountChoices( actor, @@ -274,13 +286,21 @@ export default class ProjectInit extends EasCommand { projectName ); if (existingProjectIdOnServer) { - const affirmedLink = await confirmAsync({ - message: `Existing project found: ${projectFullName} (ID: ${existingProjectIdOnServer}). Link this project?`, - }); - if (!affirmedLink) { - throw new Error( - `Project ID configuration canceled. Re-run the command to select a different account/project.` - ); + if (!force) { + if (nonInteractive) { + throw new Error( + `Existing project found: ${projectFullName} (ID: ${existingProjectIdOnServer}). Use --force flag to continue with this project.` + ); + } + + const affirmedLink = await confirmAsync({ + message: `Existing project found: ${projectFullName} (ID: ${existingProjectIdOnServer}). Link this project?`, + }); + if (!affirmedLink) { + throw new Error( + `Project ID configuration canceled. Re-run the command to select a different account/project.` + ); + } } await ProjectInit.saveProjectIdAndLogSuccessAsync(projectDir, existingProjectIdOnServer); @@ -293,11 +313,18 @@ export default class ProjectInit extends EasCommand { ); } - const affirmedCreate = await confirmAsync({ - message: `Would you like to create a project for ${projectFullName}?`, - }); - if (!affirmedCreate) { - throw new Error(`Project ID configuration canceled for ${projectFullName}.`); + if (!force) { + if (nonInteractive) { + throw new Error( + `Project does not exist: ${projectFullName}. Use --force flag to create this project.` + ); + } + const affirmedCreate = await confirmAsync({ + message: `Would you like to create a project for ${projectFullName}?`, + }); + if (!affirmedCreate) { + throw new Error(`Project ID configuration canceled for ${projectFullName}.`); + } } const projectDashboardUrl = getProjectDashboardUrl(accountName, projectName); @@ -405,10 +432,14 @@ export default class ProjectInit extends EasCommand { }); idForConsistency = idArgument; } else { - idForConsistency = await ProjectInit.initializeWithInteractiveSelectionAsync( + idForConsistency = await ProjectInit.initializeWithoutExplicitIDAsync( graphqlClient, actor, - projectDir + projectDir, + { + force, + nonInteractive, + } ); }