Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #44 from nfischer/export-command
Adding export command
- Loading branch information
Showing
10 changed files
with
293 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#!/usr/bin/env node | ||
require('./parser')(process.argv, 'export'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
'use strict'; | ||
|
||
var interfacer = require('./../util/interfacer'); | ||
var preparser = require('./../preparser'); | ||
|
||
var _export = { | ||
exec: function exec(args, options) { | ||
args = args || []; | ||
options = options || {}; | ||
|
||
if (args.length < 1) { | ||
options.p = true; | ||
} | ||
|
||
if (typeof args === 'string' || args instanceof String) { | ||
args = [args]; | ||
} | ||
|
||
// Parse similarly to how `alias` does | ||
var id = args.join(' '); | ||
var value = ''; | ||
if (String(id).indexOf('=') > -1) { | ||
var parts = String(id).trim().split('='); | ||
id = parts[0]; | ||
value = parts[1] || value; | ||
if (value.match(/^".*"$/)) { | ||
value = JSON.parse(value); | ||
} else { | ||
var regMatch = value.match(/^'(.*)'$/); | ||
if (regMatch && regMatch[1]) { | ||
value = regMatch[1]; | ||
} | ||
} | ||
} else { | ||
var parts = String(id).trim().split(' '); | ||
id = parts.shift(); | ||
value = parts.join(' ') || null; | ||
} | ||
|
||
var validIdRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/; | ||
if (options.p) { | ||
for (var name in process.env) { | ||
if (process.env.hasOwnProperty(name)) { | ||
this.log('declare -x ' + String(name) + '=' + JSON.stringify(process.env[name]).replace(/\$/g, '\\$')); | ||
} | ||
} | ||
} else if (id.match(validIdRegex)) { | ||
process.env[id] = value !== null ? value : process.env[id]; | ||
} else { | ||
this.log('-cash: export: `' + id + '\': not a valid identifier'); | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} | ||
}; | ||
|
||
module.exports = function (vorpal) { | ||
if (vorpal === undefined) { | ||
return _export; | ||
} | ||
vorpal.api.export = _export; | ||
vorpal.command('export [name...]').parse(preparser).option('-p', 'print all defined aliases in a reusable format').action(function (args, callback) { | ||
args.options = args.options || {}; | ||
return interfacer.call(this, { | ||
command: _export, | ||
args: args.name, | ||
options: args.options, | ||
callback: callback | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
'use strict'; | ||
|
||
const interfacer = require('./../util/interfacer'); | ||
const preparser = require('./../preparser'); | ||
|
||
const _export = { | ||
|
||
exec(args, options) { | ||
args = args || []; | ||
options = options || {}; | ||
|
||
if (args.length < 1) { | ||
options.p = true; | ||
} | ||
|
||
if (typeof args === 'string' || args instanceof String) { | ||
args = [args]; | ||
} | ||
|
||
// Parse similarly to how `alias` does | ||
let id = args.join(' '); | ||
let value = ''; | ||
if (String(id).indexOf('=') > -1) { | ||
const parts = String(id).trim().split('='); | ||
id = parts[0]; | ||
value = parts[1] || value; | ||
if (value.match(/^".*"$/)) { | ||
value = JSON.parse(value); | ||
} else { | ||
const regMatch = value.match(/^'(.*)'$/); | ||
if (regMatch && regMatch[1]) { | ||
value = regMatch[1]; | ||
} | ||
} | ||
} else { | ||
const parts = String(id).trim().split(' '); | ||
id = parts.shift(); | ||
value = parts.join(' ') || null; | ||
} | ||
|
||
const validIdRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/; | ||
if (options.p) { | ||
for (const name in process.env) { | ||
if (process.env.hasOwnProperty(name)) { | ||
this.log(`declare -x ${String(name)}=${JSON.stringify(process.env[name]) | ||
.replace(/\$/g, '\\$')}`); | ||
} | ||
} | ||
} else if (id.match(validIdRegex)) { | ||
process.env[id] = value !== null ? value : process.env[id]; | ||
} else { | ||
this.log(`-cash: export: \`${id}': not a valid identifier`); | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} | ||
}; | ||
|
||
module.exports = function (vorpal) { | ||
if (vorpal === undefined) { | ||
return _export; | ||
} | ||
vorpal.api.export = _export; | ||
vorpal | ||
.command('export [name...]') | ||
.parse(preparser) | ||
.option('-p', 'print all defined aliases in a reusable format') | ||
.action(function (args, callback) { | ||
args.options = args.options || {}; | ||
return interfacer.call(this, { | ||
command: _export, | ||
args: args.name, | ||
options: args.options, | ||
callback | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
module.exports = ` | ||
Usage: export [OPTION] [name[=value]] | ||
Export variables into the environment | ||
Without arguments, \`export' prints the list of environnmental variables in the | ||
form \`declare -x NAME="VALUE"' on standard output. This is the same as the | ||
behavior if \`-p' is given. | ||
Otherwise, the variable is exported to the environment. If the variable has | ||
already been defined in the environment (ex. \`PATH'), then this will either | ||
redefine its value or do nothing (if no value is passed in). If the variable is | ||
not already in the environment, it will be added with the \`VALUE' given | ||
(defaults to the empty string). | ||
-p print all exported variables in a reusable format | ||
--help display this help and exit | ||
Report export bugs to <https://github.com/dthree/cash> | ||
Cash home page: <http://cash.js.org/> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
'use strict'; | ||
|
||
require('assert'); | ||
const should = require('should'); | ||
const cash = require('../dist/index.js'); | ||
|
||
let oldProcessEnv; | ||
|
||
describe('export', function () { | ||
before(function () { | ||
oldProcessEnv = process.env; | ||
}); | ||
|
||
beforeEach(function () { | ||
process.env = {}; | ||
}); | ||
|
||
after(function () { | ||
process.env = oldProcessEnv; | ||
}); | ||
|
||
it('should exist and be a function', function () { | ||
should.exist(cash.export); | ||
}); | ||
|
||
it('should create an export with an equal symbol', function () { | ||
(function () { | ||
cash.export(['foo=bar']); | ||
}).should.not.throw(); | ||
cash('echo $foo').should.equal('bar\n'); | ||
}); | ||
|
||
it('should accept a string argument', function () { | ||
(function () { | ||
cash.export('foo=bar'); | ||
}).should.not.throw(); | ||
cash('echo $foo').should.equal('bar\n'); | ||
}); | ||
|
||
it('should print msg when reading an invalid export', function () { | ||
cash.export(['1lalalala']).should.equal('-cash: export: `1lalalala\': not a valid identifier\n'); | ||
cash.export(['la@lalala']).should.equal('-cash: export: `la@lalala\': not a valid identifier\n'); | ||
}); | ||
|
||
it('should reassign an export', function () { | ||
(function () { | ||
cash.export(['foo=cows']); | ||
cash.export(['foo=dogs']); | ||
}).should.not.throw(); | ||
cash('echo $foo').should.equal('dogs\n'); | ||
}); | ||
|
||
it('should do nothing if already exported', function () { | ||
(function () { | ||
cash.export(['PATH=/usr/bin']); | ||
cash.export(['PATH']); | ||
}).should.not.throw(); | ||
cash('echo $PATH').should.equal(`${process.env.PATH}\n`); | ||
cash('echo $PATH').should.equal('/usr/bin\n'); | ||
}); | ||
|
||
it('should work without surrounding quotes', function () { | ||
cash.export(['foo=bar']); | ||
cash('echo $foo').should.equal('bar\n'); | ||
}); | ||
|
||
it('should deal with surrounding single quotes', function () { | ||
cash.export(['foo=\'bar tender nice to meet you\'']); | ||
cash('echo $foo').should.equal('bar tender nice to meet you\n'); | ||
}); | ||
|
||
it('should deal with surrounding double quotes', function () { | ||
cash.export(['foo="bar tender nice to meet you"']); | ||
cash('echo $foo').should.equal('bar tender nice to meet you\n'); | ||
}); | ||
|
||
it('should handle multiple exports', function () { | ||
(function () { | ||
cash.export(['a="A"']); | ||
cash.export(['b=\'B\'']); | ||
cash.export(['c="C"']); | ||
}).should.not.throw(); | ||
cash('echo $a $b $c').should.equal('A B C\n'); | ||
}); | ||
|
||
it('should list all registered aliases', function () { | ||
(function () { | ||
cash.export(['a="A"']); | ||
cash.export(['b=\'B\'']); | ||
cash.export(['c="C"']); | ||
}).should.not.throw(); | ||
cash.export().should.equal('declare -x a="A"\ndeclare -x b="B"\ndeclare -x c="C"\n'); | ||
}); | ||
|
||
describe('-p', function () { | ||
it('should list all registered exports', function () { | ||
(function () { | ||
cash.export(['a="A"']); | ||
cash.export(['b=\'B\'']); | ||
cash.export(['c="C"']); | ||
}).should.not.throw(); | ||
cash.export(undefined, {p: true}).should.equal('declare -x a="A"\ndeclare -x b="B"\ndeclare -x c="C"\n'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters