From 841f42c63152782b617be13999f992f1a98daa8a Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Tue, 17 Sep 2024 18:25:42 +0200 Subject: [PATCH] feat: Allow overriding `enforceLockfile` with `--no-enforce-lockfile` --- docs/commands/bootstrap.mdx | 9 ++- docs/configuration/overview.mdx | 9 ++- .../lib/src/command_runner/bootstrap.dart | 9 +-- .../melos/lib/src/commands/bootstrap.dart | 6 +- .../melos/test/commands/bootstrap_test.dart | 62 ++++++++++++++++++- 5 files changed, 82 insertions(+), 13 deletions(-) diff --git a/docs/commands/bootstrap.mdx b/docs/commands/bootstrap.mdx index 1d12e5ae..cb9e93e3 100644 --- a/docs/commands/bootstrap.mdx +++ b/docs/commands/bootstrap.mdx @@ -86,15 +86,18 @@ melos bootstrap --diff="main" ## Bootstrap flags -- The `--no-example` flag is used to exclude flutter package's example's dependencies (https://github.com/dart-lang/pub/pull/3856) +- The `--no-example` flag is used to exclude flutter package's example's dependencies + (https://github.com/dart-lang/pub/pull/3856) - This will run `pub get` with the `--no-example` flag. - The `--enforce-lockfile` flag is used to enforce versions from `.lock` files. - Ensure .lock files exist, as failure may occur if they're not checked in. +- The `--no-enforce-lockfile` flag is used to disregard versions from `.lock` files if + `enforce-lockfile` is configured in the `melos.yaml` file. - The `--skip-linking` flag is used to skip the local linking of workspace packages. -In addition to the above flags, the `melos bootstrap` command supports a few different flags that can be defined in - your `melos.yaml` file. +In addition to the above flags, the `melos bootstrap` command supports a few different flags that +can be defined in your `melos.yaml` file. ### Shared dependencies diff --git a/docs/configuration/overview.mdx b/docs/configuration/overview.mdx index 5c54844f..7843a784 100644 --- a/docs/configuration/overview.mdx +++ b/docs/configuration/overview.mdx @@ -195,12 +195,17 @@ The default is `false`. ### enforceLockfile -Whether to run `pub get` with the `--enforce-lockfile` option or not, to force getting the versions specified in the `pubspec.lock` file. +Whether to run `pub get` with the `--enforce-lockfile` option or not, to force getting the versions +specified in the `pubspec.lock` file. -This is useful in CI environments or when you want to ensure that all environments/machines are using the same package versions. +This is useful in CI environments or when you want to ensure that all environments/machines are +using the same package versions. The default is `false`. +To temporarily override this `melos bootstrap --no-enforce-lockfile / --enforce-lockfile` can be +used. + ## command/version Configuration for the `version` command. diff --git a/packages/melos/lib/src/command_runner/bootstrap.dart b/packages/melos/lib/src/command_runner/bootstrap.dart index 11119155..026b639d 100644 --- a/packages/melos/lib/src/command_runner/bootstrap.dart +++ b/packages/melos/lib/src/command_runner/bootstrap.dart @@ -13,9 +13,10 @@ class BootstrapCommand extends MelosCommand { ); argParser.addFlag( 'enforce-lockfile', - negatable: false, - help: 'Run pub get with --enforce-lockfile to enforce versions from .lock' - ' files, ensure .lockfile exist for all packages.', + help: 'Run pub get with --enforce-lockfile to enforce versions from ' + '.lock files, ensure .lockfile exist for all packages.\n' + '--no-enforce-lockfile can be used to temporarily disregard the ' + 'lockfile versions.', ); argParser.addFlag( 'skip-linking', @@ -41,7 +42,7 @@ class BootstrapCommand extends MelosCommand { return melos.bootstrap( global: global, packageFilters: parsePackageFilters(config.path), - enforceLockfile: argResults?['enforce-lockfile'] as bool? ?? false, + enforceLockfile: argResults?['enforce-lockfile'] as bool?, noExample: argResults?['no-example'] as bool, skipLinking: argResults?['skip-linking'] as bool, ); diff --git a/packages/melos/lib/src/commands/bootstrap.dart b/packages/melos/lib/src/commands/bootstrap.dart index 62d20499..0d2a5de8 100644 --- a/packages/melos/lib/src/commands/bootstrap.dart +++ b/packages/melos/lib/src/commands/bootstrap.dart @@ -5,7 +5,7 @@ mixin _BootstrapMixin on _CleanMixin { GlobalOptions? global, PackageFilters? packageFilters, bool noExample = false, - bool enforceLockfile = false, + bool? enforceLockfile, bool skipLinking = false, }) async { final workspace = @@ -21,7 +21,7 @@ mixin _BootstrapMixin on _CleanMixin { final enforceLockfileConfigValue = workspace.config.commands.bootstrap.enforceLockfile; final shouldEnforceLockfile = - (enforceLockfileConfigValue || enforceLockfile) && hasLockFile; + (enforceLockfile ?? enforceLockfileConfigValue) && hasLockFile; final pubCommandForLogging = [ ...pubCommandExecArgs( @@ -74,7 +74,7 @@ mixin _BootstrapMixin on _CleanMixin { await _linkPackagesWithPubspecOverrides( workspace, - enforceLockfile: enforceLockfile, + enforceLockfile: shouldEnforceLockfile, noExample: noExample, ); diff --git a/packages/melos/test/commands/bootstrap_test.dart b/packages/melos/test/commands/bootstrap_test.dart index 68b5cae6..a74f348e 100644 --- a/packages/melos/test/commands/bootstrap_test.dart +++ b/packages/melos/test/commands/bootstrap_test.dart @@ -638,6 +638,62 @@ melos bootstrap Running "${pubExecArgs.join(' ')} get --enforce-lockfile" in workspace packages... > SUCCESS +Generating IntelliJ IDE files... + > SUCCESS + + -> 0 packages bootstrapped +''', + ), + ); + }); + + test('can run pub get --no-enforce-lockfile when enforced in config', + () async { + final workspaceDir = await createTemporaryWorkspace( + configBuilder: (path) => MelosWorkspaceConfig.fromYaml( + createYamlMap( + { + 'command': { + 'bootstrap': { + 'enforceLockfile': true, + }, + }, + }, + defaults: configMapDefaults, + ), + path: path, + ), + createLockfile: true, + ); + + final logger = TestLogger(); + final config = await MelosWorkspaceConfig.fromWorkspaceRoot(workspaceDir); + final workspace = await MelosWorkspace.fromConfig( + config, + logger: logger.toMelosLogger(), + ); + final melos = Melos(logger: logger, config: config); + final pubExecArgs = pubCommandExecArgs( + useFlutter: workspace.isFlutterWorkspace, + workspace: workspace, + ); + + await runMelosBootstrap( + melos, + logger, + enforceLockfile: false, + ); + + expect( + logger.output, + ignoringAnsii( + ''' +melos bootstrap + └> ${workspaceDir.path} + +Running "${pubExecArgs.join(' ')} get" in workspace packages... + > SUCCESS + Generating IntelliJ IDE files... > SUCCESS @@ -943,9 +999,13 @@ Future runMelosBootstrap( Melos melos, TestLogger logger, { bool skipLinking = false, + bool? enforceLockfile, }) async { try { - await melos.bootstrap(skipLinking: skipLinking); + await melos.bootstrap( + skipLinking: skipLinking, + enforceLockfile: enforceLockfile, + ); } on BootstrapException { // ignore: avoid_print print(logger.output);