| 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); |
| } |