From 7e651b757c69584ca638a0a2150e45ae1c15f944 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 29 Mar 2024 14:02:02 +0530 Subject: [PATCH 1/6] feat: add support for `melos bs --skip-linking` Signed-off-by: Sahil Kumar --- .../lib/src/command_runner/bootstrap.dart | 6 ++++ .../melos/lib/src/commands/bootstrap.dart | 28 +++++++++++++------ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/packages/melos/lib/src/command_runner/bootstrap.dart b/packages/melos/lib/src/command_runner/bootstrap.dart index f38d2724a..8bcf0c848 100644 --- a/packages/melos/lib/src/command_runner/bootstrap.dart +++ b/packages/melos/lib/src/command_runner/bootstrap.dart @@ -34,6 +34,11 @@ class BootstrapCommand extends MelosCommand { help: 'Run pub get with --enforce-lockfile to enforce versions from .lock' ' files, ensure .lockfile exist for all packages.', ); + argParser.addFlag( + 'skip-linking', + negatable: false, + help: 'Skips locally linking workspace packages.', + ); } @override @@ -55,6 +60,7 @@ class BootstrapCommand extends MelosCommand { packageFilters: parsePackageFilters(config.path), enforceLockfile: argResults?['enforce-lockfile'] as bool? ?? false, 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 00c430902..e04067c63 100644 --- a/packages/melos/lib/src/commands/bootstrap.dart +++ b/packages/melos/lib/src/commands/bootstrap.dart @@ -6,6 +6,7 @@ mixin _BootstrapMixin on _CleanMixin { PackageFilters? packageFilters, bool noExample = false, bool enforceLockfile = false, + bool skipLinking = false, }) async { final workspace = await createWorkspace(global: global, packageFilters: packageFilters); @@ -33,7 +34,6 @@ mixin _BootstrapMixin on _CleanMixin { ..child(targetStyle(workspace.path)) ..newLine(); - logger.log('Running "$pubCommandForLogging" in workspace packages...'); if (!utils.isCI && workspace.filteredPackages.keys.length > 20) { logger.warning( 'Note: this may take a while in large workspaces such as this one.', @@ -45,6 +45,8 @@ mixin _BootstrapMixin on _CleanMixin { if (bootstrapCommandConfig.environment != null || bootstrapCommandConfig.dependencies != null || bootstrapCommandConfig.devDependencies != null) { + logger.log('Updating common dependencies in workspace packages...'); + final filteredPackages = workspace.filteredPackages.values; await Stream.fromIterable(filteredPackages).parallel((package) { return _setSharedDependenciesForPackage( @@ -54,20 +56,28 @@ mixin _BootstrapMixin on _CleanMixin { devDependencies: bootstrapCommandConfig.devDependencies, ); }).drain(); + + logger.child(successLabel, prefix: '> '); } - await _linkPackagesWithPubspecOverrides( - workspace, - enforceLockfile: enforceLockfile, - noExample: noExample, - ); + if (!skipLinking) { + logger + ..newLine() + ..log('Running "$pubCommandForLogging" in workspace packages...'); + + await _linkPackagesWithPubspecOverrides( + workspace, + enforceLockfile: enforceLockfile, + noExample: noExample, + ); + + logger.child(successLabel, prefix: '> '); + } } on BootstrapException catch (exception) { _logBootstrapException(exception, workspace); rethrow; } - logger.child(successLabel, prefix: '> '); - if (workspace.config.ide.intelliJ.enabled) { logger ..newLine() @@ -282,7 +292,7 @@ mixin _BootstrapMixin on _CleanMixin { ]; if (message.isNotEmpty) { logger - .child(packageNameStyle(package.name), prefix: '') + .child(packageNameStyle(package.name), prefix: '$checkLabel ') .child(message.join('\n')); } } From f5114776f91cdf00ce9dd0d3458dfe6224ce09ab Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 29 Mar 2024 14:57:36 +0530 Subject: [PATCH 2/6] fix log formatting Signed-off-by: Sahil Kumar --- .../melos/lib/src/commands/bootstrap.dart | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/melos/lib/src/commands/bootstrap.dart b/packages/melos/lib/src/commands/bootstrap.dart index e04067c63..97cf9ae39 100644 --- a/packages/melos/lib/src/commands/bootstrap.dart +++ b/packages/melos/lib/src/commands/bootstrap.dart @@ -57,13 +57,15 @@ mixin _BootstrapMixin on _CleanMixin { ); }).drain(); - logger.child(successLabel, prefix: '> '); + logger + ..child(successLabel, prefix: '> ') + ..newLine(); } if (!skipLinking) { - logger - ..newLine() - ..log('Running "$pubCommandForLogging" in workspace packages...'); + logger.log( + 'Running "$pubCommandForLogging" in workspace packages...', + ); await _linkPackagesWithPubspecOverrides( workspace, @@ -71,7 +73,9 @@ mixin _BootstrapMixin on _CleanMixin { noExample: noExample, ); - logger.child(successLabel, prefix: '> '); + logger + ..child(successLabel, prefix: '> ') + ..newLine(); } } on BootstrapException catch (exception) { _logBootstrapException(exception, workspace); @@ -79,19 +83,17 @@ mixin _BootstrapMixin on _CleanMixin { } if (workspace.config.ide.intelliJ.enabled) { - logger - ..newLine() - ..log('Generating IntelliJ IDE files...'); + logger.log('Generating IntelliJ IDE files...'); await cleanIntelliJ(workspace); await workspace.ide.intelliJ.generate(); - logger.child(successLabel, prefix: '> '); + logger + ..child(successLabel, prefix: '> ') + ..newLine(); } - logger - ..newLine() - ..log( - ' -> ${workspace.filteredPackages.length} packages bootstrapped', - ); + logger.log( + ' -> ${workspace.filteredPackages.length} packages bootstrapped', + ); }, ); } From 9de59121393f28116ffebb542844c1bcea9f9cf6 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 29 Mar 2024 15:43:20 +0530 Subject: [PATCH 3/6] add tests Signed-off-by: Sahil Kumar --- .../melos/test/commands/bootstrap_test.dart | 148 +++++++++++++++++- 1 file changed, 146 insertions(+), 2 deletions(-) diff --git a/packages/melos/test/commands/bootstrap_test.dart b/packages/melos/test/commands/bootstrap_test.dart index 488bff50e..142dda4be 100644 --- a/packages/melos/test/commands/bootstrap_test.dart +++ b/packages/melos/test/commands/bootstrap_test.dart @@ -804,11 +804,155 @@ Generating IntelliJ IDE files... timeout: const Timeout(Duration(days: 2)), ); }); + + group('melos bs --skip-linking', () { + test('should skip package linking', () async { + final workspaceDir = await createTemporaryWorkspace(); + await createProject( + workspaceDir, + const PubSpec(name: 'a'), + ); + + final logger = TestLogger(); + final config = await MelosWorkspaceConfig.fromWorkspaceRoot(workspaceDir); + final melos = Melos(logger: logger, config: config); + + await runMelosBootstrap(melos, logger, skipLinking: true); + + expect( + logger.output, + ignoringAnsii( + ''' +melos bootstrap + └> ${workspaceDir.path} + +Generating IntelliJ IDE files... + > SUCCESS + + -> 1 packages bootstrapped +''', + ), + ); + }); + + test( + 'should work fine with environment config', + () async { + final workspaceDir = await createTemporaryWorkspace( + configBuilder: (path) => MelosWorkspaceConfig( + name: 'Melos', + packages: [ + createGlob('packages/**', currentDirectoryPath: path), + ], + commands: CommandConfigs( + bootstrap: BootstrapCommandConfigs( + environment: Environment( + VersionConstraint.parse('>=2.18.0 <3.0.0'), + {'flutter': '>=2.18.0 <3.0.0'}, + ), + ), + ), + path: path, + ), + ); + + await createProject( + workspaceDir, + const PubSpec(name: 'a'), + ); + + final logger = TestLogger(); + final config = + await MelosWorkspaceConfig.fromWorkspaceRoot(workspaceDir); + final melos = Melos(logger: logger, config: config); + + await runMelosBootstrap(melos, logger, skipLinking: true); + + expect( + logger.output, + ignoringAnsii( + ''' +melos bootstrap + └> ${workspaceDir.path} + +Updating common dependencies in workspace packages... + ✓ a + └> Updated environment + > SUCCESS + +Generating IntelliJ IDE files... + > SUCCESS + + -> 1 packages bootstrapped +''', + ), + ); + }, + ); + }); + + test( + 'can skip package linking if --skip-linking is enabled', + () async { + final workspaceDir = await createTemporaryWorkspace( + configBuilder: (path) => MelosWorkspaceConfig( + name: 'Melos', + packages: [ + createGlob('packages/**', currentDirectoryPath: path), + ], + commands: CommandConfigs( + bootstrap: BootstrapCommandConfigs( + environment: Environment( + VersionConstraint.parse('>=2.18.0 <3.0.0'), + {'flutter': '>=2.18.0 <3.0.0'}, + ), + ), + ), + path: path, + ), + ); + + await createProject( + workspaceDir, + const PubSpec(name: 'a'), + ); + + final logger = TestLogger(); + final config = await MelosWorkspaceConfig.fromWorkspaceRoot(workspaceDir); + final melos = Melos(logger: logger, config: config); + + await runMelosBootstrap(melos, logger, skipLinking: true); + + expect( + logger.output, + ignoringAnsii( + ''' +melos bootstrap + └> ${workspaceDir.path} + +Updating common dependencies in workspace packages... + ✓ a + └> Updated environment + > SUCCESS + +Generating IntelliJ IDE files... + > SUCCESS + + -> 1 packages bootstrapped +''', + ), + ); + }, + ); } -Future runMelosBootstrap(Melos melos, TestLogger logger) async { +Future runMelosBootstrap( + Melos melos, + TestLogger logger, { + bool skipLinking = false, +}) async { try { - await melos.bootstrap(); + await melos.bootstrap(skipLinking: skipLinking); } on BootstrapException { // ignore: avoid_print print(logger.output); From f1815f8f9fdf5feca35963279bed542223805e4a Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 29 Mar 2024 15:50:48 +0530 Subject: [PATCH 4/6] remove extra test Signed-off-by: Sahil Kumar --- .../melos/test/commands/bootstrap_test.dart | 64 +------------------ 1 file changed, 3 insertions(+), 61 deletions(-) diff --git a/packages/melos/test/commands/bootstrap_test.dart b/packages/melos/test/commands/bootstrap_test.dart index 142dda4be..f995aa5f9 100644 --- a/packages/melos/test/commands/bootstrap_test.dart +++ b/packages/melos/test/commands/bootstrap_test.dart @@ -835,65 +835,7 @@ Generating IntelliJ IDE files... ); }); - test( - 'should work fine with environment config', - () async { - final workspaceDir = await createTemporaryWorkspace( - configBuilder: (path) => MelosWorkspaceConfig( - name: 'Melos', - packages: [ - createGlob('packages/**', currentDirectoryPath: path), - ], - commands: CommandConfigs( - bootstrap: BootstrapCommandConfigs( - environment: Environment( - VersionConstraint.parse('>=2.18.0 <3.0.0'), - {'flutter': '>=2.18.0 <3.0.0'}, - ), - ), - ), - path: path, - ), - ); - - await createProject( - workspaceDir, - const PubSpec(name: 'a'), - ); - - final logger = TestLogger(); - final config = - await MelosWorkspaceConfig.fromWorkspaceRoot(workspaceDir); - final melos = Melos(logger: logger, config: config); - - await runMelosBootstrap(melos, logger, skipLinking: true); - - expect( - logger.output, - ignoringAnsii( - ''' -melos bootstrap - └> ${workspaceDir.path} - -Updating common dependencies in workspace packages... - ✓ a - └> Updated environment - > SUCCESS - -Generating IntelliJ IDE files... - > SUCCESS - - -> 1 packages bootstrapped -''', - ), - ); - }, - ); - }); - - test( - 'can skip package linking if --skip-linking is enabled', - () async { + test('should work fine with environment config', () async { final workspaceDir = await createTemporaryWorkspace( configBuilder: (path) => MelosWorkspaceConfig( name: 'Melos', @@ -942,8 +884,8 @@ Generating IntelliJ IDE files... ''', ), ); - }, - ); + }); + }); } Future runMelosBootstrap( From c1f64269258a1571504c12fb83fc632f9bdbdb44 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 29 Mar 2024 15:55:40 +0530 Subject: [PATCH 5/6] update bootstrap docs Signed-off-by: Sahil Kumar --- docs/commands/bootstrap.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/commands/bootstrap.mdx b/docs/commands/bootstrap.mdx index 55d98ae05..f4cbad3ec 100644 --- a/docs/commands/bootstrap.mdx +++ b/docs/commands/bootstrap.mdx @@ -90,6 +90,7 @@ melos bootstrap --diff="main" - 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 `--skip-linking` flag is used to skip the local linking for workspace packages. In addition to the above flags, the `melos bootstrap` command supports a few different flags that can be defined in From 8eea9d894adbcc0a942bbfb7d1eaec0e7c736993 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 29 Mar 2024 15:58:16 +0530 Subject: [PATCH 6/6] fix typo Signed-off-by: Sahil Kumar --- docs/commands/bootstrap.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/commands/bootstrap.mdx b/docs/commands/bootstrap.mdx index f4cbad3ec..1d12e5ae7 100644 --- a/docs/commands/bootstrap.mdx +++ b/docs/commands/bootstrap.mdx @@ -90,7 +90,7 @@ melos bootstrap --diff="main" - 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 `--skip-linking` flag is used to skip the local linking for workspace packages. +- 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