diff options
author | Gar <gar+gh@danger.computer> | 2021-07-28 01:38:07 +0300 |
---|---|---|
committer | Luke Karrys <luke@lukekarrys.com> | 2021-09-30 23:35:23 +0300 |
commit | f17dfa0ced7d8df9bb7baf378bb20d33175c8e8b (patch) | |
tree | 68ddb44f93c8f139e8cb592340a1612e608c65a6 | |
parent | 8349c3c1557ac52973ad08c10db492e3a5a30204 (diff) |
feat(workspaces): --include-workspace-root
Adds a new config item that includes the workspace root when running
non-arborist commands (i.e. repo, version, publish). Arborist will need
to be udpated to look for this flag to change its behavior to include
the workspace root for its functions.
This also changes --workspaces to a trinary, so that setting it to false
will explicitly exclude workspaces altogether. This is also going to
require an arborist change so that it ignores workspaces altogether.
Co-author: @fritzy
PR-URL: https://github.com/npm/cli/pull/3816
Credit: @isaacs
Close: #3816
Reviewed-by: @wraithgar
74 files changed, 1219 insertions, 282 deletions
diff --git a/docs/content/commands/npm-audit.md b/docs/content/commands/npm-audit.md index 9fa8c0fcc..58c614d79 100644 --- a/docs/content/commands/npm-audit.md +++ b/docs/content/commands/npm-audit.md @@ -313,8 +313,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -327,17 +327,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-dedupe.md b/docs/content/commands/npm-dedupe.md index dcb2a98fe..377e17d81 100644 --- a/docs/content/commands/npm-dedupe.md +++ b/docs/content/commands/npm-dedupe.md @@ -247,8 +247,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -261,17 +261,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-diff.md b/docs/content/commands/npm-diff.md index cf0bbec15..8d05df779 100644 --- a/docs/content/commands/npm-diff.md +++ b/docs/content/commands/npm-diff.md @@ -286,8 +286,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -300,17 +300,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ## See Also diff --git a/docs/content/commands/npm-dist-tag.md b/docs/content/commands/npm-dist-tag.md index 4ad68ff56..a4e0243aa 100644 --- a/docs/content/commands/npm-dist-tag.md +++ b/docs/content/commands/npm-dist-tag.md @@ -106,8 +106,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -120,17 +120,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-docs.md b/docs/content/commands/npm-docs.md index 9f1387dae..970d17aa8 100644 --- a/docs/content/commands/npm-docs.md +++ b/docs/content/commands/npm-docs.md @@ -63,8 +63,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -77,17 +77,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-exec.md b/docs/content/commands/npm-exec.md index 82908d65e..db2353662 100644 --- a/docs/content/commands/npm-exec.md +++ b/docs/content/commands/npm-exec.md @@ -164,8 +164,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -178,17 +178,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### Examples diff --git a/docs/content/commands/npm-explain.md b/docs/content/commands/npm-explain.md index 4a8af2f70..5f05cac0f 100644 --- a/docs/content/commands/npm-explain.md +++ b/docs/content/commands/npm-explain.md @@ -85,8 +85,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a diff --git a/docs/content/commands/npm-find-dupes.md b/docs/content/commands/npm-find-dupes.md index e9dbac6d1..f7dc84f9c 100644 --- a/docs/content/commands/npm-find-dupes.md +++ b/docs/content/commands/npm-find-dupes.md @@ -174,8 +174,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -188,17 +188,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-fund.md b/docs/content/commands/npm-fund.md index 83c0b13d8..606b0a188 100644 --- a/docs/content/commands/npm-fund.md +++ b/docs/content/commands/npm-fund.md @@ -122,8 +122,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a diff --git a/docs/content/commands/npm-init.md b/docs/content/commands/npm-init.md index 7355c7588..d5a02494f 100644 --- a/docs/content/commands/npm-init.md +++ b/docs/content/commands/npm-init.md @@ -200,8 +200,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -214,12 +214,20 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> diff --git a/docs/content/commands/npm-install-test.md b/docs/content/commands/npm-install-test.md index c2f9ab3d2..c464e5bd0 100644 --- a/docs/content/commands/npm-install-test.md +++ b/docs/content/commands/npm-install-test.md @@ -241,8 +241,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -255,17 +255,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-install.md b/docs/content/commands/npm-install.md index de7378718..a103845d1 100644 --- a/docs/content/commands/npm-install.md +++ b/docs/content/commands/npm-install.md @@ -625,8 +625,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -639,17 +639,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### Algorithm diff --git a/docs/content/commands/npm-link.md b/docs/content/commands/npm-link.md index 5811a8b23..d4ef41ae9 100644 --- a/docs/content/commands/npm-link.md +++ b/docs/content/commands/npm-link.md @@ -325,8 +325,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -339,17 +339,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-ls.md b/docs/content/commands/npm-ls.md index 528140bee..3b33f0a36 100644 --- a/docs/content/commands/npm-ls.md +++ b/docs/content/commands/npm-ls.md @@ -227,8 +227,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -241,17 +241,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-outdated.md b/docs/content/commands/npm-outdated.md index 8eb5528c3..1b58a6afd 100644 --- a/docs/content/commands/npm-outdated.md +++ b/docs/content/commands/npm-outdated.md @@ -167,8 +167,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a diff --git a/docs/content/commands/npm-pack.md b/docs/content/commands/npm-pack.md index dda30512d..539459868 100644 --- a/docs/content/commands/npm-pack.md +++ b/docs/content/commands/npm-pack.md @@ -69,8 +69,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -83,17 +83,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### Description diff --git a/docs/content/commands/npm-pkg.md b/docs/content/commands/npm-pkg.md index bf6a2df5d..beee9c1c4 100644 --- a/docs/content/commands/npm-pkg.md +++ b/docs/content/commands/npm-pkg.md @@ -223,8 +223,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -237,12 +237,20 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> diff --git a/docs/content/commands/npm-prune.md b/docs/content/commands/npm-prune.md index 7bd7ad131..658ab2610 100644 --- a/docs/content/commands/npm-prune.md +++ b/docs/content/commands/npm-prune.md @@ -103,8 +103,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -117,17 +117,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-publish.md b/docs/content/commands/npm-publish.md index 946109de4..6958b1066 100644 --- a/docs/content/commands/npm-publish.md +++ b/docs/content/commands/npm-publish.md @@ -188,8 +188,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -202,17 +202,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-rebuild.md b/docs/content/commands/npm-rebuild.md index 19684796f..75e71c60e 100644 --- a/docs/content/commands/npm-rebuild.md +++ b/docs/content/commands/npm-rebuild.md @@ -89,8 +89,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -103,17 +103,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-repo.md b/docs/content/commands/npm-repo.md index c3c509e0b..cd47fde47 100644 --- a/docs/content/commands/npm-repo.md +++ b/docs/content/commands/npm-repo.md @@ -50,8 +50,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -64,17 +64,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-run-script.md b/docs/content/commands/npm-run-script.md index e436bc27f..6dd602d03 100644 --- a/docs/content/commands/npm-run-script.md +++ b/docs/content/commands/npm-run-script.md @@ -152,8 +152,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -166,17 +166,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + #### `if-present` * Default: false diff --git a/docs/content/commands/npm-set-script.md b/docs/content/commands/npm-set-script.md index e39b7a18c..869ceede0 100644 --- a/docs/content/commands/npm-set-script.md +++ b/docs/content/commands/npm-set-script.md @@ -44,8 +44,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -58,17 +58,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-uninstall.md b/docs/content/commands/npm-uninstall.md index c04e1a7fd..824d0d876 100644 --- a/docs/content/commands/npm-uninstall.md +++ b/docs/content/commands/npm-uninstall.md @@ -85,8 +85,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -99,17 +99,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-unpublish.md b/docs/content/commands/npm-unpublish.md index 1678bb305..13589a03e 100644 --- a/docs/content/commands/npm-unpublish.md +++ b/docs/content/commands/npm-unpublish.md @@ -107,8 +107,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -121,12 +121,20 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> diff --git a/docs/content/commands/npm-update.md b/docs/content/commands/npm-update.md index 57b9b91f9..ad02118e4 100644 --- a/docs/content/commands/npm-update.md +++ b/docs/content/commands/npm-update.md @@ -341,8 +341,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -355,17 +355,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### See Also diff --git a/docs/content/commands/npm-version.md b/docs/content/commands/npm-version.md index a02bf5bb9..91ab0dee0 100644 --- a/docs/content/commands/npm-version.md +++ b/docs/content/commands/npm-version.md @@ -103,8 +103,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -117,17 +117,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### Description diff --git a/docs/content/commands/npm-view.md b/docs/content/commands/npm-view.md index af354deb8..9a1793f13 100644 --- a/docs/content/commands/npm-view.md +++ b/docs/content/commands/npm-view.md @@ -127,8 +127,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -141,17 +141,39 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + <!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> ### Output diff --git a/docs/content/using-npm/config.md b/docs/content/using-npm/config.md index 10e8ca9b9..647a9e1e0 100644 --- a/docs/content/using-npm/config.md +++ b/docs/content/using-npm/config.md @@ -806,6 +806,20 @@ This is experimental, and not implemented by the npm public registry. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + #### `init-author-email` * Default: "" @@ -1744,8 +1758,8 @@ Valid values for the `workspace` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the `npm init` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -1758,12 +1772,20 @@ This value is not exported to the environment for child processes. #### `workspaces` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> diff --git a/lib/base-command.js b/lib/base-command.js index 870c69acc..c5bd3fd94 100644 --- a/lib/base-command.js +++ b/lib/base-command.js @@ -7,8 +7,6 @@ class BaseCommand { constructor (npm) { this.wrapWidth = 80 this.npm = npm - this.workspaces = null - this.workspacePaths = null } get name () { @@ -75,7 +73,13 @@ class BaseCommand { } async setWorkspaces (filters) { - const ws = await getWorkspaces(filters, { path: this.npm.localPrefix }) + if (this.isArboristCmd) + this.includeWorkspaceRoot = false + + const ws = await getWorkspaces(filters, { + path: this.npm.localPrefix, + includeWorkspaceRoot: this.includeWorkspaceRoot, + }) this.workspaces = ws this.workspaceNames = [...ws.keys()] this.workspacePaths = [...ws.values()] diff --git a/lib/diff.js b/lib/diff.js index 01658c466..b1a32705c 100644 --- a/lib/diff.js +++ b/lib/diff.js @@ -43,6 +43,7 @@ class Diff extends BaseCommand { 'tag', 'workspace', 'workspaces', + 'include-workspace-root', ] } diff --git a/lib/dist-tag.js b/lib/dist-tag.js index e32dcf61f..be44f39ff 100644 --- a/lib/dist-tag.js +++ b/lib/dist-tag.js @@ -14,7 +14,7 @@ class DistTag extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['workspace', 'workspaces'] + return ['workspace', 'workspaces', 'include-workspace-root'] } /* istanbul ignore next - see test/lib/load-all-commands.js */ diff --git a/lib/docs.js b/lib/docs.js index 69a19c35c..51f8be388 100644 --- a/lib/docs.js +++ b/lib/docs.js @@ -17,7 +17,13 @@ class Docs extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['browser', 'registry', 'workspace', 'workspaces'] + return [ + 'browser', + 'registry', + 'workspace', + 'workspaces', + 'include-workspace-root', + ] } /* istanbul ignore next - see test/lib/load-all-commands.js */ diff --git a/lib/exec.js b/lib/exec.js index 8c64c2f24..d11947483 100644 --- a/lib/exec.js +++ b/lib/exec.js @@ -35,7 +35,13 @@ class Exec extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['package', 'call', 'workspace', 'workspaces'] + return [ + 'package', + 'call', + 'workspace', + 'workspaces', + 'include-workspace-root', + ] } /* istanbul ignore next - see test/lib/load-all-commands.js */ diff --git a/lib/explain.js b/lib/explain.js index 7d785d7bf..fc7f57891 100644 --- a/lib/explain.js +++ b/lib/explain.js @@ -46,8 +46,15 @@ class Explain extends ArboristWorkspaceCmd { const arb = new Arborist({ path: this.npm.prefix, ...this.npm.flatOptions }) const tree = await arb.loadActual() - if (this.workspaceNames && this.workspaceNames.length) + if (this.npm.flatOptions.workspacesEnabled + && this.workspaceNames + && this.workspaceNames.length + ) this.filterSet = arb.workspaceDependencySet(tree, this.workspaceNames) + else if (!this.npm.flatOptions.workspacesEnabled) { + this.filterSet = + arb.excludeWorkspacesDependencySet(tree) + } const nodes = new Set() for (const arg of args) { diff --git a/lib/fund.js b/lib/fund.js index 1e0fa1ecb..97139f5bb 100644 --- a/lib/fund.js +++ b/lib/fund.js @@ -92,6 +92,7 @@ class Fund extends ArboristWorkspaceCmd { return } + // TODO: add !workspacesEnabled option handling to libnpmfund const fundingInfo = getFundingInfo(tree, { ...this.flatOptions, log: this.npm.log, diff --git a/lib/init.js b/lib/init.js index e4bd20b72..30fd7e2f7 100644 --- a/lib/init.js +++ b/lib/init.js @@ -54,6 +54,10 @@ class Init extends BaseCommand { } async initWorkspaces (args, filters) { + // if the root package is uninitiated, take care of it first + if (this.npm.flatOptions.includeWorkspaceRoot) + await this.init(args) + // reads package.json for the top-level folder first, by doing this we // ensure the command throw if no package.json is found before trying // to create a workspace package.json file or its folders diff --git a/lib/link.js b/lib/link.js index febd90871..2437eb12e 100644 --- a/lib/link.js +++ b/lib/link.js @@ -185,6 +185,7 @@ class Link extends ArboristWorkspaceCmd { // atm but should be simple once we have a mocked registry again if (arg.name !== node.name /* istanbul ignore next */ || ( arg.version && + /* istanbul ignore next */ !semver.satisfies(node.version, arg.version) )) { foundNodes.push(node) @@ -82,6 +82,7 @@ class LS extends ArboristWorkspaceCmd { const production = this.npm.config.get('production') const unicode = this.npm.config.get('unicode') const packageLockOnly = this.npm.config.get('package-lock-only') + const workspacesEnabled = this.npm.flatOptions.workspacesEnabled const path = global ? resolve(this.npm.globalDir, '..') : this.npm.prefix @@ -100,12 +101,18 @@ class LS extends ArboristWorkspaceCmd { if (this.workspaceNames && this.workspaceNames.length) wsNodes = arb.workspaceNodes(tree, this.workspaceNames) const filterBySelectedWorkspaces = edge => { + if (!workspacesEnabled + && edge.from.isProjectRoot + && edge.to.isWorkspace + ) + return false + if (!wsNodes || !wsNodes.length) return true if (edge.from.isProjectRoot) { return edge.to && - edge.to.isWorkspace & + edge.to.isWorkspace && wsNodes.includes(edge.to.target) } diff --git a/lib/npm.js b/lib/npm.js index 966d11210..9b9f3b238 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -137,7 +137,19 @@ const npm = module.exports = new class extends EventEmitter { const workspacesEnabled = this.config.get('workspaces') const workspacesFilters = this.config.get('workspace') + if (workspacesEnabled === false && workspacesFilters.length > 0) + return cb(new Error('Can not use --no-workspaces and --workspace at the same time')) + const filterByWorkspaces = workspacesEnabled || workspacesFilters.length > 0 + // normally this would go in the constructor, but our tests don't + // actually use a real npm object so this.npm.config isn't always + // populated. this is the compromise until we can make that a reality + // and then move this into the constructor. + impl.workspaces = this.config.get('workspaces') + impl.workspacePaths = null + // normally this would be evaluated in base-command#setWorkspaces, see + // above for explanation + impl.includeWorkspaceRoot = this.config.get('include-workspace-root') if (this.config.get('usage')) { this.output(impl.usage) diff --git a/lib/outdated.js b/lib/outdated.js index b3b630421..ab46b4536 100644 --- a/lib/outdated.js +++ b/lib/outdated.js @@ -62,7 +62,14 @@ class Outdated extends ArboristWorkspaceCmd { if (this.workspaceNames && this.workspaceNames.length) { this.filterSet = - arb.workspaceDependencySet(this.tree, this.workspaceNames) + arb.workspaceDependencySet( + this.tree, + this.workspaceNames, + this.npm.flatOptions.includeWorkspaceRoot + ) + } else if (!this.npm.flatOptions.workspacesEnabled) { + this.filterSet = + arb.excludeWorkspacesDependencySet(this.tree) } if (args.length !== 0) { diff --git a/lib/pack.js b/lib/pack.js index 8fc89db1a..848f8afd5 100644 --- a/lib/pack.js +++ b/lib/pack.js @@ -30,6 +30,7 @@ class Pack extends BaseCommand { 'pack-destination', 'workspace', 'workspaces', + 'include-workspace-root', ] } diff --git a/lib/publish.js b/lib/publish.js index 9c747eb50..32e70129f 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -36,7 +36,15 @@ class Publish extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['tag', 'access', 'dry-run', 'otp', 'workspace', 'workspaces'] + return [ + 'tag', + 'access', + 'dry-run', + 'otp', + 'workspace', + 'workspaces', + 'include-workspace-root', + ] } /* istanbul ignore next - see test/lib/load-all-commands.js */ diff --git a/lib/repo.js b/lib/repo.js index e0172d01f..bf1d1e7ff 100644 --- a/lib/repo.js +++ b/lib/repo.js @@ -19,7 +19,7 @@ class Repo extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['browser', 'workspace', 'workspaces'] + return ['browser', 'workspace', 'workspaces', 'include-workspace-root'] } /* istanbul ignore next - see test/lib/load-all-commands.js */ @@ -48,7 +48,13 @@ class Repo extends BaseCommand { } async get (pkg) { - const opts = { ...this.npm.flatOptions, fullMetadata: true } + // XXX It is very odd that `where` is how pacote knows to look anywhere + // other than the cwd. + const opts = { + ...this.npm.flatOptions, + where: this.npm.localPrefix, + fullMetadata: true, + } const mani = await pacote.manifest(pkg, opts) const r = mani.repository diff --git a/lib/run-script.js b/lib/run-script.js index 1daaeb990..de847ff28 100644 --- a/lib/run-script.js +++ b/lib/run-script.js @@ -38,6 +38,7 @@ class RunScript extends BaseCommand { return [ 'workspace', 'workspaces', + 'include-workspace-root', 'if-present', 'ignore-scripts', 'script-shell', diff --git a/lib/set-script.js b/lib/set-script.js index 24e4d8f20..185c4cc90 100644 --- a/lib/set-script.js +++ b/lib/set-script.js @@ -12,7 +12,7 @@ class SetScript extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return ['workspace', 'workspaces'] + return ['workspace', 'workspaces', 'include-workspace-root'] } /* istanbul ignore next - see test/lib/load-all-commands.js */ diff --git a/lib/utils/completion/installed-deep.js b/lib/utils/completion/installed-deep.js index 590955a1e..62686f9b2 100644 --- a/lib/utils/completion/installed-deep.js +++ b/lib/utils/completion/installed-deep.js @@ -7,6 +7,7 @@ const installedDeep = async (npm) => { depth, global, prefix, + workspacesEnabled, } = npm.flatOptions const getValues = (tree) => @@ -19,14 +20,18 @@ const installedDeep = async (npm) => { .sort((a, b) => (a.depth - b.depth) || localeCompare(a.name, b.name)) const res = new Set() - const gArb = new Arborist({ global: true, path: resolve(npm.globalDir, '..') }) + const gArb = new Arborist({ + global: true, + path: resolve(npm.globalDir, '..'), + workspacesEnabled, + }) const gTree = await gArb.loadActual({ global: true }) for (const node of getValues(gTree)) res.add(global ? node.name : [node.name, '-g']) if (!global) { - const arb = new Arborist({ global: false, path: prefix }) + const arb = new Arborist({ global: false, path: prefix, workspacesEnabled }) const tree = await arb.loadActual() for (const node of getValues(tree)) res.add(node.name) diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js index 009f60a7b..57a50d1c8 100644 --- a/lib/utils/config/definitions.js +++ b/lib/utils/config/definitions.js @@ -918,6 +918,19 @@ define('include-staged', { flatten, }) +define('include-workspace-root', { + default: false, + type: Boolean, + description: ` + Include the workspace root when workspaces are enabled for a command. + + When false, specifying individual workspaces via the \`workspace\` config, + or all workspaces via the \`workspaces\` flag, will cause npm to operate only + on the specified workspaces, and not on the root project. + `, + flatten, +}) + define('init-author-email', { default: '', type: String, @@ -2137,8 +2150,8 @@ define('workspace', { * Workspace names * Path to a workspace directory - * Path to a parent workspace directory (will result to selecting all of the - nested workspaces) + * Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the \`npm init\` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it @@ -2150,16 +2163,34 @@ define('workspace', { }) define('workspaces', { - default: false, - type: Boolean, + default: null, + type: [null, Boolean], short: 'ws', envExport: false, description: ` - Enable running a command in the context of **all** the configured + Set to true to run the command in the context of **all** configured workspaces. + + Explicitly setting this to false will cause commands like \`install\` to + ignore workspaces altogether. + When not set explicitly: + + - Commands that operate on the \`node_modules\` tree (install, update, + etc.) will link workspaces into the \`node_modules\` folder. + - Commands that do other things (test, exec, publish, etc.) will operate + on the root project, _unless_ one or more workspaces are specified in + the \`workspace\` config. `, flatten: (key, obj, flatOptions) => { definitions['user-agent'].flatten('user-agent', obj, flatOptions) + + // TODO: this is a derived value, and should be reworked when we have a + // pattern for derived value + + // workspacesEnabled is true whether workspaces is null or true + // commands contextually work with workspaces or not regardless of + // configuration, so we need an option specifically to disable workspaces + flatOptions.workspacesEnabled = obj[key] !== false }, }) diff --git a/lib/version.js b/lib/version.js index f3680fe8b..917a64747 100644 --- a/lib/version.js +++ b/lib/version.js @@ -26,6 +26,7 @@ class Version extends BaseCommand { 'sign-git-tag', 'workspace', 'workspaces', + 'include-workspace-root', ] } diff --git a/lib/view.js b/lib/view.js index 0124bfb7d..46b1b5edf 100644 --- a/lib/view.js +++ b/lib/view.js @@ -31,6 +31,7 @@ class View extends BaseCommand { 'json', 'workspace', 'workspaces', + 'include-workspace-root', ] } diff --git a/lib/workspaces/arborist-cmd.js b/lib/workspaces/arborist-cmd.js index cb6b66b8c..a75b351be 100644 --- a/lib/workspaces/arborist-cmd.js +++ b/lib/workspaces/arborist-cmd.js @@ -4,16 +4,21 @@ const BaseCommand = require('../base-command.js') class ArboristCmd extends BaseCommand { + get isArboristCmd () { + return true + } + /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { return [ 'workspace', 'workspaces', + 'include-workspace-root', ] } execWorkspaces (args, filters, cb) { - this.setWorkspaces(filters) + this.setWorkspaces(filters, true) .then(() => { this.exec(args, cb) }) diff --git a/lib/workspaces/get-workspaces.js b/lib/workspaces/get-workspaces.js index 91b007455..3eb8e4865 100644 --- a/lib/workspaces/get-workspaces.js +++ b/lib/workspaces/get-workspaces.js @@ -5,11 +5,16 @@ const rpj = require('read-package-json-fast') // Returns an Map of paths to workspaces indexed by workspace name // { foo => '/path/to/foo' } -const getWorkspaces = async (filters, { path }) => { +const getWorkspaces = async (filters, { path, includeWorkspaceRoot }) => { // TODO we need a better error to be bubbled up here if this rpj call fails const pkg = await rpj(resolve(path, 'package.json')) const workspaces = await mapWorkspaces({ cwd: path, pkg }) - const res = filters.length ? new Map() : workspaces + let res = new Map() + if (includeWorkspaceRoot) + res.set(pkg.name, path) + + if (!filters.length) + res = new Map([...res, ...workspaces]) for (const filterArg of filters) { for (const [workspaceName, workspacePath] of workspaces.entries()) { diff --git a/package-lock.json b/package-lock.json index b8decbc1a..ec78e50f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "npm", "version": "7.24.1", "bundleDependencies": [ + "@isaacs/string-locale-compare", "@npmcli/arborist", "@npmcli/ci-detect", "@npmcli/config", diff --git a/package.json b/package.json index 31083ff0b..f4cde1d17 100644 --- a/package.json +++ b/package.json @@ -125,6 +125,7 @@ "write-file-atomic": "^3.0.3" }, "bundleDependencies": [ + "@isaacs/string-locale-compare", "@npmcli/arborist", "@npmcli/ci-detect", "@npmcli/config", diff --git a/tap-snapshots/test/lib/config.js.test.cjs b/tap-snapshots/test/lib/config.js.test.cjs index b21b75cd2..805370351 100644 --- a/tap-snapshots/test/lib/config.js.test.cjs +++ b/tap-snapshots/test/lib/config.js.test.cjs @@ -68,6 +68,7 @@ exports[`test/lib/config.js TAP config list --json > output matches snapshot 1`] "ignore-scripts": false, "include": [], "include-staged": false, + "include-workspace-root": false, "init-author-email": "", "init-author-name": "", "init-author-url": "", @@ -152,7 +153,7 @@ exports[`test/lib/config.js TAP config list --json > output matches snapshot 1`] "viewer": "{VIEWER}", "which": null, "workspace": [], - "workspaces": false, + "workspaces": null, "yes": null, "metrics-registry": "https://registry.npmjs.org/" } @@ -217,6 +218,7 @@ if-present = false ignore-scripts = false include = [] include-staged = false +include-workspace-root = false init-author-email = "" init-author-name = "" init-author-url = "" @@ -303,7 +305,7 @@ versions = false viewer = "{VIEWER}" which = null workspace = [] -workspaces = false +workspaces = null yes = null ; "global" config from {GLOBALPREFIX}/npmrc diff --git a/tap-snapshots/test/lib/dist-tag.js.test.cjs b/tap-snapshots/test/lib/dist-tag.js.test.cjs index 21d9331db..f651f7b67 100644 --- a/tap-snapshots/test/lib/dist-tag.js.test.cjs +++ b/tap-snapshots/test/lib/dist-tag.js.test.cjs @@ -18,7 +18,7 @@ npm dist-tag ls [<pkg>] Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: dist-tags @@ -40,7 +40,7 @@ npm dist-tag ls [<pkg>] Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: dist-tags @@ -71,7 +71,7 @@ npm dist-tag ls [<pkg>] Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: dist-tags @@ -93,7 +93,7 @@ npm dist-tag ls [<pkg>] Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: dist-tags @@ -121,7 +121,7 @@ npm dist-tag ls [<pkg>] Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: dist-tags @@ -179,7 +179,7 @@ npm dist-tag ls [<pkg>] Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: dist-tags diff --git a/tap-snapshots/test/lib/init.js.test.cjs b/tap-snapshots/test/lib/init.js.test.cjs index 95abbe6c1..37ad8c3a8 100644 --- a/tap-snapshots/test/lib/init.js.test.cjs +++ b/tap-snapshots/test/lib/init.js.test.cjs @@ -5,6 +5,10 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' +exports[`test/lib/init.js TAP npm init workspces with root > should print helper info 1`] = ` +Array [] +` + exports[`test/lib/init.js TAP workspaces no args > should print helper info 1`] = ` Array [ Array [ diff --git a/tap-snapshots/test/lib/load-all-commands.js.test.cjs b/tap-snapshots/test/lib/load-all-commands.js.test.cjs index 9f811a005..d287d1284 100644 --- a/tap-snapshots/test/lib/load-all-commands.js.test.cjs +++ b/tap-snapshots/test/lib/load-all-commands.js.test.cjs @@ -56,7 +56,7 @@ Options: [--json] [--package-lock-only] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] Run "npm help audit" for more info ` @@ -173,7 +173,7 @@ Options: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: ddp @@ -208,7 +208,7 @@ Options: [--diff-no-prefix] [--diff-src-prefix <path>] [--diff-dst-prefix <path>] [--diff-text] [-g|--global] [--tag <tag>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] Run "npm help diff" for more info ` @@ -225,7 +225,7 @@ npm dist-tag ls [<pkg>] Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: dist-tags @@ -243,7 +243,7 @@ npm docs [<pkgname> [<pkgname> ...]] Options: [--no-browser|--browser <browser>] [--registry <registry>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: home @@ -293,7 +293,7 @@ Options: [--package <pkg>[@<version>] [--package <pkg>[@<version>] ...]] [-c|--call <call>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: x @@ -343,7 +343,7 @@ Options: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] Run "npm help find-dupes" for more info ` @@ -452,7 +452,7 @@ Options: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] aliases: i, in, ins, inst, insta, instal, isnt, isnta, isntal, add @@ -499,7 +499,7 @@ Options: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: it @@ -522,7 +522,7 @@ Options: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: ln @@ -542,7 +542,7 @@ Options: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--link] [--package-lock-only] [--unicode] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: la @@ -592,7 +592,7 @@ Options: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--link] [--package-lock-only] [--unicode] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: list @@ -661,7 +661,7 @@ npm pack [[<@scope>/]<pkg>...] Options: [--dry-run] [--json] [--pack-destination <pack-destination>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] Run "npm help pack" for more info ` @@ -740,7 +740,7 @@ npm prune [[<@scope>/]<pkg>...] Options: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--dry-run] [--json] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] Run "npm help prune" for more info ` @@ -756,7 +756,7 @@ npm publish [<folder>] Options: [--tag <tag>] [--access <restricted|public>] [--dry-run] [--otp <otp>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] Run "npm help publish" for more info ` @@ -772,7 +772,7 @@ npm rebuild [[<@scope>/]<name>[@<version>] ...] Options: [-g|--global] [--no-bin-links] [--ignore-scripts] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: rb @@ -790,7 +790,7 @@ npm repo [<pkgname> [<pkgname> ...]] Options: [--no-browser|--browser <browser>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] Run "npm help repo" for more info ` @@ -833,7 +833,7 @@ npm run-script <command> [-- <args>] Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] [--if-present] [--ignore-scripts] +[-ws|--workspaces] [--include-workspace-root] [--if-present] [--ignore-scripts] [--script-shell <script-shell>] aliases: run, rum, urn @@ -880,7 +880,7 @@ npm set-script [<script>] [<command>] Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] Run "npm help set-script" for more info ` @@ -1014,7 +1014,7 @@ npm uninstall [<@scope>/]<pkg>... Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] aliases: un, unlink, remove, rm, r @@ -1064,7 +1064,7 @@ Options: [--no-package-lock] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] aliases: up, upgrade, udpate @@ -1083,7 +1083,7 @@ Options: [--allow-same-version] [--no-commit-hooks] [--no-git-tag-version] [--json] [--preid prerelease-id] [--sign-git-tag] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] alias: verison @@ -1100,7 +1100,7 @@ npm view [<@scope>/]<pkg>[@<version>] [<field>[.subfield]...] Options: [--json] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] aliases: v, info, show diff --git a/tap-snapshots/test/lib/ls.js.test.cjs b/tap-snapshots/test/lib/ls.js.test.cjs index c3d0a8764..c550f447c 100644 --- a/tap-snapshots/test/lib/ls.js.test.cjs +++ b/tap-snapshots/test/lib/ls.js.test.cjs @@ -547,6 +547,12 @@ exports[`test/lib/ls.js TAP ls loading a tree containing workspaces > should lis [0m[0m ` +exports[`test/lib/ls.js TAP ls loading a tree containing workspaces > should not list workspaces with --no-workspaces 1`] = ` +[0mworkspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces[0m +[0m\`-- (empty)[0m +[0m[0m +` + exports[`test/lib/ls.js TAP ls loading a tree containing workspaces > should print all tree and filter by dep within only the ws subtree 1`] = ` workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces \`-- d@1.0.0 -> ./d diff --git a/tap-snapshots/test/lib/outdated.js.test.cjs b/tap-snapshots/test/lib/outdated.js.test.cjs index 9f589d013..2f5c164f4 100644 --- a/tap-snapshots/test/lib/outdated.js.test.cjs +++ b/tap-snapshots/test/lib/outdated.js.test.cjs @@ -192,6 +192,14 @@ exports[`test/lib/outdated.js TAP workspaces > should display no results if ws h ` +exports[`test/lib/outdated.js TAP workspaces > should display only root outdated when ws disabled 1`] = ` + +` + +exports[`test/lib/outdated.js TAP workspaces > should display only root outdated when ws disabled 2`] = ` + +` + exports[`test/lib/outdated.js TAP workspaces > should display parseable results filtered by ws 1`] = ` {CWD}/test/lib/tap-testdir-outdated-workspaces/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:a diff --git a/tap-snapshots/test/lib/publish.js.test.cjs b/tap-snapshots/test/lib/publish.js.test.cjs index 13e8f7d4b..f028494b9 100644 --- a/tap-snapshots/test/lib/publish.js.test.cjs +++ b/tap-snapshots/test/lib/publish.js.test.cjs @@ -53,7 +53,7 @@ npm publish [<folder>] Options: [--tag <tag>] [--access <restricted|public>] [--dry-run] [--otp <otp>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] -[-ws|--workspaces] +[-ws|--workspaces] [--include-workspace-root] Run "npm help publish" for more info { "code": "EUSAGE", diff --git a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs index 9d5fe79af..fcfec5941 100644 --- a/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs @@ -63,6 +63,7 @@ Array [ "ignore-scripts", "include", "include-staged", + "include-workspace-root", "init-author-email", "init-author-name", "init-author-url", @@ -831,6 +832,19 @@ Allow installing "staged" published packages, as defined by [npm RFC PR This is experimental, and not implemented by the npm public registry. ` +exports[`test/lib/utils/config/definitions.js TAP > config description for include-workspace-root 1`] = ` +#### \`include-workspace-root\` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the \`workspace\` config, or +all workspaces via the \`workspaces\` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. +` + exports[`test/lib/utils/config/definitions.js TAP > config description for init-author-email 1`] = ` #### \`init-author-email\` @@ -1839,8 +1853,8 @@ Valid values for the \`workspace\` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the \`npm init\` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -1852,12 +1866,20 @@ This value is not exported to the environment for child processes. exports[`test/lib/utils/config/definitions.js TAP > config description for workspaces 1`] = ` #### \`workspaces\` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like \`install\` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the \`node_modules\` tree (install, update, etc.) +will link workspaces into the \`node_modules\` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the \`workspace\` config. + This value is not exported to the environment for child processes. ` diff --git a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs index 4e3efb916..ff401d0d7 100644 --- a/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs +++ b/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs @@ -680,6 +680,20 @@ This is experimental, and not implemented by the npm public registry. <!-- automatically generated, do not edit manually --> <!-- see lib/utils/config/definitions.js --> +#### \`include-workspace-root\` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the \`workspace\` config, or +all workspaces via the \`workspaces\` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +<!-- automatically generated, do not edit manually --> +<!-- see lib/utils/config/definitions.js --> + #### \`init-author-email\` * Default: "" @@ -1618,8 +1632,8 @@ Valid values for the \`workspace\` config are either: * Workspace names * Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) When set for the \`npm init\` command, this may be set to the folder of a workspace which does not yet exist, to create the folder and set it up as a @@ -1632,12 +1646,20 @@ This value is not exported to the environment for child processes. #### \`workspaces\` -* Default: false -* Type: Boolean +* Default: null +* Type: null or Boolean -Enable running a command in the context of **all** the configured +Set to true to run the command in the context of **all** configured workspaces. +Explicitly setting this to false will cause commands like \`install\` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the \`node_modules\` tree (install, update, etc.) +will link workspaces into the \`node_modules\` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the \`workspace\` config. + This value is not exported to the environment for child processes. <!-- automatically generated, do not edit manually --> diff --git a/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs b/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs index 0fd36c7c1..0273adf99 100644 --- a/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs +++ b/tap-snapshots/test/lib/utils/npm-usage.js.test.cjs @@ -211,7 +211,7 @@ All commands: [--json] [--package-lock-only] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] Run "npm help audit" for more info @@ -314,7 +314,7 @@ All commands: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: ddp @@ -345,7 +345,7 @@ All commands: [--diff-no-prefix] [--diff-src-prefix <path>] [--diff-dst-prefix <path>] [--diff-text] [-g|--global] [--tag <tag>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] Run "npm help diff" for more info @@ -360,7 +360,7 @@ All commands: Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: dist-tags @@ -376,7 +376,7 @@ All commands: Options: [--no-browser|--browser <browser>] [--registry <registry>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: home @@ -420,7 +420,7 @@ All commands: [--package <pkg>[@<version>] [--package <pkg>[@<version>] ...]] [-c|--call <call>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: x @@ -464,7 +464,7 @@ All commands: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] Run "npm help find-dupes" for more info @@ -561,7 +561,7 @@ All commands: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] aliases: i, in, ins, inst, insta, instal, isnt, isnta, isntal, add @@ -604,7 +604,7 @@ All commands: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: it @@ -625,7 +625,7 @@ All commands: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: ln @@ -643,7 +643,7 @@ All commands: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--link] [--package-lock-only] [--unicode] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: la @@ -687,7 +687,7 @@ All commands: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--link] [--package-lock-only] [--unicode] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: list @@ -748,7 +748,7 @@ All commands: Options: [--dry-run] [--json] [--pack-destination <pack-destination>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] Run "npm help pack" for more info @@ -817,7 +817,7 @@ All commands: Options: [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--dry-run] [--json] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] Run "npm help prune" for more info @@ -831,7 +831,7 @@ All commands: Options: [--tag <tag>] [--access <restricted|public>] [--dry-run] [--otp <otp>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] Run "npm help publish" for more info @@ -845,7 +845,7 @@ All commands: Options: [-g|--global] [--no-bin-links] [--ignore-scripts] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: rb @@ -861,7 +861,7 @@ All commands: Options: [--no-browser|--browser <browser>] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] Run "npm help repo" for more info @@ -898,7 +898,7 @@ All commands: Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] [--if-present] [--ignore-scripts] + [-ws|--workspaces] [--include-workspace-root] [--if-present] [--ignore-scripts] [--script-shell <script-shell>] aliases: run, rum, urn @@ -939,7 +939,7 @@ All commands: Options: [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] Run "npm help set-script" for more info @@ -1055,7 +1055,7 @@ All commands: Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] aliases: un, unlink, remove, rm, r @@ -1099,7 +1099,7 @@ All commands: [--no-package-lock] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] aliases: up, upgrade, udpate @@ -1116,7 +1116,7 @@ All commands: [--allow-same-version] [--no-commit-hooks] [--no-git-tag-version] [--json] [--preid prerelease-id] [--sign-git-tag] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] alias: verison @@ -1131,7 +1131,7 @@ All commands: Options: [--json] [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]] - [-ws|--workspaces] + [-ws|--workspaces] [--include-workspace-root] aliases: v, info, show diff --git a/test/lib/explain.js b/test/lib/explain.js index f690aeb2c..ebec13619 100644 --- a/test/lib/explain.js +++ b/test/lib/explain.js @@ -2,7 +2,7 @@ const t = require('tap') const npm = { prefix: null, color: true, - flatOptions: {}, + flatOptions: { workspacesEnabled: true }, output: (...args) => { OUTPUT.push(args) }, @@ -301,3 +301,80 @@ t.test('workspaces', async t => { }) }) }) + +t.test('workspaces disabled', async t => { + npm.localPrefix = npm.prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'workspaces-project', + version: '1.0.0', + workspaces: ['packages/*'], + dependencies: { + abbrev: '^1.0.0', + }, + }), + node_modules: { + a: t.fixture('symlink', '../packages/a'), + b: t.fixture('symlink', '../packages/b'), + c: t.fixture('symlink', '../packages/c'), + once: { + 'package.json': JSON.stringify({ + name: 'once', + version: '1.0.0', + dependencies: { + wrappy: '2.0.0', + }, + }), + }, + abbrev: { + 'package.json': JSON.stringify({ + name: 'abbrev', + version: '1.0.0', + }), + }, + wrappy: { + 'package.json': JSON.stringify({ + name: 'wrappy', + version: '2.0.0', + }), + }, + }, + packages: { + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + dependencies: { + once: '1.0.0', + }, + }), + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + dependencies: { + abbrev: '^1.0.0', + }, + }), + }, + c: { + 'package.json': JSON.stringify({ + name: 'c', + version: '1.0.0', + }), + }, + }, + }) + + await new Promise((res, rej) => { + explain.npm.flatOptions.workspacesEnabled = false + explain.exec(['once'], err => { + t.equal( + err, + 'No dependencies found matching once', + 'should throw usage if dep not found when excluding ws' + ) + res() + }) + }) +}) diff --git a/test/lib/init.js b/test/lib/init.js index 1cefb1fc9..20699d879 100644 --- a/test/lib/init.js +++ b/test/lib/init.js @@ -513,3 +513,26 @@ t.test('workspaces', t => { t.end() }) +t.test('npm init workspces with root', t => { + t.teardown(() => { + npm._mockOutputs.length = 0 + }) + npm.localPrefix = t.testdir({}) + npm.flatOptions.includeWorkspaceRoot = true + + // init-package-json prints directly to console.log + // this avoids poluting test output with those logs + console.log = noop + + process.chdir(npm.localPrefix) + init.execWorkspaces([], ['packages/a'], err => { + if (err) + throw err + + const pkg = require(resolve(npm.localPrefix, 'package.json')) + t.equal(pkg.version, '1.0.0') + t.equal(pkg.license, 'ISC') + t.matchSnapshot(npm._mockOutputs, 'should print helper info') + t.end() + }) +}) diff --git a/test/lib/ls.js b/test/lib/ls.js index 5f196501e..46dfd7fba 100644 --- a/test/lib/ls.js +++ b/test/lib/ls.js @@ -110,6 +110,7 @@ const config = { 'package-lock-only': false, } const flatOptions = { + workspacesEnabled: true, } const npm = mockNpm({ config, @@ -1530,6 +1531,25 @@ t.test('ls', (t) => { }) }) + await new Promise((res, rej) => { + config.all = false + config.depth = 0 + npm.color = true + npm.flatOptions.workspacesEnabled = false + ls.exec([], (err) => { + if (err) + rej(err) + + t.matchSnapshot(redactCwd(result), + 'should not list workspaces with --no-workspaces') + config.all = true + config.depth = Infinity + npm.color = false + npm.flatOptions.workspacesEnabled = true + res() + }) + }) + // --all await new Promise((res, rej) => { ls.exec([], (err) => { diff --git a/test/lib/npm.js b/test/lib/npm.js index 03bb46d8d..aa31147fa 100644 --- a/test/lib/npm.js +++ b/test/lib/npm.js @@ -292,6 +292,44 @@ t.test('npm.load', t => { await new Promise((res) => setTimeout(res)) }) + t.test('--no-workspaces with --workspace', async t => { + const dir = t.testdir({ + packages: { + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + scripts: { test: 'echo test a' }, + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'root', + version: '1.0.0', + workspaces: ['./packages/*'], + }), + }) + process.argv = [ + process.execPath, + process.argv[1], + '--userconfig', resolve(dir, '.npmrc'), + '--color', 'false', + '--workspaces', 'false', + '--workspace', 'a', + ] + const { npm } = mockNpm(t) + await npm.load() + npm.localPrefix = dir + await new Promise((res, rej) => { + npm.commands.run([], er => { + if (!er) + return rej(new Error('Expected an error')) + t.match(er.message, 'Can not use --no-workspaces and --workspace at the same time') + res() + }) + }) + }) + t.test('workspace-aware configs and commands', async t => { const dir = t.testdir({ packages: { diff --git a/test/lib/outdated.js b/test/lib/outdated.js index 518436d0a..76e97ff52 100644 --- a/test/lib/outdated.js +++ b/test/lib/outdated.js @@ -83,6 +83,10 @@ const globalDir = t.testdir({ }, }) +const flatOptions = { + workspacesEnabled: true, +} + const outdated = (dir, opts) => { logs = '' const Outdated = t.mock('../../lib/outdated.js', { @@ -94,6 +98,7 @@ const outdated = (dir, opts) => { ...opts, localPrefix: dir, prefix: dir, + flatOptions, globalDir: `${globalDir}/node_modules`, output, }) @@ -562,6 +567,30 @@ t.test('workspaces', async t => { }) await new Promise((res, rej) => { + flatOptions.workspacesEnabled = false + outdated(testDir, {}).exec([], err => { + if (err) + rej(err) + + t.matchSnapshot(logs, 'should display only root outdated when ws disabled') + flatOptions.workspacesEnabled = true + res() + }) + }) + + await new Promise((res, rej) => { + flatOptions.workspacesEnabled = false + outdated(testDir, {}).exec([], err => { + if (err) + rej(err) + + t.matchSnapshot(logs, 'should display only root outdated when ws disabled') + flatOptions.workspacesEnabled = true + res() + }) + }) + + await new Promise((res, rej) => { outdated(testDir, { config: { json: true, diff --git a/test/lib/publish.js b/test/lib/publish.js index 6e0075835..8e5a853c4 100644 --- a/test/lib/publish.js +++ b/test/lib/publish.js @@ -61,6 +61,7 @@ t.test('should publish with libnpmpublish, passing through flatOptions and respe const npm = mockNpm({ flatOptions: { customValue: true, + workspacesEnabled: true, }, }) npm.config.getCredentialsByURI = (uri) => { diff --git a/test/lib/repo.js b/test/lib/repo.js index e1ac90b1e..41bff2744 100644 --- a/test/lib/repo.js +++ b/test/lib/repo.js @@ -1,5 +1,5 @@ const t = require('tap') -const { fake: mockNpm } = require('../fixtures/mock-npm.js') +const { real: mockNpm } = require('../fixtures/mock-npm.js') const { join, sep } = require('path') const pkgDirs = t.testdir({ @@ -154,6 +154,7 @@ const pkgDirs = t.testdir({ name: 'workspaces-test', version: '1.2.3-test', workspaces: ['workspace-a', 'workspace-b', 'workspace-c'], + repository: 'https://github.com/npm/workspaces-test', }), 'workspace-a': { 'package.json': JSON.stringify({ @@ -185,19 +186,17 @@ const openUrl = async (npm, url, errMsg) => { opened[url]++ } -const Repo = t.mock('../../lib/repo.js', { +const { command, npm } = mockNpm(t, { '../../lib/utils/open-url.js': openUrl, }) -const flatOptions = {} -const npm = mockNpm({ flatOptions }) -const repo = new Repo(npm) +t.before(async () => { + await npm.load() +}) t.afterEach(() => opened = {}) t.test('open repo urls', t => { - // XXX It is very odd that `where` is how pacote knows to look anywhere other - // than the cwd. I would think npm.localPrefix would factor in somehow - flatOptions.where = pkgDirs + npm.localPrefix = pkgDirs const expect = { hostedgit: 'https://github.com/foo/hostedgit', hostedgitat: 'https://github.com/foo/hostedgitat', @@ -227,22 +226,19 @@ t.test('open repo urls', t => { const keys = Object.keys(expect) t.plan(keys.length) keys.forEach(pkg => { - t.test(pkg, t => { - repo.exec([['.', pkg].join(sep)], (err) => { - if (err) - throw err - const url = expect[pkg] - t.match({ - [url]: 1, - }, opened, `opened ${url}`, {opened}) - t.end() - }) + t.test(pkg, async t => { + await command('repo', [['.', pkg].join(sep)]) + const url = expect[pkg] + t.match({ + [url]: 1, + }, opened, `opened ${url}`, {opened}) + t.end() }) }) }) t.test('fail if cannot figure out repo url', t => { - flatOptions.where = pkgDirs + npm.localPrefix = pkgDirs const cases = [ 'norepo', 'repoobbj-nourl', @@ -253,57 +249,65 @@ t.test('fail if cannot figure out repo url', t => { t.plan(cases.length) cases.forEach(pkg => { - t.test(pkg, t => { - repo.exec([['.', pkg].join(sep)], (err) => { - t.match(err, { pkgid: pkg }) - t.end() - }) + t.test(pkg, async t => { + t.rejects( + command('repo', [['.', pkg].join(sep)]), + { pkgid: pkg } + ) }) }) }) -t.test('open default package if none specified', t => { - flatOptions.where = pkgDirs - repo.exec([], (er) => { - if (er) - throw er - t.equal(opened['https://example.com/thispkg'], 1, 'opened expected url', {opened}) - t.end() - }) +t.test('open default package if none specified', async t => { + npm.localPrefix = pkgDirs + await command('repo', []) + t.equal(opened['https://example.com/thispkg'], 1, 'opened expected url', {opened}) }) t.test('workspaces', t => { - flatOptions.where = undefined npm.localPrefix = join(pkgDirs, 'workspaces') - t.test('all workspaces', (t) => { - repo.execWorkspaces([], [], (err) => { - t.notOk(err) - t.match({ - 'https://repo.workspace-a/': 1, // Gets translated to https! - 'https://github.com/npm/workspace-b': 1, - }, opened, 'opened two valid repo urls') - t.end() - }) + t.afterEach(() => { + npm.config.set('workspaces', null) + npm.config.set('workspace', []) + npm.config.set('include-workspace-root', false) }) - t.test('one workspace', (t) => { - repo.execWorkspaces([], ['workspace-a'], (err) => { - t.notOk(err) - t.match({ - 'https://repo.workspace-a/': 1, - }, opened, 'opened one requested repo urls') - t.end() - }) + t.test('include workspace root', async (t) => { + npm.config.set('workspaces', true) + npm.config.set('include-workspace-root', true) + await command('repo', []) + t.match({ + 'https://github.com/npm/workspaces-test': 1, + 'https://repo.workspace-a/': 1, // Gets translated to https! + 'https://github.com/npm/workspace-b': 1, + }, opened, 'opened two valid repo urls') }) - t.test('invalid workspace', (t) => { - repo.execWorkspaces([], ['workspace-x'], (err) => { - t.match(err, /No workspaces found/) - t.match(err, /workspace-x/) - t.match({}, opened, 'opened no repo urls') - t.end() - }) + t.test('all workspaces', async (t) => { + npm.config.set('workspaces', true) + await command('repo', []) + t.match({ + 'https://repo.workspace-a/': 1, // Gets translated to https! + 'https://github.com/npm/workspace-b': 1, + }, opened, 'opened two valid repo urls') + }) + + t.test('one workspace', async (t) => { + npm.config.set('workspace', ['workspace-a']) + await command('repo', []) + t.match({ + 'https://repo.workspace-a/': 1, + }, opened, 'opened one requested repo urls') + }) + + t.test('invalid workspace', async (t) => { + npm.config.set('workspace', ['workspace-x']) + await t.rejects( + command('repo', []), + /workspace-x/ + ) + t.match({}, opened, 'opened no repo urls') }) t.end() }) diff --git a/test/lib/utils/completion/installed-deep.js b/test/lib/utils/completion/installed-deep.js index aa0d85ec1..f0e36faee 100644 --- a/test/lib/utils/completion/installed-deep.js +++ b/test/lib/utils/completion/installed-deep.js @@ -6,6 +6,7 @@ let globalDir = 'MISSING_GLOBAL_DIR' const _flatOptions = { depth: Infinity, global: false, + workspacesEnabled: true, get prefix () { return prefix }, diff --git a/test/lib/utils/config/definitions.js b/test/lib/utils/config/definitions.js index 88993303b..622e603bc 100644 --- a/test/lib/utils/config/definitions.js +++ b/test/lib/utils/config/definitions.js @@ -875,3 +875,20 @@ t.test('workspace', t => { t.match(flat.userAgent, /workspaces\/true/) t.end() }) + +t.test('workspaces derived', t => { + const obj = { + workspaces: ['a'], + 'user-agent': definitions['user-agent'].default, + } + const flat = {} + definitions.workspaces.flatten('workspaces', obj, flat) + t.equal(flat.workspacesEnabled, true) + obj.workspaces = null + definitions.workspaces.flatten('workspaces', obj, flat) + t.equal(flat.workspacesEnabled, true) + obj.workspaces = false + definitions.workspaces.flatten('workspaces', obj, flat) + t.equal(flat.workspacesEnabled, false) + t.end() +}) diff --git a/test/lib/workspaces/get-workspaces.js b/test/lib/workspaces/get-workspaces.js index 4ea055e02..0f51d95fc 100644 --- a/test/lib/workspaces/get-workspaces.js +++ b/test/lib/workspaces/get-workspaces.js @@ -86,6 +86,17 @@ t.test('get-workspaces', async t => { 'should filter by package name' ) + workspaces = await getWorkspaces(['a', 'b'], { path, includeWorkspaceRoot: true }) + t.same( + clean(workspaces, path), + new Map(Object.entries({ + x: '{PATH}', + a: '{PATH}/packages/a', + b: '{PATH}/packages/b', + })), + 'include rootspace root' + ) + workspaces = await getWorkspaces(['./packages/c'], { path }) t.same( clean(workspaces, path), |