blob: 890a127ebfe1a3d75ae2ade8871c9bbb724fe822 [file] [log] [blame]
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:_discoveryapis_commons/_discoveryapis_commons.dart';
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';
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 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);
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(
String channel, String revision, String repository) async {
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 stableVersion = await getVersion('stable', revisions['stable']);
await new 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,
Map<String, String> gitEnvironment) async {
print("git ${args.join(' ')}");
var result = await Process.run('git', args,
workingDirectory: repository, environment: gitEnvironment);
print(result.stdout);
print(result.stderr);
}