-
Notifications
You must be signed in to change notification settings - Fork 30.2k
[flutter_conductor] update dev/tools with release tool #69791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e3dec5a
5d59aa4
c2d602c
060c91d
3f22653
aa63c04
72602a3
4527a8c
edf8dba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| checkouts/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| # Needed because if it is set, cd may print the path it changed to. | ||
| unset CDPATH | ||
|
|
||
| # On Mac OS, readlink -f doesn't work, so follow_links traverses the path one | ||
| # link at a time, and then cds into the link destination and find out where it | ||
| # ends up. | ||
| # | ||
| # The returned filesystem path must be a format usable by Dart's URI parser, | ||
| # since the Dart command line tool treats its argument as a file URI, not a | ||
| # filename. For instance, multiple consecutive slashes should be reduced to a | ||
| # single slash, since double-slashes indicate a URI "authority", and these are | ||
| # supposed to be filenames. There is an edge case where this will return | ||
| # multiple slashes: when the input resolves to the root directory. However, if | ||
| # that were the case, we wouldn't be running this shell, so we don't do anything | ||
| # about it. | ||
| # | ||
| # The function is enclosed in a subshell to avoid changing the working directory | ||
| # of the caller. | ||
| function follow_links() ( | ||
| cd -P "$(dirname -- "$1")" | ||
| file="$PWD/$(basename -- "$1")" | ||
| while [[ -h "$file" ]]; do | ||
| cd -P "$(dirname -- "$file")" | ||
| file="$(readlink -- "$file")" | ||
| cd -P "$(dirname -- "$file")" | ||
| file="$PWD/$(basename -- "$file")" | ||
| done | ||
| echo "$file" | ||
| ) | ||
|
|
||
| PROG_NAME="$(follow_links "${BASH_SOURCE[0]}")" | ||
| BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" | ||
| DART_BIN="$BIN_DIR/../../../bin/dart" | ||
|
|
||
| "$DART_BIN" --enable-asserts "$BIN_DIR/conductor.dart" "$@" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| // Copyright 2014 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| // Rolls the dev channel. | ||
| // Only tested on Linux. | ||
| // | ||
| // See: https://github.com/flutter/flutter/wiki/Release-process | ||
|
|
||
| import 'dart:io' as io; | ||
|
|
||
| import 'package:args/command_runner.dart'; | ||
| import 'package:file/file.dart'; | ||
| import 'package:file/local.dart'; | ||
| import 'package:platform/platform.dart'; | ||
| import 'package:process/process.dart'; | ||
| import 'package:dev_tools/repository.dart'; | ||
| import 'package:dev_tools/roll_dev.dart'; | ||
| import 'package:dev_tools/stdio.dart'; | ||
|
|
||
| void main(List<String> args) { | ||
| const FileSystem fileSystem = LocalFileSystem(); | ||
| const ProcessManager processManager = LocalProcessManager(); | ||
| const Platform platform = LocalPlatform(); | ||
| final Stdio stdio = VerboseStdio( | ||
| stdout: io.stdout, | ||
| stderr: io.stderr, | ||
| stdin: io.stdin, | ||
| ); | ||
| final Checkouts checkouts = Checkouts( | ||
| fileSystem: fileSystem, | ||
| platform: platform, | ||
| processManager: processManager, | ||
| ); | ||
| final CommandRunner<void> runner = CommandRunner<void>( | ||
| 'conductor', | ||
| 'A tool for coordinating Flutter releases.', | ||
| usageLineLength: 80, | ||
| ); | ||
|
|
||
| <Command<void>>[ | ||
| RollDev( | ||
| fileSystem: fileSystem, | ||
| platform: platform, | ||
| repository: checkouts.addRepo( | ||
| fileSystem: fileSystem, | ||
| platform: platform, | ||
| repoType: RepositoryType.framework, | ||
| stdio: stdio, | ||
| ), | ||
| stdio: stdio, | ||
| ), | ||
| ].forEach(runner.addCommand); | ||
|
|
||
| if (!assertsEnabled()) { | ||
| stdio.printError('The conductor tool must be run with --enable-asserts.'); | ||
| io.exit(1); | ||
| } | ||
|
|
||
| try { | ||
| runner.run(args); | ||
| } on Exception catch (e) { | ||
| stdio.printError(e.toString()); | ||
| io.exit(1); | ||
| } | ||
| } | ||
|
|
||
| bool assertsEnabled() { | ||
| // Verify asserts enabled | ||
| bool assertsEnabled = false; | ||
|
|
||
| assert(() { | ||
| assertsEnabled = true; | ||
| return true; | ||
| }()); | ||
| return assertsEnabled; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| // Copyright 2014 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| import 'dart:io'; | ||
|
|
||
| import 'package:meta/meta.dart'; | ||
| import 'package:process/process.dart'; | ||
|
|
||
| import './globals.dart'; | ||
|
|
||
| /// A wrapper around git process calls that can be mocked for unit testing. | ||
| class Git { | ||
| Git(this.processManager) : assert(processManager != null); | ||
|
|
||
| final ProcessManager processManager; | ||
|
|
||
| String getOutput( | ||
| List<String> args, | ||
| String explanation, { | ||
| @required String workingDirectory, | ||
| }) { | ||
| final ProcessResult result = _run(args, workingDirectory); | ||
| if (result.exitCode == 0) { | ||
| return stdoutToString(result.stdout); | ||
| } | ||
| _reportFailureAndExit(args, workingDirectory, result, explanation); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just a note, once this is opted into null safety you can give |
||
| return null; // for the analyzer's sake | ||
| } | ||
|
|
||
| int run( | ||
| List<String> args, | ||
| String explanation, { | ||
| bool allowNonZeroExitCode = false, | ||
| @required String workingDirectory, | ||
| }) { | ||
| final ProcessResult result = _run(args, workingDirectory); | ||
| if (result.exitCode != 0 && !allowNonZeroExitCode) { | ||
| _reportFailureAndExit(args, workingDirectory, result, explanation); | ||
| } | ||
| return result.exitCode; | ||
| } | ||
|
|
||
| ProcessResult _run(List<String> args, String workingDirectory) { | ||
| return processManager.runSync( | ||
| <String>['git', ...args], | ||
| workingDirectory: workingDirectory, | ||
| ); | ||
| } | ||
|
|
||
| void _reportFailureAndExit( | ||
| List<String> args, | ||
| String workingDirectory, | ||
| ProcessResult result, | ||
| String explanation, | ||
| ) { | ||
| final StringBuffer message = StringBuffer(); | ||
| if (result.exitCode != 0) { | ||
| message.writeln( | ||
| 'Command "git ${args.join(' ')}" failed in directory "$workingDirectory" to ' | ||
| '$explanation. Git exited with error code ${result.exitCode}.', | ||
| ); | ||
| } else { | ||
| message.writeln('Command "git ${args.join(' ')}" failed to $explanation.'); | ||
| } | ||
| if ((result.stdout as String).isNotEmpty) | ||
| message.writeln('stdout from git:\n${result.stdout}\n'); | ||
| if ((result.stderr as String).isNotEmpty) | ||
| message.writeln('stderr from git:\n${result.stderr}\n'); | ||
| throw Exception(message); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // Copyright 2014 The Flutter Authors. All rights reserved. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. uber-nit: constants?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added the function
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SGTM
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just have an irrational fear of globals |
||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| const String kIncrement = 'increment'; | ||
| const String kCommit = 'commit'; | ||
| const String kRemoteName = 'remote'; | ||
| const String kJustPrint = 'just-print'; | ||
| const String kYes = 'yes'; | ||
| const String kForce = 'force'; | ||
| const String kSkipTagging = 'skip-tagging'; | ||
|
|
||
| const String kUpstreamRemote = 'https://github.com/flutter/flutter.git'; | ||
|
|
||
| const List<String> kReleaseChannels = <String>[ | ||
| 'stable', | ||
| 'beta', | ||
| 'dev', | ||
| 'master', | ||
| ]; | ||
|
|
||
| /// Cast a dynamic to String and trim. | ||
| String stdoutToString(dynamic input) { | ||
| final String str = input as String; | ||
| return str.trim(); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and elsewhere, I would separate the cast from the method invocation. maybe a little helper method like:
String decode(dynamic value) => (value as String).trim();but with a better name 😭
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can do that. Is your concern line numbers in the stack trace, or is there a higher level code quality concern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its a bit awkward to read with the cast inline. Another approach would be to use
toString()instead since that is defined on Object/dynamicThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
implemented
String stdoutToString(dynamic input)