update_homebrew: initial cleanup

Before fixing https://github.com/dart-lang/homebrew-dart/issues/58

Change-Id: Id09065c9a732d0eb4268f2667ff1bfea635d0922
Reviewed-on: https://dart-review.googlesource.com/c/88900
Reviewed-by: Alexander Thomas <athom@google.com>
Commit-Queue: Alexander Thomas <athom@google.com>
Auto-Submit: Kevin Moore <kevmoo@google.com>
This commit is contained in:
Kevin Moore 2019-01-10 13:05:58 +00:00 committed by commit-bot@chromium.org
parent e0ede8791f
commit d908743de1
5 changed files with 164 additions and 159 deletions

View file

@ -9,14 +9,14 @@ import 'package:path/path.dart' as p;
import 'package:stack_trace/stack_trace.dart';
import 'package:update_homebrew/update_homebrew.dart';
main(List<String> args) async {
final parser = new ArgParser()
void main(List<String> args) async {
final parser = ArgParser()
..addOption('revision', abbr: 'r')
..addOption('channel', abbr: 'c', allowed: ['dev', 'stable']);
..addOption('channel', abbr: 'c', allowed: supportedChannels);
final options = parser.parse(args);
final revision = options['revision'];
final channel = options['channel'];
final revision = options['revision'] as String;
final channel = options['channel'] as String;
if ([revision, channel].contains(null)) {
print(
"Usage: generate.dart -r revision -c channel <path_to_existing_dart.rb>");
@ -31,7 +31,7 @@ main(List<String> args) async {
}
final existingDartRb = options.rest.single;
var file = new File(existingDartRb);
var file = File(existingDartRb);
if (!file.existsSync()) {
print("Expected '$existingDartRb' to exist.");

View file

@ -8,24 +8,24 @@ import 'package:args/args.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:update_homebrew/update_homebrew.dart';
main(List<String> args) async {
final parser = new ArgParser()
void main(List<String> args) async {
final parser = ArgParser()
..addOption('revision', abbr: 'r')
..addOption('channel', abbr: 'c', allowed: ['dev', 'stable'])
..addOption('channel', abbr: 'c', allowed: supportedChannels)
..addOption('key', abbr: 'k');
final options = parser.parse(args);
final revision = options['revision'];
final channel = options['channel'];
final revision = options['revision'] as String;
final channel = options['channel'] as String;
if ([revision, channel].contains(null)) {
print("Usage: update_homebrew.dart -r revision -c channel [-k ssh_key]\n"
" ssh_key should allow pushes to ${GITHUB_REPO} on github");
" ssh_key should allow pushes to $githubRepo on github");
exitCode = 1;
return;
}
Map<String, String> gitEnvironment;
final key = options['key'];
final key = options['key'] as String;
if (key != null) {
final sshWrapper = Platform.script.resolve('ssh_with_key').toFilePath();
gitEnvironment = {'GIT_SSH': sshWrapper, 'SSH_KEY_PATH': key};
@ -37,8 +37,8 @@ main(List<String> args) async {
try {
var repository = tempDir.path;
await runGit(['clone', 'git@github.com:${GITHUB_REPO}.git', '.'],
repository, gitEnvironment);
await runGit(['clone', 'git@github.com:$githubRepo.git', '.'], repository,
gitEnvironment);
await writeHomebrewInfo(channel, revision, repository);
await runGit([
'commit',

View file

@ -0,0 +1,133 @@
part of '../update_homebrew.dart';
const _files = {
'dev': [_x64File, _ia32File],
'stable': [_x64File, _ia32File]
};
const _urlBase = 'https://storage.googleapis.com/dart-archive/channels';
const _x64File = 'sdk/dartsdk-macos-x64-release.zip';
const _ia32File = 'sdk/dartsdk-macos-ia32-release.zip';
Future<String> _getHash256(
String channel, String revision, String download) async {
var client = http.Client();
try {
var api = storage.StorageApi(client);
var media = await api.objects.get('dart-archive',
'channels/$channel/release/$revision/$download.sha256sum',
downloadOptions: DownloadOptions.FullMedia) as Media;
var hashLine = await ascii.decodeStream(media.stream);
return RegExp('[0-9a-fA-F]*').stringMatch(hashLine);
} finally {
client.close();
}
}
Future<String> _getVersion(String channel, String revision) async {
var client = http.Client();
try {
var api = storage.StorageApi(client);
var media = await api.objects.get(
'dart-archive', 'channels/$channel/release/$revision/VERSION',
downloadOptions: DownloadOptions.FullMedia) as Media;
var versionObject =
await json.fuse(ascii).decoder.bind(media.stream).first as Map;
return versionObject['version'] as String;
} finally {
client.close();
}
}
Future<Map<String, String>> _getCurrentRevisions(String repository) async {
var revisions = <String, String>{};
var lines = await (File(p.join(repository, dartRbFileName))).readAsLines();
for (var channel in supportedChannels) {
/// This RegExp between release/ and /sdk matches
/// * 1 digit followed by
/// * Any number of letters, numbers, dashes and dots
/// This covers both numeric- and version-formatted revisions
///
/// Note: all of the regexp escape slashes `\` are double-escaped within the
/// Dart string
final regExp = RegExp('channels/$channel/release/(\\d[\\w\\d\\-\\.]*)/sdk');
revisions[channel] =
regExp.firstMatch(lines.firstWhere(regExp.hasMatch)).group(1);
}
return revisions;
}
Future<Map<String, Map>> _getHashes(Map<String, String> revisions) async {
var hashes = <String, Map>{};
for (var channel in supportedChannels) {
hashes[channel] = {};
for (var file in _files[channel]) {
var hash = await _getHash256(channel, revisions[channel], file);
hashes[channel][file] = hash;
}
}
return hashes;
}
String _createDartFormula(
Map revisions, Map hashes, String devVersion, String stableVersion) =>
'''
class Dart < Formula
desc "The Dart SDK"
homepage "https://www.dartlang.org/"
version "$stableVersion"
if MacOS.prefer_64_bit?
url "$_urlBase/stable/release/${revisions['stable']}/$_x64File"
sha256 "${hashes['stable'][_x64File]}"
else
url "$_urlBase/stable/release/${revisions['stable']}/$_ia32File"
sha256 "${hashes['stable'][_ia32File]}"
end
devel do
version "$devVersion"
if MacOS.prefer_64_bit?
url "$_urlBase/dev/release/${revisions['dev']}/$_x64File"
sha256 "${hashes['dev'][_x64File]}"
else
url "$_urlBase/dev/release/${revisions['dev']}/$_ia32File"
sha256 "${hashes['dev'][_ia32File]}"
end
end
def install
libexec.install Dir["*"]
bin.install_symlink "#{libexec}/bin/dart"
bin.write_exec_script Dir["#{libexec}/bin/{pub,dart?*}"]
end
def shim_script(target)
<<~EOS
#!/usr/bin/env bash
exec "#{prefix}/#{target}" "\$@"
EOS
end
def caveats; <<~EOS
Please note the path to the Dart SDK:
#{opt_libexec}
EOS
end
test do
(testpath/"sample.dart").write <<~EOS
void main() {
print(r"test message");
}
EOS
assert_equal "test message\\n", shell_output("#{bin}/dart sample.dart")
end
end
''';

View file

@ -7,166 +7,34 @@ import 'package:googleapis/storage/v1.dart' as storage;
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as p;
const GITHUB_REPO = 'dart-lang/homebrew-dart';
part 'src/impl.dart';
const CHANNELS = const ['dev', 'stable'];
const FILES = const {
'dev': const [x64File, ia32File],
'stable': const [x64File, ia32File]
};
const urlBase = 'https://storage.googleapis.com/dart-archive/channels';
const x64File = 'sdk/dartsdk-macos-x64-release.zip';
const ia32File = 'sdk/dartsdk-macos-ia32-release.zip';
const githubRepo = 'dart-lang/homebrew-dart';
const dartRbFileName = 'dart.rb';
Future<String> getHash256(
String channel, String revision, String download) async {
var client = new http.Client();
try {
var api = new storage.StorageApi(client);
var media = await api.objects.get('dart-archive',
'channels/$channel/release/$revision/$download.sha256sum',
downloadOptions: DownloadOptions.FullMedia);
Iterable<String> get supportedChannels => _files.keys;
var hashLine = await ascii.decodeStream(media.stream);
return new RegExp('[0-9a-fA-F]*').stringMatch(hashLine);
} finally {
client.close();
}
}
Future<String> getVersion(String channel, String revision) async {
var client = new http.Client();
try {
var api = new storage.StorageApi(client);
var media = await api.objects.get(
'dart-archive', 'channels/$channel/release/$revision/VERSION',
downloadOptions: DownloadOptions.FullMedia);
var versionObject =
await json.fuse(ascii).decoder.bind(media.stream).first as Map;
return versionObject['version'];
} finally {
client.close();
}
}
Future<Map> getCurrentRevisions(String repository) async {
var revisions = <String, String>{};
var lines =
await (new File(p.join(repository, dartRbFileName))).readAsLines();
for (var channel in CHANNELS) {
/// This RegExp between release/ and /sdk matches
/// * 1 digit followed by
/// * Any number of letters, numbers, dashes and dots
/// This covers both numeric- and version-formatted revisions
///
/// Note: all of the regexp escape slashes `\` are double-escaped within the
/// Dart string
final regExp =
new RegExp('channels/$channel/release/(\\d[\\w\\d\\-\\.]*)/sdk');
revisions[channel] =
regExp.firstMatch(lines.firstWhere(regExp.hasMatch)).group(1);
}
return revisions;
}
Future<Map> getHashes(Map revisions) async {
var hashes = <String, Map>{};
for (var channel in CHANNELS) {
hashes[channel] = {};
for (var file in FILES[channel]) {
var hash = await getHash256(channel, revisions[channel], file);
hashes[channel][file] = hash;
}
}
return hashes;
}
Future writeHomebrewInfo(
Future<void> writeHomebrewInfo(
String channel, String revision, String repository) async {
var revisions = await getCurrentRevisions(repository);
var revisions = await _getCurrentRevisions(repository);
if (revisions[channel] == revision) {
print("Channel $channel is already at revision $revision in homebrew.");
exit(0);
}
revisions[channel] = revision;
var hashes = await getHashes(revisions);
var devVersion = await getVersion('dev', revisions['dev']);
var hashes = await _getHashes(revisions);
var devVersion = await _getVersion('dev', revisions['dev']);
var stableVersion = await getVersion('stable', revisions['stable']);
var stableVersion = await _getVersion('stable', revisions['stable']);
await new File(p.join(repository, dartRbFileName)).writeAsString(
createDartFormula(revisions, hashes, devVersion, stableVersion),
await File(p.join(repository, dartRbFileName)).writeAsString(
_createDartFormula(revisions, hashes, devVersion, stableVersion),
flush: true);
}
String createDartFormula(
Map revisions, Map hashes, String devVersion, String stableVersion) =>
'''
class Dart < Formula
desc "The Dart SDK"
homepage "https://www.dartlang.org/"
version "$stableVersion"
if MacOS.prefer_64_bit?
url "$urlBase/stable/release/${revisions['stable']}/$x64File"
sha256 "${hashes['stable'][x64File]}"
else
url "$urlBase/stable/release/${revisions['stable']}/$ia32File"
sha256 "${hashes['stable'][ia32File]}"
end
devel do
version "$devVersion"
if MacOS.prefer_64_bit?
url "$urlBase/dev/release/${revisions['dev']}/$x64File"
sha256 "${hashes['dev'][x64File]}"
else
url "$urlBase/dev/release/${revisions['dev']}/$ia32File"
sha256 "${hashes['dev'][ia32File]}"
end
end
def install
libexec.install Dir["*"]
bin.install_symlink "#{libexec}/bin/dart"
bin.write_exec_script Dir["#{libexec}/bin/{pub,dart?*}"]
end
def shim_script(target)
<<~EOS
#!/usr/bin/env bash
exec "#{prefix}/#{target}" "\$@"
EOS
end
def caveats; <<~EOS
Please note the path to the Dart SDK:
#{opt_libexec}
EOS
end
test do
(testpath/"sample.dart").write <<~EOS
void main() {
print(r"test message");
}
EOS
assert_equal "test message\\n", shell_output("#{bin}/dart sample.dart")
end
end
''';
Future runGit(List<String> args, String repository,
Future<void> runGit(List<String> args, String repository,
Map<String, String> gitEnvironment) async {
print("git ${args.join(' ')}");

View file

@ -1,5 +1,9 @@
name: update_homebrew
version: 0.1.0
publish_to: none
environment:
sdk: '>=2.0.0 <3.0.0'
dependencies:
_discoveryapis_commons: ^0.1.3+1
args: ^1.5.0