dart install and dart remote run with descriptors
Bug: https://github.com/dart-lang/sdk/issues/62123 Change-Id: I16e4fc0c20b9728e8357b6f67540aec73b2804ce Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/477560 Reviewed-by: Daco Harkes <dacoharkes@google.com> Reviewed-by: Jonas Jensen <jonasfj@google.com> Commit-Queue: Sigurd Meldgaard <sigurdm@google.com>
This commit is contained in:
committed by
Commit Queue
parent
71250eddc2
commit
528d4faff6
@@ -2,6 +2,7 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dartdev/src/commands/build.dart';
|
||||
@@ -12,6 +13,7 @@ import 'package:front_end/src/api_prototype/compiler_options.dart'
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:pub/pub.dart';
|
||||
import 'package:pub_formats/pub_formats.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
import '../core.dart';
|
||||
|
||||
@@ -27,11 +29,20 @@ executables.
|
||||
|
||||
If the same package has been previously installed, it will be overwritten.
|
||||
|
||||
You can specify three different values for the <package> argument:
|
||||
1. A package name. This will install the package from pub.dev. (hosted)
|
||||
The [version-constraint] argument can only be passed to 'hosted'.
|
||||
2. A git url. This will install the package from a git repository. (git)
|
||||
3. A path on your machine. This will install the package from that path. (path)''';
|
||||
You can specify a package to install from pub.dev, a git repository, or a
|
||||
local path using the `<package>[@<descriptor>]` syntax.
|
||||
|
||||
The `@<descriptor>` can be a version constraint (for hosted packages) or a
|
||||
pub descriptor (consistent with pubspec.yaml).
|
||||
|
||||
Examples:
|
||||
dart install <pkg>
|
||||
dart install <pkg>@^3.0.0
|
||||
dart install '<pkg>@{hosted: https://pub.dev, version: ^3.0.0}'
|
||||
dart install '<pkg>@{git: {url: https://github.com/<owner>/<repo>, path: <path>}}'
|
||||
dart install '<pkg>@{path: /path/to/<pkg>}'
|
||||
|
||||
See https://dart.dev/go/pub-descriptors for more details.''';
|
||||
static const int genericErrorExitCode = 255;
|
||||
|
||||
static const gitRefOption = 'git-ref';
|
||||
@@ -40,7 +51,7 @@ You can specify three different values for the <package> argument:
|
||||
@override
|
||||
String get invocation {
|
||||
final superNoArguments = super.invocation.replaceAll(' [arguments]', '');
|
||||
return '$superNoArguments <package> [version-constraint]';
|
||||
return '$superNoArguments <package>[@<descriptor>]';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -53,6 +64,7 @@ You can specify three different values for the <package> argument:
|
||||
help:
|
||||
'Path of git package in repository. '
|
||||
'Only applies when using a git url for <package>.',
|
||||
hide: true,
|
||||
);
|
||||
|
||||
argParser.addOption(
|
||||
@@ -60,6 +72,7 @@ You can specify three different values for the <package> argument:
|
||||
help:
|
||||
'Git branch or commit to be retrieved. '
|
||||
'Only applies when using a git url for <package>.',
|
||||
hide: true,
|
||||
);
|
||||
|
||||
argParser.addFlag(
|
||||
@@ -74,6 +87,7 @@ You can specify three different values for the <package> argument:
|
||||
help:
|
||||
'A custom pub server URL for the package. '
|
||||
'Only applies when using a package name for <package>.',
|
||||
hide: true,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -95,71 +109,99 @@ You can specify three different values for the <package> argument:
|
||||
return arg;
|
||||
}
|
||||
|
||||
final argument = readArg('No package source given.');
|
||||
final sourceKind = _soureKindFromArgument(argument);
|
||||
|
||||
final firstArgument = readArg('Specify a package to install.');
|
||||
final gitPath = argResults.option(gitPathOption);
|
||||
var gitRef = argResults.option(gitRefOption);
|
||||
if (sourceKind != RemoteSourceKind.git &&
|
||||
(gitPath != null || gitRef != null)) {
|
||||
usageException(
|
||||
'Options `--$gitPathOption` and `--$gitRefOption` '
|
||||
'can only be used with a git source.',
|
||||
|
||||
final atIndex = firstArgument.indexOf('@');
|
||||
if (firstArgument.startsWith('git@') || atIndex == -1) {
|
||||
final sourceKind = _sourceKindFromArgument(firstArgument);
|
||||
final versionConstraint = sourceKind == RemoteSourceKind.hosted
|
||||
? (args.isEmpty ? 'any' : readArg())
|
||||
: null;
|
||||
|
||||
if (sourceKind != RemoteSourceKind.git &&
|
||||
(gitPath != null || gitRef != null)) {
|
||||
usageException(
|
||||
'Options `--$gitPathOption` and `--$gitRefOption` '
|
||||
'can only be used with a git source.',
|
||||
);
|
||||
}
|
||||
|
||||
final hostedUrl = argResults.option('hosted-url');
|
||||
if (sourceKind != RemoteSourceKind.hosted && hostedUrl != null) {
|
||||
usageException(
|
||||
'Option `--hosted-url` can only be used with a hosted source.',
|
||||
);
|
||||
}
|
||||
|
||||
if (args.isNotEmpty) {
|
||||
usageException(
|
||||
'Too many arguments, did not expect "${args.join(' ')}"',
|
||||
);
|
||||
}
|
||||
return NonDescriptorInstallCommandParsedArguments(
|
||||
source: firstArgument,
|
||||
sourceKind: sourceKind,
|
||||
versionConstraint: versionConstraint,
|
||||
gitPath: gitPath,
|
||||
gitRef: gitRef,
|
||||
hostedUrl: hostedUrl,
|
||||
overwrite: overwrite,
|
||||
);
|
||||
} else {
|
||||
if (gitPath != null || gitRef != null) {
|
||||
usageException(
|
||||
'Options `--$gitPathOption` and `--$gitRefOption` '
|
||||
'cannot be used with the @ descriptor syntax.',
|
||||
);
|
||||
}
|
||||
final Object? descriptor;
|
||||
final packageName = firstArgument.substring(0, atIndex);
|
||||
final descriptorString = firstArgument.substring(atIndex + 1);
|
||||
try {
|
||||
descriptor = loadYaml(descriptorString);
|
||||
} on FormatException catch (e) {
|
||||
usageException(
|
||||
'Could not parse (what comes after @) "$descriptorString": $e',
|
||||
);
|
||||
}
|
||||
return DescriptorInstallCommandParsedArguments(
|
||||
packageName: packageName,
|
||||
descriptor: descriptor,
|
||||
overwrite: overwrite,
|
||||
);
|
||||
}
|
||||
|
||||
final hostedUrl = argResults.option('hosted-url');
|
||||
if (sourceKind != RemoteSourceKind.hosted && hostedUrl != null) {
|
||||
usageException(
|
||||
'Option `--hosted-url` can only be used with a hosted source.',
|
||||
);
|
||||
}
|
||||
|
||||
String? versionConstraint;
|
||||
switch (sourceKind) {
|
||||
case RemoteSourceKind.git:
|
||||
case RemoteSourceKind.path:
|
||||
break;
|
||||
case RemoteSourceKind.hosted:
|
||||
versionConstraint = args.isEmpty ? 'any' : readArg();
|
||||
}
|
||||
if (args.isNotEmpty) {
|
||||
usageException('Too many arguments, did not expect "${args.join(' ')}"');
|
||||
}
|
||||
return InstallCommandParsedArguments(
|
||||
source: argument,
|
||||
sourceKind: sourceKind,
|
||||
versionConstraint: versionConstraint,
|
||||
gitPath: gitPath,
|
||||
gitRef: gitRef,
|
||||
hostedUrl: hostedUrl,
|
||||
overwrite: overwrite,
|
||||
);
|
||||
}
|
||||
|
||||
Future<String> _findPackageName(
|
||||
InstallCommandParsedArguments parsedArgs,
|
||||
) async {
|
||||
switch (parsedArgs.sourceKind) {
|
||||
case RemoteSourceKind.git:
|
||||
return await getPackageNameFromGitRepo(
|
||||
parsedArgs.source,
|
||||
ref: parsedArgs.gitRef,
|
||||
path: parsedArgs.gitPath,
|
||||
relativeTo: Directory.current.path,
|
||||
tagPattern: null,
|
||||
);
|
||||
case RemoteSourceKind.hosted:
|
||||
return parsedArgs.source;
|
||||
case RemoteSourceKind.path:
|
||||
final pubspecFile = File.fromUri(
|
||||
Directory(parsedArgs.source).absolute.uri.resolve('pubspec.yaml'),
|
||||
);
|
||||
if (!await pubspecFile.exists()) {
|
||||
usageException('No pubspec found in ${pubspecFile.path}.');
|
||||
switch (parsedArgs) {
|
||||
case DescriptorInstallCommandParsedArguments _:
|
||||
return parsedArgs.packageName;
|
||||
case NonDescriptorInstallCommandParsedArguments _:
|
||||
switch (parsedArgs.sourceKind) {
|
||||
case RemoteSourceKind.git:
|
||||
return await getPackageNameFromGitRepo(
|
||||
parsedArgs.source,
|
||||
ref: parsedArgs.gitRef,
|
||||
path: parsedArgs.gitPath,
|
||||
relativeTo: Directory.current.path,
|
||||
tagPattern: null,
|
||||
);
|
||||
case RemoteSourceKind.hosted:
|
||||
return parsedArgs.source;
|
||||
case RemoteSourceKind.path:
|
||||
final pubspecFile = File.fromUri(
|
||||
Directory(parsedArgs.source).absolute.uri.resolve('pubspec.yaml'),
|
||||
);
|
||||
if (!await pubspecFile.exists()) {
|
||||
usageException('No pubspec found in ${pubspecFile.path}.');
|
||||
}
|
||||
final pubspecYaml = PubspecYamlFile.loadSync(pubspecFile);
|
||||
return pubspecYaml.name;
|
||||
}
|
||||
final pubspecYaml = PubspecYamlFile.loadSync(pubspecFile);
|
||||
return pubspecYaml.name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,34 +222,35 @@ You can specify three different values for the <package> argument:
|
||||
final tempPubspec = File.fromUri(
|
||||
helperPackageDir.uri.resolve('pubspec.yaml'),
|
||||
);
|
||||
final helperPackagePubspec = PubspecYamlFileSyntax(
|
||||
name: _helperPackageName,
|
||||
environment: EnvironmentSyntax(
|
||||
sdk: '^${Platform.version.split(' ').first}',
|
||||
),
|
||||
dependencies: {
|
||||
packageName: switch (parsedArgs.sourceKind) {
|
||||
RemoteSourceKind.git => GitDependencySourceSyntax(
|
||||
git: GitSyntax(
|
||||
url: parsedArgs.source,
|
||||
path$: parsedArgs.gitPath,
|
||||
ref: parsedArgs.gitRef,
|
||||
),
|
||||
),
|
||||
RemoteSourceKind.hosted => HostedDependencySourceSyntax(
|
||||
hosted: parsedArgs.hostedUrl,
|
||||
version: parsedArgs.versionConstraint!,
|
||||
),
|
||||
RemoteSourceKind.path =>
|
||||
// Re-resolve dependencies for path activate, behave like it would work
|
||||
// for users of the package if the activate via hosted or git.
|
||||
PathDependencySourceSyntax(
|
||||
path$: Directory(parsedArgs.source).absolute.path,
|
||||
),
|
||||
final descriptor = switch (parsedArgs) {
|
||||
DescriptorInstallCommandParsedArguments _ => parsedArgs.descriptor,
|
||||
NonDescriptorInstallCommandParsedArguments _ =>
|
||||
switch (parsedArgs.sourceKind) {
|
||||
RemoteSourceKind.git => {
|
||||
'git': {
|
||||
'url': parsedArgs.source,
|
||||
if (parsedArgs.gitPath != null) 'path': parsedArgs.gitPath!,
|
||||
if (parsedArgs.gitRef != null) 'ref': parsedArgs.gitRef!,
|
||||
},
|
||||
},
|
||||
RemoteSourceKind.hosted => {
|
||||
'hosted': ?parsedArgs.hostedUrl,
|
||||
'version': parsedArgs.versionConstraint!,
|
||||
},
|
||||
RemoteSourceKind.path => {
|
||||
'path': Directory(parsedArgs.source).absolute.path,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
final helperPackagePubspec = <String, Object?>{
|
||||
'name': _helperPackageName,
|
||||
'environment': {'sdk': '^${Platform.version.split(' ').first}'},
|
||||
'dependencies': {packageName: descriptor},
|
||||
};
|
||||
tempPubspec.writeAsStringSync(
|
||||
JsonEncoder.withIndent(' ').convert(helperPackagePubspec),
|
||||
);
|
||||
helperPackagePubspec.writeSync(tempPubspec);
|
||||
}
|
||||
|
||||
static const _helperPackageName = 'dart_install_helper_package';
|
||||
@@ -317,42 +360,27 @@ You can specify three different values for the <package> argument:
|
||||
}
|
||||
|
||||
static AppBundleDirectory selectAppBundleDirectory(
|
||||
InstallCommandParsedArguments parsedArgs,
|
||||
String packageName,
|
||||
Directory helperPackageDir,
|
||||
File helperPackageLockFile,
|
||||
) {
|
||||
final AppBundleDirectory outputDir;
|
||||
switch (parsedArgs.sourceKind) {
|
||||
case RemoteSourceKind.git:
|
||||
final resolvedGitRef =
|
||||
parsedArgs.gitRef ??
|
||||
GitPackageDescriptionSyntax.fromJson(
|
||||
PubspecLockFile.loadSync(
|
||||
helperPackageLockFile,
|
||||
).packages![packageName]!.description.json,
|
||||
).resolvedRef;
|
||||
outputDir = DartInstallDirectory().gitAppBundle(
|
||||
packageName,
|
||||
resolvedGitRef,
|
||||
);
|
||||
case RemoteSourceKind.hosted:
|
||||
final packageGraphJson = PackageGraphFile.loadSync(
|
||||
File.fromUri(
|
||||
helperPackageDir.uri.resolve('.dart_tool/package_graph.json'),
|
||||
),
|
||||
);
|
||||
final resolvedVersion = packageGraphJson.packages
|
||||
.firstWhere((e) => e.name == packageName)
|
||||
.version;
|
||||
outputDir = DartInstallDirectory().hostedAppBundle(
|
||||
packageName,
|
||||
resolvedVersion,
|
||||
);
|
||||
case RemoteSourceKind.path:
|
||||
outputDir = DartInstallDirectory().localAppBundle(packageName);
|
||||
final lockFile = PubspecLockFile.loadSync(helperPackageLockFile);
|
||||
final resolvedPackage = lockFile.packages![packageName]!;
|
||||
final source = resolvedPackage.source;
|
||||
|
||||
if (source == PackageSourceSyntax.git) {
|
||||
final resolvedGitRef = GitPackageDescriptionSyntax.fromJson(
|
||||
resolvedPackage.description.json,
|
||||
).resolvedRef;
|
||||
return DartInstallDirectory().gitAppBundle(packageName, resolvedGitRef);
|
||||
} else if (source == PackageSourceSyntax.path$) {
|
||||
return DartInstallDirectory().localAppBundle(packageName);
|
||||
} else {
|
||||
return DartInstallDirectory().hostedAppBundle(
|
||||
packageName,
|
||||
resolvedPackage.version,
|
||||
);
|
||||
}
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
static Future<void> createAppBundleDirectory(
|
||||
@@ -572,7 +600,6 @@ You can specify three different values for the <package> argument:
|
||||
_uniinstallAllPackageVersions(packageName);
|
||||
|
||||
AppBundleDirectory appBundleDirectory = selectAppBundleDirectory(
|
||||
parsedArgs,
|
||||
packageName,
|
||||
helperPackageDirectory,
|
||||
helperPackageLockFile,
|
||||
@@ -630,7 +657,25 @@ You can specify three different values for the <package> argument:
|
||||
}
|
||||
}
|
||||
|
||||
final class InstallCommandParsedArguments {
|
||||
sealed class InstallCommandParsedArguments {
|
||||
final bool overwrite;
|
||||
InstallCommandParsedArguments({required this.overwrite});
|
||||
}
|
||||
|
||||
class DescriptorInstallCommandParsedArguments
|
||||
extends InstallCommandParsedArguments {
|
||||
final String packageName;
|
||||
final Object? descriptor;
|
||||
|
||||
DescriptorInstallCommandParsedArguments({
|
||||
required this.packageName,
|
||||
required this.descriptor,
|
||||
required super.overwrite,
|
||||
});
|
||||
}
|
||||
|
||||
class NonDescriptorInstallCommandParsedArguments
|
||||
extends InstallCommandParsedArguments {
|
||||
/// Package name, git url, or file path, depending on [sourceKind].
|
||||
final String source;
|
||||
final RemoteSourceKind sourceKind;
|
||||
@@ -638,22 +683,21 @@ final class InstallCommandParsedArguments {
|
||||
final String? gitPath;
|
||||
final String? gitRef;
|
||||
final String? hostedUrl;
|
||||
final bool overwrite;
|
||||
|
||||
InstallCommandParsedArguments({
|
||||
NonDescriptorInstallCommandParsedArguments({
|
||||
required this.source,
|
||||
required this.sourceKind,
|
||||
required this.versionConstraint,
|
||||
required this.gitPath,
|
||||
required this.gitRef,
|
||||
required this.hostedUrl,
|
||||
required this.overwrite,
|
||||
required super.overwrite,
|
||||
});
|
||||
}
|
||||
|
||||
enum RemoteSourceKind { git, hosted, path }
|
||||
|
||||
RemoteSourceKind _soureKindFromArgument(String argument) {
|
||||
RemoteSourceKind _sourceKindFromArgument(String argument) {
|
||||
if (_packageNameRegExp.hasMatch(argument)) {
|
||||
return RemoteSourceKind.hosted;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import 'package:frontend_server/resident_frontend_server_utils.dart'
|
||||
show invokeReplaceCachedDill;
|
||||
import 'package:path/path.dart';
|
||||
import 'package:pub/pub.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
import '../core.dart';
|
||||
import '../experiments.dart';
|
||||
@@ -56,17 +57,42 @@ class RunCommand extends DartdevCommand {
|
||||
bool verbose = false,
|
||||
this.nativeAssetsExperimentEnabled = false,
|
||||
this.dataAssetsExperimentEnabled = false,
|
||||
}) : super(cmdName, '''Run a Dart program from a file or a local package.
|
||||
}) : super(cmdName, '''
|
||||
Run a Dart program from a file or a local or remote package.
|
||||
|
||||
Usage: dart [vm-options] run [arguments] <dart-file>|<local-package> [args]
|
||||
Usage:
|
||||
|
||||
Running a local script or package executable:
|
||||
dart run [vm-options] <dart-file>|<local-package>[:<executable>] args
|
||||
Running a remote package executable:
|
||||
dart run <remote-package>[:<executable?]@[<descriptor>]> [args]
|
||||
|
||||
<dart-file>
|
||||
A path to a Dart script (e.g., `bin/main.dart`).
|
||||
|
||||
<local-package>
|
||||
An executable from a local package dependency, in the format <package>[:<executable>].
|
||||
For example, `test:test` runs the `test` executable from the `test` package.
|
||||
If the executable is not specified, the package name is used.''', verbose) {
|
||||
The name of a package in the local package resolution.
|
||||
|
||||
<executable>
|
||||
The name of an executable in the package to execute.
|
||||
|
||||
For example, `dart run test:test` runs the `test` executable from the `test` package.
|
||||
If the executable is not specified, the package name is used.
|
||||
|
||||
<descriptor>
|
||||
A YAML formatted string that describes how to locate the
|
||||
remote package, the same you could use in a pubspec.
|
||||
|
||||
For example, to run the latest stable `pubviz` package from pub.dev:
|
||||
dart run pubviz@
|
||||
To specify a version constraint:
|
||||
dart run pubviz@^4.0.0
|
||||
To specify a custom package host:
|
||||
dart run 'pubviz@{hosted: https://my_repository.com, version: ^1.0.0}'
|
||||
To run from a git package:
|
||||
dart run 'pubviz@{git: https://github.com/kevmoo/pubviz}'
|
||||
|
||||
See https://dart.dev/go/pub-descriptors for more details.''', verbose) {
|
||||
argParser
|
||||
..addFlag(
|
||||
residentOption,
|
||||
@@ -327,58 +353,12 @@ Usage: dart [vm-options] run [arguments] <dart-file>|<local-package> [args]
|
||||
'extension development environment.',
|
||||
)
|
||||
..addFlag('debug-dds', hide: true)
|
||||
..addExperimentalFlags(verbose: verbose)
|
||||
..addFlag(
|
||||
'enable-experiment-remote-run',
|
||||
negatable: false,
|
||||
hide: !verbose,
|
||||
help: '''
|
||||
Enables running executables from remote packages.
|
||||
|
||||
When running a remote executable, all other command-line flags are disabled,
|
||||
except for the options for remote executables. `dart run <remote-executable>`
|
||||
uses `dart install` under the hood and compiles the app into a standalone
|
||||
executable, preventing passing VM options.
|
||||
|
||||
(Syntax is expected to change in the future.)
|
||||
|
||||
From a hosted package server:
|
||||
<hosted-url>/<package>[@<version>][:<executable>]
|
||||
|
||||
Downloads the package from a hosted package server and runs the specified
|
||||
executable.
|
||||
If a version is provided, the specified version is downloaded.
|
||||
If an executable is not specified, the package name is used.
|
||||
For example, `https://pub.dev/dcli@1.0.0:dcli_complete` runs the
|
||||
`dcli_complete` executable from version 1.0.0 of the `dcli` package.
|
||||
|
||||
From a git repository:
|
||||
<git-url>[:<executable>]
|
||||
|
||||
Clones the git repository and runs the specified executable from it.
|
||||
If an executable is not specified, the package name from the cloned
|
||||
repository's pubspec.yaml is used.
|
||||
The git url can be any valid git url.''',
|
||||
)
|
||||
..addOption(
|
||||
hide: !verbose,
|
||||
gitPathOption,
|
||||
help:
|
||||
'Path of git package in repository. '
|
||||
'Only applies when using a git url for <remote-executable>.',
|
||||
)
|
||||
..addOption(
|
||||
hide: !verbose,
|
||||
gitRefOption,
|
||||
help:
|
||||
'Git branch or commit to be retrieved. '
|
||||
'Only applies when using a git url for <remote-executable>.',
|
||||
);
|
||||
..addExperimentalFlags(verbose: verbose);
|
||||
}
|
||||
|
||||
@override
|
||||
String get invocation =>
|
||||
'${super.invocation} [<dart-file|package-target> [args]]';
|
||||
'dart run [vm-options] <dart-file>|<local-pkg>|<remote-pkg>@<descriptor> <program-args...>';
|
||||
|
||||
@override
|
||||
CommandCategory get commandCategory => CommandCategory.project;
|
||||
@@ -468,8 +448,8 @@ Enables running executables from remote packages.
|
||||
runArgs = args.rest.skip(1).toList();
|
||||
}
|
||||
|
||||
if (args.flag('enable-experiment-remote-run') &&
|
||||
_isRemoteRun(mainCommand)) {
|
||||
final atIndex = mainCommand.indexOf('@');
|
||||
if (atIndex != -1) {
|
||||
return _runRemote(args, mainCommand, runArgs);
|
||||
}
|
||||
return _runLocal(args, mainCommand, runArgs);
|
||||
@@ -498,12 +478,6 @@ Enables running executables from remote packages.
|
||||
);
|
||||
return errorExitCode;
|
||||
}
|
||||
if (args.wasParsed(gitPathOption) || args.wasParsed(gitRefOption)) {
|
||||
usageException(
|
||||
'Options `--$gitPathOption` and `--$gitRefOption` '
|
||||
'can only be used with a remote executable.',
|
||||
);
|
||||
}
|
||||
|
||||
String? nativeAssets;
|
||||
final packageConfigUri = await DartNativeAssetsBuilder.ensurePackageConfig(
|
||||
@@ -639,140 +613,6 @@ Enables running executables from remote packages.
|
||||
return 0;
|
||||
}
|
||||
|
||||
static RemoteSourceKind? _remoteSourceKindFromArgument(String argument) {
|
||||
if (argument.startsWith('git@')) {
|
||||
return RemoteSourceKind.git;
|
||||
}
|
||||
final potentialUri = argument
|
||||
.split(_colonButNoSlashes)
|
||||
.first
|
||||
.split('@')
|
||||
.first;
|
||||
final endsWithDotGitRegex = RegExp(r'\.git[/\\]?$');
|
||||
if (endsWithDotGitRegex.hasMatch(potentialUri)) {
|
||||
return RemoteSourceKind.git;
|
||||
}
|
||||
final parsedUri = Uri.tryParse(potentialUri);
|
||||
if (parsedUri != null) {
|
||||
switch (parsedUri.scheme.toLowerCase()) {
|
||||
case 'git':
|
||||
return RemoteSourceKind.git;
|
||||
case 'http':
|
||||
case 'https':
|
||||
return RemoteSourceKind.hosted;
|
||||
}
|
||||
}
|
||||
final parsedGitSshUrl = GitSshUrl.tryParse(potentialUri);
|
||||
if (parsedGitSshUrl != null) {
|
||||
return RemoteSourceKind.git;
|
||||
}
|
||||
|
||||
// Local execution.
|
||||
return null;
|
||||
}
|
||||
|
||||
static bool _isRemoteRun(String mainCommand) {
|
||||
return _remoteSourceKindFromArgument(mainCommand) != null;
|
||||
}
|
||||
|
||||
/// Parse the arguments for remote run.
|
||||
///
|
||||
/// Constructs a [InstallCommandParsedArguments] to be able to reuse the
|
||||
/// [InstallCommand] implementation.
|
||||
InstallCommandParsedArguments _parseRemoteArguments(String mainCommand) {
|
||||
final argResults = this.argResults!;
|
||||
|
||||
final sourceKind = _remoteSourceKindFromArgument(mainCommand)!;
|
||||
|
||||
final gitPath = argResults.option(gitPathOption);
|
||||
var gitRef = argResults.option(gitRefOption);
|
||||
if (sourceKind != RemoteSourceKind.git &&
|
||||
(gitPath != null || gitRef != null)) {
|
||||
usageException(
|
||||
'Options `--$gitPathOption` and `--$gitRefOption` '
|
||||
'can only be used with a git source.',
|
||||
);
|
||||
}
|
||||
|
||||
for (final option in argResults.options) {
|
||||
if (argResults.wasParsed(option) &&
|
||||
option != gitPathOption &&
|
||||
option != gitRefOption &&
|
||||
option != verbosityOption &&
|
||||
option != 'enable-experiment-remote-run') {
|
||||
usageException(
|
||||
'Option $option cannot be used in remote runs. '
|
||||
'`dart run <remote-executable>` uses `dart install` under the hood '
|
||||
'and compiles the app into a standalone executable.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String? hostedUrl;
|
||||
String? versionConstraint;
|
||||
final String source;
|
||||
switch (sourceKind) {
|
||||
case RemoteSourceKind.git:
|
||||
if (mainCommand.startsWith('git@') && mainCommand.contains('.git')) {
|
||||
// Valid values might contain a colon for the command or not:
|
||||
// - git@github.com:org/repo.git
|
||||
// - git@github.com:org/repo.git:executable
|
||||
// Drop everything after the 2nd colon for the git repository.
|
||||
source = mainCommand.split(':').sublist(0, 2).join(':');
|
||||
} else {
|
||||
source = mainCommand.split(_colonButNoSlashes).first;
|
||||
}
|
||||
case RemoteSourceKind.hosted:
|
||||
final parsedUri = Uri.parse(
|
||||
mainCommand.split('@').first.split(_colonButNoSlashes).first,
|
||||
);
|
||||
hostedUrl = '${parsedUri.scheme}://${parsedUri.host}';
|
||||
source = parsedUri.path.replaceFirst('/', '');
|
||||
versionConstraint =
|
||||
mainCommand
|
||||
.split('@')
|
||||
.lastButNotFirstOrNull
|
||||
?.split(_colonButNoSlashes)
|
||||
.first ??
|
||||
'any';
|
||||
if (versionConstraint.isEmpty) {
|
||||
versionConstraint = 'any';
|
||||
}
|
||||
case RemoteSourceKind.path:
|
||||
throw StateError('Unreachable');
|
||||
}
|
||||
|
||||
return InstallCommandParsedArguments(
|
||||
source: source,
|
||||
sourceKind: sourceKind,
|
||||
versionConstraint: versionConstraint,
|
||||
gitPath: gitPath,
|
||||
gitRef: gitRef,
|
||||
hostedUrl: hostedUrl,
|
||||
overwrite: false,
|
||||
);
|
||||
}
|
||||
|
||||
Future<String> _findPackageName(
|
||||
InstallCommandParsedArguments parsedArgs,
|
||||
) async {
|
||||
switch (parsedArgs.sourceKind) {
|
||||
case RemoteSourceKind.git:
|
||||
return await getPackageNameFromGitRepo(
|
||||
parsedArgs.source,
|
||||
ref: parsedArgs.gitRef,
|
||||
path: parsedArgs.gitPath,
|
||||
relativeTo: Directory.current.path,
|
||||
tagPattern: null,
|
||||
);
|
||||
case RemoteSourceKind.hosted:
|
||||
return parsedArgs.source;
|
||||
|
||||
case RemoteSourceKind.path:
|
||||
throw StateError('Unreachable');
|
||||
}
|
||||
}
|
||||
|
||||
/// Installs (if needed) and runs the remote executable.
|
||||
///
|
||||
/// Installs the app bundle at the same location as `dart install` but does
|
||||
@@ -782,9 +622,38 @@ Enables running executables from remote packages.
|
||||
String mainCommand,
|
||||
List<String> runArgs,
|
||||
) async {
|
||||
final parsedArgs = _parseRemoteArguments(mainCommand);
|
||||
final packageName = await _findPackageName(parsedArgs);
|
||||
for (final option in args.options) {
|
||||
if (args.wasParsed(option) && option != verbosityOption) {
|
||||
usageException(
|
||||
'Option --$option cannot be used in remote runs. '
|
||||
'`dart run <remote-executable>` uses `dart install` under the hood '
|
||||
'and compiles the app into a standalone executable.',
|
||||
);
|
||||
}
|
||||
}
|
||||
final atIndex = mainCommand.indexOf('@');
|
||||
assert(atIndex != -1);
|
||||
final command = mainCommand.substring(0, atIndex);
|
||||
final descriptorString = mainCommand.substring(atIndex + 1);
|
||||
final Object? descriptor;
|
||||
try {
|
||||
descriptor = loadYaml(descriptorString);
|
||||
} on FormatException catch (e) {
|
||||
usageException(
|
||||
'Failed to parse remote executable descriptor "$descriptorString": $e',
|
||||
);
|
||||
}
|
||||
|
||||
final colonIndex = command.indexOf(':');
|
||||
final String packageName;
|
||||
final String executable;
|
||||
if (colonIndex == -1) {
|
||||
packageName = command;
|
||||
executable = command;
|
||||
} else {
|
||||
packageName = command.substring(0, colonIndex);
|
||||
executable = command.substring(colonIndex + 1);
|
||||
}
|
||||
return await InstallCommand.inTempDir((tempDirectory) async {
|
||||
try {
|
||||
// Create a helper package for running a pub-resolve and pulling in the
|
||||
@@ -796,7 +665,11 @@ Enables running executables from remote packages.
|
||||
InstallCommand.createHelperPackagePubspec(
|
||||
helperPackageDir: helperPackageDirectory,
|
||||
packageName: packageName,
|
||||
parsedArgs: parsedArgs,
|
||||
parsedArgs: DescriptorInstallCommandParsedArguments(
|
||||
packageName: packageName,
|
||||
descriptor: descriptor,
|
||||
overwrite: false,
|
||||
),
|
||||
);
|
||||
await InstallCommand.resolveHelperPackage(helperPackageDirectory);
|
||||
final helperPackageLockFile = File.fromUri(
|
||||
@@ -804,7 +677,6 @@ Enables running executables from remote packages.
|
||||
);
|
||||
|
||||
final appBundleDirectory = InstallCommand.selectAppBundleDirectory(
|
||||
parsedArgs,
|
||||
packageName,
|
||||
helperPackageDirectory,
|
||||
helperPackageLockFile,
|
||||
@@ -858,14 +730,6 @@ Enables running executables from remote packages.
|
||||
);
|
||||
}
|
||||
|
||||
final mainCommandRemainder = mainCommand.substring(
|
||||
parsedArgs.source.length,
|
||||
);
|
||||
final executable =
|
||||
mainCommandRemainder
|
||||
.split(_colonButNoSlashes)
|
||||
.lastButNotFirstOrNull ??
|
||||
packageName;
|
||||
final executableUri = appBundleDirectory.directory.uri.resolve(
|
||||
'bundle/bin/$executable',
|
||||
);
|
||||
@@ -888,17 +752,6 @@ Enables running executables from remote packages.
|
||||
}
|
||||
}
|
||||
|
||||
extension<T> on List<T> {
|
||||
/// Return the last element, but only if there are at least two elements.
|
||||
T? get lastButNotFirstOrNull {
|
||||
if (length < 2) return null;
|
||||
return last;
|
||||
}
|
||||
}
|
||||
|
||||
/// Does not match the :// in an url scheme or the :\ in a Windows path.
|
||||
final _colonButNoSlashes = RegExp(r':(?!(//|\\))');
|
||||
|
||||
/// Keep in sync with [getExecutableForCommand].
|
||||
///
|
||||
/// Returns `null` if root package should be used.
|
||||
|
||||
@@ -90,7 +90,7 @@ Project
|
||||
compile Compile Dart to various formats.
|
||||
create Create a new Dart project.
|
||||
pub Work with packages.
|
||||
run Run a Dart program from a file or a local package.
|
||||
run Run a Dart program from a file or a local or remote package.
|
||||
test Run tests for a project.
|
||||
|
||||
Source code
|
||||
|
||||
@@ -107,13 +107,13 @@ void run() {
|
||||
|
||||
expect(
|
||||
result.stdout,
|
||||
contains('Run a Dart program from a file or a local package.'),
|
||||
contains('Run a Dart program from a file or a local or remote package.'),
|
||||
);
|
||||
expect(result.stdout, contains('Debugging options:'));
|
||||
expect(
|
||||
result.stdout,
|
||||
contains(
|
||||
'Usage: dart [vm-options] run [arguments] <dart-file>|<local-package> [args]',
|
||||
'Usage: dart run [vm-options] <dart-file>|<local-pkg>|<remote-pkg>@<descriptor> <program-args...>',
|
||||
),
|
||||
);
|
||||
expect(result.stderr, isEmpty);
|
||||
@@ -126,13 +126,13 @@ void run() {
|
||||
|
||||
expect(
|
||||
result.stdout,
|
||||
contains('Run a Dart program from a file or a local package.'),
|
||||
contains('Run a Dart program from a file or a local or remote package.'),
|
||||
);
|
||||
expect(result.stdout, contains('Debugging options:'));
|
||||
expect(
|
||||
result.stdout,
|
||||
contains(
|
||||
'Usage: dart [vm-options] run [arguments] <dart-file>|<local-package> [args]',
|
||||
'dart run [vm-options] <dart-file>|<local-pkg>|<remote-pkg>@<descriptor> <program-args...>',
|
||||
),
|
||||
);
|
||||
expect(result.stderr, isEmpty);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
void main(List<String> args) {
|
||||
print('Hello from other app ${args.join(' ')}');
|
||||
}
|
||||
@@ -5,3 +5,4 @@ environment:
|
||||
|
||||
executables:
|
||||
dart_app:
|
||||
other_app:
|
||||
|
||||
@@ -90,21 +90,26 @@ executables.
|
||||
|
||||
If the same package has been previously installed, it will be overwritten.
|
||||
|
||||
You can specify three different values for the <package> argument:
|
||||
1. A package name. This will install the package from pub.dev. (hosted)
|
||||
The [version-constraint] argument can only be passed to 'hosted'.
|
||||
2. A git url. This will install the package from a git repository. (git)
|
||||
3. A path on your machine. This will install the package from that path. (path)
|
||||
You can specify a package to install from pub.dev, a git repository, or a
|
||||
local path using the `<package>[@<descriptor>]` syntax.
|
||||
|
||||
Usage: dart install <package> [version-constraint]
|
||||
-h, --help Print this usage information.
|
||||
--git-path Path of git package in repository. Only applies when using a git url for <package>.
|
||||
--git-ref Git branch or commit to be retrieved. Only applies when using a git url for <package>.
|
||||
--overwrite Overwrite executables from other packages with the same name.
|
||||
-u, --hosted-url A custom pub server URL for the package. Only applies when using a package name for <package>.
|
||||
The `@<descriptor>` can be a version constraint (for hosted packages) or a
|
||||
pub descriptor (consistent with pubspec.yaml).
|
||||
|
||||
Run "dart help" to see global options.
|
||||
''',
|
||||
Examples:
|
||||
dart install <pkg>
|
||||
dart install <pkg>@^3.0.0
|
||||
dart install '<pkg>@{hosted: https://pub.dev, version: ^3.0.0}'
|
||||
dart install '<pkg>@{git: {url: https://github.com/<owner>/<repo>, path: <path>}}'
|
||||
dart install '<pkg>@{path: /path/to/<pkg>}'
|
||||
|
||||
See https://dart.dev/go/pub-descriptors for more details.
|
||||
|
||||
Usage: dart install <package>[@<descriptor>]
|
||||
-h, --help Print this usage information.
|
||||
--overwrite Overwrite executables from other packages with the same name.
|
||||
|
||||
Run "dart help" to see global options.''',
|
||||
),
|
||||
(
|
||||
'installed',
|
||||
@@ -152,6 +157,9 @@ Run "dart help" to see global options.
|
||||
final argumentss = [
|
||||
(null, [_packageForTest]),
|
||||
(null, [_packageForTest, _packageVersion]),
|
||||
(null, ['$_packageForTest@$_packageVersion']),
|
||||
(null, ['$_packageForTest@{"version": "$_packageVersion"}']),
|
||||
(null, ['$_packageForTest@{version: $_packageVersion}']),
|
||||
(
|
||||
null,
|
||||
[_packageForTest, _packageVersion, '--hosted-url', 'https://pub.dev/'],
|
||||
@@ -225,6 +233,7 @@ Run "dart help" to see global options.
|
||||
final argumentssGit = [
|
||||
['git'],
|
||||
['git', '--git-path', '--git-ref'],
|
||||
['git-descriptor'],
|
||||
];
|
||||
|
||||
for (final testArguments in argumentssGit) {
|
||||
@@ -234,7 +243,11 @@ Run "dart help" to see global options.
|
||||
await inTempDir((tempUri) async {
|
||||
final gitUri = tempUri.resolve('app.git/');
|
||||
await Directory.fromUri(gitUri.resolve('bin/')).create(recursive: true);
|
||||
for (final file in ['pubspec.yaml', 'bin/dart_app.dart']) {
|
||||
for (final file in [
|
||||
'pubspec.yaml',
|
||||
'bin/dart_app.dart',
|
||||
'bin/other_app.dart',
|
||||
]) {
|
||||
await File.fromUri(
|
||||
_package2Dir.uri.resolve(file),
|
||||
).copy(gitUri.resolve(file).toFilePath());
|
||||
@@ -261,11 +274,21 @@ Run "dart help" to see global options.
|
||||
as String)
|
||||
.trim();
|
||||
final gitPath = './';
|
||||
final arguments = [
|
||||
gitUri.toFilePath(),
|
||||
if (testArguments.contains('--git-path')) ...['--git-path', gitPath],
|
||||
if (testArguments.contains('--git-ref')) ...['--git-ref', gitRef],
|
||||
];
|
||||
final List<String> arguments;
|
||||
if (testArguments.contains('git-descriptor')) {
|
||||
arguments = [
|
||||
'dart_app@{git: {url: ${gitUri.toFilePath()}, ref: $gitRef}}',
|
||||
];
|
||||
} else {
|
||||
arguments = [
|
||||
gitUri.toFilePath(),
|
||||
if (testArguments.contains('--git-path')) ...[
|
||||
'--git-path',
|
||||
gitPath,
|
||||
],
|
||||
if (testArguments.contains('--git-ref')) ...['--git-ref', gitRef],
|
||||
];
|
||||
}
|
||||
|
||||
final dartDataHome = tempUri.resolve('dart_home/');
|
||||
await Directory.fromUri(dartDataHome).create();
|
||||
|
||||
@@ -11,10 +11,6 @@ import 'package:test/test.dart';
|
||||
import '../utils.dart';
|
||||
import 'helpers.dart';
|
||||
|
||||
const _packageForTest = 'vm_snapshot_analysis';
|
||||
const _packageVersion = '0.7.5';
|
||||
const _cliToolForTest = 'snapshot_analysis';
|
||||
|
||||
final _sdkUri = resolveDartDevUri('.').resolve('../../');
|
||||
|
||||
final _package2RelativePath = Uri.directory('pkg/dartdev/test/data/dart_app/');
|
||||
@@ -23,8 +19,6 @@ final _package2Dir = Directory.fromUri(
|
||||
_sdkUri.resolveUri(_package2RelativePath),
|
||||
);
|
||||
|
||||
const _gitPackageForTest = 'dart_app';
|
||||
|
||||
final _pathEnvVarSeparator = Platform.isWindows ? ';' : ':';
|
||||
|
||||
const String _dartDirectoryEnvKey = 'DART_DATA_HOME';
|
||||
@@ -48,52 +42,59 @@ void main() async {
|
||||
final result = await _runDartdev(
|
||||
fromDartdevSource,
|
||||
'run',
|
||||
['--help', '-v'],
|
||||
['--help'],
|
||||
null,
|
||||
{},
|
||||
);
|
||||
print(result.stdout);
|
||||
printOnFailure('stdout:\n${result.stdout}');
|
||||
expect(
|
||||
result.stdout,
|
||||
contains(
|
||||
'''
|
||||
--enable-experiment-remote-run Enables running executables from remote packages.
|
||||
|
||||
When running a remote executable, all other command-line flags are disabled,
|
||||
except for the options for remote executables. `dart run <remote-executable>`
|
||||
uses `dart install` under the hood and compiles the app into a standalone
|
||||
executable, preventing passing VM options.
|
||||
|
||||
(Syntax is expected to change in the future.)
|
||||
|
||||
From a hosted package server:
|
||||
<hosted-url>/<package>[@<version>][:<executable>]
|
||||
|
||||
Downloads the package from a hosted package server and runs the specified
|
||||
executable.
|
||||
If a version is provided, the specified version is downloaded.
|
||||
If an executable is not specified, the package name is used.
|
||||
For example, `https://pub.dev/dcli@1.0.0:dcli_complete` runs the
|
||||
`dcli_complete` executable from version 1.0.0 of the `dcli` package.
|
||||
|
||||
From a git repository:
|
||||
<git-url>[:<executable>]
|
||||
|
||||
Clones the git repository and runs the specified executable from it.
|
||||
If an executable is not specified, the package name from the cloned
|
||||
repository's pubspec.yaml is used.
|
||||
The git url can be any valid git url.
|
||||
--git-path Path of git package in repository. Only applies when using a git url for <remote-executable>.
|
||||
--git-ref Git branch or commit to be retrieved. Only applies when using a git url for <remote-executable>.''',
|
||||
),
|
||||
contains('''
|
||||
Run a Dart program from a file or a local or remote package.
|
||||
|
||||
Usage:
|
||||
|
||||
Running a local script or package executable:
|
||||
dart run [vm-options] <dart-file>|<local-package>[:<executable>] args
|
||||
Running a remote package executable:
|
||||
dart run <remote-package>[:<executable?]@[<descriptor>]> [args]
|
||||
|
||||
<dart-file>
|
||||
A path to a Dart script (e.g., `bin/main.dart`).
|
||||
|
||||
<local-package>
|
||||
The name of a package in the local package resolution.
|
||||
|
||||
<executable>
|
||||
The name of an executable in the package to execute.
|
||||
|
||||
For example, `dart run test:test` runs the `test` executable from the `test` package.
|
||||
If the executable is not specified, the package name is used.
|
||||
|
||||
<descriptor>
|
||||
A YAML formatted string that describes how to locate the
|
||||
remote package, the same you could use in a pubspec.
|
||||
|
||||
For example, to run the latest stable `pubviz` package from pub.dev:
|
||||
dart run pubviz@
|
||||
To specify a version constraint:
|
||||
dart run pubviz@^4.0.0
|
||||
To specify a custom package host:
|
||||
dart run 'pubviz@{hosted: https://my_repository.com, version: ^1.0.0}'
|
||||
To run from a git package:
|
||||
dart run 'pubviz@{git: https://github.com/kevmoo/pubviz}'
|
||||
|
||||
See https://dart.dev/go/pub-descriptors for more details.'''),
|
||||
);
|
||||
});
|
||||
|
||||
for (final version in ['', '@$_packageVersion', '@']) {
|
||||
final testName = version == ''
|
||||
? 'no version'
|
||||
: (version == '@' ? 'empty version' : 'with version');
|
||||
test('dart run hosted package $testName', timeout: longTimeout, () async {
|
||||
for (final argument in [
|
||||
'vm_snapshot_analysis:snapshot_analysis@0.7.5',
|
||||
'vm_snapshot_analysis:snapshot_analysis@^0.7.5',
|
||||
'vm_snapshot_analysis:snapshot_analysis@', // Resolves to latest stable version.
|
||||
'vm_snapshot_analysis:snapshot_analysis@{hosted: https://pub.dev}',
|
||||
]) {
|
||||
test('dart run $argument', timeout: longTimeout, () async {
|
||||
await inTempDir((tempUri) async {
|
||||
final dartDataHome = tempUri.resolve('dart_home/');
|
||||
await Directory.fromUri(dartDataHome).create();
|
||||
@@ -109,8 +110,7 @@ void main() async {
|
||||
fromDartdevSource,
|
||||
'run',
|
||||
[
|
||||
'--enable-experiment-remote-run',
|
||||
'https://pub.dev/$_packageForTest$version:$_cliToolForTest',
|
||||
argument,
|
||||
// Make sure to pass arguments that influence stdout.
|
||||
'compare',
|
||||
'--help',
|
||||
@@ -129,23 +129,18 @@ void main() async {
|
||||
});
|
||||
}
|
||||
|
||||
final argumentssGit = [
|
||||
['git'],
|
||||
['git', '--git-path', '--git-ref'],
|
||||
];
|
||||
|
||||
for (final testArguments in argumentssGit) {
|
||||
var testName = testArguments.join(' ');
|
||||
|
||||
test('dart run from $testName', timeout: longTimeout, () async {
|
||||
await inTempDir((tempUri) async {
|
||||
final (gitUri, gitRef) = await _setupSimpleGitRepo(tempUri);
|
||||
final gitPath = './';
|
||||
test('dart run remote from git', timeout: longTimeout, () async {
|
||||
await inTempDir((tempUri) async {
|
||||
final (gitUri, gitRef) = await _setupSimpleGitRepo(tempUri);
|
||||
for (final (argument, expectedResult) in [
|
||||
('dart_app@{git: ${gitUri.toString()}}', 'Hello Alice and Bob'),
|
||||
(
|
||||
'dart_app:other_app@{git: ${gitUri.toString()}}',
|
||||
'Hello from other app Alice and Bob',
|
||||
),
|
||||
]) {
|
||||
final arguments = [
|
||||
'--enable-experiment-remote-run',
|
||||
if (testArguments.contains('--git-path')) ...['--git-path', gitPath],
|
||||
if (testArguments.contains('--git-ref')) ...['--git-ref', gitRef],
|
||||
'${gitUri.toFilePath()}:$_gitPackageForTest',
|
||||
argument,
|
||||
// Make sure to pass arguments that influence stdout.
|
||||
'Alice',
|
||||
'and',
|
||||
@@ -170,48 +165,24 @@ void main() async {
|
||||
environment,
|
||||
);
|
||||
|
||||
expect(
|
||||
runResult.stdout,
|
||||
stringContainsInOrder(['Hello Alice and Bob']),
|
||||
);
|
||||
expect(runResult.stdout, contains(expectedResult));
|
||||
expect(runResult.exitCode, 0);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
final errorArgumentss = [
|
||||
(
|
||||
[
|
||||
'--enable-experiment-remote-run',
|
||||
'https://pub.dev/this_package_does_not_exist_12345',
|
||||
],
|
||||
['this_package_does_not_exist_12345@'],
|
||||
'could not find package this_package_does_not_exist_12345 at',
|
||||
errorExitCode,
|
||||
),
|
||||
(
|
||||
[
|
||||
'--enable-experiment-remote-run',
|
||||
'--git-path',
|
||||
'foo/',
|
||||
'https://pub.dev/vm_snapshot_analysis',
|
||||
],
|
||||
'git-path',
|
||||
usageExitCode,
|
||||
),
|
||||
(
|
||||
[
|
||||
'--enable-experiment-remote-run',
|
||||
'--enable-asserts',
|
||||
'https://pub.dev/vm_snapshot_analysis',
|
||||
],
|
||||
'enable-asserts',
|
||||
usageExitCode,
|
||||
),
|
||||
(
|
||||
['--enable-experiment-remote-run', '--git-path', 'foo/'],
|
||||
'git-path',
|
||||
['--enable-asserts', 'vm_snapshot_analysis@'],
|
||||
'--enable-asserts cannot be used in remote runs',
|
||||
usageExitCode,
|
||||
),
|
||||
(['my_package@{,bad,descriptor,}'], '{,bad,descriptor,}', usageExitCode),
|
||||
];
|
||||
for (final (errorArguments, error, exitCode) in errorArgumentss) {
|
||||
test('dart run ${errorArguments.join(' ')}', timeout: longTimeout, () async {
|
||||
@@ -284,10 +255,7 @@ void main(List<String> args) async {
|
||||
final runResult = await _runDartdev(
|
||||
fromDartdevSource,
|
||||
'run',
|
||||
[
|
||||
'--enable-experiment-remote-run',
|
||||
'${gitUri.toFilePath()}:$packageName',
|
||||
],
|
||||
['test_app_with_failing_hook@{git: ${gitUri.toFilePath()}}'],
|
||||
null,
|
||||
environment,
|
||||
expectedExitCode: errorExitCode,
|
||||
@@ -309,13 +277,7 @@ void main(List<String> args) async {
|
||||
await inTempDir((tempUri) async {
|
||||
final (gitUri, gitRef) = await _setupSimpleGitRepo(tempUri);
|
||||
|
||||
final arguments = [
|
||||
'--enable-experiment-remote-run',
|
||||
'--git-ref',
|
||||
gitRef,
|
||||
'${gitUri.toFilePath()}:$_gitPackageForTest',
|
||||
'World',
|
||||
];
|
||||
final arguments = ['dart_app@{git: ${gitUri.toFilePath()}}', 'World'];
|
||||
|
||||
// 2. Setup environment
|
||||
final dartDataHome = tempUri.resolve('dart_home/');
|
||||
@@ -372,11 +334,8 @@ void main(List<String> args) async {
|
||||
);
|
||||
|
||||
final arguments = [
|
||||
'--enable-experiment-remote-run',
|
||||
if (verbosityError) '--verbosity=error',
|
||||
'--git-ref',
|
||||
gitRef,
|
||||
'${gitUri.toFilePath()}:$packageName',
|
||||
'test_app_with_hook@{git: {url: ${gitUri.toFilePath()}, ref: $gitRef}}',
|
||||
'ignored',
|
||||
'arguments',
|
||||
];
|
||||
@@ -391,8 +350,6 @@ void main(List<String> args) async {
|
||||
'${binDir.path}$_pathEnvVarSeparator${Platform.environment['PATH']!}',
|
||||
};
|
||||
|
||||
print(environment);
|
||||
print('dart run ${arguments.join(' ')}');
|
||||
final runResult = await _runDartdev(
|
||||
fromDartdevSource,
|
||||
'run',
|
||||
@@ -407,7 +364,7 @@ void main(List<String> args) async {
|
||||
expect(runResult.stdout, isNot(contains('Running build hooks')));
|
||||
expect(runResult.stdout, isNot(contains('Running link hooks')));
|
||||
expect(runResult.stdout, isNot(contains('Generated: ')));
|
||||
// Should have no other output then the program.
|
||||
// Should have no other output than the program.
|
||||
expect(runResult.stdout.trim(), equals('Hello World'));
|
||||
} else {
|
||||
expect(runResult.stdout, contains('Running build hooks'));
|
||||
@@ -513,6 +470,9 @@ Future<(Uri gitUri, String gitRef)> _setupSimpleGitRepo(Uri tempUri) async {
|
||||
'bin/dart_app.dart': await File.fromUri(
|
||||
_package2Dir.uri.resolve('bin/dart_app.dart'),
|
||||
).readAsString(),
|
||||
'bin/other_app.dart': await File.fromUri(
|
||||
_package2Dir.uri.resolve('bin/other_app.dart'),
|
||||
).readAsString(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user