generamba-udf 2.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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +10 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/CHANGELOG.md +191 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +62 -0
- data/Rakefile +6 -0
- data/VISION.md +41 -0
- data/bin/console +14 -0
- data/bin/generamba +5 -0
- data/bin/setup +7 -0
- data/docs/2.x/roadmap.md +365 -0
- data/generamba-1.6.0.gem +0 -0
- data/generamba-2.0.0.gem +0 -0
- data/generamba.gemspec +38 -0
- data/lib/generamba/cli/cli.rb +16 -0
- data/lib/generamba/cli/gen_command.rb +119 -0
- data/lib/generamba/cli/setup_command.rb +127 -0
- data/lib/generamba/cli/setup_username_command.rb +21 -0
- data/lib/generamba/cli/template/template_create_command.rb +40 -0
- data/lib/generamba/cli/template/template_group.rb +14 -0
- data/lib/generamba/cli/template/template_install_command.rb +21 -0
- data/lib/generamba/cli/template/template_list_command.rb +25 -0
- data/lib/generamba/cli/template/template_search_command.rb +30 -0
- data/lib/generamba/cli/thor_extension.rb +47 -0
- data/lib/generamba/cli/version_command.rb +25 -0
- data/lib/generamba/code_generation/Rambafile.liquid +44 -0
- data/lib/generamba/code_generation/code_module.rb +123 -0
- data/lib/generamba/code_generation/content_generator.rb +43 -0
- data/lib/generamba/code_generation/module_template.rb +31 -0
- data/lib/generamba/code_generation/rambafile_generator.rb +23 -0
- data/lib/generamba/configuration/user_preferences.rb +50 -0
- data/lib/generamba/constants/constants.rb +12 -0
- data/lib/generamba/constants/rambafile_constants.rb +41 -0
- data/lib/generamba/constants/rambaspec_constants.rb +22 -0
- data/lib/generamba/constants/user_preferences_constants.rb +5 -0
- data/lib/generamba/helpers/dependency_checker.rb +54 -0
- data/lib/generamba/helpers/gen_command_table_parameters_formatter.rb +41 -0
- data/lib/generamba/helpers/module_info_generator.rb +35 -0
- data/lib/generamba/helpers/module_validator.rb +85 -0
- data/lib/generamba/helpers/print_table.rb +17 -0
- data/lib/generamba/helpers/rambafile_validator.rb +18 -0
- data/lib/generamba/helpers/template_helper.rb +30 -0
- data/lib/generamba/helpers/xcodeproj_helper.rb +262 -0
- data/lib/generamba/module_generator.rb +148 -0
- data/lib/generamba/template/creator/new_template/Code/Service/service.h.liquid +11 -0
- data/lib/generamba/template/creator/new_template/Code/Service/service.m.liquid +13 -0
- data/lib/generamba/template/creator/new_template/Tests/Service/service_tests.m.liquid +35 -0
- data/lib/generamba/template/creator/new_template/template.rambaspec.liquid +20 -0
- data/lib/generamba/template/creator/template_creator.rb +39 -0
- data/lib/generamba/template/helpers/catalog_downloader.rb +58 -0
- data/lib/generamba/template/helpers/catalog_template_list_helper.rb +23 -0
- data/lib/generamba/template/helpers/catalog_template_search_helper.rb +27 -0
- data/lib/generamba/template/helpers/catalog_terminator.rb +21 -0
- data/lib/generamba/template/helpers/rambaspec_validator.rb +52 -0
- data/lib/generamba/template/installer/abstract_installer.rb +9 -0
- data/lib/generamba/template/installer/catalog_installer.rb +73 -0
- data/lib/generamba/template/installer/local_installer.rb +32 -0
- data/lib/generamba/template/installer/remote_installer.rb +50 -0
- data/lib/generamba/template/installer/template_installer_factory.rb +22 -0
- data/lib/generamba/template/processor/template_declaration.rb +36 -0
- data/lib/generamba/template/processor/template_processor.rb +75 -0
- data/lib/generamba/tools/string-colorize.rb +23 -0
- data/lib/generamba/version.rb +5 -0
- data/lib/generamba.rb +16 -0
- metadata +288 -0
data/docs/2.x/roadmap.md
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# Generamba 2.0 Roadmap
|
|
2
|
+
### Overview
|
|
3
|
+
|
|
4
|
+
The main aim of 2.0 release is to decouple Generamba from iOS/macOS development and make it available for other areas as well: backend, frontend, Android.
|
|
5
|
+
|
|
6
|
+
We'll definitely break the backwards compatibility with *Rambafile* and templates created for the 1.x Generamba versions. To simplify the upgrading process we're considering writing some automatic migration tools.
|
|
7
|
+
|
|
8
|
+
### High-Level Tasks
|
|
9
|
+
|
|
10
|
+
* Switch *Rambafile* from `yml` to a custom DSL format.
|
|
11
|
+
* Wrap repetitive tasks into *ramba*'s - the nearest analogs are *lane*'s from `fastlane`.
|
|
12
|
+
* Introduce the concept of two types of *plugins*: system (validation, save) and general-purpose.
|
|
13
|
+
* Allow the usage of different types of hooks - `before`, `after`, `error`.
|
|
14
|
+
* Add validation plugins, that are available to check the environment before code generation.
|
|
15
|
+
* Extract the saving logic from the Generamba core to plugins, both to filesystem and Xcode.
|
|
16
|
+
* Add saving plugins, that are available to process the text snippet created by generamba and save it somewhere.
|
|
17
|
+
* Extract the validation logic from the Generamba core to plugins, both for CocoaPods and Carthage.
|
|
18
|
+
|
|
19
|
+
### Generamba Flow
|
|
20
|
+
|
|
21
|
+
A typical generation process consists of three steps:
|
|
22
|
+
* validation
|
|
23
|
+
* generation
|
|
24
|
+
* saving
|
|
25
|
+
|
|
26
|
+
#### Validation
|
|
27
|
+
|
|
28
|
+
That step is used to validate the environment status before code generation. It's a perfect place to implement logic of checking the required packages versions, the presence of system libraries, git status and so on.
|
|
29
|
+
|
|
30
|
+
If one of checks returns an error, the overall validation process doesn't stop until all of validation methods execute. This is crucial for a smooth user experience.
|
|
31
|
+
|
|
32
|
+
#### Generation
|
|
33
|
+
|
|
34
|
+
That's the core functionality of Generamba. A user provides a template name and some options which are used as an input. After the generation Generamba produces a text snippet as an output.
|
|
35
|
+
|
|
36
|
+
There can be multiple generation actions as well. All of them are executed in the writing order and their results are stored in-memory.
|
|
37
|
+
|
|
38
|
+
#### Saving
|
|
39
|
+
|
|
40
|
+
This step defines what to do with a generation output. The most obvious options are to store it as a file in some directory on the disk, embed it in your IDE, upload somewhere or print in log.
|
|
41
|
+
|
|
42
|
+
If there are multiple saving actions, each of them is applied to each generation output. They are executed in the writing order.
|
|
43
|
+
|
|
44
|
+
### DSL
|
|
45
|
+
|
|
46
|
+
#### Basic Rambafile Structure
|
|
47
|
+
|
|
48
|
+
The main building block of *Rambafile* is `ramba`:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
desc "Creates a new Xcode project"
|
|
52
|
+
ramba :viper_module do
|
|
53
|
+
# Detailed description of generation steps
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The *Rambafile* may be monolithic as well as decomposed to multiple files. This is available via special functions:
|
|
58
|
+
- `ramba_import_local('path')` - imports the contents of `Rambafile` stored locally.
|
|
59
|
+
- `ramba_import_git('git', 'branch')` - imports the contents of Rambafile stored in remote git repository.
|
|
60
|
+
|
|
61
|
+
#### Setting Options
|
|
62
|
+
|
|
63
|
+
A user can set options in any part of *Rambafile* structure. It's important to note, that option, defined on the next level of method hierarchy, overwrites it's previous declaration. That allows to have a default value for some key and redefine it in each `ramba`.
|
|
64
|
+
```
|
|
65
|
+
set :project_name, 'MyProject'
|
|
66
|
+
|
|
67
|
+
ramba :viper_module do
|
|
68
|
+
set :project_name, 'MyProject'
|
|
69
|
+
end
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
It's also available to set an option using lambda:
|
|
73
|
+
```
|
|
74
|
+
set :date_string, -> {
|
|
75
|
+
"Current date: #{Date.now}"
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
> How options are set in Rambafile...
|
|
80
|
+
>
|
|
81
|
+
|
|
82
|
+
Besides `ramba` -specific options, there are template-specific options as well. They may correspond to a specific template and be defined in the *.rambaspec* file.
|
|
83
|
+
|
|
84
|
+
> The saving action for Xcode should behave differently depending on whether a generated file it's a code file or some resource. So, there is a special option for each file of Xcode templates:
|
|
85
|
+
> `- {name: Router/RouterTests.m, path: Tests/Router/router_tests.m.liquid, is_resource: false}`
|
|
86
|
+
|
|
87
|
+
#### Hooks
|
|
88
|
+
|
|
89
|
+
There are multiple types of hooks, which make possible to perform some action or redefine an option in certain moments of generation cycle.
|
|
90
|
+
|
|
91
|
+
##### `before` hooks
|
|
92
|
+
|
|
93
|
+
A user can specify a hook, that'll execute before a specific `ramba`:
|
|
94
|
+
```
|
|
95
|
+
before :viper_module do
|
|
96
|
+
# Some logic here...
|
|
97
|
+
end
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
It's also possible to write a hook that'll execute before each `ramba`:
|
|
101
|
+
```
|
|
102
|
+
before_each do |ramba_name|
|
|
103
|
+
# Some logic here...
|
|
104
|
+
end
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
##### `after` hooks
|
|
108
|
+
|
|
109
|
+
A user can specify a hook, that'll execute after a specific `ramba`:
|
|
110
|
+
```
|
|
111
|
+
after :viper_module do
|
|
112
|
+
# Some logic here...
|
|
113
|
+
end
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
It's also possible to write a hook that'll execute after each `ramba`:
|
|
117
|
+
```
|
|
118
|
+
after_each do |ramba_name|
|
|
119
|
+
# Some logic here...
|
|
120
|
+
end
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
##### `error` hooks
|
|
124
|
+
|
|
125
|
+
If any action returns an error, it's possible to customize the resulting behavior for a specific `ramba` :
|
|
126
|
+
```
|
|
127
|
+
error :viper_module do
|
|
128
|
+
# Some logic here...
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
It's also possible to write a hook that'll execute in case of error in any `ramba`:
|
|
132
|
+
```
|
|
133
|
+
error_each do |ramba_name|
|
|
134
|
+
# Some logic here...
|
|
135
|
+
end
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### `ramba` structure
|
|
139
|
+
|
|
140
|
+
As we've already mentioned, `ramba` consists of three main steps. Multiple actions in each step are executed in the writing order.
|
|
141
|
+
|
|
142
|
+
##### Validation actions
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
ramba :viper_module do
|
|
146
|
+
...
|
|
147
|
+
validate :validate_plugin_name do
|
|
148
|
+
set :some_option, 'some_value'
|
|
149
|
+
any_custom_action()
|
|
150
|
+
end
|
|
151
|
+
...
|
|
152
|
+
end
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
This notation means the following steps:
|
|
156
|
+
- The lambda passed to the validate action is executed.
|
|
157
|
+
- The plugin with name `validate_plugin_name` is called with options modified by lambda.
|
|
158
|
+
|
|
159
|
+
The notation can be simplified to:
|
|
160
|
+
```
|
|
161
|
+
validate :validate_plugin_name
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
##### Generation actions
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
ramba :viper_module do
|
|
168
|
+
...
|
|
169
|
+
gen :viper_module do
|
|
170
|
+
set :some_option, 'some_value'
|
|
171
|
+
any_custom_action(parameter1)
|
|
172
|
+
end
|
|
173
|
+
...
|
|
174
|
+
end
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
This notation means the following steps:
|
|
178
|
+
- The lambda passed to the gen action is executed.
|
|
179
|
+
* The `gen` command is called with a template *viper_module* and options modified by lambda.
|
|
180
|
+
|
|
181
|
+
The notation can be simplified to:
|
|
182
|
+
```
|
|
183
|
+
gen :viper_module
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
##### Saving actions
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
ramba :viper_module do
|
|
190
|
+
...
|
|
191
|
+
save :save_plugin_name do
|
|
192
|
+
set :some_option, 'some_value'
|
|
193
|
+
any_custom_action()
|
|
194
|
+
end
|
|
195
|
+
...
|
|
196
|
+
end
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
This notation means the following steps:
|
|
200
|
+
- The lambda passed to the saving action is executed.
|
|
201
|
+
- The plugin with name `save_plugin_name` is called with options modified by lambda.
|
|
202
|
+
|
|
203
|
+
The notation can be simplified to:
|
|
204
|
+
```
|
|
205
|
+
save :save_plugin_name
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
##### Custom Actions
|
|
209
|
+
|
|
210
|
+
Besides system plugins (validation and saving), a user can create a general-purpose plugin which contains some specific reusable logic. E.g. a plugin which clears the environment - calls `git reset`, uninstalls some packages and so on. It's called simply by calling it's name:
|
|
211
|
+
```
|
|
212
|
+
ramba :viper_module do
|
|
213
|
+
...
|
|
214
|
+
any_custom_action()
|
|
215
|
+
...
|
|
216
|
+
end
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
##### Templates and Catalogs
|
|
220
|
+
|
|
221
|
+
Templates and tempalte catalogs, used for code generation, can be specified right in the `ramba`'s.
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
ramba :viper_module do
|
|
225
|
+
catalog 'https://github.com/user/catalog', branch:'develop'
|
|
226
|
+
template 'viper_ios', version:'1.2.5'
|
|
227
|
+
template 'viper_ios2', path:'/local_templates'
|
|
228
|
+
end
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
- `catalog` keyword specifies a custom template catalog (like https://github.com/rambler-digital-solutions/generamba-catalog).
|
|
232
|
+
- `branch` parameter specifies a concrete catalog branch
|
|
233
|
+
- `template` keyword declares a template that needs to be installed
|
|
234
|
+
- `version` parameter specifies a concrete template version.
|
|
235
|
+
- `path` parameter specifies a local path to the template.
|
|
236
|
+
- `git` parameter specifies a remote repository path to a template.
|
|
237
|
+
- `branch` parameter is used together with `git` to specify a branch.
|
|
238
|
+
|
|
239
|
+
The `generamba template install` command aggregates all of the templates from the `Rambafile` and installs them in a `.generamba` hidden directory. When a user triggers some `ramba`, templates are loaded from this directory. The only exception are local templates - they are always installed from the specified in the `Rambafile` local path.
|
|
240
|
+
|
|
241
|
+
### Plugins
|
|
242
|
+
|
|
243
|
+
The main ideas behind plugin system are:
|
|
244
|
+
|
|
245
|
+
- Increase code reusability between different projects,
|
|
246
|
+
* Keep the Generamba core as simple as possible,
|
|
247
|
+
* Abstract from specific implementations of different IDEs,
|
|
248
|
+
* Allow users to easily extend Generamba functionality for their needs.
|
|
249
|
+
|
|
250
|
+
As we've already mentioned, there are two types of plugins:
|
|
251
|
+
|
|
252
|
+
- System plugins - validation and saving,
|
|
253
|
+
* Custom plugins.
|
|
254
|
+
|
|
255
|
+
The main difference between them is how system calls them during `ramba` execution.
|
|
256
|
+
|
|
257
|
+
#### Plugin Structure
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
module Generamba
|
|
261
|
+
module Plugins
|
|
262
|
+
class CocoaPodsPackageVersionValidationPlugin < ValidationPlugin
|
|
263
|
+
# The main body of a plugin
|
|
264
|
+
def self.run(params)
|
|
265
|
+
# Loads Podfile
|
|
266
|
+
# Analyzez dependencies version
|
|
267
|
+
# Compares these versions to the passed options
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# The description of what this plugin does
|
|
271
|
+
def self.description
|
|
272
|
+
'Verifies dependencies version in the project Podfile'
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Explicitly declaring available plugin options
|
|
276
|
+
def self.available_options
|
|
277
|
+
[
|
|
278
|
+
Generamba::ConfigItem.new(key: :package_versions,
|
|
279
|
+
description: "The hash with dependencies names and required versions",
|
|
280
|
+
default_value: [])
|
|
281
|
+
]
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# Declaring the output parameters
|
|
285
|
+
def self.output
|
|
286
|
+
[
|
|
287
|
+
['COCOAPODS_CHECK_RESULT', 'The result of dependency checking']
|
|
288
|
+
]
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# Who created this plugin
|
|
292
|
+
def self.authors
|
|
293
|
+
["etolstoy"]
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
The same structure applies to other kinds of plugins. The only difference is the base class for the plugin - it can be `ValidationPlugin`, `SavingPlugin`, `Plugin`.
|
|
301
|
+
|
|
302
|
+
We've borrowed the plugin structure from `fastlane`.
|
|
303
|
+
|
|
304
|
+
#### Plugin Distribution
|
|
305
|
+
|
|
306
|
+
To avoid over-engineering in this version plugins will be distributed together with Generamba binary. If there'll be a lot of community-created plugins, will think about switching to other distribution system.
|
|
307
|
+
|
|
308
|
+
It's also possible to store plugins near the `Rambafile` in a separate directory `/plugins`. They'll be loaded by Generamba automatically.
|
|
309
|
+
|
|
310
|
+
### Rambafile Example
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
ramba_import_local('path')
|
|
314
|
+
ramba_import_git('git', 'branch')
|
|
315
|
+
|
|
316
|
+
set :project_name, 'LiveJournal'
|
|
317
|
+
|
|
318
|
+
before :viper_module do
|
|
319
|
+
set :company, 'Rambler&Co'
|
|
320
|
+
set :xcodeproj_path, 'LiveJournal.xcodeproj'
|
|
321
|
+
set :project_targets, ['LiveJournal1', 'LiveJournal2']
|
|
322
|
+
set :test_target, 'LiveJournalTests'
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
desc "Creates a simple VIPER module"
|
|
326
|
+
ramba :viper_module do
|
|
327
|
+
validate :plugin_validate_name do
|
|
328
|
+
set :some_option, '456'
|
|
329
|
+
any_custom_action()
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
gen :template_name do
|
|
333
|
+
set :some_option, '123'
|
|
334
|
+
any_custom_action(parameter1)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
save :file_system do
|
|
338
|
+
set :some_option, '789'
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
save :xcode_proj
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
desc "Creates a new Xcode project"
|
|
345
|
+
ramba :create_project do
|
|
346
|
+
sh("liftoff") # Calling a shell script which invokes a 'liftoff' utility
|
|
347
|
+
add_pods(["Typhoon", "MagicalRecord"])
|
|
348
|
+
|
|
349
|
+
gen :app_delegate
|
|
350
|
+
gen :core_data_stack
|
|
351
|
+
|
|
352
|
+
save :file_system
|
|
353
|
+
save :xcode_proj
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
# It's called after each 'ramba' execution
|
|
357
|
+
after_each do |ramba_name|
|
|
358
|
+
# Some logic here
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
# It's called in case of an error in any 'ramba'
|
|
362
|
+
error :viper_module do
|
|
363
|
+
# Some error handling logic here
|
|
364
|
+
end
|
|
365
|
+
```
|
data/generamba-1.6.0.gem
ADDED
|
Binary file
|
data/generamba-2.0.0.gem
ADDED
|
Binary file
|
data/generamba.gemspec
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'generamba/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = 'generamba-udf'
|
|
8
|
+
spec.version = Generamba::VERSION
|
|
9
|
+
spec.authors = ['Egor Tolstoy', 'Andrey Zarembo', 'Beniamin Sarkisyan', 'Aleksandr Sychev']
|
|
10
|
+
spec.email = 'rambler.ios@rambler-co.ru'
|
|
11
|
+
|
|
12
|
+
spec.summary = 'Advanced code generator for Xcode projects with a nice and flexible template system.'
|
|
13
|
+
spec.description = 'Generamba is a powerful and easy-to-use Xcode code generator. It provides a project-based configuration, flexible templates system, the ability to generate code and tests simultaneously.'
|
|
14
|
+
spec.homepage = 'https://github.com/rambler-digital-solutions/Generamba'
|
|
15
|
+
spec.license = 'MIT'
|
|
16
|
+
|
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
|
+
spec.executables = ['generamba']
|
|
19
|
+
spec.require_paths = ['lib']
|
|
20
|
+
|
|
21
|
+
spec.required_ruby_version = '>= 2.2'
|
|
22
|
+
|
|
23
|
+
spec.add_runtime_dependency 'thor', '0.19.1'
|
|
24
|
+
spec.add_runtime_dependency 'xcodeproj', '>= 1.6.0', '< 2.0.0'
|
|
25
|
+
spec.add_runtime_dependency 'liquid', '4.0.0'
|
|
26
|
+
spec.add_runtime_dependency 'git', '1.2.9.1'
|
|
27
|
+
spec.add_runtime_dependency 'cocoapods-core', '>= 1.4.0', '< 2.0.0'
|
|
28
|
+
spec.add_runtime_dependency 'terminal-table', '1.4.5'
|
|
29
|
+
|
|
30
|
+
spec.add_development_dependency 'bundler', '~> 2.2.16'
|
|
31
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.4'
|
|
33
|
+
spec.add_development_dependency 'fakefs', '~> 0.6.1'
|
|
34
|
+
# ActiveSupport dependency is not used by dashramba; instead some other dependency
|
|
35
|
+
# requires it. We lock it to 4.2.7 so as to avoid using 5.0, which is
|
|
36
|
+
# not compatible with older versions of Ruby.
|
|
37
|
+
spec.add_development_dependency 'activesupport', '~> 4.2', '>= 4.2.7'
|
|
38
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'xcodeproj'
|
|
3
|
+
require 'liquid'
|
|
4
|
+
require 'git'
|
|
5
|
+
require 'generamba/cli/gen_command.rb'
|
|
6
|
+
require 'generamba/cli/setup_command.rb'
|
|
7
|
+
require 'generamba/cli/version_command.rb'
|
|
8
|
+
require 'generamba/cli/setup_username_command.rb'
|
|
9
|
+
require 'generamba/cli/thor_extension.rb'
|
|
10
|
+
require 'generamba/cli/template/template_group.rb'
|
|
11
|
+
|
|
12
|
+
module Generamba::CLI
|
|
13
|
+
class Application < Thor
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'generamba/helpers/print_table.rb'
|
|
3
|
+
require 'generamba/helpers/rambafile_validator.rb'
|
|
4
|
+
require 'generamba/helpers/xcodeproj_helper.rb'
|
|
5
|
+
require 'generamba/helpers/dependency_checker.rb'
|
|
6
|
+
require 'generamba/helpers/gen_command_table_parameters_formatter.rb'
|
|
7
|
+
require 'generamba/helpers/module_validator.rb'
|
|
8
|
+
require 'generamba/helpers/module_info_generator.rb'
|
|
9
|
+
|
|
10
|
+
module Generamba::CLI
|
|
11
|
+
class Application < Thor
|
|
12
|
+
|
|
13
|
+
include Generamba
|
|
14
|
+
|
|
15
|
+
desc 'gen [MODULE_NAME] [TEMPLATE_NAME]', 'Creates a new VIPER module with a given name from a specific template'
|
|
16
|
+
method_option :description, :aliases => '-d', :desc => 'Provides a full description to the module'
|
|
17
|
+
method_option :author, :desc => 'Specifies the author name for generated module'
|
|
18
|
+
method_option :project_targets, :desc => 'Specifies project targets for adding new module files'
|
|
19
|
+
method_option :project_file_path, :desc => 'Specifies a location in the filesystem for new files'
|
|
20
|
+
method_option :project_group_path, :desc => 'Specifies a location in Xcode groups for new files'
|
|
21
|
+
method_option :module_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new files'
|
|
22
|
+
method_option :test_targets, :desc => 'Specifies project targets for adding new test files'
|
|
23
|
+
method_option :test_file_path, :desc => 'Specifies a location in the filesystem for new test files'
|
|
24
|
+
method_option :test_group_path, :desc => 'Specifies a location in Xcode groups for new test files'
|
|
25
|
+
method_option :test_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new test files'
|
|
26
|
+
method_option :custom_parameters, :type => :hash, :default => {}, :desc => 'Specifies extra parameters in format `key1:value1 key2:value2` for usage during code generation'
|
|
27
|
+
def gen(module_name, template_name)
|
|
28
|
+
does_rambafile_exist = Dir[RAMBAFILE_NAME].count > 0
|
|
29
|
+
|
|
30
|
+
unless does_rambafile_exist
|
|
31
|
+
puts('Rambafile not found! Run `generamba setup` in the working directory instead!'.red)
|
|
32
|
+
return
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
rambafile_validator = Generamba::RambafileValidator.new
|
|
36
|
+
rambafile_validator.validate(RAMBAFILE_NAME)
|
|
37
|
+
|
|
38
|
+
setup_username_command = Generamba::CLI::SetupUsernameCommand.new
|
|
39
|
+
setup_username_command.setup_username
|
|
40
|
+
|
|
41
|
+
rambafile = YAML.load_file(RAMBAFILE_NAME)
|
|
42
|
+
|
|
43
|
+
code_module = CodeModule.new(module_name, rambafile, options)
|
|
44
|
+
|
|
45
|
+
module_validator = ModuleValidator.new
|
|
46
|
+
module_validator.validate(code_module)
|
|
47
|
+
|
|
48
|
+
module_info = ModuleInfoGenerator.new(code_module)
|
|
49
|
+
template = ModuleTemplate.new(template_name, module_info.scope)
|
|
50
|
+
|
|
51
|
+
parameters = GenCommandTableParametersFormatter.prepare_parameters_for_displaying(code_module, template_name)
|
|
52
|
+
PrintTable.print_values(
|
|
53
|
+
values: parameters,
|
|
54
|
+
title: "Summary for gen #{module_name}"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
DependencyChecker.check_all_required_dependencies_has_in_podfile(template.dependencies, code_module.podfile_path)
|
|
58
|
+
DependencyChecker.check_all_required_dependencies_has_in_cartfile(template.dependencies, code_module.cartfile_path)
|
|
59
|
+
|
|
60
|
+
project = XcodeprojHelper.obtain_project(code_module.xcodeproj_path)
|
|
61
|
+
module_group_already_exists = XcodeprojHelper.module_with_group_path_already_exists(project, code_module.project_group_path, code_module.create_logical_groups)
|
|
62
|
+
|
|
63
|
+
if module_group_already_exists
|
|
64
|
+
replace_exists_module = yes?("#{module_name} module already exists. Replace? (yes/no)")
|
|
65
|
+
|
|
66
|
+
unless replace_exists_module
|
|
67
|
+
return
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
generator = Generamba::ModuleGenerator.new
|
|
72
|
+
generator.generate_module(module_name, code_module, template)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
desc 'udf [TEMPLATE_NAME]', 'Creates a new SwiftUI-UDF module with a given name'
|
|
76
|
+
method_option :description, :aliases => '-d', :desc => 'Provides a full description to the storage'
|
|
77
|
+
method_option :author, :desc => 'Specifies the author name for generated storage'
|
|
78
|
+
method_option :project_targets, :desc => 'Specifies project targets for adding new module files'
|
|
79
|
+
method_option :project_file_path, :desc => 'Specifies a location in the filesystem for new files'
|
|
80
|
+
method_option :project_group_path, :desc => 'Specifies a location in Xcode groups for new files'
|
|
81
|
+
method_option :module_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new files'
|
|
82
|
+
method_option :test_targets, :desc => 'Specifies project targets for adding new test files'
|
|
83
|
+
method_option :test_file_path, :desc => 'Specifies a location in the filesystem for new test files'
|
|
84
|
+
method_option :test_group_path, :desc => 'Specifies a location in Xcode groups for new test files'
|
|
85
|
+
method_option :test_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new test files'
|
|
86
|
+
method_option :test_unit_target, :desc => 'Specifies unit tests target for adding new files'
|
|
87
|
+
method_option :test_unit_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new unit test files'
|
|
88
|
+
method_option :test_unit_testable_import, :desc => 'Specifies unit tests testable import target'
|
|
89
|
+
method_option :test_snapshot_target, :desc => 'Specifies snapshot tests target for adding new files'
|
|
90
|
+
method_option :test_snapshot_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new snapshot test files'
|
|
91
|
+
method_option :test_snapshot_testable_import, :desc => 'Specifies snapshot tests testable import target'
|
|
92
|
+
method_option :custom_parameters, :type => :hash, :default => {}, :desc => 'Specifies extra parameters in format `key1:value1 key2:value2` for usage during code generation'
|
|
93
|
+
def udf(module_name)
|
|
94
|
+
gen(module_name, 'udf')
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
desc 'storage [TEMPLATE_NAME]', 'Creates a new SwiftUI-UDF storage with a given name'
|
|
98
|
+
method_option :description, :aliases => '-d', :desc => 'Provides a full description to the storage'
|
|
99
|
+
method_option :author, :desc => 'Specifies the author name for generated storage'
|
|
100
|
+
method_option :project_targets, :desc => 'Specifies project targets for adding new module files'
|
|
101
|
+
method_option :project_file_path, :desc => 'Specifies a location in the filesystem for new files'
|
|
102
|
+
method_option :project_group_path, :desc => 'Specifies a location in Xcode groups for new files'
|
|
103
|
+
method_option :module_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new files'
|
|
104
|
+
method_option :test_targets, :desc => 'Specifies project targets for adding new test files'
|
|
105
|
+
method_option :test_file_path, :desc => 'Specifies a location in the filesystem for new test files'
|
|
106
|
+
method_option :test_group_path, :desc => 'Specifies a location in Xcode groups for new test files'
|
|
107
|
+
method_option :test_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new test files'
|
|
108
|
+
method_option :test_unit_target, :desc => 'Specifies unit tests target for adding new files'
|
|
109
|
+
method_option :test_unit_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new unit test files'
|
|
110
|
+
method_option :test_unit_testable_import, :desc => 'Specifies unit tests testable import target'
|
|
111
|
+
method_option :test_snapshot_target, :desc => 'Specifies snapshot tests target for adding new files'
|
|
112
|
+
method_option :test_snapshot_path, :desc => 'Specifies a location (both in the filesystem and Xcode) for new snapshot test files'
|
|
113
|
+
method_option :test_snapshot_testable_import, :desc => 'Specifies snapshot tests testable import target'
|
|
114
|
+
method_option :custom_parameters, :type => :hash, :default => {}, :desc => 'Specifies extra parameters in format `key1:value1 key2:value2` for usage during code generation'
|
|
115
|
+
def storage(module_name)
|
|
116
|
+
gen(module_name, 'udf-storage')
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'xcodeproj'
|
|
3
|
+
require 'liquid'
|
|
4
|
+
require 'git'
|
|
5
|
+
require 'generamba/constants/rambafile_constants.rb'
|
|
6
|
+
require 'generamba/helpers/print_table.rb'
|
|
7
|
+
|
|
8
|
+
module Generamba::CLI
|
|
9
|
+
class Application < Thor
|
|
10
|
+
include Generamba
|
|
11
|
+
|
|
12
|
+
desc 'setup', 'Creates a Rambafile with a config for a given project'
|
|
13
|
+
def setup
|
|
14
|
+
properties = {}
|
|
15
|
+
|
|
16
|
+
setup_username_command = Generamba::CLI::SetupUsernameCommand.new
|
|
17
|
+
setup_username_command.setup_username
|
|
18
|
+
|
|
19
|
+
properties[COMPANY_KEY] = ask('The company name which will be used in the headers:')
|
|
20
|
+
|
|
21
|
+
project_name = Pathname.new(Dir.getwd).basename.to_s
|
|
22
|
+
is_right_project_name = yes?("The name of your project is #{project_name}. Do you want to use it? (yes/no)")
|
|
23
|
+
|
|
24
|
+
properties[PROJECT_NAME_KEY] = is_right_project_name ? project_name : ask_non_empty_string('The project name:', 'Project name should not be empty')
|
|
25
|
+
properties[PROJECT_PREFIX_KEY] = ask('The project prefix (if any):')
|
|
26
|
+
|
|
27
|
+
xcodeproj_path = ask_file_with_path('*.xcodeproj',
|
|
28
|
+
'.xcodeproj file of the project')
|
|
29
|
+
|
|
30
|
+
properties[XCODEPROJ_PATH_KEY] = xcodeproj_path
|
|
31
|
+
project = Xcodeproj::Project.open(xcodeproj_path)
|
|
32
|
+
|
|
33
|
+
targets_prompt = ''
|
|
34
|
+
project.targets.each_with_index { |element, i| targets_prompt += ("#{i}. #{element.name}" + "\n") }
|
|
35
|
+
project_target = ask_index("Select the appropriate target for adding your MODULES (type the index):\n" + targets_prompt,project.targets)
|
|
36
|
+
include_tests = yes?('Are you using unit-tests in this project? (yes/no)')
|
|
37
|
+
|
|
38
|
+
test_target = nil
|
|
39
|
+
|
|
40
|
+
if include_tests
|
|
41
|
+
test_target = ask_index("Select the appropriate target for adding your TESTS (type the index):\n" + targets_prompt,project.targets)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
should_add_all_modules_by_one_path = yes?('Do you want to add all your modules by one path? (yes/no)')
|
|
45
|
+
|
|
46
|
+
project_file_path = nil
|
|
47
|
+
project_group_path = nil
|
|
48
|
+
|
|
49
|
+
test_file_path = nil
|
|
50
|
+
test_group_path = nil
|
|
51
|
+
|
|
52
|
+
create_logical_groups = nil
|
|
53
|
+
|
|
54
|
+
if should_add_all_modules_by_one_path || include_tests
|
|
55
|
+
should_use_same_paths = false
|
|
56
|
+
|
|
57
|
+
if should_add_all_modules_by_one_path
|
|
58
|
+
should_use_same_paths = yes?('Do you want to use the same paths for your files both in Xcode and the filesystem? (yes/no)')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if should_use_same_paths
|
|
62
|
+
if should_add_all_modules_by_one_path
|
|
63
|
+
project_group_path = ask('The default path for creating new modules:')
|
|
64
|
+
project_file_path = project_group_path
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if include_tests
|
|
68
|
+
test_group_path = ask('The default path for creating tests:')
|
|
69
|
+
test_file_path = test_group_path
|
|
70
|
+
end
|
|
71
|
+
else
|
|
72
|
+
if should_add_all_modules_by_one_path
|
|
73
|
+
project_group_path = ask('The default path for creating new modules (in Xcode groups):')
|
|
74
|
+
project_file_path = ask('The default path for creating new modules (in the filesystem):')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if include_tests
|
|
78
|
+
test_group_path = ask('The default path for creating tests (in Xcode groups):')
|
|
79
|
+
test_file_path = ask('The default path for creating tests (in the filesystem):')
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
create_logical_groups = yes?('Do you want to create Groups in Xcode without folders in filesystem? (yes/no)')
|
|
85
|
+
|
|
86
|
+
using_pods = yes?('Are you using Cocoapods? (yes/no)')
|
|
87
|
+
if using_pods
|
|
88
|
+
properties[PODFILE_PATH_KEY] = ask_file_with_path('Podfile', 'Podfile')
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
using_carthage = yes?('Are you using Carthage? (yes/no)')
|
|
92
|
+
if using_carthage
|
|
93
|
+
properties[CARTFILE_PATH_KEY] = ask_file_with_path('Cartfile', 'Cartfile')
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
should_add_templates = yes?('Do you want to add some well known templates to the Rambafile? (yes/no)')
|
|
97
|
+
if should_add_templates
|
|
98
|
+
properties[TEMPLATES_KEY] = [
|
|
99
|
+
'{name: rviper_controller}',
|
|
100
|
+
'{name: mvvm_controller}',
|
|
101
|
+
'{name: swifty_viper}'
|
|
102
|
+
]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
properties[PROJECT_TARGET_KEY] = project_target.name if project_target
|
|
106
|
+
properties[PROJECT_FILE_PATH_KEY] = project_file_path if project_file_path
|
|
107
|
+
properties[PROJECT_GROUP_PATH_KEY] = project_group_path if project_group_path
|
|
108
|
+
properties[TEST_TARGET_KEY] = test_target.name if test_target
|
|
109
|
+
properties[TEST_FILE_PATH_KEY] = test_file_path if test_file_path
|
|
110
|
+
properties[TEST_GROUP_PATH_KEY] = test_group_path if test_group_path
|
|
111
|
+
properties[CREATE_LOGICAL_GROUPS_KEY] = create_logical_groups if create_logical_groups
|
|
112
|
+
|
|
113
|
+
PrintTable.print_values(
|
|
114
|
+
values: properties,
|
|
115
|
+
title: 'Summary for generamba setup'
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
Generamba::RambafileGenerator.create_rambafile(properties)
|
|
119
|
+
if should_add_templates
|
|
120
|
+
puts('Rambafile successfully created! Now run `generamba template install`.'.green)
|
|
121
|
+
else
|
|
122
|
+
puts('Rambafile successfully created!\n Go on and find some templates in our catalog using `generamba template list` command.\n Add any of them to the Rambafile and run `generamba template install`.'.green)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|