mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
62d00c6d5f
* Migrate flutter conductor out of dev/tools and into its own directory * flesh out documentation * fix analysis options * fix integration test
205 lines
5.8 KiB
Dart
205 lines
5.8 KiB
Dart
// 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 'package:args/args.dart';
|
|
import 'package:args/command_runner.dart';
|
|
import 'package:file/file.dart';
|
|
import 'package:meta/meta.dart';
|
|
import 'package:platform/platform.dart';
|
|
|
|
import './repository.dart';
|
|
import './stdio.dart';
|
|
import './version.dart';
|
|
|
|
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';
|
|
|
|
/// Create a new dev release without cherry picks.
|
|
class RollDevCommand extends Command<void> {
|
|
RollDevCommand({
|
|
required this.checkouts,
|
|
required this.fileSystem,
|
|
required this.platform,
|
|
required this.stdio,
|
|
}) {
|
|
argParser.addOption(
|
|
kIncrement,
|
|
help: 'Specifies which part of the x.y.z version number to increment. Required.',
|
|
valueHelp: 'level',
|
|
allowed: <String>['y', 'z', 'm'],
|
|
allowedHelp: <String, String>{
|
|
'y': 'Indicates the first dev release after a beta release.',
|
|
'z': 'Indicates a hotfix to a stable release.',
|
|
'm': 'Indicates a standard dev release.',
|
|
},
|
|
);
|
|
argParser.addOption(
|
|
kCommit,
|
|
help: 'Specifies which git commit to roll to the dev branch. Required.',
|
|
valueHelp: 'hash',
|
|
defaultsTo: null, // This option is required
|
|
);
|
|
argParser.addFlag(
|
|
kForce,
|
|
abbr: 'f',
|
|
help: 'Force push. Necessary when the previous release had cherry-picks.',
|
|
negatable: false,
|
|
);
|
|
argParser.addFlag(
|
|
kJustPrint,
|
|
negatable: false,
|
|
help:
|
|
"Don't actually roll the dev channel; "
|
|
'just print the would-be version and quit.',
|
|
);
|
|
argParser.addFlag(
|
|
kSkipTagging,
|
|
negatable: false,
|
|
help: 'Do not create tag and push to remote, only update release branch. '
|
|
'For recovering when the script fails trying to git push to the release branch.'
|
|
);
|
|
argParser.addFlag(
|
|
kYes,
|
|
negatable: false,
|
|
abbr: 'y',
|
|
help: 'Skip the confirmation prompt.',
|
|
);
|
|
argParser.addOption(
|
|
kRemoteName,
|
|
help: 'Specifies which git remote to fetch from.',
|
|
defaultsTo: 'upstream',
|
|
);
|
|
}
|
|
|
|
final Checkouts checkouts;
|
|
final FileSystem fileSystem;
|
|
final Platform platform;
|
|
final Stdio stdio;
|
|
|
|
@override
|
|
String get name => 'roll-dev';
|
|
|
|
@override
|
|
String get description =>
|
|
'For publishing a dev release without cherry picks.';
|
|
|
|
@override
|
|
void run() {
|
|
rollDev(
|
|
argResults: argResults!,
|
|
repository: FrameworkRepository(checkouts),
|
|
stdio: stdio,
|
|
usage: argParser.usage,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Main script execution.
|
|
///
|
|
/// Returns true if publishing was successful, else false.
|
|
@visibleForTesting
|
|
bool rollDev({
|
|
required String usage,
|
|
required ArgResults argResults,
|
|
required Stdio stdio,
|
|
required FrameworkRepository repository,
|
|
}) {
|
|
final String remoteName = argResults[kRemoteName] as String;
|
|
final String level = argResults[kIncrement] as String;
|
|
final String commit = argResults[kCommit] as String;
|
|
final bool justPrint = argResults[kJustPrint] as bool;
|
|
final bool autoApprove = argResults[kYes] as bool;
|
|
final bool force = argResults[kForce] as bool;
|
|
final bool skipTagging = argResults[kSkipTagging] as bool;
|
|
|
|
if (level == null || commit == null) {
|
|
stdio.printStatus(
|
|
'roll_dev.dart --increment=level --commit=hash • update the version tags '
|
|
'and roll a new dev build.\n$usage');
|
|
return false;
|
|
}
|
|
|
|
final String remoteUrl = repository.remoteUrl(remoteName);
|
|
|
|
if (!repository.gitCheckoutClean()) {
|
|
throw Exception(
|
|
'Your git repository is not clean. Try running "git clean -fd". Warning, '
|
|
'this will delete files! Run with -n to find out which ones.');
|
|
}
|
|
|
|
repository.fetch(remoteName);
|
|
|
|
// Verify [commit] is valid
|
|
repository.reverseParse(commit);
|
|
|
|
stdio.printStatus('remoteName is $remoteName');
|
|
final Version lastVersion =
|
|
Version.fromString(repository.getFullTag(remoteName));
|
|
|
|
final Version version =
|
|
skipTagging ? lastVersion : Version.increment(lastVersion, level);
|
|
final String tagName = version.toString();
|
|
|
|
if (repository.reverseParse(lastVersion.toString()).contains(commit.trim())) {
|
|
throw Exception(
|
|
'Commit $commit is already on the dev branch as $lastVersion.');
|
|
}
|
|
|
|
if (justPrint) {
|
|
stdio.printStatus(tagName);
|
|
return false;
|
|
}
|
|
|
|
if (skipTagging && !repository.isCommitTagged(commit)) {
|
|
throw Exception(
|
|
'The $kSkipTagging flag is only supported for tagged commits.');
|
|
}
|
|
|
|
if (!force && !repository.isAncestor(commit, lastVersion.toString())) {
|
|
throw Exception(
|
|
'The previous dev tag $lastVersion is not a direct ancestor of $commit.\n'
|
|
'The flag "$kForce" is required to force push a new release past a cherry-pick.');
|
|
}
|
|
|
|
final String hash = repository.reverseParse(commit);
|
|
|
|
// [commit] can be a prefix for [hash].
|
|
assert(hash.startsWith(commit));
|
|
|
|
// PROMPT
|
|
if (autoApprove) {
|
|
stdio.printStatus(
|
|
'Publishing Flutter $version ($hash) to the "dev" channel.');
|
|
} else {
|
|
stdio.printStatus('Your tree is ready to publish Flutter $version '
|
|
'($hash) to the "dev" channel.');
|
|
stdio.write('Are you? [yes/no] ');
|
|
if (stdio.readLineSync() != 'yes') {
|
|
stdio.printError('The dev roll has been aborted.');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!skipTagging) {
|
|
repository.tag(commit, version.toString(), remoteName);
|
|
}
|
|
|
|
repository.updateChannel(
|
|
commit,
|
|
remoteName,
|
|
'dev',
|
|
force: force,
|
|
);
|
|
|
|
stdio.printStatus(
|
|
'Flutter version $version has been rolled to the "dev" channel at $remoteUrl.',
|
|
);
|
|
return true;
|
|
}
|