From 86647f1d2eea7ce66063fe44b0af70dc633a093e Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Mon, 7 Oct 2024 21:32:38 +0200 Subject: [PATCH] feat: Allow overriding `enforceLockfile` with `--no-enforce-lockfile` (#758) Adds the possibility to run `--no-enforce-lockfile` in a command to override the melos.yaml settings. --- 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 | 58 +++++++++++++++++++ 5 files changed, 79 insertions(+), 12 deletions(-) diff --git a/docs/commands/bootstrap.mdx b/docs/commands/bootstrap.mdx index 518aecb2..66234a65 100644 --- a/docs/commands/bootstrap.mdx +++ b/docs/commands/bootstrap.mdx @@ -86,17 +86,20 @@ 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. - The `--offline` flag is used to only resolve dependencies from the local cache by running `pub get` with the `--offline` flag. -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 d2c58de7..7074950c 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', @@ -47,7 +48,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, offline: argResults?['offline'] as bool, diff --git a/packages/melos/lib/src/commands/bootstrap.dart b/packages/melos/lib/src/commands/bootstrap.dart index 83069717..946f1cb4 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, bool offline = false, }) async { @@ -23,7 +23,7 @@ mixin _BootstrapMixin on _CleanMixin { final enforceLockfileConfigValue = workspace.config.commands.bootstrap.enforceLockfile; final shouldEnforceLockfile = - (enforceLockfileConfigValue || enforceLockfile) && hasLockFile; + (enforceLockfile ?? enforceLockfileConfigValue) && hasLockFile; final pubCommandForLogging = [ ...pubCommandExecArgs( @@ -76,7 +76,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 f56d3b81..dc4a325d 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 @@ -979,11 +1035,13 @@ Future runMelosBootstrap( Melos melos, TestLogger logger, { bool skipLinking = false, + bool? enforceLockfile, bool offline = false, }) async { try { await melos.bootstrap( skipLinking: skipLinking, + enforceLockfile: enforceLockfile, offline: offline, ); } on BootstrapException {