coa 0.3.9 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmignore +1 -0
- package/.travis.yml +3 -4
- package/README.md +6 -1
- package/README.ru.md +316 -0
- package/lib/arg.js +1 -1
- package/lib/cmd.js +60 -6
- package/lib/color.js +1 -1
- package/lib/completion.js +2 -2
- package/lib/index.js +5 -2
- package/lib/opt.js +1 -1
- package/lib/shell.js +1 -2
- package/package.json +7 -8
- package/src/cmd.coffee +58 -4
- package/src/index.coffee +2 -0
- package/test/coa.js +91 -17
- package/test/mocha.opts +1 -3
- package/tests/api-h.js +1 -1
- package/test/common.js +0 -1
package/.npmignore
CHANGED
package/.travis.yml
CHANGED
package/README.md
CHANGED
|
@@ -227,6 +227,11 @@ Default value passed through validation function as ordinary value.<br>
|
|
|
227
227
|
**@param** *Object* `_def`<br>
|
|
228
228
|
**@returns** *COA.Opt* `this` instance (for chainability)
|
|
229
229
|
|
|
230
|
+
#### Opt.input
|
|
231
|
+
Make option value inputting stream.
|
|
232
|
+
It's add useful validation and shortcut for STDIN.
|
|
233
|
+
**@returns** *{COA.Opt}* `this` instance (for chainability)
|
|
234
|
+
|
|
230
235
|
#### Opt.output
|
|
231
236
|
Make option value outputing stream.<br>
|
|
232
237
|
It's add useful validation and shortcut for STDOUT.<br>
|
|
@@ -303,7 +308,7 @@ Make argument value outputing stream.<br>
|
|
|
303
308
|
It's add useful validation and shortcut for STDOUT.<br>
|
|
304
309
|
**@returns** *COA.Arg* `this` instance (for chainability)
|
|
305
310
|
|
|
306
|
-
####
|
|
311
|
+
#### Arg.comp
|
|
307
312
|
Set custom additional completion for current argument.<br>
|
|
308
313
|
**@param** *Function* `fn` completion generation function,
|
|
309
314
|
invoked in the context of command instance.
|
package/README.ru.md
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# Command-Option-Argument
|
|
2
|
+
[](http://travis-ci.org/veged/coa)
|
|
3
|
+
|
|
4
|
+
## Что это?
|
|
5
|
+
|
|
6
|
+
COA — парсер параметров командной строки, позволяющий извлечь максимум пользы от формального API вашей программы.
|
|
7
|
+
Как только вы опишете определение в терминах команд, параметров и аргументов, вы автоматически получите:
|
|
8
|
+
|
|
9
|
+
* Справку для командной строки
|
|
10
|
+
* API для использования программы как модуля в COA-совместимых программах
|
|
11
|
+
* Автодополнение для командной строки
|
|
12
|
+
|
|
13
|
+
### Прочие возможности
|
|
14
|
+
|
|
15
|
+
* Широкий выбор настроек для параметров и аргументов, включая множественные значения, логические значения и обязательность параметров
|
|
16
|
+
* Возможность асинхронного исполнения команд, используя промисы (используется библиотека [Q](https://github.com/kriskowal/q))
|
|
17
|
+
* Простота использования существующих команд как подмодулей для новых команд
|
|
18
|
+
* Комбинированная валидация и анализ сложных значений
|
|
19
|
+
|
|
20
|
+
## Примеры
|
|
21
|
+
|
|
22
|
+
````javascript
|
|
23
|
+
require('coa').Cmd() // декларация команды верхнего уровня
|
|
24
|
+
.name(process.argv[1]) // имя команды верхнего уровня, берем из имени программы
|
|
25
|
+
.title('Жутко полезная утилита для командной строки') // название для использования в справке и сообщениях
|
|
26
|
+
.helpful() // добавляем поддержку справки командной строки (-h, --help)
|
|
27
|
+
.opt() // добавляем параметр
|
|
28
|
+
.name('version') // имя параметра для использования в API
|
|
29
|
+
.title('Version') // текст для вывода в сообщениях
|
|
30
|
+
.short('v') // короткое имя параметра: -v
|
|
31
|
+
.long('version') // длинное имя параметра: --version
|
|
32
|
+
.flag() // параметр не требует ввода значения
|
|
33
|
+
.act(function(opts) { // действия при вызове аргумента
|
|
34
|
+
// результатом является вывод текстового сообщения
|
|
35
|
+
return JSON.parse(require('fs').readFileSync(__dirname + '/package.json'))
|
|
36
|
+
.version;
|
|
37
|
+
})
|
|
38
|
+
.end() // завершаем определение параметра и возвращаемся к определению верхнего уровня
|
|
39
|
+
.cmd().name('subcommand').apply(require('./subcommand').COA).end() // загрузка подкоманды из модуля
|
|
40
|
+
.cmd() // добавляем еще одну подкоманду
|
|
41
|
+
.name('othercommand').title('Еще одна полезная подпрограмма').helpful()
|
|
42
|
+
.opt()
|
|
43
|
+
.name('input').title('input file, required')
|
|
44
|
+
.short('i').long('input')
|
|
45
|
+
.val(function(v) { // функция-валидатор, также может использоваться для трансформации значений параметров
|
|
46
|
+
return require('fs').createReadStream(v) })
|
|
47
|
+
.req() // параметр является обязательным
|
|
48
|
+
.end() // завершаем определение параметра и возвращаемся к определению команды
|
|
49
|
+
.end() // завершаем определение подкоманды и возвращаемся к определению команды верхнего уровня
|
|
50
|
+
.run(process.argv.slice(2)); // разбираем process.argv и запускаем
|
|
51
|
+
````
|
|
52
|
+
|
|
53
|
+
````javascript
|
|
54
|
+
// subcommand.js
|
|
55
|
+
exports.COA = function() {
|
|
56
|
+
this
|
|
57
|
+
.title('Полезная подпрограмма').helpful()
|
|
58
|
+
.opt()
|
|
59
|
+
.name('output').title('output file')
|
|
60
|
+
.short('o').long('output')
|
|
61
|
+
.output() // использовать стандартную настройку для параметра вывода
|
|
62
|
+
.end()
|
|
63
|
+
};
|
|
64
|
+
````
|
|
65
|
+
|
|
66
|
+
## API
|
|
67
|
+
|
|
68
|
+
### Cmd
|
|
69
|
+
Команда — сущность верхнего уровня. У команды могут быть определены параметры и аргументы.
|
|
70
|
+
|
|
71
|
+
#### Cmd.api
|
|
72
|
+
Возвращает объект, который можно использовать в других программах. Подкоманды являются методами этого объекта.<br>
|
|
73
|
+
**@returns** *{Object}*
|
|
74
|
+
|
|
75
|
+
#### Cmd.name
|
|
76
|
+
Определяет канонический идентификатор команды, используемый в вызовах API.<br>
|
|
77
|
+
**@param** *String* `_name` имя команды<br>
|
|
78
|
+
**@returns** *COA.Cmd* `this` экземпляр команды (для поддержки цепочки методов)
|
|
79
|
+
|
|
80
|
+
#### Cmd.title
|
|
81
|
+
Определяет название команды, используемый в текстовых сообщениях.<br>
|
|
82
|
+
**@param** *String* `_title` название команды<br>
|
|
83
|
+
**@returns** *COA.Cmd* `this` экземпляр команды (для поддержки цепочки методов)
|
|
84
|
+
|
|
85
|
+
#### Cmd.cmd
|
|
86
|
+
Создает новую подкоманду или добавляет ранее определенную подкоманду к текущей команде.<br>
|
|
87
|
+
**@param** *COA.Cmd* `[cmd]` экземпляр ранее определенной подкоманды<br>
|
|
88
|
+
**@returns** *COA.Cmd* экземпляр новой или ранее определенной подкоманды
|
|
89
|
+
|
|
90
|
+
#### Cmd.opt
|
|
91
|
+
Создает параметр для текущей команды.<br>
|
|
92
|
+
**@returns** *COA.Opt* `new` экземпляр параметра
|
|
93
|
+
|
|
94
|
+
#### Cmd.arg
|
|
95
|
+
Создает аргумент для текущей команды.<br>
|
|
96
|
+
**@returns** *COA.Opt* `new` экземпляр аргумента
|
|
97
|
+
|
|
98
|
+
#### Cmd.act
|
|
99
|
+
Добавляет (или создает) действие для текущей команды.<br>
|
|
100
|
+
**@param** *Function* `act` функция,
|
|
101
|
+
выполняемая в контексте экземпляра текущей команды
|
|
102
|
+
и принимающая следующие параметры:<br>
|
|
103
|
+
- *Object* `opts` параметры команды<br>
|
|
104
|
+
- *Array* `args` аргументы команды<br>
|
|
105
|
+
- *Object* `res` объект-аккумулятор результатов<br>
|
|
106
|
+
Функция может вернуть проваленный промис из Cmd.reject (в случае ошибки)
|
|
107
|
+
или любое другое значение, рассматриваемое как результат.<br>
|
|
108
|
+
**@param** *{Boolean}* [force=false] флаг, назначающий немедленное исполнение вместо добавления к списку существующих действий<br>
|
|
109
|
+
**@returns** *COA.Cmd* `this` экземпляр команды (для поддержки цепочки методов)
|
|
110
|
+
|
|
111
|
+
#### Cmd.apply
|
|
112
|
+
Исполняет функцию с переданными аргументами в контексте экземпляра текущей команды.<br>
|
|
113
|
+
**@param** *Function* `fn`<br>
|
|
114
|
+
**@param** *Array* `args`<br>
|
|
115
|
+
**@returns** *COA.Cmd* `this` экземпляр команды (для поддержки цепочки методов)
|
|
116
|
+
|
|
117
|
+
#### Cmd.comp
|
|
118
|
+
Назначает кастомную функцию автодополнения для текущей команды.<br>
|
|
119
|
+
**@param** *Function* `fn` функция-генератор автодополнения,
|
|
120
|
+
исполняемая в контексте текущей команды.
|
|
121
|
+
Принимает параметры:<br>
|
|
122
|
+
- *Object* `opts` параметры<br>
|
|
123
|
+
Может возвращать промис или любое другое значение, рассматриваемое как результат исполнения команды.<br>
|
|
124
|
+
**@returns** *COA.Cmd* `this` экземпляр команды (для поддержки цепочки методов)
|
|
125
|
+
|
|
126
|
+
#### Cmd.helpful
|
|
127
|
+
Ставит флаг поддержки справки командной строки, т.е. вызов команды с параметрами -h --help выводит справку по работе с командой.<br>
|
|
128
|
+
**@returns** *COA.Cmd* `this` экземпляр команды (для поддержки цепочки методов)
|
|
129
|
+
|
|
130
|
+
#### Cmd.completable
|
|
131
|
+
Добавляет поддержку автодополнения командной строки. Добавляется подкоманда "completion", которая выполняет все необходимые действия.<br>
|
|
132
|
+
Может быть добавлен только для главной команды.<br>
|
|
133
|
+
**@returns** *COA.Cmd* `this` экземпляр команды (для поддержки цепочки методов)
|
|
134
|
+
|
|
135
|
+
#### Cmd.usage
|
|
136
|
+
Возвращает текст справки по использованию команды для текущего экземпляра.<br>
|
|
137
|
+
**@returns** *String* `usage` Текст справки по использованию
|
|
138
|
+
|
|
139
|
+
#### Cmd.run
|
|
140
|
+
Разбирает аргументы из значения, возвращаемого NodeJS process.argv,
|
|
141
|
+
и запускает текущую программу, т.е. вызывает process.exit после завершения
|
|
142
|
+
всех действий.<br>
|
|
143
|
+
**@param** *Array* `argv`<br>
|
|
144
|
+
**@returns** *COA.Cmd* `this` экземпляр команды (для поддержки цепочки методов)
|
|
145
|
+
|
|
146
|
+
#### Cmd.invoke
|
|
147
|
+
Исполняет переданную (или текущую) команду с указанными параметрами и аргументами.<br>
|
|
148
|
+
**@param** *String|Array* `cmds` подкоманда для исполнения (необязательно)<br>
|
|
149
|
+
**@param** *Object* `opts` параметры, передаваемые команде (необязательно)<br>
|
|
150
|
+
**@param** *Object* `args` аргументы, передаваемые команде (необязательно)<br>
|
|
151
|
+
**@returns** *Q.Promise*
|
|
152
|
+
|
|
153
|
+
#### Cmd.reject
|
|
154
|
+
Проваливает промисы, возращенные в действиях.<br>
|
|
155
|
+
Используется в .act() для возврата с ошибкой.<br>
|
|
156
|
+
**@param** *Object* `reason` причина провала<br>
|
|
157
|
+
Вы можете определить метод toString() и свойство toString()
|
|
158
|
+
объекта причины провала.<br>
|
|
159
|
+
**@returns** *Q.promise* проваленный промис
|
|
160
|
+
|
|
161
|
+
#### Cmd.end
|
|
162
|
+
Завершает цепочку методов текущей подкоманды и возвращает экземпляр родительской команды.<br>
|
|
163
|
+
**@returns** *COA.Cmd* `parent` родительская команда
|
|
164
|
+
|
|
165
|
+
### Opt
|
|
166
|
+
Параметр — именованная сущность. У параметра может быть определено короткое или длинное имя для использования из командной строки.<br>
|
|
167
|
+
**@namespace**<br>
|
|
168
|
+
**@class** Переданный параметр
|
|
169
|
+
|
|
170
|
+
#### Opt.name
|
|
171
|
+
Определяет канонический идентификатор параметра, используемый в вызовах API.<br>
|
|
172
|
+
**@param** *String* `_name` имя параметра<br>
|
|
173
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
174
|
+
|
|
175
|
+
#### Opt.title
|
|
176
|
+
Определяет описание для параметра, используемое в текстовых сообщениях.<br>
|
|
177
|
+
**@param** *String* `_title` название параметра<br>
|
|
178
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
179
|
+
|
|
180
|
+
#### Opt.short
|
|
181
|
+
Назначает ключ для короткого имени параметра, передаваемого из командной строки с одинарным дефисом (например, `-v`).<br>
|
|
182
|
+
**@param** *String* `_short`<br>
|
|
183
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
184
|
+
|
|
185
|
+
#### Opt.long
|
|
186
|
+
Назначает ключ для длинного имени параметра, передаваемого из командной строки с двойным дефисом (например, `--version`).<br>
|
|
187
|
+
**@param** *String* `_long`<br>
|
|
188
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
189
|
+
|
|
190
|
+
#### Opt.flag
|
|
191
|
+
Помечает параметр как логический, т.е. параметр не имеющий значения.<br>
|
|
192
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
193
|
+
|
|
194
|
+
#### Opt.arr
|
|
195
|
+
Помечает параметр как принимающий множественные значения.<br>
|
|
196
|
+
Иначе будет использовано последнее переданное значение параметра.<br>
|
|
197
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
198
|
+
|
|
199
|
+
#### Opt.req
|
|
200
|
+
Помечает параметр как обязательный.<br>
|
|
201
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
202
|
+
|
|
203
|
+
#### Opt.only
|
|
204
|
+
Интерпретирует параметр как команду,
|
|
205
|
+
т.е. программа будет завершена сразу после выполнения параметра.<br>
|
|
206
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
207
|
+
|
|
208
|
+
#### Opt.val
|
|
209
|
+
Назначает функцию валидации (или трансформации значения) для значения параметра.<br>
|
|
210
|
+
Значение, полученное из командной строки, передается в функцию-валидатор прежде чем оно станет доступно из API.<br>
|
|
211
|
+
Используется для валидации и трансформации введенных данных.<br>
|
|
212
|
+
**@param** *Function* `_val` функция валидации,
|
|
213
|
+
исполняемая в контексте экземпляра параметра
|
|
214
|
+
и принимающая в качестве единственного параметра значение, полученное
|
|
215
|
+
из командной строки<br>
|
|
216
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
217
|
+
|
|
218
|
+
#### Opt.def
|
|
219
|
+
Назначает значение параметра по умолчанию. Это значение также передается
|
|
220
|
+
в функцию валидации как обычное значение.<br>
|
|
221
|
+
**@param** *Object* `_def`<br>
|
|
222
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
223
|
+
|
|
224
|
+
#### Opt.input
|
|
225
|
+
Помечает параметр как принимающий ввод пользователя. <br>
|
|
226
|
+
Позволяет использовать валидацию для STDIN.<br>
|
|
227
|
+
**@returns** *{COA.Opt}* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
228
|
+
|
|
229
|
+
#### Opt.output
|
|
230
|
+
Помечает параметр как вывод.<br>
|
|
231
|
+
Позволяет использовать валидацию для STDOUT.<br>
|
|
232
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
233
|
+
|
|
234
|
+
#### Opt.act
|
|
235
|
+
Добавляет (или создает) действие для текущего параметра команды.
|
|
236
|
+
Это действие будет выполнено, если текущий параметр есть
|
|
237
|
+
в списке полученных параметров (с любым значением).<br>
|
|
238
|
+
**@param** *Function* `act` функция, выполняемая в контексте
|
|
239
|
+
экземпляра текущей команды и принимающая следующие параметры:<br>
|
|
240
|
+
- *Object* `opts` параметры команды<br>
|
|
241
|
+
- *Array* `args` аргументы команды<br>
|
|
242
|
+
- *Object* `res` объект-аккумулятор результатов<br>
|
|
243
|
+
Функция может вернуть проваленный промис из Cmd.reject (в случае ошибки)
|
|
244
|
+
или любое другое значение, рассматриваемое как результат.<br>
|
|
245
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
246
|
+
|
|
247
|
+
#### Opt.comp
|
|
248
|
+
Назначает кастомную функцию автодополнения для текущей команды.<br>
|
|
249
|
+
**@param** *Function* `fn` функция-генератор автодоплнения, исполняемая в
|
|
250
|
+
контексте экземпляра команды.
|
|
251
|
+
Принимает параметры:<br>
|
|
252
|
+
- *Object* `opts` параметры автодополнения<br>
|
|
253
|
+
Может возвращать промис или любое другое значение, рассматриваемое как результат исполнения команды.<br>
|
|
254
|
+
**@returns** *COA.Opt* `this` экземпляр параметра (для поддержки цепочки методов)
|
|
255
|
+
|
|
256
|
+
#### Opt.end
|
|
257
|
+
Завершает цепочку методов текущего параметра и возвращает экземпляр родительской команды.<br>
|
|
258
|
+
**@returns** *COA.Cmd* `parent` родительская команда
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
### Arg
|
|
262
|
+
Аргумент — неименованная сущность.<br>
|
|
263
|
+
Аргументы передаются из командной строки как список неименованных значений.
|
|
264
|
+
|
|
265
|
+
#### Arg.name
|
|
266
|
+
Определяет канонический идентификатор аргумента, используемый в вызовах API.<br>
|
|
267
|
+
**@param** *String* `_name` имя аргумента<br>
|
|
268
|
+
**@returns** *COA.Arg* `this` экземпляр аргумента (для поддержки цепочки методов)
|
|
269
|
+
|
|
270
|
+
#### Arg.title
|
|
271
|
+
Определяет описание для аргумента, используемое в текстовых сообщениях.<br>
|
|
272
|
+
**@param** *String* `_title` описание аргумента<br>
|
|
273
|
+
**@returns** *COA.Arg* `this` экземпляр аргумента (для поддержки цепочки методов)
|
|
274
|
+
|
|
275
|
+
#### Arg.arr
|
|
276
|
+
Помечает аргумент как принимающий множественные значения.<br>
|
|
277
|
+
Иначе будет использовано последнее переданное значение аргумента.<br>
|
|
278
|
+
**@returns** *COA.Arg* `this` экземпляр аргумента (для поддержки цепочки методов)
|
|
279
|
+
|
|
280
|
+
#### Arg.req
|
|
281
|
+
Помечает аргумент как обязательный.<br>
|
|
282
|
+
**@returns** *COA.Arg* `this` экземпляр аргумента (для поддержки цепочки методов)
|
|
283
|
+
|
|
284
|
+
#### Arg.val
|
|
285
|
+
Назначает функцию валидации (или трансформации значения) для аргумента.<br>
|
|
286
|
+
Значение, полученное из командной строки, передается в функцию-валидатор прежде чем оно станет доступно из API.<br>
|
|
287
|
+
Используется для валидации и трансформации введенных данных.<br>
|
|
288
|
+
**@param** *Function* `_val` функция валидации,
|
|
289
|
+
исполняемая в контексте экземпляра аргумента
|
|
290
|
+
и принимающая в качестве единственного параметра значение, полученное
|
|
291
|
+
из командной строки<br>
|
|
292
|
+
**@returns** *COA.Opt* `this` экземпляр аргумента (для поддержки цепочки методов)
|
|
293
|
+
|
|
294
|
+
#### Arg.def
|
|
295
|
+
Назначает дефолтное значение для аргумента. Дефолтное значение передается
|
|
296
|
+
в функцию валидации как обычное значение.<br>
|
|
297
|
+
**@param** *Object* `_def`<br>
|
|
298
|
+
**@returns** *COA.Arg* `this` экземпляр аргумента (для поддержки цепочки методов)
|
|
299
|
+
|
|
300
|
+
#### Arg.output
|
|
301
|
+
Помечает параметр как вывод.<br>
|
|
302
|
+
Позволяет назначить валидацию для STDOUT.<br>
|
|
303
|
+
**@returns** *COA.Arg* `this` экземпляр аргумента (для поддержки цепочки методов)
|
|
304
|
+
|
|
305
|
+
#### Arg.comp
|
|
306
|
+
Назначает кастомную функцию автодополнения для текущего аргумента.<br>
|
|
307
|
+
**@param** *Function* `fn` функция-генератор автодоплнения,
|
|
308
|
+
исполняемая в контексте текущей команды.
|
|
309
|
+
Принимает параметры:<br>
|
|
310
|
+
- *Object* `opts` параметры
|
|
311
|
+
Может возвращать промис или любое другое значение, рассматриваемое как результат исполнения команды.<br>
|
|
312
|
+
**@returns** *COA.Arg* `this` экземпляр аргумента (для поддержки цепочки методов)
|
|
313
|
+
|
|
314
|
+
#### Arg.end
|
|
315
|
+
Завершает цепочку методов текущего аргумента и возвращает экземпляр родительской команды.<br>
|
|
316
|
+
**@returns** *COA.Cmd* `parent` родительская команда
|
package/lib/arg.js
CHANGED
package/lib/cmd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Generated by CoffeeScript 1.
|
|
1
|
+
// Generated by CoffeeScript 1.6.3
|
|
2
2
|
var Cmd, Color, PATH, Q, UTIL,
|
|
3
3
|
__slice = [].slice;
|
|
4
4
|
|
|
@@ -35,6 +35,7 @@ exports.Cmd = Cmd = (function() {
|
|
|
35
35
|
this._opts = [];
|
|
36
36
|
this._optsByKey = {};
|
|
37
37
|
this._args = [];
|
|
38
|
+
this._ext = false;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
Cmd.get = function(propertyName, func) {
|
|
@@ -70,10 +71,13 @@ exports.Cmd = Cmd = (function() {
|
|
|
70
71
|
});
|
|
71
72
|
|
|
72
73
|
Cmd.prototype._parent = function(cmd) {
|
|
74
|
+
this._cmd = cmd || this;
|
|
73
75
|
if (cmd) {
|
|
74
76
|
cmd._cmds.push(this);
|
|
77
|
+
if (this._name) {
|
|
78
|
+
this._cmd._cmdsByName[this._name] = this;
|
|
79
|
+
}
|
|
75
80
|
}
|
|
76
|
-
this._cmd = cmd || this;
|
|
77
81
|
return this;
|
|
78
82
|
};
|
|
79
83
|
|
|
@@ -221,10 +225,22 @@ exports.Cmd = Cmd = (function() {
|
|
|
221
225
|
return this.cmd().name('completion').apply(require('./completion')).end();
|
|
222
226
|
};
|
|
223
227
|
|
|
228
|
+
/**
|
|
229
|
+
Allow command to be extendable by external node.js modules.
|
|
230
|
+
@param {String} [pattern] Pattern of node.js module to find subcommands at.
|
|
231
|
+
@returns {COA.Cmd} this instance (for chainability)
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
Cmd.prototype.extendable = function(pattern) {
|
|
236
|
+
this._ext = pattern || true;
|
|
237
|
+
return this;
|
|
238
|
+
};
|
|
239
|
+
|
|
224
240
|
Cmd.prototype._exit = function(msg, code) {
|
|
225
241
|
return process.once('exit', function() {
|
|
226
242
|
if (msg) {
|
|
227
|
-
|
|
243
|
+
console.error(msg);
|
|
228
244
|
}
|
|
229
245
|
return process.exit(code || 0);
|
|
230
246
|
});
|
|
@@ -304,7 +320,7 @@ exports.Cmd = Cmd = (function() {
|
|
|
304
320
|
};
|
|
305
321
|
|
|
306
322
|
Cmd.prototype._parseCmd = function(argv, unparsed) {
|
|
307
|
-
var cmd, i, optSeen;
|
|
323
|
+
var c, cmd, cmdDesc, e, i, optSeen, pkg;
|
|
308
324
|
if (unparsed == null) {
|
|
309
325
|
unparsed = [];
|
|
310
326
|
}
|
|
@@ -314,8 +330,46 @@ exports.Cmd = Cmd = (function() {
|
|
|
314
330
|
if (!i.indexOf('-')) {
|
|
315
331
|
optSeen = true;
|
|
316
332
|
}
|
|
317
|
-
if (!optSeen && /^\w[\w-_]*$/.test(i)
|
|
318
|
-
|
|
333
|
+
if (!optSeen && /^\w[\w-_]*$/.test(i)) {
|
|
334
|
+
cmd = this._cmdsByName[i];
|
|
335
|
+
if (!cmd && this._ext) {
|
|
336
|
+
if (typeof this._ext === 'string') {
|
|
337
|
+
if (~this._ext.indexOf('%s')) {
|
|
338
|
+
pkg = UTIL.format(this._ext, i);
|
|
339
|
+
} else {
|
|
340
|
+
pkg = this._ext + i;
|
|
341
|
+
}
|
|
342
|
+
} else if (this._ext === true) {
|
|
343
|
+
pkg = i;
|
|
344
|
+
c = this;
|
|
345
|
+
while (true) {
|
|
346
|
+
pkg = c._name + '-' + pkg;
|
|
347
|
+
if (c._cmd === c) {
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
c = c._cmd;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
cmdDesc = require(pkg);
|
|
355
|
+
} catch (_error) {
|
|
356
|
+
e = _error;
|
|
357
|
+
}
|
|
358
|
+
if (cmdDesc) {
|
|
359
|
+
if (typeof cmdDesc === 'function') {
|
|
360
|
+
this.cmd().name(i).apply(cmdDesc).end();
|
|
361
|
+
} else if (typeof cmdDesc === 'object') {
|
|
362
|
+
this.cmd(cmdDesc);
|
|
363
|
+
cmdDesc.name(i);
|
|
364
|
+
} else {
|
|
365
|
+
throw new Error('Error: Unsupported command declaration type, ' + 'should be function or COA.Cmd() object');
|
|
366
|
+
}
|
|
367
|
+
cmd = this._cmdsByName[i];
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (cmd) {
|
|
371
|
+
return cmd._parseCmd(argv, unparsed);
|
|
372
|
+
}
|
|
319
373
|
}
|
|
320
374
|
unparsed.push(i);
|
|
321
375
|
}
|
package/lib/color.js
CHANGED
package/lib/completion.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Generated by CoffeeScript 1.
|
|
1
|
+
// Generated by CoffeeScript 1.6.3
|
|
2
2
|
/**
|
|
3
3
|
Most of the code adopted from the npm package shell completion code.
|
|
4
4
|
See https://github.com/isaacs/npm/blob/master/lib/completion.js
|
|
@@ -21,7 +21,7 @@ module.exports = function() {
|
|
|
21
21
|
e.errno = require('constants').ENOTSUP;
|
|
22
22
|
return this.reject(e);
|
|
23
23
|
}
|
|
24
|
-
if (
|
|
24
|
+
if ((process.env.COMP_CWORD == null) || (process.env.COMP_LINE == null) || (process.env.COMP_POINT == null)) {
|
|
25
25
|
return dumpScript(this._cmd._name);
|
|
26
26
|
}
|
|
27
27
|
console.error('COMP_LINE: %s', process.env.COMP_LINE);
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
// Generated by CoffeeScript 1.
|
|
2
|
-
|
|
1
|
+
// Generated by CoffeeScript 1.6.3
|
|
3
2
|
exports.Cmd = require('./cmd').Cmd;
|
|
4
3
|
|
|
4
|
+
exports.Opt = require('./cmd').Opt;
|
|
5
|
+
|
|
6
|
+
exports.Arg = require('./cmd').Arg;
|
|
7
|
+
|
|
5
8
|
exports.shell = require('./shell');
|
|
6
9
|
|
|
7
10
|
exports.require = require;
|
package/lib/opt.js
CHANGED
package/lib/shell.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coa",
|
|
3
3
|
"description": "Command-Option-Argument: Yet another parser for command line options.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.1",
|
|
5
5
|
"homepage": "http://github.com/veged/coa",
|
|
6
6
|
"author": "Sergey Berezhnoy <veged@ya.ru> (http://github.com/veged)",
|
|
7
7
|
"maintainers": [
|
|
@@ -19,22 +19,21 @@
|
|
|
19
19
|
"lib": "./lib"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"q": "
|
|
22
|
+
"q": "^1.1.2"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"coffee-script": "~1.
|
|
26
|
-
"istanbul": "~0.1.
|
|
27
|
-
"mocha-as-promised": "*",
|
|
25
|
+
"coffee-script": "~1.6.3",
|
|
26
|
+
"istanbul": "~0.1.40",
|
|
28
27
|
"mocha-istanbul": "*",
|
|
29
|
-
"mocha": "~1.
|
|
30
|
-
"chai": "~1.
|
|
28
|
+
"mocha": "~1.21.4",
|
|
29
|
+
"chai": "~1.7.2"
|
|
31
30
|
},
|
|
32
31
|
"scripts": {
|
|
33
32
|
"test": "make test",
|
|
34
33
|
"coverage": "make coverage"
|
|
35
34
|
},
|
|
36
35
|
"engines": {
|
|
37
|
-
"node": ">= 0.
|
|
36
|
+
"node": ">= 0.8.0"
|
|
38
37
|
},
|
|
39
38
|
"licenses": [
|
|
40
39
|
{
|
package/src/cmd.coffee
CHANGED
|
@@ -32,6 +32,8 @@ exports.Cmd = class Cmd
|
|
|
32
32
|
|
|
33
33
|
@_args = []
|
|
34
34
|
|
|
35
|
+
@_ext = false
|
|
36
|
+
|
|
35
37
|
@get: (propertyName, func) ->
|
|
36
38
|
Object.defineProperty @::, propertyName,
|
|
37
39
|
configurable: true
|
|
@@ -52,8 +54,10 @@ exports.Cmd = class Cmd
|
|
|
52
54
|
@_api
|
|
53
55
|
|
|
54
56
|
_parent: (cmd) ->
|
|
55
|
-
if cmd then cmd._cmds.push @
|
|
56
57
|
@_cmd = cmd or this
|
|
58
|
+
if cmd
|
|
59
|
+
cmd._cmds.push @
|
|
60
|
+
if @_name then @_cmd._cmdsByName[@_name] = @
|
|
57
61
|
@
|
|
58
62
|
|
|
59
63
|
###*
|
|
@@ -163,9 +167,18 @@ exports.Cmd = class Cmd
|
|
|
163
167
|
.apply(require './completion')
|
|
164
168
|
.end()
|
|
165
169
|
|
|
170
|
+
###*
|
|
171
|
+
Allow command to be extendable by external node.js modules.
|
|
172
|
+
@param {String} [pattern] Pattern of node.js module to find subcommands at.
|
|
173
|
+
@returns {COA.Cmd} this instance (for chainability)
|
|
174
|
+
###
|
|
175
|
+
extendable: (pattern) ->
|
|
176
|
+
@_ext = pattern or true
|
|
177
|
+
@
|
|
178
|
+
|
|
166
179
|
_exit: (msg, code) ->
|
|
167
180
|
process.once 'exit', ->
|
|
168
|
-
if msg then
|
|
181
|
+
if msg then console.error msg
|
|
169
182
|
process.exit code or 0
|
|
170
183
|
|
|
171
184
|
###*
|
|
@@ -233,8 +246,49 @@ exports.Cmd = class Cmd
|
|
|
233
246
|
while i = argv.shift()
|
|
234
247
|
if not i.indexOf '-'
|
|
235
248
|
optSeen = true
|
|
236
|
-
if not optSeen and /^\w[\w-_]*$/.test(i)
|
|
237
|
-
|
|
249
|
+
if not optSeen and /^\w[\w-_]*$/.test(i)
|
|
250
|
+
cmd = @_cmdsByName[i]
|
|
251
|
+
|
|
252
|
+
if not cmd and @_ext
|
|
253
|
+
# construct package name to require
|
|
254
|
+
if typeof @_ext is 'string'
|
|
255
|
+
if ~@_ext.indexOf('%s')
|
|
256
|
+
# use formatted string
|
|
257
|
+
pkg = UTIL.format(@_ext, i)
|
|
258
|
+
else
|
|
259
|
+
# just append subcommand name to the prefix
|
|
260
|
+
pkg = @_ext + i
|
|
261
|
+
else if @_ext is true
|
|
262
|
+
# use default scheme: <command>-<subcommand>-<subcommand> and so on
|
|
263
|
+
pkg = i
|
|
264
|
+
c = @
|
|
265
|
+
loop
|
|
266
|
+
pkg = c._name + '-' + pkg
|
|
267
|
+
if c._cmd is c then break
|
|
268
|
+
c = c._cmd
|
|
269
|
+
|
|
270
|
+
try
|
|
271
|
+
cmdDesc = require(pkg)
|
|
272
|
+
catch e
|
|
273
|
+
|
|
274
|
+
if cmdDesc
|
|
275
|
+
if typeof cmdDesc == 'function'
|
|
276
|
+
# set create subcommand, set its name and apply imported function
|
|
277
|
+
@cmd()
|
|
278
|
+
.name(i)
|
|
279
|
+
.apply(cmdDesc)
|
|
280
|
+
.end()
|
|
281
|
+
else if typeof cmdDesc == 'object'
|
|
282
|
+
# register subcommand
|
|
283
|
+
@cmd(cmdDesc)
|
|
284
|
+
# set command name
|
|
285
|
+
cmdDesc.name(i)
|
|
286
|
+
else
|
|
287
|
+
throw new Error 'Error: Unsupported command declaration type, ' +
|
|
288
|
+
'should be function or COA.Cmd() object'
|
|
289
|
+
cmd = @_cmdsByName[i]
|
|
290
|
+
if cmd
|
|
291
|
+
return cmd._parseCmd argv, unparsed
|
|
238
292
|
|
|
239
293
|
unparsed.push i
|
|
240
294
|
|
package/src/index.coffee
CHANGED
package/test/coa.js
CHANGED
|
@@ -338,6 +338,22 @@ describe('Arg', function() {
|
|
|
338
338
|
|
|
339
339
|
describe('Cmd', function() {
|
|
340
340
|
|
|
341
|
+
var doTest = function(o) {
|
|
342
|
+
assert.deepEqual(o, {
|
|
343
|
+
opts: { opt: 'value' },
|
|
344
|
+
args: {
|
|
345
|
+
arg1: 'value',
|
|
346
|
+
arg2: ['value 1', 'value 2']
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
},
|
|
350
|
+
|
|
351
|
+
invokeOpts = { opt: 'value' },
|
|
352
|
+
invokeArgs = {
|
|
353
|
+
arg1: 'value',
|
|
354
|
+
arg2: ['value 1', 'value 2']
|
|
355
|
+
};
|
|
356
|
+
|
|
341
357
|
describe('Subcommand', function() {
|
|
342
358
|
|
|
343
359
|
var cmd = COA.Cmd()
|
|
@@ -357,23 +373,7 @@ describe('Cmd', function() {
|
|
|
357
373
|
.act(function(opts, args) {
|
|
358
374
|
return { opts: opts, args: args };
|
|
359
375
|
})
|
|
360
|
-
.end()
|
|
361
|
-
|
|
362
|
-
doTest = function(o) {
|
|
363
|
-
assert.deepEqual(o, {
|
|
364
|
-
opts: { opt: 'value' },
|
|
365
|
-
args: {
|
|
366
|
-
arg1: 'value',
|
|
367
|
-
arg2: ['value 1', 'value 2']
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
},
|
|
371
|
-
|
|
372
|
-
invokeOpts = { opt: 'value' },
|
|
373
|
-
invokeArgs = {
|
|
374
|
-
arg1: 'value',
|
|
375
|
-
arg2: ['value 1', 'value 2']
|
|
376
|
-
};
|
|
376
|
+
.end();
|
|
377
377
|
|
|
378
378
|
describe('when specified on command line', function() {
|
|
379
379
|
|
|
@@ -413,6 +413,80 @@ describe('Cmd', function() {
|
|
|
413
413
|
|
|
414
414
|
});
|
|
415
415
|
|
|
416
|
+
describe('External subcommand', function() {
|
|
417
|
+
|
|
418
|
+
describe('default scheme: cmd.extendable()', function() {
|
|
419
|
+
|
|
420
|
+
describe('when described as a function', function() {
|
|
421
|
+
var cmd = COA.Cmd()
|
|
422
|
+
.name('coa')
|
|
423
|
+
.extendable();
|
|
424
|
+
|
|
425
|
+
it('should be invoked and accept passed opts and args', function() {
|
|
426
|
+
return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
|
|
427
|
+
.then(doTest);
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
describe('when described as an COA.Cmd() object', function() {
|
|
432
|
+
var cmd = COA.Cmd()
|
|
433
|
+
.name('coa')
|
|
434
|
+
.extendable();
|
|
435
|
+
|
|
436
|
+
it('should be invoked and accept passed opts and args', function() {
|
|
437
|
+
return cmd.do(['test-obj', '--opt', 'value', 'value', 'value 1', 'value 2'])
|
|
438
|
+
.then(doTest);
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
describe('2nd level subcommand', function() {
|
|
443
|
+
var cmd = COA.Cmd()
|
|
444
|
+
.name('coa')
|
|
445
|
+
.cmd()
|
|
446
|
+
.name('test')
|
|
447
|
+
.extendable()
|
|
448
|
+
.end();
|
|
449
|
+
|
|
450
|
+
it('should be invoked and accept passed opts and args', function() {
|
|
451
|
+
return cmd.do(['test', 'obj', '--opt', 'value', 'value', 'value 1', 'value 2'])
|
|
452
|
+
.then(doTest);
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
describe("common prefix: cmd.extendable('coa-')", function() {
|
|
459
|
+
|
|
460
|
+
describe('when described as a function', function() {
|
|
461
|
+
var cmd = COA.Cmd()
|
|
462
|
+
.name('coa')
|
|
463
|
+
.extendable('coa-');
|
|
464
|
+
|
|
465
|
+
it('should be invoked and accept passed opts and args', function() {
|
|
466
|
+
return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
|
|
467
|
+
.then(doTest);
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
describe("format string: cmd.extendable('coa-%s')", function() {
|
|
474
|
+
|
|
475
|
+
describe('when described as a function', function() {
|
|
476
|
+
var cmd = COA.Cmd()
|
|
477
|
+
.name('coa')
|
|
478
|
+
.extendable('coa-%s');
|
|
479
|
+
|
|
480
|
+
it('should be invoked and accept passed opts and args', function() {
|
|
481
|
+
return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
|
|
482
|
+
.then(doTest);
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
});
|
|
489
|
+
|
|
416
490
|
it('helpful(), name(), title()');
|
|
417
491
|
|
|
418
492
|
});
|
package/test/mocha.opts
CHANGED
package/tests/api-h.js
CHANGED
package/test/common.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require('mocha-as-promised')(require('mocha'));
|