Skip to content

Commit ddd493b

Browse files
authored
[flutter_tools] migrate project-validate to analyze --suggestions (#106149)
1 parent 47f54ac commit ddd493b

File tree

10 files changed

+130
-51
lines changed

10 files changed

+130
-51
lines changed

packages/flutter_tools/lib/executable.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import 'src/globals.dart' as globals;
5151
import 'src/isolated/mustache_template.dart';
5252
import 'src/isolated/resident_web_runner.dart';
5353
import 'src/pre_run_validator.dart';
54+
import 'src/project_validator.dart';
5455
import 'src/resident_runner.dart';
5556
import 'src/runner/flutter_command.dart';
5657
import 'src/web/web_runner.dart';
@@ -141,6 +142,7 @@ List<FlutterCommand> generateCommands({
141142
logger: globals.logger,
142143
terminal: globals.terminal,
143144
artifacts: globals.artifacts!,
145+
allProjectValidators: <ProjectValidator>[],
144146
),
145147
AssembleCommand(verboseHelp: verboseHelp, buildSystem: globals.buildSystem),
146148
AttachCommand(verboseHelp: verboseHelp),

packages/flutter_tools/lib/src/commands/analyze.dart

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
import 'package:process/process.dart';
66

77
import '../artifacts.dart';
8+
import '../base/common.dart';
89
import '../base/file_system.dart';
910
import '../base/logger.dart';
1011
import '../base/platform.dart';
1112
import '../base/terminal.dart';
13+
import '../project_validator.dart';
1214
import '../runner/flutter_command.dart';
15+
import 'analyze_base.dart';
1316
import 'analyze_continuously.dart';
1417
import 'analyze_once.dart';
18+
import 'validate_project.dart';
1519

1620
class AnalyzeCommand extends FlutterCommand {
1721
AnalyzeCommand({
@@ -23,11 +27,13 @@ class AnalyzeCommand extends FlutterCommand {
2327
required Logger logger,
2428
required ProcessManager processManager,
2529
required Artifacts artifacts,
30+
required List<ProjectValidator> allProjectValidators,
2631
}) : _artifacts = artifacts,
2732
_fileSystem = fileSystem,
2833
_processManager = processManager,
2934
_logger = logger,
3035
_terminal = terminal,
36+
_allProjectValidators = allProjectValidators,
3137
_platform = platform {
3238
argParser.addFlag('flutter-repo',
3339
negatable: false,
@@ -56,6 +62,9 @@ class AnalyzeCommand extends FlutterCommand {
5662
help: 'The path to write the request and response protocol. This is '
5763
'only intended to be used for debugging the tooling.',
5864
hide: !verboseHelp);
65+
argParser.addFlag('suggestions',
66+
help: 'Show suggestions about the current flutter project.'
67+
);
5968

6069
// Hidden option to enable a benchmarking mode.
6170
argParser.addFlag('benchmark',
@@ -92,6 +101,7 @@ class AnalyzeCommand extends FlutterCommand {
92101
final Terminal _terminal;
93102
final ProcessManager _processManager;
94103
final Platform _platform;
104+
final List<ProjectValidator> _allProjectValidators;
95105

96106
@override
97107
String get name => 'analyze';
@@ -119,7 +129,29 @@ class AnalyzeCommand extends FlutterCommand {
119129

120130
@override
121131
Future<FlutterCommandResult> runCommand() async {
122-
if (boolArgDeprecated('watch')) {
132+
final bool? suggestionFlag = boolArg('suggestions');
133+
if (suggestionFlag != null && suggestionFlag == true) {
134+
final String directoryPath;
135+
final bool? watchFlag = boolArg('watch');
136+
if (watchFlag != null && watchFlag) {
137+
throwToolExit('flag --watch is not compatible with --suggestions');
138+
}
139+
if (workingDirectory == null) {
140+
final Set<String> items = findDirectories(argResults!, _fileSystem);
141+
if (items.isEmpty || items.length > 1) {
142+
throwToolExit('The suggestions flags needs one directory path');
143+
}
144+
directoryPath = items.first;
145+
} else {
146+
directoryPath = workingDirectory!.path;
147+
}
148+
return ValidateProject(
149+
fileSystem: _fileSystem,
150+
logger: _logger,
151+
allProjectValidators: _allProjectValidators,
152+
userPath: directoryPath,
153+
).run();
154+
} else if (boolArgDeprecated('watch')) {
123155
await AnalyzeContinuously(
124156
argResults!,
125157
runner!.getRepoRoots(),

packages/flutter_tools/lib/src/commands/analyze_base.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,3 +286,20 @@ class PackageDependencyTracker {
286286
return result;
287287
}
288288
}
289+
290+
/// Find directories or files from argResults.rest.
291+
Set<String> findDirectories(ArgResults argResults, FileSystem fileSystem) {
292+
final Set<String> items = Set<String>.of(argResults.rest
293+
.map<String>((String path) => fileSystem.path.canonicalize(path)));
294+
if (items.isNotEmpty) {
295+
for (final String item in items) {
296+
final FileSystemEntityType type = fileSystem.typeSync(item);
297+
298+
if (type == FileSystemEntityType.notFound) {
299+
throwToolExit("You provided the path '$item', however it does not exist on disk");
300+
}
301+
}
302+
}
303+
304+
return items;
305+
}

packages/flutter_tools/lib/src/commands/analyze_once.dart

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,7 @@ class AnalyzeOnce extends AnalyzeBase {
3535
Future<void> analyze() async {
3636
final String currentDirectory =
3737
(workingDirectory ?? fileSystem.currentDirectory).path;
38-
39-
// find directories or files from argResults.rest
40-
final Set<String> items = Set<String>.of(argResults.rest
41-
.map<String>((String path) => fileSystem.path.canonicalize(path)));
42-
if (items.isNotEmpty) {
43-
for (final String item in items) {
44-
final FileSystemEntityType type = fileSystem.typeSync(item);
45-
46-
if (type == FileSystemEntityType.notFound) {
47-
throwToolExit("'$item' does not exist");
48-
}
49-
}
50-
}
38+
final Set<String> items = findDirectories(argResults, fileSystem);
5139

5240
if (isFlutterRepo) {
5341
// check for conflicting dependencies

packages/flutter_tools/lib/src/commands/validate_project.dart

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,22 @@ import '../project_validator.dart';
99
import '../project_validator_result.dart';
1010
import '../runner/flutter_command.dart';
1111

12-
class ValidateProjectCommand extends FlutterCommand {
13-
ValidateProjectCommand({
12+
class ValidateProject {
13+
ValidateProject({
1414
required this.fileSystem,
1515
required this.logger,
1616
required this.allProjectValidators,
17+
required this.userPath,
1718
this.verbose = false
1819
});
1920

2021
final FileSystem fileSystem;
2122
final Logger logger;
2223
final bool verbose;
24+
final String userPath;
2325
final List<ProjectValidator> allProjectValidators;
2426

25-
@override
26-
final String name = 'validate-project';
27-
28-
@override
29-
final String description = 'Show information about the current project.';
30-
31-
@override
32-
final String category = FlutterCommandCategory.project;
33-
34-
@override
35-
Future<FlutterCommandResult> runCommand() async {
36-
final String userPath = getUserPath();
27+
Future<FlutterCommandResult> run() async {
3728
final Directory workingDirectory = userPath.isEmpty ? fileSystem.currentDirectory : fileSystem.directory(userPath);
3829

3930
final FlutterProject project = FlutterProject.fromDirectory(workingDirectory);
@@ -94,8 +85,4 @@ class ValidateProjectCommand extends FlutterCommand {
9485

9586
return '$icon $result';
9687
}
97-
98-
String getUserPath(){
99-
return (argResults == null || argResults!.rest.isEmpty) ? '' : argResults!.rest[0];
100-
}
10188
}

packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import 'package:flutter_tools/src/commands/analyze.dart';
1919
import 'package:flutter_tools/src/dart/analysis.dart';
2020
import 'package:flutter_tools/src/dart/pub.dart';
2121
import 'package:flutter_tools/src/globals.dart' as globals;
22+
import 'package:flutter_tools/src/project_validator.dart';
2223
import 'package:process/process.dart';
2324

2425
import '../../src/common.dart';
@@ -199,6 +200,7 @@ void main() {
199200
platform: FakePlatform(),
200201
fileSystem: MemoryFileSystem.test(),
201202
processManager: processManager,
203+
allProjectValidators: <ProjectValidator>[],
202204
);
203205

204206
final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner();
@@ -246,6 +248,7 @@ void main() {
246248
platform: FakePlatform(),
247249
fileSystem: fileSystem,
248250
processManager: processManager,
251+
allProjectValidators: <ProjectValidator>[],
249252
);
250253

251254
await FakeAsync().run((FakeAsync time) async {
@@ -298,6 +301,7 @@ void main() {
298301
platform: FakePlatform(),
299302
fileSystem: MemoryFileSystem.test(),
300303
processManager: processManager,
304+
allProjectValidators: <ProjectValidator>[],
301305
);
302306

303307
await FakeAsync().run((FakeAsync time) async {

packages/flutter_tools/test/commands.shard/hermetic/project_validator_test.dart renamed to packages/flutter_tools/test/commands.shard/hermetic/analyze_suggestion_test.dart

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@
66

77
import 'package:args/command_runner.dart';
88
import 'package:file/memory.dart';
9+
import 'package:flutter_tools/src/artifacts.dart';
910
import 'package:flutter_tools/src/base/file_system.dart';
1011
import 'package:flutter_tools/src/base/logger.dart';
11-
import 'package:flutter_tools/src/commands/validate_project.dart';
12+
import 'package:flutter_tools/src/base/platform.dart';
13+
import 'package:flutter_tools/src/base/terminal.dart';
14+
import 'package:flutter_tools/src/commands/analyze.dart';
1215
import 'package:flutter_tools/src/project.dart';
1316
import 'package:flutter_tools/src/project_validator.dart';
1417
import 'package:flutter_tools/src/project_validator_result.dart';
1518

19+
import '../../src/common.dart';
1620
import '../../src/context.dart';
1721
import '../../src/test_flutter_command_runner.dart';
1822

@@ -70,26 +74,36 @@ class ProjectValidatorCrash extends ProjectValidator {
7074

7175
void main() {
7276
FileSystem fileSystem;
77+
Terminal terminal;
78+
ProcessManager processManager;
79+
Platform platform;
7380

74-
group('analyze project command', () {
81+
group('analyze --suggestions command', () {
7582

7683
setUp(() {
7784
fileSystem = MemoryFileSystem.test();
85+
terminal = Terminal.test();
86+
processManager = FakeProcessManager.empty();
87+
platform = FakePlatform();
7888
});
7989

8090
testUsingContext('success, error and warning', () async {
8191
final BufferLogger loggerTest = BufferLogger.test();
82-
final ValidateProjectCommand command = ValidateProjectCommand(
83-
fileSystem: fileSystem,
84-
logger: loggerTest,
85-
allProjectValidators: <ProjectValidator>[
86-
ProjectValidatorDummy(),
87-
ProjectValidatorSecondDummy()
88-
]
92+
final AnalyzeCommand command = AnalyzeCommand(
93+
artifacts: Artifacts.test(),
94+
fileSystem: fileSystem,
95+
logger: loggerTest,
96+
platform: platform,
97+
terminal: terminal,
98+
processManager: processManager,
99+
allProjectValidators: <ProjectValidator>[
100+
ProjectValidatorDummy(),
101+
ProjectValidatorSecondDummy()
102+
]
89103
);
90104
final CommandRunner<void> runner = createTestCommandRunner(command);
91105

92-
await runner.run(<String>['validate-project']);
106+
await runner.run(<String>['analyze', '--suggestions', './']);
93107

94108
const String expected = '\n'
95109
'┌──────────────────────────────────────────┐\n'
@@ -107,18 +121,41 @@ void main() {
107121

108122
testUsingContext('crash', () async {
109123
final BufferLogger loggerTest = BufferLogger.test();
110-
final ValidateProjectCommand command = ValidateProjectCommand(
124+
final AnalyzeCommand command = AnalyzeCommand(
125+
artifacts: Artifacts.test(),
111126
fileSystem: fileSystem,
112127
logger: loggerTest,
113-
allProjectValidators: <ProjectValidator>[ProjectValidatorCrash()]
128+
platform: platform,
129+
terminal: terminal,
130+
processManager: processManager,
131+
allProjectValidators: <ProjectValidator>[
132+
ProjectValidatorCrash(),
133+
]
114134
);
115135
final CommandRunner<void> runner = createTestCommandRunner(command);
116136

117-
await runner.run(<String>['validate-project']);
137+
await runner.run(<String>['analyze', '--suggestions', './']);
118138

119139
const String expected = '[☠] Exception: my exception: #0 ProjectValidatorCrash.start';
120140

121141
expect(loggerTest.statusText, contains(expected));
122142
});
143+
144+
testUsingContext('--watch and --suggestions not compatible together', () async {
145+
final BufferLogger loggerTest = BufferLogger.test();
146+
final AnalyzeCommand command = AnalyzeCommand(
147+
artifacts: Artifacts.test(),
148+
fileSystem: fileSystem,
149+
logger: loggerTest,
150+
platform: platform,
151+
terminal: terminal,
152+
processManager: processManager,
153+
allProjectValidators: <ProjectValidator>[]
154+
);
155+
final CommandRunner<void> runner = createTestCommandRunner(command);
156+
Future<void> result () => runner.run(<String>['analyze', '--suggestions', '--watch']);
157+
158+
expect(result, throwsToolExit(message: 'flag --watch is not compatible with --suggestions'));
159+
});
123160
});
124161
}

packages/flutter_tools/test/commands.shard/hermetic/analyze_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import 'package:flutter_tools/src/cache.dart';
1515
import 'package:flutter_tools/src/commands/analyze.dart';
1616
import 'package:flutter_tools/src/commands/analyze_base.dart';
1717
import 'package:flutter_tools/src/dart/analysis.dart';
18+
import 'package:flutter_tools/src/project_validator.dart';
1819

1920
import '../../src/common.dart';
2021
import '../../src/context.dart';
@@ -70,6 +71,7 @@ void main() {
7071
platform: platform,
7172
processManager: processManager,
7273
terminal: terminal,
74+
allProjectValidators: <ProjectValidator>[],
7375
);
7476
runner = createTestCommandRunner(command);
7577

packages/flutter_tools/test/integration.shard/analyze_once_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ void main() {
160160
testWithoutContext('file not found', () async {
161161
await runCommand(
162162
arguments: <String>['analyze', '--no-pub', 'not_found.abc'],
163-
exitMessageContains: "not_found.abc' does not exist",
163+
exitMessageContains: "not_found.abc', however it does not exist on disk",
164164
exitCode: 1
165165
);
166166
});

packages/flutter_tools/test/integration.shard/project_validator_integration_test.dart renamed to packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import 'package:args/command_runner.dart';
66
import 'package:flutter_tools/src/base/file_system.dart';
77
import 'package:flutter_tools/src/base/logger.dart';
8-
import 'package:flutter_tools/src/commands/validate_project.dart';
8+
import 'package:flutter_tools/src/commands/analyze.dart';
99
import 'package:flutter_tools/src/globals.dart' as globals;
1010
import 'package:flutter_tools/src/project_validator.dart';
1111

@@ -15,22 +15,32 @@ import '../src/test_flutter_command_runner.dart';
1515
void main() {
1616
late FileSystem fileSystem;
1717

18-
group('analyze project command', () {
18+
group('analyze --suggestions command integration', () {
1919

2020
setUp(() {
2121
fileSystem = globals.localFileSystem;
2222
});
2323

2424
testUsingContext('General Info Project Validator', () async {
2525
final BufferLogger loggerTest = BufferLogger.test();
26-
final ValidateProjectCommand command = ValidateProjectCommand(
26+
final AnalyzeCommand command = AnalyzeCommand(
27+
artifacts: globals.artifacts!,
2728
fileSystem: fileSystem,
2829
logger: loggerTest,
29-
allProjectValidators: <ProjectValidator>[GeneralInfoProjectValidator()]
30+
platform: globals.platform,
31+
terminal: globals.terminal,
32+
processManager: globals.processManager,
33+
allProjectValidators: <ProjectValidator>[GeneralInfoProjectValidator()],
3034
);
3135
final CommandRunner<void> runner = createTestCommandRunner(command);
3236

33-
await runner.run(<String>['validate-project', '../../dev/integration_tests/flutter_gallery']);
37+
await runner.run(<String>[
38+
'analyze',
39+
'--no-pub',
40+
'--no-current-package',
41+
'--suggestions',
42+
'../../dev/integration_tests/flutter_gallery',
43+
]);
3444

3545
const String expected = '\n'
3646
'┌────────────────────────────────────────────────────────────────────────────┐\n'

0 commit comments

Comments
 (0)