| Index: lib/packagemap.dart
|
| diff --git a/lib/packagemap.dart b/lib/packagemap.dart
|
| deleted file mode 100644
|
| index 25f27b9a2ff53e6f430ebc9d51d67a08027b7d40..0000000000000000000000000000000000000000
|
| --- a/lib/packagemap.dart
|
| +++ /dev/null
|
| @@ -1,228 +0,0 @@
|
| -// Copyright (c) 2015, 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.
|
| -
|
| -library package_config.packagemap;
|
| -
|
| -class Packages {
|
| - static const int _EQUALS = 0x3d;
|
| - static const int _CR = 0x0d;
|
| - static const int _NL = 0x0a;
|
| - static const int _NUMBER_SIGN = 0x23;
|
| -
|
| - final Map<String, Uri> packageMapping;
|
| -
|
| - Packages(this.packageMapping);
|
| -
|
| - /// Resolves a URI to a non-package URI.
|
| - ///
|
| - /// If [uri] is a `package:` URI, the location is resolved wrt. the
|
| - /// [packageMapping].
|
| - /// Otherwise the original URI is returned.
|
| - Uri resolve(Uri uri) {
|
| - if (uri.scheme.toLowerCase() != "package") {
|
| - return uri;
|
| - }
|
| - if (uri.hasAuthority) {
|
| - throw new ArgumentError.value(uri, "uri", "Must not have authority");
|
| - }
|
| - if (uri.path.startsWith("/")) {
|
| - throw new ArgumentError.value(
|
| - uri, "uri", "Path must not start with '/'.");
|
| - }
|
| - // Normalizes the path by removing '.' and '..' segments.
|
| - uri = uri.normalizePath();
|
| - String path = uri.path;
|
| - var slashIndex = path.indexOf('/');
|
| - String packageName;
|
| - String rest;
|
| - if (slashIndex < 0) {
|
| - packageName = path;
|
| - rest = "";
|
| - } else {
|
| - packageName = path.substring(0, slashIndex);
|
| - rest = path.substring(slashIndex + 1);
|
| - }
|
| - Uri packageLocation = packageMapping[packageName];
|
| - if (packageLocation == null) {
|
| - throw new ArgumentError.value(
|
| - uri, "uri", "Unknown package name: $packageName");
|
| - }
|
| - return packageLocation.resolveUri(new Uri(path: rest));
|
| - }
|
| -
|
| - /// Parses a `packages.cfg` file into a `Packages` object.
|
| - ///
|
| - /// The [baseLocation] is used as a base URI to resolve all relative
|
| - /// URI references against.
|
| - ///
|
| - /// The `Packages` object allows resolving package: URIs and writing
|
| - /// the mapping back to a file or string.
|
| - /// The [packageMapping] will contain a simple mapping from package name
|
| - /// to package location.
|
| - static Packages parse(String source, Uri baseLocation) {
|
| - int index = 0;
|
| - Map<String, Uri> result = <String, Uri>{};
|
| - while (index < source.length) {
|
| - bool isComment = false;
|
| - int start = index;
|
| - int eqIndex = -1;
|
| - int end = source.length;
|
| - int char = source.codeUnitAt(index++);
|
| - if (char == _CR || char == _NL) {
|
| - continue;
|
| - }
|
| - if (char == _EQUALS) {
|
| - throw new FormatException("Missing package name", source, index - 1);
|
| - }
|
| - isComment = char == _NUMBER_SIGN;
|
| - while (index < source.length) {
|
| - char = source.codeUnitAt(index++);
|
| - if (char == _EQUALS && eqIndex < 0) {
|
| - eqIndex = index - 1;
|
| - } else if (char == _NL || char == _CR) {
|
| - end = index - 1;
|
| - break;
|
| - }
|
| - }
|
| - if (isComment) continue;
|
| - if (eqIndex < 0) {
|
| - throw new FormatException("No '=' on line", source, index - 1);
|
| - }
|
| - _checkIdentifier(source, start, eqIndex);
|
| - var packageName = source.substring(start, eqIndex);
|
| -
|
| - var packageLocation = Uri.parse(source, eqIndex + 1, end);
|
| - if (!packageLocation.path.endsWith('/')) {
|
| - packageLocation =
|
| - packageLocation.replace(path: packageLocation.path + "/");
|
| - }
|
| - packageLocation = baseLocation.resolveUri(packageLocation);
|
| - if (result.containsKey(packageName)) {
|
| - throw new FormatException(
|
| - "Same package name occured twice.", source, start);
|
| - }
|
| - result[packageName] = packageLocation;
|
| - }
|
| - return new Packages(result);
|
| - }
|
| -
|
| - /**
|
| - * Writes the mapping to a [StringSink].
|
| - *
|
| - * If [comment] is provided, the output will contain this comment
|
| - * with `#` in front of each line.
|
| - *
|
| - * If [baseUri] is provided, package locations will be made relative
|
| - * to the base URI, if possible, before writing.
|
| - */
|
| - void write(StringSink output, {Uri baseUri, String comment}) {
|
| - if (baseUri != null && !baseUri.isAbsolute) {
|
| - throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute");
|
| - }
|
| -
|
| - if (comment != null) {
|
| - for (var commentLine in comment.split('\n')) {
|
| - output.write('#');
|
| - output.writeln(commentLine);
|
| - }
|
| - } else {
|
| - output.write("# generated by package:packagecfg at ");
|
| - output.write(new DateTime.now());
|
| - output.writeln();
|
| - }
|
| -
|
| - packageMapping.forEach((String packageName, Uri uri) {
|
| - // Validate packageName.
|
| - _checkIdentifier(packageName, 0, packageName.length);
|
| - output.write(packageName);
|
| -
|
| - output.write('=');
|
| -
|
| - // If baseUri provided, make uri relative.
|
| - if (baseUri != null) {
|
| - uri = relativize(uri, baseUri);
|
| - }
|
| - output.write(uri);
|
| - if (!uri.path.endsWith('/')) {
|
| - output.write('/');
|
| - }
|
| - output.writeln();
|
| - });
|
| - }
|
| -
|
| - String toString() {
|
| - StringBuffer buffer = new StringBuffer();
|
| - write(buffer);
|
| - return buffer.toString();
|
| - }
|
| -
|
| - static Uri relativize(Uri uri, Uri baseUri) {
|
| - if (uri.hasQuery || uri.hasFragment) {
|
| - uri = new Uri(
|
| - scheme: uri.scheme,
|
| - userInfo: uri.hasAuthority ? uri.userInfo : null,
|
| - host: uri.hasAuthority ? uri.host : null,
|
| - port: uri.hasAuthority ? uri.port : null,
|
| - path: uri.path);
|
| - }
|
| - if (!baseUri.isAbsolute) {
|
| - throw new ArgumentError("Base uri '$baseUri' must be absolute.");
|
| - }
|
| - // Already relative.
|
| - if (!uri.isAbsolute) return uri;
|
| -
|
| - if (baseUri.scheme.toLowerCase() != uri.scheme.toLowerCase()) {
|
| - return uri;
|
| - }
|
| - // If authority differs, we could remove the scheme, but it's not worth it.
|
| - if (uri.hasAuthority != baseUri.hasAuthority) return uri;
|
| - if (uri.hasAuthority) {
|
| - if (uri.userInfo != baseUri.userInfo ||
|
| - uri.host.toLowerCase() != baseUri.host.toLowerCase() ||
|
| - uri.port != baseUri.port) {
|
| - return uri;
|
| - }
|
| - }
|
| -
|
| - baseUri = baseUri.normalizePath();
|
| - List<String> base = baseUri.pathSegments.toList();
|
| - if (base.isNotEmpty) {
|
| - base = new List<String>.from(base)..removeLast();
|
| - }
|
| - uri = uri.normalizePath();
|
| - List<String> target = uri.pathSegments.toList();
|
| - int index = 0;
|
| - while (index < base.length && index < target.length) {
|
| - if (base[index] != target[index]) {
|
| - break;
|
| - }
|
| - index++;
|
| - }
|
| - if (index == base.length) {
|
| - return new Uri(path: target.skip(index).join('/'));
|
| - } else if (index > 0) {
|
| - return new Uri(
|
| - path: '../' * (base.length - index) + target.skip(index).join('/'));
|
| - } else {
|
| - return uri;
|
| - }
|
| - }
|
| -
|
| - static bool _checkIdentifier(String string, int start, int end) {
|
| - const int a = 0x61;
|
| - const int z = 0x7a;
|
| - const int _ = 0x5f;
|
| - const int $ = 0x24;
|
| - if (start == end) return false;
|
| - for (int i = start; i < end; i++) {
|
| - var char = string.codeUnitAt(i);
|
| - if (char == _ || char == $) continue;
|
| - if ((char ^ 0x30) <= 9 && i > 0) continue;
|
| - char |= 0x20; // Lower-case letters.
|
| - if (char >= a && char <= z) continue;
|
| - throw new FormatException("Not an identifier", string, i);
|
| - }
|
| - return true;
|
| - }
|
| -}
|
|
|