generamba-mp 0.0.2

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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +10 -0
  3. data/.gitignore +4 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +17 -0
  6. data/CHANGELOG.md +180 -0
  7. data/Gemfile +6 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +62 -0
  10. data/Rakefile +6 -0
  11. data/VISION.md +41 -0
  12. data/bin/console +14 -0
  13. data/bin/generamba +5 -0
  14. data/bin/setup +7 -0
  15. data/docs/2.x/roadmap.md +365 -0
  16. data/generamba.gemspec +38 -0
  17. data/lib/generamba.rb +16 -0
  18. data/lib/generamba/cli/cli.rb +16 -0
  19. data/lib/generamba/cli/gen_command.rb +76 -0
  20. data/lib/generamba/cli/setup_command.rb +122 -0
  21. data/lib/generamba/cli/setup_username_command.rb +21 -0
  22. data/lib/generamba/cli/template/template_create_command.rb +40 -0
  23. data/lib/generamba/cli/template/template_group.rb +14 -0
  24. data/lib/generamba/cli/template/template_install_command.rb +21 -0
  25. data/lib/generamba/cli/template/template_list_command.rb +25 -0
  26. data/lib/generamba/cli/template/template_search_command.rb +30 -0
  27. data/lib/generamba/cli/thor_extension.rb +47 -0
  28. data/lib/generamba/cli/version_command.rb +25 -0
  29. data/lib/generamba/code_generation/Rambafile.liquid +41 -0
  30. data/lib/generamba/code_generation/code_module.rb +100 -0
  31. data/lib/generamba/code_generation/content_generator.rb +43 -0
  32. data/lib/generamba/code_generation/module_template.rb +28 -0
  33. data/lib/generamba/code_generation/rambafile_generator.rb +23 -0
  34. data/lib/generamba/configuration/user_preferences.rb +50 -0
  35. data/lib/generamba/constants/constants.rb +12 -0
  36. data/lib/generamba/constants/rambafile_constants.rb +31 -0
  37. data/lib/generamba/constants/rambaspec_constants.rb +18 -0
  38. data/lib/generamba/constants/user_preferences_constants.rb +5 -0
  39. data/lib/generamba/helpers/dependency_checker.rb +54 -0
  40. data/lib/generamba/helpers/gen_command_table_parameters_formatter.rb +33 -0
  41. data/lib/generamba/helpers/module_info_generator.rb +33 -0
  42. data/lib/generamba/helpers/module_validator.rb +85 -0
  43. data/lib/generamba/helpers/print_table.rb +17 -0
  44. data/lib/generamba/helpers/rambafile_validator.rb +18 -0
  45. data/lib/generamba/helpers/template_helper.rb +30 -0
  46. data/lib/generamba/helpers/xcodeproj_helper.rb +256 -0
  47. data/lib/generamba/module_generator.rb +104 -0
  48. data/lib/generamba/template/creator/new_template/Code/Service/service.h.liquid +11 -0
  49. data/lib/generamba/template/creator/new_template/Code/Service/service.m.liquid +13 -0
  50. data/lib/generamba/template/creator/new_template/Tests/Service/service_tests.m.liquid +35 -0
  51. data/lib/generamba/template/creator/new_template/template.rambaspec.liquid +20 -0
  52. data/lib/generamba/template/creator/template_creator.rb +39 -0
  53. data/lib/generamba/template/helpers/catalog_downloader.rb +58 -0
  54. data/lib/generamba/template/helpers/catalog_template_list_helper.rb +23 -0
  55. data/lib/generamba/template/helpers/catalog_template_search_helper.rb +27 -0
  56. data/lib/generamba/template/helpers/catalog_terminator.rb +21 -0
  57. data/lib/generamba/template/helpers/rambaspec_validator.rb +52 -0
  58. data/lib/generamba/template/installer/abstract_installer.rb +9 -0
  59. data/lib/generamba/template/installer/catalog_installer.rb +73 -0
  60. data/lib/generamba/template/installer/local_installer.rb +32 -0
  61. data/lib/generamba/template/installer/remote_installer.rb +50 -0
  62. data/lib/generamba/template/installer/template_installer_factory.rb +22 -0
  63. data/lib/generamba/template/processor/template_declaration.rb +36 -0
  64. data/lib/generamba/template/processor/template_processor.rb +75 -0
  65. data/lib/generamba/tools/string-colorize.rb +23 -0
  66. data/lib/generamba/version.rb +5 -0
  67. metadata +271 -0
