Skip to content

Commit 2037de0

Browse files
committed
make pear dump consistent for file and pear
- mirror local files from the root of the pear project
1 parent ed26b7f commit 2037de0

File tree

2 files changed

+113
-20
lines changed

2 files changed

+113
-20
lines changed

subsystems/sidecar/ops/dump.js

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const path = require('bare-path')
44
const LocalDrive = require('localdrive')
55
const Hyperdrive = require('hyperdrive')
66
const plink = require('pear-link')
7+
const State = require('pear-state')
78
const {
89
ERR_PERMISSION_REQUIRED,
910
ERR_DIR_NONEMPTY,
@@ -36,6 +37,7 @@ module.exports = class Dump extends Opstream {
3637
}
3738

3839
const parsed = plink.parse(link)
40+
3941
const isFileLink = parsed.protocol === 'file:'
4042
const isFile =
4143
isFileLink && (await fsp.stat(parsed.pathname)).isDirectory() === false
@@ -48,25 +50,37 @@ module.exports = class Dump extends Opstream {
4850
const encryptionKey = traits?.encryptionKey
4951

5052
const corestore = isFileLink ? null : sidecar.getCorestore(null, null)
51-
let drive = null
5253

53-
if (corestore) {
54+
let prefix
55+
let drive
56+
57+
if (!isFileLink) {
5458
await corestore.ready()
5559
try {
5660
drive = new Hyperdrive(corestore, key, { encryptionKey })
5761
await drive.ready()
62+
prefix = parsed.pathname
5863
} catch (err) {
5964
if (err.code !== 'DECODING_ERROR') throw err
6065
throw ERR_PERMISSION_REQUIRED('Encryption key required', {
6166
key,
6267
encrypted: true
6368
})
6469
}
70+
} else {
71+
const state = new State({
72+
dir: isFile ? path.dirname(parsed.pathname) : parsed.pathname
73+
})
74+
await State.localPkg(state)
75+
prefix = path.join('/', path.relative(state.dir, parsed.pathname))
76+
drive = new LocalDrive(state.dir, { followLinks: true })
77+
if (state.dir === '/') throw ERR_NOT_FOUND('No pear project found')
6578
}
66-
const root = isFile ? path.dirname(parsed.pathname) : parsed.pathname
79+
const pathname = prefix === '/' ? '' : prefix
80+
6781
const pod = new Pod({
6882
corestore,
69-
drive: isFileLink ? new LocalDrive(root, { followLinks: true }) : drive,
83+
drive,
7084
key,
7185
checkout,
7286
swarm: sidecar.swarm
@@ -92,13 +106,6 @@ module.exports = class Dump extends Opstream {
92106
const src = pod.drive
93107
await src.ready()
94108

95-
const prefix = isFileLink ? '/' : parsed.pathname
96-
const pathname =
97-
!isFileLink && parsed.pathname === '/'
98-
? ''
99-
: isFile
100-
? path.basename(parsed.pathname)
101-
: prefix
102109
const entry = pathname === '' ? null : await src.entry(pathname)
103110

104111
if (entry === null) {

test/06-dump.test.js

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
const test = require('brittle')
33
const tmp = require('test-tmp')
44
const Localdrive = require('localdrive')
5+
const fs = require('bare-fs')
6+
const path = require('bare-path')
57

68
const Helper = require('./helper')
79

@@ -43,20 +45,13 @@ test('pear dump', async function ({ ok, plan, teardown }) {
4345
ok(await dumped.exists('/package.json'), 'package.json should exist')
4446
})
4547

46-
test('pear dump dumping subdirectory', async function ({
48+
test('pear dump dumping subdirectory from pear drive', async function ({
4749
ok,
4850
absent,
4951
plan,
5052
teardown
5153
}) {
5254
plan(4)
53-
const path = require('bare-path')
54-
const fs = require('bare-fs')
55-
const exists = (path) =>
56-
fs.promises.stat(path).then(
57-
() => true,
58-
() => false
59-
)
6055
const helper = new Helper()
6156
teardown(() => helper.close(), { order: Infinity })
6257
await helper.ready()
@@ -93,6 +88,34 @@ test('pear dump dumping subdirectory', async function ({
9388
ok(await dumped.exists('/lib/pear.js'), 'lib/pear.js should exist')
9489
})
9590

91+
test('pear dump dumping subdirectory from local drive', async function ({
92+
ok,
93+
absent,
94+
plan,
95+
teardown
96+
}) {
97+
plan(4)
98+
const helper = new Helper()
99+
teardown(() => helper.close(), { order: Infinity })
100+
await helper.ready()
101+
102+
const src = Helper.fixture('dump')
103+
const link = `file://${src}/lib`
104+
105+
const out = await tmp()
106+
107+
teardown(() => Helper.gc(out))
108+
const dump = await helper.dump({ link, dir: out })
109+
teardown(() => Helper.teardownStream(dump))
110+
const untilDump = await Helper.pick(dump, [{ tag: 'complete' }])
111+
await untilDump.complete
112+
const dumped = new Localdrive(out)
113+
absent(await dumped.exists('/index.js'), 'index.js should not exist')
114+
absent(await dumped.exists('/package.json'), 'package.json should not exist')
115+
ok(await dumped.exists('/lib/dump.js'), 'lib/dump.js should exist')
116+
ok(await dumped.exists('/lib/pear.js'), 'lib/pear.js should exist')
117+
})
118+
96119
test('pear dump dumping to existing dir', async function ({
97120
absent,
98121
is,
@@ -230,7 +253,7 @@ test('pear dump dumping a single file', async function ({
230253
absent(await dumped.exists('/package.json'), 'package.json should not exist')
231254
})
232255

233-
test('pear dump dumping a single file in a subdirectory', async function ({
256+
test('pear dump dumping a single file in a subdirectory from pear drive', async function ({
234257
ok,
235258
is,
236259
plan,
@@ -275,6 +298,69 @@ test('pear dump dumping a single file in a subdirectory', async function ({
275298
is(dirCount, 1, 'should have only one file in the lib directory')
276299
})
277300

301+
test('pear dump should throw when dumping file outisde a pear project', async function ({
302+
plan,
303+
teardown,
304+
exception
305+
}) {
306+
plan(1)
307+
308+
const helper = new Helper()
309+
teardown(() => helper.close(), { order: Infinity })
310+
await helper.ready()
311+
312+
const src = await tmp()
313+
const out = await tmp()
314+
teardown(async () => {
315+
await Helper.gc(out)
316+
await Helper.gc(src)
317+
})
318+
await fs.promises.writeFile(
319+
path.join(src, 'test.js'),
320+
'console.log("test")',
321+
{
322+
encoding: 'utf-8'
323+
}
324+
)
325+
const link = `file://${src}/test.js`
326+
327+
await exception(async () => {
328+
const dump = helper.dump({ link, dir: out })
329+
teardown(() => Helper.teardownStream(dump))
330+
const untilDump = await Helper.pick(dump, [{ tag: 'complete' }])
331+
await untilDump.complete
332+
})
333+
})
334+
335+
test('pear dump dumping a single file in a subdirectory from local drive', async function ({
336+
ok,
337+
is,
338+
plan,
339+
teardown
340+
}) {
341+
plan(2)
342+
343+
const helper = new Helper()
344+
teardown(() => helper.close(), { order: Infinity })
345+
await helper.ready()
346+
347+
const src = Helper.fixture('dump')
348+
const link = `file://${src}/lib/dump.js`
349+
350+
const out = await tmp()
351+
352+
teardown(() => Helper.gc(out))
353+
const dump = await helper.dump({ link, dir: out })
354+
teardown(() => Helper.teardownStream(dump))
355+
const untilDump = await Helper.pick(dump, [{ tag: 'complete' }])
356+
await untilDump.complete
357+
const dumped = new Localdrive(out)
358+
let dirCount = 0
359+
for await (const _ of dumped.readdir()) dirCount++
360+
ok(await dumped.exists('/lib/dump.js'), 'lib/dump.js should exist')
361+
is(dirCount, 1, 'should have only one file in the lib directory')
362+
})
363+
278364
test('pear dump dumping to stdout', async function ({ ok, plan, teardown }) {
279365
plan(4)
280366

0 commit comments

Comments
 (0)