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,25 @@
1
+ require 'thor'
2
+ require 'generamba/version.rb'
3
+
4
+ module Generamba::CLI
5
+ class Application < Thor
6
+ include Generamba
7
+
8
+ desc 'version', 'Prints out Generamba current version'
9
+ def version
10
+ options = {}
11
+ options['Version'] = Generamba::VERSION.green
12
+ options['Release date'] = Generamba::RELEASE_DATE.green
13
+ options['Change notes'] = Generamba::RELEASE_LINK.green
14
+
15
+ values = []
16
+
17
+ options.each do |title, value|
18
+ values.push("#{title}: #{value}")
19
+ end
20
+
21
+ output = values.join("\n")
22
+ puts(output)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,41 @@
1
+ ### Headers settings
2
+ company: {{ company }}
3
+
4
+ ### Xcode project settings
5
+ project_name: {{ project_name }}
6
+ xcodeproj_path: {{ xcodeproj_path }}
7
+ {% if prefix != "" %}prefix: {{ prefix }}{% endif %}
8
+
9
+ {% if (project_target != nil and project_target != "") or (project_file_path != nil and project_file_path != "") or (project_group_path != nil and project_group_path != "") %}### Code generation settings section
10
+ {% if project_target != nil and project_target != "" %}# The main project target name
11
+ project_target: {{ project_target }}{% endif %}
12
+
13
+ {% if project_file_path != nil and project_file_path != "" %}# The file path for new modules
14
+ project_file_path: {{ project_file_path }}{% endif %}
15
+
16
+ {% if project_group_path != nil and project_group_path != "" %}# The Xcode group path to new modules
17
+ project_group_path: {{ project_group_path }}{% endif %}
18
+ {% endif %}
19
+
20
+ {% if (test_target != nil and test_target != "") or (test_file_path != nil and test_file_path != "") or (test_group_path != nil and test_group_path != "") %}### Tests generation settings section
21
+ {% if test_target != nil and test_target != "" %}# The tests target name
22
+ test_target: {{ test_target }}{% endif %}
23
+
24
+ {% if test_file_path != nil and test_file_path != "" %}# The file path for new tests
25
+ test_file_path: {{ test_file_path }}{% endif %}
26
+
27
+ {% if test_group_path != nil and test_group_path != "" %}# The Xcode group path to new tests
28
+ test_group_path: {{ test_group_path }}{% endif %}
29
+ {% endif %}
30
+
31
+ {% if podfile_path != nil or cartfile_path != nil %}### Dependencies settings section{% endif %}
32
+ {% if podfile_path != nil %}podfile_path: {{ podfile_path }}{% endif %}
33
+ {% if cartfile_path != nil %}cartfile_path: {{ cartfile_path }}{% endif %}
34
+
35
+ ### Templates
36
+ templates:
37
+ {% if templates.size > 0 %}{% for item in templates %}- {{ item }}
38
+ {% endfor %}{% else %}#- {name: local_template_name, local: 'absolute/file/path'}
39
+ #- {name: remote_template_name, git: 'https://github.com/igrekde/remote_template'}
40
+ #- {name: catalog_template_name}
41
+ {% endif %}
@@ -0,0 +1,100 @@
1
+ module Generamba
2
+
3
+ SLASH_REGEX = /^\/|\/$/
4
+ C99IDENTIFIER = /[^\w]/
5
+
6
+ PATH_TYPE_PROJECT = 'project'
7
+ PATH_TYPE_TEST = 'test'
8
+
9
+ # Represents currently generating code module
10
+ class CodeModule
11
+ attr_reader :name,
12
+ :description,
13
+ :author,
14
+ :company,
15
+ :year,
16
+ :prefix,
17
+ :project_name,
18
+ :product_module_name,
19
+ :xcodeproj_path,
20
+ :project_file_path,
21
+ :project_group_path,
22
+ :test_file_path,
23
+ :test_group_path,
24
+ :project_targets,
25
+ :test_targets,
26
+ :podfile_path,
27
+ :cartfile_path,
28
+ :custom_parameters
29
+
30
+ def initialize(name, rambafile, options)
31
+ # Base initialization
32
+ @name = name
33
+ @description = options[:description] ? options[:description] : "#{name} module"
34
+ @author = rambafile[AUTHOR_NAME_KEY] ? rambafile[AUTHOR_NAME_KEY] : UserPreferences.obtain_username
35
+ @company = rambafile[COMPANY_KEY]
36
+ @year = Time.now.year.to_s
37
+
38
+ @prefix = rambafile[PROJECT_PREFIX_KEY]
39
+ @project_name = rambafile[PROJECT_NAME_KEY]
40
+
41
+ @product_module_name = rambafile[PRODUCT_MODULE_NAME_KEY]
42
+ @product_module_name = @project_name.gsub(C99IDENTIFIER, '_') if !@product_module_name && @project_name
43
+
44
+ @xcodeproj_path = rambafile[XCODEPROJ_PATH_KEY]
45
+
46
+ setup_file_and_group_paths(rambafile[PROJECT_FILE_PATH_KEY], rambafile[PROJECT_GROUP_PATH_KEY], PATH_TYPE_PROJECT)
47
+ setup_file_and_group_paths(rambafile[TEST_FILE_PATH_KEY], rambafile[TEST_GROUP_PATH_KEY], PATH_TYPE_TEST)
48
+
49
+ @project_targets = [rambafile[PROJECT_TARGET_KEY]] if rambafile[PROJECT_TARGET_KEY]
50
+ @project_targets = rambafile[PROJECT_TARGETS_KEY] if rambafile[PROJECT_TARGETS_KEY]
51
+
52
+ @test_targets = [rambafile[TEST_TARGET_KEY]] if rambafile[TEST_TARGET_KEY]
53
+ @test_targets = rambafile[TEST_TARGETS_KEY] if rambafile[TEST_TARGETS_KEY]
54
+
55
+ # Custom parameters
56
+ @custom_parameters = options[:custom_parameters]
57
+
58
+ # Options adaptation
59
+ @author = options[:author] if options[:author]
60
+ @project_targets = options[:project_targets].split(',') if options[:project_targets]
61
+ @test_targets = options[:test_targets].split(',') if options[:test_targets]
62
+
63
+ setup_file_and_group_paths(options[:project_file_path], options[:project_group_path], PATH_TYPE_PROJECT)
64
+ setup_file_and_group_paths(options[:test_file_path], options[:test_group_path], PATH_TYPE_TEST)
65
+
66
+ # The priority is given to `module_path` and 'test_path' options
67
+ setup_file_and_group_paths(options[:module_path], options[:module_path], PATH_TYPE_PROJECT)
68
+ setup_file_and_group_paths(options[:test_path], options[:test_path], PATH_TYPE_TEST)
69
+
70
+ @podfile_path = rambafile[PODFILE_PATH_KEY] if rambafile[PODFILE_PATH_KEY]
71
+ @cartfile_path = rambafile[CARTFILE_PATH_KEY] if rambafile[CARTFILE_PATH_KEY]
72
+ end
73
+
74
+ private
75
+
76
+ def setup_file_and_group_paths(file_path, group_path, path_type)
77
+ if file_path || group_path
78
+ variable_name = "#{path_type}_file_path"
79
+
80
+ if file_path || !instance_variable_get("@#{variable_name}")
81
+ file_path = group_path unless file_path
82
+
83
+ variable_value = file_path.gsub(SLASH_REGEX, '')
84
+ variable_value = Pathname.new(variable_value).join(@name)
85
+ instance_variable_set("@#{variable_name}", variable_value)
86
+ end
87
+
88
+ variable_name = "#{path_type}_group_path"
89
+
90
+ if group_path || !instance_variable_get("@#{variable_name}")
91
+ group_path = file_path unless group_path
92
+
93
+ variable_value = group_path.gsub(SLASH_REGEX, '')
94
+ variable_value = Pathname.new(variable_value).join(@name)
95
+ instance_variable_set("@#{variable_name}", variable_value)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,43 @@
1
+ require 'liquid'
2
+
3
+ module Generamba
4
+
5
+ # Responsible for generating code using provided liquid templates
6
+ class ContentGenerator
7
+
8
+ # Generates and returns a filename and a body of a specific code file.
9
+ # @param file [Hash<String,String>] A hashmap with template's filename and filepath
10
+ # @param scope [Hash<String,String>] A hashmap with module info
11
+ # @param template [ModuleTemplate] The model describing a Generamba template used for code generation
12
+ #
13
+ # @return [String], [String] The generated file_name and body
14
+ def self.create_file(file, scope, template)
15
+ file_source = IO.read(template.template_path.join(file[TEMPLATE_FILE_PATH_KEY]))
16
+ Liquid::Template.file_system = Liquid::LocalFileSystem.new(template.template_path.join('snippets'), '%s.liquid')
17
+
18
+ template = Liquid::Template.parse(file_source)
19
+ filename_template = self.file_name_template(file)
20
+
21
+ file_basename = File.basename(file[TEMPLATE_FILE_NAME_KEY])
22
+
23
+ module_info = scope['module_info']
24
+
25
+ module_info['file_basename'] = file_basename
26
+
27
+ file_name = filename_template.render(scope)
28
+
29
+ module_info['file_name'] = file_name
30
+ module_info.delete('file_basename')
31
+
32
+ content = template.render(scope)
33
+
34
+ return file_name, content
35
+ end
36
+
37
+ def self.file_name_template(file)
38
+ template_default_text = '{{ prefix }}{{ module_info.name }}{{ module_info.file_basename }}'
39
+ template_text = file[TEMPLATE_FILE_CUSTOM_NAME_KEY] || template_default_text
40
+ return Liquid::Template.parse(template_text)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ require 'generamba/helpers/template_helper.rb'
2
+
3
+ module Generamba
4
+
5
+ # Represents a single Generamba module template
6
+ class ModuleTemplate
7
+ attr_reader :template_name, :template_path, :code_files, :test_files, :dependencies
8
+
9
+ def initialize(name, options = nil)
10
+ spec_path = TemplateHelper.obtain_spec(name)
11
+
12
+ unless options
13
+ spec = YAML.load_file(spec_path)
14
+ else
15
+ spec_source = IO.read(spec_path)
16
+ spec_template = Liquid::Template.parse(spec_source)
17
+ spec_content = spec_template.render(options)
18
+ spec = YAML.load(spec_content)
19
+ end
20
+
21
+ @code_files = spec[TEMPLATE_CODE_FILES_KEY]
22
+ @test_files = spec[TEMPLATE_TEST_FILES_KEY]
23
+ @template_name = spec[TEMPLATE_NAME_KEY]
24
+ @template_path = TemplateHelper.obtain_path(name)
25
+ @dependencies = spec[TEMPLATE_DEPENDENCIES_KEY]
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ require 'liquid'
2
+
3
+ module Generamba
4
+
5
+ # Responsible for creating Generamba configs
6
+ class RambafileGenerator
7
+
8
+ # Creates a Rambafile using the provided properties hashmap
9
+ # @param properties Rambafile properties
10
+ #
11
+ # @return void
12
+ def self.create_rambafile(properties)
13
+ file_source = IO.read(File.dirname(__FILE__) + '/Rambafile.liquid')
14
+
15
+ template = Liquid::Template.parse(file_source)
16
+ output = template.render(properties).gsub!(/[\n]{3,}/, "\n\n");
17
+
18
+ File.open(RAMBAFILE_NAME, 'w+') {|f|
19
+ f.write(output)
20
+ }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,50 @@
1
+ require 'generamba/constants/user_preferences_constants.rb'
2
+
3
+ module Generamba
4
+
5
+ # A class that provides methods for working with user-specific information.
6
+ # Currently it has methods for obtaining and saving username, later it may be improved to something more general.
7
+ class UserPreferences
8
+
9
+ def self.obtain_username
10
+ path = obtain_user_preferences_path
11
+
12
+ file_contents = open(path).read
13
+ preferences = file_contents.empty? ? {} : YAML.load(file_contents).to_hash
14
+
15
+ return preferences[USERNAME_KEY]
16
+ end
17
+
18
+ def self.save_username(username)
19
+ path = obtain_user_preferences_path
20
+
21
+ file_contents = open(path).read
22
+ preferences = file_contents.empty? ? {} : YAML.load(file_contents).to_hash
23
+
24
+ preferences[USERNAME_KEY] = username
25
+ File.open(path, 'w+') { |f| f.write(preferences.to_yaml) }
26
+ end
27
+
28
+ private
29
+
30
+ def self.obtain_user_preferences_path
31
+ home_path = Pathname.new(ENV['HOME'])
32
+ .join(GENERAMBA_HOME_DIR)
33
+
34
+ path_exists = Dir.exist?(home_path)
35
+
36
+ unless path_exists
37
+ FileUtils.mkdir_p home_path
38
+ end
39
+
40
+ preferences_path = home_path.join(USER_PREFERENCES_FILE)
41
+ preferences_exist = File.file?(preferences_path)
42
+
43
+ unless preferences_exist
44
+ File.open(preferences_path, 'w+') { |f| f.write('') }
45
+ end
46
+
47
+ return preferences_path
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ module Generamba
2
+
3
+ # General constants
4
+ RAMBAFILE_NAME = 'Rambafile'
5
+ RAMBASPEC_EXTENSION = '.rambaspec'
6
+ TEMPLATES_FOLDER = 'Templates'
7
+ RAMBLER_CATALOG_REPO = 'https://github.com/rambler-digital-solutions/generamba-catalog'
8
+ GENERAMBA_CATALOG_NAME = 'generamba-catalog'
9
+ GENERAMBA_HOME_DIR = '.generamba'
10
+ CATALOGS_DIR = 'catalogs'
11
+ USER_PREFERENCES_FILE = 'user_preferences.yml'
12
+ end
@@ -0,0 +1,31 @@
1
+ module Generamba
2
+
3
+ # Keys of Rambafile files
4
+ COMPANY_KEY = 'company'
5
+ AUTHOR_NAME_KEY = 'author'
6
+ PROJECT_NAME_KEY = 'project_name'
7
+ PROJECT_PREFIX_KEY = 'prefix'
8
+ XCODEPROJ_PATH_KEY = 'xcodeproj_path'
9
+
10
+ PROJECT_TARGET_KEY = 'project_target'
11
+ PROJECT_TARGETS_KEY = 'project_targets'
12
+ PROJECT_FILE_PATH_KEY = 'project_file_path'
13
+ PROJECT_GROUP_PATH_KEY = 'project_group_path'
14
+
15
+ PRODUCT_MODULE_NAME_KEY = 'product_module_name'
16
+
17
+ TEST_TARGET_KEY = 'test_target'
18
+ TEST_TARGETS_KEY = 'test_targets'
19
+ TEST_FILE_PATH_KEY = 'test_file_path'
20
+ TEST_GROUP_PATH_KEY = 'test_group_path'
21
+
22
+ PODFILE_PATH_KEY = 'podfile_path'
23
+ CARTFILE_PATH_KEY = 'cartfile_path'
24
+
25
+ CATALOGS_KEY = 'catalogs'
26
+ TEMPLATES_KEY = 'templates'
27
+ TEMPLATE_DECLARATION_NAME_KEY = 'name'
28
+ TEMPLATE_DECLARATION_LOCAL_KEY = 'local'
29
+ TEMPLATE_DECLARATION_GIT_KEY = 'git'
30
+ TEMPLATE_DECLARATION_BRANCH_KEY = 'branch'
31
+ end
@@ -0,0 +1,18 @@
1
+ module Generamba
2
+
3
+ # Keys of .rambaspec files
4
+ TEMPLATE_NAME_KEY = 'name'
5
+ TEMPLATE_SUMMARY_KEY = 'summary'
6
+ TEMPLATE_AUTHOR_KEY = 'author'
7
+ TEMPLATE_VERSION_KEY = 'version'
8
+ TEMPLATE_LICENSE_KEY = 'license'
9
+
10
+ TEMPLATE_CODE_FILES_KEY = 'code_files'
11
+ TEMPLATE_TEST_FILES_KEY = 'test_files'
12
+ TEMPLATE_FILE_NAME_KEY = 'name'
13
+ TEMPLATE_FILE_CUSTOM_NAME_KEY = 'custom_name'
14
+ TEMPLATE_FILE_PATH_KEY = 'path'
15
+ TEMPLATE_FILE_IS_RESOURCE_KEY = 'is_resource'
16
+
17
+ TEMPLATE_DEPENDENCIES_KEY = 'dependencies'
18
+ end
@@ -0,0 +1,5 @@
1
+ module Generamba
2
+
3
+ # Keys of file user_preferences.yml
4
+ USERNAME_KEY = 'username'
5
+ end
@@ -0,0 +1,54 @@
1
+ require 'cocoapods-core'
2
+
3
+ module Generamba
4
+ # Provides methods for check dependencies from rambaspec in podfile
5
+ class DependencyChecker
6
+ # Check Podfile for dependencies
7
+ # @param dependencies [Array] Array of dependencies name
8
+ # @param podfile_path [String] String of Podfile path
9
+ #
10
+ # @return [void]
11
+ def self.check_all_required_dependencies_has_in_podfile(dependencies, podfile_path)
12
+ return if !dependencies || dependencies.count == 0 || !podfile_path
13
+
14
+ dependencies_names = []
15
+ Pod::Podfile.from_file(Pathname.new(podfile_path)).dependencies.each do |dependency|
16
+ dependencies_names.push(dependency.name.gsub(/ .*/, ''))
17
+ end
18
+
19
+ not_existing_dependency = []
20
+
21
+ dependencies.each do |dependency_name|
22
+ unless dependencies_names.include?(dependency_name)
23
+ not_existing_dependency.push(dependency_name)
24
+ end
25
+ end
26
+
27
+ if not_existing_dependency.count > 0
28
+ puts "[Warning] Dependencies #{not_existing_dependency} missed in Podfile".yellow
29
+ end
30
+ end
31
+
32
+ # Check Cartfile for dependencies
33
+ # @param dependencies [Array] Array of dependencies name
34
+ # @param cartfile_path [String] String of Podfile path
35
+ #
36
+ # @return [void]
37
+ def self.check_all_required_dependencies_has_in_cartfile(dependencies, cartfile_path)
38
+ return if !dependencies || dependencies.count == 0 || !cartfile_path
39
+
40
+ cartfile_string = File.read(cartfile_path)
41
+
42
+ not_existing_dependency = []
43
+ dependencies.each do |dependency_name|
44
+ unless cartfile_string.include?(dependency_name)
45
+ not_existing_dependency.push(dependency_name)
46
+ end
47
+ end
48
+
49
+ if not_existing_dependency.count > 0
50
+ puts "[Warning] Dependencies #{not_existing_dependency} missed in Cartfile".yellow
51
+ end
52
+ end
53
+ end
54
+ end