Skip to content

Commit

Permalink
Add prompt and dat.json to dat create (#765)
Browse files Browse the repository at this point in the history
* make create command much nicer

* add dat-json package + standard

* a bit of cleanup

* move key + plural to elements

* exit on prompt error

* fix prompt for tests
  • Loading branch information
joehand authored May 20, 2017
1 parent 653e464 commit 1343821
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 20 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"cli-truncate": "^1.0.0",
"dat-doctor": "^1.2.5",
"dat-encoding": "^4.0.2",
"dat-json": "^1.0.0",
"dat-link-resolve": "^1.0.0",
"dat-node": "^3.3.0",
"dat-registry": "^2.1.2",
Expand Down
72 changes: 65 additions & 7 deletions src/commands/create.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
var path = require('path')
var fs = require('fs')
var Dat = require('dat-node')
var neatLog = require('neat-log')
var archiveUI = require('../ui/archive')
var DatJson = require('dat-json')
var prompt = require('prompt')
var chalk = require('chalk')
var createUI = require('../ui/create')
var trackArchive = require('../lib/archive')
var onExit = require('../lib/exit')
// var datJson = require('../dat-json') TODO: dat-node/use module
var debug = require('debug')('dat')

module.exports = {
Expand All @@ -19,7 +23,7 @@ module.exports = {
name: 'import',
boolean: true,
default: false,
help: 'Import files in the given directory'
help: 'Import files from the directory'
},
{
name: 'ignoreHidden',
Expand All @@ -41,7 +45,7 @@ function create (opts) {
// Todo
// debug('Creating Dat archive in', opts.dir)

var neat = neatLog(archiveUI, { logspeed: opts.logspeed, quiet: opts.quiet })
var neat = neatLog(createUI, { logspeed: opts.logspeed, quiet: opts.quiet })
neat.use(trackArchive)
neat.use(onExit)
neat.use(function (state, bus) {
Expand All @@ -52,9 +56,63 @@ function create (opts) {
if (err && err.name === 'ExistsError') return bus.emit('exit:warn', 'Archive already exists.')
if (err) return bus.emit('exit:error', err)

// TODO: dat.json creation/write key
state.dat = dat
bus.emit('dat')
// create before import
var datjson = DatJson(dat.archive, { file: path.join(opts.dir, 'dat.json') })
fs.readFile(path.join(opts.dir, 'dat.json'), 'utf-8', function (err, data) {
if (err || !data) return doPrompt()
data = JSON.parse(data)
debug('read existing dat.json data', data)
doPrompt(data)
})

function doPrompt (data) {
if (!data) data = {}

var schema = {
properties: {
title: {
description: chalk.magenta('Dat Title'),
default: data.title || '',
// pattern: /^[a-zA-Z\s\-]+$/,
// message: 'Name must be only letters, spaces, or dashes',
required: false
},
description: {
description: chalk.magenta('Dat Description'),
default: data.description || ''
},
doImport: {
description: chalk.magenta('Would you like to import your files?'),
default: 'yes'
}
}
}
if (opts.title || opts.description) {
// avoid setting import unless these title/desc are set
var doImport = opts.import ? 'yes' : 'no'
prompt.override = { title: opts.title, description: opts.description, doImport: doImport }
}
prompt.message = chalk.green('> ')
prompt.delimiter = '' // chalk.cyan('')
prompt.start()
prompt.get(schema, writeDatJson)

function writeDatJson (err, results) {
if (err) return bus.emit('exit:error', err) // prompt error
if (results.doImport[0] === 'y') state.opts.import = true
if (!results.title && !results.description) return done()
delete results.doImport // don't want this in dat.json
datjson.create(results, done)
}

function done (err) {
if (err) return bus.emit('exit:error', err)
state.title = 'Creating a new dat'
state.dat = dat
bus.emit('dat')
bus.emit('render')
}
}
bus.emit('render')
})
})
Expand Down
1 change: 1 addition & 0 deletions src/lib/import-progress.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function trackImport (state, bus) {
var progress = state.dat.importFiles(state.opts, function (err) {
if (err) return bus.emit('exit:error', err)
state.importer.fileImport = null
state.exiting = true
bus.emit('render')
})
state.importer = xtend({
Expand Down
7 changes: 4 additions & 3 deletions src/ui/archive.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
var output = require('neat-log/output')
var stringKey = require('dat-encoding').toStr
var pretty = require('prettier-bytes')
var chalk = require('chalk')
var downloadUI = require('./components/download')
var importUI = require('./components/import-progress')
var networkUI = require('./components/network')
var sourcesUI = require('./components/sources')
var keyEl = require('./elements/key')
var pluralize = require('./elements/pluralize')

module.exports = archiveUI

Expand All @@ -19,12 +20,12 @@ function archiveUI (state) {
var progressView

if (state.writable || state.opts.showKey) {
title = `${chalk.blue('dat://' + stringKey(dat.key))}\n`
title = `${keyEl(dat.key)}\n`
}
if (state.title) title += state.title
else if (state.writable) title += 'Sharing dat'
else title += 'Downloading dat'
if (stats.version > 0) title += `: ${stats.files} files (${pretty(stats.byteLength)})`
if (stats.version > 0) title += `: ${stats.files} ${pluralize('file', stats.file)} (${pretty(stats.byteLength)})`
else if (stats.version === 0) title += ': (empty archive)'
if (state.http && state.http.listening) title += `\nServing files over http at http://localhost:${state.http.port}`

Expand Down
5 changes: 1 addition & 4 deletions src/ui/components/network.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var output = require('neat-log/output')
var pretty = require('prettier-bytes')
var pluralize = require('../elements/pluralize')

module.exports = networkUI

Expand All @@ -23,8 +24,4 @@ function networkUI (state) {
output += ` Upload ${pretty(upSpeed)}/s `
return output
}

function pluralize (str, val) {
return `${str}${val === 1 ? '' : 's'}`
}
}
51 changes: 51 additions & 0 deletions src/ui/create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
var output = require('neat-log/output')
var pretty = require('prettier-bytes')
var chalk = require('chalk')
var importUI = require('./components/import-progress')
var keyEl = require('./elements/key')
var pluralize = require('./elements/pluralize')

module.exports = createUI

function createUI (state) {
if (!state.dat) {
return output`
Creating a Dat! Add information to your dat.json file:
`
}

var dat = state.dat
var stats = dat.stats.get()
var title = '\n'
var progressView
var exitMsg = `
Your dat is created! Run ${chalk.green('dat sync')} to share:
${keyEl(dat.key)}
`
if (!state.opts.import) {
// set exiting right away
state.exiting = true
}

if (!state.exiting) {
// Only show key if not about to exit
title = `${keyEl(dat.key)}\n`
}
if (state.title) title += state.title

if (stats.version > 0) title += `: ${stats.files} ${pluralize('file', stats.files)} (${pretty(stats.byteLength)})`
else if (stats.version === 0) title += ': (empty archive)'

if (state.opts.import) {
progressView = importUI(state) + '\n'
} else {
progressView = 'Not importing files.'
}

return output`
${title}
${progressView}
${state.exiting ? exitMsg : chalk.dim('Ctrl+C to Exit')}
`
}
6 changes: 6 additions & 0 deletions src/ui/elements/key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
var stringKey = require('dat-encoding').toStr
var chalk = require('chalk')

module.exports = function (key) {
return `${chalk.blue(`dat://${stringKey(key)}`)}`
}
3 changes: 3 additions & 0 deletions src/ui/elements/pluralize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function pluralize (str, val) {
return `${str}${val === 1 ? '' : 's'}`
}
12 changes: 6 additions & 6 deletions test/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ try { fs.unlinkSync(path.join(fixtures, 'dat.json')) } catch (e) { /* ignore err

test('create - default opts no import', function (t) {
tempDir(function (_, dir, cleanup) {
var cmd = dat + ' create'
var cmd = dat + ' create --title data --description thing'
var st = spawn(t, cmd, {cwd: dir})

st.stdout.match(function (output) {
Expand All @@ -37,7 +37,7 @@ test('create - default opts no import', function (t) {

test('create - default opts with import', function (t) {
tempDir(function (_, dir, cleanup) {
var cmd = dat + ' create --import'
var cmd = dat + ' create --title data --description thing --import'
var st = spawn(t, cmd, {cwd: dir})

st.stdout.match(function (output) {
Expand All @@ -62,7 +62,7 @@ test('create - errors on existing archive', function (t) {
Dat(dir, function (err, dat) {
t.error(err, 'no error')
dat.close(function () {
var cmd = dat + ' create'
var cmd = dat + ' create --title data --description thing'
var st = spawn(t, cmd, {cwd: dir})
st.stderr.match(function (output) {
t.ok(output, 'errors')
Expand All @@ -77,7 +77,7 @@ test('create - errors on existing archive', function (t) {

test('create - sync after create ok', function (t) {
tempDir(function (_, dir, cleanup) {
var cmd = dat + ' create'
var cmd = dat + ' create --title data --description thing'
var st = spawn(t, cmd, {cwd: dir, end: false})
st.stdout.match(function (output) {
var connected = output.indexOf('Not importing files') > -1
Expand All @@ -104,7 +104,7 @@ test('create - sync after create ok', function (t) {

test('create - init alias', function (t) {
tempDir(function (_, dir, cleanup) {
var cmd = dat + ' init'
var cmd = dat + ' init --title data --description thing'
var st = spawn(t, cmd, {cwd: dir})

st.stdout.match(function (output) {
Expand All @@ -124,7 +124,7 @@ test('create - init alias', function (t) {

test('create - with path', function (t) {
tempDir(function (_, dir, cleanup) {
var cmd = dat + ' init ' + dir
var cmd = dat + ' init ' + dir + ' --title data --description thing'
var st = spawn(t, cmd)
st.stdout.match(function (output) {
var datCreated = output.indexOf('Not importing files') > -1
Expand Down

0 comments on commit 1343821

Please sign in to comment.