OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library update_homebrew; | 5 library update_homebrew; |
6 | 6 |
7 import 'dart:async'; | |
8 import 'dart:convert'; | |
7 import 'dart:io'; | 9 import 'dart:io'; |
8 import 'dart:convert'; | 10 |
9 import 'dart:async'; | 11 import 'package:args/args.dart'; |
12 import 'package:googleapis/common/common.dart' show DownloadOptions, Media; | |
13 import 'package:googleapis/storage/v1.dart' as storage; | |
10 import 'package:http/http.dart' as http; | 14 import 'package:http/http.dart' as http; |
11 import 'package:args/args.dart'; | 15 import 'package:stack_trace/stack_trace.dart'; |
12 import 'package:googleapis/storage/v1.dart' as storage; | |
13 import 'package:googleapis/common/common.dart' show DownloadOptions, Media; | |
14 | 16 |
15 String repository; // The path to the temporary git checkout of dart-homebrew. | 17 String repository; // The path to the temporary git checkout of dart-homebrew. |
16 Map gitEnvironment; // Pass a wrapper script for SSH to git in the environment. | 18 Map gitEnvironment; // Pass a wrapper script for SSH to git in the environment. |
17 | 19 |
18 final CHANNELS = ['dev', 'stable']; | 20 const _githubRepo = 'dart-lang/homebrew-dart'; |
Bill Hesse
2015/06/01 07:38:48
No other const or identifier in the script is priv
kevmoo
2015/06/01 16:51:29
Done.
| |
19 | 21 |
20 final SDK_FILES = ['sdk/dartsdk-macos-x64-release.zip', | 22 final CHANNELS = const ['dev', 'stable']; |
21 'sdk/dartsdk-macos-ia32-release.zip' ]; | 23 |
22 final DARTIUM_FILES = ['dartium/dartium-macos-ia32-release.zip', | 24 final SDK_FILES = const [ |
23 'dartium/content_shell-macos-ia32-release.zip']; | 25 'sdk/dartsdk-macos-x64-release.zip', |
26 'sdk/dartsdk-macos-ia32-release.zip' | |
27 ]; | |
28 final DARTIUM_FILES = const [ | |
29 'dartium/dartium-macos-ia32-release.zip', | |
30 'dartium/content_shell-macos-ia32-release.zip' | |
31 ]; | |
24 final FILES = []..addAll(SDK_FILES)..addAll(DARTIUM_FILES); | 32 final FILES = []..addAll(SDK_FILES)..addAll(DARTIUM_FILES); |
25 | 33 |
34 Future<String> getHash256(String channel, int revision, String download) async { | |
35 var client = new http.Client(); | |
36 try { | |
37 var api = new storage.StorageApi(client); | |
38 var media = await api.objects.get('dart-archive', | |
39 'channels/$channel/release/$revision/$download.sha256sum', | |
40 downloadOptions: DownloadOptions.FullMedia); | |
26 | 41 |
27 Future<String> getHash256(String channel, int revision, String download) { | 42 var hashLine = await ASCII.decodeStream(media.stream); |
28 var client = new http.Client(); | 43 return new RegExp('[0-9a-fA-F]*').stringMatch(hashLine); |
29 var api = new storage.StorageApi(client); | 44 } finally { |
30 return | 45 client.close(); |
31 api.objects.get('dart-archive', | 46 } |
32 'channels/$channel/release/$revision/$download.sha256sum', | |
33 downloadOptions: DownloadOptions.FullMedia) | |
34 .then((Media media) => ASCII.decodeStream(media.stream)) | |
35 .then((hashLine) => new RegExp('[0-9a-fA-F]*').stringMatch(hashLine)) | |
36 .whenComplete(client.close); | |
37 } | 47 } |
38 | 48 |
39 Future<String> getVersion(String channel, int revision) { | 49 Future<String> getVersion(String channel, int revision) async { |
40 var client = new http.Client(); | 50 var client = new http.Client(); |
41 var api = new storage.StorageApi(client); | 51 try { |
42 return api.objects.get('dart-archive', | 52 var api = new storage.StorageApi(client); |
43 'channels/$channel/release/$revision/VERSION', | 53 |
44 downloadOptions: DownloadOptions.FullMedia) | 54 var media = await api.objects.get( |
45 .then((Media media) => JSON.fuse(ASCII).decoder.bind(media.stream).first) | 55 'dart-archive', 'channels/$channel/release/$revision/VERSION', |
46 .then((versionObject) => versionObject['version']) | 56 downloadOptions: DownloadOptions.FullMedia); |
47 .whenComplete(client.close); | 57 |
58 var versionObject = await JSON.fuse(ASCII).decoder.bind(media.stream).first; | |
59 return versionObject['version']; | |
60 } finally { | |
61 client.close(); | |
62 } | |
48 } | 63 } |
49 | 64 |
50 Future setCurrentRevisions(Map revisions) { | 65 Future setCurrentRevisions(Map revisions) async { |
51 return new File('$repository/dart.rb') | 66 var lines = await (new File('$repository/dart.rb')).readAsLines(); |
52 .readAsLines() | 67 |
53 .then((lines) { | 68 for (var channel in CHANNELS) { |
54 for (var channel in CHANNELS) { | 69 final regExp = new RegExp('channels/$channel/release/(\\d*)/sdk'); |
55 final regExp = new RegExp('channels/$channel/release/(\\d*)/sdk'); | 70 revisions[channel] = |
56 revisions[channel] = | 71 regExp.firstMatch(lines.firstWhere(regExp.hasMatch)).group(1); |
57 » regExp.firstMatch(lines.firstWhere(regExp.hasMatch)).group(1); | 72 } |
58 } | |
59 }); | |
60 } | 73 } |
61 | 74 |
62 Future setHashes(Map revisions, Map hashes) { | 75 Future setHashes(Map revisions, Map hashes) { |
63 List waitOn = []; | 76 List waitOn = []; |
64 for (var channel in CHANNELS) { | 77 for (var channel in CHANNELS) { |
65 hashes[channel] = {}; | 78 hashes[channel] = {}; |
66 for (var file in FILES) { | 79 for (var file in FILES) { |
67 waitOn.add(getHash256(channel, revisions[channel], file).then((hash) { | 80 waitOn.add(getHash256(channel, revisions[channel], file).then((hash) { |
68 hashes[channel][file] = hash; | 81 hashes[channel][file] = hash; |
69 })); | 82 })); |
70 } | 83 } |
71 } | 84 } |
72 return Future.wait(waitOn); | 85 return Future.wait(waitOn); |
73 } | 86 } |
74 | 87 |
75 Future writeHomebrewInfo(String channel, int revision) { | 88 Future writeHomebrewInfo(String channel, int revision) async { |
76 var revisions = {}; | 89 var revisions = {}; |
77 var hashes = {}; | 90 var hashes = {}; |
78 var devVersion; | 91 |
79 var stableVersion; | 92 await setCurrentRevisions(revisions); |
80 return setCurrentRevisions(revisions).then((_) { | 93 |
81 if (revisions[channel] == revision) { | 94 if (revisions[channel] == revision) { |
82 print("Channel $channel is already at revision $revision in homebrew."); | 95 print("Channel $channel is already at revision $revision in homebrew."); |
83 exit(0); | 96 exit(0); |
84 } | 97 } |
85 revisions[channel] = revision; | 98 revisions[channel] = revision; |
86 return setHashes(revisions, hashes); | 99 await setHashes(revisions, hashes); |
87 }).then((_) { | 100 var devVersion = await getVersion('dev', revisions['dev']); |
88 return getVersion('dev', revisions['dev']); | 101 |
89 }).then((version) { | 102 var stableVersion = await getVersion('stable', revisions['stable']); |
90 devVersion = version; | 103 |
91 return getVersion('stable', revisions['stable']); | 104 await (new File('$repository/dartium.rb').openWrite() |
92 }).then((version) { | 105 ..write(DartiumFile(revisions, hashes, devVersion, stableVersion))).close(); |
93 stableVersion = version; | 106 await (new File('$repository/dart.rb').openWrite() |
94 return (new File('$repository/dartium.rb').openWrite() | 107 ..write(DartFile(revisions, hashes, devVersion, stableVersion))).close(); |
95 ..write(DartiumFile(revisions, hashes, devVersion, stableVersion))) | |
96 .close(); | |
97 }).then((_) { | |
98 return (new File('$repository/dart.rb').openWrite() | |
99 ..write(DartFile(revisions, hashes, devVersion, stableVersion))) | |
100 .close(); | |
101 }); | |
102 } | 108 } |
103 | 109 |
104 String DartiumFile(Map revisions, | 110 String DartiumFile( |
105 Map hashes, | 111 Map revisions, Map hashes, String devVersion, String stableVersion) { |
106 String devVersion, | |
107 String stableVersion) { | |
108 final urlBase = 'https://storage.googleapis.com/dart-archive/channels'; | 112 final urlBase = 'https://storage.googleapis.com/dart-archive/channels'; |
109 final dartiumFile = 'dartium/dartium-macos-ia32-release.zip'; | 113 final dartiumFile = 'dartium/dartium-macos-ia32-release.zip'; |
110 final contentShellFile = 'dartium/content_shell-macos-ia32-release.zip'; | 114 final contentShellFile = 'dartium/content_shell-macos-ia32-release.zip'; |
111 | 115 |
112 return ''' | 116 return ''' |
113 require 'formula' | 117 require 'formula' |
114 | 118 |
115 class Dartium < Formula | 119 class Dartium < Formula |
116 homepage "https://www.dartlang.org" | 120 homepage "https://www.dartlang.org" |
117 | 121 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 EOS | 164 EOS |
161 end | 165 end |
162 | 166 |
163 test do | 167 test do |
164 system "#{bin}/dartium" | 168 system "#{bin}/dartium" |
165 end | 169 end |
166 end | 170 end |
167 '''; | 171 '''; |
168 } | 172 } |
169 | 173 |
170 String DartFile(Map revisions, | 174 String DartFile( |
171 Map hashes, | 175 Map revisions, Map hashes, String devVersion, String stableVersion) { |
172 String devVersion, | |
173 String stableVersion) { | |
174 final urlBase = 'https://storage.googleapis.com/dart-archive/channels'; | 176 final urlBase = 'https://storage.googleapis.com/dart-archive/channels'; |
175 final x64File = 'sdk/dartsdk-macos-x64-release.zip'; | 177 final x64File = 'sdk/dartsdk-macos-x64-release.zip'; |
176 final ia32File = 'sdk/dartsdk-macos-ia32-release.zip'; | 178 final ia32File = 'sdk/dartsdk-macos-ia32-release.zip'; |
177 | 179 |
178 return ''' | 180 return ''' |
179 require 'formula' | 181 require 'formula' |
180 | 182 |
181 class Dart < Formula | 183 class Dart < Formula |
182 homepage 'https://www.dartlang.org/' | 184 homepage 'https://www.dartlang.org/' |
183 | 185 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 print(r"test message"); | 221 print(r"test message"); |
220 } | 222 } |
221 EOS | 223 EOS |
222 | 224 |
223 assert_equal "test message\\n", shell_output("#{bin}/dart sample.dart") | 225 assert_equal "test message\\n", shell_output("#{bin}/dart sample.dart") |
224 end | 226 end |
225 end | 227 end |
226 '''; | 228 '''; |
227 } | 229 } |
228 | 230 |
229 Future runGit(List<String> args) { | 231 Future runGit(List<String> args) async { |
230 print("git ${args.join(' ')}"); | 232 print("git ${args.join(' ')}"); |
231 return Process.run('git', args, workingDirectory: repository, | 233 |
232 environment: gitEnvironment) | 234 var result = await Process.run('git', args, |
233 .then((result) { | 235 workingDirectory: repository, environment: gitEnvironment); |
234 print(result.stdout); | 236 |
235 print(result.stderr); | 237 print(result.stdout); |
236 }); | 238 print(result.stderr); |
237 } | 239 } |
238 | 240 |
239 main(args) { | 241 main(args) async { |
240 final parser = new ArgParser() | 242 final parser = new ArgParser() |
241 ..addOption('revision', abbr: 'r') | 243 ..addOption('revision', abbr: 'r') |
242 ..addOption('channel', abbr: 'c', allowed: ['dev', 'stable']) | 244 ..addOption('channel', abbr: 'c', allowed: ['dev', 'stable']) |
243 ..addOption('key', abbr: 'k'); | 245 ..addOption('key', abbr: 'k'); |
244 final options = parser.parse(args); | 246 final options = parser.parse(args); |
245 final revision = options['revision']; | 247 final revision = options['revision']; |
246 final channel = options['channel']; | 248 final channel = options['channel']; |
247 if ([revision, channel, options['key']].contains(null)) { | 249 final key = options['key']; |
250 if ([revision, channel, key].contains(null)) { | |
248 print("Usage: update_homebrew.dart -r revision -c channel -k ssh_key\n" | 251 print("Usage: update_homebrew.dart -r revision -c channel -k ssh_key\n" |
249 " ssh_key should allow pushes to dart-lang/homebrew-dart on github"); | 252 " ssh_key should allow pushes to ${_githubRepo} on github"); |
250 return; | 253 return; |
251 } | 254 } |
252 final sshWrapper = Platform.script.resolve('ssh_with_key').toFilePath(); | 255 final sshWrapper = Platform.script.resolve('ssh_with_key').toFilePath(); |
253 gitEnvironment = {'GIT_SSH': sshWrapper, | 256 gitEnvironment = {'GIT_SSH': sshWrapper, 'SSH_KEY_PATH': key}; |
254 'SSH_KEY_PATH': options['key']}; | |
255 | 257 |
256 Directory.systemTemp.createTemp('update_homebrew') | 258 Chain.capture(() async { |
257 .then((tempDir) { | 259 var tempDir = await Directory.systemTemp.createTemp('update_homebrew'); |
258 repository = tempDir.path; | 260 |
259 }) | 261 try { |
260 .then((_) => runGit( | 262 repository = tempDir.path; |
261 ['clone', 'git@github.com:dart-lang/homebrew-dart.git', '.'])) | 263 |
262 .then((_) => writeHomebrewInfo(channel, revision)) | 264 await runGit(['clone', 'git@github.com:${_githubRepo}.git', '.']); |
263 .then((_) => runGit(['commit', '-a', '-m', | 265 await writeHomebrewInfo(channel, revision); |
264 'Updated $channel branch to revision $revision'])) | 266 await runGit([ |
265 .then((_) => runGit(['push'])) | 267 'commit', |
266 .whenComplete(() => new Directory(repository).delete(recursive: true)); | 268 '-a', |
269 '-m', | |
270 'Updated $channel branch to revision $revision' | |
271 ]); | |
272 | |
273 await runGit(['push']); | |
274 } finally { | |
275 await tempDir.delete(recursive: true); | |
276 } | |
277 }, onError: (error, chain) { | |
278 print(error); | |
279 print(chain.terse); | |
280 }); | |
267 } | 281 } |
OLD | NEW |