gena 0.0.7 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,90 @@
1
+
2
+
3
+ module Gena
4
+
5
+ class Config
6
+
7
+ @data = {}
8
+
9
+ def Config.exists?
10
+ File.exists?('gena.plist')
11
+ end
12
+
13
+ def Config.create
14
+ hash = Hash.new
15
+ hash[:plugins_url] = [
16
+ '~/Development/gena-plugins'
17
+ ]
18
+ hash['sources_dir'] = '/Users/alex/Development/fisho-ios/Sources'
19
+
20
+ File.open('gena.plist', 'w') { |f| f.write hash.to_plist }
21
+ end
22
+
23
+ def save!
24
+ File.open('gena.plist', 'w') { |f| f.write self.data.to_plist }
25
+ end
26
+
27
+ def load_plist_config
28
+ @data = Plist::parse_xml('gena.plist')
29
+ end
30
+
31
+ def data
32
+ @data
33
+ end
34
+
35
+ def data=(new_data)
36
+ @data = new_data
37
+ end
38
+
39
+ def data_without_plugins
40
+ @data.reject { |k, v| k == GENA_PLUGINS_CONFIG_KEY }
41
+ end
42
+
43
+ def header_dir
44
+ if @data['header'] && !@data['header'].empty?
45
+ expand_to_project(File.dirname(@data['header']))
46
+ else
47
+ ''
48
+ end
49
+ end
50
+
51
+ def project_dir
52
+ File.expand_path((!self.data['project_dir'] || self.data['project_dir'].empty?)? '.' : self.data['project_dir'])
53
+ end
54
+
55
+ def expand_to_project(path)
56
+ if path[0] == '/'
57
+ path
58
+ else
59
+ File.join(self.project_dir, path)
60
+ end
61
+ end
62
+
63
+ def collapse_to_project(path)
64
+ if path[0] == '/'
65
+ path = path.dup
66
+ path["#{$config.project_dir}/"] = ''
67
+ end
68
+ path
69
+ end
70
+
71
+ def sources_dir
72
+ self.expand_to_project(self.data['sources_dir'])
73
+ end
74
+
75
+ def tests_dir
76
+ self.expand_to_project(self.data['tests_dir'])
77
+ end
78
+
79
+ def xcode_project_path
80
+ path = self.expand_to_project("#{@data['project_name']}.xcodeproj")
81
+ unless File.exists? path
82
+ say "Can't find project with name '#{@data['project_name']}.xcodeproj''", Color::RED
83
+ abort
84
+ end
85
+ path
86
+ end
87
+
88
+ end
89
+
90
+ end
data/lib/constants.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Gena
2
+ GENA_HOME = '~/.gena'
3
+ GENA_UPDATE_CHECK_INTERVAL = 10800
4
+ GENA_PLUGINS_CONFIG_KEY = 'configs'
5
+ VERSION = '0.1.0'
6
+ RELEASE_DATE = '2017-10-04'
7
+ end
data/lib/gena.rb CHANGED
@@ -1,10 +1,29 @@
1
1
  require 'optparse'
2
2
  require 'yaml'
3
- require 'generamba'
3
+
4
+ require 'thor'
5
+ require 'liquid'
6
+ require 'fileutils'
7
+ require 'xcodeproj'
8
+
9
+ require 'plist'
10
+ require 'digest'
11
+ require 'json'
12
+
13
+
14
+ require_relative 'constants'
15
+ require_relative 'utils/utils'
16
+ require_relative 'utils/xcode_utils'
17
+
18
+
19
+ require_relative 'plugin/plugin'
20
+ require_relative 'cli/cli'
21
+ require_relative 'cli/init'
22
+
23
+ require_relative 'codegen/codegen'
24
+
25
+ require_relative 'config/config'
26
+
27
+
4
28
 
5
29
 
