From a4f6fd02d3dae1054ace17ff21103d48b2c9bee5 Mon Sep 17 00:00:00 2001 From: devmil Date: Sun, 10 Mar 2024 21:54:18 +0100 Subject: [PATCH 1/5] introduces `override-use-flutter` argument for commands --- README.md | 5 ++- lib/src/cli/commands/command_mixin.dart | 41 ++++++++++++++++++++--- lib/src/cli/commands/diff_command.dart | 11 ++++-- lib/src/cli/commands/extract_command.dart | 3 ++ lib/src/tooling/dart_interaction.dart | 31 ++++++++++++----- lib/src/tooling/pub_interaction.dart | 2 ++ 6 files changed, 77 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index dd1a4e8..efc672d 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Usage: dart-apitool extract [arguments] --[no-]remove-example Removes examples from the package to analyze. (defaults to on) --[no-]set-exit-on-missing-export Sets exit code to != 0 if missing exports are detected in the API. + --override-use-flutter Overrides automatic decision whether to use Flutter or Dart. ``` ### diff @@ -91,10 +92,12 @@ Usage: dart-apitool diff [arguments] [none, allowAdding (default), strict] --[no-]remove-example Removes examples from the package to analyze. (defaults to on) - --[no-]ignore-requiredness Whether to ignore the required aspect of interfaces (yielding less strict version bump requirements) + --[no-]ignore-requiredness Whether to ignore the required aspect of interfaces + (yielding less strict version bump requirements) --report-format Which output format should be used [cli (default), markdown, json] --report-file-path Where to store the report file (no effect on cli option) + --override-use-flutter Overrides automatic decision whether to use Flutter or Dart. ``` ## Integration diff --git a/lib/src/cli/commands/command_mixin.dart b/lib/src/cli/commands/command_mixin.dart index 5a0ec4f..5d23ec8 100644 --- a/lib/src/cli/commands/command_mixin.dart +++ b/lib/src/cli/commands/command_mixin.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; +import 'package:args/args.dart'; import 'package:dart_apitool/api_tool.dart'; import 'package:dart_apitool/src/cli/source_item.dart'; import 'package:path/path.dart' as p; @@ -22,13 +23,33 @@ Package reference can be one of: OBSOLETE: Has no effect anymore. '''; + static final String _optionNameOverrideUserFlutter = 'override-use-flutter'; + static final String _helpTextOverrideUserFlutter = + 'Overrides automatic decision whether to use Flutter or Dart.'; + + void init(ArgParser argParser) { + argParser.addFlag( + _optionNameOverrideUserFlutter, + help: _helpTextOverrideUserFlutter, + defaultsTo: null, + negatable: false, + ); + } + /// prepares given [ref]. Depending on the type of ref this can include /// - copying the package to a temporary directory /// - running pub get /// If you use [analyze] with this result then it will take care to clean up /// everything (e.g. removing temp directory) - Future prepare(PackageRef ref) async { + Future prepare( + ArgResults argResults, + PackageRef ref, + ) async { final stdoutSession = StdoutSession(); + + final overrideUseFlutterCommand = + argResults[_optionNameOverrideUserFlutter] as bool?; + List sources = []; String? packageRelativePath; if (ref.isDirectoryPath) { @@ -72,8 +93,11 @@ OBSOLETE: Has no effect anymore. if (!sourceItem.isInCache) { await stdoutSession.writeln( 'Preparing package dependencies for local package ${sourceItem.sourceDir}'); - await PubInteraction.runPubGet(sourceItem.sourceDir, - stdoutSession: stdoutSession); + await PubInteraction.runPubGet( + sourceItem.sourceDir, + stdoutSession: stdoutSession, + overrideUseFlutterCommand: overrideUseFlutterCommand, + ); final sourcePackageConfig = File(_getPackageConfigPathForPackage(sourceItem.sourceDir)); final targetPackageConfig = @@ -106,11 +130,16 @@ OBSOLETE: Has no effect anymore. /// [doMergeBaseClasses] defines if base classes should be merged into derived ones. This allows to remove private base classes from the list of interface declarations. /// [doAnalyzePlatformConstraints] defines if the platform constraints of the package shall be analyzed. Future analyze( + ArgResults argResults, PreparedPackageRef preparedRef, { bool doAnalyzePlatformConstraints = true, bool doRemoveExample = true, }) async { final stdoutSession = StdoutSession(); + + final overrideUseFlutterCommand = + argResults[_optionNameOverrideUserFlutter] as bool?; + String? path; if (preparedRef.packageRef.isDirectoryPath) { path = preparedRef.packageRef.ref; @@ -141,7 +170,11 @@ OBSOLETE: Has no effect anymore. final packageConfig = File(_getPackageConfigPathForPackage(packagePath)); if (!packageConfig.existsSync()) { await stdoutSession.writeln('Running pub get'); - await PubInteraction.runPubGet(packagePath, stdoutSession: stdoutSession); + await PubInteraction.runPubGet( + packagePath, + stdoutSession: stdoutSession, + overrideUseFlutterCommand: overrideUseFlutterCommand, + ); } else { await stdoutSession .writeln('Omitting pub get (package config already present)'); diff --git a/lib/src/cli/commands/diff_command.dart b/lib/src/cli/commands/diff_command.dart index e874160..1b1d777 100644 --- a/lib/src/cli/commands/diff_command.dart +++ b/lib/src/cli/commands/diff_command.dart @@ -97,8 +97,10 @@ You may want to do this if you want to make sure ); argParser.addFlag( _optionNameIgnoreRequiredness, - help: - 'Whether to ignore the required aspect of interfaces (yielding less strict version bump requirements)', + help: ''' +Whether to ignore the required aspect of interfaces +(yielding less strict version bump requirements) +''', defaultsTo: false, negatable: true, ); @@ -114,6 +116,7 @@ You may want to do this if you want to make sure help: 'Where to store the report file (no effect on cli option)', mandatory: false, ); + init(argParser); } @override @@ -150,18 +153,22 @@ You may want to do this if you want to make sure argResults![_optionNameIgnoreRequiredness] as bool; final preparedOldPackageRef = await prepare( + argResults!, oldPackageRef, ); final preparedNewPackageRef = await prepare( + argResults!, newPackageRef, ); final oldPackageApi = await analyze( + argResults!, preparedOldPackageRef, doAnalyzePlatformConstraints: !noAnalyzePlatformConstraints, doRemoveExample: doRemoveExample, ); final newPackageApi = await analyze( + argResults!, preparedNewPackageRef, doAnalyzePlatformConstraints: !noAnalyzePlatformConstraints, doRemoveExample: doRemoveExample, diff --git a/lib/src/cli/commands/extract_command.dart b/lib/src/cli/commands/extract_command.dart index 62e833c..ccce9de 100644 --- a/lib/src/cli/commands/extract_command.dart +++ b/lib/src/cli/commands/extract_command.dart @@ -60,6 +60,7 @@ If not specified the extracted API will be printed to the console. defaultsTo: false, negatable: true, ); + init(argParser); } @override @@ -72,9 +73,11 @@ If not specified the extracted API will be printed to the console. argResults![_optionNameSetExitCodeOnMissingExport] as bool; final preparedPackageRef = await prepare( + argResults!, packageRef, ); final packageApi = await analyze( + argResults!, preparedPackageRef, doAnalyzePlatformConstraints: !noAnalyzePlatformConstraints, doRemoveExample: doRemoveExample, diff --git a/lib/src/tooling/dart_interaction.dart b/lib/src/tooling/dart_interaction.dart index 041c38f..268df90 100644 --- a/lib/src/tooling/dart_interaction.dart +++ b/lib/src/tooling/dart_interaction.dart @@ -11,22 +11,35 @@ import '../utils/utils.dart'; /// Helper class for interacting with Dart and Flutter abstract class DartInteraction { /// runs the dart or flutter command with the given [args]. - /// The decision which command to run is taken from the pubspeck.yaml file in + /// The decision which command to run is taken from the pubspec.yaml file in /// [forDirectory] + /// This command determines which tool to use based on the pubspcec.yaml file. + /// If [overrideUseFlutterCommand] is given then this value will be used to + /// determine which tool to use. [true] means Flutter, [false] means Dart static Future runDartOrFlutterCommand( String forDirectory, { List args = const [], StdoutSession? stdoutSession, + bool? overrideUseFlutterCommand, }) async { - final pubspecPath = path.join(forDirectory, 'pubspec.yaml'); - final pubspecExists = await File(pubspecPath).exists(); - if (!pubspecExists) { - throw RunDartError( - 'Error running pub get in $forDirectory:\nThis is not a valid dart package directory'); + bool useFlutter = false; + if (overrideUseFlutterCommand == null) { + // if no override is specified we get the information which tool to use + // from the pubspec.yaml file + final pubspecPath = path.join(forDirectory, 'pubspec.yaml'); + final pubspecExists = await File(pubspecPath).exists(); + if (!pubspecExists) { + throw RunDartError( + 'Error running pub get in $forDirectory:\nThis is not a valid dart package directory'); + } + final yamlContent = await File(pubspecPath).readAsString(); + final pubSpec = Pubspec.parse(yamlContent); + useFlutter = pubSpec.dependencies.containsKey('flutter'); + } else { + // if the decision is overridden we use the given value (overrideUseFlutterCommand == true => Flutter, == false => Dart) + useFlutter = overrideUseFlutterCommand; } - final yamlContent = await File(pubspecPath).readAsString(); - final pubSpec = Pubspec.parse(yamlContent); - if (!pubSpec.dependencies.containsKey('flutter')) { + if (!useFlutter) { return _runDartOrFlutterCommand( _getDartExecutablePath(), workingDirectory: forDirectory, diff --git a/lib/src/tooling/pub_interaction.dart b/lib/src/tooling/pub_interaction.dart index 3daa7f6..6f6f2c4 100644 --- a/lib/src/tooling/pub_interaction.dart +++ b/lib/src/tooling/pub_interaction.dart @@ -111,6 +111,7 @@ abstract class PubInteraction { static Future runPubGet( String packageDirectory, { StdoutSession? stdoutSession, + bool? overrideUseFlutterCommand, }) async { return DartInteraction.runDartOrFlutterCommand( packageDirectory, @@ -119,6 +120,7 @@ abstract class PubInteraction { 'get', ], stdoutSession: stdoutSession, + overrideUseFlutterCommand: overrideUseFlutterCommand, ); } } From 04a89c93f479f4072c046d1726dce0ce2c3db7f6 Mon Sep 17 00:00:00 2001 From: devmil Date: Sun, 10 Mar 2024 21:59:18 +0100 Subject: [PATCH 2/5] adds CHANGELOG entry and bumps major --- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 635c816..e0782da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## Version 0.19.0 +- introduces `override-use-flutter` option for all commands to override the automatic decision whether to use Flutter or Dart. + ## Version 0.18.0 - add missing export to json output for `extract` command - adds analysis of readability and writability of fields. diff --git a/pubspec.yaml b/pubspec.yaml index 41e5eb5..f75e89a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: dart_apitool description: A tool to analyze the public API of a package, create a model of it and diff it against another version to check semver. repository: https://github.com/bmw-tech/dart_apitool -version: 0.18.1-dev +version: 0.19.0-dev environment: sdk: ">=3.0.0 <4.0.0" From 27c42a6dff6f59521fd7f9e25b3eaa916dae041a Mon Sep 17 00:00:00 2001 From: devmil Date: Fri, 5 Apr 2024 10:39:38 +0200 Subject: [PATCH 3/5] fix typo and adapt flag name to be more clear --- CHANGELOG.md | 2 +- README.md | 10 ++++++++-- lib/src/cli/commands/command_mixin.dart | 24 ++++++++++++------------ lib/src/tooling/dart_interaction.dart | 12 ++++++------ lib/src/tooling/pub_interaction.dart | 4 ++-- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0782da..12e5f73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog ## Version 0.19.0 -- introduces `override-use-flutter` option for all commands to override the automatic decision whether to use Flutter or Dart. +- introduces `force-use-flutter` option for all commands to force dart_apitool to use the `flutter` command. ## Version 0.18.0 - add missing export to json output for `extract` command diff --git a/README.md b/README.md index efc672d..ee43f70 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,10 @@ Usage: dart-apitool extract [arguments] --[no-]remove-example Removes examples from the package to analyze. (defaults to on) --[no-]set-exit-on-missing-export Sets exit code to != 0 if missing exports are detected in the API. - --override-use-flutter Overrides automatic decision whether to use Flutter or Dart. + --force-use-flutter If present forces dart_apitool to use Flutter + (instead of Dart if the project is Dart only) + +Run "dart-apitool help" to see global options. ``` ### diff @@ -97,7 +100,10 @@ Usage: dart-apitool diff [arguments] --report-format Which output format should be used [cli (default), markdown, json] --report-file-path Where to store the report file (no effect on cli option) - --override-use-flutter Overrides automatic decision whether to use Flutter or Dart. + --force-use-flutter If present forces dart_apitool to use Flutter + (instead of Dart if the project is Dart only) + +Run "dart-apitool help" to see global options. ``` ## Integration diff --git a/lib/src/cli/commands/command_mixin.dart b/lib/src/cli/commands/command_mixin.dart index 5d23ec8..92c4dbc 100644 --- a/lib/src/cli/commands/command_mixin.dart +++ b/lib/src/cli/commands/command_mixin.dart @@ -23,15 +23,15 @@ Package reference can be one of: OBSOLETE: Has no effect anymore. '''; - static final String _optionNameOverrideUserFlutter = 'override-use-flutter'; - static final String _helpTextOverrideUserFlutter = - 'Overrides automatic decision whether to use Flutter or Dart.'; + static final String _flagNameForceUseFlutter = 'force-use-flutter'; + static final String _helpTextForceUseFlutter = + 'If present forces dart_apitool to use Flutter\n(instead of Dart if the project is Dart only)'; void init(ArgParser argParser) { argParser.addFlag( - _optionNameOverrideUserFlutter, - help: _helpTextOverrideUserFlutter, - defaultsTo: null, + _flagNameForceUseFlutter, + help: _helpTextForceUseFlutter, + defaultsTo: false, negatable: false, ); } @@ -47,8 +47,8 @@ OBSOLETE: Has no effect anymore. ) async { final stdoutSession = StdoutSession(); - final overrideUseFlutterCommand = - argResults[_optionNameOverrideUserFlutter] as bool?; + final forceUseFlutterTool = + (argResults[_flagNameForceUseFlutter] as bool?) ?? false; List sources = []; String? packageRelativePath; @@ -96,7 +96,7 @@ OBSOLETE: Has no effect anymore. await PubInteraction.runPubGet( sourceItem.sourceDir, stdoutSession: stdoutSession, - overrideUseFlutterCommand: overrideUseFlutterCommand, + forceUseFlutterTool: forceUseFlutterTool, ); final sourcePackageConfig = File(_getPackageConfigPathForPackage(sourceItem.sourceDir)); @@ -137,8 +137,8 @@ OBSOLETE: Has no effect anymore. }) async { final stdoutSession = StdoutSession(); - final overrideUseFlutterCommand = - argResults[_optionNameOverrideUserFlutter] as bool?; + final forceUseFlutterTool = + (argResults[_flagNameForceUseFlutter] as bool?) ?? false; String? path; if (preparedRef.packageRef.isDirectoryPath) { @@ -173,7 +173,7 @@ OBSOLETE: Has no effect anymore. await PubInteraction.runPubGet( packagePath, stdoutSession: stdoutSession, - overrideUseFlutterCommand: overrideUseFlutterCommand, + forceUseFlutterTool: forceUseFlutterTool, ); } else { await stdoutSession diff --git a/lib/src/tooling/dart_interaction.dart b/lib/src/tooling/dart_interaction.dart index 268df90..803e651 100644 --- a/lib/src/tooling/dart_interaction.dart +++ b/lib/src/tooling/dart_interaction.dart @@ -14,17 +14,17 @@ abstract class DartInteraction { /// The decision which command to run is taken from the pubspec.yaml file in /// [forDirectory] /// This command determines which tool to use based on the pubspcec.yaml file. - /// If [overrideUseFlutterCommand] is given then this value will be used to + /// If [forceUseFlutterTool] is given then this value will be used to /// determine which tool to use. [true] means Flutter, [false] means Dart static Future runDartOrFlutterCommand( String forDirectory, { List args = const [], StdoutSession? stdoutSession, - bool? overrideUseFlutterCommand, + bool forceUseFlutterTool = false, }) async { bool useFlutter = false; - if (overrideUseFlutterCommand == null) { - // if no override is specified we get the information which tool to use + if (!forceUseFlutterTool) { + // if we are not forced to use Flutter then we get this information // from the pubspec.yaml file final pubspecPath = path.join(forDirectory, 'pubspec.yaml'); final pubspecExists = await File(pubspecPath).exists(); @@ -36,8 +36,8 @@ abstract class DartInteraction { final pubSpec = Pubspec.parse(yamlContent); useFlutter = pubSpec.dependencies.containsKey('flutter'); } else { - // if the decision is overridden we use the given value (overrideUseFlutterCommand == true => Flutter, == false => Dart) - useFlutter = overrideUseFlutterCommand; + // here we are forced to use Flutter (forceUseFlutterTool == true) + useFlutter = true; } if (!useFlutter) { return _runDartOrFlutterCommand( diff --git a/lib/src/tooling/pub_interaction.dart b/lib/src/tooling/pub_interaction.dart index 6f6f2c4..935b6ea 100644 --- a/lib/src/tooling/pub_interaction.dart +++ b/lib/src/tooling/pub_interaction.dart @@ -111,7 +111,7 @@ abstract class PubInteraction { static Future runPubGet( String packageDirectory, { StdoutSession? stdoutSession, - bool? overrideUseFlutterCommand, + bool forceUseFlutterTool = false, }) async { return DartInteraction.runDartOrFlutterCommand( packageDirectory, @@ -120,7 +120,7 @@ abstract class PubInteraction { 'get', ], stdoutSession: stdoutSession, - overrideUseFlutterCommand: overrideUseFlutterCommand, + forceUseFlutterTool: forceUseFlutterTool, ); } } From 982a48c2e3eab87b35d92830d961f66a0487d57c Mon Sep 17 00:00:00 2001 From: devmil Date: Fri, 5 Apr 2024 10:48:53 +0200 Subject: [PATCH 4/5] add console output if Flutter is forced --- lib/src/cli/commands/command_mixin.dart | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/src/cli/commands/command_mixin.dart b/lib/src/cli/commands/command_mixin.dart index 92c4dbc..1afa88b 100644 --- a/lib/src/cli/commands/command_mixin.dart +++ b/lib/src/cli/commands/command_mixin.dart @@ -53,7 +53,11 @@ OBSOLETE: Has no effect anymore. List sources = []; String? packageRelativePath; if (ref.isDirectoryPath) { - await stdoutSession.writeln('Preparing ${ref.ref}'); + String forceUseFlutterSuffix = ''; + if (forceUseFlutterTool) { + forceUseFlutterSuffix = ' (forced Flutter)'; + } + await stdoutSession.writeln('Preparing ${ref.ref}$forceUseFlutterSuffix'); String sourceDir = ref.ref; if (sourceDir.endsWith(p.separator)) { sourceDir = @@ -91,8 +95,13 @@ OBSOLETE: Has no effect anymore. await _copyPath(sourceItem.sourceDir, sourceItem.destinationPath(forPrefix: tempDir.path)); if (!sourceItem.isInCache) { + String forceUseFlutterSuffix = ''; + if (forceUseFlutterTool) { + forceUseFlutterSuffix = ' (forced Flutter)'; + } + await stdoutSession.writeln( - 'Preparing package dependencies for local package ${sourceItem.sourceDir}'); + 'Preparing package dependencies for local package ${sourceItem.sourceDir}$forceUseFlutterSuffix'); await PubInteraction.runPubGet( sourceItem.sourceDir, stdoutSession: stdoutSession, From 28549568b6dc4ac1af43eee15820ed7c46e0715d Mon Sep 17 00:00:00 2001 From: devmil Date: Fri, 5 Apr 2024 11:01:17 +0200 Subject: [PATCH 5/5] fix typo --- lib/src/tooling/dart_interaction.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/tooling/dart_interaction.dart b/lib/src/tooling/dart_interaction.dart index 803e651..38d5ba2 100644 --- a/lib/src/tooling/dart_interaction.dart +++ b/lib/src/tooling/dart_interaction.dart @@ -13,7 +13,7 @@ abstract class DartInteraction { /// runs the dart or flutter command with the given [args]. /// The decision which command to run is taken from the pubspec.yaml file in /// [forDirectory] - /// This command determines which tool to use based on the pubspcec.yaml file. + /// This command determines which tool to use based on the pubspec.yaml file. /// If [forceUseFlutterTool] is given then this value will be used to /// determine which tool to use. [true] means Flutter, [false] means Dart static Future runDartOrFlutterCommand(