Skip to content

Commit cafeb26

Browse files
ljharbwesleytodd
authored andcommitted
feat: add engines and cwd options
1 parent a5dd9af commit cafeb26

6 files changed

Lines changed: 245 additions & 1 deletion

File tree

README.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,109 @@ console.log(versions.map((v) => v.version))
8181
*/
8282
```
8383

84+
## Command line interface (CLI)
85+
86+
Options:
87+
- `--only-version`: instead of the entire output, only print one version number per line
88+
- `--engines`: only print versions that match the current directory's `engines.node` field
89+
- `--engines=lts`: only print LTS versions that also match the current directory's `engines.node` field
90+
91+
```sh
92+
$ nv ls lts
93+
{
94+
"version": "18.20.4",
95+
"major": 18,
96+
"minor": 20,
97+
"patch": 4,
98+
"tag": "",
99+
"codename": "hydrogen",
100+
"versionName": "v18",
101+
"start": "2022-04-19T00:00:00.000Z",
102+
"lts": "2022-10-25T00:00:00.000Z",
103+
"maintenance": "2023-10-18T00:00:00.000Z",
104+
"end": "2025-04-30T00:00:00.000Z",
105+
"releaseDate": "2024-07-08T00:00:00.000Z",
106+
"isLts": true,
107+
"files": [
108+
"aix-ppc64",
109+
"headers",
110+
"linux-arm64",
111+
"linux-armv7l",
112+
"linux-ppc64le",
113+
"linux-s390x",
114+
"linux-x64",
115+
"osx-arm64-tar",
116+
"osx-x64-pkg",
117+
"osx-x64-tar",
118+
"src",
119+
"win-x64-7z",
120+
"win-x64-exe",
121+
"win-x64-msi",
122+
"win-x64-zip",
123+
"win-x86-7z",
124+
"win-x86-exe",
125+
"win-x86-msi",
126+
"win-x86-zip"
127+
],
128+
"dependencies": {
129+
"npm": "10.7.0",
130+
"v8": "10.2.154.26",
131+
"uv": "1.44.2",
132+
"zlib": "1.3.0.1-motley",
133+
"openssl": "3.0.13+quic"
134+
}
135+
}
136+
{
137+
"version": "20.15.1",
138+
"major": 20,
139+
"minor": 15,
140+
"patch": 1,
141+
"tag": "",
142+
"codename": "iron",
143+
"versionName": "v20",
144+
"start": "2023-04-18T00:00:00.000Z",
145+
"lts": "2023-10-24T00:00:00.000Z",
146+
"maintenance": "2024-10-22T00:00:00.000Z",
147+
"end": "2026-04-30T00:00:00.000Z",
148+
"releaseDate": "2024-07-08T00:00:00.000Z",
149+
"isLts": true,
150+
"files": [
151+
"aix-ppc64",
152+
"headers",
153+
"linux-arm64",
154+
"linux-armv7l",
155+
"linux-ppc64le",
156+
"linux-s390x",
157+
"linux-x64",
158+
"osx-arm64-tar",
159+
"osx-x64-pkg",
160+
"osx-x64-tar",
161+
"src",
162+
"win-arm64-7z",
163+
"win-arm64-zip",
164+
"win-x64-7z",
165+
"win-x64-exe",
166+
"win-x64-msi",
167+
"win-x64-zip",
168+
"win-x86-7z",
169+
"win-x86-exe",
170+
"win-x86-msi",
171+
"win-x86-zip"
172+
],
173+
"dependencies": {
174+
"npm": "10.7.0",
175+
"v8": "11.3.244.8",
176+
"uv": "1.46.0",
177+
"zlib": "1.3.0.1-motley",
178+
"openssl": "3.0.13+quic"
179+
}
180+
}
181+
182+
$ nv ls lts --only-version
183+
18.20.4
184+
20.15.1
185+
```
186+
84187
## Supported Aliases
85188

86189
**Support Aliases**

bin/nv

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@ require('yargs')
2222
type: 'boolean',
2323
description: 'show version number only'
2424
})
25+
yargs.option('engines', {
26+
type: 'string',
27+
description: 'read the value of `engines.node`. if a value is provided, and it satisfies, the version is shown; if not, the max satisfying version is shown'
28+
})
2529
},
2630
handler: (argv) => {
2731
nv(argv.versions, {
32+
engines: argv.engines,
2833
mirror: argv.mirror
2934
})
3035
.then(result => {
@@ -41,7 +46,7 @@ require('yargs')
4146
})
4247
}).catch(e => {
4348
console.error(e)
44-
process.exitCode = e.code || 1
49+
process.exitCode ||= e.code || 1
4550
})
4651
}
4752
})

index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
'use strict'
2+
const { readFile } = require('fs/promises')
3+
const { join } = require('path')
4+
25
const got = require('got')
36
const semver = require('semver')
47
const _cache = new Map()
@@ -8,6 +11,8 @@ module.exports = async function (alias = 'lts_active', opts = {}) {
811
const cache = opts.cache || _cache
912
const mirror = opts.mirror || 'https://nodejs.org/dist/'
1013
const latestOfMajorOnly = opts.latestOfMajorOnly || false
14+
const engines = opts.engines
15+
const cwd = opts.cwd || process.cwd()
1116

1217
const a = Array.isArray(alias) ? alias : [alias]
1318
const versions = await getLatestVersionsByCodename(now, cache, mirror)
@@ -25,6 +30,18 @@ module.exports = async function (alias = 'lts_active', opts = {}) {
2530
return m
2631
}, {})
2732

33+
if (typeof engines === 'string' || engines === true) {
34+
const { engines: { node } = { node: '*' } } = JSON.parse(await readFile(join(cwd, 'package.json'), 'utf8'))
35+
36+
m = Object.fromEntries(Object.entries(m).filter(([version]) => semver.satisfies(version, node)))
37+
38+
const matching = Object.entries(m).filter(([version]) => semver.satisfies(version, engines))
39+
40+
if (matching.length > 0) {
41+
m = Object.fromEntries(matching)
42+
}
43+
}
44+
2845
// If only latest major is true, filter out all but latest
2946
if (latestOfMajorOnly) {
3047
const vers = Object.values(m).reduce((latestMajor, v) => {

test/cli.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,62 @@ suite('nv cli', () => {
4040
assert(semver.valid(r))
4141
})
4242
})
43+
44+
test('works with `--engines`', () => {
45+
const result = execFileSync(nv, ['ls', '8.x', '--only-version', '--engines=">=8"'], { cwd: path.join(__dirname, 'fixtures', 'engines') })
46+
.toString().trim().split('\n')
47+
48+
assert.deepEqual(result, [
49+
'8.10.0',
50+
'8.11.0',
51+
'8.11.1',
52+
'8.11.2',
53+
'8.11.3',
54+
'8.11.4',
55+
'8.12.0',
56+
'8.13.0',
57+
'8.14.0',
58+
'8.14.1',
59+
'8.15.0',
60+
'8.15.1',
61+
'8.16.0',
62+
'8.16.1',
63+
'8.16.2',
64+
'8.17.0'
65+
])
66+
67+
const result2 = execFileSync(nv, ['ls', '8.x', '--only-version', '--engines=">=8.15"'], { cwd: path.join(__dirname, 'fixtures', 'engines') })
68+
.toString().trim().split('\n')
69+
70+
assert.deepEqual(result2, [
71+
'8.15.0',
72+
'8.15.1',
73+
'8.16.0',
74+
'8.16.1',
75+
'8.16.2',
76+
'8.17.0'
77+
])
78+
79+
const result3 = execFileSync(nv, ['ls', '8.x', '--only-version', '--engines'], { cwd: path.join(__dirname, 'fixtures', 'engines') })
80+
.toString().trim().split('\n')
81+
82+
assert.deepEqual(result3, [
83+
'8.10.0',
84+
'8.11.0',
85+
'8.11.1',
86+
'8.11.2',
87+
'8.11.3',
88+
'8.11.4',
89+
'8.12.0',
90+
'8.13.0',
91+
'8.14.0',
92+
'8.14.1',
93+
'8.15.0',
94+
'8.15.1',
95+
'8.16.0',
96+
'8.16.1',
97+
'8.16.2',
98+
'8.17.0'
99+
])
100+
})
43101
})

test/fixtures/engines/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"engines": {
3+
"node": "^8.10"
4+
}
5+
}

test/index.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22
const { suite, test } = require('mocha')
33
const assert = require('assert')
4+
const path = require('path')
45
const nv = require('..')
56

67
// 2019-02-07T16:15:49.683Z
@@ -182,4 +183,59 @@ suite('nv', () => {
182183
const versions = await nv('0.8.0', { now })
183184
assert.strictEqual(versions[0].codename, null)
184185
})
186+
187+
test('engines option', async () => {
188+
const versions = await nv('8.x', { now, cwd: path.join(__dirname, 'fixtures', 'engines'), engines: '>=8' })
189+
190+
assert.deepEqual(versions.map(x => x.version), [
191+
'8.10.0',
192+
'8.11.0',
193+
'8.11.1',
194+
'8.11.2',
195+
'8.11.3',
196+
'8.11.4',
197+
'8.12.0',
198+
'8.13.0',
199+
'8.14.0',
200+
'8.14.1',
201+
'8.15.0',
202+
'8.15.1',
203+
'8.16.0',
204+
'8.16.1',
205+
'8.16.2',
206+
'8.17.0'
207+
])
208+
209+
const versions2 = await nv('8.x', { now, cwd: path.join(__dirname, 'fixtures', 'engines'), engines: '>=8.15' })
210+
211+
assert.deepEqual(versions2.map(x => x.version), [
212+
'8.15.0',
213+
'8.15.1',
214+
'8.16.0',
215+
'8.16.1',
216+
'8.16.2',
217+
'8.17.0'
218+
])
219+
220+
const versions3 = await nv('8.x', { now, cwd: path.join(__dirname, 'fixtures', 'engines'), engines: true })
221+
222+
assert.deepEqual(versions3.map(x => x.version), [
223+
'8.10.0',
224+
'8.11.0',
225+
'8.11.1',
226+
'8.11.2',
227+
'8.11.3',
228+
'8.11.4',
229+
'8.12.0',
230+
'8.13.0',
231+
'8.14.0',
232+
'8.14.1',
233+
'8.15.0',
234+
'8.15.1',
235+
'8.16.0',
236+
'8.16.1',
237+
'8.16.2',
238+
'8.17.0'
239+
])
240+
})
185241
})

0 commit comments

Comments
 (0)