6
- require_relative 'config'
7
- require_relative 'base_template'
8
- require_relative 'ramba_adapter'
9
- require_relative 'string_utils'
10
- require_relative 'generate_cli'
@@ -0,0 +1,58 @@
1
+ require 'thor'
2
+
3
+ ## Base class for all plugins
4
+
5
+ module Gena
6
+
7
+ class Plugin < Thor
8
+
9
+ @gena_config
10
+ @config
11
+
12
+ def self.setup_thor_commands
13
+ app_klass = Gena::Application
14
+ app_klass.commands.merge!(self.commands)
15
+ self.commands.each do |key, value|
16
+ hash = app_klass.class_for_command
17
+ hash[key] = self
18
+ app_klass.class_for_command = hash
19
+ end
20
+ end
21
+
22
+ def self.descendants
23
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
24
+ end
25
+
26
+ no_tasks do
27
+
28
+ def config
29
+ config = $config.data
30
+ config.reject { |k, v| k == GENA_PLUGINS_CONFIG_KEY }
31
+ end
32
+
33
+ def plugin_config
34
+ # puts "Class: #{self.class.plugin_config_name}"
35
+ $config.data[GENA_PLUGINS_CONFIG_KEY][self.class.plugin_config_name]
36
+ end
37
+
38
+ def sources_path
39
+ $config.sources_dir
40
+ end
41
+
42
+ def tests_path
43
+ $config.tests_dir
44
+ end
45
+
46
+ def self.plugin_config_name
47
+ self.name.split("::").last.underscore
48
+ end
49
+
50
+ def self.plugin_config_defaults
51
+ Hash.new
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,77 @@
1
+
2
+
3
+ def gena_system(*args)
4
+ if $verbose
5
+ system *args
6
+ else
7
+ system *args, :out => ['/dev/null', 'a'], :err => ['/dev/null', 'a']
8
+ end
9
+ end
10
+
11
+ class String
12
+ def include_one_of?(*array)
13
+ array.flatten.each do |str|
14
+ return true if self.include?(str)
15
+ end
16
+ false
17
+ end
18
+ def capitalize_first
19
+ self.slice(0,1).capitalize + self.slice(1..-1)
20
+ end
21
+ def capitalize_first!
22
+ self.replace(self.capitalize_first)
23
+ end
24
+ def lowercase_first
25
+ str = to_s
26
+ str[0,1].downcase + str[1..-1]
27
+ end
28
+ def underscore
29
+ self.gsub(/::/, '/').
30
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
31
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
32
+ tr("-", "_").
33
+ downcase
34
+ end
35
+ def path_intersection(other)
36
+ component_start = 0
37
+ (0..[other.size, self.size].min).each { |i|
38
+
39
+ if self[i] == '/'
40
+ component_start = i
41
+ end
42
+
43
+ if self[i] != other[i]
44
+ if i > 0
45
+ return self[0..component_start]
46
+ else
47
+ return ''
48
+ end
49
+ end
50
+ }
51
+ self
52
+ end
53
+
54
+ def delete_last_path_component
55
+ self.split(File::SEPARATOR)[0..-2].join(File::SEPARATOR)
56
+ end
57
+ end
58
+
59
+ def common_path(paths)
60
+ common = ''
61
+ paths.each do |file|
62
+ path_components = file.to_s
63
+ if common.empty?
64
+ common = path_components
65
+ else
66
+ common = common.path_intersection path_components
67
+ end
68
+ end
69
+
70
+ if File.file? common
71
+ common = common.delete_last_path_component
72
+ end
73
+ if common[-1] == '/'
74
+ common = common[0..-2]
75
+ end
76
+ common
77
+ end
@@ -0,0 +1,122 @@
1
+ module Gena
2
+
3
+ $xcode_project = nil
4
+
5
+ class XcodeUtils < Thor
6
+
7
+ no_tasks do
8
+
9
+ def self.shared
10
+ unless $utils
11
+ $utils = XcodeUtils.new
12
+ end
13
+ $utils
14
+ end
15
+
16
+ def load_project_if_needed
17
+ unless $xcode_project
18
+ say "Loading project: #{$config.xcode_project_path}", Color::YELLOW if $verbose
19
+ $xcode_project = Xcodeproj::Project.open($config.xcode_project_path)
20
+ end
21
+ end
22
+
23
+ def save_project
24
+ if $xcode_project
25
+ say "Writing project (#{$config.xcode_project_path}) to disk..", Color::YELLOW if $verbose
26
+ $xcode_project.save
27
+ end
28
+ end
29
+
30
+ def obtain_target(target_name)
31
+ load_project_if_needed
32
+ $xcode_project.targets.each do |target|
33
+ return target if target.name == target_name
34
+ end
35
+ say "Cannot find a target with name #{target_name} in Xcode project", Color::RED
36
+ abort
37
+ end
38
+
39
+ def make_group(group_path, dir_path)
40
+ load_project_if_needed
41
+
42
+ group_path = $config.collapse_to_project(group_path)
43
+ dir_path = $config.collapse_to_project(dir_path)
44
+
45
+ group_names = path_names_from_path(group_path)
46
+
47
+ group_components_count = group_names.count
48
+
49
+ final_group = $xcode_project
50
+
51
+ group_names.each_with_index do |group_name, index|
52
+ next_group = final_group[group_name]
53
+
54
+ unless next_group
55
+
56
+ if group_path != dir_path && index == group_components_count-1
57
+ next_group = final_group.new_group(group_name, dir_path, :project)
58
+ else
59
+ next_group = final_group.new_group(group_name, group_name)
60
+ end
61
+ end
62
+
63
+ final_group = next_group
64
+ end
65
+
66
+ final_group
67
+ end
68
+
69
+ def add_file(target, group, file_path, is_resource)
70
+ load_project_if_needed
71
+ group.files.each do |file|
72
+ if file.path == File.basename(file_path)
73
+ return
74
+ end
75
+ end
76
+ file = group.new_file(File.absolute_path(file_path))
77
+ if is_resource
78
+ target.add_resources([file])
79
+ else
80
+ target.add_file_references([file])
81
+ end
82
+ end
83
+
84
+ def delete_path(path)
85
+ load_project_if_needed
86
+
87
+ path = $config.collapse_to_project(path)
88
+
89
+ path_names = path_names_from_path(path)
90
+
91
+ final_group = $xcode_project
92
+ path_names.each_with_index do |group_name, index|
93
+ final_group = final_group[group_name]
94
+ end
95
+
96
+ delete_node final_group
97
+ end
98
+
99
+ private
100
+
101
+ def delete_node(node)
102
+ if node.kind_of? Xcodeproj::Project::Object::PBXGroup
103
+ node.recursive_children.each do |child|
104
+ delete_node(child)
105
+ end
106
+ node.remove_from_project
107
+ elsif node.kind_of? Xcodeproj::Project::Object::PBXFileReference
108
+ node.build_files.each { |build_file| build_file.remove_from_project }
109
+ node.remove_from_project
110
+ end
111
+ end
112
+
113
+ def path_names_from_path(path)
114
+ path.to_s.split('/')
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+
122
+ end
metadata CHANGED
@@ -1,35 +1,75 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gena
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleksey Garbarev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-16 00:00:00.000000000 Z
11
+ date: 2017-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: generamba
14
+ name: xcodeproj
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '1.5'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.3.0
22
+ version: 1.5.2
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '1.3'
29
+ version: '1.5'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 1.3.0
32
+ version: 1.5.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: thor
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.20'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.20.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.20'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.20.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: liquid
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '4.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 4.0.0
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '4.0'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 4.0.0
33
73
  - !ruby/object:Gem::Dependency
