diff --git a/lib/src/command/global_activate.dart b/lib/src/command/global_activate.dart index 4535c3694..c09941cbd 100644 --- a/lib/src/command/global_activate.dart +++ b/lib/src/command/global_activate.dart @@ -38,6 +38,11 @@ class GlobalActivateCommand extends PubCommand { argParser.addFlag("overwrite", negatable: false, help: "Overwrite executables from other packages with the same name."); + + argParser.addOption("hosted-url", + abbr: "u", + help: + "A custom pub server URL for the package. Only applies when using the `hosted` source."); } Future run() { @@ -67,6 +72,7 @@ class GlobalActivateCommand extends PubCommand { } var overwrite = argResults["overwrite"]; + var hostedUrl = argResults["hosted-url"]; Iterable args = argResults.rest; readArg([String error]) { @@ -106,7 +112,7 @@ class GlobalActivateCommand extends PubCommand { validateNoExtraArgs(); return globals.activateHosted(package, constraint, executables, - features: features, overwriteBinStubs: overwrite); + features: features, overwriteBinStubs: overwrite, url: hostedUrl); case "path": if (features.isNotEmpty) { diff --git a/lib/src/global_packages.dart b/lib/src/global_packages.dart index 03e296017..796a4b2f9 100644 --- a/lib/src/global_packages.dart +++ b/lib/src/global_packages.dart @@ -113,13 +113,18 @@ class GlobalPackages { /// if [overwriteBinStubs] is `true`, any binstubs that collide with /// existing binstubs in other packages will be overwritten by this one's. /// Otherwise, the previous ones will be preserved. + /// + /// [url] is an optional custom pub server URL. If not null, the package to be + /// activated will be fetched from this URL instead of the default pub URL. Future activateHosted( String name, VersionConstraint constraint, List executables, - {Map features, bool overwriteBinStubs}) async { + {Map features, + bool overwriteBinStubs, + String url}) async { _describeActive(name); await _installInCache( cache.hosted.source - .refFor(name) + .refFor(name, url: url) .withConstraint(constraint) .withFeatures(features ?? const {}), executables, diff --git a/test/global/activate/custom_hosted_url_test.dart b/test/global/activate/custom_hosted_url_test.dart new file mode 100644 index 000000000..f5fb0c869 --- /dev/null +++ b/test/global/activate/custom_hosted_url_test.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// 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 'package:test/test.dart'; + +import '../../test_pub.dart'; + +main() { + test('activating a package from a custom pub server', () async { + // The default pub server (i.e. pub.dartlang.org). + await servePackages((builder) { + builder.serve("baz", "1.0.0"); + }); + + // The custom pub server. + final customServer = await PackageServer.start((builder) { + Map hostedDep(String name, String constraint) => { + "hosted": { + "url": builder.serverUrl, + "name": name, + }, + "version": constraint, + }; + builder.serve("foo", "1.0.0", deps: {"bar": hostedDep("bar", "any")}); + builder.serve("bar", "1.0.0", deps: {"baz": "any"}); + }); + + await runPub( + args: ["global", "activate", "foo", "-u", customServer.url], + output: allOf([ + contains("Downloading bar 1.0.0..."), + contains("Downloading baz 1.0.0..."), + contains("Downloading foo 1.0.0..."), + contains("Activated foo 1.0.0") + ])); + }); +} diff --git a/test/package_server.dart b/test/package_server.dart index 107ff9d51..5626745f5 100644 --- a/test/package_server.dart +++ b/test/package_server.dart @@ -58,12 +58,12 @@ class PackageServer { /// package to serve. /// /// This is preserved so that additional packages can be added. - final _builder = PackageServerBuilder._(); + PackageServerBuilder _builder; - /// A future that will complete to the port used for the server. + /// The port used for the server. int get port => _inner.port; - /// A future that will complete to the URL for the server. + /// The URL for the server. String get url => 'http://localhost:$port'; /// Creates an HTTP server that replicates the structure of pub.dartlang.org. @@ -81,7 +81,9 @@ class PackageServer { return server; } - PackageServer._(this._inner); + PackageServer._(this._inner) { + _builder = PackageServerBuilder._(this); + } /// Add to the current set of packages that are being served. void add(void callback(PackageServerBuilder builder)) { @@ -135,7 +137,13 @@ class PackageServerBuilder { /// A map from package names to a list of concrete packages to serve. final _packages = >{}; - PackageServerBuilder._(); + /// The package server that this builder is associated with. + final PackageServer _server; + + /// The URL for the server that this builder is associated with. + String get serverUrl => _server.url; + + PackageServerBuilder._(this._server); /// Specifies that a package named [name] with [version] should be served. ///