Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit e1ee4e6

Browse files
authored
Merge pull request #3 from ipfs/cli-integration
feat: integrate with jsipfs cli
2 parents fc5c478 + 42fde51 commit e1ee4e6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1723
-581
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ Loading this module through a script tag will make the `mfs` obj available in th
6262
<script src="https://npmcdn.com/ipfs-mfs/dist/index.js"></script>
6363
```
6464

65+
### A note on concurrency
66+
67+
The mfs works by storing a reference to the root node's CID in LevelDB. LevelDB does not support concurrent access so there are read/write locks around bits of the code that modify the the root node's CID.
68+
69+
A lock is kept on the main thread and any requests to read/write from workers or the main thread itself are queued pending release of the lock by the existing holder.
70+
71+
Reads are executed together, writes are executed sequentially and prevent any reads from starting.
72+
73+
If you are using IPFS in a single process or with the node [cluster](https://nodejs.org/api/cluster.html) module this should be completely transparent.
74+
75+
If you are using [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) there is no way to globally listen to messages sent between workers and the main thread so you will need to also use the [observable-webworkers](https://www.npmjs.com/package/observable-webworkers) module to ensure the right message transports are set up to allow requesting/releasing the locks.
76+
6577
## Contribute
6678

6779
All are welcome, please join in!

cli.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict'
2+
3+
module.exports = require('./src/cli')

core.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict'
2+
3+
module.exports = require('./src/core')

http.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict'
2+
3+
module.exports = require('./src/http')

package.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"scripts": {
1111
"test": "cross-env aegir test -f test/browser.js",
1212
"test:node": "aegir test -t node",
13-
"test:browser": "aegir test -t browser -t webworker -f test/browser.js",
13+
"test:browser": "aegir test -t browser -f test/browser.js",
14+
"test:webworker": "aegir test -t webworker -f test/browser.js",
1415
"build": "aegir build",
1516
"lint": "aegir lint",
1617
"release": "aegir release",
@@ -38,13 +39,14 @@
3839
"devDependencies": {
3940
"@commitlint/cli": "^6.2.0",
4041
"@commitlint/config-conventional": "^6.1.3",
41-
"aegir": "^13.0.6",
42+
"aegir": "^14.0.0",
4243
"chai": "^4.1.2",
4344
"cross-env": "^5.1.4",
45+
"detect-webworker": "^1.0.0",
4446
"dirty-chai": "^2.0.1",
45-
"ipfs": "~0.28.2",
47+
"ipfs": "~0.29.0",
4648
"pre-commit": "^1.2.2",
47-
"pre-push": "^0.1.1",
49+
"pre-push": "~0.1.1",
4850
"safe-buffer": "^5.1.1",
4951
"sign-commit": "~0.1.0",
5052
"tmp": "~0.0.33"
@@ -59,10 +61,12 @@
5961
"file-api": "~0.10.4",
6062
"filereader-stream": "^2.0.0",
6163
"interface-datastore": "~0.4.2",
62-
"ipfs-unixfs": "~0.1.14",
63-
"ipfs-unixfs-engine": "~0.29.0",
64+
"ipfs-unixfs": "~0.1.15",
65+
"ipfs-unixfs-engine": "~0.30.0",
6466
"is-pull-stream": "~0.0.0",
6567
"is-stream": "^1.1.0",
68+
"joi": "^13.4.0",
69+
"mortice": "^1.0.0",
6670
"promisify-es6": "^1.0.3",
6771
"pull-cat": "^1.1.11",
6872
"pull-paramap": "^1.2.2",

src/cli/cp.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
11
'use strict'
22

3+
const {
4+
asBoolean
5+
} = require('./utils')
6+
37
module.exports = {
48
command: 'cp <source> <dest>',
59

6-
describe: 'Copy files between locations in the mfs.',
10+
describe: 'Copy files between locations in the mfs',
711

812
builder: {
913
parents: {
1014
alias: 'p',
1115
type: 'boolean',
1216
default: false,
17+
coerce: asBoolean,
1318
describe: 'Create any non-existent intermediate directories'
1419
},
15-
recursive: {
16-
alias: 'r',
17-
type: 'boolean',
18-
default: false,
19-
describe: 'Remove directories recursively'
20+
format: {
21+
alias: 'h',
22+
type: 'string',
23+
default: 'dag-pb',
24+
describe: 'If intermediate directories are created, use this format to create them (experimental)'
25+
},
26+
hash: {
27+
alias: 'h',
28+
type: 'string',
29+
default: 'sha2-256',
30+
describe: 'Hash function to use. Will set Cid version to 1 if used. (experimental)'
2031
}
2132
},
2233

@@ -26,16 +37,16 @@ module.exports = {
2637
dest,
2738
ipfs,
2839
parents,
29-
recursive
40+
format,
41+
hash
3042
} = argv
3143

32-
ipfs.mfs.cp(source, dest, {
33-
parents,
34-
recursive
35-
}, (error) => {
36-
if (error) {
37-
throw error
38-
}
39-
})
44+
argv.resolve(
45+
ipfs.files.cp(source, dest, {
46+
parents,
47+
format,
48+
hashAlg: hash
49+
})
50+
)
4051
}
4152
}

src/cli/flush.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict'
2+
3+
const {
4+
FILE_SEPARATOR
5+
} = require('../core/utils')
6+
7+
module.exports = {
8+
command: 'flush [path]',
9+
10+
describe: ' Flush a given path\'s data to disk',
11+
12+
builder: {},
13+
14+
handler (argv) {
15+
let {
16+
path,
17+
ipfs
18+
} = argv
19+
20+
argv.resolve(
21+
ipfs.files.flush(path || FILE_SEPARATOR, {})
22+
)
23+
}
24+
}

src/cli/index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict'
2+
3+
const {
4+
print
5+
} = require('./utils')
6+
7+
const command = {
8+
command: 'files <command>',
9+
10+
description: 'Operations over mfs files (ls, mkdir, rm, etc)',
11+
12+
builder (yargs) {
13+
return yargs.commandDir('.')
14+
},
15+
16+
handler (argv) {
17+
print('Type `jsipfs files --help` for more instructions')
18+
}
19+
}
20+
21+
module.exports = (yargs) => {
22+
return yargs
23+
.command(command)
24+
}

src/cli/ls.js

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
'use strict'
22

33
const {
4-
print
4+
print,
5+
asBoolean
56
} = require('./utils')
7+
const {
8+
FILE_SEPARATOR
9+
} = require('../core/utils')
610

711
module.exports = {
8-
command: 'ls <path>',
12+
command: 'ls [path]',
913

10-
describe: 'List directories in the local mutable namespace.',
14+
describe: 'List mfs directories',
1115

1216
builder: {
1317
long: {
1418
alias: 'l',
1519
type: 'boolean',
1620
default: false,
21+
coerce: asBoolean,
1722
describe: 'Use long listing format.'
1823
}
1924
},
@@ -25,20 +30,47 @@ module.exports = {
2530
long
2631
} = argv
2732

28-
ipfs.mfs.ls(path, {
29-
long
30-
}, (error, files) => {
31-
if (error) {
32-
throw error
33-
}
34-
35-
files.forEach(link => {
36-
if (long) {
37-
return print(`${link.name} ${link.hash} ${link.size}`)
38-
}
39-
40-
print(link.name)
41-
})
42-
})
33+
argv.resolve(
34+
ipfs.files.ls(path || FILE_SEPARATOR)
35+
.then(files => {
36+
if (long) {
37+
const table = []
38+
const lengths = {}
39+
40+
files.forEach(link => {
41+
const row = {
42+
name: `${link.name}`,
43+
hash: `${link.hash}`,
44+
size: `${link.size}`
45+
}
46+
47+
Object.keys(row).forEach(key => {
48+
const value = row[key]
49+
50+
lengths[key] = lengths[key] > value.length ? lengths[key] : value.length
51+
})
52+
53+
table.push(row)
54+
})
55+
56+
table.forEach(row => {
57+
let line = ''
58+
59+
Object.keys(row).forEach(key => {
60+
const value = row[key]
61+
62+
line += value.padEnd(lengths[key])
63+
line += '\t'
64+
})
65+
66+
print(line)
67+
})
68+
69+
return
70+
}
71+
72+
files.forEach(link => print(link.name))
73+
})
74+
)
4375
}
4476
}

src/cli/mkdir.js

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
'use strict'
22

33
const {
4-
print
4+
asBoolean
55
} = require('./utils')
66

77
module.exports = {
88
command: 'mkdir <path>',
99

10-
describe: 'Make directories.',
10+
describe: 'Make mfs directories',
1111

1212
builder: {
1313
parents: {
1414
alias: 'p',
1515
type: 'boolean',
1616
default: false,
17+
coerce: asBoolean,
1718
describe: 'No error if existing, make parent directories as needed.'
1819
},
1920
cidVersion: {
@@ -28,6 +29,7 @@ module.exports = {
2829
flush: {
2930
alias: 'f',
3031
type: 'boolean',
32+
coerce: asBoolean,
3133
describe: 'Weird undocumented option'
3234
}
3335
},
@@ -42,17 +44,13 @@ module.exports = {
4244
flush
4345
} = argv
4446

45-
ipfs.mfs.mkdir(path, {
46-
parents,
47-
cidVersion,
48-
hash,
49-
flush
50-
}, (error, result) => {
51-
if (error) {
52-
throw error
53-
}
54-
55-
print(result)
56-
})
47+
argv.resolve(
48+
ipfs.files.mkdir(path, {
49+
parents,
50+
cidVersion,
51+
hash,
52+
flush
53+
})
54+
)
5755
}
5856
}

src/cli/mv.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
'use strict'
22

3+
const {
4+
asBoolean
5+
} = require('./utils')
6+
37
module.exports = {
48
command: 'mv <source> <dest>',
59

6-
describe: 'Move files around. Just like traditional unix mv',
10+
describe: 'Move mfs files around',
711

812
builder: {
913
parents: {
1014
alias: 'p',
1115
type: 'boolean',
1216
default: false,
17+
coerce: asBoolean,
1318
describe: 'Create any non-existent intermediate directories'
1419
},
1520
recursive: {
1621
alias: 'r',
1722
type: 'boolean',
1823
default: false,
24+
coerce: asBoolean,
1925
describe: 'Remove directories recursively'
2026
}
2127
},
@@ -29,13 +35,11 @@ module.exports = {
2935
recursive
3036
} = argv
3137

32-
ipfs.mfs.mv(source, dest, {
33-
parents,
34-
recursive
35-
}, (error) => {
36-
if (error) {
37-
throw error
38-
}
39-
})
38+
argv.resolve(
39+
ipfs.files.mv(source, dest, {
40+
parents,
41+
recursive
42+
})
43+
)
4044
}
4145
}

0 commit comments

Comments
 (0)