From 3533029347ef08046f3fa5ea8089258bf3a34301 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Sat, 4 Feb 2023 20:21:22 +0100 Subject: [PATCH 1/2] feat!: make naming around package filters more consistent --- .github/workflows/validate.yaml | 2 +- docs/commands/run.mdx | 9 +- docs/configuration/overview.mdx | 5 + docs/configuration/scripts.mdx | 15 +- docs/guides/migrations.mdx | 28 ++++ melos.yaml | 6 +- packages/melos/lib/melos.dart | 4 +- .../melos/lib/src/command_runner/base.dart | 4 +- .../lib/src/command_runner/bootstrap.dart | 2 +- .../melos/lib/src/command_runner/clean.dart | 2 +- .../melos/lib/src/command_runner/exec.dart | 4 +- .../melos/lib/src/command_runner/list.dart | 2 +- .../melos/lib/src/command_runner/publish.dart | 4 +- .../melos/lib/src/command_runner/run.dart | 2 +- .../melos/lib/src/command_runner/script.dart | 2 +- .../melos/lib/src/command_runner/version.dart | 4 +- .../melos/lib/src/commands/bootstrap.dart | 8 +- packages/melos/lib/src/commands/clean.dart | 8 +- packages/melos/lib/src/commands/exec.dart | 5 +- packages/melos/lib/src/commands/list.dart | 5 +- packages/melos/lib/src/commands/publish.dart | 5 +- packages/melos/lib/src/commands/run.dart | 12 +- packages/melos/lib/src/commands/runner.dart | 8 +- packages/melos/lib/src/commands/version.dart | 12 +- packages/melos/lib/src/common/utils.dart | 18 +++ packages/melos/lib/src/common/validation.dart | 3 +- packages/melos/lib/src/package.dart | 143 ++++++++++-------- packages/melos/lib/src/scripts.dart | 28 ++-- packages/melos/lib/src/workspace.dart | 4 +- packages/melos/lib/src/workspace_configs.dart | 22 +-- packages/melos/test/commands/exec_test.dart | 6 +- packages/melos/test/commands/list_test.dart | 2 +- packages/melos/test/commands/run_test.dart | 2 +- packages/melos/test/package_filter_test.dart | 6 +- packages/melos/test/package_test.dart | 60 ++++---- .../melos/test/workspace_config_test.dart | 2 +- packages/melos/test/workspace_test.dart | 16 +- 37 files changed, 276 insertions(+), 194 deletions(-) diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index 9ba25a3c..0b386440 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -47,7 +47,7 @@ jobs: - name: Install Tools run: ./.github/workflows/scripts/install-tools.sh - name: Check formatting - run: melos format-check + run: melos format:check test_linux: runs-on: ubuntu-latest diff --git a/docs/commands/run.mdx b/docs/commands/run.mdx index 8fe0c779..404ca77f 100644 --- a/docs/commands/run.mdx +++ b/docs/commands/run.mdx @@ -1,11 +1,12 @@ --- title: Run Command -description: "Learn more about the `run` command in Melos." +description: 'Learn more about the `run` command in Melos.' --- # Run Command -Run a [script](/configuration/scripts) by name defined in the workspace `melos.yaml` config file. +Run a [script](/configuration/scripts) by name defined in the workspace +`melos.yaml` config file. ```bash melos run @@ -13,7 +14,9 @@ melos run ## --no-select -Skips the prompt to select a package (if defined in the script configuration). Filters defined in the scripts "select-package" options will however still be applied. +Skips the prompt to select a package (if defined in the script configuration). +Filters defined in the script's "packageFilters" options will however still be +applied. ```bash melos run --no-select diff --git a/docs/configuration/overview.mdx b/docs/configuration/overview.mdx index 84a4ea72..1d542fe2 100644 --- a/docs/configuration/overview.mdx +++ b/docs/configuration/overview.mdx @@ -303,6 +303,11 @@ Package filters to match packages that should be included in the changelog. See [Filtering Packages](/filters) for all available filters. + + The filter names in `packageFilters` are camel cased. For example, for the + equivalent of the command line option `--file-exists` use `fileExists`. + + ### `command/version/changelogs/description` > optional diff --git a/docs/configuration/scripts.mdx b/docs/configuration/scripts.mdx index bb85cf9a..0fa26e10 100644 --- a/docs/configuration/scripts.mdx +++ b/docs/configuration/scripts.mdx @@ -79,7 +79,7 @@ scripts: concurrency: 1 ``` -See the [`select-package`](/configuration/scripts#scriptsselect-package) option +See the [`packageFilters`](/configuration/scripts#scriptspackagefilter) option for filtering the packages to execute the command in. ## `scripts/*/exec/concurrency` @@ -104,11 +104,11 @@ depend on each other. Defaults to `false`. A map of environment variables that will be passed to the executed command. -## `scripts/*/select-package` +## `scripts/*/packageFilters` The [`melos exec`](/commands/exec) command allows you to execute a command for multiple packages. When used in a script, you can declare filter options in the -`select-packages` section. +`packageFilters` section. The `hello_flutter` script below is only executed in Flutter packages: @@ -116,13 +116,18 @@ The `hello_flutter` script below is only executed in Flutter packages: scripts: hello_flutter: exec: echo 'Hello $(dirname $PWD)' - select-package: + packageFilters: flutter: true ``` See the [global options](/filters) for a list of supported filters. -When running a script that uses `select-package`, you will be prompted to select + + The filter names in `packageFilters` are camel cased. For example, for the + equivalent of the command line option `--file-exists` use `fileExists`. + + +When running a script that uses `packageFilters`, you will be prompted to select the package to execute the script in. If you want to skip this prompt and run the script in all packages, use the `--no-select` option. diff --git a/docs/guides/migrations.mdx b/docs/guides/migrations.mdx index 20792c06..12344c1c 100644 --- a/docs/guides/migrations.mdx +++ b/docs/guides/migrations.mdx @@ -66,3 +66,31 @@ command, like for all other commands. The new `preVersionCommmit` hook is executed before the version commit is created and is the equivalent of the previous `version` hook. + +### Package filters + +The `select-package` option for scripts has been renamed to `packageFilters`. +This brings it in line with `command/version/changelogs/packageFilters`. + +The names of filters specified in `packageFilters` are now camel cased instead +of kebab cased. + +For example, take the following `test` script configuration: + +```yaml +scripts: + test: + exec: dart test + packageFilters: + dirExists: test +``` + +This would previously have been written as: + +```yaml +scripts: + test: + exec: dart test + select-package: + dir-exists: test +``` diff --git a/melos.yaml b/melos.yaml index f4142e17..6e0b31fc 100644 --- a/melos.yaml +++ b/melos.yaml @@ -21,7 +21,7 @@ scripts: description: Format Dart code. run: dart format . - format-check: + format:check: description: Check formatting of Dart code. run: dart format --output none --set-exit-if-changed . @@ -34,8 +34,8 @@ scripts: run: dart test exec: concurrency: 1 - select-package: - dir-exists: + packageFilters: + dirExists: - 'test/' # This tells Melos tests to ignore env variables passed to tests from `melos run test` # as they could change the behaviour of how tests filter packages. diff --git a/packages/melos/lib/melos.dart b/packages/melos/lib/melos.dart index bf10c6f1..30113854 100644 --- a/packages/melos/lib/melos.dart +++ b/packages/melos/lib/melos.dart @@ -15,9 +15,9 @@ export 'src/global_options.dart' show GlobalOptions; export 'src/logging.dart' show MelosLogger, ToMelosLoggerExtension; export 'src/package.dart' show - InvalidPackageFilterException, + InvalidPackageFiltersException, Package, - PackageFilter, + PackageFilters, PackageMap, PackageType; export 'src/workspace.dart' show IdeWorkspace, MelosWorkspace; diff --git a/packages/melos/lib/src/command_runner/base.dart b/packages/melos/lib/src/command_runner/base.dart index a6926b30..9f604d84 100644 --- a/packages/melos/lib/src/command_runner/base.dart +++ b/packages/melos/lib/src/command_runner/base.dart @@ -139,7 +139,7 @@ abstract class MelosCommand extends Command { ); } - PackageFilter parsePackageFilter( + PackageFilters parsePackageFilters( String workingDirPath, { bool diffEnabled = true, }) { @@ -153,7 +153,7 @@ abstract class MelosCommand extends Command { final scope = argResults![filterOptionScope] as List? ?? []; final ignore = argResults![filterOptionIgnore] as List? ?? []; - return PackageFilter( + return PackageFilters( scope: scope .map((e) => createGlob(e, currentDirectoryPath: workingDirPath)) .toList(), diff --git a/packages/melos/lib/src/command_runner/bootstrap.dart b/packages/melos/lib/src/command_runner/bootstrap.dart index db2b5fd6..2650339d 100644 --- a/packages/melos/lib/src/command_runner/bootstrap.dart +++ b/packages/melos/lib/src/command_runner/bootstrap.dart @@ -42,7 +42,7 @@ class BootstrapCommand extends MelosCommand { return melos.bootstrap( global: global, - filter: parsePackageFilter(config.path), + packageFilters: parsePackageFilters(config.path), ); } } diff --git a/packages/melos/lib/src/command_runner/clean.dart b/packages/melos/lib/src/command_runner/clean.dart index c2505e6c..ea5ba0fe 100644 --- a/packages/melos/lib/src/command_runner/clean.dart +++ b/packages/melos/lib/src/command_runner/clean.dart @@ -37,7 +37,7 @@ class CleanCommand extends MelosCommand { await melos.clean( global: global, - filter: parsePackageFilter(config.path), + packageFilters: parsePackageFilters(config.path), ); } } diff --git a/packages/melos/lib/src/command_runner/exec.dart b/packages/melos/lib/src/command_runner/exec.dart index ecadc224..29401e6f 100644 --- a/packages/melos/lib/src/command_runner/exec.dart +++ b/packages/melos/lib/src/command_runner/exec.dart @@ -66,7 +66,7 @@ class ExecCommand extends MelosCommand { final melos = Melos(logger: logger, config: config); - final packageFilter = parsePackageFilter(config.path); + final packageFilters = parsePackageFilters(config.path); final concurrency = int.parse(argResults!['concurrency'] as String); final failFast = argResults!['fail-fast'] as bool; final orderDependents = argResults!['order-dependents'] as bool; @@ -77,7 +77,7 @@ class ExecCommand extends MelosCommand { failFast: failFast, orderDependents: orderDependents, global: global, - filter: packageFilter, + packageFilters: packageFilters, ); } } diff --git a/packages/melos/lib/src/command_runner/list.dart b/packages/melos/lib/src/command_runner/list.dart index eee05b63..e3c74a98 100644 --- a/packages/melos/lib/src/command_runner/list.dart +++ b/packages/melos/lib/src/command_runner/list.dart @@ -93,7 +93,7 @@ class ListCommand extends MelosCommand { return melos.list( long: long, global: global, - filter: parsePackageFilter(config.path), + packageFilters: parsePackageFilters(config.path), relativePaths: relative, kind: kind, ); diff --git a/packages/melos/lib/src/command_runner/publish.dart b/packages/melos/lib/src/command_runner/publish.dart index 065ddbf9..a9402366 100644 --- a/packages/melos/lib/src/command_runner/publish.dart +++ b/packages/melos/lib/src/command_runner/publish.dart @@ -57,11 +57,11 @@ class PublishCommand extends MelosCommand { final yes = argResults!['yes'] as bool || false; final melos = Melos(logger: logger, config: config); - final filter = parsePackageFilter(config.path); + final packageFilters = parsePackageFilters(config.path); return melos.publish( global: global, - filter: filter, + packageFilters: packageFilters, dryRun: dryRun, force: yes, gitTagVersion: gitTagVersion, diff --git a/packages/melos/lib/src/command_runner/run.dart b/packages/melos/lib/src/command_runner/run.dart index 1519bfca..92da77cc 100644 --- a/packages/melos/lib/src/command_runner/run.dart +++ b/packages/melos/lib/src/command_runner/run.dart @@ -24,7 +24,7 @@ class RunCommand extends MelosCommand { 'no-select', negatable: false, help: 'Skips the prompt to select a package (if defined in the script ' - 'configuration). Filters defined in the scripts "select-package" ' + """configuration). Filters defined in the script's "packageFilters" """ 'options will however still be applied.', ); } diff --git a/packages/melos/lib/src/command_runner/script.dart b/packages/melos/lib/src/command_runner/script.dart index 0828e328..3b1351c6 100644 --- a/packages/melos/lib/src/command_runner/script.dart +++ b/packages/melos/lib/src/command_runner/script.dart @@ -28,7 +28,7 @@ class ScriptCommand extends MelosCommand { 'no-select', negatable: false, help: 'Skips the prompt to select a package (if defined in the script ' - 'configuration). Filters defined in the scripts "select-package" ' + """configuration). Filters defined in the script's "packageFilters" """ 'options will however still be applied.', ); } diff --git a/packages/melos/lib/src/command_runner/version.dart b/packages/melos/lib/src/command_runner/version.dart index 83aedf07..f51ccf09 100644 --- a/packages/melos/lib/src/command_runner/version.dart +++ b/packages/melos/lib/src/command_runner/version.dart @@ -192,7 +192,7 @@ class VersionCommand extends MelosCommand { return melos.version( // We only want to version the specified package and not all packages // that could be versioned. - filter: PackageFilter(scope: [Glob(packageName)]), + packageFilters: PackageFilters(scope: [Glob(packageName)]), manualVersions: {packageName: versionChange}, force: force, gitTag: tag, @@ -235,7 +235,7 @@ class VersionCommand extends MelosCommand { await melos.version( global: global, - filter: parsePackageFilter(config.path), + packageFilters: parsePackageFilters(config.path), force: force, gitTag: tag, releaseUrl: releaseUrl, diff --git a/packages/melos/lib/src/commands/bootstrap.dart b/packages/melos/lib/src/commands/bootstrap.dart index 8e8a0fdc..2b0d44cd 100644 --- a/packages/melos/lib/src/commands/bootstrap.dart +++ b/packages/melos/lib/src/commands/bootstrap.dart @@ -1,8 +1,12 @@ part of 'runner.dart'; mixin _BootstrapMixin on _CleanMixin { - Future bootstrap({GlobalOptions? global, PackageFilter? filter}) async { - final workspace = await createWorkspace(global: global, filter: filter); + Future bootstrap({ + GlobalOptions? global, + PackageFilters? packageFilters, + }) async { + final workspace = + await createWorkspace(global: global, packageFilters: packageFilters); return _runLifecycle( workspace, diff --git a/packages/melos/lib/src/commands/clean.dart b/packages/melos/lib/src/commands/clean.dart index da60ae2a..9075335c 100644 --- a/packages/melos/lib/src/commands/clean.dart +++ b/packages/melos/lib/src/commands/clean.dart @@ -1,8 +1,12 @@ part of 'runner.dart'; mixin _CleanMixin on _Melos { - Future clean({GlobalOptions? global, PackageFilter? filter}) async { - final workspace = await createWorkspace(global: global, filter: filter); + Future clean({ + GlobalOptions? global, + PackageFilters? packageFilters, + }) async { + final workspace = + await createWorkspace(global: global, packageFilters: packageFilters); return _runLifecycle( workspace, diff --git a/packages/melos/lib/src/commands/exec.dart b/packages/melos/lib/src/commands/exec.dart index ee0ea694..0f454d69 100644 --- a/packages/melos/lib/src/commands/exec.dart +++ b/packages/melos/lib/src/commands/exec.dart @@ -4,12 +4,13 @@ mixin _ExecMixin on _Melos { Future exec( List execArgs, { GlobalOptions? global, - PackageFilter? filter, + PackageFilters? packageFilters, int concurrency = 5, bool failFast = false, bool orderDependents = false, }) async { - final workspace = await createWorkspace(global: global, filter: filter); + final workspace = + await createWorkspace(global: global, packageFilters: packageFilters); final packages = workspace.filteredPackages.values; await _execForAllPackages( diff --git a/packages/melos/lib/src/commands/list.dart b/packages/melos/lib/src/commands/list.dart index 1083bb54..65c04167 100644 --- a/packages/melos/lib/src/commands/list.dart +++ b/packages/melos/lib/src/commands/list.dart @@ -8,10 +8,11 @@ mixin _ListMixin on _Melos { GlobalOptions? global, bool long = false, bool relativePaths = false, - PackageFilter? filter, + PackageFilters? packageFilters, ListOutputKind kind = ListOutputKind.column, }) async { - final workspace = await createWorkspace(global: global, filter: filter); + final workspace = + await createWorkspace(global: global, packageFilters: packageFilters); switch (kind) { case ListOutputKind.graph: diff --git a/packages/melos/lib/src/commands/publish.dart b/packages/melos/lib/src/commands/publish.dart index 18460787..90519017 100644 --- a/packages/melos/lib/src/commands/publish.dart +++ b/packages/melos/lib/src/commands/publish.dart @@ -3,13 +3,14 @@ part of 'runner.dart'; mixin _PublishMixin on _ExecMixin { Future publish({ GlobalOptions? global, - PackageFilter? filter, + PackageFilters? packageFilters, bool dryRun = true, bool gitTagVersion = true, // yes bool force = false, }) async { - final workspace = await createWorkspace(global: global, filter: filter); + final workspace = + await createWorkspace(global: global, packageFilters: packageFilters); logger.command('melos publish${dryRun ? " --dry-run" : ''}'); logger.child(targetStyle(workspace.path)).newLine(); diff --git a/packages/melos/lib/src/commands/run.dart b/packages/melos/lib/src/commands/run.dart index e44dd912..efdd3399 100644 --- a/packages/melos/lib/src/commands/run.dart +++ b/packages/melos/lib/src/commands/run.dart @@ -78,8 +78,8 @@ mixin _RunMixin on _Melos { final workspace = await MelosWorkspace.fromConfig( config, global: global, - filter: script.filter?.copyWithUpdatedIgnore([ - ...script.filter!.ignore, + packageFilters: script.packageFilters?.copyWithUpdatedIgnore([ + ...script.packageFilters!.ignore, ...config.ignore, ]), logger: logger, @@ -94,14 +94,14 @@ mixin _RunMixin on _Melos { ...script.env, }; - if (script.filter != null) { + if (script.packageFilters != null) { final packages = workspace.filteredPackages.values.toList(); var choices = packages.map((e) => AnsiStyles.cyan(e.name)).toList(); if (choices.isEmpty) { throw NoPackageFoundScriptException._( - script.filter, + script.packageFilters, script.name, ); } @@ -167,9 +167,9 @@ mixin _RunMixin on _Melos { } class NoPackageFoundScriptException implements MelosException { - NoPackageFoundScriptException._(this.filter, this.scriptName); + NoPackageFoundScriptException._(this.filters, this.scriptName); - final PackageFilter? filter; + final PackageFilters? filters; final String? scriptName; @override diff --git a/packages/melos/lib/src/commands/runner.dart b/packages/melos/lib/src/commands/runner.dart index 19f9e2fa..44265a8e 100644 --- a/packages/melos/lib/src/commands/runner.dart +++ b/packages/melos/lib/src/commands/runner.dart @@ -78,16 +78,16 @@ abstract class _Melos { Future createWorkspace({ GlobalOptions? global, - PackageFilter? filter, + PackageFilters? packageFilters, }) async { - var filterWithEnv = filter; + var filterWithEnv = packageFilters; if (currentPlatform.environment.containsKey(envKeyMelosPackages)) { // MELOS_PACKAGES environment variable is a comma delimited list of // package names - used instead of filters if it is present. // This can be user defined or can come from package selection in // `melos run`. - filterWithEnv = PackageFilter( + filterWithEnv = PackageFilters( scope: currentPlatform.environment[envKeyMelosPackages]! .split(',') .map( @@ -100,7 +100,7 @@ abstract class _Melos { return (await MelosWorkspace.fromConfig( config, global: global, - filter: filterWithEnv, + packageFilters: filterWithEnv, logger: logger, )) ..validate(); diff --git a/packages/melos/lib/src/commands/version.dart b/packages/melos/lib/src/commands/version.dart index 86682246..2207a93c 100644 --- a/packages/melos/lib/src/commands/version.dart +++ b/packages/melos/lib/src/commands/version.dart @@ -5,7 +5,7 @@ mixin _VersionMixin on _RunMixin { /// specified versions. Future version({ GlobalOptions? global, - PackageFilter? filter, + PackageFilters? packageFilters, bool asPrerelease = false, bool asStableRelease = false, bool updateChangelog = true, @@ -45,14 +45,14 @@ mixin _VersionMixin on _RunMixin { // already filters it itself, filtering here would map dependant version // fail as it won't be aware of any packages that have been filtered out // here because of the 'diff' filter. - filter: filter?.copyWithDiff(null), + packageFilters: packageFilters?.copyWithDiff(null), ); return _runLifecycle(workspace, ScriptLifecycle.version, () { return _version( workspace: workspace, global: global, - filter: filter, + packageFilters: packageFilters, asPrerelease: asPrerelease, asStableRelease: asStableRelease, updateChangelog: updateChangelog, @@ -74,7 +74,7 @@ mixin _VersionMixin on _RunMixin { Future _version({ required MelosWorkspace workspace, GlobalOptions? global, - PackageFilter? filter, + PackageFilters? packageFilters, bool asPrerelease = false, bool asStableRelease = false, bool updateChangelog = true, @@ -117,7 +117,7 @@ mixin _VersionMixin on _RunMixin { final packageCommits = await _getPackageCommits( workspace, versionPrivatePackages: versionPrivatePackages, - diff: filter?.diff, + diff: packageFilters?.diff, ); final packagesWithVersionableCommits = @@ -716,7 +716,7 @@ mixin _VersionMixin on _RunMixin { ].join('-'); final packages = - await workspace.allPackages.applyFilter(config.packageFilter); + await workspace.allPackages.applyFilters(config.packageFilters); // ignore: parameter_assignments pendingPackageUpdates = pendingPackageUpdates .where((update) => packages[update.package.name] != null) diff --git a/packages/melos/lib/src/common/utils.dart b/packages/melos/lib/src/common/utils.dart index 945cb4b3..037c4bb8 100644 --- a/packages/melos/lib/src/common/utils.dart +++ b/packages/melos/lib/src/common/utils.dart @@ -76,6 +76,8 @@ const envKeyMelosTerminalWidth = 'MELOS_TERMINAL_WIDTH'; final melosPackageUri = Uri.parse('package:melos/melos.dart'); +final _camelCasedDelimiterRegExp = RegExp(r'[_\s-]+'); + extension StringUtils on String { String indent(String indent) { final split = this.split('\n'); @@ -108,6 +110,22 @@ extension StringUtils on String { if (isEmpty) return this; return '${this[0].toUpperCase()}${substring(1)}'; } + + String get camelCased { + if (isEmpty) return this; + var isFirstWord = true; + return splitMapJoin( + _camelCasedDelimiterRegExp, + onMatch: (m) => '', + onNonMatch: (n) { + if (isFirstWord) { + isFirstWord = false; + return n; + } + return n.capitalized; + }, + ); + } } int get terminalWidth { diff --git a/packages/melos/lib/src/common/validation.dart b/packages/melos/lib/src/common/validation.dart index 1d1a1ac6..688e3538 100644 --- a/packages/melos/lib/src/common/validation.dart +++ b/packages/melos/lib/src/common/validation.dart @@ -29,8 +29,7 @@ T assertKeyIsA({ throw MelosConfigException.missingKey(key: key, path: path); } - final value = map[key]; - return assertIsA(value: value, key: key); + return assertIsA(value: map[key], key: key); } List assertListOrString({ diff --git a/packages/melos/lib/src/package.dart b/packages/melos/lib/src/package.dart index f6964d1f..f45d4a03 100644 --- a/packages/melos/lib/src/package.dart +++ b/packages/melos/lib/src/package.dart @@ -115,8 +115,8 @@ RegExp dependencyTagReplaceRegex(String dependencyName) { } @immutable -class PackageFilter { - PackageFilter({ +class PackageFilters { + PackageFilters({ this.scope = const [], this.ignore = const [], this.dirExists = const [], @@ -140,62 +140,72 @@ class PackageFilter { if (flutter == false) 'flutter', ]; - factory PackageFilter.fromYaml( + factory PackageFilters.fromYaml( Map yaml, { required String path, required String workspacePath, }) { final scope = assertListOrString( - key: filterOptionScope, + key: filterOptionScope.camelCased, map: yaml, path: path, ); + final ignore = assertListOrString( - key: filterOptionIgnore, + key: filterOptionIgnore.camelCased, map: yaml, path: path, ); + final dirExists = assertListOrString( - key: filterOptionDirExists, + key: filterOptionDirExists.camelCased, map: yaml, path: path, ); + final fileExists = assertListOrString( - key: filterOptionFileExists, + key: filterOptionFileExists.camelCased, map: yaml, path: path, ); + final dependsOn = assertListOrString( - key: filterOptionDependsOn, + key: filterOptionDependsOn.camelCased, map: yaml, path: path, ); + final noDependsOn = assertListOrString( - key: filterOptionNoDependsOn, + key: filterOptionNoDependsOn.camelCased, map: yaml, path: path, ); - final diff = assertIsA( - value: yaml[filterOptionDiff], - key: filterOptionDiff, + final diff = assertKeyIsA( + key: filterOptionDiff.camelCased, + map: yaml, path: path, ); - final excludePrivatePackagesTmp = assertIsA( - value: yaml[filterOptionNoPrivate], - key: filterOptionNoPrivate, + final noPrivateOptionKey = filterOptionNoPrivate.camelCased; + final excludePrivatePackagesTmp = assertKeyIsA( + key: noPrivateOptionKey, + map: yaml, path: path, ); - final includePrivatePackagesTmp = assertIsA( - value: yaml[filterOptionPrivate], - key: filterOptionNoPrivate, + + final privateOptionKey = filterOptionPrivate.camelCased; + final includePrivatePackagesTmp = assertKeyIsA( + key: privateOptionKey, + map: yaml, path: path, ); + if (includePrivatePackagesTmp != null && excludePrivatePackagesTmp != null) { throw MelosConfigException( - 'Cannot specify both --private and --no-private at the same time', + 'Cannot specify both "$noPrivateOptionKey" and ' + '"$excludePrivatePackagesTmp" at the same time in "$path".', ); } bool? includePrivatePackages; @@ -206,26 +216,28 @@ class PackageFilter { includePrivatePackages = !excludePrivatePackagesTmp; } - final published = assertIsA( - value: yaml[filterOptionPublished], - key: filterOptionPublished, + final published = assertKeyIsA( + key: filterOptionPublished.camelCased, + map: yaml, path: path, ); - final nullSafe = assertIsA( - value: yaml[filterOptionNullsafety], - key: filterOptionNullsafety, + + final nullSafe = assertKeyIsA( + key: filterOptionNullsafety.camelCased, + map: yaml, path: path, ); - final flutter = assertIsA( - value: yaml[filterOptionFlutter], - key: filterOptionFlutter, + + final flutter = assertKeyIsA( + key: filterOptionFlutter.camelCased, + map: yaml, path: path, ); Glob createPackageGlob(String pattern) => createGlob(pattern, currentDirectoryPath: workspacePath); - return PackageFilter( + return PackageFilters( scope: scope.map(createPackageGlob).toList(), ignore: ignore.map(createPackageGlob).toList(), dirExists: dirExists, @@ -242,7 +254,7 @@ class PackageFilter { /// A default constructor with **all** properties as requires, to ensure that /// copyWith functions properly copy all properties. - PackageFilter._({ + PackageFilters._({ required this.scope, required this.ignore, required this.dirExists, @@ -304,25 +316,26 @@ class PackageFilter { Map toJson() { return { if (scope.isNotEmpty) - filterOptionScope: scope.map((e) => e.toString()).toList(), + filterOptionScope.camelCased: scope.map((e) => e.toString()).toList(), if (ignore.isNotEmpty) - filterOptionIgnore: ignore.map((e) => e.toString()).toList(), - if (dirExists.isNotEmpty) filterOptionDirExists: dirExists, - if (fileExists.isNotEmpty) filterOptionFileExists: fileExists, - if (dependsOn.isNotEmpty) filterOptionDependsOn: dependsOn, - if (noDependsOn.isNotEmpty) filterOptionNoDependsOn: noDependsOn, - if (diff != null) filterOptionDiff: diff, + filterOptionIgnore.camelCased: ignore.map((e) => e.toString()).toList(), + if (dirExists.isNotEmpty) filterOptionDirExists.camelCased: dirExists, + if (fileExists.isNotEmpty) filterOptionFileExists.camelCased: fileExists, + if (dependsOn.isNotEmpty) filterOptionDependsOn.camelCased: dependsOn, + if (noDependsOn.isNotEmpty) + filterOptionNoDependsOn.camelCased: noDependsOn, + if (diff != null) filterOptionDiff.camelCased: diff, if (includePrivatePackages != null) - filterOptionPrivate: includePrivatePackages, - if (published != null) filterOptionPublished: published, - if (nullSafe != null) filterOptionNullsafety: nullSafe, - if (includeDependents) filterOptionIncludeDependents: true, - if (includeDependencies) filterOptionIncludeDependencies: true, + filterOptionPrivate.camelCased: includePrivatePackages, + if (published != null) filterOptionPublished.camelCased: published, + if (nullSafe != null) filterOptionNullsafety.camelCased: nullSafe, + if (includeDependents) filterOptionIncludeDependents.camelCased: true, + if (includeDependencies) filterOptionIncludeDependencies.camelCased: true, }; } - PackageFilter copyWithDiff(String? diff) { - return PackageFilter._( + PackageFilters copyWithDiff(String? diff) { + return PackageFilters._( dependsOn: dependsOn, dirExists: dirExists, fileExists: fileExists, @@ -338,8 +351,8 @@ class PackageFilter { ); } - PackageFilter copyWithUpdatedIgnore(List ignore) { - return PackageFilter._( + PackageFilters copyWithUpdatedIgnore(List ignore) { + return PackageFilters._( dependsOn: dependsOn, dirExists: dirExists, fileExists: fileExists, @@ -357,7 +370,7 @@ class PackageFilter { @override bool operator ==(Object other) => - other is PackageFilter && + other is PackageFilters && runtimeType == other.runtimeType && other.nullSafe == nullSafe && other.published == published && @@ -391,7 +404,7 @@ class PackageFilter { @override String toString() { return ''' -PackageFilter( +PackageFilters( nullSafe: $nullSafe, published: $published, includeDependencies: $includeDependencies, @@ -408,8 +421,8 @@ PackageFilter( } } -class InvalidPackageFilterException extends MelosException { - InvalidPackageFilterException(this.message); +class InvalidPackageFiltersException extends MelosException { + InvalidPackageFiltersException(this.message); final String message; @@ -551,28 +564,28 @@ The packages that caused the problem are: /// Detect packages in the workspace with the provided filters. /// /// This is the default packages behaviour when a workspace is loaded. - Future applyFilter(PackageFilter? filter) async { - if (filter == null) return this; + Future applyFilters(PackageFilters? filters) async { + if (filters == null) return this; var packageList = await values - .applyIgnore(filter.ignore) - .applyDirExists(filter.dirExists) - .applyFileExists(filter.fileExists) - .filterPrivatePackages(include: filter.includePrivatePackages) - .applyScope(filter.scope) - .applyDependsOn(filter.dependsOn) - .applyNoDependsOn(filter.noDependsOn) - .filterNullSafe(nullSafe: filter.nullSafe) - .filterPublishedPackages(published: filter.published); - - final diff = filter.diff; + .applyIgnore(filters.ignore) + .applyDirExists(filters.dirExists) + .applyFileExists(filters.fileExists) + .filterPrivatePackages(include: filters.includePrivatePackages) + .applyScope(filters.scope) + .applyDependsOn(filters.dependsOn) + .applyNoDependsOn(filters.noDependsOn) + .filterNullSafe(nullSafe: filters.nullSafe) + .filterPublishedPackages(published: filters.published); + + final diff = filters.diff; if (diff != null) { packageList = await packageList.applyDiff(diff, _logger); } packageList = packageList.applyIncludeDependentsOrDependencies( - includeDependents: filter.includeDependents, - includeDependencies: filter.includeDependencies, + includeDependents: filters.includeDependents, + includeDependencies: filters.includeDependencies, ); return PackageMap( diff --git a/packages/melos/lib/src/scripts.dart b/packages/melos/lib/src/scripts.dart index f5e2a8f3..2534cfa8 100644 --- a/packages/melos/lib/src/scripts.dart +++ b/packages/melos/lib/src/scripts.dart @@ -190,7 +190,7 @@ class Script { required this.run, this.description, this.env = const {}, - this.filter, + this.packageFilters, this.exec, }); @@ -203,7 +203,7 @@ class Script { String run; String? description; var env = {}; - PackageFilter? packageFilter; + PackageFilters? packageFilters; ExecOptions? exec; if (yaml is String) { @@ -247,17 +247,17 @@ class Script { ): entry.value.toString(), }; - final packageFilterMap = assertKeyIsA?>( - key: 'select-package', + final packageFiltersMap = assertKeyIsA?>( + key: 'packageFilters', map: yaml, path: scriptPath, ); - packageFilter = packageFilterMap == null + packageFilters = packageFiltersMap == null ? null - : PackageFilter.fromYaml( - packageFilterMap, - path: 'scripts/$name/select-package', + : PackageFilters.fromYaml( + packageFiltersMap, + path: 'scripts/$name/packageFilters', workspacePath: workspacePath, ); @@ -283,7 +283,7 @@ class Script { run: run, description: description, env: env, - filter: packageFilter, + packageFilters: packageFilters, exec: exec, ); } @@ -337,7 +337,7 @@ class Script { /// If the [run] command is a melos command, allows filtering packages that /// will execute the command. - final PackageFilter? filter; + final PackageFilters? packageFilters; /// The options for `melos exec`, if [run] should be executed in multiple /// packages. @@ -390,7 +390,7 @@ class Script { 'run': run, if (description != null) 'description': description, if (env.isNotEmpty) 'env': env, - if (filter != null) 'select-package': filter!.toJson(), + if (packageFilters != null) 'packageFilters': packageFilters!.toJson(), if (exec != null) 'exec': exec!.toJson(), }; } @@ -403,7 +403,7 @@ class Script { other.run == run && other.description == description && const DeepCollectionEquality().equals(other.env, env) && - other.filter == filter && + other.packageFilters == packageFilters && other.exec == exec; @override @@ -413,7 +413,7 @@ class Script { run.hashCode ^ description.hashCode ^ const DeepCollectionEquality().hash(env) ^ - filter.hashCode ^ + packageFilters.hashCode ^ exec.hashCode; @override @@ -424,7 +424,7 @@ Script( run: $run, description: $description, env: $env, - packageFilter: ${filter.toString().indent(' ')}, + packageFilters: ${packageFilters.toString().indent(' ')}, exec: ${exec.toString().indent(' ')}, )'''; } diff --git a/packages/melos/lib/src/workspace.dart b/packages/melos/lib/src/workspace.dart index 38c66c1c..7b8251e2 100644 --- a/packages/melos/lib/src/workspace.dart +++ b/packages/melos/lib/src/workspace.dart @@ -57,7 +57,7 @@ class MelosWorkspace { static Future fromConfig( MelosWorkspaceConfig workspaceConfig, { GlobalOptions? global, - PackageFilter? filter, + PackageFilters? packageFilters, required MelosLogger logger, }) async { final allPackages = await PackageMap.resolvePackages( @@ -73,7 +73,7 @@ class MelosWorkspace { logger: logger, ); - final filteredPackages = await allPackages.applyFilter(filter); + final filteredPackages = await allPackages.applyFilters(packageFilters); return MelosWorkspace( name: workspaceConfig.name, diff --git a/packages/melos/lib/src/workspace_configs.dart b/packages/melos/lib/src/workspace_configs.dart index 75cfeeb1..459fd00e 100644 --- a/packages/melos/lib/src/workspace_configs.dart +++ b/packages/melos/lib/src/workspace_configs.dart @@ -325,7 +325,7 @@ class AggregateChangelogConfig { AggregateChangelogConfig({ this.isWorkspaceChangelog = false, required this.path, - required this.packageFilter, + required this.packageFilters, this.description, }); @@ -333,7 +333,7 @@ class AggregateChangelogConfig { : this( isWorkspaceChangelog: true, path: 'CHANGELOG.md', - packageFilter: PackageFilter(), + packageFilters: PackageFilters(), description: ''' All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. @@ -342,14 +342,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline final bool isWorkspaceChangelog; final String path; - final PackageFilter packageFilter; + final PackageFilters packageFilters; final String? description; Map toJson() { return { 'isWorkspaceChangelog': isWorkspaceChangelog, 'path': path, - 'packageFilter': packageFilter, + 'packageFilters': packageFilters, 'description': description, }; } @@ -360,7 +360,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline runtimeType == other.runtimeType && other.isWorkspaceChangelog == isWorkspaceChangelog && other.path == path && - other.packageFilter == packageFilter && + other.packageFilters == packageFilters && other.description == description; @override @@ -368,7 +368,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline runtimeType.hashCode ^ isWorkspaceChangelog.hashCode ^ path.hashCode ^ - packageFilter.hashCode ^ + packageFilters.hashCode ^ description.hashCode; @override @@ -377,7 +377,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline AggregateChangelogConfig( isWorkspaceChangelog: $isWorkspaceChangelog, path: $path, - packageFilter: $packageFilter, + packageFilters: $packageFilters, description: $description, )'''; } @@ -464,13 +464,13 @@ class VersionCommandConfigs { key: 'path', ); - final packageFilterMap = assertKeyIsA>( + final packageFiltersMap = assertKeyIsA>( map: entry, key: 'packageFilters', path: 'command/version/changelogs[$i]', ); - final packageFilter = PackageFilter.fromYaml( - packageFilterMap, + final packageFilters = PackageFilters.fromYaml( + packageFiltersMap, path: 'command/version/changelogs[$i]', workspacePath: workspacePath, ); @@ -482,7 +482,7 @@ class VersionCommandConfigs { ); final changelogConfig = AggregateChangelogConfig( path: path, - packageFilter: packageFilter, + packageFilters: packageFilters, description: description, ); diff --git a/packages/melos/test/commands/exec_test.dart b/packages/melos/test/commands/exec_test.dart index 83175ae5..f575e439 100644 --- a/packages/melos/test/commands/exec_test.dart +++ b/packages/melos/test/commands/exec_test.dart @@ -11,7 +11,7 @@ import '../utils.dart'; void main() { group('exec', () { - test('supports package filter', () async { + test('supports package filters', () async { final workspaceDir = createTemporaryWorkspaceDirectory(); final aDir = await createProject( @@ -41,7 +41,7 @@ void main() { await melos.exec( ['echo', 'hello', 'world'], concurrency: 1, - filter: PackageFilter( + packageFilters: PackageFilters( fileExists: const ['log.txt'], ), ); @@ -228,7 +228,7 @@ ${'-' * terminalWidth} ['echo', 'hello', 'world'], concurrency: 2, orderDependents: true, - filter: PackageFilter( + packageFilters: PackageFilters( fileExists: const ['log.txt'], ), ); diff --git a/packages/melos/test/commands/list_test.dart b/packages/melos/test/commands/list_test.dart index 30b15fa0..2850fd2f 100644 --- a/packages/melos/test/commands/list_test.dart +++ b/packages/melos/test/commands/list_test.dart @@ -97,7 +97,7 @@ c final melos = Melos(logger: logger, config: config); await melos.list( - filter: PackageFilter( + packageFilters: PackageFilters( includePrivatePackages: true, ignore: [ createGlob('b', currentDirectoryPath: workspaceDir.path), diff --git a/packages/melos/test/commands/run_test.dart b/packages/melos/test/commands/run_test.dart index 2e406015..1ef60d1e 100644 --- a/packages/melos/test/commands/run_test.dart +++ b/packages/melos/test/commands/run_test.dart @@ -27,7 +27,7 @@ void main() { 'test_script': Script( name: 'test_script', run: 'melos exec -- "echo hello"', - filter: PackageFilter( + packageFilters: PackageFilters( fileExists: const ['log.txt'], ), ) diff --git a/packages/melos/test/package_filter_test.dart b/packages/melos/test/package_filter_test.dart index ce966c43..180cdb62 100644 --- a/packages/melos/test/package_filter_test.dart +++ b/packages/melos/test/package_filter_test.dart @@ -7,7 +7,7 @@ import 'package:test/test.dart'; import 'utils.dart'; void main() { - group('PackageFilter', () { + group('PackageFilters', () { test('dirExists', () async { final workspaceDir = createTemporaryWorkspaceDirectory(); @@ -26,7 +26,7 @@ void main() { final workspace = await MelosWorkspace.fromConfig( config, logger: TestLogger().toMelosLogger(), - filter: PackageFilter( + packageFilters: PackageFilters( dirExists: const ['test'], ), ); @@ -62,7 +62,7 @@ void main() { final workspace = await MelosWorkspace.fromConfig( config, logger: TestLogger().toMelosLogger(), - filter: PackageFilter( + packageFilters: PackageFilters( fileExists: const ['log.txt'], ), ); diff --git a/packages/melos/test/package_test.dart b/packages/melos/test/package_test.dart index fadcfbe4..75520cc2 100644 --- a/packages/melos/test/package_test.dart +++ b/packages/melos/test/package_test.dart @@ -165,33 +165,33 @@ void main() { }); }); - group('PackageFilter', () { + group('PackageFilters', () { test('default', () { - final filter = PackageFilter(); - - expect(filter.dependsOn, isEmpty); - expect(filter.noDependsOn, isEmpty); - expect(filter.dirExists, isEmpty); - expect(filter.fileExists, isEmpty); - expect(filter.ignore, isEmpty); - expect(filter.scope, isEmpty); - expect(filter.includeDependencies, false); - expect(filter.includeDependents, false); - expect(filter.includePrivatePackages, null); - expect(filter.nullSafe, null); - expect(filter.published, null); - expect(filter.diff, null); + final filters = PackageFilters(); + + expect(filters.dependsOn, isEmpty); + expect(filters.noDependsOn, isEmpty); + expect(filters.dirExists, isEmpty); + expect(filters.fileExists, isEmpty); + expect(filters.ignore, isEmpty); + expect(filters.scope, isEmpty); + expect(filters.includeDependencies, false); + expect(filters.includeDependents, false); + expect(filters.includePrivatePackages, null); + expect(filters.nullSafe, null); + expect(filters.published, null); + expect(filters.diff, null); }); group('copyWithWithDiff', () { test('can assign null', () { - final filter = PackageFilter(diff: '123'); + final filters = PackageFilters(diff: '123'); - expect(filter.copyWithDiff(null).diff, null); + expect(filters.copyWithDiff(null).diff, null); }); test('clone properties besides diff', () { - final filter = PackageFilter( + final filters = PackageFilters( dependsOn: const ['a'], dirExists: const ['a'], fileExists: const ['a'], @@ -207,20 +207,20 @@ void main() { diff: '123', ); - final copy = filter.copyWithDiff('456'); + final copy = filters.copyWithDiff('456'); expect(copy.diff, '456'); - expect(copy.dependsOn, filter.dependsOn); - expect(copy.dirExists, filter.dirExists); - expect(copy.fileExists, filter.fileExists); - expect(copy.scope, filter.scope); - expect(copy.ignore, filter.ignore); - expect(copy.includeDependencies, filter.includeDependencies); - expect(copy.includeDependents, filter.includeDependents); - expect(copy.includePrivatePackages, filter.includePrivatePackages); - expect(copy.noDependsOn, filter.noDependsOn); - expect(copy.nullSafe, filter.nullSafe); - expect(copy.published, filter.published); + expect(copy.dependsOn, filters.dependsOn); + expect(copy.dirExists, filters.dirExists); + expect(copy.fileExists, filters.fileExists); + expect(copy.scope, filters.scope); + expect(copy.ignore, filters.ignore); + expect(copy.includeDependencies, filters.includeDependencies); + expect(copy.includeDependents, filters.includeDependents); + expect(copy.includePrivatePackages, filters.includePrivatePackages); + expect(copy.noDependsOn, filters.noDependsOn); + expect(copy.nullSafe, filters.nullSafe); + expect(copy.published, filters.published); }); }); }); diff --git a/packages/melos/test/workspace_config_test.dart b/packages/melos/test/workspace_config_test.dart index c3f42f66..522d492a 100644 --- a/packages/melos/test/workspace_config_test.dart +++ b/packages/melos/test/workspace_config_test.dart @@ -169,7 +169,7 @@ void main() { AggregateChangelogConfig.workspace(), AggregateChangelogConfig( path: 'FOO_CHANGELOG.md', - packageFilter: PackageFilter(flutter: true), + packageFilters: PackageFilters(flutter: true), description: 'Changelog for all foo packages.', ), ], diff --git a/packages/melos/test/workspace_test.dart b/packages/melos/test/workspace_test.dart index 6fce8885..811b2179 100644 --- a/packages/melos/test/workspace_test.dart +++ b/packages/melos/test/workspace_test.dart @@ -242,7 +242,7 @@ The packages that caused the problem are: ); final workspace = await MelosWorkspace.fromConfig( config, - filter: PackageFilter( + packageFilters: PackageFilters( scope: [ createGlob('b', currentDirectoryPath: workspaceDir.path) ], @@ -269,7 +269,7 @@ The packages that caused the problem are: ); final workspace = await MelosWorkspace.fromConfig( config, - filter: PackageFilter( + packageFilters: PackageFilters( scope: [ createGlob('a', currentDirectoryPath: workspaceDir.path), ], @@ -303,7 +303,7 @@ The packages that caused the problem are: ); final workspace = await MelosWorkspace.fromConfig( config, - filter: PackageFilter( + packageFilters: PackageFilters( scope: [ createGlob('a', currentDirectoryPath: workspaceDir.path), ], @@ -339,7 +339,7 @@ The packages that caused the problem are: ); final workspace = await MelosWorkspace.fromConfig( config, - filter: PackageFilter( + packageFilters: PackageFilters( scope: [ createGlob('a', currentDirectoryPath: workspaceDir.path), ], @@ -372,7 +372,7 @@ The packages that caused the problem are: ); final workspace = await MelosWorkspace.fromConfig( config, - filter: PackageFilter( + packageFilters: PackageFilters( scope: [ createGlob('a', currentDirectoryPath: workspaceDir.path), ], @@ -399,7 +399,7 @@ The packages that caused the problem are: ); final workspace = await MelosWorkspace.fromConfig( config, - filter: PackageFilter( + packageFilters: PackageFilters( scope: [ createGlob('b', currentDirectoryPath: workspaceDir.path), ], @@ -431,7 +431,7 @@ The packages that caused the problem are: ); final workspace = await MelosWorkspace.fromConfig( config, - filter: PackageFilter( + packageFilters: PackageFilters( scope: [ createGlob('c', currentDirectoryPath: workspaceDir.path), ], @@ -467,7 +467,7 @@ The packages that caused the problem are: ); final workspace = await MelosWorkspace.fromConfig( config, - filter: PackageFilter( + packageFilters: PackageFilters( scope: [ createGlob('d', currentDirectoryPath: workspaceDir.path), ], From 4ac9851390632092139eb5569f59025556e2ad96 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Sat, 4 Feb 2023 20:29:03 +0100 Subject: [PATCH 2/2] fixup --- docs/configuration/scripts.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/scripts.mdx b/docs/configuration/scripts.mdx index 0fa26e10..4fd60b48 100644 --- a/docs/configuration/scripts.mdx +++ b/docs/configuration/scripts.mdx @@ -79,7 +79,7 @@ scripts: concurrency: 1 ``` -See the [`packageFilters`](/configuration/scripts#scriptspackagefilter) option +See the [`packageFilters`](/configuration/scripts#scriptspackagefilters) option for filtering the packages to execute the command in. ## `scripts/*/exec/concurrency`