@@ -0,0 +1,33 @@
1
+ module Generamba
2
+ # Provides methods for prepare parameters for displaying in table.
3
+ class GenCommandTableParametersFormatter
4
+ require 'json'
5
+
6
+ # This method prepared parameter for displaying
7
+ def self.prepare_parameters_for_displaying(code_module, template_name)
8
+ params = {}
9
+
10
+ params['Targets'] = code_module.project_targets.join(',') if code_module.project_targets
11
+ params['Module path'] = code_module.project_file_path if code_module.project_file_path
12
+
13
+ if code_module.project_file_path != code_module.project_group_path
14
+ params['Module group path'] = code_module.project_group_path
15
+ end
16
+
17
+ params['Test targets'] = code_module.test_targets.join(',') if code_module.test_targets
18
+ params['Test file path'] = code_module.test_file_path if code_module.test_file_path
19
+
20
+ if code_module.test_file_path != code_module.test_group_path
21
+ params['Test group path'] = code_module.test_group_path
22
+ end
23
+
24
+ params['Template'] = template_name
25
+
26
+ unless code_module.custom_parameters.empty?
27
+ params['Custom parameters'] = code_module.custom_parameters.to_json
28
+ end
29
+
30
+ params
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ module Generamba
2
+
3
+ class ModuleInfoGenerator
4
+ attr_reader :scope
5
+
6
+ def initialize(code_module)
7
+ module_info = {
8
+ 'name' => code_module.name,
9
+ 'description' => code_module.description,
10
+ 'project_name' => code_module.project_name,
11
+ 'product_module_name' => code_module.product_module_name,
12
+ 'project_targets' => code_module.project_targets,
13
+ 'test_targets' => code_module.test_targets
14
+ }
15
+
16
+ developer = {
17
+ 'name' => code_module.author,
18
+ 'company' => code_module.company
19
+ }
20
+
21
+ @scope = {
22
+ 'year' => code_module.year,
23
+ 'date' => Time.now.strftime('%d/%m/%Y'),
24
+ 'developer' => developer,
25
+ 'module_info' => module_info,
26
+ 'prefix' => code_module.prefix,
27
+ 'custom_parameters' => code_module.custom_parameters
28
+ }
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,85 @@
1
+ module Generamba
2
+ # Provides methods for validating module
3
+ class ModuleValidator
4
+
5
+ TARGET_TYPE_PROJECT = 'project'
6
+ TARGET_TYPE_TEST = 'test'
7
+
8
+ # Method validates module
9
+ # @param code_module [CodeModule] The instance of CodeModule
10
+ #
11
+ # @return [Void]
12
+ def validate(code_module)
13
+ mandatory_fields = [COMPANY_KEY,
14
+ PROJECT_NAME_KEY,
15
+ XCODEPROJ_PATH_KEY]
16
+
17
+ mandatory_fields.each do |field|
18
+ unless code_module.instance_variable_get("@#{field}")
19
+ puts "Module is broken! *#{field}* field cannot be empty, because it is mandatory.".red
20
+ exit
21
+ end
22
+ end
23
+
24
+ project_failure_fields = all_project_failure_fields(code_module)
25
+ test_failure_fields = all_test_failure_fields(code_module)
26
+ failure_fields = project_failure_fields + test_failure_fields
27
+
28
+ if failure_fields.count > 0
29
+ puts "Module is broken! *#{failure_fields}* field cannot be empty, because it is mandatory.".red
30
+ exit
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ # Method which return all project failure fields
37
+ # @param code_module [CodeModule] The instance of CodeModule
38
+ #
39
+ # @return [Array]
40
+ def all_project_failure_fields(code_module)
41
+ return [] if !code_module.project_targets && !code_module.project_file_path && !code_module.project_group_path
42
+
43
+ all_nil_mandatory_fields_for_target_type(TARGET_TYPE_PROJECT, code_module)
44
+ end
45
+
46
+ # Method which return all test failure fields
47
+ # @param code_module [CodeModule] The instance of CodeModule
48
+ #
49
+ # @return [Array]
50
+ def all_test_failure_fields(code_module)
51
+ return [] if !code_module.test_targets && !code_module.test_file_path && !code_module.test_group_path
52
+
53
+ all_nil_mandatory_fields_for_target_type(TARGET_TYPE_TEST, code_module)
54
+ end
55
+
56
+ # Method which return all failure fields for target_type
57
+ # @param target_type [String] "project" or "test"
58
+ # @param code_module [CodeModule] The instance of CodeModule
59
+ #
60
+ # @return [Array]
61
+ def all_nil_mandatory_fields_for_target_type(target_type, code_module)
62
+ fields = []
63
+
64
+ variable_name = "#{target_type}_targets"
65
+
66
+ unless code_module.instance_variable_get("@#{variable_name}")
67
+ target_const_value = Generamba.const_get(target_type.upcase + '_TARGET_KEY')
68
+ targets_const_value = Generamba.const_get(target_type.upcase + '_TARGETS_KEY')
69
+ fields.push(target_const_value)
70
+ fields.push(targets_const_value)
71
+ end
72
+
73
+ variable_name = "#{target_type}_file_path"
74
+ file_path_const_value = Generamba.const_get(target_type.upcase + '_FILE_PATH_KEY')
75
+ fields.push(file_path_const_value) unless code_module.instance_variable_get("@#{variable_name}")
76
+
77
+ variable_name = "#{target_type}_group_path"
78
+ group_path_const_value = Generamba.const_get(target_type.upcase + '_GROUP_PATH_KEY')
79
+ fields.push(group_path_const_value) unless code_module.instance_variable_get("@#{variable_name}")
80
+
81
+ fields
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,17 @@
1
+ module Generamba
2
+ # Provides methods for print parameters in nice table.
3
+ class PrintTable
4
+ # This method prints out all the user inputs in a nice table.
5
+ def self.print_values(values: nil, title: nil)
6
+ require 'terminal-table'
7
+
8
+ params = {}
9
+ params[:rows] = values
10
+ params[:title] = title.green if title
11
+
12
+ puts ''
13
+ puts Terminal::Table.new(params)
14
+ puts ''
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Generamba
2
+ # Provides methods for validating Rambafile contents
3
+ class RambafileValidator
4
+ # Method validates Rambafile contents
5
+ # @param path [String] The path to a Rambafile
6
+ #
7
+ # @return [Void]
8
+ def validate(path)
9
+ file_contents = open(path).read
10
+ preferences = file_contents.empty? ? {} : YAML.load(file_contents).to_hash
11
+
12
+ unless preferences[TEMPLATES_KEY]
13
+ puts "You can't run *generamba gen* without any templates installed. Add their declarations to a Rambafile and run *generamba template install*.".red
14
+ exit
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ module Generamba
2
+ # Provides a number of helper methods for manipulating Generamba template files
3
+ class TemplateHelper
4
+ # Returns a file path for a specific template .rambaspec file
5
+ # @param template_name [String] The Generamba template name
6
+ #
7
+ # @return [Pathname]
8
+ def self.obtain_spec(template_name)
9
+ template_path = self.obtain_path(template_name)
10
+ spec_path = template_path.join(template_name + RAMBASPEC_EXTENSION)
11
+
12
+ spec_path
13
+ end
14
+
15
+ # Returns a file path for a specific template folder
16
+ # @param template_name [String] The Generamba template name
17
+ #
18
+ # @return [Pathname]
19
+ def self.obtain_path(template_name)
20
+ path = Pathname.new(Dir.getwd)
21
+ .join(TEMPLATES_FOLDER)
22
+ .join(template_name)
23
+
24
+ error_description = "Cannot find template named #{template_name}! Add it to the Rambafile and run *generamba template install*".red
25
+ raise StandardError, error_description unless path.exist?
26
+
27
+ path
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,256 @@
1
+ module Generamba
2
+ # Provides a number of helper methods for working with xcodeproj gem
3
+ class XcodeprojHelper
4
+ # Returns a PBXProject class for a given name
5
+ # @param project_name [String] The name of the project file
6
+ #
7
+ # @return [Xcodeproj::Project]
8
+ def self.obtain_project(project_name)
9
+ Xcodeproj::Project.open(project_name)
10
+ end
11
+
12
+ # Adds a provided file to a specific Project and Target
13
+ # @param project [Xcodeproj::Project] The target xcodeproj file
14
+ # @param targets_name [String] Array of targets name
15
+ # @param group_path [Pathname] The Xcode group path for current file
16
+ # @param dir_path [Pathname] The directory path for current file
17
+ # @param file_group_path [String] Directory path
18
+ # @param file_name [String] Current file name
19
+ # @param file_is_resource [TrueClass or FalseClass] If true then file is resource
20
+ #
21
+ # @return [void]
22
+ def self.add_file_to_project_and_targets(project, targets_name, group_path, dir_path, file_group_path, file_name, file_is_resource = false)
23
+ file_path = dir_path
24
+ file_path = file_path.join(file_group_path) if file_group_path
25
+ file_path = file_path.join(file_name) if file_name
26
+
27
+ module_group = self.retrieve_group_or_create_if_needed(group_path, dir_path, file_group_path, project, true)
28
+ xcode_file = module_group.new_file(File.absolute_path(file_path))
29
+
30
+ targets_name.each do |target|
31
+ xcode_target = obtain_target(target, project)
32
+
33
+ if file_is_resource || self.is_bundle_resource?(file_name)
34
+ xcode_target.add_resources([xcode_file])
35
+ elsif self.is_compile_source?(file_name)
36
+ xcode_target.add_file_references([xcode_file])
37
+ end
38
+ end
39
+ end
40
+
41
+ # Adds a provided directory to a specific Project
42
+ # @param project [Xcodeproj::Project] The target xcodeproj file
43
+ # @param group_path [Pathname] The Xcode group path for current directory
44
+ # @param dir_path [Pathname] The directory path for current directory
45
+ # @param directory_name [String] Current directory name
46
+ #
47
+ # @return [void]
48
+ def self.add_group_to_project(project, group_path, dir_path, directory_name)
49
+ self.retrieve_group_or_create_if_needed(group_path, dir_path, directory_name, project, true)
50
+ end
51
+
52
+ # File is a compiled source
53
+ # @param file_name [String] String of file name
54
+ #
55
+ # @return [TrueClass or FalseClass]
56
+ def self.is_compile_source?(file_name)
57
+ File.extname(file_name) == '.m' || File.extname(file_name) == '.swift' || File.extname(file_name) == '.mm'
58
+ end
59
+
60
+ # File is a resource
61
+ # @param resource_name [String] String of resource name
62
+ #
63
+ # @return [TrueClass or FalseClass]
64
+ def self.is_bundle_resource?(resource_name)
65
+ File.extname(resource_name) == '.xib' || File.extname(resource_name) == '.storyboard'
66
+ end
67
+
68
+ # Recursively clears children of the given group
69
+ # @param project [Xcodeproj::Project] The working Xcode project file
70
+ # @param group_path [Pathname] The full group path
71
+ #
72
+ # @return [Void]
73
+ def self.clear_group(project, targets_name, group_path)
74
+ module_group = self.retrieve_group_or_create_if_needed(group_path, nil, nil, project, false)
75
+ return unless module_group
76
+
77
+ files_path = self.files_path_from_group(module_group, project)
78
+ return unless files_path
79
+
80
+ files_path.each do |file_path|
81
+ self.remove_file_by_file_path(file_path, targets_name, project)
82
+ end
83
+
84
+ module_group.clear
85
+ end
86
+
87
+ # Finds a group in a xcodeproj file with a given path
88
+ # @param project [Xcodeproj::Project] The working Xcode project file
89
+ # @param group_path [Pathname] The full group path
90
+ #
91
+ # @return [TrueClass or FalseClass]
92
+ def self.module_with_group_path_already_exists(project, group_path)
93
+ module_group = self.retrieve_group_or_create_if_needed(group_path, nil, nil, project, false)
94
+ module_group.nil? ? false : true
95
+ end
96
+
97
+ private
98
+
99
+ # Finds or creates a group in a xcodeproj file with a given path
100
+ # @param group_path [Pathname] The Xcode group path for module
101
+ # @param dir_path [Pathname] The directory path for module
102
+ # @param file_group_path [String] Directory path
103
+ # @param project [Xcodeproj::Project] The working Xcode project file
104
+ # @param create_group_if_not_exists [TrueClass or FalseClass] If true nonexistent group will be created
105
+ #
106
+ # @return [PBXGroup]
107
+ def self.retrieve_group_or_create_if_needed(group_path, dir_path, file_group_path, project, create_group_if_not_exists)
108
+ group_names = path_names_from_path(group_path)
109
+ group_components_count = group_names.count
110
+ group_names += path_names_from_path(file_group_path) if file_group_path
111
+
112
+ final_group = project
113
+
114
+ group_names.each_with_index do |group_name, index|
115
+ next_group = final_group[group_name]
116
+
117
+ unless next_group
118
+ return nil unless create_group_if_not_exists
119
+
120
+ if group_path != dir_path && index == group_components_count-1
121
+ next_group = final_group.new_group(group_name, dir_path, :project)
122
+ else
123
+ next_group = final_group.new_group(group_name, group_name)
124
+ end
125
+ end
126
+
127
+ final_group = next_group
128
+ end
129
+
130
+ final_group
131
+ end
132
+
133
+ # Returns an AbstractTarget class for a given name
134
+ # @param target_name [String] The name of the target
135
+ # @param project [Xcodeproj::Project] The target xcodeproj file
136
+ #
137
+ # @return [Xcodeproj::AbstractTarget]
138
+ def self.obtain_target(target_name, project)
139
+ project.targets.each do |target|
140
+ return target if target.name == target_name
141
+ end
142
+
143
+ error_description = "Cannot find a target with name #{target_name} in Xcode project".red
144
+ raise StandardError, error_description
145
+ end
146
+
147
+ # Splits the provided Xcode path to an array of separate paths
148
+ # @param path The full group or file path
149
+ #
150
+ # @return [[String]]
151
+ def self.path_names_from_path(path)
152
+ path.to_s.split('/')
153
+ end
154
+
155
+ # Remove build file from target build phase
156
+ # @param file_path [String] The path of the file
157
+ # @param targets_name [String] Array of targets
158
+ # @param project [Xcodeproj::Project] The target xcodeproj file
159
+ #
160
+ # @return [Void]
161
+ def self.remove_file_by_file_path(file_path, targets_name, project)
162
+ file_names = path_names_from_path(file_path)
163
+
164
+ build_phases = nil
165
+
166
+ if self.is_compile_source?(file_names.last)
167
+ build_phases = self.build_phases_from_targets(targets_name, project)
168
+ elsif self.is_bundle_resource?(file_names.last)
169
+ build_phases = self.resources_build_phase_from_targets(targets_name, project)
170
+ end
171
+
172
+ self.remove_file_from_build_phases(file_path, build_phases)
173
+ end
174
+
175
+ def self.remove_file_from_build_phases(file_path, build_phases)
176
+ return if build_phases.nil?
177
+
178
+ build_phases.each do |build_phase|
179
+ build_phase.files.each do |build_file|
180
+ next if build_file.nil? || build_file.file_ref.nil?
181
+
182
+ build_file_path = self.configure_file_ref_path(build_file.file_ref)
183
+
184
+ if build_file_path == file_path
185
+ build_phase.remove_build_file(build_file)
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ # Find and return target build phases
192
+ # @param targets_name [String] Array of targets
193
+ # @param project [Xcodeproj::Project] The target xcodeproj file
194
+ #
195
+ # @return [[PBXSourcesBuildPhase]]
196
+ def self.build_phases_from_targets(targets_name, project)
197
+ build_phases = []
198
+
199
+ targets_name.each do |target_name|
200
+ xcode_target = self.obtain_target(target_name, project)
201
+ xcode_target.build_phases.each do |build_phase|
202
+ if build_phase.isa == 'PBXSourcesBuildPhase'
203
+ build_phases.push(build_phase)
204
+ end
205
+ end
206
+ end
207
+
208
+ build_phases
209
+ end
210
+
211
+ # Find and return target resources build phase
212
+ # @param targets_name [String] Array of targets
213
+ # @param project [Xcodeproj::Project] The target xcodeproj file
214
+ #
215
+ # @return [[PBXResourcesBuildPhase]]
216
+ def self.resources_build_phase_from_targets(targets_name, project)
217
+ resource_build_phase = []
218
+
219
+ targets_name.each do |target_name|
220
+ xcode_target = self.obtain_target(target_name, project)
221
+ resource_build_phase.push(xcode_target.resources_build_phase)
222
+ end
223
+
224
+ resource_build_phase
225
+ end
226
+
227
+ # Get configure file full path
228
+ # @param file_ref [PBXFileReference] Build file
229
+ #
230
+ # @return [String]
231
+ def self.configure_file_ref_path(file_ref)
232
+ build_file_ref_path = file_ref.hierarchy_path.to_s
233
+ build_file_ref_path[0] = ''
234
+
235
+ build_file_ref_path
236
+ end
237
+
238
+ # Get all files path from group path
239
+ # @param module_group [PBXGroup] The module group
240
+ # @param project [Xcodeproj::Project] The target xcodeproj file
241
+ #
242
+ # @return [[String]]
243
+ def self.files_path_from_group(module_group, _project)
244
+ files_path = []
245
+
246
+ module_group.recursive_children.each do |file_ref|
247
+ if file_ref.isa == 'PBXFileReference'
248
+ file_ref_path = configure_file_ref_path(file_ref)
249
+ files_path.push(file_ref_path)
250
+ end
251
+ end
252
+
253
+ files_path
254
+ end
255
+ end
256
+ end