diff --git a/bin/dependency_validator.dart b/bin/dependency_validator.dart index 7a7bf46..643658c 100644 --- a/bin/dependency_validator.dart +++ b/bin/dependency_validator.dart @@ -36,20 +36,19 @@ example: usage:'''; /// Parses the command-line arguments -final ArgParser argParser = - ArgParser() - ..addFlag(helpArg, abbr: 'h', help: 'Displays this info.') - ..addFlag( - verboseArg, - defaultsTo: false, - help: 'Display extra information for debugging.', - ) - ..addOption( - rootDirArg, - abbr: "C", - help: 'Validate dependencies in a subdirectory', - defaultsTo: '.', - ); +final ArgParser argParser = ArgParser() + ..addFlag(helpArg, abbr: 'h', help: 'Displays this info.') + ..addFlag( + verboseArg, + defaultsTo: false, + help: 'Display extra information for debugging.', + ) + ..addOption( + rootDirArg, + abbr: "C", + help: 'Validate dependencies in a subdirectory', + defaultsTo: '.', + ); void showHelpAndExit({ExitCode exitCode = ExitCode.success}) { Logger.root.shout(helpMessage); diff --git a/lib/src/constants.dart b/lib/src/constants.dart index 17274a6..a7e7d29 100644 --- a/lib/src/constants.dart +++ b/lib/src/constants.dart @@ -53,8 +53,8 @@ class DependencyPinEvaluation { /// possible prerelease. static const DependencyPinEvaluation buildOrPrerelease = DependencyPinEvaluation._( - 'Builds or preleases as max bounds block minor bumps and patches.', - ); + 'Builds or preleases as max bounds block minor bumps and patches.', + ); /// 1.2.3 static const DependencyPinEvaluation directPin = DependencyPinEvaluation._( diff --git a/lib/src/dependency_validator.dart b/lib/src/dependency_validator.dart index 4fe5ed1..7eb7d9e 100644 --- a/lib/src/dependency_validator.dart +++ b/lib/src/dependency_validator.dart @@ -54,18 +54,17 @@ Future checkPackage({required String root}) async { config = pubspecConfig.dependencyValidator; } - final excludes = - config.exclude - .map((s) { - try { - return makeGlob("$root/$s"); - } catch (_, __) { - logger.shout(yellow.wrap('invalid glob syntax: "$s"')); - return null; - } - }) - .nonNulls - .toList(); + final excludes = config.exclude + .map((s) { + try { + return makeGlob("$root/$s"); + } catch (_, __) { + logger.shout(yellow.wrap('invalid glob syntax: "$s"')); + return null; + } + }) + .nonNulls + .toList(); logger.fine('excludes:\n${bulletItems(excludes.map((g) => g.pattern))}\n'); final ignoredPackages = config.ignore; logger.fine('ignored packages:\n${bulletItems(ignoredPackages)}\n'); @@ -268,13 +267,13 @@ Future checkPackage({required String root}) async { // Packages that are not used in lib/, but are used elsewhere, that are // dependencies when they should be dev_dependencies. final overPromotedDependencies = - // Start with dependencies that are not used in lib/ - (deps - .difference(packagesUsedInPublicFiles) - // Intersect with deps that are used outside lib/ (excludes unused deps) - .intersection(packagesUsedOutsidePublicDirs)) - // Ignore known over-promoted packages. - ..removeAll(ignoredPackages); + // Start with dependencies that are not used in lib/ + (deps + .difference(packagesUsedInPublicFiles) + // Intersect with deps that are used outside lib/ (excludes unused deps) + .intersection(packagesUsedOutsidePublicDirs)) + // Ignore known over-promoted packages. + ..removeAll(ignoredPackages); if (overPromotedDependencies.isNotEmpty) { log( @@ -287,10 +286,10 @@ Future checkPackage({required String root}) async { // Packages that are used in lib/, but are dev_dependencies. final underPromotedDependencies = - // Start with dev_dependencies that are used in lib/ - devDeps.intersection(packagesUsedInPublicFiles) - // Ignore known under-promoted packages - ..removeAll(ignoredPackages); + // Start with dev_dependencies that are used in lib/ + devDeps.intersection(packagesUsedInPublicFiles) + // Ignore known under-promoted packages + ..removeAll(ignoredPackages); if (underPromotedDependencies.isNotEmpty) { log( @@ -334,8 +333,8 @@ Future checkPackage({required String root}) async { for (final target in rootBuildConfig.buildTargets.values) ...target.builders.keys, ] - .map((key) => normalizeBuilderKeyUsage(key, pubspec.name)) - .any((key) => key.startsWith('$dependencyName:')); + .map((key) => normalizeBuilderKeyUsage(key, pubspec.name)) + .any((key) => key.startsWith('$dependencyName:')); final packagesWithConsumedBuilders = Set(); for (final name in unusedDependencies) { @@ -420,7 +419,10 @@ Future checkPackage({required String root}) async { Future dependencyDefinesAutoAppliedBuilder(String path) async => (await BuildConfig.fromPackageDir( path, - )).builderDefinitions.values.any((def) => def.autoApply != AutoApply.none); + )) + .builderDefinitions + .values + .any((def) => def.autoApply != AutoApply.none); /// Checks for dependency pins. /// diff --git a/lib/src/pubspec_config.dart b/lib/src/pubspec_config.dart index 470fb1c..c9400a4 100644 --- a/lib/src/pubspec_config.dart +++ b/lib/src/pubspec_config.dart @@ -17,7 +17,7 @@ class PubspecDepValidatorConfig { dependencyValidator.ignore.isNotEmpty; PubspecDepValidatorConfig({DepValidatorConfig? dependencyValidator}) - : dependencyValidator = dependencyValidator ?? DepValidatorConfig(); + : dependencyValidator = dependencyValidator ?? DepValidatorConfig(); factory PubspecDepValidatorConfig.fromJson(Map json) => _$PubspecDepValidatorConfigFromJson(json); diff --git a/test/pubspec_to_json.dart b/test/pubspec_to_json.dart index 3dd7316..cadcbf6 100644 --- a/test/pubspec_to_json.dart +++ b/test/pubspec_to_json.dart @@ -12,23 +12,23 @@ typedef Json = Map; extension on Dependency { Json toJson() => switch (this) { - SdkDependency(:final sdk, :final version) => { - "sdk": sdk, - "version": version.toString(), - }, - HostedDependency(:final hosted, :final version) => { - if (hosted != null) "hosted": hosted.url.toString(), - "version": version.toString(), - }, - GitDependency(:final url, :final ref, :final path) => { - "git": { - "url": url.toString(), - if (path != null) "ref": ref, - if (path != null) "path": path, - }, - }, - PathDependency(:final path) => {"path": path.replaceAll(r'\', '/')}, - }; + SdkDependency(:final sdk, :final version) => { + "sdk": sdk, + "version": version.toString(), + }, + HostedDependency(:final hosted, :final version) => { + if (hosted != null) "hosted": hosted.url.toString(), + "version": version.toString(), + }, + GitDependency(:final url, :final ref, :final path) => { + "git": { + "url": url.toString(), + if (path != null) "ref": ref, + if (path != null) "path": path, + }, + }, + PathDependency(:final path) => {"path": path.replaceAll(r'\', '/')}, + }; } /// An as-needed implementation of `Pubspec.toJson` for testing. @@ -36,20 +36,21 @@ extension on Dependency { /// See: https://github.com/dart-lang/tools/issues/1801 extension PubspecToJson on Pubspec { Json toJson() => { - "name": name, - "environment": { - for (final (sdk, version) in environment.records) sdk: version.toString(), - }, - if (resolution != null) "resolution": resolution, - if (workspace != null) "workspace": workspace, - "dependencies": { - for (final (name, dependency) in dependencies.records) - name: dependency.toJson(), - }, - "dev_dependencies": { - for (final (name, dependency) in devDependencies.records) - name: dependency.toJson(), - }, - // ... - }; + "name": name, + "environment": { + for (final (sdk, version) in environment.records) + sdk: version.toString(), + }, + if (resolution != null) "resolution": resolution, + if (workspace != null) "workspace": workspace, + "dependencies": { + for (final (name, dependency) in dependencies.records) + name: dependency.toJson(), + }, + "dev_dependencies": { + for (final (name, dependency) in devDependencies.records) + name: dependency.toJson(), + }, + // ... + }; } diff --git a/test/utils.dart b/test/utils.dart index 5fbb37f..9b23add 100644 --- a/test/utils.dart +++ b/test/utils.dart @@ -47,8 +47,8 @@ Future checkProject({ } Dependency hostedCompatibleWith(String version) => HostedDependency( - version: VersionConstraint.compatibleWith(Version.parse(version)), -); + version: VersionConstraint.compatibleWith(Version.parse(version)), + ); Dependency hostedPinned(String version) => HostedDependency(version: Version.parse(version)); diff --git a/test/workspace_test.dart b/test/workspace_test.dart index 223e245..8498d39 100644 --- a/test/workspace_test.dart +++ b/test/workspace_test.dart @@ -25,128 +25,128 @@ final dependsOnMeta = { final excludeMain = DepValidatorConfig(exclude: ['lib/main.dart']); void main() => group('Workspaces', () { - initLogs(); - test( - 'works in the trivial case', - () => checkWorkspace( - workspaceDeps: {}, - workspace: [], - subpackage: [], - subpackageDeps: {}, - ), - ); - - test( - 'works in a basic case', - () => checkWorkspace( - workspace: usesHttp, - workspaceDeps: dependsOnHttp, - subpackage: usesHttp, - subpackageDeps: dependsOnHttp, - ), - ); - - test( - 'works when the packages have different dependencies', - () => checkWorkspace( - workspace: usesHttp, - workspaceDeps: dependsOnHttp, - subpackage: usesMeta, - subpackageDeps: dependsOnMeta, - ), - ); - - group('fails when the root has an issue', () { - test( - '(sub-package is okay)', - () => checkWorkspace( - workspace: [], - workspaceDeps: {}, - subpackage: usesHttp, - subpackageDeps: dependsOnHttp, - ), - ); - - test( - 'even when it shares a dependency with the subpackage', - () => checkWorkspace( - workspaceDeps: dependsOnHttp, - workspace: [], - subpackageDeps: dependsOnHttp, - subpackage: usesHttp, - matcher: isFalse, - ), - ); - }); - - group('fails when the subpackage has an issue', () { - test( - '(root is okay)', - () => checkWorkspace( - workspace: usesHttp, - workspaceDeps: dependsOnHttp, - subpackage: [], - subpackageDeps: {}, - ), - ); - - test( - 'even when it shares a dependency with the subpackage', - () => checkWorkspace( - workspace: usesHttp, - workspaceDeps: dependsOnHttp, - subpackage: usesHttp, - subpackageDeps: {}, - matcher: isFalse, - ), - ); - }); - - group('handles configs', () { - test( - 'at the root', - () => checkWorkspace( - workspace: usesHttp, - workspaceDeps: {}, - workspaceConfig: excludeMain, - subpackage: [], - subpackageDeps: {}, - ), - ); - - test( - 'and fails at root when config is in subpackage', - () => checkWorkspace( - workspace: usesHttp, - workspaceDeps: {}, - subpackage: [], - subpackageDeps: {}, - subpackageConfig: excludeMain, - matcher: isFalse, - ), - ); - - test( - 'in a subpackage', - () => checkWorkspace( - workspace: [], - workspaceDeps: {}, - subpackage: usesHttp, - subpackageDeps: {}, - subpackageConfig: excludeMain, - ), - ); - - test( - 'and fails in subpackage when config is in root', - () => checkWorkspace( - workspace: [], - workspaceDeps: {}, - workspaceConfig: excludeMain, - subpackage: usesHttp, - subpackageDeps: {}, - matcher: isFalse, - ), - ); - }); -}); + initLogs(); + test( + 'works in the trivial case', + () => checkWorkspace( + workspaceDeps: {}, + workspace: [], + subpackage: [], + subpackageDeps: {}, + ), + ); + + test( + 'works in a basic case', + () => checkWorkspace( + workspace: usesHttp, + workspaceDeps: dependsOnHttp, + subpackage: usesHttp, + subpackageDeps: dependsOnHttp, + ), + ); + + test( + 'works when the packages have different dependencies', + () => checkWorkspace( + workspace: usesHttp, + workspaceDeps: dependsOnHttp, + subpackage: usesMeta, + subpackageDeps: dependsOnMeta, + ), + ); + + group('fails when the root has an issue', () { + test( + '(sub-package is okay)', + () => checkWorkspace( + workspace: [], + workspaceDeps: {}, + subpackage: usesHttp, + subpackageDeps: dependsOnHttp, + ), + ); + + test( + 'even when it shares a dependency with the subpackage', + () => checkWorkspace( + workspaceDeps: dependsOnHttp, + workspace: [], + subpackageDeps: dependsOnHttp, + subpackage: usesHttp, + matcher: isFalse, + ), + ); + }); + + group('fails when the subpackage has an issue', () { + test( + '(root is okay)', + () => checkWorkspace( + workspace: usesHttp, + workspaceDeps: dependsOnHttp, + subpackage: [], + subpackageDeps: {}, + ), + ); + + test( + 'even when it shares a dependency with the subpackage', + () => checkWorkspace( + workspace: usesHttp, + workspaceDeps: dependsOnHttp, + subpackage: usesHttp, + subpackageDeps: {}, + matcher: isFalse, + ), + ); + }); + + group('handles configs', () { + test( + 'at the root', + () => checkWorkspace( + workspace: usesHttp, + workspaceDeps: {}, + workspaceConfig: excludeMain, + subpackage: [], + subpackageDeps: {}, + ), + ); + + test( + 'and fails at root when config is in subpackage', + () => checkWorkspace( + workspace: usesHttp, + workspaceDeps: {}, + subpackage: [], + subpackageDeps: {}, + subpackageConfig: excludeMain, + matcher: isFalse, + ), + ); + + test( + 'in a subpackage', + () => checkWorkspace( + workspace: [], + workspaceDeps: {}, + subpackage: usesHttp, + subpackageDeps: {}, + subpackageConfig: excludeMain, + ), + ); + + test( + 'and fails in subpackage when config is in root', + () => checkWorkspace( + workspace: [], + workspaceDeps: {}, + workspaceConfig: excludeMain, + subpackage: usesHttp, + subpackageDeps: {}, + matcher: isFalse, + ), + ); + }); + });