Unverified Commit ddd493b9 authored by Jesús S Guerrero's avatar Jesús S Guerrero Committed by GitHub

[flutter_tools] migrate project-validate to analyze --suggestions (#106149)

parent 47f54ace
...@@ -51,6 +51,7 @@ import 'src/globals.dart' as globals; ...@@ -51,6 +51,7 @@ import 'src/globals.dart' as globals;
import 'src/isolated/mustache_template.dart'; import 'src/isolated/mustache_template.dart';
import 'src/isolated/resident_web_runner.dart'; import 'src/isolated/resident_web_runner.dart';
import 'src/pre_run_validator.dart'; import 'src/pre_run_validator.dart';
import 'src/project_validator.dart';
import 'src/resident_runner.dart'; import 'src/resident_runner.dart';
import 'src/runner/flutter_command.dart'; import 'src/runner/flutter_command.dart';
import 'src/web/web_runner.dart'; import 'src/web/web_runner.dart';
...@@ -141,6 +142,7 @@ List<FlutterCommand> generateCommands({ ...@@ -141,6 +142,7 @@ List<FlutterCommand> generateCommands({
logger: globals.logger, logger: globals.logger,
terminal: globals.terminal, terminal: globals.terminal,
artifacts: globals.artifacts!, artifacts: globals.artifacts!,
allProjectValidators: <ProjectValidator>[],
), ),
AssembleCommand(verboseHelp: verboseHelp, buildSystem: globals.buildSystem), AssembleCommand(verboseHelp: verboseHelp, buildSystem: globals.buildSystem),
AttachCommand(verboseHelp: verboseHelp), AttachCommand(verboseHelp: verboseHelp),
......
...@@ -5,13 +5,17 @@ ...@@ -5,13 +5,17 @@
import 'package:process/process.dart'; import 'package:process/process.dart';
import '../artifacts.dart'; import '../artifacts.dart';
import '../base/common.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../base/terminal.dart'; import '../base/terminal.dart';
import '../project_validator.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
import 'analyze_base.dart';
import 'analyze_continuously.dart'; import 'analyze_continuously.dart';
import 'analyze_once.dart'; import 'analyze_once.dart';
import 'validate_project.dart';
class AnalyzeCommand extends FlutterCommand { class AnalyzeCommand extends FlutterCommand {
AnalyzeCommand({ AnalyzeCommand({
...@@ -23,11 +27,13 @@ class AnalyzeCommand extends FlutterCommand { ...@@ -23,11 +27,13 @@ class AnalyzeCommand extends FlutterCommand {
required Logger logger, required Logger logger,
required ProcessManager processManager, required ProcessManager processManager,
required Artifacts artifacts, required Artifacts artifacts,
required List<ProjectValidator> allProjectValidators,
}) : _artifacts = artifacts, }) : _artifacts = artifacts,
_fileSystem = fileSystem, _fileSystem = fileSystem,
_processManager = processManager, _processManager = processManager,
_logger = logger, _logger = logger,
_terminal = terminal, _terminal = terminal,
_allProjectValidators = allProjectValidators,
_platform = platform { _platform = platform {
argParser.addFlag('flutter-repo', argParser.addFlag('flutter-repo',
negatable: false, negatable: false,
...@@ -56,6 +62,9 @@ class AnalyzeCommand extends FlutterCommand { ...@@ -56,6 +62,9 @@ class AnalyzeCommand extends FlutterCommand {
help: 'The path to write the request and response protocol. This is ' help: 'The path to write the request and response protocol. This is '
'only intended to be used for debugging the tooling.', 'only intended to be used for debugging the tooling.',
hide: !verboseHelp); hide: !verboseHelp);
argParser.addFlag('suggestions',
help: 'Show suggestions about the current flutter project.'
);
// Hidden option to enable a benchmarking mode. // Hidden option to enable a benchmarking mode.
argParser.addFlag('benchmark', argParser.addFlag('benchmark',
...@@ -92,6 +101,7 @@ class AnalyzeCommand extends FlutterCommand { ...@@ -92,6 +101,7 @@ class AnalyzeCommand extends FlutterCommand {
final Terminal _terminal; final Terminal _terminal;
final ProcessManager _processManager; final ProcessManager _processManager;
final Platform _platform; final Platform _platform;
final List<ProjectValidator> _allProjectValidators;
@override @override
String get name => 'analyze'; String get name => 'analyze';
...@@ -119,7 +129,29 @@ class AnalyzeCommand extends FlutterCommand { ...@@ -119,7 +129,29 @@ class AnalyzeCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (boolArgDeprecated('watch')) { final bool? suggestionFlag = boolArg('suggestions');
if (suggestionFlag != null && suggestionFlag == true) {
final String directoryPath;
final bool? watchFlag = boolArg('watch');
if (watchFlag != null && watchFlag) {
throwToolExit('flag --watch is not compatible with --suggestions');
}
if (workingDirectory == null) {
final Set<String> items = findDirectories(argResults!, _fileSystem);
if (items.isEmpty || items.length > 1) {
throwToolExit('The suggestions flags needs one directory path');
}
directoryPath = items.first;
} else {
directoryPath = workingDirectory!.path;
}
return ValidateProject(
fileSystem: _fileSystem,
logger: _logger,
allProjectValidators: _allProjectValidators,
userPath: directoryPath,
).run();
} else if (boolArgDeprecated('watch')) {
await AnalyzeContinuously( await AnalyzeContinuously(
argResults!, argResults!,
runner!.getRepoRoots(), runner!.getRepoRoots(),
......
...@@ -286,3 +286,20 @@ class PackageDependencyTracker { ...@@ -286,3 +286,20 @@ class PackageDependencyTracker {
return result; return result;
} }
} }
/// Find directories or files from argResults.rest.
Set<String> findDirectories(ArgResults argResults, FileSystem fileSystem) {
final Set<String> items = Set<String>.of(argResults.rest
.map<String>((String path) => fileSystem.path.canonicalize(path)));
if (items.isNotEmpty) {
for (final String item in items) {
final FileSystemEntityType type = fileSystem.typeSync(item);
if (type == FileSystemEntityType.notFound) {
throwToolExit("You provided the path '$item', however it does not exist on disk");
}
}
}
return items;
}
...@@ -35,19 +35,7 @@ class AnalyzeOnce extends AnalyzeBase { ...@@ -35,19 +35,7 @@ class AnalyzeOnce extends AnalyzeBase {
Future<void> analyze() async { Future<void> analyze() async {
final String currentDirectory = final String currentDirectory =
(workingDirectory ?? fileSystem.currentDirectory).path; (workingDirectory ?? fileSystem.currentDirectory).path;
final Set<String> items = findDirectories(argResults, fileSystem);
// find directories or files from argResults.rest
final Set<String> items = Set<String>.of(argResults.rest
.map<String>((String path) => fileSystem.path.canonicalize(path)));
if (items.isNotEmpty) {
for (final String item in items) {
final FileSystemEntityType type = fileSystem.typeSync(item);
if (type == FileSystemEntityType.notFound) {
throwToolExit("'$item' does not exist");
}
}
}
if (isFlutterRepo) { if (isFlutterRepo) {
// check for conflicting dependencies // check for conflicting dependencies
......
...@@ -9,31 +9,22 @@ import '../project_validator.dart'; ...@@ -9,31 +9,22 @@ import '../project_validator.dart';
import '../project_validator_result.dart'; import '../project_validator_result.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
class ValidateProjectCommand extends FlutterCommand { class ValidateProject {
ValidateProjectCommand({ ValidateProject({
required this.fileSystem, required this.fileSystem,
required this.logger, required this.logger,
required this.allProjectValidators, required this.allProjectValidators,
required this.userPath,
this.verbose = false this.verbose = false
}); });
final FileSystem fileSystem; final FileSystem fileSystem;
final Logger logger; final Logger logger;
final bool verbose; final bool verbose;
final String userPath;
final List<ProjectValidator> allProjectValidators; final List<ProjectValidator> allProjectValidators;
@override Future<FlutterCommandResult> run() async {
final String name = 'validate-project';
@override
final String description = 'Show information about the current project.';
@override
final String category = FlutterCommandCategory.project;
@override
Future<FlutterCommandResult> runCommand() async {
final String userPath = getUserPath();
final Directory workingDirectory = userPath.isEmpty ? fileSystem.currentDirectory : fileSystem.directory(userPath); final Directory workingDirectory = userPath.isEmpty ? fileSystem.currentDirectory : fileSystem.directory(userPath);
final FlutterProject project = FlutterProject.fromDirectory(workingDirectory); final FlutterProject project = FlutterProject.fromDirectory(workingDirectory);
...@@ -94,8 +85,4 @@ class ValidateProjectCommand extends FlutterCommand { ...@@ -94,8 +85,4 @@ class ValidateProjectCommand extends FlutterCommand {
return '$icon $result'; return '$icon $result';
} }
String getUserPath(){
return (argResults == null || argResults!.rest.isEmpty) ? '' : argResults!.rest[0];
}
} }
...@@ -19,6 +19,7 @@ import 'package:flutter_tools/src/commands/analyze.dart'; ...@@ -19,6 +19,7 @@ import 'package:flutter_tools/src/commands/analyze.dart';
import 'package:flutter_tools/src/dart/analysis.dart'; import 'package:flutter_tools/src/dart/analysis.dart';
import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/project_validator.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
import '../../src/common.dart'; import '../../src/common.dart';
...@@ -199,6 +200,7 @@ void main() { ...@@ -199,6 +200,7 @@ void main() {
platform: FakePlatform(), platform: FakePlatform(),
fileSystem: MemoryFileSystem.test(), fileSystem: MemoryFileSystem.test(),
processManager: processManager, processManager: processManager,
allProjectValidators: <ProjectValidator>[],
); );
final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner(); final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner();
...@@ -246,6 +248,7 @@ void main() { ...@@ -246,6 +248,7 @@ void main() {
platform: FakePlatform(), platform: FakePlatform(),
fileSystem: fileSystem, fileSystem: fileSystem,
processManager: processManager, processManager: processManager,
allProjectValidators: <ProjectValidator>[],
); );
await FakeAsync().run((FakeAsync time) async { await FakeAsync().run((FakeAsync time) async {
...@@ -298,6 +301,7 @@ void main() { ...@@ -298,6 +301,7 @@ void main() {
platform: FakePlatform(), platform: FakePlatform(),
fileSystem: MemoryFileSystem.test(), fileSystem: MemoryFileSystem.test(),
processManager: processManager, processManager: processManager,
allProjectValidators: <ProjectValidator>[],
); );
await FakeAsync().run((FakeAsync time) async { await FakeAsync().run((FakeAsync time) async {
......
...@@ -6,13 +6,17 @@ ...@@ -6,13 +6,17 @@
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/commands/validate_project.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/commands/analyze.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/project_validator.dart'; import 'package:flutter_tools/src/project_validator.dart';
import 'package:flutter_tools/src/project_validator_result.dart'; import 'package:flutter_tools/src/project_validator_result.dart';
import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/test_flutter_command_runner.dart'; import '../../src/test_flutter_command_runner.dart';
...@@ -70,26 +74,36 @@ class ProjectValidatorCrash extends ProjectValidator { ...@@ -70,26 +74,36 @@ class ProjectValidatorCrash extends ProjectValidator {
void main() { void main() {
FileSystem fileSystem; FileSystem fileSystem;
Terminal terminal;
ProcessManager processManager;
Platform platform;
group('analyze project command', () { group('analyze --suggestions command', () {
setUp(() { setUp(() {
fileSystem = MemoryFileSystem.test(); fileSystem = MemoryFileSystem.test();
terminal = Terminal.test();
processManager = FakeProcessManager.empty();
platform = FakePlatform();
}); });
testUsingContext('success, error and warning', () async { testUsingContext('success, error and warning', () async {
final BufferLogger loggerTest = BufferLogger.test(); final BufferLogger loggerTest = BufferLogger.test();
final ValidateProjectCommand command = ValidateProjectCommand( final AnalyzeCommand command = AnalyzeCommand(
fileSystem: fileSystem, artifacts: Artifacts.test(),
logger: loggerTest, fileSystem: fileSystem,
allProjectValidators: <ProjectValidator>[ logger: loggerTest,
ProjectValidatorDummy(), platform: platform,
ProjectValidatorSecondDummy() terminal: terminal,
] processManager: processManager,
allProjectValidators: <ProjectValidator>[
ProjectValidatorDummy(),
ProjectValidatorSecondDummy()
]
); );
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['validate-project']); await runner.run(<String>['analyze', '--suggestions', './']);
const String expected = '\n' const String expected = '\n'
'┌──────────────────────────────────────────┐\n' '┌──────────────────────────────────────────┐\n'
...@@ -107,18 +121,41 @@ void main() { ...@@ -107,18 +121,41 @@ void main() {
testUsingContext('crash', () async { testUsingContext('crash', () async {
final BufferLogger loggerTest = BufferLogger.test(); final BufferLogger loggerTest = BufferLogger.test();
final ValidateProjectCommand command = ValidateProjectCommand( final AnalyzeCommand command = AnalyzeCommand(
artifacts: Artifacts.test(),
fileSystem: fileSystem, fileSystem: fileSystem,
logger: loggerTest, logger: loggerTest,
allProjectValidators: <ProjectValidator>[ProjectValidatorCrash()] platform: platform,
terminal: terminal,
processManager: processManager,
allProjectValidators: <ProjectValidator>[
ProjectValidatorCrash(),
]
); );
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['validate-project']); await runner.run(<String>['analyze', '--suggestions', './']);
const String expected = '[☠] Exception: my exception: #0 ProjectValidatorCrash.start'; const String expected = '[☠] Exception: my exception: #0 ProjectValidatorCrash.start';
expect(loggerTest.statusText, contains(expected)); expect(loggerTest.statusText, contains(expected));
}); });
testUsingContext('--watch and --suggestions not compatible together', () async {
final BufferLogger loggerTest = BufferLogger.test();
final AnalyzeCommand command = AnalyzeCommand(
artifacts: Artifacts.test(),
fileSystem: fileSystem,
logger: loggerTest,
platform: platform,
terminal: terminal,
processManager: processManager,
allProjectValidators: <ProjectValidator>[]
);
final CommandRunner<void> runner = createTestCommandRunner(command);
Future<void> result () => runner.run(<String>['analyze', '--suggestions', '--watch']);
expect(result, throwsToolExit(message: 'flag --watch is not compatible with --suggestions'));
});
}); });
} }
...@@ -15,6 +15,7 @@ import 'package:flutter_tools/src/cache.dart'; ...@@ -15,6 +15,7 @@ import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/analyze.dart'; import 'package:flutter_tools/src/commands/analyze.dart';
import 'package:flutter_tools/src/commands/analyze_base.dart'; import 'package:flutter_tools/src/commands/analyze_base.dart';
import 'package:flutter_tools/src/dart/analysis.dart'; import 'package:flutter_tools/src/dart/analysis.dart';
import 'package:flutter_tools/src/project_validator.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
...@@ -70,6 +71,7 @@ void main() { ...@@ -70,6 +71,7 @@ void main() {
platform: platform, platform: platform,
processManager: processManager, processManager: processManager,
terminal: terminal, terminal: terminal,
allProjectValidators: <ProjectValidator>[],
); );
runner = createTestCommandRunner(command); runner = createTestCommandRunner(command);
......
...@@ -160,7 +160,7 @@ void main() { ...@@ -160,7 +160,7 @@ void main() {
testWithoutContext('file not found', () async { testWithoutContext('file not found', () async {
await runCommand( await runCommand(
arguments: <String>['analyze', '--no-pub', 'not_found.abc'], arguments: <String>['analyze', '--no-pub', 'not_found.abc'],
exitMessageContains: "not_found.abc' does not exist", exitMessageContains: "not_found.abc', however it does not exist on disk",
exitCode: 1 exitCode: 1
); );
}); });
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/commands/validate_project.dart'; import 'package:flutter_tools/src/commands/analyze.dart';
import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/project_validator.dart'; import 'package:flutter_tools/src/project_validator.dart';
...@@ -15,7 +15,7 @@ import '../src/test_flutter_command_runner.dart'; ...@@ -15,7 +15,7 @@ import '../src/test_flutter_command_runner.dart';
void main() { void main() {
late FileSystem fileSystem; late FileSystem fileSystem;
group('analyze project command', () { group('analyze --suggestions command integration', () {
setUp(() { setUp(() {
fileSystem = globals.localFileSystem; fileSystem = globals.localFileSystem;
...@@ -23,14 +23,24 @@ void main() { ...@@ -23,14 +23,24 @@ void main() {
testUsingContext('General Info Project Validator', () async { testUsingContext('General Info Project Validator', () async {
final BufferLogger loggerTest = BufferLogger.test(); final BufferLogger loggerTest = BufferLogger.test();
final ValidateProjectCommand command = ValidateProjectCommand( final AnalyzeCommand command = AnalyzeCommand(
artifacts: globals.artifacts!,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: loggerTest, logger: loggerTest,
allProjectValidators: <ProjectValidator>[GeneralInfoProjectValidator()] platform: globals.platform,
terminal: globals.terminal,
processManager: globals.processManager,
allProjectValidators: <ProjectValidator>[GeneralInfoProjectValidator()],
); );
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['validate-project', '../../dev/integration_tests/flutter_gallery']); await runner.run(<String>[
'analyze',
'--no-pub',
'--no-current-package',
'--suggestions',
'../../dev/integration_tests/flutter_gallery',
]);
const String expected = '\n' const String expected = '\n'
'┌────────────────────────────────────────────────────────────────────────────┐\n' '┌────────────────────────────────────────────────────────────────────────────┐\n'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment