-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: CLI should accept content from stdin (#474) #785
Changes from all commits
242b165
ed3f719
bd8a691
784046c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
|
||
const fs = require('fs') | ||
const path = require('path') | ||
const stream = require('stream') | ||
const glob = require('glob') | ||
const sortBy = require('lodash.sortby') | ||
const pull = require('pull-stream') | ||
|
@@ -36,6 +37,19 @@ function checkPath (inPath, recursive) { | |
return inPath | ||
} | ||
|
||
function printResult (added) { | ||
sortBy(added, 'path') | ||
.reverse() | ||
.map((file) => { | ||
const log = [ 'added', file.hash ] | ||
|
||
if (file.path.length > 0) log.push(file.path) | ||
|
||
return log.join(' ') | ||
}) | ||
.forEach((msg) => console.log(msg)) | ||
} | ||
|
||
module.exports = { | ||
command: 'add <file>', | ||
|
||
|
@@ -69,8 +83,7 @@ module.exports = { | |
}, | ||
|
||
handler (argv) { | ||
const inPath = checkPath(argv.file, argv.recursive) | ||
const index = inPath.lastIndexOf('/') + 1 | ||
const hasPipedArgs = argv.hasPipedArgs | ||
const options = { | ||
strategy: argv.trickle ? 'trickle' : 'balanced', | ||
shardSplitThreshold: argv.enableShardingExperiment ? argv.shardSplitThreshold : Infinity | ||
|
@@ -94,26 +107,62 @@ module.exports = { | |
} | ||
} | ||
|
||
createAddStream((err, addStream) => { | ||
if (err) { | ||
// if there are piped arguments, input is data to publish instead of a file | ||
// path | ||
if(hasPipedArgs) { | ||
const data = argv.file | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the whole file is going to be buffered before the command is triggered. I assumed that since this is for a CLI interface, it would make sense to do so. So it's better to buffer the file using streams and make it async? |
||
const dataStream = new stream.Readable() | ||
dataStream.push(Buffer.from(data, 'utf8')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might not be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, it can use the default. I will remove that option parameter. |
||
dataStream.push(null) | ||
createAddStream((err, addStream) => { | ||
if(err) | ||
throw err | ||
} | ||
|
||
addDataPipeline([dataStream], addStream) | ||
}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something doesn't look right here:
If you want to add one stream, you should not need to call that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. So the right solution would be to do something like this?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, see: #785 (review) |
||
} | ||
else { | ||
const inPath = checkPath(argv.file, argv.recursive) | ||
const index = inPath.lastIndexOf('/') + 1 | ||
|
||
glob(path.join(inPath, '/**/*'), (err, list) => { | ||
createAddStream((err, addStream) => { | ||
if (err) { | ||
throw err | ||
} | ||
if (list.length === 0) { | ||
list = [inPath] | ||
} | ||
|
||
glob(path.join(inPath, '/**/*'), (err, list) => { | ||
if (err) { | ||
throw err | ||
} | ||
if (list.length === 0) { | ||
list = [inPath] | ||
} | ||
|
||
addFilePipeline(index, addStream, list, argv.wrapWithDirectory) | ||
}) | ||
}) | ||
} | ||
} | ||
} | ||
|
||
addPipeline(index, addStream, list, argv.wrapWithDirectory) | ||
}) | ||
function addDataPipeline (dataStream, addStream) { | ||
pull( | ||
pull.values(dataStream), | ||
pull.map(dataStream => { | ||
return { path: '', content: dataStream } | ||
}), | ||
addStream, | ||
pull.collect((err, added) => { | ||
if(err) { | ||
throw err | ||
} | ||
printResult(added) | ||
}) | ||
} | ||
) | ||
} | ||
|
||
function addPipeline (index, addStream, list, wrapWithDirectory) { | ||
|
||
function addFilePipeline (index, addStream, list, wrapWithDirectory) { | ||
pull( | ||
zip( | ||
pull.values(list), | ||
|
@@ -122,16 +171,19 @@ function addPipeline (index, addStream, list, wrapWithDirectory) { | |
paramap(fs.stat.bind(fs), 50) | ||
) | ||
), | ||
pull.map((pair) => ({ | ||
path: pair[0], | ||
isDirectory: pair[1].isDirectory() | ||
})), | ||
pull.filter((file) => !file.isDirectory), | ||
pull.map((pair) => { | ||
return ({ | ||
path: pair[0], | ||
isDirectory: pair[1].isDirectory() | ||
})}), | ||
pull.filter((file) => { | ||
return !file.isDirectory | ||
}), | ||
pull.map((file) => ({ | ||
path: file.path.substring(index, file.path.length), | ||
originalPath: file.path | ||
})), | ||
pull.map((file) => ({ | ||
pull.map((file) => ({ | ||
path: wrapWithDirectory ? path.join(WRAPPER, file.path) : file.path, | ||
content: fs.createReadStream(file.originalPath) | ||
})), | ||
|
@@ -144,17 +196,7 @@ function addPipeline (index, addStream, list, wrapWithDirectory) { | |
if (err) { | ||
throw err | ||
} | ||
|
||
sortBy(added, 'path') | ||
.reverse() | ||
.map((file) => { | ||
const log = [ 'added', file.hash ] | ||
|
||
if (file.path.length > 0) log.push(file.path) | ||
|
||
return log.join(' ') | ||
}) | ||
.forEach((msg) => console.log(msg)) | ||
printResult(added) | ||
}) | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be missing a few commands.
config
andpubsub
are two I remember from the top of my head, but I guess there is more.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is a Github search that shows which
go-ipfs
commands accepts stdin: https://github.com/ipfs/go-ipfs/search?utf8=%E2%9C%93&q=EnableStdin&type=