34
74
  name: plist
35
75
  requirement: !ruby/object:Gem::Requirement
@@ -70,7 +110,7 @@ dependencies:
70
110
  - - ">="
71
111
  - !ruby/object:Gem::Version
72
112
  version: 1.4.0
73
- description: Depends on Generamba it generates templates for generamba :)
113
+ description: Code generation and automation tool
74
114
  email: alex.garbarev@gmail.com
75
115
  executables:
76
116
  - gena
@@ -78,13 +118,16 @@ extensions: []
78
118
  extra_rdoc_files: []
79
119
  files:
80
120
  - bin/gena
81
- - lib/base_template.rb
82
- - lib/config.rb
121
+ - lib/cli/cli.rb
122
+ - lib/cli/init.rb
123
+ - lib/codegen/codegen.rb
124
+ - lib/config/config.rb
125
+ - lib/constants.rb
83
126
  - lib/gena.rb
84
- - lib/generate_cli.rb
85
- - lib/ramba_adapter.rb
86
- - lib/string_utils.rb
87
- homepage: http://rubygems.org/gems/cc_generate
127
+ - lib/plugin/plugin.rb
128
+ - lib/utils/utils.rb
129
+ - lib/utils/xcode_utils.rb
130
+ homepage: http://rubygems.org/gems/gena
88
131
  licenses:
89
132
  - MIT
90
133
  metadata: {}
@@ -104,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
147
  version: '0'
105
148
  requirements: []
106
149
  rubyforge_project:
107
- rubygems_version: 2.6.8
150
+ rubygems_version: 2.6.13
108
151
  signing_key:
109
152
  specification_version: 4
110
153
  summary: iOS code generation tool
