| // 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:file/file.dart'; |
| import 'package:file/local.dart'; |
| import 'package:platform/platform.dart'; |
| |
| const String kUpstreamRemote = 'https://github.com/flutter/flutter.git'; |
| |
| const String gsutilBinary = 'gsutil.py'; |
| |
| const List<String> kReleaseChannels = <String>[ |
| 'stable', |
| 'beta', |
| 'dev', |
| 'master', |
| ]; |
| |
| const String kReleaseDocumentationUrl = 'https://github.com/flutter/flutter/wiki/Flutter-Cherrypick-Process'; |
| |
| final RegExp releaseCandidateBranchRegex = RegExp( |
| r'flutter-(\d+)\.(\d+)-candidate\.(\d+)', |
| ); |
| |
| /// Cast a dynamic to String and trim. |
| String stdoutToString(dynamic input) { |
| final String str = input as String; |
| return str.trim(); |
| } |
| |
| class ConductorException implements Exception { |
| ConductorException(this.message); |
| |
| final String message; |
| |
| @override |
| String toString() => 'Exception: $message'; |
| } |
| |
| Directory? _flutterRoot; |
| Directory get localFlutterRoot { |
| if (_flutterRoot != null) { |
| return _flutterRoot!; |
| } |
| String filePath; |
| const FileSystem fileSystem = LocalFileSystem(); |
| const Platform platform = LocalPlatform(); |
| |
| // If a test |
| if (platform.script.scheme == 'data') { |
| final RegExp pattern = RegExp( |
| r'(file:\/\/[^"]*[/\\]dev\/tools[/\\][^"]+\.dart)', |
| multiLine: true, |
| ); |
| final Match? match = |
| pattern.firstMatch(Uri.decodeFull(platform.script.path)); |
| if (match == null) { |
| throw Exception( |
| 'Cannot determine path of script!\n${platform.script.path}', |
| ); |
| } |
| filePath = Uri.parse(match.group(1)!).path.replaceAll(r'%20', ' '); |
| } else { |
| filePath = platform.script.toFilePath(); |
| } |
| final String checkoutsDirname = fileSystem.path.normalize( |
| fileSystem.path.join( |
| fileSystem.path.dirname(filePath), |
| '..', // flutter/dev/tools |
| '..', // flutter/dev |
| '..', // flutter |
| ), |
| ); |
| _flutterRoot = fileSystem.directory(checkoutsDirname); |
| return _flutterRoot!; |
| } |
| |
| bool assertsEnabled() { |
| // Verify asserts enabled |
| bool assertsEnabled = false; |
| |
| assert(() { |
| assertsEnabled = true; |
| return true; |
| }()); |
| return assertsEnabled; |
| } |
| |
| /// Either return the value from [env] or fall back to [argResults]. |
| /// |
| /// If the key does not exist in either the environment or CLI args, throws a |
| /// [ConductorException]. |
| /// |
| /// The environment is favored over CLI args since the latter can have a default |
| /// value, which the environment should be able to override. |
| String? getValueFromEnvOrArgs( |
| String name, |
| ArgResults argResults, |
| Map<String, String> env, { |
| bool allowNull = false, |
| } |
| ) { |
| final String envName = fromArgToEnvName(name); |
| if (env[envName] != null ) { |
| return env[envName]; |
| } |
| final String? argValue = argResults[name] as String?; |
| if (argValue != null) { |
| return argValue; |
| } |
| |
| if (allowNull) { |
| return null; |
| } |
| throw ConductorException( |
| 'Expected either the CLI arg --$name or the environment variable $envName ' |
| 'to be provided!'); |
| } |
| |
| /// Return multiple values from the environment or fall back to [argResults]. |
| /// |
| /// Values read from an environment variable are assumed to be comma-delimited. |
| /// |
| /// If the key does not exist in either the CLI args or environment, throws a |
| /// [ConductorException]. |
| /// |
| /// The environment is favored over CLI args since the latter can have a default |
| /// value, which the environment should be able to override. |
| List<String> getValuesFromEnvOrArgs( |
| String name, |
| ArgResults argResults, |
| Map<String, String> env, |
| ) { |
| final String envName = fromArgToEnvName(name); |
| if (env[envName] != null && env[envName] != '') { |
| return env[envName]!.split(','); |
| } |
| final List<String> argValues = argResults[name] as List<String>; |
| if (argValues != null) { |
| return argValues; |
| } |
| |
| throw ConductorException( |
| 'Expected either the CLI arg --$name or the environment variable $envName ' |
| 'to be provided!'); |
| } |
| |
| /// Translate CLI arg names to env variable names. |
| /// |
| /// For example, 'state-file' -> 'STATE_FILE'. |
| String fromArgToEnvName(String argName) { |
| return argName.toUpperCase().replaceAll(r'-', r'_'); |
| } |