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 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
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here