gena 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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