| // Copyright (c) 2013, 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. |
| |
| /// Pub-specific test descriptors. |
| import 'dart:convert'; |
| |
| import 'package:oauth2/oauth2.dart' as oauth2; |
| import 'package:pub/src/package_config.dart'; |
| import 'package:test_descriptor/test_descriptor.dart'; |
| import 'package:meta/meta.dart'; |
| import 'package:path/path.dart' as p; |
| |
| import 'descriptor/git.dart'; |
| import 'descriptor/packages.dart'; |
| import 'descriptor/tar.dart'; |
| import 'descriptor/yaml.dart'; |
| import 'test_pub.dart'; |
| |
| export 'package:test_descriptor/test_descriptor.dart'; |
| export 'descriptor/git.dart'; |
| export 'descriptor/packages.dart'; |
| export 'descriptor/tar.dart'; |
| |
| /// Creates a new [GitRepoDescriptor] with [name] and [contents]. |
| GitRepoDescriptor git(String name, [Iterable<Descriptor> contents]) => |
| GitRepoDescriptor(name, contents ?? <Descriptor>[]); |
| |
| /// Creates a new [TarFileDescriptor] with [name] and [contents]. |
| TarFileDescriptor tar(String name, [Iterable<Descriptor> contents]) => |
| TarFileDescriptor(name, contents ?? <Descriptor>[]); |
| |
| /// Describes a package that passes all validation. |
| Descriptor get validPackage => dir(appPath, [ |
| libPubspec('test_pkg', '1.0.0', sdk: '>=1.8.0 <=2.0.0'), |
| file('LICENSE', 'Eh, do what you want.'), |
| file('README.md', "This package isn't real."), |
| file('CHANGELOG.md', '# 1.0.0\nFirst version\n'), |
| dir('lib', [file('test_pkg.dart', 'int i = 1;')]) |
| ]); |
| |
| /// Returns a descriptor of a snapshot that can't be run by the current VM. |
| /// |
| /// This snapshot was generated using version 2.0.0-dev.58.0 of the VM. |
| FileDescriptor outOfDateSnapshot(String name) => file( |
| name, |
| base64.decode( |
| 'kKvN7wAAAAYBAAEAAQAAAAAAAAABBgMBBh8AAQEAAAABA' |
| 'wofAAAAAAAAAFwBShABHhAGAQABJwIAAAAAEwAAAAAAAA' |
| 'AVAAAAOQAAAAEAAAACAAAAJWZpbGU6Ly8vVXNlcnMvcm5' |
| '5c3Ryb20vdGVtcC90ZW1wLmRhcnQgdm9pZCBtYWluKCkg' |
| 'PT4gcHJpbnQoJ2hlbGxvIScpOwoDACABAAAAUQAAAFQGA' |
| 'AMBBAIBAAUEBAUGAAAAAAcABAovN0BFbWFpbmhlbGxvIW' |
| 'ZpbGU6Ly8vVXNlcnMvcm55c3Ryb20vdGVtcC90ZW1wLmR' |
| 'hcnRAbWV0aG9kc2RhcnQ6Y29yZXByaW50AAAAAE0AAACn' |
| 'AAAAtAAAALQAAAC4AAABBQAAAAMAAAAJAAAATQAAAAEAA' |
| 'AEy', |
| ), |
| ); |
| |
| /// Describes a file named `pubspec.yaml` with the given YAML-serialized |
| /// [contents], which should be a serializable object. |
| /// |
| /// [contents] may contain [Future]s that resolve to serializable objects, |
| /// which may in turn contain [Future]s recursively. |
| Descriptor pubspec(Map<String, Object> contents) => YamlDescriptor( |
| 'pubspec.yaml', |
| yaml({ |
| ...contents, |
| // TODO: Copy-pasting this into all call-sites, or use d.libPubspec |
| 'environment': { |
| 'sdk': '>=0.1.2 <1.0.0', |
| ...contents['environment'] as Map ?? {}, |
| }, |
| }), |
| ); |
| |
| Descriptor rawPubspec(Map<String, Object> contents) => |
| YamlDescriptor('pubspec.yaml', yaml(contents)); |
| |
| /// Describes a file named `pubspec.yaml` for an application package with the |
| /// given [dependencies]. |
| Descriptor appPubspec([Map dependencies]) { |
| var map = <String, dynamic>{ |
| 'name': 'myapp', |
| 'environment': { |
| 'sdk': '>=0.1.2 <1.0.0', |
| }, |
| }; |
| if (dependencies != null) map['dependencies'] = dependencies; |
| return pubspec(map); |
| } |
| |
| /// Describes a file named `pubspec.yaml` for a library package with the given |
| /// [name], [version], and [deps]. If "sdk" is given, then it adds an SDK |
| /// constraint on that version, otherwise it adds an SDK constraint allowing |
| /// the current SDK version. |
| Descriptor libPubspec(String name, String version, |
| {Map deps, Map devDeps, String sdk}) { |
| var map = packageMap(name, version, deps, devDeps); |
| if (sdk != null) { |
| map['environment'] = {'sdk': sdk}; |
| } else { |
| map['environment'] = {'sdk': '>=0.1.2 <1.0.0'}; |
| } |
| return pubspec(map); |
| } |
| |
| /// Describes a directory named `lib` containing a single dart file named |
| /// `<name>.dart` that contains a line of Dart code. |
| Descriptor libDir(String name, [String code]) { |
| // Default to printing the name if no other code was given. |
| code ??= name; |
| return dir('lib', [file('$name.dart', 'main() => "$code";')]); |
| } |
| |
| /// Describes a directory whose name ends with a hyphen followed by an |
| /// alphanumeric hash. |
| Descriptor hashDir(String name, Iterable<Descriptor> contents) => pattern( |
| RegExp("$name${r'-[a-f0-9]+'}"), (dirName) => dir(dirName, contents)); |
| |
| /// Describes a directory for a Git repo with a dart package. |
| /// This directory is of the form found in the revision cache of the global |
| /// package cache. |
| /// |
| /// If [repoName] is not given it is assumed to be equal to [packageName]. |
| Descriptor gitPackageRevisionCacheDir( |
| String packageName, { |
| int modifier, |
| String repoName, |
| }) { |
| repoName = repoName ?? packageName; |
| var value = packageName; |
| if (modifier != null) value = '$packageName $modifier'; |
| return hashDir(repoName, [libDir(packageName, value)]); |
| } |
| |
| /// Describes a directory for a Git package. This directory is of the form |
| /// found in the repo cache of the global package cache. |
| Descriptor gitPackageRepoCacheDir(String name) => |
| hashDir(name, [dir('objects'), dir('refs')]); |
| |
| /// Describes the global package cache directory containing all the given |
| /// [packages], which should be name/version pairs. The packages will be |
| /// validated against the format produced by the mock package server. |
| /// |
| /// A package's value may also be a list of versions, in which case all |
| /// versions are expected to be downloaded. |
| /// |
| /// If [port] is passed, it's used as the port number of the local hosted server |
| /// that this cache represents. It defaults to [globalServer.port]. |
| /// |
| /// If [includePubspecs] is `true`, then pubspecs will be created for each |
| /// package. Defaults to `false` so that the contents of pubspecs are not |
| /// validated since they will often lack the dependencies section that the |
| /// real pubspec being compared against has. You usually only need to pass |
| /// `true` for this if you plan to call [create] on the resulting descriptor. |
| Descriptor cacheDir(Map packages, {int port, bool includePubspecs = false}) { |
| var contents = <Descriptor>[]; |
| packages.forEach((name, versions) { |
| if (versions is! List) versions = [versions]; |
| for (var version in versions) { |
| var packageContents = [libDir(name, '$name $version')]; |
| if (includePubspecs) { |
| packageContents.add(libPubspec(name, version)); |
| } |
| contents.add(dir('$name-$version', packageContents)); |
| } |
| }); |
| |
| return hostedCache(contents, port: port); |
| } |
| |
| /// Describes the main cache directory containing cached hosted packages |
| /// downloaded from the mock package server. |
| /// |
| /// If [port] is passed, it's used as the port number of the local hosted server |
| /// that this cache represents. It defaults to [globalServer.port]. |
| Descriptor hostedCache(Iterable<Descriptor> contents, {int port}) { |
| return dir(cachePath, [ |
| dir('hosted', [dir('localhost%58${port ?? globalServer.port}', contents)]) |
| ]); |
| } |
| |
| /// Describes the file in the system cache that contains the client's OAuth2 |
| /// credentials. The URL "/token" on [server] will be used as the token |
| /// endpoint for refreshing the access token. |
| Descriptor credentialsFile(PackageServer server, String accessToken, |
| {String refreshToken, DateTime expiration}) { |
| return dir(cachePath, [ |
| file( |
| 'credentials.json', |
| oauth2.Credentials(accessToken, |
| refreshToken: refreshToken, |
| tokenEndpoint: Uri.parse(server.url).resolve('/token'), |
| scopes: [ |
| 'openid', |
| 'https://www.googleapis.com/auth/userinfo.email', |
| ], |
| expiration: expiration) |
| .toJson()) |
| ]); |
| } |
| |
| /// Describes the application directory, containing only a pubspec specifying |
| /// the given [dependencies]. |
| DirectoryDescriptor appDir([Map dependencies]) => |
| dir(appPath, [appPubspec(dependencies)]); |
| |
| /// Describes a `.packages` file. |
| /// |
| /// [dependencies] maps package names to strings describing where the packages |
| /// are located on disk. If the strings are semantic versions, then the packages |
| /// are located in the system cache; otherwise, the strings are interpreted as |
| /// relative `file:` URLs. |
| /// |
| /// Validation checks that the `.packages` file exists, has the expected |
| /// entries (one per key in [dependencies]), each with a path that contains |
| /// either the version string (for a reference to the pub cache) or a |
| /// path to a path dependency, relative to the application directory. |
| Descriptor packagesFile([Map<String, String> dependencies]) => |
| PackagesFileDescriptor(dependencies); |
| |
| /// Describes a `.dart_tools/package_config.json` file. |
| /// |
| /// [dependencies] is a list of packages included in the file. |
| /// |
| /// Validation checks that the `.dart_tools/package_config.json` file exists, |
| /// has the expected entries (one per key in [dependencies]), each with a path |
| /// that matches the `rootUri` of that package. |
| Descriptor packageConfigFile(List<PackageConfigEntry> packages) => |
| PackageConfigFileDescriptor(packages); |
| |
| /// Create a [PackageConfigEntry] which assumes package with [name] is either |
| /// a cached package with given [version] or a path dependency at given [path]. |
| PackageConfigEntry packageConfigEntry({ |
| @required String name, |
| String version, |
| String path, |
| String languageVersion, |
| }) { |
| if (version != null && path != null) { |
| throw ArgumentError.value( |
| path, 'path', 'Only one of "version" and "path" can be provided'); |
| } |
| if (version == null && path == null) { |
| throw ArgumentError.value( |
| version, 'version', 'Either "version" or "path" must be given'); |
| } |
| Uri rootUri; |
| if (version != null) { |
| rootUri = p.toUri(globalPackageServer.pathInCache(name, version)); |
| } else { |
| rootUri = p.toUri(p.join('..', path)); |
| } |
| return PackageConfigEntry( |
| name: name, |
| rootUri: rootUri, |
| packageUri: Uri(path: 'lib/'), |
| languageVersion: languageVersion, |
| ); |
| } |
| |
| /// Describes a `.packages` file in the application directory, including the |
| /// implicit entry for the app itself. |
| Descriptor appPackagesFile(Map<String, String> dependencies) { |
| var copied = Map<String, String>.from(dependencies); |
| copied['myapp'] = '.'; |
| return dir(appPath, [packagesFile(copied)]); |
| } |