Skip to content

Commit

Permalink
feat: add support for Dart/Flutter SDK at custom sdkPath (#288)
Browse files Browse the repository at this point in the history
  • Loading branch information
acoutts authored May 9, 2022
1 parent dddf8ff commit 740050c
Show file tree
Hide file tree
Showing 29 changed files with 655 additions and 83 deletions.
18 changes: 18 additions & 0 deletions docs/configuration/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@ Supported hosts:
repository: https://github.com/invertase/melos
```

## `sdkPath`

Path to the Dart/Flutter SDK that should be used.

Relative paths are resolved relative to the `melos.yaml` file.

To use the system-wide SDK, provide the special value "auto".

If the SDK path is specified though multiple mechanisms, the precedence from highest to lowest is:

1. `--sdk-path` global command line option
2. `MELOS_SDK_PATH` environment variable
3. `sdkPath` in `melos.yaml`

```yaml
sdkPath: .fvm/flutter_sdk
```

## `packages`

> required
Expand Down
7 changes: 6 additions & 1 deletion docs/environment-variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@ Note, this 'parent package' functionality only currently works when the 'child p

### `MELOS_PACKAGES`

Define a comma delimited list of package names that Melos should focus on. This bypasses all filtering flags if defined.
Define a comma delimited list of package names that Melos should focus on. This bypasses all filtering flags if defined.

### `MELOS_SDK_PATH`

The path to the Dart/Flutter SDK to use. This environment variable has precedence over the `sdkPath`
option in `melos.yaml`, but is overridden by the command line option `--sdk-path`.
1 change: 1 addition & 0 deletions packages/melos/lib/melos.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export 'src/commands/runner.dart'
ListOutputKind;
export 'src/common/exception.dart' show CancelledException, MelosException;
export 'src/common/validation.dart' show MelosConfigException;
export 'src/global_options.dart' show GlobalOptions;
export 'src/package.dart' show Package, PackageFilter, PackageMap, PackageType;
export 'src/workspace.dart' show IdeWorkspace, MelosWorkspace;
export 'src/workspace_configs.dart'
Expand Down
13 changes: 11 additions & 2 deletions packages/melos/lib/src/command_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import 'package:args/args.dart';
import 'package:args/command_runner.dart';

import 'command_runner/bootstrap.dart';
import 'command_runner/clean.dart';
import 'command_runner/exec.dart';
Expand All @@ -35,7 +36,7 @@ import 'workspace_configs.dart';
/// ```dart
/// final melos = MelosCommandRunner();
///
/// await melos.run(['boostrap']);
/// await melos.run(['bootstrap']);
/// ```
class MelosCommandRunner extends CommandRunner<void> {
MelosCommandRunner(MelosWorkspaceConfig config)
Expand All @@ -45,10 +46,18 @@ class MelosCommandRunner extends CommandRunner<void> {
usageLineLength: terminalWidth,
) {
argParser.addFlag(
'verbose',
globalOptionVerbose,
negatable: false,
help: 'Enable verbose logging.',
);
argParser.addOption(
globalOptionSdkPath,
help: 'Path to the Dart/Flutter SDK that should be used. This command '
'line option has precedence over the `sdkPath` option in the '
'`melos.yaml` configuration file and the `MELOS_SDK_PATH` '
'environment variable. To use the system-wide SDK, provide '
'the special value "auto".',
);

addCommand(ExecCommand(config));
addCommand(BootstrapCommand(config));
Expand Down
14 changes: 12 additions & 2 deletions packages/melos/lib/src/command_runner/base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:cli_util/cli_logging.dart';

import '../common/glob.dart';
import '../common/utils.dart';
import '../global_options.dart';
import '../package.dart';
import '../workspace_configs.dart';

Expand All @@ -12,8 +13,10 @@ abstract class MelosCommand extends Command<void> {

final MelosWorkspaceConfig config;

Logger? get logger =>
globalResults!['verbose'] as bool ? Logger.verbose() : Logger.standard();
/// The global Melos options parsed from the command line.
late final global = _parseGlobalOptions();

Logger? get logger => global.verbose ? Logger.verbose() : Logger.standard();

/// The `melos.yaml` configuration for this command.
/// see [ArgParser.allowTrailingOptions]
Expand All @@ -26,6 +29,13 @@ abstract class MelosCommand extends Command<void> {
allowTrailingOptions: allowTrailingOptions,
);

GlobalOptions _parseGlobalOptions() {
return GlobalOptions(
verbose: globalResults![globalOptionVerbose]! as bool,
sdkPath: globalResults![globalOptionSdkPath] as String?,
);
}

void setupPackageFilterParser() {
argParser.addFlag(
filterOptionPrivate,
Expand Down
1 change: 1 addition & 0 deletions packages/melos/lib/src/command_runner/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class BootstrapCommand extends MelosCommand {
final melos = Melos(logger: logger, config: config);

return melos.bootstrap(
global: global,
filter: parsePackageFilter(config.path),
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/melos/lib/src/command_runner/clean.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class CleanCommand extends MelosCommand {
final melos = Melos(logger: logger, config: config);

await melos.clean(
global: global,
filter: parsePackageFilter(config.path),
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/melos/lib/src/command_runner/exec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class ExecCommand extends MelosCommand {
execArgs,
concurrency: concurrency,
failFast: failFast,
global: global,
filter: packageFilter,
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/melos/lib/src/command_runner/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class ListCommand extends MelosCommand {

return melos.list(
long: long,
global: global,
filter: parsePackageFilter(config.path),
relativePaths: relative,
kind: kind,
Expand Down
1 change: 1 addition & 0 deletions packages/melos/lib/src/command_runner/publish.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class PublishCommand extends MelosCommand {
final filter = parsePackageFilter(config.path);

return melos.publish(
global: global,
filter: filter,
dryRun: dryRun,
force: yes,
Expand Down
1 change: 1 addition & 0 deletions packages/melos/lib/src/command_runner/version.dart
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class VersionCommand extends MelosCommand {
}

await melos.version(
global: global,
filter: parsePackageFilter(config.path),
force: force,
gitTag: tag,
Expand Down
31 changes: 20 additions & 11 deletions packages/melos/lib/src/commands/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ final _warningLabel = AnsiStyles.yellow('WARNING');
final _checkLabel = AnsiStyles.greenBright('✓');

mixin _BootstrapMixin on _CleanMixin {
Future<void> bootstrap({PackageFilter? filter}) async {
final workspace = await createWorkspace(filter: filter);
Future<void> bootstrap({GlobalOptions? global, PackageFilter? filter}) async {
final workspace = await createWorkspace(global: global, filter: filter);

return _runLifecycle(
workspace,
ScriptLifecycle.bootstrap,
() async {
final pubCommandForLogging =
"${workspace.isFlutterWorkspace ? "flutter " : "dart "}pub get";
final pubCommandForLogging = [
...pubCommandExecArgs(
useFlutter: workspace.isFlutterWorkspace,
workspace: workspace,
),
'get'
].join(' ');

logger?.stdout(AnsiStyles.yellow.bold('melos bootstrap'));
logger?.stdout(' └> ${AnsiStyles.cyan.bold(workspace.path)}\n');
Expand Down Expand Up @@ -61,7 +66,7 @@ mixin _BootstrapMixin on _CleanMixin {
Future<void> _linkPackagesWithPubspecOverrides(
MelosWorkspace workspace,
) async {
if (!isPubspecOverridesSupported) {
if (!workspace.isPubspecOverridesSupported) {
logger?.stderr(
'$_warningLabel: Dart 2.17.0 or greater is required to use Melos with '
'pubspec overrides.',
Expand All @@ -88,7 +93,7 @@ mixin _BootstrapMixin on _CleanMixin {
);
},
parallelism: workspace.config.commands.bootstrap.runPubGetInParallel &&
canRunPubGetConcurrently
workspace.canRunPubGetConcurrently
? null
: 1,
).drain<void>();
Expand Down Expand Up @@ -167,7 +172,7 @@ mixin _BootstrapMixin on _CleanMixin {
return package;
},
parallelism: workspace.config.commands.bootstrap.runPubGetInParallel &&
canRunPubGetConcurrently
workspace.canRunPubGetConcurrently
? null
: 1,
);
Expand All @@ -177,10 +182,14 @@ mixin _BootstrapMixin on _CleanMixin {
Package package, {
bool inTemporaryProject = false,
}) async {
final pubGetArgs = ['pub', 'get'];
final execArgs = package.isFlutterPackage
? ['flutter', ...pubGetArgs]
: [if (utils.isPubSubcommand()) 'dart', ...pubGetArgs];
final execArgs = [
...pubCommandExecArgs(
useFlutter: package.isFlutterPackage,
workspace: workspace,
),
'get',
];

final executable = currentPlatform.isWindows ? 'cmd' : '/bin/sh';
final packagePath = inTemporaryProject
? join(workspace.melosToolPath, package.pathRelativeToWorkspace)
Expand Down
4 changes: 2 additions & 2 deletions packages/melos/lib/src/commands/clean.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
part of 'runner.dart';

mixin _CleanMixin on _Melos {
Future<void> clean({PackageFilter? filter}) async {
final workspace = await createWorkspace(filter: filter);
Future<void> clean({GlobalOptions? global, PackageFilter? filter}) async {
final workspace = await createWorkspace(global: global, filter: filter);

return _runLifecycle(
workspace,
Expand Down
11 changes: 8 additions & 3 deletions packages/melos/lib/src/commands/exec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ part of 'runner.dart';
mixin _ExecMixin on _Melos {
Future<void> exec(
List<String> execArgs, {
GlobalOptions? global,
PackageFilter? filter,
int concurrency = 5,
bool failFast = false,
}) async {
final workspace = await createWorkspace(filter: filter);
final workspace = await createWorkspace(global: global, filter: filter);
final packages = workspace.filteredPackages.values;

await _execForAllPackages(
Expand All @@ -34,6 +35,9 @@ mixin _ExecMixin on _Melos {
'MELOS_PACKAGE_VERSION': (package.version).toString(),
'MELOS_PACKAGE_PATH': package.path,
'MELOS_ROOT_PATH': workspace.path,
if (workspace.sdkPath != null) envKeyMelosSdkPath: workspace.sdkPath!,
if (workspace.childProcessPath != null)
'PATH': workspace.childProcessPath!,
};

// TODO what if it's not called 'example'?
Expand Down Expand Up @@ -66,8 +70,9 @@ mixin _ExecMixin on _Melos {
environment.remove('MELOS_PARENT_PACKAGE_NAME');
environment.remove('MELOS_PARENT_PACKAGE_VERSION');
environment.remove('MELOS_PARENT_PACKAGE_PATH');
environment.remove('MELOS_PACKAGES');
environment.remove('MELOS_TERMINAL_WIDTH');
environment.remove(envKeyMelosPackages);
environment.remove(envKeyMelosSdkPath);
environment.remove(envKeyMelosTerminalWidth);
}

return startProcess(
Expand Down
3 changes: 2 additions & 1 deletion packages/melos/lib/src/commands/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ enum ListOutputKind { json, parsable, graph, gviz, column }

mixin _ListMixin on _Melos {
Future<void> list({
GlobalOptions? global,
bool long = false,
bool relativePaths = false,
PackageFilter? filter,
ListOutputKind kind = ListOutputKind.column,
}) async {
final workspace = await createWorkspace(filter: filter);
final workspace = await createWorkspace(global: global, filter: filter);

switch (kind) {
case ListOutputKind.graph:
Expand Down
6 changes: 3 additions & 3 deletions packages/melos/lib/src/commands/publish.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ part of 'runner.dart';

mixin _PublishMixin on _ExecMixin {
Future<void> publish({
GlobalOptions? global,
PackageFilter? filter,
bool dryRun = true,
bool gitTagVersion = true,
// yes
bool force = false,
}) async {
final workspace = await createWorkspace(filter: filter);
final workspace = await createWorkspace(global: global, filter: filter);

logger?.stdout(
AnsiStyles.yellow.bold('melos publish${dryRun ? " --dry-run" : ''}'),
Expand Down Expand Up @@ -142,8 +143,7 @@ mixin _PublishMixin on _ExecMixin {
'Publishing ${unpublishedPackages.length} packages to registry:',
);
final execArgs = [
if (isPubSubcommand()) 'dart',
'pub',
...pubCommandExecArgs(useFlutter: false, workspace: workspace),
'publish',
];

Expand Down
26 changes: 17 additions & 9 deletions packages/melos/lib/src/commands/run.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ part of 'runner.dart';
mixin _RunMixin on _Melos {
@override
Future<void> run({
GlobalOptions? global,
String? scriptName,
bool noSelect = false,
List<String> extraArgs = const [],
Expand All @@ -22,6 +23,7 @@ mixin _RunMixin on _Melos {
final exitCode = await _runScript(
script,
config,
global: global,
noSelect: noSelect,
extraArgs: extraArgs,
);
Expand Down Expand Up @@ -67,24 +69,30 @@ mixin _RunMixin on _Melos {
Future<int> _runScript(
Script script,
MelosWorkspaceConfig config, {
GlobalOptions? global,
required bool noSelect,
List<String> extraArgs = const [],
}) async {
final workspace = await MelosWorkspace.fromConfig(
config,
global: global,
filter: script.filter?.copyWithUpdatedIgnore([
...script.filter!.ignore,
...config.ignore,
]),
logger: logger,
)
..validate();

final environment = {
'MELOS_ROOT_PATH': config.path,
if (workspace.sdkPath != null) envKeyMelosSdkPath: workspace.sdkPath!,
if (workspace.childProcessPath != null)
'PATH': workspace.childProcessPath!,
...script.env,
};

if (script.filter != null) {
final workspace = await MelosWorkspace.fromConfig(
config,
filter: script.filter!.copyWithUpdatedIgnore([
...script.filter!.ignore,
...config.ignore,
]),
logger: logger,
);

final packages = workspace.filteredPackages.values.toList();

var choices = packages.map((e) => AnsiStyles.cyan(e.name)).toList();
Expand Down
Loading

0 comments on commit 740050c

Please sign in to comment.