diff --git a/dev/tools/lib/archive_publisher.dart b/dev/tools/lib/archive_publisher.dart index 4ea085e2b0..55481e3080 100644 --- a/dev/tools/lib/archive_publisher.dart +++ b/dev/tools/lib/archive_publisher.dart @@ -22,7 +22,7 @@ class ArchivePublisherException implements Exception { } final String stderr = result?.stderr ?? ''; if (stderr.isNotEmpty) { - output += ':\n$result.stderr'; + output += ':\n${result.stderr}'; } return output; } @@ -87,9 +87,6 @@ class ArchivePublisher { /// Publishes the archive for the given constructor parameters. bool publishArchive() { assert(channel == Channel.dev, 'Channel must be dev (beta not yet supported)'); - // Check for access early so that we don't try to publish things if the - // user doesn't have access to the metadata file. - _checkForGSUtilAccess(); final List platforms = ['linux', 'mac', 'win']; final Map metadata = {}; for (String platform in platforms) { @@ -108,12 +105,14 @@ class ArchivePublisher { /// Checks to make sure the user has access to the Google Storage bucket /// required to publish. Will throw an [ArchivePublisherException] if not. - void _checkForGSUtilAccess() { + void checkForGSUtilAccess() { // Fetching ACLs requires FULL_CONTROL access. final ProcessResult result = _runGsUtil(['acl', 'get', metadataGsPath]); if (result.exitCode != 0) { throw new ArchivePublisherException( - 'GSUtil cannot get ACLs for metadata file $metadataGsPath', result); + 'GSUtil cannot get ACLs for metadata file $metadataGsPath', + result, + ); } } diff --git a/dev/tools/lib/roll_dev.dart b/dev/tools/lib/roll_dev.dart index 4672435ef5..bba0de3589 100644 --- a/dev/tools/lib/roll_dev.dart +++ b/dev/tools/lib/roll_dev.dart @@ -16,13 +16,12 @@ const String kIncrement = 'increment'; const String kX = 'x'; const String kY = 'y'; const String kZ = 'z'; +const String kCommit = 'commit'; const String kHelp = 'help'; -void main(List args) { - // Set the cwd to the repo root, since we know where this script is located. - final Directory scriptLocation = new Directory(Platform.script.toFilePath()); - Directory.current = scriptLocation.parent.parent.parent; +const String kUpstreamRemote = 'git@github.com:flutter/flutter.git'; +void main(List args) { final ArgParser argParser = new ArgParser(allowTrailingOptions: false); argParser.addOption( kIncrement, @@ -35,6 +34,12 @@ void main(List args) { kZ: 'Indicates the least notable level of change. You normally want this.', }, ); + argParser.addOption( + kCommit, + help: 'Specifies which git commit to roll to the dev branch.', + valueHelp: 'hash', + defaultsTo: 'upstream/master', + ); argParser.addFlag(kHelp, negatable: false, help: 'Show this help message.', hide: true); ArgResults argResults; try { @@ -46,14 +51,21 @@ void main(List args) { } final String level = argResults[kIncrement]; + final bool commit = argResults[kCommit]; final bool help = argResults[kHelp]; if (help || level == null) { - print('roll_dev.dart --increment=x • update the version tags and roll a new dev build.\n'); + print('roll_dev.dart --increment=level --commit=hash • update the version tags and roll a new dev build.\n'); print(argParser.usage); exit(0); } + if (getGitOutput('remote get-url upstream', 'check whether this is a flutter checkout') != kUpstreamRemote) { + print('The current directory is not a Flutter repository checkout with a correctly configured upstream remote.'); + print('For more details see: https://github.com/flutter/flutter/wiki/Release-process'); + exit(1); + } + runGit('checkout master', 'switch to master branch'); if (getGitOutput('status --porcelain', 'check status of your local checkout') != '') { @@ -62,6 +74,9 @@ void main(List args) { exit(1); } + runGit('fetch upstream', 'fetch upstream'); + runGit('reset $commit --hard', 'check out master branch'); + String version = getFullTag(); final Match match = parseFullTag(version); if (match == null) { @@ -97,10 +112,24 @@ void main(List args) { } version = parts.join('.'); - runGit('fetch upstream', 'fetch upstream'); - runGit('reset upstream/master --hard', 'check out master branch'); + final String hash = getGitOutput('rev-parse HEAD', 'Get git hash for $commit'); + + final ArchivePublisher publisher = new ArchivePublisher(hash, version, Channel.dev); + + // Check for access early so that we don't try to publish things if the + // user doesn't have access to the metadata file. + try { + publisher.checkForGSUtilAccess(); + } on ArchivePublisherException { + print('You do not appear to have the credentials required to update the archive links.'); + print('Make sure you have "gsutil" installed, then run "gsutil config".'); + print('Talk to @gspencergoog for details on which project to use.'); + exit(1); + } + runGit('tag v$version', 'tag the commit with the version label'); - final String hash = getGitOutput('rev-parse HEAD', 'Get git hash for $version tag'); + + // PROMPT print('Your tree is ready to publish Flutter $version (${hash.substring(0, 10)}) ' 'to the "dev" channel.'); @@ -114,12 +143,12 @@ void main(List args) { // Publish the archive before pushing the tag so that if something fails in // the publish step, we can clean up. try { - new ArchivePublisher(hash, version, Channel.dev)..publishArchive(); + publisher.publishArchive(); } on ArchivePublisherException catch (e) { print('Archive publishing failed.\n$e'); - runGit('tag -d $version', 'remove the tag that was not published'); + runGit('tag -d v$version', 'remove the tag that was not published'); print('The dev roll has been aborted.'); - exit(0); + exit(1); } runGit('push upstream v$version', 'publish the version');