Skip to content

Commit

Permalink
Executes scripts with same dart/melos combination as currently running
Browse files Browse the repository at this point in the history
  • Loading branch information
Boris Spinner committed Oct 29, 2024
1 parent 9681481 commit daa7230
Showing 1 changed file with 44 additions and 1 deletion.
45 changes: 44 additions & 1 deletion packages/melos/lib/src/scripts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:collection';
import 'package:collection/collection.dart';
import 'package:meta/meta.dart';

import 'common/platform.dart';
import 'common/utils.dart';
import 'common/validation.dart';
import 'package.dart';
Expand Down Expand Up @@ -318,7 +319,8 @@ class Script {
if (exec == null) {
return scriptCommand;
} else {
final execCommand = ['melos', 'exec'];
/// `dart melos.dart exec` or `melos exec` with absolute paths
final execCommand = [..._determineMelosExecutablePaths(), 'exec'];

if (exec.concurrency != null) {
execCommand.addAll(['--concurrency', '${exec.concurrency}']);
Expand All @@ -338,6 +340,47 @@ class Script {
}
}

/// Identifies path of currently running melos and reuses it for nested script execution.
///
/// Starting melos by just calling `melos` via shell
/// would use the first found binary found in `$PATH`,
/// i.e. usually the globally activated version. If there is one.
///
/// This can cause issues when melos is started with `dart run melos`,
/// which will prefer the melos version specified via (dev_)dependencies.
/// So the initially started melos binary/script and the one used for melos script execution
/// could differ.
///
/// Besides ensuring starting the same melos as currently running,
/// this furthermore enables use of melos in environments
/// where `.pub-cache/bin` should/must not be put in `$PATH`.
List<String> _determineMelosExecutablePaths() {
final currentExecutablePathString = currentPlatform.resolvedExecutable;
final currentExecutablePathUri = Uri.file(currentExecutablePathString);
if (!currentExecutablePathUri.isAbsolute) {
throw 'Got invalid, unsupported or relative path to running executable. Expected absolute path.';
}

final currentScriptPathUri = currentPlatform.script;
final currentScriptPathString = currentScriptPathUri.toFilePath();
if (!currentScriptPathString.isEmpty && !currentScriptPathUri.isAbsolute) {
throw 'Got invalid, unsupported or relative path to melos. Expected absolute path.';
}

// Determine if melos is running as script or compiled binary
final isScriptPathAvailable = !currentScriptPathString.isEmpty;
final isCompiledMelosRunning =
currentExecutablePathUri == currentScriptPathUri;

if (!isScriptPathAvailable || isCompiledMelosRunning) {
return [currentExecutablePathString];
}

// currentExecutablePathString => path to dart binary
// currentScriptPathUri => path to melos.dart
return [currentExecutablePathString, currentScriptPathString];
}

/// Validates the script. Throws a [MelosConfigException] if the script is
/// invalid.
void validate() {
Expand Down

0 comments on commit daa7230

Please sign in to comment.