Skip to content

Commit

Permalink
feat: add fund workspaces
Browse files Browse the repository at this point in the history
Add workspaces support to `npm fund`

- Add ability to filter fund results to a specific set of workspaces
- Added tests and docs

Fixes: npm/statusboard#301
  • Loading branch information
ruyadorno committed May 13, 2021
1 parent b551c68 commit 91f0750
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 3 deletions.
54 changes: 54 additions & 0 deletions docs/content/commands/npm-fund.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ description: Retrieve funding information

```bash
npm fund [<pkg>]
npm fund [-w <workspace-name>]
```

### Description
Expand All @@ -24,6 +25,43 @@ The list will avoid duplicated entries and will stack all packages that
share the same url as a single entry. Thus, the list does not have the same
shape of the output from `npm ls`.

#### Example

### Workspaces support

It's possible to filter the results to only include a single workspace and its
dependencies using the `workspace` config option.

#### Example:

Here's an example running `npm fund` in a project with a configured
workspace `a`:

```bash
$ npm fund
test-workspaces-fund@1.0.0
+-- https://example.com/a
| | `-- a@1.0.0
| `-- https://github.com/sponsors/ljharb
| `-- has-symbols@1.0.2
+-- https://example.com/funding
| `-- @npmcli/test-funding
`-- https://github.com/sponsors/isaacs
`-- promise-all-reject-late@1.0.1
```

And here is an example of the expected result when filtering only by
a specific workspace `a` in the same project:

```bash
$ npm fund -w a
test-workspaces-fund@1.0.0
`-- https://github.com/sponsors
| `-- a@1.0.0
`-- https://github.com/sponsors/ljharb
`-- has-symbols@1.0.2
```

### Configuration

#### browser
Expand All @@ -48,6 +86,21 @@ Show information in JSON format.
Whether to represent the tree structure using unicode characters.
Set it to `false` in order to use all-ansi output.

#### workspace

* Alias: `-w`
* Type: Array
* Default: `[]`

Enable filtering funding info results for `npm fund` to dependencies of a
set of configured **workspaces**.

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
children workspaces)

#### which

* Type: Number
Expand All @@ -61,3 +114,4 @@ If there are multiple funding sources, which 1-indexed source URL to open.
* [npm docs](/commands/npm-docs)
* [npm ls](/commands/npm-ls)
* [npm config](/commands/npm-config)
* [npm workspaces](/using-npm/workspaces)
22 changes: 19 additions & 3 deletions lib/fund.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const {

const completion = require('./utils/completion/installed-deep.js')
const openUrl = require('./utils/open-url.js')
const getWorkspaces = require('./workspaces/get-workspaces.js')

const getPrintableName = ({ name, version }) => {
const printableVersion = version ? `@${version}` : ''
Expand All @@ -38,6 +39,7 @@ class Fund extends BaseCommand {
'json',
'browser',
'unicode',
'workspace',
'which',
]
}
Expand All @@ -56,7 +58,15 @@ class Fund extends BaseCommand {
this.fund(args).then(() => cb()).catch(cb)
}

async fund (args) {
execWorkspaces (args, filters, cb) {
getWorkspaces(filters, { path: this.npm.localPrefix })
.then(workspaces => {
this.workspaces = [...workspaces.keys()]
this.exec(args, cb)
})
}

async fund (args, opts) {
const spec = args[0]
const numberArg = this.npm.config.get('which')

Expand Down Expand Up @@ -92,10 +102,16 @@ class Fund extends BaseCommand {
return
}

const fundingInfo = getFundingInfo(tree, {
...this.flatOptions,
log: this.npm.log,
workspaces: this.workspaces,
})

if (this.npm.config.get('json'))
this.npm.output(this.printJSON(getFundingInfo(tree)))
this.npm.output(this.printJSON(fundingInfo))
else
this.npm.output(this.printHuman(getFundingInfo(tree)))
this.npm.output(this.printHuman(fundingInfo))
}

printJSON (fundingInfo) {
Expand Down
10 changes: 10 additions & 0 deletions tap-snapshots/test/lib/fund.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,13 @@ test-multiple-funding-sources@1.0.0
`

exports[`test/lib/fund.js TAP workspaces filter funding info by a specific workspace > should display only filtered workspace and its deps 1`] = `
workspaces-support@1.0.0
\`-- https://example.com/a
| \`-- a@1.0.0
\`-- http://example.com/c
\`-- c@1.0.0
`
69 changes: 69 additions & 0 deletions test/lib/fund.js
Original file line number Diff line number Diff line change
Expand Up @@ -839,3 +839,72 @@ t.test('sub dep with fund info and a parent with no funding info', t => {
t.end()
})
})

t.test('workspaces', t => {
t.test('filter funding info by a specific workspace', t => {
npm.localPrefix = npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'workspaces-support',
version: '1.0.0',
workspaces: ['packages/*'],
dependencies: {
d: '^1.0.0',
},
}),
node_modules: {
a: t.fixture('symlink', '../packages/a'),
b: t.fixture('symlink', '../packages/b'),
c: {
'package.json': JSON.stringify({
name: 'c',
version: '1.0.0',
funding: [
'http://example.com/c',
'http://example.com/c-other',
],
}),
},
d: {
'package.json': JSON.stringify({
name: 'd',
version: '1.0.0',
funding: 'http://example.com/d',
}),
},
},
packages: {
a: {
'package.json': JSON.stringify({
name: 'a',
version: '1.0.0',
funding: 'https://example.com/a',
dependencies: {
c: '^1.0.0',
},
}),
},
b: {
'package.json': JSON.stringify({
name: 'b',
version: '1.0.0',
funding: 'http://example.com/b',
dependencies: {
d: '^1.0.0',
},
}),
},
},
})

fund.execWorkspaces([], ['a'], (err) => {
t.error(err, 'should not error out')
t.matchSnapshot(result,
'should display only filtered workspace and its deps')

result = ''
t.end()
})
})

t.end()
})

0 comments on commit 91f0750

Please sign in to comment.