feature/clean-a-specific-scheme: Add this-scheme new flag for clean command (#116733)
Co-authored-by: Enguerrand_ARMINJON_MAC_2 <earminjon@sqli.com>
This commit is contained in:
parent
902d86e09c
commit
6259b690f6
@ -5,6 +5,7 @@
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../../src/macos/xcode.dart';
|
||||
import '../base/common.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/logger.dart';
|
||||
import '../build_info.dart';
|
||||
@ -18,6 +19,10 @@ class CleanCommand extends FlutterCommand {
|
||||
bool verbose = false,
|
||||
}) : _verbose = verbose {
|
||||
requiresPubspecYaml();
|
||||
argParser.addOption(
|
||||
'scheme',
|
||||
help: 'When cleaning Xcode schemes, clean only the specified scheme.',
|
||||
);
|
||||
}
|
||||
|
||||
final bool _verbose;
|
||||
@ -81,11 +86,27 @@ class CleanCommand extends FlutterCommand {
|
||||
try {
|
||||
final XcodeProjectInterpreter xcodeProjectInterpreter = globals.xcodeProjectInterpreter!;
|
||||
final XcodeProjectInfo projectInfo = (await xcodeProjectInterpreter.getInfo(xcodeWorkspace.parent.path))!;
|
||||
for (final String scheme in projectInfo.schemes) {
|
||||
if (argResults?.wasParsed('scheme') ?? false) {
|
||||
final String scheme = argResults!['scheme'] as String;
|
||||
if (scheme.isEmpty) {
|
||||
throwToolExit('No scheme was specified for --scheme');
|
||||
}
|
||||
if (!projectInfo.schemes.contains(scheme)) {
|
||||
throwToolExit('Scheme "$scheme" not found in ${projectInfo.schemes}');
|
||||
}
|
||||
await xcodeProjectInterpreter.cleanWorkspace(xcodeWorkspace.path, scheme, verbose: _verbose);
|
||||
} else {
|
||||
for (final String scheme in projectInfo.schemes) {
|
||||
await xcodeProjectInterpreter.cleanWorkspace(xcodeWorkspace.path, scheme, verbose: _verbose);
|
||||
}
|
||||
}
|
||||
} on Exception catch (error) {
|
||||
globals.printTrace('Could not clean Xcode workspace: $error');
|
||||
final String message = 'Could not clean Xcode workspace: $error';
|
||||
if (argResults?.wasParsed('scheme') ?? false) {
|
||||
throwToolExit(message);
|
||||
} else {
|
||||
globals.printTrace(message);
|
||||
}
|
||||
} finally {
|
||||
xcodeStatus.stop();
|
||||
}
|
||||
@ -110,8 +131,7 @@ class CleanCommand extends FlutterCommand {
|
||||
} on FileSystemException catch (error) {
|
||||
final String path = file.path;
|
||||
if (globals.platform.isWindows) {
|
||||
globals.printError(
|
||||
'Failed to remove $path. '
|
||||
globals.printError('Failed to remove $path. '
|
||||
'A program may still be using a file in the directory or the directory itself. '
|
||||
'To find and stop such a program, see: '
|
||||
'https://superuser.com/questions/1333118/cant-delete-empty-folder-because-it-is-used');
|
||||
|
@ -2,12 +2,14 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:file_testing/file_testing.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/version.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/clean.dart';
|
||||
import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
||||
import 'package:flutter_tools/src/macos/xcode.dart';
|
||||
@ -17,6 +19,7 @@ import 'package:test/fake.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/test_flutter_command_runner.dart';
|
||||
|
||||
void main() {
|
||||
group('clean command', () {
|
||||
@ -24,6 +27,7 @@ void main() {
|
||||
late FakeXcodeProjectInterpreter xcodeProjectInterpreter;
|
||||
|
||||
setUp(() {
|
||||
Cache.disableLocking();
|
||||
xcodeProjectInterpreter = FakeXcodeProjectInterpreter();
|
||||
xcode = Xcode.test(
|
||||
processManager: FakeProcessManager.any(),
|
||||
@ -37,6 +41,7 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
fs = MemoryFileSystem.test();
|
||||
fs.file('pubspec.yaml').createSync(recursive: true);
|
||||
|
||||
final Directory currentDirectory = fs.currentDirectory;
|
||||
buildDirectory = currentDirectory.childDirectory('build');
|
||||
@ -72,7 +77,30 @@ void main() {
|
||||
|
||||
expect(xcodeProjectInterpreter.workspaces, const <CleanWorkspaceCall>[
|
||||
CleanWorkspaceCall('/ios/Runner.xcworkspace', 'Runner', false),
|
||||
CleanWorkspaceCall('/ios/Runner.xcworkspace', 'custom-scheme', false),
|
||||
CleanWorkspaceCall('/macos/Runner.xcworkspace', 'Runner', false),
|
||||
CleanWorkspaceCall('/macos/Runner.xcworkspace', 'custom-scheme', false),
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
Xcode: () => xcode,
|
||||
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
|
||||
});
|
||||
|
||||
testUsingContext('$CleanCommand removes a specific xcode scheme --scheme', () async {
|
||||
setupProjectUnderTest(fs.currentDirectory, true);
|
||||
// Xcode is installed and version satisfactory.
|
||||
xcodeProjectInterpreter.isInstalled = true;
|
||||
xcodeProjectInterpreter.version = Version(1000, 0, 0);
|
||||
|
||||
final CleanCommand command = CleanCommand();
|
||||
final CommandRunner<void> runner = createTestCommandRunner(command);
|
||||
await runner.run(<String>['clean', '--scheme=custom-scheme']);
|
||||
|
||||
expect(xcodeProjectInterpreter.workspaces, <CleanWorkspaceCall>[
|
||||
const CleanWorkspaceCall('/ios/Runner.xcworkspace', 'custom-scheme', false),
|
||||
const CleanWorkspaceCall('/macos/Runner.xcworkspace', 'custom-scheme', false),
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
@ -96,6 +124,28 @@ void main() {
|
||||
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
|
||||
});
|
||||
|
||||
testUsingContext('$CleanCommand throws when given an invalid value for --scheme', () async {
|
||||
setupProjectUnderTest(fs.currentDirectory, true);
|
||||
// Xcode is installed and version satisfactory.
|
||||
xcodeProjectInterpreter.isInstalled = true;
|
||||
xcodeProjectInterpreter.version = Version(1000, 0, 0);
|
||||
|
||||
final CleanCommand command = CleanCommand();
|
||||
expect(
|
||||
() => createTestCommandRunner(command).run(<String>['clean', '--scheme']),
|
||||
throwsUsageException(),
|
||||
);
|
||||
expect(
|
||||
() => createTestCommandRunner(command).run(<String>['clean', '--scheme=unknown']),
|
||||
throwsToolExit(),
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
Xcode: () => xcode,
|
||||
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
|
||||
});
|
||||
|
||||
testUsingContext('$CleanCommand cleans Xcode verbosely for iOS and macOS', () async {
|
||||
setupProjectUnderTest(fs.currentDirectory, true);
|
||||
// Xcode is installed and version satisfactory.
|
||||
@ -106,7 +156,9 @@ void main() {
|
||||
|
||||
expect(xcodeProjectInterpreter.workspaces, const <CleanWorkspaceCall>[
|
||||
CleanWorkspaceCall('/ios/Runner.xcworkspace', 'Runner', true),
|
||||
CleanWorkspaceCall('/ios/Runner.xcworkspace', 'custom-scheme', true),
|
||||
CleanWorkspaceCall('/macos/Runner.xcworkspace', 'Runner', true),
|
||||
CleanWorkspaceCall('/macos/Runner.xcworkspace', 'custom-scheme', true),
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
@ -209,7 +261,7 @@ class FakeXcodeProjectInterpreter extends Fake implements XcodeProjectInterprete
|
||||
return XcodeProjectInfo(
|
||||
const <String>[],
|
||||
const <String>[],
|
||||
<String>['Runner'],
|
||||
<String>['Runner', 'custom-scheme'],
|
||||
BufferLogger.test(),
|
||||
);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/context.dart';
|
||||
@ -103,6 +104,18 @@ Matcher throwsToolExit({ int? exitCode, Pattern? message }) {
|
||||
/// Matcher for [ToolExit]s.
|
||||
final TypeMatcher<ToolExit> _isToolExit = isA<ToolExit>();
|
||||
|
||||
/// Matcher for functions that throw [UsageException].
|
||||
Matcher throwsUsageException({Pattern? message }) {
|
||||
Matcher matcher = _isUsageException;
|
||||
if (message != null) {
|
||||
matcher = allOf(matcher, (UsageException e) => e.message.contains(message));
|
||||
}
|
||||
return throwsA(matcher);
|
||||
}
|
||||
|
||||
/// Matcher for [UsageException]s.
|
||||
final TypeMatcher<UsageException> _isUsageException = isA<UsageException>();
|
||||
|
||||
/// Matcher for functions that throw [ProcessException].
|
||||
Matcher throwsProcessException({ Pattern? message }) {
|
||||
Matcher matcher = _isProcessException;
|
||||
|
Loading…
x
Reference in New Issue
Block a user