New release process (#14061)
Generate the "version" file from git tags. Remove the old VERSION file and mentions of versions in pubspec.yaml files. Replace the old update_versions.dart script with a new roll_dev.dart script. Update "flutter channel". Update "flutter upgrade", including making it transition from alpha to dev. Update "flutter --version" and "flutter doctor".
This commit is contained in:
parent
4353297079
commit
9e42e4b88f
1
.gitignore
vendored
1
.gitignore
vendored
@ -29,6 +29,7 @@
|
|||||||
/dev/docs/lib/
|
/dev/docs/lib/
|
||||||
/dev/docs/pubspec.yaml
|
/dev/docs/pubspec.yaml
|
||||||
/packages/flutter/coverage/
|
/packages/flutter/coverage/
|
||||||
|
version
|
||||||
|
|
||||||
# Flutter/Dart/Pub related
|
# Flutter/Dart/Pub related
|
||||||
**/doc/api/
|
**/doc/api/
|
||||||
|
34
.travis.yml
34
.travis.yml
@ -1,8 +1,21 @@
|
|||||||
|
# ENVIRONMENTS
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
|
env:
|
||||||
|
- SHARD=analyze
|
||||||
|
- SHARD=tests
|
||||||
|
- SHARD=docs
|
||||||
|
matrix:
|
||||||
|
exclude:
|
||||||
|
- os: osx
|
||||||
|
env: SHARD=analyze
|
||||||
|
- os: osx
|
||||||
|
env: SHARD=docs
|
||||||
sudo: false
|
sudo: false
|
||||||
filter_secrets: false
|
filter_secrets: false
|
||||||
|
|
||||||
|
# INSTALLATION
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
# sky_shell binary depends on /usr/lib/x86_64-linux-gnu/libstdc++.so.6 version GLIBCXX_3.4.18
|
# sky_shell binary depends on /usr/lib/x86_64-linux-gnu/libstdc++.so.6 version GLIBCXX_3.4.18
|
||||||
@ -14,23 +27,18 @@ addons:
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "6"
|
- "6"
|
||||||
|
git:
|
||||||
|
# We rely on git tags for determining the version.
|
||||||
|
depth: false
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.pub-cache
|
||||||
install:
|
install:
|
||||||
- ./dev/bots/travis_install.sh
|
- ./dev/bots/travis_install.sh
|
||||||
env:
|
|
||||||
- SHARD=analyze
|
# TESTING
|
||||||
- SHARD=tests
|
|
||||||
- SHARD=docs
|
|
||||||
before_script:
|
before_script:
|
||||||
- ./dev/bots/travis_setup.sh
|
- ./dev/bots/travis_setup.sh
|
||||||
script:
|
script:
|
||||||
- ulimit -S -n 2048 # https://github.com/flutter/flutter/issues/2976
|
- ulimit -S -n 2048 # https://github.com/flutter/flutter/issues/2976
|
||||||
- (./bin/cache/dart-sdk/bin/dart ./dev/bots/test.dart && ./dev/bots/travis_upload.sh)
|
- (./bin/cache/dart-sdk/bin/dart ./dev/bots/test.dart && ./dev/bots/travis_upload.sh)
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- $HOME/.pub-cache
|
|
||||||
matrix:
|
|
||||||
exclude:
|
|
||||||
- os: osx
|
|
||||||
env: SHARD=analyze
|
|
||||||
- os: osx
|
|
||||||
env: SHARD=docs
|
|
||||||
|
9
VERSION
9
VERSION
@ -1,9 +0,0 @@
|
|||||||
# This file defines a semantic version for the Flutter SDK. This version will
|
|
||||||
# describes breaking changes in the SDK as a whole, separately from the
|
|
||||||
# individual packages in the SDK. For example, if the flutter command line
|
|
||||||
# tool's options change in an incompatible way, this version will update to
|
|
||||||
# reflect that change. However, if the API for package:flutter changes in an
|
|
||||||
# incompatible way, this version number might not change. Instead, the version
|
|
||||||
# number for package:flutter will update to reflect that change.
|
|
||||||
|
|
||||||
0.0.21-dev
|
|
@ -73,6 +73,7 @@ function upgrade_flutter () {
|
|||||||
|
|
||||||
local revision=`(cd "$FLUTTER_ROOT"; git rev-parse HEAD)`
|
local revision=`(cd "$FLUTTER_ROOT"; git rev-parse HEAD)`
|
||||||
if [ ! -f "$SNAPSHOT_PATH" ] || [ ! -s "$STAMP_PATH" ] || [ `cat "$STAMP_PATH"` != "$revision" ] || [ "$FLUTTER_TOOLS_DIR/pubspec.yaml" -nt "$FLUTTER_TOOLS_DIR/pubspec.lock" ]; then
|
if [ ! -f "$SNAPSHOT_PATH" ] || [ ! -s "$STAMP_PATH" ] || [ `cat "$STAMP_PATH"` != "$revision" ] || [ "$FLUTTER_TOOLS_DIR/pubspec.yaml" -nt "$FLUTTER_TOOLS_DIR/pubspec.lock" ]; then
|
||||||
|
rm -f "$FLUTTER_ROOT/version"
|
||||||
mkdir -p "$FLUTTER_ROOT/bin/cache"
|
mkdir -p "$FLUTTER_ROOT/bin/cache"
|
||||||
touch "$FLUTTER_ROOT/bin/cache/.dartignore"
|
touch "$FLUTTER_ROOT/bin/cache/.dartignore"
|
||||||
"$FLUTTER_ROOT/bin/internal/update_dart_sdk.sh"
|
"$FLUTTER_ROOT/bin/internal/update_dart_sdk.sh"
|
||||||
|
@ -93,6 +93,7 @@ GOTO :after_subroutine
|
|||||||
)
|
)
|
||||||
|
|
||||||
:do_snapshot
|
:do_snapshot
|
||||||
|
IF EXIST "%FLUTTER_ROOT%\version" DEL "%FLUTTER_ROOT%\version"
|
||||||
ECHO: > "%cache_dir%\.dartignore"
|
ECHO: > "%cache_dir%\.dartignore"
|
||||||
ECHO Updating flutter tool...
|
ECHO Updating flutter tool...
|
||||||
PUSHD "%flutter_tools_dir%"
|
PUSHD "%flutter_tools_dir%"
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
name: flutter_devicelab
|
name: flutter_devicelab
|
||||||
version: 0.0.1
|
|
||||||
author: Flutter Authors <flutter-dev@googlegroups.com>
|
author: Flutter Authors <flutter-dev@googlegroups.com>
|
||||||
description: Flutter continuous integration performance and correctness tests.
|
description: Flutter continuous integration performance and correctness tests.
|
||||||
homepage: https://github.com/flutter/flutter
|
homepage: https://github.com/flutter/flutter
|
||||||
|
@ -8,7 +8,6 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
import 'update_versions.dart';
|
|
||||||
|
|
||||||
/// Whether to report all error messages (true) or attempt to filter out some
|
/// Whether to report all error messages (true) or attempt to filter out some
|
||||||
/// known false positives (false).
|
/// known false positives (false).
|
||||||
@ -36,15 +35,18 @@ Future<Null> main(List<String> args) async {
|
|||||||
if (path.basename(Directory.current.path) == 'tools')
|
if (path.basename(Directory.current.path) == 'tools')
|
||||||
Directory.current = Directory.current.parent.parent;
|
Directory.current = Directory.current.parent.parent;
|
||||||
|
|
||||||
final RawVersion version = new RawVersion('VERSION');
|
final ProcessResult flutter = Process.runSync('flutter', <String>[]);
|
||||||
|
final File versionFile = new File('version');
|
||||||
|
if (flutter.exitCode != 0 || !versionFile.existsSync())
|
||||||
|
throw new Exception('Failed to determine Flutter version.');
|
||||||
|
final String version = versionFile.readAsStringSync();
|
||||||
|
|
||||||
// Create the pubspec.yaml file.
|
// Create the pubspec.yaml file.
|
||||||
final StringBuffer buf = new StringBuffer('''
|
final StringBuffer buf = new StringBuffer();
|
||||||
name: Flutter
|
buf.writeln('name: Flutter');
|
||||||
homepage: https://flutter.io
|
buf.writeln('homepage: https://flutter.io');
|
||||||
version: $version
|
buf.writeln('version: $version');
|
||||||
dependencies:
|
buf.writeln('dependencies:');
|
||||||
''');
|
|
||||||
for (String package in findPackageNames()) {
|
for (String package in findPackageNames()) {
|
||||||
buf.writeln(' $package:');
|
buf.writeln(' $package:');
|
||||||
buf.writeln(' sdk: flutter');
|
buf.writeln(' sdk: flutter');
|
||||||
@ -100,7 +102,7 @@ dependencies:
|
|||||||
workingDirectory: 'dev/docs',
|
workingDirectory: 'dev/docs',
|
||||||
environment: pubEnvironment,
|
environment: pubEnvironment,
|
||||||
);
|
);
|
||||||
print('\n${result.stdout}');
|
print('\n${result.stdout}flutter version: $version\n');
|
||||||
|
|
||||||
// Generate the documentation.
|
// Generate the documentation.
|
||||||
final List<String> args = <String>[
|
final List<String> args = <String>[
|
||||||
@ -159,7 +161,10 @@ void createFooter(String footerPath) {
|
|||||||
const int kGitRevisionLength = 10;
|
const int kGitRevisionLength = 10;
|
||||||
|
|
||||||
final ProcessResult gitResult = Process.runSync('git', <String>['rev-parse', 'HEAD']);
|
final ProcessResult gitResult = Process.runSync('git', <String>['rev-parse', 'HEAD']);
|
||||||
String gitRevision = (gitResult.exitCode == 0) ? gitResult.stdout.trim() : 'unknown';
|
if (gitResult.exitCode != 0)
|
||||||
|
throw 'git exit with non-zero exit code: ${gitResult.exitCode}';
|
||||||
|
String gitRevision = gitResult.stdout.trim();
|
||||||
|
|
||||||
gitRevision = gitRevision.length > kGitRevisionLength ? gitRevision.substring(0, kGitRevisionLength) : gitRevision;
|
gitRevision = gitRevision.length > kGitRevisionLength ? gitRevision.substring(0, kGitRevisionLength) : gitRevision;
|
||||||
|
|
||||||
final String timestamp = new DateFormat('yyyy-MM-dd HH:mm').format(new DateTime.now());
|
final String timestamp = new DateFormat('yyyy-MM-dd HH:mm').format(new DateTime.now());
|
||||||
|
158
dev/tools/lib/roll_dev.dart
Normal file
158
dev/tools/lib/roll_dev.dart
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// Rolls the dev channel.
|
||||||
|
// Only tested on Linux.
|
||||||
|
//
|
||||||
|
// See: https://github.com/flutter/flutter/wiki/Release-process
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:args/args.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
const String kIncrement = 'increment';
|
||||||
|
const String kX = 'x';
|
||||||
|
const String kY = 'y';
|
||||||
|
const String kZ = 'z';
|
||||||
|
const String kHelp = 'help';
|
||||||
|
|
||||||
|
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(allowTrailingOptions: false);
|
||||||
|
argParser.addOption(
|
||||||
|
kIncrement,
|
||||||
|
help: 'Specifies which part of the x.y.z version number to increment. Required.',
|
||||||
|
valueHelp: 'level',
|
||||||
|
allowed: <String>[kX, kY, kZ],
|
||||||
|
allowedHelp: <String, String>{
|
||||||
|
kX: 'Indicates a major development, e.g. typically changed after a big press event.',
|
||||||
|
kY: 'Indicates a minor development, e.g. typically changed after a beta release.',
|
||||||
|
kZ: 'Indicates the least notable level of change. You normally want this.',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
argParser.addFlag(kHelp, negatable: false, help: 'Show this help message.', hide: true);
|
||||||
|
ArgResults argResults;
|
||||||
|
try {
|
||||||
|
argResults = argParser.parse(args);
|
||||||
|
} on ArgParserException catch (error) {
|
||||||
|
print(error.message);
|
||||||
|
print(argParser.usage);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String level = argResults[kIncrement];
|
||||||
|
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(argParser.usage);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
runGit('checkout master', 'switch to master branch');
|
||||||
|
|
||||||
|
if (getGitOutput('status --porcelain', 'check status of your local checkout') != '') {
|
||||||
|
print('Your git repository is not clean. Try running "git clean -fd". Warning, this ');
|
||||||
|
print('will delete files! Run with -n to find out which ones.');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String version = getFullTag();
|
||||||
|
final Match match = parseFullTag(version);
|
||||||
|
if (match == null) {
|
||||||
|
print('Could not determine the version for this build.');
|
||||||
|
if (version.isNotEmpty)
|
||||||
|
print('Git reported the latest version as "$version", which does not fit the expected pattern.');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<int> parts = match.groups(<int>[1, 2, 3]).map(int.parse).toList();
|
||||||
|
|
||||||
|
if (match.group(4) == '0') {
|
||||||
|
print('This commit has already been released, as version ${parts.join(".")}.');
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (level) {
|
||||||
|
case kX:
|
||||||
|
parts[0] += 1;
|
||||||
|
parts[1] = 0;
|
||||||
|
parts[2] = 0;
|
||||||
|
break;
|
||||||
|
case kY:
|
||||||
|
parts[1] += 1;
|
||||||
|
parts[2] = 0;
|
||||||
|
break;
|
||||||
|
case kZ:
|
||||||
|
parts[2] += 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print('Unknown increment level. The valid values are "$kX", "$kY", and "$kZ".');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
version = parts.join('.');
|
||||||
|
|
||||||
|
runGit('fetch upstream', 'fetch upstream');
|
||||||
|
runGit('reset upstream/master --hard', 'check out master branch');
|
||||||
|
runGit('tag $version', 'tag the commit with the version label');
|
||||||
|
|
||||||
|
print('Your tree is ready to publish Flutter $version to the "dev" channel.');
|
||||||
|
stdout.write('Are you? [yes/no] ');
|
||||||
|
if (stdin.readLineSync() != 'yes') {
|
||||||
|
runGit('tag -d $version', 'remove the tag you did not want to publish');
|
||||||
|
print('The dev roll has been aborted.');
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
runGit('push upstream $version', 'publish the version');
|
||||||
|
runGit('push upstream HEAD:dev', 'land the new version on the "dev" branch');
|
||||||
|
print('Flutter version $version has been rolled to the "dev" channel!');
|
||||||
|
}
|
||||||
|
|
||||||
|
String getFullTag() {
|
||||||
|
return getGitOutput(
|
||||||
|
'describe --match v*.*.* --exclude *-* --first-parent --long --tags',
|
||||||
|
'obtain last released version number',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Match parseFullTag(String version) {
|
||||||
|
final RegExp versionPattern = new RegExp('^v([0-9]+)\.([0-9]+)\.([0-9]+)-([0-9]+)-g([a-f0-9]+)\$');
|
||||||
|
return versionPattern.matchAsPrefix(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
String getGitOutput(String command, String explanation) {
|
||||||
|
final ProcessResult result = _runGit(command);
|
||||||
|
if (result.stderr.isEmpty && result.exitCode == 0)
|
||||||
|
return result.stdout.trim();
|
||||||
|
_reportGitFailureAndExit(result, explanation);
|
||||||
|
return null; // for the analyzer's sake
|
||||||
|
}
|
||||||
|
|
||||||
|
void runGit(String command, String explanation) {
|
||||||
|
final ProcessResult result = _runGit(command);
|
||||||
|
if (result.exitCode != 0)
|
||||||
|
_reportGitFailureAndExit(result, explanation);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessResult _runGit(String command) {
|
||||||
|
return Process.runSync('git', command.split(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _reportGitFailureAndExit(ProcessResult result, String explanation) {
|
||||||
|
if (result.exitCode != 0) {
|
||||||
|
print('Failed to $explanation. Git exitted with error code ${result.exitCode}.');
|
||||||
|
} else {
|
||||||
|
print('Failed to $explanation.');
|
||||||
|
}
|
||||||
|
if (result.stdout.isNotEmpty)
|
||||||
|
print('stdout from git:\n${result.stdout}\n');
|
||||||
|
if (result.stderr.isNotEmpty)
|
||||||
|
print('stderr from git:\n${result.stderr}\n');
|
||||||
|
exit(1);
|
||||||
|
}
|
@ -1,205 +0,0 @@
|
|||||||
// 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');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
name: flutter
|
name: flutter
|
||||||
version: 0.0.41-dev
|
|
||||||
author: Flutter Authors <flutter-dev@googlegroups.com>
|
author: Flutter Authors <flutter-dev@googlegroups.com>
|
||||||
description: A framework for writing Flutter applications
|
description: A framework for writing Flutter applications
|
||||||
homepage: http://flutter.io
|
homepage: http://flutter.io
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
name: flutter_driver
|
name: flutter_driver
|
||||||
version: 0.0.19-dev
|
|
||||||
description: Integration and performance test API for Flutter applications
|
description: Integration and performance test API for Flutter applications
|
||||||
homepage: http://flutter.io
|
homepage: http://flutter.io
|
||||||
author: Flutter Authors <flutter-dev@googlegroups.com>
|
author: Flutter Authors <flutter-dev@googlegroups.com>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
name: flutter_localizations
|
name: flutter_localizations
|
||||||
version: 0.0.1-dev
|
|
||||||
dependencies:
|
dependencies:
|
||||||
# To update these, use "flutter update-packages --force-upgrade".
|
# To update these, use "flutter update-packages --force-upgrade".
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
name: flutter_test
|
name: flutter_test
|
||||||
version: 0.0.19-dev
|
|
||||||
dependencies:
|
dependencies:
|
||||||
# To update these, use "flutter update-packages --force-upgrade".
|
# To update these, use "flutter update-packages --force-upgrade".
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ Future<Null> main(List<String> args) async {
|
|||||||
await runner.run(args, <FlutterCommand>[
|
await runner.run(args, <FlutterCommand>[
|
||||||
new AnalyzeCommand(verboseHelp: verboseHelp),
|
new AnalyzeCommand(verboseHelp: verboseHelp),
|
||||||
new BuildCommand(verboseHelp: verboseHelp),
|
new BuildCommand(verboseHelp: verboseHelp),
|
||||||
new ChannelCommand(),
|
new ChannelCommand(verboseHelp: verboseHelp),
|
||||||
new CleanCommand(),
|
new CleanCommand(),
|
||||||
new InjectPluginsCommand(hidden: !verboseHelp),
|
new InjectPluginsCommand(hidden: !verboseHelp),
|
||||||
new ConfigCommand(verboseHelp: verboseHelp),
|
new ConfigCommand(verboseHelp: verboseHelp),
|
||||||
|
@ -9,8 +9,19 @@ import '../base/process.dart';
|
|||||||
import '../cache.dart';
|
import '../cache.dart';
|
||||||
import '../globals.dart';
|
import '../globals.dart';
|
||||||
import '../runner/flutter_command.dart';
|
import '../runner/flutter_command.dart';
|
||||||
|
import '../version.dart';
|
||||||
|
|
||||||
class ChannelCommand extends FlutterCommand {
|
class ChannelCommand extends FlutterCommand {
|
||||||
|
ChannelCommand({ bool verboseHelp: false }) {
|
||||||
|
argParser.addFlag(
|
||||||
|
'all',
|
||||||
|
abbr: 'a',
|
||||||
|
help: 'Include all the available branches (including local branches) when listing channels.',
|
||||||
|
defaultsTo: false,
|
||||||
|
hide: !verboseHelp,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String name = 'channel';
|
final String name = 'channel';
|
||||||
|
|
||||||
@ -24,7 +35,7 @@ class ChannelCommand extends FlutterCommand {
|
|||||||
Future<Null> runCommand() {
|
Future<Null> runCommand() {
|
||||||
switch (argResults.rest.length) {
|
switch (argResults.rest.length) {
|
||||||
case 0:
|
case 0:
|
||||||
return _listChannels();
|
return _listChannels(showAll: argResults['all']);
|
||||||
case 1:
|
case 1:
|
||||||
return _switchChannel(argResults.rest[0]);
|
return _switchChannel(argResults.rest[0]);
|
||||||
default:
|
default:
|
||||||
@ -32,10 +43,12 @@ class ChannelCommand extends FlutterCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Null> _listChannels() async {
|
Future<Null> _listChannels({ bool showAll }) async {
|
||||||
final String currentBranch = runSync(
|
// Beware: currentBranch could contain PII. See getBranchName().
|
||||||
<String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
|
final String currentChannel = FlutterVersion.instance.channel;
|
||||||
workingDirectory: Cache.flutterRoot);
|
final String currentBranch = FlutterVersion.instance.getBranchName();
|
||||||
|
|
||||||
|
showAll = showAll || currentChannel != currentBranch;
|
||||||
|
|
||||||
printStatus('Flutter channels:');
|
printStatus('Flutter channels:');
|
||||||
final int result = await runCommandAndStreamOutput(
|
final int result = await runCommandAndStreamOutput(
|
||||||
@ -46,24 +59,45 @@ class ChannelCommand extends FlutterCommand {
|
|||||||
if (split.length < 2)
|
if (split.length < 2)
|
||||||
return null;
|
return null;
|
||||||
final String branchName = split[1];
|
final String branchName = split[1];
|
||||||
if (branchName.startsWith('HEAD'))
|
|
||||||
return null;
|
|
||||||
if (branchName == currentBranch)
|
if (branchName == currentBranch)
|
||||||
return '* $branchName';
|
return '* $branchName';
|
||||||
return ' $branchName';
|
if (!branchName.startsWith('HEAD ') &&
|
||||||
|
(showAll || FlutterVersion.officialChannels.contains(branchName)))
|
||||||
|
return ' $branchName';
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
throwToolExit('List channels failed: $result', exitCode: result);
|
throwToolExit('List channels failed: $result', exitCode: result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Null> _switchChannel(String branchName) async {
|
Future<Null> _switchChannel(String branchName) {
|
||||||
printStatus('Switching to flutter channel named $branchName');
|
printStatus("Switching to flutter channel '$branchName'...");
|
||||||
|
if (FlutterVersion.obsoleteBranches.containsKey(branchName)) {
|
||||||
|
final String alternative = FlutterVersion.obsoleteBranches[branchName];
|
||||||
|
printStatus("This channel is obsolete. Consider switching to the '$alternative' channel instead.");
|
||||||
|
} else if (!FlutterVersion.officialChannels.contains(branchName)) {
|
||||||
|
printStatus('This is not an official channel. For a list of available channels, try "flutter channel".');
|
||||||
|
}
|
||||||
|
return _checkout(branchName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Null> upgradeChannel() async {
|
||||||
|
final String channel = FlutterVersion.instance.channel;
|
||||||
|
if (FlutterVersion.obsoleteBranches.containsKey(channel)) {
|
||||||
|
final String alternative = FlutterVersion.obsoleteBranches[channel];
|
||||||
|
printStatus("Transitioning from '$channel' to '$alternative'...");
|
||||||
|
return _checkout(alternative);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Null> _checkout(String branchName) async {
|
||||||
final int result = await runCommandAndStreamOutput(
|
final int result = await runCommandAndStreamOutput(
|
||||||
<String>['git', 'checkout', branchName],
|
<String>['git', 'checkout', branchName],
|
||||||
workingDirectory: Cache.flutterRoot,
|
workingDirectory: Cache.flutterRoot,
|
||||||
|
prefix: 'git: ',
|
||||||
);
|
);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
throwToolExit('Switch channel failed: $result', exitCode: result);
|
throwToolExit('Switching channels failed with error code $result.', exitCode: result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import '../doctor.dart';
|
|||||||
import '../globals.dart';
|
import '../globals.dart';
|
||||||
import '../runner/flutter_command.dart';
|
import '../runner/flutter_command.dart';
|
||||||
import '../version.dart';
|
import '../version.dart';
|
||||||
|
import 'channel.dart';
|
||||||
|
|
||||||
class UpgradeCommand extends FlutterCommand {
|
class UpgradeCommand extends FlutterCommand {
|
||||||
@override
|
@override
|
||||||
@ -39,6 +40,8 @@ class UpgradeCommand extends FlutterCommand {
|
|||||||
|
|
||||||
printStatus('Upgrading Flutter from ${Cache.flutterRoot}...');
|
printStatus('Upgrading Flutter from ${Cache.flutterRoot}...');
|
||||||
|
|
||||||
|
await ChannelCommand.upgradeChannel();
|
||||||
|
|
||||||
int code = await runCommandAndStreamOutput(
|
int code = await runCommandAndStreamOutput(
|
||||||
<String>['git', 'pull', '--ff-only'],
|
<String>['git', 'pull', '--ff-only'],
|
||||||
workingDirectory: Cache.flutterRoot,
|
workingDirectory: Cache.flutterRoot,
|
||||||
|
@ -198,7 +198,7 @@ class _FlutterValidator extends DoctorValidator {
|
|||||||
|
|
||||||
final FlutterVersion version = FlutterVersion.instance;
|
final FlutterVersion version = FlutterVersion.instance;
|
||||||
|
|
||||||
messages.add(new ValidationMessage('Flutter at ${Cache.flutterRoot}'));
|
messages.add(new ValidationMessage('Flutter version ${version.frameworkVersion} at ${Cache.flutterRoot}'));
|
||||||
if (Cache.flutterRoot.contains(' '))
|
if (Cache.flutterRoot.contains(' '))
|
||||||
messages.add(new ValidationMessage.error(
|
messages.add(new ValidationMessage.error(
|
||||||
'Flutter SDK install paths with spaces are not yet supported. (https://github.com/flutter/flutter/issues/6577)\n'
|
'Flutter SDK install paths with spaces are not yet supported. (https://github.com/flutter/flutter/issues/6577)\n'
|
||||||
|
@ -247,6 +247,7 @@ class FlutterCommandRunner extends CommandRunner<Null> {
|
|||||||
flutterUsage.suppressAnalytics = true;
|
flutterUsage.suppressAnalytics = true;
|
||||||
|
|
||||||
_checkFlutterCopy();
|
_checkFlutterCopy();
|
||||||
|
await FlutterVersion.instance.ensureVersionFile();
|
||||||
await FlutterVersion.instance.checkFlutterVersionFreshness();
|
await FlutterVersion.instance.checkFlutterVersionFreshness();
|
||||||
|
|
||||||
if (globalResults.wasParsed('packages'))
|
if (globalResults.wasParsed('packages'))
|
||||||
|
@ -24,7 +24,7 @@ class Usage {
|
|||||||
/// used for testing.
|
/// used for testing.
|
||||||
Usage({ String settingsName: 'flutter', String versionOverride, String configDirOverride}) {
|
Usage({ String settingsName: 'flutter', String versionOverride, String configDirOverride}) {
|
||||||
final FlutterVersion flutterVersion = FlutterVersion.instance;
|
final FlutterVersion flutterVersion = FlutterVersion.instance;
|
||||||
final String version = versionOverride ?? flutterVersion.getVersionString(whitelistBranchName: true);
|
final String version = versionOverride ?? flutterVersion.getVersionString(redactUnknownBranches: true);
|
||||||
_analytics = new AnalyticsIO(_kFlutterUA, settingsName, version,
|
_analytics = new AnalyticsIO(_kFlutterUA, settingsName, version,
|
||||||
// Analyzer doesn't recognize that [Directory] objects match up due to a
|
// Analyzer doesn't recognize that [Directory] objects match up due to a
|
||||||
// conditional import.
|
// conditional import.
|
||||||
@ -34,7 +34,7 @@ class Usage {
|
|||||||
// Report a more detailed OS version string than package:usage does by default.
|
// Report a more detailed OS version string than package:usage does by default.
|
||||||
_analytics.setSessionValue('cd1', os.name);
|
_analytics.setSessionValue('cd1', os.name);
|
||||||
// Send the branch name as the "channel".
|
// Send the branch name as the "channel".
|
||||||
_analytics.setSessionValue('cd2', flutterVersion.getBranchName(whitelistBranchName: true));
|
_analytics.setSessionValue('cd2', flutterVersion.getBranchName(redactUnknownBranches: true));
|
||||||
// Record the host as the application installer ID - the context that flutter_tools is running in.
|
// Record the host as the application installer ID - the context that flutter_tools is running in.
|
||||||
if (platform.environment.containsKey('FLUTTER_HOST')) {
|
if (platform.environment.containsKey('FLUTTER_HOST')) {
|
||||||
_analytics.setSessionValue('aiid', platform.environment['FLUTTER_HOST']);
|
_analytics.setSessionValue('aiid', platform.environment['FLUTTER_HOST']);
|
||||||
|
@ -10,20 +10,13 @@ import 'package:quiver/time.dart';
|
|||||||
|
|
||||||
import 'base/common.dart';
|
import 'base/common.dart';
|
||||||
import 'base/context.dart';
|
import 'base/context.dart';
|
||||||
|
import 'base/file_system.dart';
|
||||||
import 'base/io.dart';
|
import 'base/io.dart';
|
||||||
import 'base/process.dart';
|
import 'base/process.dart';
|
||||||
import 'base/process_manager.dart';
|
import 'base/process_manager.dart';
|
||||||
import 'cache.dart';
|
import 'cache.dart';
|
||||||
import 'globals.dart';
|
import 'globals.dart';
|
||||||
|
|
||||||
final Set<String> kKnownBranchNames = new Set<String>.from(<String>[
|
|
||||||
'master',
|
|
||||||
'alpha',
|
|
||||||
'hackathon',
|
|
||||||
'codelab',
|
|
||||||
'beta'
|
|
||||||
]);
|
|
||||||
|
|
||||||
class FlutterVersion {
|
class FlutterVersion {
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
FlutterVersion(this._clock) {
|
FlutterVersion(this._clock) {
|
||||||
@ -42,6 +35,7 @@ class FlutterVersion {
|
|||||||
|
|
||||||
_frameworkRevision = _runGit('git log -n 1 --pretty=format:%H');
|
_frameworkRevision = _runGit('git log -n 1 --pretty=format:%H');
|
||||||
_frameworkAge = _runGit('git log -n 1 --pretty=format:%ar');
|
_frameworkAge = _runGit('git log -n 1 --pretty=format:%ar');
|
||||||
|
_frameworkVersion = GitTagVersion.determine().frameworkVersionFor(_frameworkRevision);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Clock _clock;
|
final Clock _clock;
|
||||||
@ -49,11 +43,31 @@ class FlutterVersion {
|
|||||||
String _repositoryUrl;
|
String _repositoryUrl;
|
||||||
String get repositoryUrl => _repositoryUrl;
|
String get repositoryUrl => _repositoryUrl;
|
||||||
|
|
||||||
|
static Set<String> officialChannels = new Set<String>.from(<String>[
|
||||||
|
'master',
|
||||||
|
'dev',
|
||||||
|
'beta',
|
||||||
|
'release',
|
||||||
|
]);
|
||||||
|
|
||||||
|
/// This maps old branch names to the names of branches that replaced them.
|
||||||
|
///
|
||||||
|
/// For example, in early 2018 we changed from having an "alpha" branch to
|
||||||
|
/// having a "dev" branch, so anyone using "alpha" now gets transitioned to
|
||||||
|
/// "dev".
|
||||||
|
static Map<String, String> obsoleteBranches = <String, String>{
|
||||||
|
'alpha': 'dev',
|
||||||
|
'hackathon': 'dev',
|
||||||
|
'codelab': 'dev',
|
||||||
|
};
|
||||||
|
|
||||||
String _channel;
|
String _channel;
|
||||||
/// `master`, `alpha`, `hackathon`, ...
|
/// The channel is the upstream branch.
|
||||||
|
/// `master`, `dev`, `beta`, `release`; or old ones, like `alpha`, `hackathon`, ...
|
||||||
String get channel => _channel;
|
String get channel => _channel;
|
||||||
|
|
||||||
/// The name of the local branch
|
/// The name of the local branch.
|
||||||
|
/// Use getBranchName() to read this.
|
||||||
String _branch;
|
String _branch;
|
||||||
|
|
||||||
String _frameworkRevision;
|
String _frameworkRevision;
|
||||||
@ -63,6 +77,9 @@ class FlutterVersion {
|
|||||||
String _frameworkAge;
|
String _frameworkAge;
|
||||||
String get frameworkAge => _frameworkAge;
|
String get frameworkAge => _frameworkAge;
|
||||||
|
|
||||||
|
String _frameworkVersion;
|
||||||
|
String get frameworkVersion => _frameworkVersion;
|
||||||
|
|
||||||
String get frameworkDate => frameworkCommitDate;
|
String get frameworkDate => frameworkCommitDate;
|
||||||
|
|
||||||
String get dartSdkVersion => Cache.instance.dartSdkVersion.split(' ')[0];
|
String get dartSdkVersion => Cache.instance.dartSdkVersion.split(' ')[0];
|
||||||
@ -71,16 +88,19 @@ class FlutterVersion {
|
|||||||
String get engineRevision => Cache.instance.engineRevision;
|
String get engineRevision => Cache.instance.engineRevision;
|
||||||
String get engineRevisionShort => _shortGitRevision(engineRevision);
|
String get engineRevisionShort => _shortGitRevision(engineRevision);
|
||||||
|
|
||||||
String _runGit(String command) => runSync(command.split(' '), workingDirectory: Cache.flutterRoot);
|
Future<Null> ensureVersionFile() {
|
||||||
|
return fs.file(fs.path.join(Cache.flutterRoot, 'version')).writeAsString(_frameworkVersion);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
final String flutterText = 'Flutter • channel $channel • ${repositoryUrl == null ? 'unknown source' : repositoryUrl}';
|
final String versionText = frameworkVersion == 'unknown' ? '' : ' $frameworkVersion';
|
||||||
|
final String flutterText = 'Flutter$versionText • channel $channel • ${repositoryUrl == null ? 'unknown source' : repositoryUrl}';
|
||||||
final String frameworkText = 'Framework • revision $frameworkRevisionShort ($frameworkAge) • $frameworkCommitDate';
|
final String frameworkText = 'Framework • revision $frameworkRevisionShort ($frameworkAge) • $frameworkCommitDate';
|
||||||
final String engineText = 'Engine • revision $engineRevisionShort';
|
final String engineText = 'Engine • revision $engineRevisionShort';
|
||||||
final String toolsText = 'Tools • Dart $dartSdkVersion';
|
final String toolsText = 'Tools • Dart $dartSdkVersion';
|
||||||
|
|
||||||
// Flutter • channel master • https://github.com/flutter/flutter.git
|
// Flutter 1.3.922-pre.2 • channel master • https://github.com/flutter/flutter.git
|
||||||
// Framework • revision 2259c59be8 • 19 minutes ago • 2016-08-15 22:51:40
|
// Framework • revision 2259c59be8 • 19 minutes ago • 2016-08-15 22:51:40
|
||||||
// Engine • revision fe509b0d96
|
// Engine • revision fe509b0d96
|
||||||
// Tools • Dart 1.19.0-dev.5.0
|
// Tools • Dart 1.19.0-dev.5.0
|
||||||
@ -150,20 +170,22 @@ class FlutterVersion {
|
|||||||
|
|
||||||
static FlutterVersion get instance => context.putIfAbsent(FlutterVersion, () => new FlutterVersion(const Clock()));
|
static FlutterVersion get instance => context.putIfAbsent(FlutterVersion, () => new FlutterVersion(const Clock()));
|
||||||
|
|
||||||
/// Return a short string for the version (`alpha/a76bc8e22b`).
|
/// Return a short string for the version (e.g. `master/0.0.59-pre.92`, `scroll_refactor/a76bc8e22b`).
|
||||||
String getVersionString({bool whitelistBranchName: false}) {
|
String getVersionString({bool redactUnknownBranches: false}) {
|
||||||
return '${getBranchName(whitelistBranchName: whitelistBranchName)}/$frameworkRevisionShort';
|
if (frameworkVersion != 'unknown')
|
||||||
|
return '${getBranchName(redactUnknownBranches: redactUnknownBranches)}/$frameworkVersion';
|
||||||
|
return '${getBranchName(redactUnknownBranches: redactUnknownBranches)}/$frameworkRevisionShort';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the branch name.
|
/// Return the branch name.
|
||||||
///
|
///
|
||||||
/// If [whitelistBranchName] is true and the branch is unknown,
|
/// If [redactUnknownBranches] is true and the branch is unknown,
|
||||||
/// the branch name will be returned as 'dev'.
|
/// the branch name will be returned as `'[user-branch]'`.
|
||||||
String getBranchName({ bool whitelistBranchName: false }) {
|
String getBranchName({ bool redactUnknownBranches: false }) {
|
||||||
if (whitelistBranchName || _branch.isEmpty) {
|
if (redactUnknownBranches || _branch.isEmpty) {
|
||||||
// Only return the branch names we know about; arbitrary branch names might contain PII.
|
// Only return the branch names we know about; arbitrary branch names might contain PII.
|
||||||
if (!kKnownBranchNames.contains(_branch))
|
if (!officialChannels.contains(_branch) && !obsoleteBranches.containsKey(_branch))
|
||||||
return 'dev';
|
return '[user-branch]';
|
||||||
}
|
}
|
||||||
return _branch;
|
return _branch;
|
||||||
}
|
}
|
||||||
@ -424,6 +446,10 @@ String _runSync(List<String> command, {bool lenient: true}) {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _runGit(String command) {
|
||||||
|
return runSync(command.split(' '), workingDirectory: Cache.flutterRoot);
|
||||||
|
}
|
||||||
|
|
||||||
/// Runs [command] in the root of the Flutter installation and returns the
|
/// Runs [command] in the root of the Flutter installation and returns the
|
||||||
/// standard output as a string.
|
/// standard output as a string.
|
||||||
///
|
///
|
||||||
@ -445,3 +471,45 @@ String _shortGitRevision(String revision) {
|
|||||||
return '';
|
return '';
|
||||||
return revision.length > 10 ? revision.substring(0, 10) : revision;
|
return revision.length > 10 ? revision.substring(0, 10) : revision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GitTagVersion {
|
||||||
|
const GitTagVersion(this.x, this.y, this.z, this.commits, this.hash);
|
||||||
|
const GitTagVersion.unknown() : x = null, y = null, z = null, commits = 0, hash = '';
|
||||||
|
|
||||||
|
/// The X in vX.Y.Z.
|
||||||
|
final int x;
|
||||||
|
|
||||||
|
/// The Y in vX.Y.Z.
|
||||||
|
final int y;
|
||||||
|
|
||||||
|
/// The Z in vX.Y.Z.
|
||||||
|
final int z;
|
||||||
|
|
||||||
|
/// Number of commits since the vX.Y.Z tag.
|
||||||
|
final int commits;
|
||||||
|
|
||||||
|
/// The git hash (or an abbreviation thereof) for this commit.
|
||||||
|
final String hash;
|
||||||
|
|
||||||
|
static GitTagVersion determine() {
|
||||||
|
final String version = _runGit('git describe --match v*.*.* --exclude *-* --first-parent --long --tags');
|
||||||
|
final RegExp versionPattern = new RegExp('^v([0-9]+)\.([0-9]+)\.([0-9]+)-([0-9]+)-g([a-f0-9]+)\$');
|
||||||
|
final List<String> parts = versionPattern.matchAsPrefix(version)?.groups(<int>[1, 2, 3, 4, 5]);
|
||||||
|
if (parts == null) {
|
||||||
|
printTrace('Could not interpret results of "git describe": $version');
|
||||||
|
return const GitTagVersion.unknown();
|
||||||
|
}
|
||||||
|
final List<int> parsedParts = parts.take(4).map<int>(
|
||||||
|
(String value) => int.parse(value, onError: (String value) => null),
|
||||||
|
).toList();
|
||||||
|
return new GitTagVersion(parsedParts[0], parsedParts[1], parsedParts[2], parsedParts[3], parts[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
String frameworkVersionFor(String revision) {
|
||||||
|
if (x == null || y == null || z == null || !revision.startsWith(hash))
|
||||||
|
return 'unknown';
|
||||||
|
if (commits == 0)
|
||||||
|
return '$x.$y.$z';
|
||||||
|
return '$x.$y.${z + 1}-pre.$commits';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user