Skip to content

Commit

Permalink
feat: add support for melos bs --skip-linking (#684)
Browse files Browse the repository at this point in the history
  • Loading branch information
xsahil03x authored Mar 29, 2024
1 parent 16fc890 commit 699fedc
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 20 deletions.
1 change: 1 addition & 0 deletions docs/commands/bootstrap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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 of workspace packages.


In addition to the above flags, the `melos bootstrap` command supports a few different flags that can be defined in
Expand Down
6 changes: 6 additions & 0 deletions packages/melos/lib/src/command_runner/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
);
}
}
48 changes: 30 additions & 18 deletions packages/melos/lib/src/commands/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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.',
Expand All @@ -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(
Expand All @@ -54,34 +56,44 @@ mixin _BootstrapMixin on _CleanMixin {
devDependencies: bootstrapCommandConfig.devDependencies,
);
}).drain<void>();

logger
..child(successLabel, prefix: '> ')
..newLine();
}

await _linkPackagesWithPubspecOverrides(
workspace,
enforceLockfile: enforceLockfile,
noExample: noExample,
);
if (!skipLinking) {
logger.log(
'Running "$pubCommandForLogging" in workspace packages...',
);

await _linkPackagesWithPubspecOverrides(
workspace,
enforceLockfile: enforceLockfile,
noExample: noExample,
);

logger
..child(successLabel, prefix: '> ')
..newLine();
}
} on BootstrapException catch (exception) {
_logBootstrapException(exception, workspace);
rethrow;
}

logger.child(successLabel, prefix: '> ');

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',
);
},
);
}
Expand Down Expand Up @@ -282,7 +294,7 @@ mixin _BootstrapMixin on _CleanMixin {
];
if (message.isNotEmpty) {
logger
.child(packageNameStyle(package.name), prefix: '')
.child(packageNameStyle(package.name), prefix: '$checkLabel ')
.child(message.join('\n'));
}
}
Expand Down
90 changes: 88 additions & 2 deletions packages/melos/test/commands/bootstrap_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -804,11 +804,97 @@ 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
''',
),
);
});
});
}

Future<void> runMelosBootstrap(Melos melos, TestLogger logger) async {
Future<void> 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);
Expand Down

0 comments on commit 699fedc

Please sign in to comment.