veged / coa Goto Github PK
View Code? Open in Web Editor NEWCommand-Option-Argument: Get more from defining your command line interface
License: MIT License
Command-Option-Argument: Get more from defining your command line interface
License: MIT License
One could run bem my
and COA should try to search for bem-cmd-my
module and if not found for binary bem-my
in PATH
and run the found one.
Also think of shell completion for custom commands.
To provide a better user experience we should not force event loop to stop since some library code can require additional things to do.
In other words we should set exitCode
instead of calling exit()
method.
Line 197 in fb1080e
Минимальный пример, показывающий, что команды совсем не работают:
require('../lib/coa').Cmd()
.name('cmd')
.title('Command test')
.helpful()
.cmd()
.name('command')
.title('Do command work')
.helpful()
.act(function() {
console.log('Doing command work...');
})
.end()
.run(['command', '--help'])
.run(['command']);
bem-tools can now work with node 0.5+, but coa strictly depends on node ~0.4.0
, that prevents bem-tools from installing on node 0.5.x.
Need to bump up node version dependence to:
{
"node" : ">=0.4.0 <0.7.0"
}
The program ends without errors if errors throws in async functions.
Example:
cmd()
.act((options) => {
setTimeout(() => {
throw new Error('catch me if you can')
}, 100)
})
.run()
As per http://bem.info/tools/bem/installation/ I 'm running bem completion
, which fails with
$ bem completion
Error: shell completion not supported on windows
at Cmd.module.exports (c:\Users\leonids.maslovs\AppData\Roaming\npm\node_modules\bem\node_modules\coa\lib\completion.js:19:11)
at exports.Cmd.Cmd._do (c:\Users\leonids.maslovs\AppData\Roaming\npm\node_modules\bem\node_modules\coa\lib\cmd.js:429:22)
From previous event:
at Cmd.exports.Cmd.Cmd._do (c:\Users\leonids.maslovs\AppData\Roaming\npm\node_modules\bem\node_modules\coa\lib\cmd.js:424:14)
at Cmd.exports.Cmd.Cmd.do (c:\Users\leonids.maslovs\AppData\Roaming\npm\node_modules\bem\node_modules\coa\lib\cmd.js:471:17)
at Cmd.exports.Cmd.Cmd.run (c:\Users\leonids.maslovs\AppData\Roaming\npm\node_modules\bem\node_modules\coa\lib\cmd.js:459:22)
at Object.<anonymous> (c:\Users\leonids.maslovs\AppData\Roaming\npm\node_modules\bem\bin\bem:6:23)
I appears the problem is with ./blob/master/lib/completion.js#L18-23
If I comment it out - it works perfectly well and generated autocomplete code works for me (.bashrc). In my opinion - completion.js either should comment it out completely or should check for execution environment (e.g. bash, msys etc ..). What's you opinion on this? If the later is the case, I could try to comeup with pull-request (though I'm unfamiliar with nodejs thing and that might be a personal challenge to some degree ;) )
PS: following environment variables are available:
MACHTYPE=i686-pc-msys
OSTYPE=msys
Нужна возможность реализовывать опции-комманды вроде --help и --version.
Выполнение act() для этих опций должно прерывать цепочку всех действий команды, но не завершать выполнение команды с ошибкой. Поэтому this.reject() не подходит.
Кроме прочего не хочется сильно усложнять существующий API и хочется попробовать вписать это в Promises API.
Варианты такие.
Hi there,
We were wondering if you might consider adding one so that we can use your package. Thanks!
We could implement fsPath(glob)
(or something) helper for Opt
and Arg
that will add shell completion for the opt/arg on fs paths.
For example:
program --opt="--one --two"
here we have one option
but coa
thinks there are three of them
Если есть хотя бы одна из опций с req() и есть какой-нибудь --version, запуск ./cmd --version будет фейлиться из-за отсутствующей опции с req()
cmd.opt()
.name('format')
.title('Output format: html, bemjson. Defaults to html')
.short('f')
.long('format')
.def('html')
.val(function(value) {
// FIXME: don't use private API _usage()
!value && this.end().errorExit("Missing required option value\n" + this._usage());
(['html', 'bemjson'].indexOf(value) == -1) && this.end()
.errorExit('Wrong output format "' + value + '" specified, must be one of "html" or "bemjson"');
return value;
})
.end()
My proposal it to change API of .act()
callbacks from
function(opts, args) {
}
to
function(options) {
// options = opts + args
}
The difference between opts
and args
in semantical only and only make sense when command is run from the command line
It is hard to explain to develepor what the difference between opts
and args
when it uses COA API to run command
Division into two different arguments makes sense in case when opts
is a hash and args
is an array
Compare
var BEM = require('bem');
BEM.api.create.block({ tech: ['css', 'js'] }, { names: ['b1', 'b2'] });
and
var BEM = require('bem');
BEM.api.create.block({ names: ['b1', 'b2'], tech: ['css', 'js'] });
/cc @veged
Hi!
I'm using coa in my-script.js
this way:
require('coa').Cmd()
.name(process.argv[1]).title('Makes awesome things').helpful()
.opt()
.name('awesomeOpt')
.title('My awesome option')
.long('awesome-opt')
.arr()
.def(['1', '2'])
.end()
.act(opts => console.log(opts))
.run();
Then I run my script:
$ node my-script.js
The output is:
{ awesomeOpt: [['1', '2']] }
but I expected:
{ awesomeOpt: ['1', '2'] }
Built-in shell-mode for calling commands via stdin
killme.js:
require('coa').Cmd()
.act(function(opts, args) {
return 'o.O';
})
.run();
$ node killme.js > killme.txt
o.O
$ cat ./killme.txt
# nothing
$ node killme.js 2> killme.txt
$ cat ./killme.txt
o.O
I want to add variadic options support to COA.
What is a preferred solution?
Cmd
flag-method like allowAny()
, that will translate all specified cmd options to opts
regardless of there existence in the command descriptionOpt
flag-method like prefixed()
, that will translate all the options with common prefix that equals to opt
name to opts.<opt-name>
object as propertiesAtm there are few different ways of using namespaces: {COA.Cmd}
, {Cmd}
, etc. Need to choose one.
Prerequisites:
.arg()
.name('name')
.title('some description')
.req()
.end()
Bug:
Pass ""
as an argument -> error:
Missing required argument:
NAME : some description (required)
UPD: Empty string can't be passed as argument at all. Remove .req()
from the example above, pass ""
as an argument and there will be no arguments at all, but should be argument with name name
To simplify contribution and development of this project
Hi.
In current versions long options will never work. This is a path to fix it: https://gist.github.com/1165284.
No breaking changes were introduced in 1.0.0: https://github.com/kriskowal/q/blob/v1/CHANGES.md
I encourage you to change dependency to "q": "^1.0.0"
I do not see any API breaking changes.
I'm right?
Deprecated mocha-as-promised
package is not compatible with mocha ~1.12.0
long
, title
should use name
to generate default
.
Also opt should not crash on opts without short
/long
.
end
should throw If the name
wasn't passed in.
Consider such code:
require('coa').Cmd()
.name('myscript')
.helpful()
.opt()
.name('target')
.title('Target')
.short('t').long('target')
.req()
.end()
.opt()
.name('path')
.title('Path')
.short('p').long('path')
.def('~/bin')
.end()
.run()
When I add the "req()" method to an option, I expect to get a kind of hint on the help sheet, that the option is required. However, I get the same descriptions for different kinds of options.
£ ./myscript -h
Usage:
myscript [OPTIONS] [ARGS]
Options:
-h, --help : Help
-t TARGET, --target=TARGET : Target
-p PATH, --path=PATH : Path
Need to make a test for exitCode: #89
Should you more precise one from karma
for example.
###-begin-karma-completion-###
#
# karma command completion script
# This is stolen from NPM. Thanks @isaac!
#
# Installation: karma completion >> ~/.bashrc (or ~/.zshrc)
# Or, maybe: karma completion > /usr/local/etc/bash_completion.d/karma
#
if type complete &>/dev/null; then
__karma_completion () {
local si="$IFS"
IFS=$'\n' COMPREPLY=($(COMP_CWORD="$COMP_CWORD" \
COMP_LINE="$COMP_LINE" \
COMP_POINT="$COMP_POINT" \
karma completion -- "${COMP_WORDS[@]}" \
2>/dev/null)) || return $?
IFS="$si"
}
complete -F __karma_completion karma
elif type compdef &>/dev/null; then
__karma_completion() {
si=$IFS
compadd -- $(COMP_CWORD=$((CURRENT-1)) \
COMP_LINE=$BUFFER \
COMP_POINT=0 \
karma completion -- "${words[@]}" \
2>/dev/null)
IFS=$si
}
compdef __karma_completion karma
elif type compctl &>/dev/null; then
__karma_completion () {
local cword line point words si
read -Ac words
read -cn cword
let cword-=1
read -l line
read -ln point
si="$IFS"
IFS=$'\n' reply=($(COMP_CWORD="$cword" \
COMP_LINE="$line" \
COMP_POINT="$point" \
karma completion -- "${words[@]}" \
2>/dev/null)) || return $?
IFS="$si"
}
compctl -K __karma_completion karma
fi
###-end-karma-completion-###
arikon-osx% bem create -l \"Calibre\ Library/\"
\"Calibre\ Library/\" .gitconfig
There should be now \
before "
.
Example:
Cmd()
.opt()
.name('a')
.short('a')
.def(false) // .def(0)
.end()
.act((options) => {
console.log(options) // => {}
})
Expected options return { a: false }
It's a major change but it will add a way to extend basic behaviour of helpers.
E.g. .helpful().title('another title').act(function() { doSomething(); return this.__base.apply(); }).end()
.
As temporary (or persistent) alternative we can add an option like .helpful({ endless: true })
.
See #65
I dunno who's at fault for this one. SVGO depends on COA, but when you use COA 1.0.2 the termination code for svgo -v
at the command line is incorrect, which breaks integration with other tools. When you use COA 1.0.1, it works just fine. I'm looping you in so somebody can figure out what's up.
See: svg/svgo#739
There's no reason to have the test
and tests
directories in production through npm install
. It's wasteful! You can ignore them easily through an .npmignore
file or whitelisting files in the package.json
. I can do both as a PR if you want.
One could define alias as cb = create -b
and invoke bem cb block
. COA should resolve cb
alias and invoke bem create -b block
command.
Also think of shell completion for aliases.
Rel: #66
Demo of problem, see comment inside code block:
var FS = require('fs'),
output = process.stdout
data = getData();
output = FS.createWriteStream('exit-test.txt');
output.on('end', function() {
console.log('output stream end');
});
output.write(data);
if (output !== process.stdout) output.end();
process.once('exit', function(code) {
code = code || 0;
console.log('about to exit with code %s', code);
process.exit(code);
});
// Uncomment, and exit-test.txt wiil be empty
//process.exit(1);
function getData() {
var data = '';
for (var i = 0; i < 5000000; i++) {
data += 'a';
}
return data;
}
Feels like this project in stale state because of coffeescript.
What about rewriting it to plain js or es6?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.