Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: sdk/lib/_internal/pub/test/serve_packages.dart

Issue 488323002: Make servePackages's contents argument saner. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, 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 serve_packages;
6
7 import 'dart:async';
8 import 'dart:convert';
9
10 import 'package:path/path.dart' as p;
11 import 'package:scheduled_test/scheduled_test.dart';
12 import 'package:yaml/yaml.dart';
13
14 import '../lib/src/io.dart';
15 import '../lib/src/utils.dart';
16 import '../lib/src/version.dart';
17 import 'descriptor.dart' as d;
18 import 'test_pub.dart';
19
20 /// The [d.DirectoryDescriptor] describing the server layout of `/api/packages`
21 /// on the test server.
22 ///
23 /// This contains metadata for packages that are being served via
24 /// [servePackages]. It's `null` if [servePackages] has not yet been called for
25 /// this test.
26 d.DirectoryDescriptor _servedApiPackageDir;
27
28 /// The [d.DirectoryDescriptor] describing the server layout of `/packages` on
29 /// the test server.
30 ///
31 /// This contains the tarballs for packages that are being served via
32 /// [servePackages]. It's `null` if [servePackages] has not yet been called for
33 /// this test.
34 d.DirectoryDescriptor _servedPackageDir;
35
36 PackageServerBuilder _builder;
37
38 /// Creates an HTTP server that replicates the structure of pub.dartlang.org.
39 ///
40 /// [pubspecs] is a list of unserialized pubspecs representing the packages to
41 /// serve.
42 ///
43 /// If [replace] is false, subsequent calls to [servePackages] will add to the
44 /// set of packages that are being served. Previous packages will continue to be
45 /// served. Otherwise, the previous packages will no longer be served.
46 ///
47 /// If [contents] is given, it should be a map from package names and versions
48 /// (e.g. "foo-1.2.3") to their contents.
Bob Nystrom 2014/08/21 16:44:17 Remove this.
nweiz 2014/08/21 18:28:51 Done.
49 ///
50 /// If [serveBarback] is true, the repo versions of barback and its dependencies
51 /// will be served as well.
Bob Nystrom 2014/08/21 16:44:17 Remove this.
nweiz 2014/08/21 18:28:52 Done.
52 void servePackages(void callback(PackageServerBuilder builder),
53 {bool replace: false}) {
Bob Nystrom 2014/08/21 16:44:17 Ah, now I see why builder isn't optional. You *cou
nweiz 2014/08/21 18:28:52 Done.
54 if (_servedPackageDir == null) {
55 _builder = new PackageServerBuilder();
56 _servedApiPackageDir = d.dir('packages', []);
57 _servedPackageDir = d.dir('packages', []);
58 serve([
59 d.dir('api', [_servedApiPackageDir]),
60 _servedPackageDir
61 ]);
62
63 currentSchedule.onComplete.schedule(() {
64 _builder = null;
65 _servedApiPackageDir = null;
66 _servedPackageDir = null;
67 }, 'cleaning up served packages');
68 }
69
70 schedule(() {
71 if (replace) _builder = new PackageServerBuilder();
72 callback(_builder);
73 return _builder._await().then((resolvedPubspecs) {
74 _servedApiPackageDir.contents.clear();
75 _servedPackageDir.contents.clear();
76 _builder._packages.forEach((name, versions) {
77 _servedApiPackageDir.contents.addAll([
78 d.file('$name', JSON.encode({
79 'name': name,
80 'uploaders': ['nweiz@google.com'],
81 'versions': versions.map((version) =>
82 packageVersionApiMap(version.pubspec)).toList()
83 })),
84 d.dir(name, [
85 d.dir('versions', versions.map((version) {
86 return d.file(version.version.toString(), JSON.encode(
87 packageVersionApiMap(version.pubspec, full: true)));
88 }))
89 ])
90 ]);
91
92 _servedPackageDir.contents.add(d.dir(name, [
93 d.dir('versions', versions.map((version) =>
94 d.tar('${version.version}.tar.gz', version.contents)))
95 ]));
96 });
97 });
98 }, 'initializing the package server');
99 }
100
101 class PackageServerBuilder {
Bob Nystrom 2014/08/21 16:44:17 Doc comment here and below.
nweiz 2014/08/21 18:28:52 Done.
102 final _packages = new Map<String, List<_ServedPackage>>();
103 var _futures = new FutureGroup();
Bob Nystrom 2014/08/21 16:44:17 I know it's initialized here, but I think we still
nweiz 2014/08/21 18:28:52 I don't think we're consistent either way. Why wou
104
105 void serve(String name, String version, {Map pubspec,
106 Iterable<d.Descriptor> contents}) {
107 _futures.add(awaitObject(pubspec)).then((resolvedPubspec) {
108 var pubspecFields = {
109 "name": name,
110 "version": version
111 };
112 if (resolvedPubspec != null) pubspecFields.addAll(resolvedPubspec);
113
114 if (contents == null) contents = [d.libDir(name, "$name $version")];
115 contents = [d.file("pubspec.yaml", yaml(pubspecFields))]
116 ..addAll(contents);
117
118 var packages = _packages.putIfAbsent(name, () => []);
119 packages.add(new _ServedPackage(pubspecFields, contents));
120 });
121 }
122
123 void serveRepoPackage(String package) {
124 _addPackage(name) {
125 if (_packages.containsKey(name)) return;
126 _packages[name] = [];
127
128 var pubspec = new Map.from(loadYaml(
129 readTextFile(p.join(repoRoot, 'pkg', name, 'pubspec.yaml'))));
130
131 // Remove any SDK constraints since we don't have a valid SDK version
132 // while testing.
133 pubspec.remove('environment');
134
135 _packages[name].add(new _ServedPackage(pubspec, [
136 d.file('pubspec.yaml', yaml(pubspec)),
137 new d.DirectoryDescriptor.fromFilesystem('lib',
138 p.join(repoRoot, 'pkg', name, 'lib'))
139 ]));
140
141 if (pubspec.containsKey('dependencies')) {
142 pubspec['dependencies'].keys.forEach(_addPackage);
143 }
144 }
145
146 _addPackage(package);
147 }
148
149 Future _await() {
150 if (_futures.futures.isEmpty) return new Future.value();
151 return _futures.future.then((_) => _futures = new FutureGroup());
Bob Nystrom 2014/08/21 16:44:17 The intent here isn't to return the FutureGroup, r
nweiz 2014/08/21 18:28:52 Done.
152 }
153 }
154
155 class _ServedPackage {
156 final Map pubspec;
157 final List<d.Descriptor> contents;
158
159 Version get version => new Version.parse(pubspec['version']);
160
161 _ServedPackage(this.pubspec, this.contents);
162 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698