From be17cdf30c5f657e26977840f9b6d5a9dc5ee518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Sasovsky?= Date: Wed, 19 Jun 2024 05:16:34 +0200 Subject: [PATCH 1/4] feat: 'auto' option for runPubGetInParallel Adds the new value of 'auto' to runPubGetInParallel, which is now default and will only run pub get sequentially if it's being run on a CI instance. --- .../lib/src/command_configs/bootstrap.dart | 73 +++++++++++++++---- .../melos/lib/src/commands/bootstrap.dart | 13 +++- .../melos/test/workspace_config_test.dart | 6 +- 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/packages/melos/lib/src/command_configs/bootstrap.dart b/packages/melos/lib/src/command_configs/bootstrap.dart index 12121085c..a6c0807c3 100644 --- a/packages/melos/lib/src/command_configs/bootstrap.dart +++ b/packages/melos/lib/src/command_configs/bootstrap.dart @@ -13,7 +13,7 @@ import '../lifecycle_hooks/lifecycle_hooks.dart'; @immutable class BootstrapCommandConfigs { const BootstrapCommandConfigs({ - this.runPubGetInParallel = true, + this.parallelPubGetMode = ParallelPubGetMode.auto, this.runPubGetOffline = false, this.enforceLockfile = false, this.environment, @@ -27,12 +27,31 @@ class BootstrapCommandConfigs { Map yaml, { required String workspacePath, }) { - final runPubGetInParallel = assertKeyIsA( - key: 'runPubGetInParallel', - map: yaml, - path: 'command/bootstrap', - ) ?? - true; + ParallelPubGetMode parallelPubGetMode; + try { + final runPubGetInParallel = assertKeyIsA( + key: 'runPubGetInParallel', + map: yaml, + path: 'command/bootstrap', + ); + if (runPubGetInParallel != null) { + parallelPubGetMode = runPubGetInParallel + ? ParallelPubGetMode.enabled + : ParallelPubGetMode.disabled; + } else { + parallelPubGetMode = ParallelPubGetMode.auto; + } + } on MelosConfigException { + final runPubGetInParallel = assertKeyIsA( + key: 'runPubGetInParallel', + map: yaml, + path: 'command/bootstrap', + ) ?? + 'auto'; + parallelPubGetMode = ParallelPubGetMode.fromValue(runPubGetInParallel); + } catch (_) { + rethrow; + } final runPubGetOffline = assertKeyIsA( key: 'runPubGetOffline', @@ -94,7 +113,7 @@ class BootstrapCommandConfigs { : LifecycleHooks.empty; return BootstrapCommandConfigs( - runPubGetInParallel: runPubGetInParallel, + parallelPubGetMode: parallelPubGetMode, runPubGetOffline: runPubGetOffline, enforceLockfile: enforceLockfile, environment: environment, @@ -114,8 +133,9 @@ class BootstrapCommandConfigs { /// Whether to run `pub get` in parallel during bootstrapping. /// - /// The default is `true`. - final bool runPubGetInParallel; + /// The default is `auto`, which will run `pub get` in parallel if the `CI` + /// environment variable is not set. + final ParallelPubGetMode parallelPubGetMode; /// Whether to attempt to run `pub get` in offline mode during bootstrapping. /// Useful in closed network environments with pre-populated pubcaches. @@ -148,7 +168,7 @@ class BootstrapCommandConfigs { Map toJson() { return { - 'runPubGetInParallel': runPubGetInParallel, + 'runPubGetInParallel': parallelPubGetMode.name, 'runPubGetOffline': runPubGetOffline, 'enforceLockfile': enforceLockfile, if (environment != null) 'environment': environment!.toJson(), @@ -171,7 +191,7 @@ class BootstrapCommandConfigs { bool operator ==(Object other) => other is BootstrapCommandConfigs && runtimeType == other.runtimeType && - other.runPubGetInParallel == runPubGetInParallel && + other.parallelPubGetMode == parallelPubGetMode && other.runPubGetOffline == runPubGetOffline && other.enforceLockfile == enforceLockfile && // Extracting equality from environment here as it does not implement == @@ -190,7 +210,7 @@ class BootstrapCommandConfigs { @override int get hashCode => runtimeType.hashCode ^ - runPubGetInParallel.hashCode ^ + parallelPubGetMode.hashCode ^ runPubGetOffline.hashCode ^ enforceLockfile.hashCode ^ // Extracting hashCode from environment here as it does not implement @@ -209,7 +229,7 @@ class BootstrapCommandConfigs { String toString() { return ''' BootstrapCommandConfigs( - runPubGetInParallel: $runPubGetInParallel, + runPubGetInParallel: $parallelPubGetMode, runPubGetOffline: $runPubGetOffline, enforceLockfile: $enforceLockfile, environment: $environment, @@ -220,3 +240,28 @@ BootstrapCommandConfigs( )'''; } } + +enum ParallelPubGetMode { + auto, + enabled, + disabled; + + factory ParallelPubGetMode.fromValue(String value) { + switch (value) { + case 'auto': + return ParallelPubGetMode.auto; + case 'true': + case 'enabled': + return ParallelPubGetMode.enabled; + case 'false': + case 'disabled': + return ParallelPubGetMode.disabled; + default: + throw ArgumentError.value( + value, + 'name', + 'Invalid value for ParallelPubGetMode', + ); + } + } +} diff --git a/packages/melos/lib/src/commands/bootstrap.dart b/packages/melos/lib/src/commands/bootstrap.dart index 62d204997..45d465147 100644 --- a/packages/melos/lib/src/commands/bootstrap.dart +++ b/packages/melos/lib/src/commands/bootstrap.dart @@ -109,6 +109,16 @@ mixin _BootstrapMixin on _CleanMixin { required bool noExample, }) async { final filteredPackages = workspace.filteredPackages.values; + final isCI = utils.isCI; + + bool parallelism; + if (workspace.config.commands.bootstrap.parallelPubGetMode == + ParallelPubGetMode.auto) { + parallelism = !isCI; + } else { + parallelism = workspace.config.commands.bootstrap.parallelPubGetMode == + ParallelPubGetMode.enabled; + } await Stream.fromIterable(filteredPackages).parallel( (package) async { @@ -143,8 +153,7 @@ mixin _BootstrapMixin on _CleanMixin { bootstrappedPackages.forEach(_logBootstrapSuccess); }, - parallelism: - workspace.config.commands.bootstrap.runPubGetInParallel ? null : 1, + parallelism: parallelism ? null : 1, ).drain(); } diff --git a/packages/melos/test/workspace_config_test.dart b/packages/melos/test/workspace_config_test.dart index 4a85ba4ec..7588d66f8 100644 --- a/packages/melos/test/workspace_config_test.dart +++ b/packages/melos/test/workspace_config_test.dart @@ -14,7 +14,7 @@ void main() { // ignore: use_named_constants const value = BootstrapCommandConfigs(); - expect(value.runPubGetInParallel, true); + expect(value.parallelPubGetMode, ParallelPubGetMode.auto); }); group('fromYaml', () { @@ -49,7 +49,7 @@ void main() { workspacePath: '.', ), BootstrapCommandConfigs( - runPubGetInParallel: false, + parallelPubGetMode: ParallelPubGetMode.disabled, runPubGetOffline: true, enforceLockfile: true, dependencyOverridePaths: [ @@ -243,7 +243,7 @@ void main() { // ignore: avoid_redundant_argument_values, use_named_constants bootstrap: BootstrapCommandConfigs( // ignore: avoid_redundant_argument_values - runPubGetInParallel: true, + parallelPubGetMode: ParallelPubGetMode.enabled, ), ), ); From 8ab74d941d78ef2d7dfd3b07317683e7edc1ce80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Sasovsky?= Date: Wed, 19 Jun 2024 17:52:56 +0200 Subject: [PATCH 2/4] docs: update API documentation to reflect new changes from PR --- docs/configuration/overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/overview.mdx b/docs/configuration/overview.mdx index 5c54844f2..c32a3be46 100644 --- a/docs/configuration/overview.mdx +++ b/docs/configuration/overview.mdx @@ -183,7 +183,7 @@ dependencyOverridePaths: Whether to run `pub get` in parallel during bootstrapping. -The default is `true`. +The default is `auto`, which fallbacks to `false` if the machine is a CI instance. ### runPubGetOffline From e2261969b9368c098c5b723fc11665b0cf2dd39d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Sasovsky?= Date: Wed, 19 Jun 2024 17:54:30 +0200 Subject: [PATCH 3/4] refactor: use a switch case for readability when processing ParallelPubGetMode values --- packages/melos/lib/src/commands/bootstrap.dart | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/melos/lib/src/commands/bootstrap.dart b/packages/melos/lib/src/commands/bootstrap.dart index 45d465147..5d83fafc0 100644 --- a/packages/melos/lib/src/commands/bootstrap.dart +++ b/packages/melos/lib/src/commands/bootstrap.dart @@ -112,12 +112,13 @@ mixin _BootstrapMixin on _CleanMixin { final isCI = utils.isCI; bool parallelism; - if (workspace.config.commands.bootstrap.parallelPubGetMode == - ParallelPubGetMode.auto) { - parallelism = !isCI; - } else { - parallelism = workspace.config.commands.bootstrap.parallelPubGetMode == - ParallelPubGetMode.enabled; + switch (workspace.config.commands.bootstrap.parallelPubGetMode) { + case ParallelPubGetMode.auto: + parallelism = !isCI; + case ParallelPubGetMode.enabled: + parallelism = true; + case ParallelPubGetMode.disabled: + parallelism = false; } await Stream.fromIterable(filteredPackages).parallel( From 6de71d83648869199c44403ee96ad0c8e8b60bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Sasovsky?= Date: Wed, 19 Jun 2024 17:55:33 +0200 Subject: [PATCH 4/4] chore: change ArgumentError name field from 'name' to 'value' --- packages/melos/lib/src/command_configs/bootstrap.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/melos/lib/src/command_configs/bootstrap.dart b/packages/melos/lib/src/command_configs/bootstrap.dart index a6c0807c3..91069c7e2 100644 --- a/packages/melos/lib/src/command_configs/bootstrap.dart +++ b/packages/melos/lib/src/command_configs/bootstrap.dart @@ -259,7 +259,7 @@ enum ParallelPubGetMode { default: throw ArgumentError.value( value, - 'name', + 'value', 'Invalid value for ParallelPubGetMode', ); }