From 4bad4597649dc63da0d2cf3b50915d49fe560d13 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 18:40:32 +0800 Subject: [PATCH 01/20] add blank AutoFix --- lib/src/auto_fix.dart | 23 +++++++++++++++++++++++ lib/src/dependency_validator.dart | 8 ++++++++ 2 files changed, 31 insertions(+) create mode 100644 lib/src/auto_fix.dart diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart new file mode 100644 index 0000000..740b690 --- /dev/null +++ b/lib/src/auto_fix.dart @@ -0,0 +1,23 @@ +class AutoFix { + final commands = []; + + void handleMissingDependencies(Set deps) { + TODO; + } + + void handleMissingDevDependencies(Set deps) { + TODO; + } + + void handleOverPromotedDependencies(Set deps) { + TODO; + } + + void handleUnderPromotedDependencies(Set deps) { + TODO; + } + + void handleUnusedDependencies(Set deps) { + TODO; + } +} diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index 4655cd3..fa09c11 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -15,6 +15,7 @@ import 'dart:io'; import 'package:build_config/build_config.dart'; +import 'package:dependency_validator/src/auto_fix.dart'; import 'package:glob/glob.dart'; import 'package:io/ansi.dart'; import 'package:logging/logging.dart'; @@ -28,6 +29,8 @@ import 'utils.dart'; /// Check for missing, under-promoted, over-promoted, and unused dependencies. Future run() async { + final autoFix = AutoFix(); + if (!File('pubspec.yaml').existsSync()) { logger.shout(red.wrap('pubspec.yaml not found')); exit(1); @@ -200,6 +203,7 @@ Future run() async { 'These packages are used in lib/ but are not dependencies:', missingDependencies, ); + autoFix.handleMissingDependencies(missingDependencies); exitCode = 1; } @@ -222,6 +226,7 @@ Future run() async { 'These packages are used outside lib/ but are not dev_dependencies:', missingDevDependencies, ); + autoFix.handleMissingDevDependencies(missingDevDependencies); exitCode = 1; } @@ -242,6 +247,7 @@ Future run() async { 'These packages are only used outside lib/ and should be downgraded to dev_dependencies:', overPromotedDependencies, ); + autoFix.handleOverPromotedDependencies(overPromotedDependencies); exitCode = 1; } @@ -258,6 +264,7 @@ Future run() async { 'These packages are used in lib/ and should be promoted to actual dependencies:', underPromotedDependencies, ); + autoFix.handleUnderPromotedDependencies(underPromotedDependencies); exitCode = 1; } @@ -343,6 +350,7 @@ Future run() async { 'These packages may be unused, or you may be using assets from these packages:', unusedDependencies, ); + autoFix.handleUnusedDependencies(unusedDependencies); exitCode = 1; } From 55dd81c24a19a57b5f3c64eb4b6d93f1e5428539 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:22:59 +0800 Subject: [PATCH 02/20] implement commands in AutoFix --- lib/src/auto_fix.dart | 12 +++++++----- lib/src/dependency_validator.dart | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index 740b690..d664676 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -1,23 +1,25 @@ +import 'package:pubspec_parse/pubspec_parse.dart'; + class AutoFix { final commands = []; void handleMissingDependencies(Set deps) { - TODO; + commands.add('dart pub add ' + deps.join(' ')); } void handleMissingDevDependencies(Set deps) { - TODO; + commands.add('dart pub add --dev ' + deps.join(' ')); } - void handleOverPromotedDependencies(Set deps) { + void handleOverPromotedDependencies(Set deps, Pubspec pubspec) { TODO; } - void handleUnderPromotedDependencies(Set deps) { + void handleUnderPromotedDependencies(Set deps, Pubspec pubspec) { TODO; } void handleUnusedDependencies(Set deps) { - TODO; + commands.add('dart remove ' + deps.join(' ')); } } diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index fa09c11..0e051fd 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -247,7 +247,7 @@ Future run() async { 'These packages are only used outside lib/ and should be downgraded to dev_dependencies:', overPromotedDependencies, ); - autoFix.handleOverPromotedDependencies(overPromotedDependencies); + autoFix.handleOverPromotedDependencies(overPromotedDependencies, pubspec); exitCode = 1; } @@ -264,7 +264,7 @@ Future run() async { 'These packages are used in lib/ and should be promoted to actual dependencies:', underPromotedDependencies, ); - autoFix.handleUnderPromotedDependencies(underPromotedDependencies); + autoFix.handleUnderPromotedDependencies(underPromotedDependencies, pubspec); exitCode = 1; } From 6f9dbf57a7b1bfbb4953eee8b0d03e7ca37364f8 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:25:16 +0800 Subject: [PATCH 03/20] reimplement --- lib/src/auto_fix.dart | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index d664676..c85300a 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -1,25 +1,37 @@ import 'package:pubspec_parse/pubspec_parse.dart'; class AutoFix { - final commands = []; + final _pubAdd = []; + final _pubAddDev = []; + final _pubRemove = []; void handleMissingDependencies(Set deps) { - commands.add('dart pub add ' + deps.join(' ')); + _pubAdd.addAll(deps); } void handleMissingDevDependencies(Set deps) { - commands.add('dart pub add --dev ' + deps.join(' ')); + _pubAddDev.addAll(deps); } void handleOverPromotedDependencies(Set deps, Pubspec pubspec) { - TODO; + _pubRemove.addAll(deps); + _pubAddDev.addAll(TODO); } void handleUnderPromotedDependencies(Set deps, Pubspec pubspec) { - TODO; + _pubRemove.addAll(deps); + _pubAdd.addAll(TODO); } void handleUnusedDependencies(Set deps) { - commands.add('dart remove ' + deps.join(' ')); + _pubRemove.addAll(deps); + } + + List compile() { + return [ + 'dart remove ' + _pubRemove.join(' '), + 'dart pub add ' + _pubAdd.join(' '), + 'dart pub add --dev ' + _pubAddDev.join(' '), + ]; } } From 5ffbe7ffe75cbc50dca8f759cfaa244f37eb7262 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:30:53 +0800 Subject: [PATCH 04/20] implement promote for AutoFix --- lib/src/auto_fix.dart | 23 +++++++++++++++++++---- lib/src/dependency_validator.dart | 8 ++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index c85300a..b33969d 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -1,10 +1,14 @@ import 'package:pubspec_parse/pubspec_parse.dart'; class AutoFix { + final Pubspec pubspec; + final _pubAdd = []; final _pubAddDev = []; final _pubRemove = []; + AutoFix(this.pubspec); + void handleMissingDependencies(Set deps) { _pubAdd.addAll(deps); } @@ -13,20 +17,31 @@ class AutoFix { _pubAddDev.addAll(deps); } - void handleOverPromotedDependencies(Set deps, Pubspec pubspec) { + void handleOverPromotedDependencies(Set deps) { _pubRemove.addAll(deps); - _pubAddDev.addAll(TODO); + _pubAddDev.addAll(_parseDepsWithConstraints(deps)); } - void handleUnderPromotedDependencies(Set deps, Pubspec pubspec) { + void handleUnderPromotedDependencies(Set deps) { _pubRemove.addAll(deps); - _pubAdd.addAll(TODO); + _pubAdd.addAll(_parseDepsWithConstraints(deps)); } void handleUnusedDependencies(Set deps) { _pubRemove.addAll(deps); } + List _parseDepsWithConstraints(Set deps) { + return deps.map((dep) => _parseConstraint(dep)).where((e) => e != null).map((e) => e!).toList(); + } + + String? _parseConstraint(String name) { + final dependency = pubspec.dependencies[name] ?? pubspec.devDependencies[name]; + if (dependency == null || dependency is! HostedDependency) return null; + final constraint = dependency.version.toString(); + return name + ':' + constraint; + } + List compile() { return [ 'dart remove ' + _pubRemove.join(' '), diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index 0e051fd..32c4664 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -29,8 +29,6 @@ import 'utils.dart'; /// Check for missing, under-promoted, over-promoted, and unused dependencies. Future run() async { - final autoFix = AutoFix(); - if (!File('pubspec.yaml').existsSync()) { logger.shout(red.wrap('pubspec.yaml not found')); exit(1); @@ -79,6 +77,8 @@ Future run() async { final pubspec = Pubspec.parse(pubspecFile.readAsStringSync(), sourceUrl: pubspecFile.uri); + final autoFix = AutoFix(pubspec); + logger.info('Validating dependencies for ${pubspec.name}...'); if (!config.allowPins) { @@ -247,7 +247,7 @@ Future run() async { 'These packages are only used outside lib/ and should be downgraded to dev_dependencies:', overPromotedDependencies, ); - autoFix.handleOverPromotedDependencies(overPromotedDependencies, pubspec); + autoFix.handleOverPromotedDependencies(overPromotedDependencies); exitCode = 1; } @@ -264,7 +264,7 @@ Future run() async { 'These packages are used in lib/ and should be promoted to actual dependencies:', underPromotedDependencies, ); - autoFix.handleUnderPromotedDependencies(underPromotedDependencies, pubspec); + autoFix.handleUnderPromotedDependencies(underPromotedDependencies); exitCode = 1; } From d47b4d71e540677f1362d1c3075c52a1fd6a6c3b Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:32:41 +0800 Subject: [PATCH 05/20] print commands --- lib/src/dependency_validator.dart | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index 32c4664..7c12f4c 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -354,6 +354,15 @@ Future run() async { exitCode = 1; } + final autoFixCommands = autoFix.compile(); + if (autoFixCommands.isNotEmpty) { + log( + Level.INFO, + 'Suggestion for auto fix:', + autoFixCommands, + ); + } + if (exitCode == 0) { logger.info(green.wrap('✓ No dependency issues found!')); } From 3a6359da3eefbcdc59014e11f81954addc882a9d Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:34:35 +0800 Subject: [PATCH 06/20] add cwd --- bin/dependency_validator.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bin/dependency_validator.dart b/bin/dependency_validator.dart index bc762f8..de3bdea 100644 --- a/bin/dependency_validator.dart +++ b/bin/dependency_validator.dart @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import 'dart:io' show exit, stderr, stdout; +import 'dart:io' show Directory, exit, stderr, stdout; import 'package:args/args.dart'; import 'package:dependency_validator/src/dependency_validator.dart'; @@ -36,6 +36,11 @@ usage:'''; /// Parses the command-line arguments final ArgParser argParser = ArgParser() + ..addOption( + 'path', + abbr: 'p', + help: 'Specify package path', + ) ..addFlag( helpArg, abbr: 'h', @@ -78,5 +83,10 @@ void main(List args) async { Logger.root.level = Level.ALL; } + final path = argResults['path'] as String?; + if (path != null) { + Directory.current = path; + } + await run(); } From 379bb6ee7ae12b54bbb1a4a9031b68dae9f5f206 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:36:04 +0800 Subject: [PATCH 07/20] improve output --- lib/src/dependency_validator.dart | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index 7c12f4c..9b051d7 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -356,11 +356,7 @@ Future run() async { final autoFixCommands = autoFix.compile(); if (autoFixCommands.isNotEmpty) { - log( - Level.INFO, - 'Suggestion for auto fix:', - autoFixCommands, - ); + logger.info('Suggestion for auto fix: ${autoFixCommands.join(" && ")}'); } if (exitCode == 0) { From d27fd3674ecc8ea3e65de516ff71ce1a80dac780 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:36:41 +0800 Subject: [PATCH 08/20] minor change --- lib/src/auto_fix.dart | 4 ++-- lib/src/dependency_validator.dart | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index b33969d..fb6dc4a 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -42,11 +42,11 @@ class AutoFix { return name + ':' + constraint; } - List compile() { + String compile() { return [ 'dart remove ' + _pubRemove.join(' '), 'dart pub add ' + _pubAdd.join(' '), 'dart pub add --dev ' + _pubAddDev.join(' '), - ]; + ].join(' && '); } } diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index 9b051d7..11d57b9 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -354,9 +354,9 @@ Future run() async { exitCode = 1; } - final autoFixCommands = autoFix.compile(); - if (autoFixCommands.isNotEmpty) { - logger.info('Suggestion for auto fix: ${autoFixCommands.join(" && ")}'); + final autoFixCommand = autoFix.compile(); + if (autoFixCommand.isNotEmpty) { + logger.info('Suggestion for auto fix: ${autoFixCommand}'); } if (exitCode == 0) { From 5bb4815fbf44d90c22b31b165538c0a23f476c99 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:41:01 +0800 Subject: [PATCH 09/20] auto execute autofix commands --- bin/dependency_validator.dart | 14 +++++++++++--- lib/src/dependency_validator.dart | 12 +++++++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/bin/dependency_validator.dart b/bin/dependency_validator.dart index de3bdea..75a78ef 100644 --- a/bin/dependency_validator.dart +++ b/bin/dependency_validator.dart @@ -18,7 +18,10 @@ import 'package:args/args.dart'; import 'package:dependency_validator/src/dependency_validator.dart'; import 'package:io/io.dart'; import 'package:logging/logging.dart'; +import 'package:test/test.dart'; +const String pathArg = 'path'; +const String autoFixArg = 'auto-fix'; const String helpArg = 'help'; const String verboseArg = 'verbose'; const String helpMessage = @@ -37,10 +40,15 @@ usage:'''; /// Parses the command-line arguments final ArgParser argParser = ArgParser() ..addOption( - 'path', + pathArg, abbr: 'p', help: 'Specify package path', ) + ..addFlag( + autoFixArg, + abbr: 'a', + help: 'Auto fix issues', + ) ..addFlag( helpArg, abbr: 'h', @@ -83,10 +91,10 @@ void main(List args) async { Logger.root.level = Level.ALL; } - final path = argResults['path'] as String?; + final path = argResults[pathArg] as String?; if (path != null) { Directory.current = path; } - await run(); + await run(shouldAutoFix: argResults[autoFixArg]); } diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index 11d57b9..5d33a63 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -28,7 +28,7 @@ import 'pubspec_config.dart'; import 'utils.dart'; /// Check for missing, under-promoted, over-promoted, and unused dependencies. -Future run() async { +Future run({required bool shouldAutoFix}) async { if (!File('pubspec.yaml').existsSync()) { logger.shout(red.wrap('pubspec.yaml not found')); exit(1); @@ -357,6 +357,16 @@ Future run() async { final autoFixCommand = autoFix.compile(); if (autoFixCommand.isNotEmpty) { logger.info('Suggestion for auto fix: ${autoFixCommand}'); + + if (shouldAutoFix) { + logger.info('Start autofix...'); + final process = await Process.start(autoFixCommand, [], runInShell: true); + process.stdout.pipe(stdout); + process.stderr.pipe(stderr); + final exitCode = await process.exitCode; + if (exitCode != 0) throw Exception('process exit with exitCode=$exitCode'); + logger.info('End autofix.'); + } } if (exitCode == 0) { From 9c8cb6295ce0a459b0c8131050810fa758202854 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:42:00 +0800 Subject: [PATCH 10/20] fix process.start --- lib/src/dependency_validator.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index 5d33a63..f31cdef 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -360,7 +360,7 @@ Future run({required bool shouldAutoFix}) async { if (shouldAutoFix) { logger.info('Start autofix...'); - final process = await Process.start(autoFixCommand, [], runInShell: true); + final process = await Process.start('/bin/sh', ['-c', autoFixCommand]); process.stdout.pipe(stdout); process.stderr.pipe(stderr); final exitCode = await process.exitCode; From b66af4055e422222d0edc26cc232c22b01ee8252 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:42:10 +0800 Subject: [PATCH 11/20] fix wrong command --- lib/src/auto_fix.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index fb6dc4a..82b724d 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -44,7 +44,7 @@ class AutoFix { String compile() { return [ - 'dart remove ' + _pubRemove.join(' '), + 'dart pub remove ' + _pubRemove.join(' '), 'dart pub add ' + _pubAdd.join(' '), 'dart pub add --dev ' + _pubAddDev.join(' '), ].join(' && '); From c829d20753b9c7e0d450495d68c8117eaad19069 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:43:54 +0800 Subject: [PATCH 12/20] let shell be more strict --- lib/src/dependency_validator.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index f31cdef..6129c54 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -360,7 +360,7 @@ Future run({required bool shouldAutoFix}) async { if (shouldAutoFix) { logger.info('Start autofix...'); - final process = await Process.start('/bin/sh', ['-c', autoFixCommand]); + final process = await Process.start('/bin/sh', ['-euxc', autoFixCommand]); process.stdout.pipe(stdout); process.stderr.pipe(stderr); final exitCode = await process.exitCode; From 95d3a830d9dfe2db24057e48695fcbac6a16473b Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:48:49 +0800 Subject: [PATCH 13/20] fix error when empty --- lib/src/auto_fix.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index 82b724d..a3bf840 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -44,9 +44,9 @@ class AutoFix { String compile() { return [ - 'dart pub remove ' + _pubRemove.join(' '), - 'dart pub add ' + _pubAdd.join(' '), - 'dart pub add --dev ' + _pubAddDev.join(' '), + if (_pubRemove.isNotEmpty) 'dart pub remove ' + _pubRemove.join(' '), + if (_pubAdd.isNotEmpty) 'dart pub add ' + _pubAdd.join(' '), + if (_pubAddDev.isNotEmpty) 'dart pub add --dev ' + _pubAddDev.join(' '), ].join(' && '); } } From 3dacd203d05694b26afbed33fd42e565c511ff3a Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:52:04 +0800 Subject: [PATCH 14/20] add logs --- lib/src/auto_fix.dart | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index a3bf840..44ce4ac 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -1,3 +1,4 @@ +import 'package:dependency_validator/src/utils.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; class AutoFix { @@ -37,9 +38,19 @@ class AutoFix { String? _parseConstraint(String name) { final dependency = pubspec.dependencies[name] ?? pubspec.devDependencies[name]; - if (dependency == null || dependency is! HostedDependency) return null; - final constraint = dependency.version.toString(); - return name + ':' + constraint; + if (dependency == null) { + logger.warning('parseConstraint cannot find dependency name=$name'); + return null; + } + + if (dependency is HostedDependency) { + final constraint = dependency.version.toString(); + return name + ':' + constraint; + } + + logger.warning('parseConstraint do not know type of dependency ' + 'name=$name dependency=$dependency type=${dependency.runtimeType}'); + return null; } String compile() { From 4f3c5e82aaab47c10d3046d749e8f150ff7a9503 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 19:56:54 +0800 Subject: [PATCH 15/20] handle more types of dependencies --- lib/src/auto_fix.dart | 101 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 19 deletions(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index 44ce4ac..a592912 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -4,60 +4,123 @@ import 'package:pubspec_parse/pubspec_parse.dart'; class AutoFix { final Pubspec pubspec; - final _pubAdd = []; - final _pubAddDev = []; - final _pubRemove = []; + final _pubRemoveNames = []; + final _pubAdds = []; AutoFix(this.pubspec); void handleMissingDependencies(Set deps) { - _pubAdd.addAll(deps); + _pubAdds.addAll(deps.map((dep) => PubAddCommand(packageAndConstraints: [dep], dev: false))); } void handleMissingDevDependencies(Set deps) { - _pubAddDev.addAll(deps); + _pubAdds.addAll(deps.map((dep) => PubAddCommand(packageAndConstraints: [dep], dev: true))); } void handleOverPromotedDependencies(Set deps) { - _pubRemove.addAll(deps); - _pubAddDev.addAll(_parseDepsWithConstraints(deps)); + _pubRemoveNames.addAll(deps); + _pubAdds.addAll(_parsePubAddListByPubspec(deps, dev: true)); } void handleUnderPromotedDependencies(Set deps) { - _pubRemove.addAll(deps); - _pubAdd.addAll(_parseDepsWithConstraints(deps)); + _pubRemoveNames.addAll(deps); + _pubAdds.addAll(_parsePubAddListByPubspec(deps, dev: false)); } void handleUnusedDependencies(Set deps) { - _pubRemove.addAll(deps); + _pubRemoveNames.addAll(deps); } - List _parseDepsWithConstraints(Set deps) { - return deps.map((dep) => _parseConstraint(dep)).where((e) => e != null).map((e) => e!).toList(); + List _parsePubAddListByPubspec(Set deps, {required bool dev}) { + return deps.map((dep) => _parsePubAddByPubspec(dep, dev: dev)).where((e) => e != null).map((e) => e!).toList(); } - String? _parseConstraint(String name) { + PubAddCommand? _parsePubAddByPubspec(String name, {required bool dev}) { final dependency = pubspec.dependencies[name] ?? pubspec.devDependencies[name]; if (dependency == null) { - logger.warning('parseConstraint cannot find dependency name=$name'); + logger.warning('WARN: cannot find dependency name=$name'); return null; } if (dependency is HostedDependency) { final constraint = dependency.version.toString(); - return name + ':' + constraint; + return PubAddCommand(packageAndConstraints: ['$name:$constraint'], dev: dev); } - logger.warning('parseConstraint do not know type of dependency ' + if (dependency is PathDependency) { + return PubAddCommand( + packageAndConstraints: [name], + dev: dev, + extraArgs: '--path ${dependency.path}', + ); + } + + if (dependency is GitDependency) { + return PubAddCommand( + packageAndConstraints: [name], + dev: dev, + extraArgs: '--git-url ${dependency.url} --git-ref ${dependency.ref} --git-path ${dependency.path}', + ); + } + + logger.warning('WARN: do not know type of dependency ' 'name=$name dependency=$dependency type=${dependency.runtimeType}'); return null; } String compile() { + final mergedPubAdds = PubAddCommand.merge(_pubAdds); return [ - if (_pubRemove.isNotEmpty) 'dart pub remove ' + _pubRemove.join(' '), - if (_pubAdd.isNotEmpty) 'dart pub add ' + _pubAdd.join(' '), - if (_pubAddDev.isNotEmpty) 'dart pub add --dev ' + _pubAddDev.join(' '), + if (_pubRemoveNames.isNotEmpty) 'dart pub remove ' + _pubRemoveNames.join(' '), + ...mergedPubAdds.map((e) => e.compile()), ].join(' && '); } } + +class PubAddCommand { + final bool dev; + final List packageAndConstraints; + final String? extraArgs; + + PubAddCommand({ + required this.packageAndConstraints, + required this.dev, + this.extraArgs, + }); + + String compile() { + var ans = 'dart pub add '; + if (dev) ans += '--dev '; + ans += packageAndConstraints.join(' ') + ' '; + ans += extraArgs ?? ''; + return ans; + } + + static List merge(List commands) { + final simpleAdd = []; + final simpleAddDev = []; + final others = []; + + for (final command in commands) { + if (command.extraArgs == null) { + (command.dev ? simpleAddDev : simpleAdd).add(command); + } else { + others.add(command); + } + } + + return [ + if (simpleAdd.isNotEmpty) + PubAddCommand( + packageAndConstraints: simpleAdd.expand((c) => c.packageAndConstraints).toList(), + dev: false, + ), + if (simpleAddDev.isNotEmpty) + PubAddCommand( + packageAndConstraints: simpleAddDev.expand((c) => c.packageAndConstraints).toList(), + dev: true, + ), + ...others, + ]; + } +} From c0afd1f44769191da3d8a0170849ed5d9300fd44 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 20:06:15 +0800 Subject: [PATCH 16/20] fix null --- lib/src/auto_fix.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index a592912..478e045 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -56,10 +56,14 @@ class AutoFix { } if (dependency is GitDependency) { + var extraArgs = '--git-url ${dependency.url} '; + if (dependency.ref != null) extraArgs += '--git-ref ${dependency.ref} '; + if (dependency.path != null) extraArgs += '--git-path ${dependency.path} '; + return PubAddCommand( packageAndConstraints: [name], dev: dev, - extraArgs: '--git-url ${dependency.url} --git-ref ${dependency.ref} --git-path ${dependency.path}', + extraArgs: extraArgs, ); } From 733a7052ac92a11e0a1fe742c12b06296c6b482f Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 20:12:42 +0800 Subject: [PATCH 17/20] set exitcode to zero if have fixed --- lib/src/dependency_validator.dart | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index 6129c54..f528bb0 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -357,16 +357,18 @@ Future run({required bool shouldAutoFix}) async { final autoFixCommand = autoFix.compile(); if (autoFixCommand.isNotEmpty) { logger.info('Suggestion for auto fix: ${autoFixCommand}'); + } - if (shouldAutoFix) { - logger.info('Start autofix...'); - final process = await Process.start('/bin/sh', ['-euxc', autoFixCommand]); - process.stdout.pipe(stdout); - process.stderr.pipe(stderr); - final exitCode = await process.exitCode; - if (exitCode != 0) throw Exception('process exit with exitCode=$exitCode'); - logger.info('End autofix.'); - } + if (shouldAutoFix && autoFixCommand.isNotEmpty) { + logger.info('Start autofix...'); + final process = await Process.start('/bin/sh', ['-euxc', autoFixCommand]); + process.stdout.pipe(stdout); + process.stderr.pipe(stderr); + final processExitCode = await process.exitCode; + if (processExitCode != 0) throw Exception('process exit with exitCode=$processExitCode'); + logger.info('End autofix.'); + + exitCode = 0; } if (exitCode == 0) { From 13f65ee5beab4a5ad93498835bbee7af0933db9d Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 20:31:08 +0800 Subject: [PATCH 18/20] allow run next command even previous fail --- lib/src/auto_fix.dart | 2 +- lib/src/dependency_validator.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index 478e045..28c9610 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -77,7 +77,7 @@ class AutoFix { return [ if (_pubRemoveNames.isNotEmpty) 'dart pub remove ' + _pubRemoveNames.join(' '), ...mergedPubAdds.map((e) => e.compile()), - ].join(' && '); + ].join('; '); } } diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index f528bb0..fd2ac2a 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -361,7 +361,7 @@ Future run({required bool shouldAutoFix}) async { if (shouldAutoFix && autoFixCommand.isNotEmpty) { logger.info('Start autofix...'); - final process = await Process.start('/bin/sh', ['-euxc', autoFixCommand]); + final process = await Process.start('/bin/sh', ['-xc', autoFixCommand]); process.stdout.pipe(stdout); process.stderr.pipe(stderr); final processExitCode = await process.exitCode; From 5193f2beb7bea360d5b220b18a5603a1e3751346 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 20:34:28 +0800 Subject: [PATCH 19/20] remove merging, such that things are independent --- lib/src/auto_fix.dart | 62 +++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/lib/src/auto_fix.dart b/lib/src/auto_fix.dart index 28c9610..64e73d5 100644 --- a/lib/src/auto_fix.dart +++ b/lib/src/auto_fix.dart @@ -10,11 +10,11 @@ class AutoFix { AutoFix(this.pubspec); void handleMissingDependencies(Set deps) { - _pubAdds.addAll(deps.map((dep) => PubAddCommand(packageAndConstraints: [dep], dev: false))); + _pubAdds.add(PubAddCommand(packageAndConstraints: deps.toList(), dev: false)); } void handleMissingDevDependencies(Set deps) { - _pubAdds.addAll(deps.map((dep) => PubAddCommand(packageAndConstraints: [dep], dev: true))); + _pubAdds.add(PubAddCommand(packageAndConstraints: deps.toList(), dev: true)); } void handleOverPromotedDependencies(Set deps) { @@ -73,10 +73,10 @@ class AutoFix { } String compile() { - final mergedPubAdds = PubAddCommand.merge(_pubAdds); + // final mergedPubAdds = PubAddCommand.merge(_pubAdds); return [ if (_pubRemoveNames.isNotEmpty) 'dart pub remove ' + _pubRemoveNames.join(' '), - ...mergedPubAdds.map((e) => e.compile()), + ..._pubAdds.map((e) => e.compile()), ].join('; '); } } @@ -100,31 +100,31 @@ class PubAddCommand { return ans; } - static List merge(List commands) { - final simpleAdd = []; - final simpleAddDev = []; - final others = []; - - for (final command in commands) { - if (command.extraArgs == null) { - (command.dev ? simpleAddDev : simpleAdd).add(command); - } else { - others.add(command); - } - } - - return [ - if (simpleAdd.isNotEmpty) - PubAddCommand( - packageAndConstraints: simpleAdd.expand((c) => c.packageAndConstraints).toList(), - dev: false, - ), - if (simpleAddDev.isNotEmpty) - PubAddCommand( - packageAndConstraints: simpleAddDev.expand((c) => c.packageAndConstraints).toList(), - dev: true, - ), - ...others, - ]; - } + // static List merge(List commands) { + // final simpleAdd = []; + // final simpleAddDev = []; + // final others = []; + // + // for (final command in commands) { + // if (command.extraArgs == null) { + // (command.dev ? simpleAddDev : simpleAdd).add(command); + // } else { + // others.add(command); + // } + // } + // + // return [ + // if (simpleAdd.isNotEmpty) + // PubAddCommand( + // packageAndConstraints: simpleAdd.expand((c) => c.packageAndConstraints).toList(), + // dev: false, + // ), + // if (simpleAddDev.isNotEmpty) + // PubAddCommand( + // packageAndConstraints: simpleAddDev.expand((c) => c.packageAndConstraints).toList(), + // dev: true, + // ), + // ...others, + // ]; + // } } From a093b1403e61bf61842cee17cff366871a4336cd Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 26 May 2022 20:44:25 +0800 Subject: [PATCH 20/20] remove unused imports --- bin/dependency_validator.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/dependency_validator.dart b/bin/dependency_validator.dart index 75a78ef..b6e92fe 100644 --- a/bin/dependency_validator.dart +++ b/bin/dependency_validator.dart @@ -18,7 +18,6 @@ import 'package:args/args.dart'; import 'package:dependency_validator/src/dependency_validator.dart'; import 'package:io/io.dart'; import 'package:logging/logging.dart'; -import 'package:test/test.dart'; const String pathArg = 'path'; const String autoFixArg = 'auto-fix';