Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit 80ac58c

Browse files
authored
fix: ensure directory is passed (#3968)
Fixes bug where importing files directly was broken
1 parent 45ac973 commit 80ac58c

File tree

2 files changed

+106
-7
lines changed

2 files changed

+106
-7
lines changed

packages/ipfs-cli/src/commands/add.js

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import {
1414
import globSource from 'ipfs-utils/src/files/glob-source.js'
1515
import parseDuration from 'parse-duration'
1616
import merge from 'it-merge'
17+
import fs from 'fs'
18+
import path from 'path'
1719

1820
const getFolderSize = promisify(getFolderSizeCb)
1921

@@ -25,6 +27,64 @@ async function getTotalBytes (paths) {
2527
return sizes.reduce((total, size) => total + size, 0)
2628
}
2729

30+
/**
31+
* @param {string} target
32+
* @param {object} options
33+
* @param {boolean} [options.recursive]
34+
* @param {boolean} [options.hidden]
35+
* @param {boolean} [options.preserveMode]
36+
* @param {boolean} [options.preserveMtime]
37+
* @param {number} [options.mode]
38+
* @param {import('ipfs-unixfs').MtimeLike} [options.mtime]
39+
*/
40+
async function * getSource (target, options = {}) {
41+
const absolutePath = path.resolve(target)
42+
const stats = await fs.promises.stat(absolutePath)
43+
44+
if (stats.isFile()) {
45+
let mtime = options.mtime
46+
let mode = options.mode
47+
48+
if (options.preserveMtime) {
49+
mtime = stats.mtime
50+
}
51+
52+
if (options.preserveMode) {
53+
mode = stats.mode
54+
}
55+
56+
yield {
57+
path: path.basename(target),
58+
content: fs.createReadStream(absolutePath),
59+
mtime,
60+
mode
61+
}
62+
63+
return
64+
}
65+
66+
const dirName = path.basename(absolutePath)
67+
68+
let pattern = '*'
69+
70+
if (options.recursive) {
71+
pattern = '**/*'
72+
}
73+
74+
for await (const content of globSource(target, pattern, {
75+
hidden: options.hidden,
76+
preserveMode: options.preserveMode,
77+
preserveMtime: options.preserveMtime,
78+
mode: options.mode,
79+
mtime: options.mtime
80+
})) {
81+
yield {
82+
...content,
83+
path: `${dirName}${content.path}`
84+
}
85+
}
86+
}
87+
2888
export default {
2989
command: 'add [file...]',
3090

@@ -287,15 +347,10 @@ export default {
287347
date = { secs: mtime, nsecs: mtimeNsecs }
288348
}
289349

290-
let pattern = '*'
291-
292-
if (recursive) {
293-
pattern = '**/*'
294-
}
295-
296350
const source = file
297-
? merge(...file.map(file => globSource(file, pattern, {
351+
? merge(...file.map(file => getSource(file, {
298352
hidden,
353+
recursive,
299354
preserveMode,
300355
preserveMtime,
301356
mode,

packages/ipfs-cli/test/add.spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { cli } from './utils/cli.js'
99
import sinon from 'sinon'
1010
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
1111
import { matchIterable } from './utils/match-iterable.js'
12+
import all from 'it-all'
13+
import map from 'it-map'
1214

1315
// TODO: Test against all algorithms Object.keys(mh.names)
1416
// This subset is known to work with both go-ipfs and js-ipfs as of 2017-09-05
@@ -62,6 +64,48 @@ describe('add', () => {
6264

6365
const out = await cli('add --progress false README.md', { ipfs })
6466
expect(out).to.equal(`added ${cid} README.md\n`)
67+
68+
const files = await all(map(ipfs.addAll.getCall(0).args[0], (file) => file.path))
69+
expect(files).to.deep.equal([
70+
'README.md'
71+
])
72+
})
73+
74+
it('should add a directory', async () => {
75+
const cid = CID.parse('QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB')
76+
77+
ipfs.addAll.withArgs(matchIterable(), defaultOptions).returns([{
78+
cid,
79+
path: 'bitswap/index.js'
80+
}, {
81+
cid,
82+
path: 'bitswap/unwant.js'
83+
}, {
84+
cid,
85+
path: 'bitswap/wantlist.js'
86+
}, {
87+
cid,
88+
path: 'bitswap/stat.js'
89+
}, {
90+
cid,
91+
path: 'bitswap'
92+
}])
93+
ipfs.bases.getBase.withArgs('base58btc').returns(base58btc)
94+
95+
const out = await cli('add --recursive src/commands/bitswap', { ipfs })
96+
expect(out).to.include(`added ${cid} bitswap/index.js\n`)
97+
expect(out).to.include(`added ${cid} bitswap/unwant.js\n`)
98+
expect(out).to.include(`added ${cid} bitswap/wantlist.js\n`)
99+
expect(out).to.include(`added ${cid} bitswap/stat.js\n`)
100+
expect(out).to.include(`added ${cid} bitswap\n`)
101+
102+
const files = await all(map(ipfs.addAll.getCall(0).args[0], (file) => file.path))
103+
expect(files.sort()).to.deep.equal([
104+
'bitswap/index.js',
105+
'bitswap/unwant.js',
106+
'bitswap/wantlist.js',
107+
'bitswap/stat.js'
108+
].sort())
65109
})
66110

67111
it('should strip control characters from paths when add a file', async () => {

0 commit comments

Comments
 (0)