generamba 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa6d08c063acbc143e6bb207b57f3ff29335003f
4
- data.tar.gz: 75be1fd6927e0a08bf3d9dc122925166abbfb654
3
+ metadata.gz: b25fd879d1e1ee8d3207d476da127fcb08fcfdd5
4
+ data.tar.gz: eed7ef7a0a606908dc0bf9833ab653b9ad74e993
5
5
  SHA512:
6
- metadata.gz: 0c532fd9d76a7714fae9d7083849b41516bab539554195cb4e9a3f69dbceb3d63b076950732fd2a37676c564d73a7e0e4aebcb1d49f0ea6b2ef7ef6d68cdad95
7
- data.tar.gz: 2b4bfa45e3fcc56debd966132ff98b09c239a52472a3fbdcc5113e816c977425133aeb2b1b50779ee67e6d8f313959866b5813ab100fcb0446036a5bd6468fb3
6
+ metadata.gz: 7b73f00f33b102a49e4c76cd5a2442533827a5eabb9705d3f9bef6c0a98ab94bd96a52be8a3518921ca8d803e8b81f15647e10741eb4a898cc26dde8de191942
7
+ data.tar.gz: a81ba5d21f02796dd6ef4f20baa93538325fee01f9afcc7eb90208509506f8ece559badb1b82d271a36a18ccaa702ea22235f8f57374d92df1ba74d63ffe8bc6
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .idea/.name
2
+ .idea/Generamba.iml
3
+ .idea/misc.xml
4
+ .idea/modules.xml
5
+ .idea/vcs.xml
6
+ .idea/workspace.xml
data/.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
+ os:
2
+ - osx
1
3
  language: ruby
2
4
  rvm:
3
5
  - 2.1.6
4
- before_install: gem install bundler -v 1.10.6
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in generamba.gemspec
4
4
  gemspec
5
+
6
+ gem 'rspec', '~> 3.0'
data/Gemfile.lock CHANGED
@@ -1,18 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- generamba (0.5.0)
5
- git
6
- liquid
7
- settingslogic
8
- thor
9
- tilt
10
- xcodeproj
4
+ generamba (0.7.1)
5
+ git (= 1.2.9.1)
6
+ liquid (= 3.0.6)
7
+ thor (= 0.19.1)
8
+ tilt (= 2.0.1)
9
+ xcodeproj (= 0.28.2)
11
10
 
12
11
  GEM
13
12
  remote: https://rubygems.org/
14
13
  specs:
15
- activesupport (4.2.4)
14
+ activesupport (4.2.5)
16
15
  i18n (~> 0.7)
17
16
  json (~> 1.7, >= 1.7.7)
18
17
  minitest (~> 5.1)
@@ -21,11 +20,12 @@ GEM
21
20
  claide (0.9.1)
22
21
  colored (1.2)
23
22
  diff-lcs (1.2.5)
23
+ fakefs (0.6.7)
24
24
  git (1.2.9.1)
25
25
  i18n (0.7.0)
26
26
  json (1.8.3)
27
27
  liquid (3.0.6)
28
- minitest (5.8.1)
28
+ minitest (5.8.3)
29
29
  rake (10.4.2)
30
30
  rspec (3.3.0)
31
31
  rspec-core (~> 3.3.0)
@@ -40,7 +40,6 @@ GEM
40
40
  diff-lcs (>= 1.2.0, < 2.0)
41
41
  rspec-support (~> 3.3.0)
42
42
  rspec-support (3.3.0)
43
- settingslogic (2.0.9)
44
43
  thor (0.19.1)
45
44
  thread_safe (0.3.5)
46
45
  tilt (2.0.1)
@@ -56,9 +55,10 @@ PLATFORMS
56
55
 
57
56
  DEPENDENCIES
58
57
  bundler (~> 1.10)
58
+ fakefs (~> 0.6)
59
59
  generamba!
60
60
  rake (~> 10.0)
61
- rspec
61
+ rspec (~> 3.0)
62
62
 
63
63
  BUNDLED WITH
