Skip to content

Commit

Permalink
Merge pull request #22 from faberNovel/feature/allow_user_templates
Browse files Browse the repository at this point in the history
Allow user to override templates with their own
  • Loading branch information
Nooba authored Oct 3, 2023
2 parents f4058e8 + 789eb7f commit 0fa040b
Show file tree
Hide file tree
Showing 35 changed files with 377 additions and 72 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Set up Ruby 2.6
uses: actions/setup-ruby@v1
- uses: actions/checkout@v4
- name: Set up Ruby 3.2
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6.x
bundler-cache: true
- name: Build and test with Rake
run: |
gem install bundler
Expand Down
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.2.2
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

## [4.1.0]

### Added
- Allow user to overload templates with local version thanks to the new config parameter in `.ccios.yml`

## [4.0.2]

### Fixed
Expand Down
25 changes: 13 additions & 12 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,40 +1,41 @@
PATH
remote: .
specs:
ccios (4.0.2)
ccios (4.1.0)
activesupport (> 4)
mustache (~> 1.0)
xcodeproj (~> 1.4)

GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.3)
activesupport (6.1.3)
CFPropertyList (3.0.6)
rexml
activesupport (7.0.8)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
atomos (0.1.3)
claide (1.0.3)
claide (1.1.0)
colored2 (3.1.2)
concurrent-ruby (1.1.8)
i18n (1.8.9)
concurrent-ruby (1.2.2)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
minitest (5.14.2)
minitest (5.20.0)
mustache (1.1.1)
nanaimo (0.3.0)
rake (12.3.3)
tzinfo (2.0.4)
rexml (3.2.6)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
xcodeproj (1.19.0)
xcodeproj (1.23.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
zeitwerk (2.4.2)
rexml (~> 3.2.4)

PLATFORMS
ruby
Expand All @@ -45,4 +46,4 @@ DEPENDENCIES
rake (~> 12.3)

BUNDLED WITH
1.17.3
2.4.10
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,14 @@ data:
target: MyProjectData # optional
repository:
group: MyProjectData/Sources/Repositories
```

*Note*: The path of the new files will be infered from the path of the group. It works with *Group with folder* and *Group without folder* in Xcode.

And lastly you may want to use your own templates, by adding this parameter to the file:
```
templates:
path: Path/To/Users/Templates
```


2 changes: 1 addition & 1 deletion ccios.gemspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = 'ccios'
s.version = '4.0.2'
s.version = '4.1.0'
s.executables << 'ccios'
s.date = '2016-08-03'
s.summary = "Clean Code iOS Generator"
Expand Down
20 changes: 10 additions & 10 deletions lib/ccios.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options[:verbose] = v
end
opts.on("-pName", "--presenter=Name", "Generate NamePresenter, NamePresenterImplementation, NameViewContract and NameViewController") do |v|
options[:presenter] = v
opts.on("-pName", "--presenter=Name", "Generate NamePresenter, NamePresenterImplementation, NameViewContract and NameViewController") do |name|
options[:presenter] = name
end
opts.on("-cName", "--coordinator=Name", "Generate NameCoordinator") do |v|
options[:coordinator] = v
opts.on("-cName", "--coordinator=Name", "Generate NameCoordinator") do |name|
options[:coordinator] = name
end
opts.on("-iName", "--interactor=Name", "Generate NameInteractor and NameInteractorImplementation") do |v|
options[:interactor] = v
opts.on("-iName", "--interactor=Name", "Generate NameInteractor and NameInteractorImplementation") do |name|
options[:interactor] = name
end
opts.on("-rName", "--repository=Name", "Generate NameRepository and NameRepositoryImplementation") do |v|
options[:repository] = v
opts.on("-rName", "--repository=Name", "Generate NameRepository and NameRepositoryImplementation") do |name|
options[:repository] = name
end
opts.on("-d", "--delegate", "Add delegate for curent generation") do |v|
options[:generate_delegate] = v
opts.on("-d", "--delegate", "Add delegate for curent generation") do |add_delegate|
options[:generate_delegate] = add_delegate
end
opts.on("-h", "--help", "Print this help") do
puts opts
Expand Down
5 changes: 3 additions & 2 deletions lib/ccios/code_templater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
require 'active_support/core_ext/string'

class CodeTemplater
def initialize(options = {})
def initialize(options = {}, templates_path)
@options = options
@templates_path = templates_path
end

def content_for_suffix(prefix, suffix)
template_name = suffix.underscore
options = @options.merge({name: prefix, lowercased_name: prefix.camelize(:lower)})
template_file = File.join(File.dirname(__FILE__), "templates/#{template_name}.mustache")
template_file = File.join(@templates_path, "#{template_name}.mustache")
Mustache.render(File.read(template_file), options)
end
end
25 changes: 21 additions & 4 deletions lib/ccios/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

class Config

attr_reader :app, :core, :data
attr_reader :app, :core, :data, :templates

def self.parse(source_path)
if File.exist?(source_path)
config = YAML.load_file(source_path)
self.new config, source_path
else
puts "File #{source_path} does not exists. Using default config."
puts "File #{source_path} does not exist. Using default config."
self.default
end
end
Expand All @@ -30,20 +30,30 @@ def self.default_config_hash
"data" => {
"project" => project,
"repository" => {"group" => "Classes/Data"}
}
},
"templates" => self.default_templates_hash
}
end

def self.default
self.new default_config_hash
end

def self.default_templates_hash
{ "path" => File.join(File.dirname(__FILE__), "templates") }
end

def initialize(config_hash, source_path = nil)
@source_path = source_path
validate config_hash
@app = AppConfig.new config_hash["app"]
@core = CoreConfig.new config_hash["core"]
@data = DataConfig.new config_hash["data"]
if config_hash["templates"].nil?
@templates = TemplatesConfig.new Config.default_templates_hash
else
@templates = TemplatesConfig.new config_hash["templates"]
end
end

def validate(hash)
Expand Down Expand Up @@ -107,10 +117,17 @@ def initialize(hash)
end

class ObjectConfig

attr_reader :group

def initialize(hash)
@group = hash["group"]
end
end

class TemplatesConfig
attr_reader :path

def initialize(hash)
@path = hash["path"]
end
end
2 changes: 1 addition & 1 deletion lib/ccios/coordinator_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def initialize(parser, config)

def generate(coordinator_name, options = {})
coordinator_group = @parser.coordinator_group
file_creator = FileCreator.new(options)
file_creator = FileCreator.new(options, @config)
target = @parser.app_target
coordinator_name = coordinator_name.gsub("Coordinator", "")
file_creator.create_file(coordinator_name, 'Coordinator', coordinator_group, target)
Expand Down
7 changes: 4 additions & 3 deletions lib/ccios/file_creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ def logger
FileCreator.logger
end

def initialize(options = {})
def initialize(options = {}, config)
@options = options
@config = config
end

def templater_options(target)
Expand All @@ -50,7 +51,7 @@ def create_file(prefix, suffix, group, target)
file = File.new(file_path, 'w')

templater_options = templater_options(target)
code_templater = CodeTemplater.new(templater_options)
code_templater = CodeTemplater.new(templater_options, @config.templates.path)
file_content = code_templater.content_for_suffix(prefix, suffix)
file.puts(file_content)

Expand All @@ -70,7 +71,7 @@ def create_empty_directory(group)
def print_file_content(prefix, suffix)
file_name = suffix + '.swift'

code_templater = CodeTemplater.new(@options)
code_templater = CodeTemplater.new(@options, @config.templates.path)
template = code_templater.content_for_suffix(prefix, suffix)

logger.info "Add this snippet to #{file_name}"
Expand Down
2 changes: 1 addition & 1 deletion lib/ccios/interactor_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def generate(interactor_name, options = {})
path: new_group_path
)

file_creator = FileCreator.new(options)
file_creator = FileCreator.new(options, @config)
target = @parser.core_target
file_creator.create_file(interactor_name, 'Interactor', new_group, target)
file_creator.create_file(interactor_name, 'InteractorImplementation', new_group, target)
Expand Down
2 changes: 1 addition & 1 deletion lib/ccios/presenter_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def generate(presenter_name, options = {})
path: model_group_path
)

file_creator = FileCreator.new(options)
file_creator = FileCreator.new(options, @config)
target = @parser.app_target
file_creator.create_file(presenter_name, 'ViewContract', ui_group, target)
file_creator.create_file(presenter_name, 'ViewController', view_controller_group, target)
Expand Down
4 changes: 2 additions & 2 deletions lib/ccios/repository_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ def generate(repository_name, options = {})
path: data_new_group_path
)

file_creator = FileCreator.new(options)
file_creator = FileCreator.new(options, @config)
core_target = @parser.core_target
file_creator.create_file(repository_name, 'Repository', core_data_new_group, core_target)

file_creator = FileCreator.new(options)
file_creator = FileCreator.new(options, @config)
data_target = @parser.data_target
file_creator.create_file(repository_name, 'RepositoryImplementation', data_new_group, data_target)

Expand Down
1 change: 0 additions & 1 deletion lib/ccios/templates/repository_implementation.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// Created by {{full_username}} on {{date}}.
//
//
//

import Foundation
import Core
Expand Down
41 changes: 41 additions & 0 deletions templates_library/async/coordinator.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// {{name}}Coordinator.swift
// {{project_name}}
//
// Created by {{full_username}} on {{date}}.
//
//

import Foundation
import ADCoordinator

{{#generate_delegate}}
@MainActor
protocol {{name}}CoordinatorDelegate: AnyObject {
}

{{/generate_delegate}}
@MainActor
class {{name}}Coordinator: Coordinator {
{{#generate_delegate}}
weak var delegate: {{name}}CoordinatorDelegate?
{{/generate_delegate}}
private let dependencyProvider: ApplicationDependencyProvider
private unowned var navigationController: UINavigationController

nonisolated init(navigationController: UINavigationController,
dependencyProvider: ApplicationDependencyProvider) {
self.navigationController = navigationController
self.dependencyProvider = dependencyProvider
}

// MARK: - Public

func start() {
let viewController = UIViewController()
navigationController.pushViewController(viewController, animated: false)
bindToLifecycle(of: viewController)
}
}
14 changes: 14 additions & 0 deletions templates_library/async/dependency_provider.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{{#generate_delegate}}
func {{lowercased_name}}Presenter(viewContract: {{name}}ViewContract, presenterDelegate: {{name}}PresenterDelegate) -> {{name}}Presenter? {
return presenterAssembler
.resolver
.resolve({{name}}Presenter.self, arguments: viewContract, presenterDelegate)
}
{{/generate_delegate}}
{{^generate_delegate}}
func {{lowercased_name}}Presenter(viewContract: {{name}}ViewContract) -> {{name}}Presenter? {
return presenterAssembler
.resolver
.resolve({{name}}Presenter.self, argument: viewContract)
}
{{/generate_delegate}}
13 changes: 13 additions & 0 deletions templates_library/async/interactor.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// {{name}}Interactor.swift
// {{project_name}}
//
// Created by {{full_username}} on {{date}}.
//
//

import Foundation

public protocol {{name}}Interactor {
func execute() async throws
}
5 changes: 5 additions & 0 deletions templates_library/async/interactor_assembly.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
container.register({{name}}Interactor.self) { _ in
{{name}}InteractorImplementation(

)
}
Loading

0 comments on commit 0fa040b

Please sign in to comment.