LCOV - code coverage report
Current view: top level - package_config-1.0.3/lib - packages_file.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 0 82 0.0 %
Date: 2017-10-10 20:17:03 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
       2             : // for details. All rights reserved. Use of this source code is governed by a
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : library package_config.packages_file;
       6             : 
       7             : import "package:charcode/ascii.dart";
       8             : 
       9             : import "src/util.dart" show isValidPackageName;
      10             : 
      11             : /// Parses a `.packages` file into a map from package name to base URI.
      12             : ///
      13             : /// The [source] is the byte content of a `.packages` file, assumed to be
      14             : /// UTF-8 encoded. In practice, all significant parts of the file must be ASCII,
      15             : /// so Latin-1 or Windows-1252 encoding will also work fine.
      16             : ///
      17             : /// If the file content is available as a string, its [String.codeUnits] can
      18             : /// be used as the `source` argument of this function.
      19             : ///
      20             : /// The [baseLocation] is used as a base URI to resolve all relative
      21             : /// URI references against.
      22             : /// If the content was read from a file, `baseLocation` should be the
      23             : /// location of that file.
      24             : ///
      25             : /// Returns a simple mapping from package name to package location.
      26             : Map<String, Uri> parse(List<int> source, Uri baseLocation) {
      27             :   int index = 0;
      28           0 :   Map<String, Uri> result = <String, Uri>{};
      29           0 :   while (index < source.length) {
      30             :     bool isComment = false;
      31             :     int start = index;
      32             :     int separatorIndex = -1;
      33           0 :     int end = source.length;
      34           0 :     int char = source[index++];
      35           0 :     if (char == $cr || char == $lf) {
      36             :       continue;
      37             :     }
      38           0 :     if (char == $colon) {
      39           0 :       throw new FormatException("Missing package name", source, index - 1);
      40             :     }
      41           0 :     isComment = char == $hash;
      42           0 :     while (index < source.length) {
      43           0 :       char = source[index++];
      44           0 :       if (char == $colon && separatorIndex < 0) {
      45           0 :         separatorIndex = index - 1;
      46           0 :       } else if (char == $cr || char == $lf) {
      47           0 :         end = index - 1;
      48             :         break;
      49             :       }
      50             :     }
      51             :     if (isComment) continue;
      52           0 :     if (separatorIndex < 0) {
      53           0 :       throw new FormatException("No ':' on line", source, index - 1);
      54             :     }
      55           0 :     var packageName = new String.fromCharCodes(source, start, separatorIndex);
      56           0 :     if (!isValidPackageName(packageName)) {
      57           0 :       throw new FormatException("Not a valid package name", packageName, 0);
      58             :     }
      59           0 :     var packageUri = new String.fromCharCodes(source, separatorIndex + 1, end);
      60           0 :     var packageLocation = Uri.parse(packageUri);
      61           0 :     packageLocation = baseLocation.resolveUri(packageLocation);
      62           0 :     if (!packageLocation.path.endsWith('/')) {
      63             :       packageLocation =
      64           0 :           packageLocation.replace(path: packageLocation.path + "/");
      65             :     }
      66           0 :     if (result.containsKey(packageName)) {
      67           0 :       throw new FormatException(
      68             :           "Same package name occured twice.", source, start);
      69             :     }
      70           0 :     result[packageName] = packageLocation;
      71             :   }
      72             :   return result;
      73             : }
      74             : 
      75             : /// Writes the mapping to a [StringSink].
      76             : ///
      77             : /// If [comment] is provided, the output will contain this comment
      78             : /// with `# ` in front of each line.
      79             : /// Lines are defined as ending in line feed (`'\n'`). If the final
      80             : /// line of the comment doesn't end in a line feed, one will be added.
      81             : ///
      82             : /// If [baseUri] is provided, package locations will be made relative
      83             : /// to the base URI, if possible, before writing.
      84             : ///
      85             : /// All the keys of [packageMapping] must be valid package names,
      86             : /// and the values must be URIs that do not have the `package:` scheme.
      87             : void write(StringSink output, Map<String, Uri> packageMapping,
      88             :     {Uri baseUri, String comment}) {
      89           0 :   if (baseUri != null && !baseUri.isAbsolute) {
      90           0 :     throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute");
      91             :   }
      92             : 
      93             :   if (comment != null) {
      94           0 :     var lines = comment.split('\n');
      95           0 :     if (lines.last.isEmpty) lines.removeLast();
      96           0 :     for (var commentLine in lines) {
      97           0 :       output.write('# ');
      98           0 :       output.writeln(commentLine);
      99             :     }
     100             :   } else {
     101           0 :     output.write("# generated by package:package_config at ");
     102           0 :     output.write(new DateTime.now());
     103           0 :     output.writeln();
     104             :   }
     105             : 
     106           0 :   packageMapping.forEach((String packageName, Uri uri) {
     107             :     // Validate packageName.
     108           0 :     if (!isValidPackageName(packageName)) {
     109           0 :       throw new ArgumentError('"$packageName" is not a valid package name');
     110             :     }
     111           0 :     if (uri.scheme == "package") {
     112           0 :       throw new ArgumentError.value(
     113           0 :           "Package location must not be a package: URI", uri.toString());
     114             :     }
     115           0 :     output.write(packageName);
     116           0 :     output.write(':');
     117             :     // If baseUri provided, make uri relative.
     118             :     if (baseUri != null) {
     119           0 :       uri = _relativize(uri, baseUri);
     120             :     }
     121           0 :     output.write(uri);
     122           0 :     if (!uri.path.endsWith('/')) {
     123           0 :       output.write('/');
     124             :     }
     125           0 :     output.writeln();
     126             :   });
     127             : }
     128             : 
     129             : /// Attempts to return a relative URI for [uri].
     130             : ///
     131             : /// The result URI satisfies `baseUri.resolveUri(result) == uri`,
     132             : /// but may be relative.
     133             : /// The `baseUri` must be absolute.
     134             : Uri _relativize(Uri uri, Uri baseUri) {
     135             :   assert(baseUri.isAbsolute);
     136           0 :   if (uri.hasQuery || uri.hasFragment) {
     137           0 :     uri = new Uri(
     138           0 :         scheme: uri.scheme,
     139           0 :         userInfo: uri.hasAuthority ? uri.userInfo : null,
     140           0 :         host: uri.hasAuthority ? uri.host : null,
     141           0 :         port: uri.hasAuthority ? uri.port : null,
     142           0 :         path: uri.path);
     143             :   }
     144             : 
     145             :   // Already relative. We assume the caller knows what they are doing.
     146           0 :   if (!uri.isAbsolute) return uri;
     147             : 
     148           0 :   if (baseUri.scheme != uri.scheme) {
     149             :     return uri;
     150             :   }
     151             : 
     152             :   // If authority differs, we could remove the scheme, but it's not worth it.
     153           0 :   if (uri.hasAuthority != baseUri.hasAuthority) return uri;
     154           0 :   if (uri.hasAuthority) {
     155           0 :     if (uri.userInfo != baseUri.userInfo ||
     156           0 :         uri.host.toLowerCase() != baseUri.host.toLowerCase() ||
     157           0 :         uri.port != baseUri.port) {
     158             :       return uri;
     159             :     }
     160             :   }
     161             : 
     162           0 :   baseUri = _normalizePath(baseUri);
     163           0 :   List<String> base = baseUri.pathSegments.toList();
     164           0 :   if (base.isNotEmpty) {
     165           0 :     base = new List<String>.from(base)..removeLast();
     166             :   }
     167           0 :   uri = _normalizePath(uri);
     168           0 :   List<String> target = uri.pathSegments.toList();
     169           0 :   if (target.isNotEmpty && target.last.isEmpty) target.removeLast();
     170             :   int index = 0;
     171           0 :   while (index < base.length && index < target.length) {
     172           0 :     if (base[index] != target[index]) {
     173             :       break;
     174             :     }
     175           0 :     index++;
     176             :   }
     177           0 :   if (index == base.length) {
     178           0 :     if (index == target.length) {
     179           0 :       return new Uri(path: "./");
     180             :     }
     181           0 :     return new Uri(path: target.skip(index).join('/'));
     182           0 :   } else if (index > 0) {
     183           0 :     return new Uri(
     184           0 :         path: '../' * (base.length - index) + target.skip(index).join('/'));
     185             :   } else {
     186             :     return uri;
     187             :   }
     188             : }
     189             : 
     190             : // TODO: inline to uri.normalizePath() when we move to 1.11
     191           0 : Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri);

Generated by: LCOV version 1.13