|  | // Copyright 2017 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // Updates the version numbers of the Flutter repo. | 
|  | // Only tested on Linux. | 
|  | // | 
|  | // See: https://github.com/flutter/flutter/wiki/Release-process | 
|  |  | 
|  | import 'dart:io'; | 
|  |  | 
|  | import 'package:args/args.dart'; | 
|  | import 'package:meta/meta.dart'; | 
|  | import 'package:path/path.dart' as path; | 
|  |  | 
|  | const String kIncrement = 'increment'; | 
|  | const String kBrokeSdk = 'broke-sdk'; | 
|  | const String kBrokeFramework = 'broke-framework'; | 
|  | const String kBrokeTest = 'broke-test'; | 
|  | const String kBrokeDriver = 'broke-driver'; | 
|  | const String kMarkRelease = 'release'; | 
|  | const String kHelp = 'help'; | 
|  |  | 
|  | const String kYamlVersionPrefix = 'version: '; | 
|  | const String kDev = '-dev'; | 
|  |  | 
|  | enum VersionKind { dev, release } | 
|  |  | 
|  | void main(List<String> args) { | 
|  | // If we're run from the `tools` dir, set the cwd to the repo root. | 
|  | if (path.basename(Directory.current.path) == 'tools') | 
|  | Directory.current = Directory.current.parent.parent; | 
|  |  | 
|  | final ArgParser argParser = new ArgParser(); | 
|  | argParser.addFlag(kIncrement, defaultsTo: false, help: 'Increment all the version numbers. Cannot be specified with --$kMarkRelease or with any --broke-* commands.'); | 
|  | argParser.addFlag(kBrokeSdk, defaultsTo: false, negatable: false, help: 'Increment the Flutter SDK version number to indicate that there has been a breaking change to the SDK (for example, to the command line options).'); | 
|  | argParser.addFlag(kBrokeFramework, defaultsTo: false, negatable: false, help: 'Increment the "flutter" package version number to indicate that there has been a breaking change to the Flutter framework.'); | 
|  | argParser.addFlag(kBrokeTest, defaultsTo: false, negatable: false, help: 'Increment the "flutter_test" package version number to indicate that there has been a breaking change to the test API framework.'); | 
|  | argParser.addFlag(kBrokeDriver, defaultsTo: false, negatable: false, help: 'Increment the "flutter_driver" package version number to indicate that there has been a breaking change to the driver API framework.'); | 
|  | argParser.addFlag(kMarkRelease, defaultsTo: false, help: 'Remove "-dev" from each version number. This is used when releasing. When not present, "-dev" is added to each version number. Cannot be specified with --$kIncrement or with any --broke-* commands.'); | 
|  | argParser.addFlag(kHelp, negatable: false, help: 'Show this help message.'); | 
|  | final ArgResults argResults = argParser.parse(args); | 
|  |  | 
|  | final bool increment = argResults[kIncrement]; | 
|  | final bool brokeSdk = argResults[kBrokeSdk]; | 
|  | final bool brokeFramework = argResults[kBrokeFramework]; | 
|  | final bool brokeTest = argResults[kBrokeTest]; | 
|  | final bool brokeDriver = argResults[kBrokeDriver]; | 
|  | final bool brokeAnything = brokeSdk || brokeFramework || brokeTest || brokeDriver; | 
|  | final VersionKind level = argResults[kMarkRelease] ? VersionKind.release : VersionKind.dev; | 
|  | final bool help = argResults[kHelp]; | 
|  |  | 
|  | if (help) { | 
|  | print('update_versions.dart - update version numbers of Flutter packages and SDK'); | 
|  | print(argParser.usage); | 
|  | exit(0); | 
|  | } | 
|  |  | 
|  | final bool release = level == VersionKind.release; | 
|  | if ((brokeAnything && release) || (brokeAnything && increment) || (release && increment)) { | 
|  | print('You can either increment all the version numbers (--$kIncrement), indicate that some packages have had breaking changes (--broke-*), or switch to release mode (--$kMarkRelease).'); | 
|  | print('You cannot combine these, however.'); | 
|  | exit(1); | 
|  | } | 
|  |  | 
|  | final RawVersion sdk = new RawVersion('VERSION'); | 
|  | final PubSpecVersion framework = new PubSpecVersion('packages/flutter/pubspec.yaml'); | 
|  | final PubSpecVersion test = new PubSpecVersion('packages/flutter_test/pubspec.yaml'); | 
|  | final PubSpecVersion driver = new PubSpecVersion('packages/flutter_driver/pubspec.yaml'); | 
|  |  | 
|  | if (increment || brokeAnything) | 
|  | sdk.increment(brokeAnything); | 
|  | sdk.setMode(level); | 
|  |  | 
|  | if (increment || brokeFramework) | 
|  | framework.increment(brokeFramework); | 
|  | framework.setMode(level); | 
|  |  | 
|  | if (increment || brokeTest) | 
|  | test.increment(brokeTest); | 
|  | test.setMode(level); | 
|  |  | 
|  | if (increment || brokeDriver) | 
|  | driver.increment(brokeDriver); | 
|  | driver.setMode(level); | 
|  |  | 
|  | sdk.write(); | 
|  | framework.write(); | 
|  | test.write(); | 
|  | driver.write(); | 
|  |  | 
|  | print('Flutter SDK is now at version: $sdk'); | 
|  | print('flutter package is now at version: $framework'); | 
|  | print('flutter_test package is now at version: $test'); | 
|  | print('flutter_driver package is now at version: $driver'); | 
|  |  | 
|  | if (release) { | 
|  | print('\nDuring the tagging step in the instructions, the commands will be:'); | 
|  | print('git tag $sdk'); | 
|  | print('git push upstream $sdk'); | 
|  | } | 
|  | } | 
|  |  | 
|  | abstract class Version { | 
|  | Version() { | 
|  | read(); | 
|  | } | 
|  |  | 
|  | @protected | 
|  | final List<int> version = <int>[]; | 
|  |  | 
|  | @protected | 
|  | VersionKind level; | 
|  |  | 
|  | @protected | 
|  | bool dirty = false; | 
|  |  | 
|  | @protected | 
|  | void read(); | 
|  |  | 
|  | void interpret(String value) { | 
|  | level = value.endsWith(kDev) ? VersionKind.dev : VersionKind.release; | 
|  | if (level == VersionKind.dev) | 
|  | value = value.substring(0, value.length - kDev.length); | 
|  | version.addAll(value.split('.').map<int>(int.parse)); | 
|  | } | 
|  |  | 
|  | void increment(bool breaking) { | 
|  | assert(version.length == 3); | 
|  | if (breaking) { | 
|  | version[1] += 1; | 
|  | version[2] = 0; | 
|  | } else { | 
|  | version[2] += 1; | 
|  | } | 
|  | dirty = true; | 
|  | } | 
|  |  | 
|  | void setMode(VersionKind value) { | 
|  | if (value != level) { | 
|  | level = value; | 
|  | dirty = true; | 
|  | } | 
|  | } | 
|  |  | 
|  | void write(); | 
|  |  | 
|  | @override | 
|  | String toString() => version.join('.') + (level == VersionKind.dev ? kDev : ''); | 
|  | } | 
|  |  | 
|  | class PubSpecVersion extends Version { | 
|  | PubSpecVersion(this.path); | 
|  |  | 
|  | final String path; | 
|  |  | 
|  | @override | 
|  | void read() { | 
|  | final List<String> lines = new File(path).readAsLinesSync(); | 
|  | final String versionLine = lines.where((String line) => line.startsWith(kYamlVersionPrefix)).single; | 
|  | interpret(versionLine.substring(kYamlVersionPrefix.length)); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void write() { | 
|  | if (!dirty) | 
|  | return; | 
|  | final List<String> lines = new File(path).readAsLinesSync(); | 
|  | for (int index = 0; index < lines.length; index += 1) { | 
|  | final String line = lines[index]; | 
|  | if (line.startsWith(kYamlVersionPrefix)) { | 
|  | lines[index] = '$kYamlVersionPrefix$this'; | 
|  | break; | 
|  | } | 
|  | } | 
|  | new File(path).writeAsStringSync(lines.join('\n') + '\n'); | 
|  | } | 
|  | } | 
|  |  | 
|  | class RawVersion extends Version { | 
|  | RawVersion(this.path); | 
|  |  | 
|  | final String path; | 
|  |  | 
|  | @override | 
|  | void read() { | 
|  | final List<String> lines = new File(path).readAsLinesSync(); | 
|  | interpret(lines.where((String line) => line.isNotEmpty && !line.startsWith('#')).single); | 
|  | } | 
|  |  | 
|  | @override | 
|  | void write() { | 
|  | if (!dirty) | 
|  | return; | 
|  | final List<String> lines = new File(path).readAsLinesSync(); | 
|  | for (int index = 0; index < lines.length; index += 1) { | 
|  | final String line = lines[index]; | 
|  | if (line.isNotEmpty && !line.startsWith('#')) { | 
|  | lines[index] = '$this'; | 
|  | break; | 
|  | } | 
|  | } | 
|  | new File(path).writeAsStringSync(lines.join('\n') + '\n'); | 
|  | } | 
|  | } |