64
- 1.10.6
64
+ 1.11.2
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ ### Overview
2
+
3
+ [![Build Status](https://travis-ci.org/rambler-ios/Generamba.svg)](https://travis-ci.org/rambler-ios/Generamba)
4
+ [![Gem Version](https://badge.fury.io/rb/generamba.svg)](https://badge.fury.io/rb/generamba)
5
+
6
+ **Generamba** is a code generator made for working with Xcode. Primarily it is designed to generate VIPER modules but it is quite easy to customize it for generation of any other classes (both in Objective-C and Swift).
7
+
8
+ ![Generamba Screenshot](http://s24.postimg.org/gej9cg1cl/generamba.jpg)
9
+
10
+ ### Key features
11
+
12
+ - Supports work with *.xcodeproj* files out of the box. All generated class files are automaticly placed on specific folders and groups of Xcode project.
13
+ - Can generate both code itself and tests adding them to right targets.
14
+ - Based on work with [liquid-templates](https://github.com/Shopify/liquid) that have plain and readable syntax in comparison with templates for Xcode.
15
+ - It is very easy to create a new module: `generamba gen [MODULE_NAME] [TEMPLATE_NAME]`. You do not need to input a bunch of data each time because each project corresponds to only one configuration file that holds standard file system and Xcode-project pathes, names of targets, information about the author.
16
+
17
+ ### Installation
18
+
19
+ > Ruby 2.2 or later version is required. To check your current Ruby version run this command in terminal:
20
+ ```bash
21
+ $ ruby --version
22
+ ```
23
+ When necessary you can install the required Ruby version with the help of [`rvm`](http://octopress.org/docs/setup/rvm/) or [`rbenv`](http://octopress.org/docs/setup/rbenv/).
24
+
25
+ Run the command `gem install generamba`.
26
+
27
+ ### Using
28
+ 1. Run [`generamba setup`](https://github.com/rambler-ios/Generamba/wiki/Available-Commands#basic-generamba-configuration) in the project root folder. This command helps to create [Rambafile](https://github.com/rambler-ios/Generamba/wiki/Rambafile-Structure) that define all configuration needed to generate code. You can modify this file directly in future.
29
+ 2. Add all templates planned to use in the project to the generated [Rambafile](https://github.com/rambler-ios/Generamba/wiki/Rambafile-Structure). You can begin with one of the templates from our catalog: `{name: 'rviper_controller'}`.
30
+ 3. Run [`generamba template install`](https://github.com/rambler-ios/Generamba/wiki/Available-Commands#template-installation). All the templates will be placed in the '/Templates' folder of your current project.
31
+ 4. Run [`generamba gen [MODULE_NAME] [TEMPLATE_NAME]`](https://github.com/rambler-ios/Generamba/wiki/Available-Commands#module-generation) - It creates module with specific name from specific template.
32
+
33
+ ### Additional info
34
+
35
+ Run `generamba help` to learn more about each of the Generamba features.
36
+
37
+ **Wiki:**
38
+ - [Command list](https://github.com/rambler-ios/Generamba/wiki/Available-Commands)
39
+ - [Understanding the Rambafile](https://github.com/rambler-ios/Generamba/wiki/Rambafile-Structure)
40
+ - [Understanding templates](https://github.com/rambler-ios/Generamba/wiki/Template-Structure)
41
+
42
+ **Other materials:**
43
+ - [Russian] Rambler.iOS V: Generamba and Code Generation ([Slides](http://www.slideshare.net/Rambler-iOS/viper-56423582) | [Video](http://www.youtube.com/watch?v=NXNiN9FaUnY))
44
+
45
+ ### Authors
46
+
47
+ - Egor Tolstoy, Beniamin Sarkisyan, Andrey Zarembo and the rest of [Rambler.iOS team](https://github.com/orgs/rambler-ios/people).
48
+
49
+ ### License
50
+
51
+ MIT
data/generamba.gemspec CHANGED
@@ -29,4 +29,5 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency 'bundler', '~> 1.10'
30
30
  spec.add_development_dependency 'rake', '~> 10.0'
31
31
  spec.add_development_dependency 'rspec', '~> 3.4'
32
+ spec.add_development_dependency 'fakefs', '~> 0.6'
32
33
  end
@@ -5,6 +5,7 @@ require 'tilt'
5
5
  require 'git'
6
6
  require 'generamba/cli/gen_command.rb'
7
7
  require 'generamba/cli/setup_command.rb'
8
+ require 'generamba/cli/version_command.rb'
8
9
  require 'generamba/cli/setup_username_command.rb'
9
10
  require 'generamba/cli/thor_extension.rb'
10
11
  require 'generamba/cli/template/template_group.rb'
@@ -1,5 +1,6 @@
1
1
  require 'thor'
2
2
  require 'generamba/helpers/rambafile_validator.rb'
3
+ require 'generamba/helpers/xcodeproj_helper.rb'
3
4
 
4
5
  module Generamba::CLI
5
6
  class Application < Thor
@@ -20,7 +21,7 @@ module Generamba::CLI
20
21
 
21
22
  does_rambafile_exist = Dir[RAMBAFILE_NAME].count > 0
22
23
 
23
- if (does_rambafile_exist == false)
24
+ unless does_rambafile_exist
24
25
  puts('Rambafile not found! Run `generamba setup` in the working directory instead!'.red)
25
26
  return
26
27
  end
@@ -39,6 +40,17 @@ module Generamba::CLI
39
40
  template = ModuleTemplate.new(template_name)
40
41
  code_module = CodeModule.new(module_name, module_description, rambafile, options)
41
42
 
43
+ project = XcodeprojHelper.obtain_project(code_module.xcodeproj_path)
44
+ module_group_already_exists = XcodeprojHelper.module_with_group_path_already_exists(project, code_module.module_group_path)
45
+
46
+ if module_group_already_exists
47
+ replace_exists_module = yes?("#{module_name} module already exists. Replace? (yes/no)")
48
+
49
+ unless replace_exists_module
50
+ return
51
+ end
52
+ end
53
+
42
54
  generator = Generamba::ModuleGenerator.new()
43
55
  generator.generate_module(module_name, code_module, template)
44
56
  end
@@ -4,7 +4,7 @@ module Generamba::CLI
4
4
  no_commands {
5
5
  def setup_username
6
6
  username = Generamba::UserPreferences.obtain_username
7
- if username == nil
7
+ unless username
8
8
  puts('The author name is not configured!'.red)
9
9
  git_username = Git.init.config['user.name']
10
10
  if git_username != nil && yes?("Your name in git is configured as #{git_username}. Do you want to use it in code headers? (yes/no)")
@@ -5,13 +5,17 @@ module Generamba::CLI
5
5
  def install
6
6
  does_rambafile_exist = Dir[RAMBAFILE_NAME].count > 0
7
7
 
8
- if (does_rambafile_exist == false)
8
+ unless does_rambafile_exist
9
9
  puts('Rambafile not found! Run `generamba setup` in the working directory instead!'.red)
10
10
  return
11
11
  end
12
12
 
13
- template_processor = Generamba::TemplateProcessor.new
14
- template_processor.install_templates
13
+ catalog_downloader = Generamba::CatalogDownloader.new
14
+ installer_factory = Generamba::TemplateInstallerFactory.new
15
+ template_processor = Generamba::TemplateProcessor.new(catalog_downloader, installer_factory)
16
+
17
+ rambafile = YAML.load_file(RAMBAFILE_NAME)
18
+ template_processor.install_templates(rambafile)
15
19
  end
16
20
  end
17
21
  end
@@ -0,0 +1,13 @@
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
+ puts(Generamba::VERSION.green)
11
+ end
12
+ end
13
+ end
@@ -14,12 +14,12 @@ module Generamba
14
14
  # @return [String] The generated body
15
15
  def self.create_file_content(file, code_module, template)
16
16
  file_template = Tilt.new(template.template_path.join(file[TEMPLATE_FILE_PATH_KEY]))
17
- file_name = File.basename(file[TEMPLATE_FILE_NAME_KEY])
17
+ file_name = File.basename(file[TEMPLATE_FILE_NAME_KEY])
18
18
  module_info = {
19
19
  'name' => code_module.name,
20
20
  'file_name' => file_name,
21
21
  'description' => code_module.description,
22
- 'project_name' => code_module.project_name
22
+ 'project_name' => code_module.project_name
23
23
  }
24
24
 
25
25
  developer = {
@@ -33,14 +33,14 @@ module Generamba
33
33
 
34
34
  path_exists = Dir.exist?(home_path)
35
35
 
36
- if path_exists == false
36
+ unless path_exists
37
37
  FileUtils.mkdir_p home_path
38
38
  end
39
39
 
40
40
  preferences_path = home_path.join(USER_PREFERENCES_FILE)
41
41
  preferences_exist = File.file?(preferences_path)
42
42
 
43
- if preferences_exist == false
43
+ unless preferences_exist
44
44
  File.open(preferences_path, 'w+') { |f| f.write('') }
45
45
  end
46
46
 
@@ -19,6 +19,7 @@ module Generamba
19
19
  PODFILE_PATH_KEY = 'podfile_path'
20
20
  CARTFILE_PATH_KEY = 'cartfile_path'
21
21
 
22
+ CATALOGS_KEY = 'catalogs'
22
23
  TEMPLATES_KEY = 'templates'
23
24
  TEMPLATE_DECLARATION_NAME_KEY = 'name'
24
25
  TEMPLATE_DECLARATION_LOCAL_KEY = 'local'
@@ -5,43 +5,100 @@ module Generamba
5
5
 
6
6
  # Method validates Rambafile contents
7
7
  # @param path [String] The path to a Rambafile
8
+ #
9
+ # @return [Void]
8
10
  def validate(path)
9
11
  file_contents = open(path).read
10
12
  preferences = file_contents.empty? ? {} : YAML.load(file_contents).to_hash
11
13
 
12
14
  mandatory_fields = [COMPANY_KEY,
13
15
  PROJECT_NAME_KEY,
14
- XCODEPROJ_PATH_KEY,
15
- PROJECT_FILE_PATH_KEY,
16
- PROJECT_GROUP_PATH_KEY,
17
- TEMPLATES_KEY]
18
-
19
- interchangable_fields = [[PROJECT_TARGETS_KEY, PROJECT_TARGET_KEY]]
16
+ XCODEPROJ_PATH_KEY]
20
17
 
21
18
  mandatory_fields.each do |field|
22
- if preferences.has_key?(field) == false
23
- error_description = "Rambafile is broken! Cannot find #{field} field, which is mandatory. Either add it manually, or run *generamba setup*.".red
24
- raise StandardError.new(error_description)
19
+ unless preferences[field]
20
+ puts "Rambafile is broken! *#{field}* field cannot be empty, because it is mandatory. Either add it manually, or run *generamba setup*.".red
21
+ exit
25
22
  end
26
23
  end
27
24
 
28
- interchangable_fields.each do |fields_array|
29
- has_value = false
30
- fields_array.each do |field|
31
- has_value = preferences.has_key?(field) || has_value
32
- end
25
+ project_failure_fields = all_project_failure_fields(preferences)
26
+ test_failure_fields = all_test_failure_fields(preferences)
27
+ failure_fields = project_failure_fields + test_failure_fields
33
28
 
34
- if has_value == false
35
- error_description = "Rambafile is broken! Cannot find any of #{fields_array} fields, one of them is mandatory. Either add it manually, or run *generamba setup*.".red
36
- raise StandardError.new(error_description)
37
- end
29
+ if failure_fields.count > 0
30
+ puts "Rambafile is broken! Cannot find any of #{failure_fields} fields, one of them is mandatory. Either add it manually, or run *generamba setup*.".red
31
+ exit
38
32
  end
39
33
 
40
- if preferences[TEMPLATES_KEY] == nil
41
- error_description = "You can't run *generamba gen* without any templates installed. Add their declarations to a Rambafile and run *generamba template install*.".red
42
- raise StandardError.new(error_description)
34
+ unless preferences[TEMPLATES_KEY]
35
+ puts "You can't run *generamba gen* without any templates installed. Add their declarations to a Rambafile and run *generamba template install*.".red
36
+ exit
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ # Method which return all project failure fields
43
+ # @param preferences [Hash] Converted Rambafile
44
+ #
45
+ # @return [Array]
46
+ def all_project_failure_fields(preferences)
47
+ return all_nil_mandatory_fields_for_target_type("project", preferences)
48
+ end
49
+
50
+ # Method which return all test failure fields
51
+ # @param preferences [Hash] Converted Rambafile
52
+ #
53
+ # @return [Array]
54
+ def all_test_failure_fields(preferences)
55
+ target = preferences[TEST_TARGET_KEY]
56
+ targets = preferences[TEST_TARGETS_KEY]
57
+ file_path = preferences[TEST_FILE_PATH_KEY]
58
+ group_path = preferences[TEST_GROUP_PATH_KEY]
59
+
60
+ has_test_fields = target || targets || file_path || group_path
61
+
62
+ unless has_test_fields
63
+ return []
64
+ end
65
+
66
+ return all_nil_mandatory_fields_for_target_type("test", preferences)
67
+ end
68
+
69
+ # Method which return all failure fields for target_type
70
+ # @param target_type [String] "project" or "test"
71
+ # @param preferences [Hash] Converted Rambafile
72
+ #
73
+ # @return [Array]
74
+ def all_nil_mandatory_fields_for_target_type(target_type, preferences)
75
+ target_type = target_type.upcase
76
+
77
+ target_const_value = Generamba.const_get(target_type + "_TARGET_KEY")
78
+ targets_const_value = Generamba.const_get(target_type + "_TARGETS_KEY")
79
+
80
+ target = preferences[target_const_value]
81
+ targets = preferences[targets_const_value]
82
+
83
+ fields = []
84
+
85
+ if !target && (!targets || (targets && targets.count == 0))
86
+ fields.push(target_const_value)
87
+ end
88
+
89
+ file_path_const_value = Generamba.const_get(target_type + "_FILE_PATH_KEY")
90
+
91
+ unless preferences[file_path_const_value]
92
+ fields.push(file_path_const_value)
93
+ end
94
+
95
+ group_path_const_value = Generamba.const_get(target_type + "_GROUP_PATH_KEY")
96
+
97
+ unless preferences[group_path_const_value]
98
+ fields.push(group_path_const_value)
43
99
  end
44
100
 
101
+ return fields
45
102
  end
46
103
 
47
104
  end
@@ -24,7 +24,7 @@ module Generamba
24
24
  .join(template_name)
25
25
 
26
26
  error_description = "Cannot find template named #{template_name}! Add it to the Rambafile and run *generamba template install*".red
27
- raise StandardError.new(error_description) if path.exist? == false
27
+ raise StandardError.new(error_description) unless path.exist?
28
28
 
29
29
  return path
30
30
  end
@@ -13,50 +13,81 @@ module Generamba
13
13
 
14
14
  # Adds a provided file to a specific Project and Target
15
15
  # @param project [Xcodeproj::Project] The target xcodeproj file
16
- # @param targets [AbstractTarget] Array of tatgets
16
+ # @param targets_name [String] Array of targets name
17
17
  # @param group_path [Pathname] The Xcode group path for current file
18
18
  # @param file_path [Pathname] The file path for current file
19
19
  #
20
20
  # @return [void]
21
- def self.add_file_to_project_and_targets(project, targets, group_path, file_path)
22
- module_group = self.retreive_or_create_group(group_path, project)
21
+ def self.add_file_to_project_and_targets(project, targets_name, group_path, file_path)
22
+ module_group = self.retreive_group_or_create_if_needed(group_path, project, true)
23
23
  xcode_file = module_group.new_file(File.absolute_path(file_path))
24
24
 
25
25
  file_name = File.basename(file_path)
26
- if File.extname(file_name) == '.m'
27
- targets.each do |target|
28
- xcode_target = self.obtain_target(target, project)
29
- xcode_target.add_file_references([xcode_file])
30
- end
31
- end
26
+ targets_name.each do |target|
27
+ xcode_target = self.obtain_target(target, project)
28
+ xcode_target.add_file_references([xcode_file])
29
+ end if self.add_file_to_target?(file_name)
30
+ end
31
+
32
+ # Decides should file be added
33
+ # @param file_name [String] Array of targets name
34
+ #
35
+ # @return [TrueClass or FalseClass]
36
+ def self.add_file_to_target?(file_name)
37
+ File.extname(file_name) == '.m' || File.extname(file_name) == '.swift' || File.extname(file_name) == '.mm'
32
38
  end
33
39
 
34
- # Recursively clears children of te given group
40
+ # Recursively clears children of the given group
35
41
  # @param project [Xcodeproj::Project] The working Xcode project file
36
42
  # @param group_path [Pathname] The full group path
37
43
  #
38
44
  # @return [Void]
39
- def self.clear_group(project, group_path)
40
- module_group = self.retreive_or_create_group(group_path, project)
45
+ def self.clear_group(project, targets_name, group_path)
46
+ module_group = self.retreive_group_or_create_if_needed(group_path, project, false)
47
+ return unless module_group
48
+
49
+ files_path = self.files_path_from_group(module_group, project)
50
+ return unless files_path
51
+
52
+ files_path.each do |file_path|
53
+ self.remove_file_by_file_path(file_path, targets_name, project)
54
+ end
55
+
41
56
  module_group.clear
42
57
  end
43
58
 
59
+ # Finds a group in a xcodeproj file with a given path
60
+ # @param project [Xcodeproj::Project] The working Xcode project file
61
+ # @param group_path [Pathname] The full group path
62
+ #
63
+ # @return [TrueClass or FalseClass]
64
+ def self.module_with_group_path_already_exists(project, group_path)
65
+ module_group = self.retreive_group_or_create_if_needed(group_path, project, false)
66
+ return module_group == nil ? false : true
67
+ end
68
+
44
69
  private
45
70
 
46
71
  # Finds or creates a group in a xcodeproj file with a given path
47
72
  # @param group_path [Pathname] The full group path
48
73
  # @param project [Xcodeproj::Project] The working Xcode project file
74
+ # @param create_group_if_not_exists [TrueClass or FalseClass] If true notexistent group will be created
49
75
  #
50
76
  # @return [PBXGroup]
51
- def self.retreive_or_create_group(group_path, project)
77
+ def self.retreive_group_or_create_if_needed(group_path, project, create_group_if_not_exists)
52
78
  group_names = group_names_from_group_path(group_path)
53
79
 
54
80
  final_group = project
55
81
 
56
82
  group_names.each do |group_name|
57
83
  next_group = final_group[group_name]
58
- if (next_group == nil)
59
- next_group = final_group.new_group(group_name)
84
+ unless next_group
85
+ unless create_group_if_not_exists
86
+ return nil
87
+ end
88
+
89
+ new_group_path = group_name
90
+ next_group = final_group.new_group(group_name, new_group_path)
60
91
  end
61
92
 
62
93
  final_group = next_group
@@ -89,5 +120,77 @@ module Generamba
89
120
  groups = group_path.to_s.split('/')
90
121
  return groups
91
122
  end
123
+
124
+ # Remove build file from target build phase
125
+ # @param file_path [String] The path of the file
126
+ # @param targets_name [String] Array of targets
127
+ # @param project [Xcodeproj::Project] The target xcodeproj file
128
+ #
129
+ # @return [Void]
130
+ def self.remove_file_by_file_path(file_path, targets_name, project)
131
+ build_phases = self.build_phases_from_targets(targets_name, project)
132
+
133
+ build_phases.each do |build_phase|
134
+ build_phase.files.each do |build_file|
135
+ next if build_file.nil? || build_file.file_ref.nil?
136
+
137
+ build_file_path = self.configure_file_ref_path(build_file.file_ref)
138
+
139
+ if build_file_path == file_path
140
+ build_phase.remove_build_file(build_file)
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ # Find and return target build phases
147
+ # @param targets_name [String] Array of targets
148
+ # @param project [Xcodeproj::Project] The target xcodeproj file
149
+ #
150
+ # @return [[PBXSourcesBuildPhase]]
151
+ def self.build_phases_from_targets(targets_name, project)
152
+ build_phases = []
153
+
154
+ targets_name.each do |target_name|
155
+ xcode_target = self.obtain_target(target_name, project)
156
+ xcode_target.build_phases.each do |build_phase|
157
+ if build_phase.isa == 'PBXSourcesBuildPhase'
158
+ build_phases.push(build_phase)
159
+ end
160
+ end
161
+ end
162
+
163
+ return build_phases
164
+ end
165
+
166
+ # Get configure file full path
167
+ # @param file_ref [PBXFileReference] Build file
168
+ #
169
+ # @return [String]
170
+ def self.configure_file_ref_path(file_ref)
171
+ build_file_ref_path = file_ref.hierarchy_path.to_s
172
+ build_file_ref_path[0] = ''
173
+
174
+ return build_file_ref_path
175
+ end
176
+
177
+ # Get all files path from group path
178
+ # @param module_group [PBXGroup] The module group
179
+ # @param project [Xcodeproj::Project] The target xcodeproj file
180
+ #
181
+ # @return [[String]]
182
+ def self.files_path_from_group(module_group, project)
183
+ files_path = []
184
+
185
+ module_group.recursive_children.each do |file_ref|
186
+ if file_ref.isa == 'PBXFileReference'
187
+ file_ref_path = self.configure_file_ref_path(file_ref)
188
+ files_path.push(file_ref_path)
189
+ end
190
+ end
191
+
192
+ return files_path
193
+ end
194
+
92
195
  end
93
196
  end
@@ -21,33 +21,41 @@ module Generamba
21
21
  # Creating code files
22
22
  puts('Creating code files...')
23
23
  process_files_if_needed(template.code_files,
24
- name,
25
- code_module,
26
- template,
27
- project,
28
- code_module.project_targets,
29
- code_module.module_group_path,
30
- code_module.module_file_path)
24
+ name,
25
+ code_module,
26
+ template,
27
+ project,
28
+ code_module.project_targets,
29
+ code_module.module_group_path,
30
+ code_module.module_file_path)
31
31
 
32
32
  # Creating test files
33
- puts('Creating test files...')
34
- process_files_if_needed(template.test_files,
35
- name,
36
- code_module,
37
- template,
38
- project,
39
- code_module.test_targets,
40
- code_module.test_group_path,
41
- code_module.test_file_path)
33
+ included_tests = code_module.test_targets && code_module.test_group_path && code_module.test_file_path
34
+
35
+ if included_tests
36
+ puts('Creating test files...')
37
+ process_files_if_needed(template.test_files,
38
+ name,
39
+ code_module,
40
+ template,
41
+ project,
42
+ code_module.test_targets,
43
+ code_module.test_group_path,
44
+ code_module.test_file_path)
45
+ end
42
46
 
43
47
  # Saving the current changes in the Xcode project
44
48
  project.save
49
+
50
+ test_file_path_created_message = !code_module.test_file_path ? "" : "Test file path: #{code_module.test_file_path}".green + "\n"
51
+ test_group_path_created_message = !code_module.test_group_path ? "" : "Test group path: #{code_module.test_group_path}".green
52
+
45
53
  puts("Module successfully created!\n" +
46
- "Name: #{name}".green + "\n" +
47
- "Module file path: #{code_module.module_file_path}".green + "\n" +
48
- "Module group path: #{code_module.module_group_path}".green + "\n" +
49
- "Test file path: #{code_module.test_file_path}".green + "\n" +
50
- "Test group path: #{code_module.test_group_path}".green)
54
+ "Name: #{name}".green + "\n" +
55
+ "Module file path: #{code_module.module_file_path}".green + "\n" +
56
+ "Module group path: #{code_module.module_group_path}".green + "\n" +
57
+ test_file_path_created_message +
58
+ test_group_path_created_message)
51
59
  end
52
60
 
53
61
  def process_files_if_needed(files, name, code_module, template, project, targets, group_path, dir_path)
@@ -57,7 +65,7 @@ module Generamba
57
65
  return
58
66
  end
59
67
 
60
- XcodeprojHelper.clear_group(project, group_path)
68
+ XcodeprojHelper.clear_group(project, targets, group_path)
61
69
  files.each do |file|
62
70
  # The target file's name consists of three parameters: project prefix, module name and template file name.
63
71
  # E.g. RDS + Authorization + Presenter.h = RDSAuthorizationPresenter.h
@@ -68,12 +76,9 @@ module Generamba
68
76
  file_group = File.dirname(file[TEMPLATE_NAME_KEY])
69
77
 
70
78
  # Generating the content of the code file
71
- file_content = ContentGenerator.create_file_content(file,
72
- code_module,
73
- template)
74
- file_path = dir_path
75
- .join(file_group)
76
- .join(file_name)
79
+ file_content = ContentGenerator.create_file_content(file, code_module, template)
80
+ file_path = dir_path.join(file_group)
81
+ .join(file_name)
77
82
 
78
83
  # Creating the file in the filesystem
79
84
  FileUtils.mkdir_p File.dirname(file_path)
@@ -82,10 +87,7 @@ module Generamba
82
87
  end
83
88
 
84
89
  # Creating the file in the Xcode project
85
- XcodeprojHelper.add_file_to_project_and_targets(project,
86
- targets,
87
- group_path.join(file_group),
88
- file_path)
90
+ XcodeprojHelper.add_file_to_project_and_targets(project, targets, group_path.join(file_group), file_path)
89
91
  end
90
92
  end
91
93
  end
@@ -12,16 +12,15 @@ module Generamba
12
12
  #
13
13
  # @return [Pathname] A filepath to the downloaded catalog
14
14
  def download_catalog(name, url)
15
- catalog_local_path = Pathname.new(ENV['HOME'])
15
+ catalogs_local_path = Pathname.new(ENV['HOME'])
16
16
  .join(GENERAMBA_HOME_DIR)
17
17
  .join(CATALOGS_DIR)
18
- FileUtils.rm_rf catalog_local_path
19
- FileUtils.mkdir_p catalog_local_path
18
+ current_catalog_path = catalogs_local_path
19
+ .join(name)
20
20
 
21
- Git.clone(url, name, :path => catalog_local_path)
21
+ Git.clone(url, name, :path => catalogs_local_path)
22
22
 
23
- return catalog_local_path
24
- .join(name)
23
+ return current_catalog_path
25
24
  end
26
25
  end
27
26
  end
@@ -12,29 +12,62 @@ module Generamba
12
12
  puts("Installing #{template_name}...")
13
13
 
14
14
  template_name = template_declaration.name
15
- catalog_path = Pathname.new(ENV['HOME'])
15
+ catalogs_path = Pathname.new(ENV['HOME'])
16
16
  .join(GENERAMBA_HOME_DIR)
17
17
  .join(CATALOGS_DIR)
18
- .join(GENERAMBA_CATALOG_NAME)
19
- template_path = catalog_path.join(template_name)
20
18
 
21
- rambaspec_exist = Generamba::RambaspecValidator.validate_spec_existance(template_name, template_path)
19
+ catalog_path = catalogs_path.children.select { |child|
20
+ child.directory? && child.split.last.to_s[0] != '.'
21
+ }.select { |catalog_path|
22
+ template_path = browse_catalog_for_a_template(catalog_path, template_name)
23
+ template_path != nil
24
+ }.first
22
25
 
23
- if rambaspec_exist == false
24
- error_description = "Cannot find #{template_name + RAMBASPEC_EXTENSION} in the template catalog. Try another name.".red
25
- raise StandardError.new(error_description)
26
+ if catalog_path == nil
27
+ error_description = "Cannot find #{template_name} in any catalog. Try another name.".red
28
+ puts(error_description)
29
+ return
30
+ end
31
+
32
+ template_path = catalog_path.join(template_name)
33
+ rambaspec_exist = Generamba::RambaspecValidator.validate_spec_existance(template_name, template_path)
34
+ unless rambaspec_exist
35
+ error_description = "Cannot find #{template_name + RAMBASPEC_EXTENSION} in the template catalog #{catalog_path}. Try another name.".red
36
+ puts(error_description)
37
+ return
26
38
  end
27
39
 
28
40
  rambaspec_valid = Generamba::RambaspecValidator.validate_spec(template_name, template_path)
29
- if rambaspec_valid == false
41
+ unless rambaspec_valid
30
42
  error_description = "#{template_name + RAMBASPEC_EXTENSION} is not valid.".red
31
- raise StandardError.new(error_description)
43
+ puts(error_description)
44
+ return
32
45
  end
33
46
 
34
47
  install_path = Pathname.new(TEMPLATES_FOLDER)
35
48
  .join(template_name)
36
49
  FileUtils.mkdir_p install_path
37
- FileUtils.copy_entry(template_path, install_path)
50
+
51
+ src = template_path.to_s + '/.'
52
+ FileUtils.cp_r(src, install_path)
53
+ end
54
+
55
+ private
56
+
57
+ # Browses a given catalog and returns a template path
58
+ #
59
+ # @param catalog_path [Pathname] A path to a catalog
60
+ # @param template_name [String] A name of the template
61
+ #
62
+ # @return [Pathname] A path to a template, if found
63
+ def browse_catalog_for_a_template(catalog_path, template_name)
64
+ template_path = catalog_path.join(template_name)
65
+
66
+ if Dir.exist?(template_path)
67
+ return template_path
68
+ end
69
+
70
+ return nil
38
71
  end
39
72
  end
40
73
  end
@@ -12,13 +12,13 @@ module Generamba
12
12
  local_path = template_declaration.local
13
13
  rambaspec_exist = Generamba::RambaspecValidator.validate_spec_existance(template_name, local_path)
14
14
 
15
- if rambaspec_exist == false
15
+ unless rambaspec_exist
16
16
  error_description = "Cannot find #{template_name + RAMBASPEC_EXTENSION} in the specified directory. Try another path or name.".red
17
17
  raise StandardError.new(error_description)
18
18
  end
19
19
 
20
20
  rambaspec_valid = Generamba::RambaspecValidator.validate_spec(template_name, local_path)
21
- if rambaspec_valid == false
21
+ unless rambaspec_valid
22
22
  error_description = "#{template_name + RAMBASPEC_EXTENSION} is not valid.".red
23
23
  raise StandardError.new(error_description)
24
24
  end
@@ -20,14 +20,14 @@ module Generamba
20
20
  Git.clone(repo_url, template_name, :path => temp_path)
21
21
 
22
22
  rambaspec_exist = Generamba::RambaspecValidator.validate_spec_existance(template_name, template_dir)
23
- if rambaspec_exist == false
23
+ unless rambaspec_exist
24
24
  FileUtils.rm_rf(temp_path)
25
25
  error_description = "Cannot find #{template_name + RAMBASPEC_EXTENSION} in the root directory of specified repository.".red
26
26
  raise StandardError.new(error_description)
27
27
  end
28
28
 
29
29
  rambaspec_valid = Generamba::RambaspecValidator.validate_spec(template_name, template_dir)
30
- if rambaspec_valid == false
30
+ unless rambaspec_valid
31
31
  error_description = "#{template_name + RAMBASPEC_EXTENSION} is not valid.".red
32
32
  raise StandardError.new(error_description)
33
33
  end
@@ -0,0 +1,22 @@
1
+ require 'generamba/template/processor/template_declaration'
2
+
3
+ module Generamba
4
+
5
+ # Factory that creates a proper installer for a given template type
6
+ class TemplateInstallerFactory
7
+
8
+ # Provides the appropriate strategy for a given template type
9
+ def installer_for_type(type)
10
+ case type
11
+ when TemplateDeclarationType::LOCAL_TEMPLATE
12
+ return Generamba::LocalInstaller.new
13
+ when TemplateDeclarationType::REMOTE_TEMPLATE
14
+ return Generamba::RemoteInstaller.new
15
+ when TemplateDeclarationType::CATALOG_TEMPLATE
16
+ return Generamba::CatalogInstaller.new
17
+ else
18
+ return nil
19
+ end
20
+ end
21
+ end
22
+ end
@@ -14,6 +14,7 @@ module Generamba
14
14
 
15
15
  # Describes a Generamba template declaration model
16
16
  class TemplateDeclaration
17
+
17
18
  attr_reader :name, :local, :git, :type
18
19
 
19
20
  def initialize(template_hash)
@@ -10,28 +10,34 @@ module Generamba
10
10
  # Incapsulates logic of processing templates declaration section from Rambafile
11
11
  class TemplateProcessor
12
12
 
13
+ def initialize(catalog_downloader, installer_factory)
14
+ @catalog_downloader = catalog_downloader
15
+ @installer_factory = installer_factory
16
+ end
17
+
13
18
  # This method parses Rambafile, serializes templates hashes into model objects and install them
14
- def install_templates
19
+ def install_templates(rambafile)
15
20
  # We always clear previously installed templates to avoid conflicts in different versions
16
21
  clear_installed_templates
17
22
 
18
- rambafile = YAML.load_file(RAMBAFILE_NAME)
23
+ templates = rambafile[TEMPLATES_KEY]
24
+
25
+ if !templates || templates.count == 0
26
+ puts 'You must specify at least one template in Rambafile under the key *templates*'.red
27
+ return
28
+ end
19
29
 
20
30
  # Mapping hashes to model objects
21
31
  templates = rambafile[TEMPLATES_KEY].map { |template_hash|
22
- template_declaration = Generamba::TemplateDeclaration.new(template_hash)
32
+ Generamba::TemplateDeclaration.new(template_hash)
23
33
  }
24
34
 
25
- if !templates || templates.count == 0
26
- error_description = 'You must specify at least one template in Rambafile under the key *project_templates*'.red
27
- raise StandardError.new(error_description)
28
- end
29
-
30
- # If there is at least one template from the shared catalog, we should update our local copy of the catalog
31
- update_shared_catalog_if_needed(templates)
35
+ catalogs = rambafile[CATALOGS_KEY]
36
+ # If there is at least one template from catalogs, we should update our local copy of the catalog
37
+ update_catalogs_if_needed(catalogs, templates)
32
38
 
33
39
  templates.each do |template_declaration|
34
- strategy = strategy_for_type(template_declaration.type)
40
+ strategy = @installer_factory.installer_for_type(template_declaration.type)
35
41
  template_declaration.install(strategy)
36
42
  end
37
43
  end
@@ -44,30 +50,38 @@ module Generamba
44
50
  FileUtils.rm_rf(Dir.glob(install_path))
45
51
  end
46
52
 
47
- # Clones remote template catalog to the local directory
48
- def update_shared_catalog_if_needed(templates)
53
+ # Clones remote template catalogs to the local directory
54
+ def update_catalogs_if_needed(catalogs, templates)
49
55
  needs_update = templates.any? {|template| template.type == TemplateDeclarationType::CATALOG_TEMPLATE}
50
56
 
51
57
  return unless needs_update
52
58
 
59
+ remove_all_catalogs
53
60
  puts('Updating shared generamba-catalog specs...')
61
+ @catalog_downloader.download_catalog(GENERAMBA_CATALOG_NAME, RAMBLER_CATALOG_REPO)
62
+
63
+ return unless catalogs != nil && catalogs.count > 0
54
64
 
55
- downloader = CatalogDownloader.new
56
- downloader.download_catalog(GENERAMBA_CATALOG_NAME, RAMBLER_CATALOG_REPO)
65
+ catalogs.each do |catalog_url|
66
+ catalog_name = catalog_url.split('://').last
67
+ catalog_name = catalog_name.gsub('/', '-');
68
+ puts("Updating #{catalog_name} specs...")
69
+ @catalog_downloader.download_catalog(catalog_name, catalog_url)
70
+ end
57
71
  end
58
72
 
59
- # Provides the appropriate strategy for a given template type
60
- def strategy_for_type(type)
61
- case type
62
- when TemplateDeclarationType::LOCAL_TEMPLATE
63
- return Generamba::LocalInstaller.new
64
- when TemplateDeclarationType::REMOTE_TEMPLATE
65
- return Generamba::RemoteInstaller.new
66
- when TemplateDeclarationType::CATALOG_TEMPLATE
67
- return Generamba::CatalogInstaller.new
68
- else
69
- return nil
73
+ def remove_all_catalogs
74
+ catalogs_path = Pathname.new(ENV['HOME'])
75
+ .join(GENERAMBA_HOME_DIR)
76
+ .join(CATALOGS_DIR)
77
+ if Dir.exist?(catalogs_path) == false
78
+ FileUtils.mkdir_p catalogs_path
70
79
  end
80
+ catalogs_path.children.select { |child|
81
+ child.directory? && child.split.last.to_s[0] != '.'
82
+ }.each { |catalog_path|
83
+ FileUtils.rm_rf(catalog_path)
84
+ }
71
85
  end
72
86
  end
73
87
  end
@@ -1,3 +1,3 @@
1
1
  module Generamba
2
- VERSION = '0.7.1'
2
+ VERSION = '0.7.2'
3
3
  end
data/lib/generamba.rb CHANGED
@@ -11,6 +11,7 @@ module Generamba
11
11
  require 'generamba/code_generation/rambafile_generator.rb'
12
12
  require 'generamba/module_generator.rb'
13
13
  require 'generamba/template/processor/template_processor.rb'
14
+ require 'generamba/template/installer/template_installer_factory'
14
15
  require 'generamba/configuration/user_preferences.rb'
15
16
  require 'generamba/template/creator/template_creator.rb'
16
17
  require 'generamba/tools/string-colorize.rb'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: generamba
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Egor Tolstoy
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-12-20 00:00:00.000000000 Z
12
+ date: 2016-01-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -123,6 +123,20 @@ dependencies:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
125
  version: '3.4'
126
+ - !ruby/object:Gem::Dependency
127
+ name: fakefs
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '0.6'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.6'
126
140
  description: Generamba is a powerful and easy-to-use Xcode code generator. It provides
127
141
  a project-based configuration, flexible templates system, the ability to generate
128
142
  code and tests simultaneously.
@@ -132,13 +146,14 @@ executables:
132
146
  extensions: []
133
147
  extra_rdoc_files: []
134
148
  files:
149
+ - ".gitignore"
135
150
  - ".rspec"
136
151
  - ".travis.yml"
137
152
  - Gemfile
138
153
  - Gemfile.lock
139
154
  - LICENSE.txt
155
+ - README.md
140
156
  - Rakefile
141
- - Readme.md
142
157
  - bin/console
143
158
  - bin/generamba
144
159
  - bin/setup
@@ -154,6 +169,7 @@ files:
154
169
  - lib/generamba/cli/template/template_list_command.rb
155
170
  - lib/generamba/cli/template/template_search_command.rb
156
171
  - lib/generamba/cli/thor_extension.rb
172
+ - lib/generamba/cli/version_command.rb
157
173
  - lib/generamba/code_generation/Rambafile.liquid
158
174
  - lib/generamba/code_generation/code_module.rb
159
175
  - lib/generamba/code_generation/content_generator.rb
@@ -179,6 +195,7 @@ files:
179
195
  - lib/generamba/template/installer/catalog_installer.rb
180
196
  - lib/generamba/template/installer/local_installer.rb
181
197
  - lib/generamba/template/installer/remote_installer.rb
198
+ - lib/generamba/template/installer/template_installer_factory.rb
182
199
  - lib/generamba/template/processor/template_declaration.rb
183
200
  - lib/generamba/template/processor/template_processor.rb
184
201
  - lib/generamba/tools/string-colorize.rb
data/Readme.md DELETED
@@ -1,51 +0,0 @@
1
- ### Overview
2
-
3
- **Generamba** - это генератор кода, заточенный под работу с Xcode. В первую очередь предназначен для генерации модулей VIPER - но достаточно легко настраивается и для генерации любых других классов.
4
-
5
- ### Основные особенности
6
-
7
- - Из коробки поддерживает работу с *.xcodeproj* файлами - все сгенерированные классы автоматически распределяются как по файловой структуре, так и по группам в проекте.
8
- - Умеет генерировать как непосредственно код, так и тесты, автоматически распределяя их по правильным таргетам.
9
- - Основан на работе с [liquid-шаблонами](https://github.com/Shopify/liquid) - синтаксис простой и понятный, особенно в сравнении с шаблонами для Xcode.
10
- - Создать новый модуль очень просто: `generamba gen MyModule`. Не требуется каждый раз вводить кучу данных - каждому проекту соответствует один конфигурационный файл, содержащий в себе стандартные пути в файловой системе и Xcode-проекте, названия таргетов, информацию об авторе.
11
-
12
-
13
- ### Установка
14
- Проект пока что находится в стадии beta-версии, поэтому не добавлен в общий каталог ruby-gem'ов. Локальная установка осуществляется следующим образом:
15
-
16
- 1. Склонируйте репозиторий себе на компьютер
17
- 2. В консоли перейдите в директорию проекта
18
- 3. Вызовите команду `gem install generamba`
19
-
20
- ### Использование
21
- В настоящий момент Generamba поддерживает две команды:
22
-
23
- 1. `generamba setup` - вызывается в корневой директории проекта. Помогает автоматически создать и настроить *Rambafile*, описывающий всю конфигурацию, необходимую для генерации кода. В дальнейшем этот файл может быть модифицирован вручную.
24
- 2. `generamba gen MODULE_NAME` - генерирует модуль с указанным названием. В качестве стандартного используется шаблон *viper_module*. Команда поддерживает несколбко дополнительных опций - узнать о них больше поможет команда `generamba help gen`.
25
-
26
- В текущей версии нет возможности создавать локальные шаблоны и использовать их для генерации. Пока что используем следующий workaround:
27
-
28
- 1. `open ~/.rvm/gems/ruby-2.1.6/gems`
29
- 2. Находим директорию *Generamba-x.x.x*
30
- 3. Переходим в *lib/generamba/default_templates/*
31
- 4. Создаем папку с названием нового модуля. В остальном модуль создается по образцу стандартного.
32
-
33
- Оптимизация добавления шаблонов является главным приоритетом на данный момент.
34
-
35
- ### Авторы
36
-
37
- - Егор Толстой
38
- - Андрей Зарембо-Годзяцкий
39
-
40
- ### Лицензия
41
-
42
- MIT
43
-
44
- ### TODO
45
-
46
- - Дать возможность использовать локальный шаблон, указав полный путь до него
47
- - В Rambafile держать информацию обо всех используемых в проекте шаблонах
48
- - Вынести из Rambafile информацию, специфичную для текущего автора (имя)
49
- - Добавить для каждого шаблона возможность модифицировать Podfile проекта
50
- - Добавить GUI
51
- - Добавить возможность генерирования тестов по указанным интерфейсным файлам