data/lib/base_template.rb DELETED
@@ -1,91 +0,0 @@
1
- module Generate
2
-
3
- class BaseTemplate
4
-
5
- def initialize(options, config)
6
- @options = options
7
- @config = config
8
- end
9
-
10
- def options
11
- @options
12
- end
13
-
14
- def config
15
- @config
16
- end
17
-
18
- def type_config
19
- @config['template_options'][self.class.template_name.downcase]
20
- end
21
-
22
- def self.template_name
23
- self.name.split('::').last || ''
24
- end
25
-
26
- def sources_absolute_path
27
- "#{@config['sources_dir']}/#{sources_path}"
28
- end
29
-
30
- def tests_absolute_path
31
- "#{@config['tests_dir']}/#{tests_path}"
32
- end
33
-
34
- def template_parameters_string
35
- self.template_parameters.map{|k,v| "#{k}:#{v}"}.join(' ')
36
- end
37
-
38
- def self.descendants
39
- ObjectSpace.each_object(Class).select { |klass| klass < self }
40
- end
41
-
42
- def self.new_from_options(options, config)
43
- template_class = Object.const_get("Generate::#{options[:template_type].capitalize_first}")
44
- template_class.new(options, config.config)
45
- end
46
-
47
- def self.name_required?(options)
48
- template_class = Object.const_get("Generate::#{options[:template_type].capitalize_first}")
49
- template_class.generamba?
50
- end
51
-
52
- ##############
53
- ####### Methods to override in subclass
54
- ##############
55
-
56
- def self.register_options(opts, options)
57
-
58
- end
59
-
60
- def sources_path
61
- ''
62
- end
63
-
64
- def tests_path
65
- sources_path
66
- end
67
-
68
- def template_source_files
69
- []
70
- end
71
-
72
- def template_test_files
73
- []
74
- end
75
-
76
- # Custom parameters for generamba
77
- def template_parameters
78
- { }
79
- end
80
-
81
- def self.generamba?
82
- true
83
- end
84
-
85
- def run
86
-
87
- end
88
-
89
- end
90
-
91
- end
data/lib/config.rb DELETED
@@ -1,44 +0,0 @@
1
-
2
- require 'plist'
3
- require 'yaml'
4
- require 'generamba'
5
-
6
- module Generate
7
-
8
- class Config
9
-
10
- @config = {}
11
-
12
- def load_plist_config()
13
-
14
- if File.exists?('generate.plist')
15
- puts 'Found old generate.plist. Renaming to gena.plist'
16
- FileUtils.mv('generate.plist', 'gena.plist')
17
- end
18
-
19
- @config = Plist::parse_xml('gena.plist')
20
- end
21
-
22
- def to_rambafile()
23
- rambafile_content = {}
24
- rambafile_content['project_name'] = @config['project_name']
25
- rambafile_content['xcodeproj_path'] = "#{@config['project_name']}.xcodeproj"
26
- rambafile_content['company'] = @config['company']
27
- rambafile_content['prefix'] = @config['prefix']
28
- rambafile_content['project_target'] = @config['project_target']
29
- rambafile_content['test_target'] = @config['test_target']
30
- rambafile_content['templates'] = [ { name: 'default'}]
31
- rambafile_content.to_yaml
32
- end
33
-
34
- def config()
35
- @config
36
- end
37
-
38
- def xcode_project_path()
39
- "#{@config['project_name']}.xcodeproj"
40
- end
41
-
42
- end
43
-
44
- end
data/lib/generate_cli.rb DELETED
@@ -1,60 +0,0 @@
1
- require 'optparse'
2
- require_relative 'base_template'
3
-
4
- class GenerateCli
5
-
6
- def all_types
7
- Generate::BaseTemplate.descendants.map { |clazz| clazz.template_name.downcase }.join(', ')
8
- end
9
-
10
-
11
- def parse_arguments
12
- options = {}
13
-
14
- parser = OptionParser.new do |opts|
15
- opts.banner = "Usage: gena TEMPLATE MODULE_NAME [options]"
16
- opts.separator ""
17
- opts.separator "TEMPLATE is be one of [#{all_types}]"
18
- opts.separator ""
19
- opts.separator "Options are:"
20
-
21
- Generate::BaseTemplate.descendants.each do |clazz|
22
- clazz.register_options(opts, options)
23
- end
24
- opts.on('-h', '--help', 'Prints help') { puts opts; exit }
25
- opts.on('-v', '--verbose') { options[:verbose] = true }
26
- opts.on('--tests', 'Generate tests if possible') { options[:generate_tests] = true }
27
- opts.on('--cleanup', 'Removes temporary data instead of generation') { options[:cleanup] = true; return options; }
28
- opts.on('--fetch', 'Fetches templates from remote repository') { options[:fetch] = true; return options; }
29
- end
30
-
31
- parser.parse!
32
-
33
- type = ARGV[0]
34
- unless type
35
- puts "\n- You should specify TEMPLATE to proceed\n\n----\n\n"
36
- puts parser
37
- exit
38
- end
39
- ARGV.delete_at(0)
40
- options[:template_type] = type
41
-
42
- name = ARGV.pop
43
-
44
- name_required = Generate::BaseTemplate.name_required?(options)
45
-
46
- if !name && name_required
47
- puts "\n- You should specify MODULE_NAME to proceed with #{type} template\n\n----\n\n"
48
- puts parser
49
- exit
50
- end
51
-
52
- if name
53
- name = name.capitalize_first
54
- options[:name] = name
55
- end
56
-
57
- options
58
- end
59
-
60
- end