cli_application 0.1.0
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +480 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/cli_application/app.rb +267 -0
- data/lib/cli_application/argv.rb +152 -0
- data/lib/cli_application/config.rb +82 -0
- data/lib/cli_application/databases.rb +39 -0
- data/lib/cli_application/includes.rb +21 -0
- data/lib/cli_application/json_struct.rb +48 -0
- data/lib/cli_application/stat.rb +170 -0
- data/lib/cli_application/version.rb +3 -0
- data/lib/cli_application.rb +21 -0
- data/test/cli_example.rb +25 -0
- data/test/examples/1/app.rb +26 -0
- data/test/examples/1/cli_example.rb +14 -0
- data/test/examples/1/stat/app.yml +33 -0
- data/test/examples/2/app.rb +28 -0
- data/test/examples/3/app.rb +25 -0
- data/test/examples/4/app.rb +49 -0
- data/test/examples/5/app.rb +33 -0
- data/test/examples/6/app.rb +31 -0
- data/test/examples/6/offer.rb +5 -0
- data/test/stat/rdebug-ide +21 -0
- data/test/stat/test_app.yml +29 -0
- data/test/test_app.rb +60 -0
- data/test/tovar.rb +5 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 66b49ebc791cd738f94c6dc2274df4c7e6468871
|
4
|
+
data.tar.gz: f2276b446ecba4f73a41b3714b49c580025bcf83
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 265b0f7f6389a54fe2ce307a1c31f36b779c72b70e8fe92bd90034cd671bb93f982d05f3a648d8f294e1e2b37f8c6141a4b08836eb8d8afda2b229fbc0e3e39a
|
7
|
+
data.tar.gz: 2dfbd6666e691431d398182af34434d1bca6cbda18b897fd1b705b022342f6613079990f96d80c9618bc889dabaa3b260e6d4f8b61311c6412a71de85ed88bbc
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Stan Zhuravlev
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,480 @@
|
|
1
|
+
# CliApplication
|
2
|
+
|
3
|
+
Библиотека CliApplication предназначена для построения CLI-приложений. В процессе работы над различым ПО Backoffice,
|
4
|
+
приходиться регулярно сталкиваться с задачами создания т.н. "фоновых скриптов", которые выполняют различные операции:
|
5
|
+
|
6
|
+
- готовят данные для выдачи абоненту
|
7
|
+
- парсят другие сайты
|
8
|
+
- получают различную информацию от внешних систем
|
9
|
+
|
10
|
+
Использовать для этого разработку REST-методов в рамках стандартной модели Rails накладно по ряду причин - проще для
|
11
|
+
этого разработать отдельные скрипты и вызывать их через cron как любой другой bash-скрипт. Библиотека предназначена как раз
|
12
|
+
для создания таких приложений, взаимодействие с которыми идет через командную строку. При этом библиотека обеспечивает
|
13
|
+
крайне быструю и удобную разработку таких приложений.
|
14
|
+
|
15
|
+
CLI-приложения, написанные на базе библиотеки CliApplication, представляют собой трех-уровеную структуру, базирующуюся
|
16
|
+
на следующей иерархии классов: `CliApplication -> YouCliClass -> YouCliApplication`.
|
17
|
+
|
18
|
+
В данной иерархии обеспечивается:
|
19
|
+
|
20
|
+
- на уровне CliApplication - поддержка управления аргументами командной строки, ведение статистики по вызовам приложения.
|
21
|
+
- на уровне YouCliClass - поддержка управления конфигами, общими функциями и данными приложений.
|
22
|
+
- на уровне YouCliApplication - выполнение логики скрипта.
|
23
|
+
|
24
|
+
Быстрота разработки обеспечивается:
|
25
|
+
|
26
|
+
1. Возможность писать свой конфиг (как на уровне класса, так и на уровне приложения), но добавлять его в единый механизм чтения конфигов CliApplication
|
27
|
+
2. Возможность удобно манипуляировать аргументами командной строки, включая различные преобразования (например, см. [здесь](http://www.rubydoc.info/gems/st_tools/0.3.5/StTools/Module/String#to_range-instance_method))
|
28
|
+
3. Подключение ко всем необходимым базам данных, заданных в конфигах
|
29
|
+
4. Наличием готовых функций формирования статистики для постанализа статуса запуска приложений.
|
30
|
+
4. Переиспользованием моделей ActiveRecord Rails-приложения для единообразного управления запиями баз данных.
|
31
|
+
|
32
|
+
## Установка
|
33
|
+
|
34
|
+
Добавить в Gemfile:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
gem 'cli_application'
|
38
|
+
```
|
39
|
+
|
40
|
+
Установить гем cредствами Bundler:
|
41
|
+
|
42
|
+
$ bundle
|
43
|
+
|
44
|
+
Или установить его отдельно:
|
45
|
+
|
46
|
+
$ gem install cli_application
|
47
|
+
|
48
|
+
# Зависимости
|
49
|
+
|
50
|
+
Для работы гема требуется Ruby не младше версии 2.2.1. Также для работы необходим гем StTools (https://github.com/StanZhuravlev/st_tools).
|
51
|
+
|
52
|
+
## Использование
|
53
|
+
|
54
|
+
Использование библиотеки проще всего показать на базе примеров. Все примеры доступны в папке /test/examples
|
55
|
+
|
56
|
+
### Пример 1 - по традиции, Hello, World (или не World)
|
57
|
+
|
58
|
+
_См. /test/examples/1_
|
59
|
+
|
60
|
+
Сначала создадим класс ```ruby CliExample```, который станет основной для CLI-приложений в конкретном проекте.
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
require 'cli_application'
|
64
|
+
|
65
|
+
class CliExample < CliApplication::App
|
66
|
+
|
67
|
+
def initialize(argv, folder, lang = :ru)
|
68
|
+
super(argv, folder, __dir__, lang)
|
69
|
+
end
|
70
|
+
|
71
|
+
def init_app
|
72
|
+
super
|
73
|
+
add_config('config.yml', :class)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
Затем формируем минимальный конфиг, который включает настройки времени.
|
80
|
+
|
81
|
+
```yaml
|
82
|
+
cli:
|
83
|
+
timezone: "Moscow"
|
84
|
+
ar_timezone: "Moscow"
|
85
|
+
```
|
86
|
+
|
87
|
+
И создаем своё тестовое приложение
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
#!/usr/bin/env ruby
|
91
|
+
#encoding: utf-8
|
92
|
+
require './cli_example.rb'
|
93
|
+
|
94
|
+
class TestApp < CliExample
|
95
|
+
|
96
|
+
def main
|
97
|
+
puts "Hello, #{argv.user}!"
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
app = TestApp.new(ARGV, __dir__)
|
103
|
+
|
104
|
+
app.version = '1.0'
|
105
|
+
app.releasedate = '2015-05-11'
|
106
|
+
app.shortdescription = 'Пример 1 - Hello, world'
|
107
|
+
app.description = "CliApplication gem демо. #{app.shortdescription}"
|
108
|
+
|
109
|
+
app.set_argv(:string, 'user', 'World', 'Имя того, кого приветствуем')
|
110
|
+
|
111
|
+
app.help
|
112
|
+
|
113
|
+
app.run
|
114
|
+
exit(app.exitcode)
|
115
|
+
```
|
116
|
+
|
117
|
+
Результатом работы данного скрипта при запуске без каких либо параметров будет следующий вывод:
|
118
|
+
|
119
|
+
```text
|
120
|
+
app.rb - Пример 1 - Hello, world
|
121
|
+
Версия 1.0 (2015-05-11)
|
122
|
+
Ранее не запускалось
|
123
|
+
Всего было 1 запусков
|
124
|
+
|
125
|
+
CliApplication gem демо. Пример 1 - Hello, world
|
126
|
+
|
127
|
+
Параметры приложения:
|
128
|
+
user - Имя того, кого приветствуем (по умолчанию "World":String)
|
129
|
+
|
130
|
+
|
131
|
+
Hello, World!
|
132
|
+
```
|
133
|
+
|
134
|
+
Как видим, при запуске скрипта сразу был выведен текст подсказки, включая описание параметров командной строки
|
135
|
+
с указанием значения по умолчанию. Самое значение по умолчанию оказалось в переменной argv (```ruby argv[:user] ```).
|
136
|
+
|
137
|
+
Теперь запустим приложение ```text app.rb user=Egor```. Получим следующий вывод.
|
138
|
+
|
139
|
+
```text
|
140
|
+
app.rb - Пример 1 - Hello, world
|
141
|
+
Версия 1.0 (2015-05-11)
|
142
|
+
Последний запуск: 11 мая 2015 г. 19:14:46 (21 минута 12 секунд назад)
|
143
|
+
Всего было 2 запусков
|
144
|
+
|
145
|
+
CliApplication gem демо. Пример 1 - Hello, world
|
146
|
+
|
147
|
+
Параметры приложения:
|
148
|
+
user - Имя того, кого приветствуем (по умолчанию "World":String)
|
149
|
+
|
150
|
+
|
151
|
+
Hello, Egor!
|
152
|
+
```
|
153
|
+
|
154
|
+
При этом выводится информация о дате и времени предыдущего запуска приложений. Эта информация хранится в папке stat,
|
155
|
+
автоматически создаваемой в той же папке, где находится класс CliExample. В нашем случае, в папке создан файл app.yml
|
156
|
+
следующего содержания.
|
157
|
+
|
158
|
+
```yaml
|
159
|
+
---
|
160
|
+
:name: app.rb
|
161
|
+
:shortdescription: "Пример 1 - Hello, world"
|
162
|
+
:version: '1.0'
|
163
|
+
:releasedate: '2015-05-11'
|
164
|
+
:timezone: Moscow
|
165
|
+
:last_started_at: '2015-05-11 19:35:58 +0300'
|
166
|
+
:folders:
|
167
|
+
:app: "/Users/Stan/Documents/Development/cli_application/test/examples/1"
|
168
|
+
:class: "/Users/Stan/Documents/Development/cli_application/test/examples/1"
|
169
|
+
:stat: "/Users/Stan/Documents/Development/cli_application/test/examples/1/stat"
|
170
|
+
:avg:
|
171
|
+
:starts: 3
|
172
|
+
:executed_at: 0.020647
|
173
|
+
:executed_at_human: 0.020647 секунд
|
174
|
+
:memory: 32126
|
175
|
+
:last:
|
176
|
+
:started_at: '2015-05-11 19:35:58 +0300'
|
177
|
+
:executed_at: 0.031052
|
178
|
+
:executed_at_human: 0.031052 секунд
|
179
|
+
:memory: 32 кбайт
|
180
|
+
:exitcode: 255
|
181
|
+
:last10:
|
182
|
+
- 2015-05-11 19:35:58 +0300,255,0.031052,32 кбайт
|
183
|
+
- 2015-05-11 19:14:46 +0300,255,0.030889,31 кбайт
|
184
|
+
```
|
185
|
+
|
186
|
+
Данный файл содержит статистическую информацию относительно запусков приложения, включая среднее время исполнения,
|
187
|
+
объем задействованной памяти и прочее.
|
188
|
+
|
189
|
+
### Пример 2 - Различные параметры приложения
|
190
|
+
|
191
|
+
_См. /test/examples/2_
|
192
|
+
|
193
|
+
Второй пример показывает набор данных, которые можно получить внутри приложения. Для этого полностью заменим функцию
|
194
|
+
`main` из предыдущего примера на следующую...
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
def main
|
198
|
+
puts "Приложение: #{exename}"
|
199
|
+
puts "Запущено из папки: #{folders[:app]}"
|
200
|
+
puts "Базовый класс в: #{folders[:class]}"
|
201
|
+
puts "Занимает сейчас в памяти #{StTools::Human.memory}"
|
202
|
+
puts "С момента начала выполнения прошло #{executed_at} секунд"
|
203
|
+
end
|
204
|
+
```
|
205
|
+
...и посмотрим на результат запуска приложения.
|
206
|
+
|
207
|
+
```text
|
208
|
+
Приложение: app.rb
|
209
|
+
Запущено из папки: /Users/Stan/Documents/Development/cli_application/test/examples/2
|
210
|
+
Базовый клас в: /Users/Stan/Documents/Development/cli_application/test/examples/1
|
211
|
+
Занимает сейчас в памяти 31 кбайт
|
212
|
+
С момента начала выполнения прошло 0.055399 секунд
|
213
|
+
```
|
214
|
+
Показатель `executed_at` - время в секундах с момента старта приложения. Это может быть важно для фиксации
|
215
|
+
продолжительности работы скрипта.
|
216
|
+
|
217
|
+
Объект `folders` содержит список папок различных частей приложения. Наиболее важны два типа папок, `folders[:class]`
|
218
|
+
возвращает папку, в которой находится базовый класс всех приложений одного проекта. Может быть использована, например,
|
219
|
+
для записи логов каждого приложения в единое место (по аналогии с файлом статистики). Вторая папка `folders[:app]`
|
220
|
+
возвращает папку, из которой запущено приложение.
|
221
|
+
|
222
|
+
### Пример 3 - Футер
|
223
|
+
|
224
|
+
_См. /test/examples/3_
|
225
|
+
|
226
|
+
Для добавления в конце работы приложения футера с итогом работы приложения можно использовать параметр `app.footer`.
|
227
|
+
Данный параметр поддерживает переменные, которые в конце исполнения приложения заменятся на результаты работы приложения.
|
228
|
+
|
229
|
+
Сделаем следующую функцию `main`.
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
def main
|
233
|
+
return 0
|
234
|
+
end
|
235
|
+
```
|
236
|
+
|
237
|
+
И добавим перед вызовом `run` функцию `footer`.
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
app.help
|
241
|
+
app.footer = "{status} ({exitcode}) - приложение завершено за {executed_at} секунд (занято в памяти {memory})"
|
242
|
+
app.run
|
243
|
+
```
|
244
|
+
|
245
|
+
Запустим приложение.
|
246
|
+
|
247
|
+
```text
|
248
|
+
SUCCESS (0) - приложение завершено за 0.033943 секунд (занято в памяти 32 кбайт)
|
249
|
+
```
|
250
|
+
|
251
|
+
Заменим в функции `main` выражение `return 0` на `return 10`, и запустим приложение вновь
|
252
|
+
|
253
|
+
```text
|
254
|
+
FAIL (10) - приложение завершено за 0.046153 секунд (занято в памяти 30 кбайт)
|
255
|
+
```
|
256
|
+
Если нужно отключить футер в процессе выполнения приложения, необходимо внутри функции `main` выполнить `footer = nil`.
|
257
|
+
Также футер можно изменить в функции `main` в любой момент на другой.
|
258
|
+
|
259
|
+
Переменные шаблонизатора представлены в следующей таблице
|
260
|
+
|
261
|
+
|Параметр|Значение|
|
262
|
+
|--------|--------|
|
263
|
+
|executed_at|Число секунд с момента начала работы приложения|
|
264
|
+
|memory|Объем паямти, занятой приложением в human-виде|
|
265
|
+
|status|SUCCESS если exitcode равно нулю, и FAIL в других случаях|
|
266
|
+
|exitcode|Код, который приложение вернет в bash-среду. Соответствует значению от 0 до 255, возвращаемому из функции `main`|
|
267
|
+
|
268
|
+
|
269
|
+
### Пример 4 - Форматирование параметров командной строки
|
270
|
+
|
271
|
+
_См. /test/examples/4_
|
272
|
+
|
273
|
+
Рассмотрим ситуацию, когда в CLI-скрипт необходимо передвать большое количество различных параметров, причем на выходе
|
274
|
+
желатлеьно иметь данные, пригодные к машиной обработке. Для этого существует возможность задавать параметры командной строки
|
275
|
+
с указаним различных преобразований, которые должны быть проведены над данными. Рассмотрим это на примере.
|
276
|
+
|
277
|
+
Добавим перед функцией `app.help` следующий код
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
app.set_argv(:downcase, 'ex1', 'НИКолай', 'Пример преобразования аргумента в нижний регистр')
|
281
|
+
app.set_argv(:upcase, 'ex2', 'НИКолай', 'Пример преобразования аргумента в верхний регистр')
|
282
|
+
app.set_argv(:bool, 'ex3', true, 'Пример преобразования логического аргумента в тип boolean')
|
283
|
+
app.set_argv(:split, 'ex4', 'Москва,Санкт-Петербург,Абакан', 'Пример преобразования входного списка в массив')
|
284
|
+
app.set_argv(:range, 'ex5', '1, 35, 23, 10-14', 'Пример преобразования диапазона в массив')
|
285
|
+
app.set_argv(:float, 'ex6', 3.14, 'Пример числа с плавающей запятой')
|
286
|
+
app.set_argv(:integer, 'ex7', 3.14, 'Пример целого числа')
|
287
|
+
app.set_argv(:normalize, 'ex8', 'Москва - крупный город ', 'Пример нормализации строки')
|
288
|
+
app.set_argv(:caps, 'ex9', 'иванов иВАН иваныч', 'Пример перевода строки в красивый human-вид')
|
289
|
+
app.set_argv(:string, 'ex10', 'ПрИвВеТ', 'Пример неизменного аргумента командной строки')
|
290
|
+
```
|
291
|
+
|
292
|
+
...и напишем следующую функцию `main`.
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
def main
|
296
|
+
puts ":downcase - #{argv.ex1.inspect} (#{argv.ex1.class.to_s})"
|
297
|
+
puts ":upcase - #{argv.ex2.inspect} (#{argv.ex2.class.to_s})"
|
298
|
+
puts ":bool - #{argv.ex3.inspect} (#{argv.ex3.class.to_s})"
|
299
|
+
puts ":split - #{argv.ex4.inspect} (#{argv.ex4.class.to_s})"
|
300
|
+
puts ":range - #{argv.ex5.inspect} (#{argv.ex5.class.to_s})"
|
301
|
+
puts ":float - #{argv.ex6.inspect} (#{argv.ex6.class.to_s})"
|
302
|
+
puts ":integer - #{argv.ex7.inspect} (#{argv.ex7.class.to_s})"
|
303
|
+
puts ":normalize - #{argv.ex8.inspect} (#{argv.ex8.class.to_s})"
|
304
|
+
puts ":caps - #{argv.ex9.inspect} (#{argv.ex9.class.to_s})"
|
305
|
+
puts ":string - #{argv.ex10.inspect} (#{argv.ex10.class.to_s})"
|
306
|
+
puts "Неизвестный ключ возвращает nil - #{argv.no_key.inspect}"
|
307
|
+
puts
|
308
|
+
0
|
309
|
+
end
|
310
|
+
```
|
311
|
+
|
312
|
+
Запустим приложение. Для изменения значений по умочланию запустим следующим образом: `app.rb ex1=value ex2='val value' ex3=1,23,4`.
|
313
|
+
|
314
|
+
```text
|
315
|
+
app.rb - Пример 4 - Различные параметры командной строки
|
316
|
+
Версия 1.0 (2015-05-11)
|
317
|
+
Последний запуск: 12 мая 2015 г. 13:57:44 (4 минуты 20 секунд назад)
|
318
|
+
Всего было 29 запусков
|
319
|
+
|
320
|
+
CliApplication gem демо. Пример 4 - Различные параметры командной строки
|
321
|
+
|
322
|
+
Параметры приложения:
|
323
|
+
ex1 - Пример преобразования аргумента в нижний регистр (по умолчанию "НИКолай":String)
|
324
|
+
ex2 - Пример преобразования аргумента в верхний регистр (по умолчанию "НИКолай":String)
|
325
|
+
ex3 - Пример преобразования логического аргумента в тип boolean (по умолчанию true:TrueClass)
|
326
|
+
ex4 - Пример преобразования входного списка в массив (по умолчанию "Москва,Санкт-Петербург,Абакан
|
327
|
+
":Array)
|
328
|
+
ex5 - Пример преобразования диапазона в массив (по умолчанию "1, 35, 23, 10-14":Array)
|
329
|
+
ex6 - Пример числа с плавающей запятой (по умолчанию 3.14:Float)
|
330
|
+
ex7 - Пример целого числа (по умолчанию 3.14:Fixnum)
|
331
|
+
ex8 - Пример нормализации строки (по умолчанию "Москва - крупный город ":String)
|
332
|
+
ex9 - Пример перевода строки в красивый human-вид (по умолчанию "иванов иВАН иваныч":String)
|
333
|
+
ex10 - Пример неизменного аргумента командной строки (по умолчанию "ПрИвВеТ":String)
|
334
|
+
|
335
|
+
|
336
|
+
:downcase - "николай" (String)
|
337
|
+
:upcase - "НИКОЛАЙ" (String)
|
338
|
+
:bool - true (TrueClass)
|
339
|
+
:split - ["Абакан", "Москва", "Санкт-Петербург"] (Array)
|
340
|
+
:range - [1, 10, 11, 12, 13, 14, 23, 35] (Array)
|
341
|
+
:float - 3.14 (Float)
|
342
|
+
:integer - 3 (Fixnum)
|
343
|
+
:normalize - "москва - крупный город" (String)
|
344
|
+
:caps - "Иванов Иван Иваныч" (String)
|
345
|
+
:string - "ПрИвВеТ" (String)
|
346
|
+
|
347
|
+
SUCCESS (0) - приложение завершено за 0.041796 секунд (занято в памяти 30 кбайт)
|
348
|
+
```
|
349
|
+
|
350
|
+
Мы видим, что все параметры командной строки показаны в виде подсказок при запуске приложения.
|
351
|
+
При этом они оформлены "красиво" с учетом отступов, с указанием значений по умолчанию.
|
352
|
+
Допустимы следующие типы преобразований.
|
353
|
+
|
354
|
+
|Преобразование|Описание|
|
355
|
+
|---------|---------|
|
356
|
+
|:string|Строка передается в приложение, как есть, без модификаций|
|
357
|
+
|:bool или :boolean|Исходная строка преобразуется в `true` или `false` в соответствии с правилами, описанными [здесь](http://www.rubydoc.info/gems/st_tools/0.3.5/StTools/String#to_bool-class_method).|
|
358
|
+
|:downcase|Строка приводится к нижнему регистру, как описано [здесь](http://www.rubydoc.info/gems/st_tools/0.3.5/StTools/String#downcase-class_method).|
|
359
|
+
|:upcase|Строка приводится к верхнему регистру, как описано [здесь](http://www.rubydoc.info/gems/st_tools/0.3.5/StTools/String#upcase-class_method).|
|
360
|
+
|:normalize|Строка нормализуется для машинной обработки, как описано [здесь](http://www.rubydoc.info/gems/st_tools/0.3.5/StTools/String#normalize-class_method).|
|
361
|
+
|:caps|Первая буква каждого слова отделенного пробелом или дефисом, приводится к верхнему регистру, остальный - к нижнему (см. [здесь](http://www.rubydoc.info/gems/st_tools/0.3.5/StTools/String#caps-class_method)).|
|
362
|
+
|:split|Строка делится на массив элементов, разделенных запятыми. Значения сортируются по возрастанию.|
|
363
|
+
|:range|Строка вида '3,4,10-20' преобразуется в массив значений. Подробнее [здесь](http://www.rubydoc.info/gems/st_tools/0.3.5/StTools/String#to_range-class_method).|
|
364
|
+
|:range_no_uniq|Аналогично предыдущему, но над массивом не проводится операция `uniq`.|
|
365
|
+
|:float|Значение введенной строки переводится в float.|
|
366
|
+
|:integer|Значение введенной строки переводится в целое число.|
|
367
|
+
|
368
|
+
### Пример 5 - Подключение дополнительных конфигов
|
369
|
+
|
370
|
+
В приложениях можно подключать сколько угодно дополнительных конфигов. Для этого в текст базового класса, или в текст
|
371
|
+
конкретного приложения, нужно добавить функцию `init_app` следующего содержания. В нашем случае, добавим эту функцию в класс
|
372
|
+
тестового приложения.
|
373
|
+
|
374
|
+
```ruby
|
375
|
+
def init_app
|
376
|
+
super
|
377
|
+
@config.add('app_config.yml', :app)
|
378
|
+
end
|
379
|
+
```
|
380
|
+
|
381
|
+
Сам конфиг сделаем таким
|
382
|
+
|
383
|
+
```yaml
|
384
|
+
this_app:
|
385
|
+
test_key: "Hello, world!"
|
386
|
+
```
|
387
|
+
|
388
|
+
Функцию `main` сделаем такой.
|
389
|
+
|
390
|
+
```ruby
|
391
|
+
def main
|
392
|
+
puts "Временная зона для приложения (из конфига класса): #{config.cli.timezone}"
|
393
|
+
puts "Тестовый ключ (из доп. конфига приложения): #{config.this_app.test_key}"
|
394
|
+
puts
|
395
|
+
0
|
396
|
+
end
|
397
|
+
```
|
398
|
+
|
399
|
+
Запустим приложение, посомтрим, что оно выводит.
|
400
|
+
|
401
|
+
```text
|
402
|
+
Временная зона для приложения (из конфига класса): Moscow
|
403
|
+
Тестовый ключ (из доп. конфига приложения): Hello, world!
|
404
|
+
```
|
405
|
+
Таким образом, видно, что после добавления нового конфига, мы смогли внутри приложения обращаться "прозрачно"
|
406
|
+
как к данным конфига класса, так и к данным нового конфига.
|
407
|
+
|
408
|
+
Разберем подробнее.
|
409
|
+
|
410
|
+
Мы создали конфиг `app_config.yml`, указав в нем корневой ключ - `this_app`. Данный ключ может быть любым кроме `cli`,
|
411
|
+
который зарезервирован за конфигом класса (см. пример 1) (без указания временной зоны приложение будет завершаться ошибкой).
|
412
|
+
При заведении класса в приложение нужно указать его тип - `:app`. Допустимы два типа конфига: `:class` и `:app`. Допустимо
|
413
|
+
добавлять сколько угодно конфигов с указанием `:class` или `:app`.
|
414
|
+
|
415
|
+
При запуске функции `@config.add_config` происходит перечитывание всех конфигов.
|
416
|
+
|
417
|
+
Затем в функции `main` осуществляется использование данных конфига с использованием имеющихся в конфиге ключей.
|
418
|
+
|
419
|
+
### Пример 6 - Подключение баз данных и моделей ActiveRecord's
|
420
|
+
|
421
|
+
С помощью класса CliApplication можно эффективно управлять соединениями с базами данных, и моделями ActiveRecords.
|
422
|
+
Давайте представим, что мы сделали Rails-проект, определили там модели ActiveRecord, и теперь хотим их переиспользовать
|
423
|
+
в CLI-приложении. Для этого сделаем следующее.
|
424
|
+
|
425
|
+
Сначала пропишем в конфиге параметры подключения к базам данных. Характеристики должны быть в ключе `config.cli.databases`.
|
426
|
+
Данный ключ должен содержать записи вида <имя конфигурации> => <параметры конфигурации>. Баз данных можно подключать неограниченно.
|
427
|
+
Рассмотрим пример конфига для подключения к MySQL. Имя конфигурации - `default`.
|
428
|
+
|
429
|
+
```yaml
|
430
|
+
cli:
|
431
|
+
timezone: "Moscow"
|
432
|
+
ar_timezone: "Moscow" # Active Record timezone
|
433
|
+
|
434
|
+
databases:
|
435
|
+
default:
|
436
|
+
adapter: mysql2
|
437
|
+
host: localhost
|
438
|
+
database: online_store
|
439
|
+
username: usersql
|
440
|
+
password: password_chars
|
441
|
+
```
|
442
|
+
|
443
|
+
Затем создадим функцию `app.init_active_records`, в которой будем подключать модели. Покажем ее вместе с функцией `main`.
|
444
|
+
|
445
|
+
```ruby
|
446
|
+
def main
|
447
|
+
puts Offer.first.inspect
|
448
|
+
puts
|
449
|
+
0
|
450
|
+
end
|
451
|
+
|
452
|
+
def init_active_records
|
453
|
+
require './offer.rb'
|
454
|
+
end
|
455
|
+
```
|
456
|
+
|
457
|
+
Сама модель (файл offer.rb) должна выглядеть как показано ниже.
|
458
|
+
|
459
|
+
```ruby
|
460
|
+
class Offer < ActiveRecord::Base
|
461
|
+
self.establish_connection self.configurations[:default]
|
462
|
+
self.table_name = "offers_table"
|
463
|
+
end
|
464
|
+
```
|
465
|
+
Запустим приложение, посомтрим на результат
|
466
|
+
|
467
|
+
```text
|
468
|
+
#<Offer id: 10, category: 1, name: "Игрушка десткая", description: "Эта игрушка непременно понравится...", ...
|
469
|
+
```
|
470
|
+
|
471
|
+
Таким образом, буквально в несколько строк мы можем работать с базами данных в CLI-приложении, так же, как в привычном
|
472
|
+
Rails-окружении.
|
473
|
+
|
474
|
+
## Contributing
|
475
|
+
|
476
|
+
1. Fork it ( https://github.com/[my-github-username]/cli_application/fork )
|
477
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
478
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
479
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
480
|
+
5. Create a new Pull Request
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "cli_application"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|