ccios 2.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +128 -0
- data/README.md +96 -0
- data/bin/ccios +3 -0
- data/ccios.gemspec +17 -0
- data/lib/ccios.rb +66 -0
- data/lib/ccios/code_templater.rb +14 -0
- data/lib/ccios/coordinator_generator.rb +16 -0
- data/lib/ccios/file_creator.rb +49 -0
- data/lib/ccios/interactor_generator.rb +23 -0
- data/lib/ccios/pbxproj_parser.rb +50 -0
- data/lib/ccios/presenter_generator.rb +31 -0
- data/lib/ccios/repository_generator.rb +27 -0
- data/lib/ccios/templates/coordinator.mustache +33 -0
- data/lib/ccios/templates/dependency_provider.mustache +14 -0
- data/lib/ccios/templates/interactor.mustache +13 -0
- data/lib/ccios/templates/interactor_assembly.mustache +5 -0
- data/lib/ccios/templates/interactor_implementation.mustache +18 -0
- data/lib/ccios/templates/presenter.mustache +19 -0
- data/lib/ccios/templates/presenter_assembly.mustache +15 -0
- data/lib/ccios/templates/presenter_implementation.mustache +35 -0
- data/lib/ccios/templates/repository.mustache +13 -0
- data/lib/ccios/templates/repository_assembly.mustache +5 -0
- data/lib/ccios/templates/repository_implementation.mustache +20 -0
- data/lib/ccios/templates/view_contract.mustache +13 -0
- data/lib/ccios/templates/view_controller.mustache +31 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 43f453c19f1da51cd1a18d5d25e15d5ca3e90683
|
4
|
+
data.tar.gz: 5a8c08ab93303d719503eaafa901a6c4fa2513d6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1d7a760a1579d28981af27a313942b1ded9ff443aa890fa6c3c2dad1debbf1ff266705c3f0f75357cb7637dd9fa6d80f8e9bdf85411ee883450457ebc444e402
|
7
|
+
data.tar.gz: 73136cf66b35647c5906b5ed7baa1e433fc0d904d576c6b441e2f25e56f8f2082fa800d7f4407f60e9b80aae9e90dcdf1180a22a6ed3dbc6b6e6c3ceac23098f
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ccios-*.gem
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ccios (1.0.3)
|
5
|
+
mustache (~> 1.0)
|
6
|
+
rails
|
7
|
+
xcodeproj (~> 1.4)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
CFPropertyList (2.3.5)
|
13
|
+
actioncable (5.1.3)
|
14
|
+
actionpack (= 5.1.3)
|
15
|
+
nio4r (~> 2.0)
|
16
|
+
websocket-driver (~> 0.6.1)
|
17
|
+
actionmailer (5.1.3)
|
18
|
+
actionpack (= 5.1.3)
|
19
|
+
actionview (= 5.1.3)
|
20
|
+
activejob (= 5.1.3)
|
21
|
+
mail (~> 2.5, >= 2.5.4)
|
22
|
+
rails-dom-testing (~> 2.0)
|
23
|
+
actionpack (5.1.3)
|
24
|
+
actionview (= 5.1.3)
|
25
|
+
activesupport (= 5.1.3)
|
26
|
+
rack (~> 2.0)
|
27
|
+
rack-test (~> 0.6.3)
|
28
|
+
rails-dom-testing (~> 2.0)
|
29
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
30
|
+
actionview (5.1.3)
|
31
|
+
activesupport (= 5.1.3)
|
32
|
+
builder (~> 3.1)
|
33
|
+
erubi (~> 1.4)
|
34
|
+
rails-dom-testing (~> 2.0)
|
35
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
36
|
+
activejob (5.1.3)
|
37
|
+
activesupport (= 5.1.3)
|
38
|
+
globalid (>= 0.3.6)
|
39
|
+
activemodel (5.1.3)
|
40
|
+
activesupport (= 5.1.3)
|
41
|
+
activerecord (5.1.3)
|
42
|
+
activemodel (= 5.1.3)
|
43
|
+
activesupport (= 5.1.3)
|
44
|
+
arel (~> 8.0)
|
45
|
+
activesupport (5.1.3)
|
46
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
47
|
+
i18n (~> 0.7)
|
48
|
+
minitest (~> 5.1)
|
49
|
+
tzinfo (~> 1.1)
|
50
|
+
arel (8.0.0)
|
51
|
+
builder (3.2.3)
|
52
|
+
claide (1.0.2)
|
53
|
+
colored2 (3.1.2)
|
54
|
+
concurrent-ruby (1.0.5)
|
55
|
+
erubi (1.6.1)
|
56
|
+
globalid (0.4.0)
|
57
|
+
activesupport (>= 4.2.0)
|
58
|
+
i18n (0.8.6)
|
59
|
+
loofah (2.0.3)
|
60
|
+
nokogiri (>= 1.5.9)
|
61
|
+
mail (2.6.6)
|
62
|
+
mime-types (>= 1.16, < 4)
|
63
|
+
method_source (0.8.2)
|
64
|
+
mime-types (3.1)
|
65
|
+
mime-types-data (~> 3.2015)
|
66
|
+
mime-types-data (3.2016.0521)
|
67
|
+
mini_portile2 (2.2.0)
|
68
|
+
minitest (5.10.3)
|
69
|
+
mustache (1.0.5)
|
70
|
+
nanaimo (0.2.3)
|
71
|
+
nio4r (2.1.0)
|
72
|
+
nokogiri (1.8.0)
|
73
|
+
mini_portile2 (~> 2.2.0)
|
74
|
+
rack (2.0.3)
|
75
|
+
rack-test (0.6.3)
|
76
|
+
rack (>= 1.0)
|
77
|
+
rails (5.1.3)
|
78
|
+
actioncable (= 5.1.3)
|
79
|
+
actionmailer (= 5.1.3)
|
80
|
+
actionpack (= 5.1.3)
|
81
|
+
actionview (= 5.1.3)
|
82
|
+
activejob (= 5.1.3)
|
83
|
+
activemodel (= 5.1.3)
|
84
|
+
activerecord (= 5.1.3)
|
85
|
+
activesupport (= 5.1.3)
|
86
|
+
bundler (>= 1.3.0)
|
87
|
+
railties (= 5.1.3)
|
88
|
+
sprockets-rails (>= 2.0.0)
|
89
|
+
rails-dom-testing (2.0.3)
|
90
|
+
activesupport (>= 4.2.0)
|
91
|
+
nokogiri (>= 1.6)
|
92
|
+
rails-html-sanitizer (1.0.3)
|
93
|
+
loofah (~> 2.0)
|
94
|
+
railties (5.1.3)
|
95
|
+
actionpack (= 5.1.3)
|
96
|
+
activesupport (= 5.1.3)
|
97
|
+
method_source
|
98
|
+
rake (>= 0.8.7)
|
99
|
+
thor (>= 0.18.1, < 2.0)
|
100
|
+
rake (12.0.0)
|
101
|
+
sprockets (3.7.1)
|
102
|
+
concurrent-ruby (~> 1.0)
|
103
|
+
rack (> 1, < 3)
|
104
|
+
sprockets-rails (3.2.0)
|
105
|
+
actionpack (>= 4.0)
|
106
|
+
activesupport (>= 4.0)
|
107
|
+
sprockets (>= 3.0.0)
|
108
|
+
thor (0.20.0)
|
109
|
+
thread_safe (0.3.6)
|
110
|
+
tzinfo (1.2.3)
|
111
|
+
thread_safe (~> 0.1)
|
112
|
+
websocket-driver (0.6.5)
|
113
|
+
websocket-extensions (>= 0.1.0)
|
114
|
+
websocket-extensions (0.1.2)
|
115
|
+
xcodeproj (1.5.1)
|
116
|
+
CFPropertyList (~> 2.3.3)
|
117
|
+
claide (>= 1.0.2, < 2.0)
|
118
|
+
colored2 (~> 3.1)
|
119
|
+
nanaimo (~> 0.2.3)
|
120
|
+
|
121
|
+
PLATFORMS
|
122
|
+
ruby
|
123
|
+
|
124
|
+
DEPENDENCIES
|
125
|
+
ccios!
|
126
|
+
|
127
|
+
BUNDLED WITH
|
128
|
+
1.12.3
|
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# ccios
|
2
|
+
Xcode File Generator for Clean Code architecture
|
3
|
+
|
4
|
+
# How to install
|
5
|
+
|
6
|
+
```
|
7
|
+
cd ccios
|
8
|
+
gem build ccios.gemspec
|
9
|
+
gem install ./ccios-x.x.x.gem
|
10
|
+
```
|
11
|
+
|
12
|
+
# How to use
|
13
|
+
|
14
|
+
Go to your `.xcodeproj` folder `cd /paht/to/my/xcodeproj`.
|
15
|
+
Then generate files with prefix `Example`:
|
16
|
+
|
17
|
+
```
|
18
|
+
ccios [-p|-i|-r|-c] Example [-d]
|
19
|
+
```
|
20
|
+
|
21
|
+
Generated templates can be found [here](https://github.com/felginep/ccios/tree/master/lib/ccios/templates)
|
22
|
+
|
23
|
+
### `-p`
|
24
|
+
`-p` stands for `presenter`
|
25
|
+
|
26
|
+
This generates 4 files: `ExampleViewController`, `ExampleViewContract`, `ExamplePresenter`, `ExamplePresenterImplementation`. If the `-d` option is supplied the protocol `ExamplePresenterDelegate` will be generated.
|
27
|
+
|
28
|
+
What's more it prints the code you need to add to `DependencyProvider.swift` and `PresenterAssembly.swift` for dependency injection.
|
29
|
+
|
30
|
+
The following structure is created for you in the Xcode project:
|
31
|
+
|
32
|
+
```
|
33
|
+
.
|
34
|
+
+-- App/
|
35
|
+
| +-- Example/
|
36
|
+
| | +-- UI/
|
37
|
+
| | | +-- View/
|
38
|
+
| | | +-- ViewController/
|
39
|
+
| | | | +-- ExampleViewController
|
40
|
+
| | | +-- ExampleViewContract
|
41
|
+
| | +-- Presenter/
|
42
|
+
| | | +-- ExamplePresenter
|
43
|
+
| | | +-- ExamplePresenterImplementation
|
44
|
+
| | +-- Model/
|
45
|
+
```
|
46
|
+
|
47
|
+
### `-i`
|
48
|
+
`-i` stands for `interactor`
|
49
|
+
|
50
|
+
This generates 2 files: `ExampleInteractor` and `ExampleInteractorImplementation`.
|
51
|
+
|
52
|
+
What's more it prints the code you need to add to `InteractorAssembly.swift` for dependency injection.
|
53
|
+
|
54
|
+
The following structure is created for you in the Xcode project:
|
55
|
+
|
56
|
+
```
|
57
|
+
.
|
58
|
+
+-- Core/
|
59
|
+
| +-- Interactor/
|
60
|
+
| | +-- ExampleInteractor/
|
61
|
+
| | | +-- ExampleInteractor
|
62
|
+
| | | +-- ExampleInteractorImplementation
|
63
|
+
```
|
64
|
+
|
65
|
+
### `-r`
|
66
|
+
`-r` stands for `repository`
|
67
|
+
|
68
|
+
This generates 2 files: `ExampleRepository` and `ExampleRepositoryImplementation`.
|
69
|
+
|
70
|
+
What's more it prints the code you need to add to `RepositoryAssembly.swift` for dependency injection.
|
71
|
+
|
72
|
+
The following structure is created for you in the Xcode project:
|
73
|
+
|
74
|
+
```
|
75
|
+
.
|
76
|
+
+-- Core/
|
77
|
+
| +-- Data/
|
78
|
+
| | +-- Example
|
79
|
+
| | | +-- ExampleRepository
|
80
|
+
+-- Data/
|
81
|
+
| +-- Example
|
82
|
+
| | +-- ExampleRepositoryImplementation
|
83
|
+
```
|
84
|
+
|
85
|
+
### `-c`
|
86
|
+
`-c` stands for `coordinator`
|
87
|
+
|
88
|
+
This generates one file: `ExampleCoordinator`. If the `-d` option is supplied the protocol `ExampleCoordinatorDelegate` will be generated.
|
89
|
+
|
90
|
+
The following structure is created for you in the Xcode project:
|
91
|
+
|
92
|
+
```
|
93
|
+
.
|
94
|
+
+-- Coordinator/
|
95
|
+
| +-- ExampleCoordinator
|
96
|
+
```
|
data/bin/ccios
ADDED
data/ccios.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'ccios'
|
3
|
+
s.version = '2.0.2'
|
4
|
+
s.executables << 'ccios'
|
5
|
+
s.date = '2016-08-03'
|
6
|
+
s.summary = "Clean Code iOS Generator"
|
7
|
+
s.description = "Clean Code iOS Generator"
|
8
|
+
s.authors = ["Pierre Felgines"]
|
9
|
+
s.email = 'pierre.felgines@gmail.com'
|
10
|
+
# use `git ls-files -coz -x *.gem` for development
|
11
|
+
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
12
|
+
s.homepage = 'http://rubygems.org/gems/hola'
|
13
|
+
s.license = 'MIT'
|
14
|
+
s.add_dependency 'xcodeproj', '~> 1.4'
|
15
|
+
s.add_dependency 'rails', '~> 5.1'
|
16
|
+
s.add_dependency "mustache", "~> 1.0"
|
17
|
+
end
|
data/lib/ccios.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'xcodeproj'
|
3
|
+
require 'optparse'
|
4
|
+
require 'rails' # for underscore method used in code_templater.rb
|
5
|
+
require 'ccios/presenter_generator'
|
6
|
+
require 'ccios/coordinator_generator'
|
7
|
+
require 'ccios/interactor_generator'
|
8
|
+
require 'ccios/repository_generator'
|
9
|
+
|
10
|
+
options = {}
|
11
|
+
OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: ccios [options]"
|
13
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
14
|
+
options[:verbose] = v
|
15
|
+
end
|
16
|
+
opts.on("-pName", "--presenter=Name", "Generate NamePresenter, NamePresenterImplementation, NameViewContract and NameViewController") do |v|
|
17
|
+
options[:presenter] = v
|
18
|
+
end
|
19
|
+
opts.on("-cName", "--coordinator=Name", "Generate NameCoordinator") do |v|
|
20
|
+
options[:coordinator] = v
|
21
|
+
end
|
22
|
+
opts.on("-iName", "--interactor=Name", "Generate NameInteractor and NameInteractorImplementation") do |v|
|
23
|
+
options[:interactor] = v
|
24
|
+
end
|
25
|
+
opts.on("-rName", "--repository=Name", "Generate NameRepository and NameRepositoryImplementation") do |v|
|
26
|
+
options[:repository] = v
|
27
|
+
end
|
28
|
+
opts.on("-d", "--delegate", "Add delegate for curent generation") do |v|
|
29
|
+
options[:generate_delegate] = v
|
30
|
+
end
|
31
|
+
opts.on("-h", "--help", "Print this help") do
|
32
|
+
puts opts
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
end.parse!
|
36
|
+
|
37
|
+
source_path = Dir.pwd
|
38
|
+
parser = PBXProjParser.new source_path
|
39
|
+
|
40
|
+
if options[:presenter]
|
41
|
+
presenter_name = options[:presenter]
|
42
|
+
presenter_generator = PresenterGenerator.new parser
|
43
|
+
generator_options = {generate_delegate: options[:generate_delegate]}
|
44
|
+
presenter_generator.generate(presenter_name, generator_options)
|
45
|
+
end
|
46
|
+
|
47
|
+
if options[:coordinator]
|
48
|
+
coordinator_name = options[:coordinator]
|
49
|
+
coordinator_generator = CoordinatorGenerator.new parser
|
50
|
+
generator_options = {generate_delegate: options[:generate_delegate]}
|
51
|
+
coordinator_generator.generate(coordinator_name, generator_options)
|
52
|
+
end
|
53
|
+
|
54
|
+
if options[:interactor]
|
55
|
+
interactor_name = options[:interactor]
|
56
|
+
interactor_generator = InteractorGenerator.new parser
|
57
|
+
interactor_generator.generate(interactor_name)
|
58
|
+
end
|
59
|
+
|
60
|
+
if options[:repository]
|
61
|
+
repository_name = options[:repository]
|
62
|
+
repository_generator = RepositoryGenerator.new parser
|
63
|
+
repository_generator.generate(repository_name)
|
64
|
+
end
|
65
|
+
|
66
|
+
parser.save
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'mustache'
|
2
|
+
|
3
|
+
class CodeTemplater
|
4
|
+
def initialize(options = {})
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def content_for_suffix(prefix, suffix)
|
9
|
+
template_name = suffix.underscore
|
10
|
+
options = @options.merge({name: prefix, lowercased_name: prefix.camelize(:lower)})
|
11
|
+
template_file = File.join(File.dirname(__FILE__), "templates/#{template_name}.mustache")
|
12
|
+
Mustache.render(File.read(template_file), options)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'file_creator'
|
2
|
+
require_relative "pbxproj_parser"
|
3
|
+
|
4
|
+
class CoordinatorGenerator
|
5
|
+
|
6
|
+
def initialize(parser)
|
7
|
+
@parser = parser
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate(coordinator_name, options = {})
|
11
|
+
coordinator_group = @parser.coordinator_group
|
12
|
+
file_creator = FileCreator.new(@parser.source_path, options)
|
13
|
+
target = @parser.main_target
|
14
|
+
file_creator.create_file(coordinator_name, 'Coordinator', coordinator_group, target)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative 'code_templater'
|
2
|
+
|
3
|
+
class FileCreator
|
4
|
+
def initialize(source_path, options = {})
|
5
|
+
@source_path = source_path
|
6
|
+
@classes_path = source_path + '/Classes'
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def templater_options(target)
|
11
|
+
defaults = {
|
12
|
+
project_name: target.display_name,
|
13
|
+
full_username: git_username,
|
14
|
+
date: DateTime.now.strftime("%d/%m/%Y"),
|
15
|
+
}
|
16
|
+
defaults.merge(@options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def git_username
|
20
|
+
`cd #{@source_path}; git config user.name`.strip
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_file(prefix, suffix, group, target)
|
24
|
+
file_path = @classes_path + '/' + prefix + suffix + '.swift'
|
25
|
+
|
26
|
+
raise "File #{file_path} already exists" if File.exists?(file_path)
|
27
|
+
file = File.new(file_path, 'w')
|
28
|
+
|
29
|
+
templater_options = templater_options(target)
|
30
|
+
code_templater = CodeTemplater.new(templater_options)
|
31
|
+
file_content = code_templater.content_for_suffix(prefix, suffix)
|
32
|
+
file.puts(file_content)
|
33
|
+
|
34
|
+
file.close
|
35
|
+
file_ref = group.new_reference(file_path)
|
36
|
+
target.add_file_references([file_ref])
|
37
|
+
end
|
38
|
+
|
39
|
+
def print_file_content(prefix, suffix)
|
40
|
+
file_path = @classes_path + '/' + suffix + '.swift'
|
41
|
+
|
42
|
+
code_templater = CodeTemplater.new(@options)
|
43
|
+
template = code_templater.content_for_suffix(prefix, suffix)
|
44
|
+
|
45
|
+
puts "Add this snippet to #{file_path}"
|
46
|
+
puts template
|
47
|
+
puts "\n"
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'file_creator'
|
2
|
+
require_relative "pbxproj_parser"
|
3
|
+
|
4
|
+
class InteractorGenerator
|
5
|
+
|
6
|
+
def initialize(parser)
|
7
|
+
@parser = parser
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate(interactor_name, options = {})
|
11
|
+
interactor_group = @parser.interactor_group
|
12
|
+
new_group_name = "#{interactor_name}Interactor"
|
13
|
+
raise "[Error] Group #{new_group_name} already exists in #{app_group.display_name}" if interactor_group[new_group_name]
|
14
|
+
new_group = interactor_group.new_group(new_group_name)
|
15
|
+
|
16
|
+
file_creator = FileCreator.new(@parser.source_path, options)
|
17
|
+
target = @parser.main_target
|
18
|
+
file_creator.create_file(interactor_name, 'Interactor', new_group, target)
|
19
|
+
file_creator.create_file(interactor_name, 'InteractorImplementation', new_group, target)
|
20
|
+
|
21
|
+
file_creator.print_file_content(interactor_name, 'InteractorAssembly')
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'xcodeproj'
|
2
|
+
|
3
|
+
class PBXProjParser
|
4
|
+
|
5
|
+
attr_accessor :source_path, :project
|
6
|
+
|
7
|
+
def initialize(source_path)
|
8
|
+
@source_path = source_path
|
9
|
+
if project_path.nil?
|
10
|
+
raise "[Error] There is no xcodeproj at path #{@source_path}"
|
11
|
+
end
|
12
|
+
@project = Xcodeproj::Project.open(project_path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def project_path
|
16
|
+
Dir.glob("#{@source_path}/*.xcodeproj").first
|
17
|
+
end
|
18
|
+
|
19
|
+
def main_target
|
20
|
+
@project.targets.first
|
21
|
+
end
|
22
|
+
|
23
|
+
def classes_group
|
24
|
+
@project.groups.find { |g| g.display_name === "Classes" }
|
25
|
+
end
|
26
|
+
|
27
|
+
def app_group
|
28
|
+
classes_group["App"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def core_group
|
32
|
+
classes_group["Core"]
|
33
|
+
end
|
34
|
+
|
35
|
+
def coordinator_group
|
36
|
+
classes_group["Coordinator"]
|
37
|
+
end
|
38
|
+
|
39
|
+
def interactor_group
|
40
|
+
core_group["Interactor"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def data_group
|
44
|
+
classes_group["Data"]
|
45
|
+
end
|
46
|
+
|
47
|
+
def save
|
48
|
+
@project.save
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'file_creator'
|
2
|
+
require_relative "pbxproj_parser"
|
3
|
+
|
4
|
+
class PresenterGenerator
|
5
|
+
|
6
|
+
def initialize(parser)
|
7
|
+
@parser = parser
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate(presenter_name, options = {})
|
11
|
+
app_group = @parser.app_group
|
12
|
+
raise "[Error] Group #{presenter_name} already exists in #{app_group.display_name}" if app_group[presenter_name]
|
13
|
+
new_group = app_group.new_group(presenter_name)
|
14
|
+
|
15
|
+
ui_group = new_group.new_group("UI")
|
16
|
+
ui_group.new_group("View")
|
17
|
+
view_controller_group = ui_group.new_group("ViewController")
|
18
|
+
presenter_group = new_group.new_group("Presenter")
|
19
|
+
model_group = new_group.new_group("Model")
|
20
|
+
|
21
|
+
file_creator = FileCreator.new(@parser.source_path, options)
|
22
|
+
target = @parser.main_target
|
23
|
+
file_creator.create_file(presenter_name, 'ViewContract', ui_group, target)
|
24
|
+
file_creator.create_file(presenter_name, 'ViewController', view_controller_group, target)
|
25
|
+
file_creator.create_file(presenter_name, 'Presenter', presenter_group, target)
|
26
|
+
file_creator.create_file(presenter_name, 'PresenterImplementation', presenter_group, target)
|
27
|
+
|
28
|
+
file_creator.print_file_content(presenter_name, 'DependencyProvider')
|
29
|
+
file_creator.print_file_content(presenter_name, 'PresenterAssembly')
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative 'file_creator'
|
2
|
+
require_relative "pbxproj_parser"
|
3
|
+
|
4
|
+
class RepositoryGenerator
|
5
|
+
|
6
|
+
def initialize(parser)
|
7
|
+
@parser = parser
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate(repository_name, options = {})
|
11
|
+
core_group = @parser.core_group
|
12
|
+
core_data_group = core_group["Data"]
|
13
|
+
data_group = @parser.data_group
|
14
|
+
raise "[Error] Group #{repository_name} already exists in #{core_data_group.display_name}" if core_data_group[repository_name]
|
15
|
+
core_data_new_group = core_data_group.new_group(repository_name)
|
16
|
+
|
17
|
+
raise "[Error] Group #{repository_name} already exists in #{data_group.display_name}" if data_group[repository_name]
|
18
|
+
data_new_group = data_group.new_group(repository_name)
|
19
|
+
|
20
|
+
file_creator = FileCreator.new(@parser.source_path, options)
|
21
|
+
target = @parser.main_target
|
22
|
+
file_creator.create_file(repository_name, 'Repository', core_data_new_group, target)
|
23
|
+
file_creator.create_file(repository_name, 'RepositoryImplementation', data_new_group, target)
|
24
|
+
|
25
|
+
file_creator.print_file_content(repository_name, 'RepositoryAssembly')
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
//
|
2
|
+
// {{name}}Coordinator.swift
|
3
|
+
// {{project_name}}
|
4
|
+
//
|
5
|
+
// Created by {{full_username}} on {{date}}.
|
6
|
+
//
|
7
|
+
//
|
8
|
+
|
9
|
+
import Foundation
|
10
|
+
|
11
|
+
{{#generate_delegate}}
|
12
|
+
protocol {{name}}CoordinatorDelegate : class {
|
13
|
+
|
14
|
+
}
|
15
|
+
|
16
|
+
{{/generate_delegate}}
|
17
|
+
class {{name}}Coordinator: Coordinator {
|
18
|
+
|
19
|
+
{{#generate_delegate}}
|
20
|
+
weak var delegate: {{name}}CoordinatorDelegate?
|
21
|
+
{{/generate_delegate}}
|
22
|
+
private let navigationController: UINavigationController
|
23
|
+
|
24
|
+
init(navigationController: UINavigationController) {
|
25
|
+
self.navigationController = navigationController
|
26
|
+
}
|
27
|
+
|
28
|
+
//MARK: - Public
|
29
|
+
|
30
|
+
func start() {
|
31
|
+
|
32
|
+
}
|
33
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{{#generate_delegate}}
|
2
|
+
func {{lowercased_name}}Presenter(viewContract: {{name}}ViewContract, presenterDelegate: {{name}}PresenterDelegate) -> {{name}}Presenter? {
|
3
|
+
return presenterAssembler
|
4
|
+
.resolver
|
5
|
+
.resolve({{name}}Presenter.self, arguments: viewContract, presenterDelegate)
|
6
|
+
}
|
7
|
+
{{/generate_delegate}}
|
8
|
+
{{^generate_delegate}}
|
9
|
+
func {{lowercased_name}}Presenter(viewContract: {{name}}ViewContract) -> {{name}}Presenter? {
|
10
|
+
return presenterAssembler
|
11
|
+
.resolver
|
12
|
+
.resolve({{name}}Presenter.self, argument: viewContract)
|
13
|
+
}
|
14
|
+
{{/generate_delegate}}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
//
|
2
|
+
// {{name}}InteractorImplementation.swift
|
3
|
+
// {{project_name}}
|
4
|
+
//
|
5
|
+
// Created by {{full_username}} on {{date}}.
|
6
|
+
//
|
7
|
+
//
|
8
|
+
|
9
|
+
import Foundation
|
10
|
+
|
11
|
+
class {{name}}InteractorImplementation : {{name}}Interactor {
|
12
|
+
|
13
|
+
//MARK: - {{name}}Interactor
|
14
|
+
|
15
|
+
func execute() {
|
16
|
+
|
17
|
+
}
|
18
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
//
|
2
|
+
// {{name}}Presenter.swift
|
3
|
+
// {{project_name}}
|
4
|
+
//
|
5
|
+
// Created by {{full_username}} on {{date}}.
|
6
|
+
//
|
7
|
+
//
|
8
|
+
|
9
|
+
import Foundation
|
10
|
+
|
11
|
+
protocol {{name}}Presenter {
|
12
|
+
func start()
|
13
|
+
}
|
14
|
+
{{#generate_delegate}}
|
15
|
+
|
16
|
+
protocol {{name}}PresenterDelegate : class {
|
17
|
+
|
18
|
+
}
|
19
|
+
{{/generate_delegate}}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{{#generate_delegate}}
|
2
|
+
container.register({{name}}Presenter.self) { r, viewContract, delegate in
|
3
|
+
{{name}}PresenterImplementation(
|
4
|
+
viewContract: viewContract,
|
5
|
+
delegate: delegate
|
6
|
+
)
|
7
|
+
}
|
8
|
+
{{/generate_delegate}}
|
9
|
+
{{^generate_delegate}}
|
10
|
+
container.register({{name}}Presenter.self) { r, viewContract in
|
11
|
+
{{name}}PresenterImplementation(
|
12
|
+
viewContract: viewContract
|
13
|
+
)
|
14
|
+
}
|
15
|
+
{{/generate_delegate}}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
//
|
2
|
+
// {{name}}PresenterImplementation.swift
|
3
|
+
// {{project_name}}
|
4
|
+
//
|
5
|
+
// Created by {{full_username}} on {{date}}.
|
6
|
+
//
|
7
|
+
//
|
8
|
+
|
9
|
+
import Foundation
|
10
|
+
|
11
|
+
class {{name}}PresenterImplementation : {{name}}Presenter {
|
12
|
+
|
13
|
+
private weak var viewContract: {{name}}ViewContract?
|
14
|
+
{{#generate_delegate}}
|
15
|
+
private weak var delegate: {{name}}PresenterDelegate?
|
16
|
+
{{/generate_delegate}}
|
17
|
+
|
18
|
+
{{#generate_delegate}}
|
19
|
+
init(viewContract: {{name}}ViewContract, delegate: {{name}}PresenterDelegate) {
|
20
|
+
self.viewContract = viewContract
|
21
|
+
self.delegate = delegate
|
22
|
+
}
|
23
|
+
{{/generate_delegate}}
|
24
|
+
{{^generate_delegate}}
|
25
|
+
init(viewContract: {{name}}ViewContract) {
|
26
|
+
self.viewContract = viewContract
|
27
|
+
}
|
28
|
+
{{/generate_delegate}}
|
29
|
+
|
30
|
+
//MARK: - {{name}}Presenter
|
31
|
+
|
32
|
+
func start() {
|
33
|
+
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
//
|
2
|
+
// {{name}}RepositoryImplementation.swift
|
3
|
+
// {{project_name}}
|
4
|
+
//
|
5
|
+
// Created by {{full_username}} on {{date}}.
|
6
|
+
//
|
7
|
+
//
|
8
|
+
//
|
9
|
+
|
10
|
+
import Foundation
|
11
|
+
|
12
|
+
class {{name}}RepositoryImplementation : {{name}}Repository {
|
13
|
+
|
14
|
+
init() {
|
15
|
+
|
16
|
+
}
|
17
|
+
|
18
|
+
//MARK: - {{name}}Repository
|
19
|
+
|
20
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
//
|
2
|
+
// {{name}}ViewController.swift
|
3
|
+
// {{project_name}}
|
4
|
+
//
|
5
|
+
// Created by {{full_username}} on {{date}}.
|
6
|
+
//
|
7
|
+
//
|
8
|
+
|
9
|
+
import Foundation
|
10
|
+
import UIKit
|
11
|
+
|
12
|
+
class {{name}}ViewController : SharedViewController, {{name}}ViewContract {
|
13
|
+
var presenter: {{name}}Presenter?
|
14
|
+
|
15
|
+
init() {
|
16
|
+
super.init(nibName: nil, bundle: nil)
|
17
|
+
}
|
18
|
+
|
19
|
+
@available(*, unavailable)
|
20
|
+
required init?(coder decoder: NSCoder) {
|
21
|
+
fatalError("init(coder:) has not been implemented")
|
22
|
+
}
|
23
|
+
|
24
|
+
override func viewDidLoad() {
|
25
|
+
super.viewDidLoad()
|
26
|
+
presenter?.start()
|
27
|
+
}
|
28
|
+
|
29
|
+
//MARK: - {{name}}ViewContract
|
30
|
+
|
31
|
+
}
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ccios
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pierre Felgines
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: xcodeproj
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mustache
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
description: Clean Code iOS Generator
|
56
|
+
email: pierre.felgines@gmail.com
|
57
|
+
executables:
|
58
|
+
- ccios
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- Gemfile.lock
|
65
|
+
- README.md
|
66
|
+
- bin/ccios
|
67
|
+
- ccios.gemspec
|
68
|
+
- lib/ccios.rb
|
69
|
+
- lib/ccios/code_templater.rb
|
70
|
+
- lib/ccios/coordinator_generator.rb
|
71
|
+
- lib/ccios/file_creator.rb
|
72
|
+
- lib/ccios/interactor_generator.rb
|
73
|
+
- lib/ccios/pbxproj_parser.rb
|
74
|
+
- lib/ccios/presenter_generator.rb
|
75
|
+
- lib/ccios/repository_generator.rb
|
76
|
+
- lib/ccios/templates/coordinator.mustache
|
77
|
+
- lib/ccios/templates/dependency_provider.mustache
|
78
|
+
- lib/ccios/templates/interactor.mustache
|
79
|
+
- lib/ccios/templates/interactor_assembly.mustache
|
80
|
+
- lib/ccios/templates/interactor_implementation.mustache
|
81
|
+
- lib/ccios/templates/presenter.mustache
|
82
|
+
- lib/ccios/templates/presenter_assembly.mustache
|
83
|
+
- lib/ccios/templates/presenter_implementation.mustache
|
84
|
+
- lib/ccios/templates/repository.mustache
|
85
|
+
- lib/ccios/templates/repository_assembly.mustache
|
86
|
+
- lib/ccios/templates/repository_implementation.mustache
|
87
|
+
- lib/ccios/templates/view_contract.mustache
|
88
|
+
- lib/ccios/templates/view_controller.mustache
|
89
|
+
homepage: http://rubygems.org/gems/hola
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.4.5.1
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Clean Code iOS Generator
|
113
|
+
test_files: []
|