Skip to content

Commit c87260a

Browse files
authored
refactor: add normalizePackageMan helper (#100)
## What / Why Aligns normalization logic with `directories.bin` See also: https://github.com/npm/normalize-package-data/blob/main/lib/fixer.js#L105 ```js fixManField: function (data) { if (!data.man) { return } if (typeof data.man === 'string') { data.man = [data.man] } }, ``` ## References * continues npm/read-package-json#177 * relates #104 CC @wraithgar
1 parent 3968292 commit c87260a

File tree

2 files changed

+134
-20
lines changed

2 files changed

+134
-20
lines changed

lib/normalize.js

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,36 @@ function normalizePackageBin (pkg, changes) {
8383
delete pkg.bin
8484
}
8585

86+
function normalizePackageMan (pkg, changes) {
87+
if (pkg.man) {
88+
const mans = []
89+
for (const man of (Array.isArray(pkg.man) ? pkg.man : [pkg.man])) {
90+
if (typeof man !== 'string') {
91+
changes?.push(`removed invalid "man [${man}]"`)
92+
} else {
93+
mans.push(unixifyPath(securePath(unixifyPath(man))))
94+
}
95+
}
96+
97+
if (!mans.length) {
98+
changes?.push('empty "man" was removed')
99+
} else {
100+
pkg.man = mans
101+
return pkg
102+
}
103+
}
104+
delete pkg.man
105+
}
106+
86107
function isCorrectlyEncodedName (spec) {
87108
return !spec.match(/[/@\s+%:]/) &&
88109
spec === encodeURIComponent(spec)
89110
}
90111

112+
function unixifyPath (ref) {
113+
return ref.replace(/\\|:/g, '/')
114+
}
115+
91116
function isValidScopedPackageName (spec) {
92117
if (spec.charAt(0) !== '@') {
93118
return false
@@ -329,13 +354,16 @@ const normalize = async (pkg, { strict, steps, root, changes, allowLegacyCase })
329354
}
330355

331356
// expand directories.man
332-
if (steps.includes('mans') && !data.man && data.directories?.man) {
333-
const manDir = data.directories.man
334-
const cwd = path.resolve(pkg.path, securePath(manDir))
335-
const files = await lazyLoadGlob()('**/*.[0-9]', { cwd })
336-
data.man = files.map(man =>
337-
path.relative(pkg.path, path.join(cwd, man)).split(path.sep).join('/')
338-
)
357+
if (steps.includes('mans')) {
358+
if (data.directories?.man && !data.man) {
359+
const manDir = unixifyPath(securePath(unixifyPath(data.directories.man)))
360+
const cwd = path.resolve(pkg.path, manDir)
361+
const files = await lazyLoadGlob()('**/*.[0-9]', { cwd })
362+
data.man = files.map(man =>
363+
path.relative(pkg.path, path.join(cwd, man)).split(path.sep).join('/')
364+
)
365+
}
366+
normalizePackageMan(data, changes)
339367
}
340368

341369
if (steps.includes('bin') || steps.includes('binDir') || steps.includes('binRefs')) {

test/prepare.js

Lines changed: 99 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,105 @@ for (const [name, testPrepare] of Object.entries(testMethods)) {
154154
t.end()
155155
})
156156

157+
t.test('man', t => {
158+
t.test('resolves directory', async t => {
159+
const { content } = await testPrepare(t, ({
160+
'package.json': JSON.stringify({
161+
directories: { man: './man' },
162+
}),
163+
man: { man1: { 'test.1': 'man test file' } },
164+
}))
165+
t.strictSame(content.man, ['man/man1/test.1'])
166+
})
167+
168+
if (name === '@npmcli/package-json') {
169+
t.test('non-string', async t => {
170+
const { content } = await testPrepare(t, ({
171+
'package.json': JSON.stringify({
172+
man: 123,
173+
}),
174+
}))
175+
t.has(content, { man: undefined })
176+
})
177+
178+
t.test('good', async t => {
179+
const { content } = await testPrepare(t, ({
180+
'package.json': JSON.stringify({
181+
man: './man/test.1',
182+
}),
183+
}))
184+
t.strictSame(content.man, ['man/test.1'])
185+
})
186+
187+
t.test('empty', async t => {
188+
const { content } = await testPrepare(t, ({
189+
'package.json': JSON.stringify({
190+
man: [],
191+
}),
192+
}))
193+
t.has(content, { man: undefined })
194+
})
195+
196+
t.test('directories.man no prefix', async t => {
197+
const { content } = await testPrepare(t, ({
198+
'package.json': JSON.stringify({
199+
name: 'man-test',
200+
directories: {
201+
man: './man',
202+
},
203+
}),
204+
man: { 'test.1': '.TH man "test man page"' },
205+
}))
206+
t.strictSame(content.man, ['man/test.1'])
207+
})
208+
209+
t.test('directories.man trim prefix', async t => {
210+
const { content } = await testPrepare(t, ({
211+
'package.json': JSON.stringify({
212+
name: 'man-test',
213+
directories: {
214+
man: '../../../../../man',
215+
},
216+
}),
217+
man: { 'test.1': '.TH man "test man page"' },
218+
}))
219+
t.strictSame(content.man, ['man/test.1'])
220+
})
221+
222+
t.test('directories.man handles reversed slashes', async t => {
223+
const { content } = await testPrepare(t, ({
224+
'package.json': JSON.stringify({
225+
name: 'man-test',
226+
directories: {
227+
man: '..\\..\\man',
228+
},
229+
}),
230+
man: { 'test.1': '.TH man "test man page"' },
231+
}))
232+
t.strictSame(content.man, ['man/test.1'])
233+
})
234+
235+
t.test('directories.man with man', async t => {
236+
const { content } = await testPrepare(t, ({
237+
'package.json': JSON.stringify({
238+
name: 'man-test',
239+
directories: {
240+
man: './man',
241+
},
242+
man: '../../test.2',
243+
}),
244+
man: {
245+
'test.1': '.TH man "test man page 1"',
246+
'test.2': '.TH man "test man page 2"',
247+
},
248+
}))
249+
t.strictSame(content.man, ['test.2'])
250+
})
251+
}
252+
253+
t.end()
254+
})
255+
157256
t.test('bundleDependencies', t => {
158257
t.test('true', async t => {
159258
const { content } = await testPrepare(t, ({
@@ -325,19 +424,6 @@ for (const [name, testPrepare] of Object.entries(testMethods)) {
325424
t.end()
326425
})
327426

328-
t.test('man', t => {
329-
t.test('resolves directory', async t => {
330-
const { content } = await testPrepare(t, ({
331-
'package.json': JSON.stringify({
332-
directories: { man: './man' },
333-
}),
334-
man: { man1: { 'test.1': 'man test file' } },
335-
}))
336-
t.strictSame(content.man, ['man/man1/test.1'])
337-
})
338-
t.end()
339-
})
340-
341427
t.test('gitHead', t => {
342428
t.test('HEAD with no ref', async t => {
343429
const { content } = await testPrepare(t, ({

0 commit comments

Comments
 (0)