| Index: utils/pub/hosted_source.dart
|
| diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
|
| index 6fdc8e91328b745441897ab13fdceb0a8a724f4b..44f7195ea5ffe8cbd3bf098a2de3c09112fbf945 100644
|
| --- a/utils/pub/hosted_source.dart
|
| +++ b/utils/pub/hosted_source.dart
|
| @@ -29,21 +29,20 @@ class HostedSource extends Source {
|
| final name = "hosted";
|
| final shouldCache = true;
|
|
|
| - /// The URL of the default package repository.
|
| - static final defaultUrl = "https://pub.dartlang.org";
|
| -
|
| /// Downloads a list of all versions of a package that are available from the
|
| /// site.
|
| Future<List<Version>> getVersions(String name, description) {
|
| - var parsed = _parseDescription(description);
|
| - var fullUrl = "${parsed.last}/packages/${parsed.first}.json";
|
| + var url = _makeUrl(description,
|
| + (server, package) => "$server/packages/$package.json");
|
|
|
| - return httpClient.read(fullUrl).then((body) {
|
| + log.io("Get versions from $url.");
|
| + return httpClient.read(url).then((body) {
|
| var doc = json.parse(body);
|
| return doc['versions']
|
| .map((version) => new Version.parse(version))
|
| .toList();
|
| }).catchError((ex) {
|
| + var parsed = _parseDescription(description);
|
| _throwFriendlyError(ex, parsed.first, parsed.last);
|
| });
|
| }
|
| @@ -51,13 +50,14 @@ class HostedSource extends Source {
|
| /// Downloads and parses the pubspec for a specific version of a package that
|
| /// is available from the site.
|
| Future<Pubspec> describe(PackageId id) {
|
| - var parsed = _parseDescription(id.description);
|
| - var fullUrl = "${parsed.last}/packages/${parsed.first}/versions/"
|
| - "${id.version}.yaml";
|
| + var url = _makeVersionUrl(id, (server, package, version) =>
|
| + "$server/packages/$package/versions/$version.yaml");
|
|
|
| - return httpClient.read(fullUrl).then((yaml) {
|
| + log.io("Describe package at $url.");
|
| + return httpClient.read(url).then((yaml) {
|
| return new Pubspec.parse(null, yaml, systemCache.sources);
|
| }).catchError((ex) {
|
| + var parsed = _parseDescription(id.description);
|
| _throwFriendlyError(ex, id, parsed.last);
|
| });
|
| }
|
| @@ -65,21 +65,19 @@ class HostedSource extends Source {
|
| /// Downloads a package from the site and unpacks it.
|
| Future<bool> install(PackageId id, String destPath) {
|
| return defer(() {
|
| - var parsedDescription = _parseDescription(id.description);
|
| - var name = parsedDescription.first;
|
| - var url = parsedDescription.last;
|
| -
|
| - var fullUrl = "$url/packages/$name/versions/${id.version}.tar.gz";
|
| + var url = _makeVersionUrl(id, (server, package, version) =>
|
| + "$server/packages/$package/versions/$version.tar.gz");
|
| + log.io("Install package from $url.");
|
|
|
| log.message('Downloading $id...');
|
|
|
| // Download and extract the archive to a temp directory.
|
| var tempDir = systemCache.createTempDir();
|
| - return httpClient.send(new http.Request("GET", Uri.parse(fullUrl)))
|
| + return httpClient.send(new http.Request("GET", url))
|
| .then((response) => response.stream)
|
| .then((stream) {
|
| return timeout(extractTarGz(stream, tempDir), HTTP_TIMEOUT,
|
| - 'fetching URL "$fullUrl"');
|
| + 'fetching URL "$url"');
|
| }).then((_) {
|
| // Now that the install has succeeded, move it to the real location in
|
| // the cache. This ensures that we don't leave half-busted ghost
|
| @@ -142,31 +140,57 @@ class HostedSource extends Source {
|
| throw asyncError;
|
| }
|
|
|
| - /// Parses the description for a package.
|
| - ///
|
| - /// If the package parses correctly, this returns a (name, url) pair. If not,
|
| - /// this throws a descriptive FormatException.
|
| - Pair<String, String> _parseDescription(description) {
|
| - if (description is String) {
|
| - return new Pair<String, String>(description, defaultUrl);
|
| - }
|
| +}
|
|
|
| - if (description is! Map) {
|
| - throw new FormatException(
|
| - "The description must be a package name or map.");
|
| - }
|
| +/// The URL of the default package repository.
|
| +final _defaultUrl = "https://pub.dartlang.org";
|
| +
|
| +/// Parses [description] into its server and package name components, then
|
| +/// converts that to a Uri given [pattern]. Ensures the package name is
|
| +/// properly URL encoded.
|
| +Uri _makeUrl(description, String pattern(String server, String package)) {
|
| + var parsed = _parseDescription(description);
|
| + var server = parsed.last;
|
| + var package = encodeUriComponent(parsed.first);
|
| + return new Uri(pattern(server, package));
|
| +}
|
|
|
| - if (!description.containsKey("name")) {
|
| - throw new FormatException(
|
| - "The description map must contain a 'name' key.");
|
| - }
|
| +/// Parses [id] into its server, package name, and version components, then
|
| +/// converts that to a Uri given [pattern]. Ensures the package name is
|
| +/// properly URL encoded.
|
| +Uri _makeVersionUrl(PackageId id,
|
| + String pattern(String server, String package, String version)) {
|
| + var parsed = _parseDescription(id.description);
|
| + var server = parsed.last;
|
| + var package = encodeUriComponent(parsed.first);
|
| + var version = encodeUriComponent(id.version.toString());
|
| + return new Uri(pattern(server, package, version));
|
| +}
|
|
|
| - var name = description["name"];
|
| - if (name is! String) {
|
| - throw new FormatException("The 'name' key must have a string value.");
|
| - }
|
| +/// Parses the description for a package.
|
| +///
|
| +/// If the package parses correctly, this returns a (name, url) pair. If not,
|
| +/// this throws a descriptive FormatException.
|
| +Pair<String, String> _parseDescription(description) {
|
| + if (description is String) {
|
| + return new Pair<String, String>(description, _defaultUrl);
|
| + }
|
| +
|
| + if (description is! Map) {
|
| + throw new FormatException(
|
| + "The description must be a package name or map.");
|
| + }
|
| +
|
| + if (!description.containsKey("name")) {
|
| + throw new FormatException(
|
| + "The description map must contain a 'name' key.");
|
| + }
|
|
|
| - var url = description.containsKey("url") ? description["url"] : defaultUrl;
|
| - return new Pair<String, String>(name, url);
|
| + var name = description["name"];
|
| + if (name is! String) {
|
| + throw new FormatException("The 'name' key must have a string value.");
|
| }
|
| +
|
| + var url = description.containsKey("url") ? description["url"] : _defaultUrl;
|
| + return new Pair<String, String>(name, url);
|
| }
|
|
|