🐛 [tool] Do not handle directory arguments implicitly for pub commands (#160223)

- Resolves https://github.com/flutter/flutter/issues/144898
- Resolves https://github.com/flutter/flutter/issues/160145

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Alex Li 2024-12-17 03:55:04 +08:00 committed by GitHub
parent 2bda0ccc75
commit a0f2424e2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 32 deletions

View File

@ -234,7 +234,7 @@ class PackagesGetCommand extends FlutterCommand {
@override
Future<FlutterCommandResult> runCommand() async {
List<String> rest = argResults!.rest;
final List<String> rest = argResults!.rest;
bool isHelp = false;
bool example = true;
bool exampleWasParsed = false;
@ -254,34 +254,12 @@ class PackagesGetCommand extends FlutterCommand {
FlutterProject? rootProject;
if (!isHelp) {
if (directoryOption == null &&
rest.length == 1 &&
// Anything that looks like an argument should not be interpreted as
// a directory.
!rest.single.startsWith('-') &&
((rest.single.contains('/') || rest.single.contains(r'\')) ||
name == 'get')) {
// For historical reasons, if there is one argument to the command and it contains
// a multiple-component path (i.e. contains a slash) then we use that to determine
// to which project we're applying the command.
target = findProjectRoot(globals.fs, rest.single);
globals.printWarning('''
Using a naked argument for directory is deprecated and will stop working in a future Flutter release.
Use --directory instead.''');
if (target == null) {
throwToolExit('Expected to find project root in ${rest.single}.');
}
rest = <String>[];
} else {
target = findProjectRoot(globals.fs, directoryOption);
if (target == null) {
if (directoryOption == null) {
throwToolExit('Expected to find project root in current working directory.');
} else {
throwToolExit('Expected to find project root in $directoryOption.');
}
target = findProjectRoot(globals.fs, directoryOption);
if (target == null) {
if (directoryOption == null) {
throwToolExit('Expected to find project root in current working directory.');
} else {
throwToolExit('Expected to find project root in $directoryOption.');
}
}

View File

@ -114,7 +114,7 @@ void main() {
final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet);
final CommandRunner<void> commandRunner = createTestCommandRunner(command);
await commandRunner.run(<String>['get', targetDirectory.path]);
await commandRunner.run(<String>['get', '--directory=${targetDirectory.path}']);
final FlutterProject rootProject = FlutterProject.fromDirectory(targetDirectory);
final File packageConfigFile = rootProject.dartTool.childFile('package_config.json');
expect(packageConfigFile.existsSync(), true);
@ -138,7 +138,7 @@ void main() {
FileSystem: () => fileSystem,
});
testUsingContext("pub get doesn't treat -v as directory", () async {
testUsingContext("pub get doesn't treat -v as directory", () async {
fileSystem.currentDirectory.childDirectory('target').createSync();
fileSystem.currentDirectory.childFile('pubspec.yaml').createSync();
final PackagesGetCommand command = PackagesGetCommand('get', '', PubContext.pubGet);
@ -151,6 +151,34 @@ void main() {
FileSystem: () => fileSystem,
});
// Regression test for https://github.com/flutter/flutter/issues/144898
// Regression test for https://github.com/flutter/flutter/issues/160145
testUsingContext("pub add doesn't treat dependency syntax as directory", () async {
fileSystem.currentDirectory.childDirectory('target').createSync();
fileSystem.currentDirectory.childFile('pubspec.yaml').createSync();
fileSystem.currentDirectory.childDirectory('example').createSync(recursive: true);
fileSystem.currentDirectory.childDirectory('android').childFile('AndroidManifest.xml')
..createSync(recursive: true)
..writeAsStringSync(minimalV2EmbeddingManifest);
final PackagesGetCommand command = PackagesGetCommand('add', '', PubContext.pubAdd);
final CommandRunner<void> commandRunner = createTestCommandRunner(command);
const List<String> availableSyntax = <String>[
'foo:{"path":"../foo"}',
'foo:{"hosted":"my-pub.dev"}',
'foo:{"sdk":"flutter"}',
'foo:{"git":"https://github.com/foo/foo"}',
];
for (final String syntax in availableSyntax) {
pub.expectedArguments = <String>['add', syntax, '--example', '--directory', '.'];
await commandRunner.run(<String>['add', syntax]);
}
}, overrides: <Type, Generator>{
Pub: () => pub,
ProcessManager: () => FakeProcessManager.any(),
FileSystem: () => fileSystem,
});
testUsingContext("pub get skips example directory if it doesn't contain a pubspec.yaml", () async {
fileSystem.currentDirectory.childFile('pubspec.yaml').createSync();
fileSystem.currentDirectory.childDirectory('example').createSync(recursive: true);
@ -179,7 +207,7 @@ void main() {
final CommandRunner<void> commandRunner = createTestCommandRunner(command);
try {
await commandRunner.run(<String>['get', 'missing_dir']);
await commandRunner.run(<String>['get', '--directory=missing_dir']);
fail('expected an exception');
} on Exception catch (e) {
expect(e.toString(), contains('Expected to find project root in missing_dir'));