mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
[flutter_tools] document flutter root initialization (#67884)
Moves the flutter root initialization to a static method on the cache. This is a small step towards making this functionality non-static and instead injected like normal members - however, completely removing all of the static-ness at once was too large of a change. Instead document and add unit tests and change existing code as little as possible. #47161
This commit is contained in:
parent
f5ce638959
commit
9e5e763ebe
@ -21,12 +21,14 @@ import 'base/net.dart';
|
||||
import 'base/os.dart' show OperatingSystemUtils;
|
||||
import 'base/platform.dart';
|
||||
import 'base/process.dart';
|
||||
import 'base/user_messages.dart';
|
||||
import 'convert.dart';
|
||||
import 'dart/package_map.dart';
|
||||
import 'dart/pub.dart';
|
||||
import 'features.dart';
|
||||
import 'globals.dart' as globals;
|
||||
import 'runner/flutter_command.dart';
|
||||
import 'runner/flutter_command_runner.dart';
|
||||
|
||||
/// A tag for a set of development artifacts that need to be cached.
|
||||
class DevelopmentArtifact {
|
||||
@ -215,6 +217,69 @@ class Cache {
|
||||
// Initialized by FlutterCommandRunner on startup.
|
||||
static String flutterRoot;
|
||||
|
||||
|
||||
/// Determine the absolute and normalized path for the root of the current
|
||||
/// Flutter checkout.
|
||||
///
|
||||
/// This method has a series of fallbacks for determining the repo location. The
|
||||
/// first success will immediately return the root without further checks.
|
||||
///
|
||||
/// The order of these tests is:
|
||||
/// 1. FLUTTER_ROOT environment variable contains the path.
|
||||
/// 2. Platform script is a data URI scheme, returning `../..` to support
|
||||
/// tests run from `packages/flutter_tools`.
|
||||
/// 3. Platform script is package URI scheme, returning the grandparent directory
|
||||
/// of the package config file location from `packages/flutter_tools/.packages`.
|
||||
/// 4. Platform script file path is the snapshot path generated by `bin/flutter`,
|
||||
/// returning the grandparent directory from `bin/cache`.
|
||||
/// 5. Platform script file name is the entrypoint in `packages/flutter_tools/bin/flutter_tools.dart`,
|
||||
/// returning the 4th parent directory.
|
||||
/// 6. The current directory
|
||||
///
|
||||
/// If an exception is thrown during any of these checks, an error message is
|
||||
/// printed and `.` is returned by default (6).
|
||||
static String defaultFlutterRoot({
|
||||
@required Platform platform,
|
||||
@required FileSystem fileSystem,
|
||||
@required UserMessages userMessages,
|
||||
}) {
|
||||
String normalize(String path) {
|
||||
return fileSystem.path.normalize(fileSystem.path.absolute(path));
|
||||
}
|
||||
if (platform.environment.containsKey(kFlutterRootEnvironmentVariableName)) {
|
||||
return normalize(platform.environment[kFlutterRootEnvironmentVariableName]);
|
||||
}
|
||||
try {
|
||||
if (platform.script.scheme == 'data') {
|
||||
return normalize('../..'); // The tool is running as a test.
|
||||
}
|
||||
final String Function(String) dirname = fileSystem.path.dirname;
|
||||
|
||||
if (platform.script.scheme == 'package') {
|
||||
final String packageConfigPath = Uri.parse(platform.packageConfig).toFilePath(
|
||||
windows: platform.isWindows,
|
||||
);
|
||||
return normalize(dirname(dirname(dirname(packageConfigPath))));
|
||||
}
|
||||
|
||||
if (platform.script.scheme == 'file') {
|
||||
final String script = platform.script.toFilePath(
|
||||
windows: platform.isWindows,
|
||||
);
|
||||
if (fileSystem.path.basename(script) == kSnapshotFileName) {
|
||||
return normalize(dirname(dirname(fileSystem.path.dirname(script))));
|
||||
}
|
||||
if (fileSystem.path.basename(script) == kFlutterToolsScriptFileName) {
|
||||
return normalize(dirname(dirname(dirname(dirname(script)))));
|
||||
}
|
||||
}
|
||||
} on Exception catch (error) {
|
||||
// There is currently no logger attached since this is computed at startup.
|
||||
print(userMessages.runnerNoRoot('$error'));
|
||||
}
|
||||
return normalize('.');
|
||||
}
|
||||
|
||||
// Whether to cache artifacts for all platforms. Defaults to only caching
|
||||
// artifacts for the current platform.
|
||||
bool includeAllPlatforms = false;
|
||||
|
@ -156,43 +156,6 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
return '$prefix\n\n$usageWithoutDescription';
|
||||
}
|
||||
|
||||
static String get defaultFlutterRoot {
|
||||
if (globals.platform.environment.containsKey(kFlutterRootEnvironmentVariableName)) {
|
||||
return globals.platform.environment[kFlutterRootEnvironmentVariableName];
|
||||
}
|
||||
try {
|
||||
if (globals.platform.script.scheme == 'data') {
|
||||
return '../..'; // we're running as a test
|
||||
}
|
||||
|
||||
if (globals.platform.script.scheme == 'package') {
|
||||
final String packageConfigPath = Uri.parse(globals.platform.packageConfig).toFilePath();
|
||||
return globals.fs.path.dirname(globals.fs.path.dirname(globals.fs.path.dirname(packageConfigPath)));
|
||||
}
|
||||
|
||||
final String script = globals.platform.script.toFilePath();
|
||||
if (globals.fs.path.basename(script) == kSnapshotFileName) {
|
||||
return globals.fs.path.dirname(globals.fs.path.dirname(globals.fs.path.dirname(script)));
|
||||
}
|
||||
if (globals.fs.path.basename(script) == kFlutterToolsScriptFileName) {
|
||||
return globals.fs.path.dirname(globals.fs.path.dirname(globals.fs.path.dirname(globals.fs.path.dirname(script))));
|
||||
}
|
||||
|
||||
// If run from a bare script within the repo.
|
||||
if (script.contains('flutter/packages/')) {
|
||||
return script.substring(0, script.indexOf('flutter/packages/') + 8);
|
||||
}
|
||||
if (script.contains('flutter/examples/')) {
|
||||
return script.substring(0, script.indexOf('flutter/examples/') + 8);
|
||||
}
|
||||
} on Exception catch (error) {
|
||||
// we don't have a logger at the time this is run
|
||||
// (which is why we don't use printTrace here)
|
||||
print(userMessages.runnerNoRoot('$error'));
|
||||
}
|
||||
return '.';
|
||||
}
|
||||
|
||||
@override
|
||||
ArgResults parse(Iterable<String> args) {
|
||||
try {
|
||||
@ -264,7 +227,11 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
|
||||
// We must set Cache.flutterRoot early because other features use it (e.g.
|
||||
// enginePath's initializer uses it).
|
||||
final String flutterRoot = topLevelResults['flutter-root'] as String ?? defaultFlutterRoot;
|
||||
final String flutterRoot = topLevelResults['flutter-root'] as String ?? Cache.defaultFlutterRoot(
|
||||
platform: globals.platform,
|
||||
fileSystem: globals.fs,
|
||||
userMessages: globals.userMessages,
|
||||
);
|
||||
Cache.flutterRoot = globals.fs.path.normalize(globals.fs.path.absolute(flutterRoot));
|
||||
|
||||
// Set up the tooling configuration.
|
||||
@ -339,7 +306,11 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
|
||||
@visibleForTesting
|
||||
static void initFlutterRoot() {
|
||||
Cache.flutterRoot ??= defaultFlutterRoot;
|
||||
Cache.flutterRoot ??= Cache.defaultFlutterRoot(
|
||||
platform: globals.platform,
|
||||
fileSystem: globals.fs,
|
||||
userMessages: globals.userMessages,
|
||||
);
|
||||
}
|
||||
|
||||
/// Get the root directories of the repo - the directories containing Dart packages.
|
||||
|
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter_tools/src/base/error_handling_io.dart';
|
||||
import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
@ -14,7 +15,6 @@ import 'package:flutter_tools/src/base/terminal.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/analyze.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
@ -108,7 +108,6 @@ void main() {
|
||||
|
||||
setUpAll(() {
|
||||
Cache.disableLocking();
|
||||
Cache.flutterRoot = FlutterCommandRunner.defaultFlutterRoot;
|
||||
processManager = const LocalProcessManager();
|
||||
platform = const LocalPlatform();
|
||||
terminal = AnsiTerminal(platform: platform, stdio: Stdio());
|
||||
@ -123,6 +122,11 @@ void main() {
|
||||
fileSystem: fileSystem,
|
||||
platform: platform,
|
||||
);
|
||||
Cache.flutterRoot = Cache.defaultFlutterRoot(
|
||||
fileSystem: fileSystem,
|
||||
platform: platform,
|
||||
userMessages: UserMessages(),
|
||||
);
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
|
@ -0,0 +1,104 @@
|
||||
// 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:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
|
||||
void main() {
|
||||
testWithoutContext('Cache can initialize flutter root from environment variable', () {
|
||||
final String defaultFlutterRoot = Cache.defaultFlutterRoot(
|
||||
fileSystem: MemoryFileSystem.test(),
|
||||
userMessages: UserMessages(),
|
||||
platform: FakePlatform(
|
||||
environment: <String, String>{
|
||||
'FLUTTER_ROOT': 'path/to/flutter'
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
expect(defaultFlutterRoot, '/path/to/flutter');
|
||||
});
|
||||
|
||||
testWithoutContext('Cache can initialize flutter root data-scheme platform script', () {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
// For data-uri, the root is initialized to ../.. and then normalized. Change the
|
||||
// current directory to verify this.
|
||||
final Directory directory = fileSystem.directory('foo/bar/baz/')
|
||||
..createSync(recursive: true);
|
||||
fileSystem.currentDirectory = directory;
|
||||
|
||||
final String defaultFlutterRoot = Cache.defaultFlutterRoot(
|
||||
fileSystem: fileSystem,
|
||||
userMessages: UserMessages(),
|
||||
platform: FakePlatform(
|
||||
environment: <String, String>{},
|
||||
script: Uri.parse('data:,Hello%2C%20World!'),
|
||||
)
|
||||
);
|
||||
|
||||
expect(defaultFlutterRoot, '/foo');
|
||||
});
|
||||
|
||||
testWithoutContext('Cache can initialize flutter root package-scheme platform script', () {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final String defaultFlutterRoot = Cache.defaultFlutterRoot(
|
||||
fileSystem: fileSystem,
|
||||
userMessages: UserMessages(),
|
||||
platform: FakePlatform(
|
||||
environment: <String, String>{},
|
||||
script: Uri.parse('package:flutter_tools/flutter_tools.dart'),
|
||||
packageConfig: 'flutter/packages/flutter_tools/.packages'
|
||||
)
|
||||
);
|
||||
|
||||
expect(defaultFlutterRoot, '/flutter');
|
||||
});
|
||||
|
||||
testWithoutContext('Cache can initialize flutter root from snapshot location', () {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final String defaultFlutterRoot = Cache.defaultFlutterRoot(
|
||||
fileSystem: fileSystem,
|
||||
userMessages: UserMessages(),
|
||||
platform: FakePlatform(
|
||||
environment: <String, String>{},
|
||||
script: Uri.parse('file:///flutter/bin/cache/flutter_tools.snapshot'),
|
||||
)
|
||||
);
|
||||
|
||||
expect(defaultFlutterRoot, '/flutter');
|
||||
});
|
||||
|
||||
testWithoutContext('Cache can initialize flutter root from script file', () {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final String defaultFlutterRoot = Cache.defaultFlutterRoot(
|
||||
fileSystem: fileSystem,
|
||||
userMessages: UserMessages(),
|
||||
platform: FakePlatform(
|
||||
environment: <String, String>{},
|
||||
script: Uri.parse('file:///flutter/packages/flutter_tools/bin/flutter_tools.dart'),
|
||||
)
|
||||
);
|
||||
|
||||
expect(defaultFlutterRoot, '/flutter');
|
||||
});
|
||||
|
||||
testWithoutContext('Cache will default to current directory if there are no matches', () {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final String defaultFlutterRoot = Cache.defaultFlutterRoot(
|
||||
fileSystem: fileSystem,
|
||||
userMessages: UserMessages(),
|
||||
platform: FakePlatform(
|
||||
environment: <String, String>{},
|
||||
script: Uri.parse('http://foo.bar'), // does not match any heuristics.
|
||||
)
|
||||
);
|
||||
|
||||
expect(defaultFlutterRoot, '/');
|
||||
});
|
||||
}
|
@ -32,7 +32,6 @@ void main() {
|
||||
|
||||
setUpAll(() {
|
||||
Cache.disableLocking();
|
||||
Cache.flutterRoot = FlutterCommandRunner.defaultFlutterRoot;
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
|
Loading…
Reference in New Issue
Block a user