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, ); } }