Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite template system #23

Merged
merged 38 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
333bf61
Implement new templating system to provide more customization of temp…
alexandre-pod Feb 13, 2024
c55723e
Transform existing templates to new format
alexandre-pod Feb 13, 2024
f55e1ac
Allow configuration of which project is used through ccios config file
alexandre-pod Feb 6, 2024
04a15af
Use variables hierarchy for generated element base_path
alexandre-pod Feb 6, 2024
3f01270
Update config to support overrides of variables globally, for a templ…
alexandre-pod Feb 6, 2024
f7046ff
WIP support hierarchical variable management
alexandre-pod Feb 6, 2024
0e0db9c
Use variables mecanism to choose target to use for each file
alexandre-pod Feb 6, 2024
aa45481
Add support for custom collections
alexandre-pod Feb 6, 2024
44250ae
Fix name conflict in code_templater
alexandre-pod Feb 6, 2024
cd23ec9
Make file creator capable of adding file to multiple targets
alexandre-pod Feb 6, 2024
11ffa63
Update README.md
alexandre-pod Feb 13, 2024
4dfe6bb
Update Changelog
alexandre-pod Feb 13, 2024
9ff4452
Fix changelog
alexandre-pod Feb 20, 2024
9804664
Create TemplatesLoader
alexandre-pod Feb 20, 2024
e7464eb
Add missing require
alexandre-pod Feb 20, 2024
e2080ff
Add missing description field to TemplateDefinition
alexandre-pod Feb 20, 2024
0a9f16b
Add tests for templates_loader
alexandre-pod Feb 20, 2024
b10968a
Update tests for config
alexandre-pod Feb 20, 2024
8c224e8
Update test for CodeTemplater
alexandre-pod Feb 20, 2024
f7e81d3
Update test for PBXProjParser
alexandre-pod Feb 20, 2024
5e679fc
Update tests of generated files with or without groups
alexandre-pod Feb 20, 2024
2d49779
Fix template definition parser when no snippets are given
alexandre-pod Feb 20, 2024
ff27fc5
Add missing target definition to Coordinator template
alexandre-pod Feb 20, 2024
e49ff64
Fix snippets for default presenter template
alexandre-pod Feb 20, 2024
cf62cb7
Remove old comment
alexandre-pod Feb 20, 2024
0235946
Remove old test snapshots
alexandre-pod Feb 20, 2024
d9ef67e
Reimplement argument suffix removal
alexandre-pod Feb 20, 2024
b39cfda
Test auto suffix removal
alexandre-pod Feb 20, 2024
f548b17
Update changelog
alexandre-pod Feb 20, 2024
927edf8
Migrate sample async templates to new template system
alexandre-pod Feb 20, 2024
623e87d
Fix presenter snippet for dependency provider
alexandre-pod Feb 23, 2024
6ed096f
Add missing documentation
alexandre-pod Feb 23, 2024
1dce784
Use generic description and names in readme instead of values used in…
alexandre-pod Mar 5, 2024
83cf238
Fix typos in Readme and Changelog
alexandre-pod Mar 5, 2024
fe80bd2
Fix inconsistent naming in presenter template
alexandre-pod Mar 5, 2024
22bfc07
Add missing documentation for code_snippets
alexandre-pod Mar 5, 2024
ec0c2bf
Fix inconsistent naming in async presenter template
alexandre-pod Mar 5, 2024
117d4fc
Fix help message for templates with multiple argument parameters
alexandre-pod Mar 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

This release is an entire rewrite of the templating system, allowing customization of template and settings.

### Added

- New templating system that allows definition of custom templates per project
- A template can now declare multiple CLI arguments and flags
- Generated files can be added to multiple targets
- The base_path group and target can be configured independently for each generated file if needed.
- Add validation that each variable used in a mustache file is provided by the template. The default provided variables are: `filename`, `lowercase_filename`, `project_name`, `full_username` and `date`
- List of known templates is available using `ccios --help`

### Changed

- Default templates has been migrated to the new format
- Configuration file (`.ccios`) format has been changed
- Command line invocation has changed:
- `ccios -p Example [-d]` is now `ccios presenter Example [-d]`
- `ccios -c Example [-d]` is now `ccios coordinator Example [-d]`
- `ccios -i Example [-d]` is now `ccios interactor Example`
- `ccios -r Example [-d]` is now `ccios repository Example`
- Some default provided mustache variables has been renamed:
Nooba marked this conversation as resolved.
Show resolved Hide resolved
- `name` is now `filename`
- `lowercased_name` is now `lowercased_filename`

## [4.1.0]

### Added
Expand Down
240 changes: 184 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,24 @@ To run the tests run:
Go to your `.xcodeproj` folder `cd /paht/to/my/xcodeproj`.
Then generate files with prefix `Example`:

```bash
ccios <template_name> [template_arguments...] [template_options]
```
ccios [-p|-i|-r|-c] Example [-d]

The list of known templates is visible using the following command:
```bash
ccios --help
```

Generated templates can be found [here](https://github.com/felginep/ccios/tree/master/lib/ccios/templates)
Generated templates can be found [here](https://github.com/fabernovel/ccios/tree/master/lib/ccios/templates)

## Default templates

### `presenter`

### `-p`
`-p` stands for `presenter`
```bash
ccios presenter Example [-d]
```

This generates 4 files: `ExampleViewController`, `ExampleViewContract`, `ExamplePresenter`, `ExamplePresenterImplementation`. If the `-d` option is supplied the protocol `ExamplePresenterDelegate` will be generated.

Expand All @@ -51,8 +61,11 @@ The following structure is created for you in the Xcode project:
| | +-- Model/
```

### `-i`
`-i` stands for `interactor`
### `interactor`

```bash
ccios interactor Example
```

This generates 2 files: `ExampleInteractor` and `ExampleInteractorImplementation`.

Expand All @@ -69,8 +82,11 @@ The following structure is created for you in the Xcode project:
| | | +-- ExampleInteractorImplementation
```

### `-r`
`-r` stands for `repository`
### `repository`

```bash
ccios repository Example
```

This generates 2 files: `ExampleRepository` and `ExampleRepositoryImplementation`.

Expand All @@ -89,8 +105,11 @@ The following structure is created for you in the Xcode project:
| | +-- ExampleRepositoryImplementation
```

### `-c`
`-c` stands for `coordinator`
### `coordinator`

```bash
ccios coordinator Example [-d]
```

This generates one file: `ExampleCoordinator`. If the `-d` option is supplied the protocol `ExampleCoordinatorDelegate` will be generated.

Expand All @@ -104,64 +123,173 @@ The following structure is created for you in the Xcode project:

## Configuration


Each project is different. You can configure the groups to use in the xcodeproj for the new files.
Each project is different. You can configure the available templates that can be used
You can configure the groups to use in the xcodeproj for the new files.

Create a file `.ccios.yml` at the root of your project.

By default, if no file is present, the following configuration will be used:
```
app:
project: MyProject.xcodeproj
An empty config file is valid as all properties are optional.

```yml
# Path to an additional collection of templates. [Optional]
# Templates present in this folder will be available. If the collection use the same name as a default template, it will override it.
templates_collection: ccios/templates

# Global overrides of variables [Optional]
variables:
project: Project.xcodeproj

# Per template variables override
templates_config:
# Use the template name (in template.yml) to specify overrides on this template:
TEMPLATE_NAME:
# This overrides the default template variables
variables:
project: "Project.pbxproj"
# You can specify multiple target for generated files.
target:
- SomeTarget
- SomeOtherTarget
- ThirdTarget
# Per element variable override
elements_variables:
# This overrides the default variables for the element named "ELEMENT_NAME_1"
ELEMENT_NAME_1:
base_path: Core/Data
target: Core
ELEMENT_NAME_2:
base_path: Data
target: Data
# Another template variable override
presenter:
group: Classes/App
variables:
base_path: MyProject/App
elements_variables:
repository:
base_path: "Core/Data"
coordinator:
group: Classes/Coordinator

core:
project: MyProject.xcodeproj
interactor:
group: Classes/Core/Interactor
repository:
group: Classes/Core/Data

data:
project: MyProject.xcodeproj
repository:
group: Classes/Data
variables:
base_path: MyProject/Coordinator
```

But you could imagine more complex project structures with multiple xcodeproj:
```
app:
project: MyProject/MyProject.xcodeproj
target: MyProject # optional
presenter:
group: Classes/App
coordinator:
group: Classes/Coordinator
*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.

core:
project: MyProjectCore/MyProjectCore.xcodeproj
target: MyProjectCore # optional
interactor:
group: MyProjectCore/Interactors
repository:
group: MyProjectCore/Repository
## Template definition

data:
project: MyProjectData/MyProjectData.xcodeproj
target: MyProjectData # optional
repository:
group: MyProjectData/Sources/Repositories
```
Default templates can be found [here](https://github.com/fabernovel/ccios/tree/master/lib/ccios/templates), and can be used to see what is possible.

*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.
A template is a folder containing a file `template.yml` next to all templating files that will be used during generation.
Example for the default Interactor template:
```
Interactor/
template.yml
interactor.mustache
interactor_assembly.mustache
interactor_implementation.mustache
```

And lastly you may want to use your own templates, by adding this parameter to the file:
### `template.yml` format

```yml
# name of the template to use in the CLI. [required]
name: "custom_template"
# description of the template. [optional]
description: "Custom template definition"
# List of the parameters that will be given to the file templates. [required]
# The parameters can be used in template files, and in file path.
parameters:
# Use this to represent a string argument parameter in the CLI
# By default the argument will be passed to template renderer under the name "name", to use another name, specify a `template_variable_name`
- argument: "name"
# Description used in the help command. [Optional]
description: "name argument description"
# When present, the argument will be usable in templates under the provided name. [Optional]
template_variable_name: "in_template_variable_name"
# When present, will remove the provided suffix from the argument given. Example "MySuffix" will be tranformed into "My". [Optional]
removeSuffix: "Suffix"
# When present, the lowercased argument will be usable in templates under the provided name. [Optional]
lowercased_variable_name: "name_of_the_lowercased_variable"
# Use this to represent a flag parameter in the CLI, the flag will be provided to templates as `true` when present in the executed command.
- flag: "long_name"
# The short name of this flag to use on CLI. [optional]
short_name: "n"
# Description used in the help command. [Optional]
description: "Generate delegate protocols when provided"
# When present, the argument will be usable in templates under the provided name. [Optional]
template_variable_name: "generate_delegate"
Nooba marked this conversation as resolved.
Show resolved Hide resolved
# List of templates variables that is used to generate files in an xcode project. [Optional]
# Those variables can be overridden in config file, see section "Variable hierarchy" for more informations.
variables:
# The name of the xcode project. "*.xcodeproj" will use the first it finds. [required]
project: "*.xcodeproj"
# The base path used to generate an element. This variable must be defined once here, or on each elements below.
base_path: "path/to/base_group"
# The target in which files are added. Can be a string, a list of strings, or an empty string. This variable must be defined once here, or on each elements below. If an empty string is provided, it will use the first target found in the Xcode project.
target: ""
# List of generated elements. [Required]
# Each element can be a file (using `file`), or an empty folder (using `group`)
generated_elements:
# Path from the `base_path` variable where the file will be generated
- file: "{{ name }}/{{ name }}File.swift"
# This name identify this generated file to allow variable overrides in config file. [Required]
Nooba marked this conversation as resolved.
Show resolved Hide resolved
name: "file"
# The template specify the name of template that will be used from `template_file_source`
Nooba marked this conversation as resolved.
Show resolved Hide resolved
template: "file"
# List of default element variable. [Optional]
variables: {}
# Path from the `base_path` variable where the directory will be generated
- group: "{{ name }}/group"
# This name identify this generated file to allow variable overrides in config file. [Required]
Nooba marked this conversation as resolved.
Show resolved Hide resolved
name: "group"
# List of default element variable. [Optional]
variables:
- base_path: "path/override/to/base_group"
# List of code snippets that will be printer by the CLI after the generation of files. [Optional]
Nooba marked this conversation as resolved.
Show resolved Hide resolved
code_snippets:
- name: InteractorAssembly
template: "file_snippets"
# List of templating files used for element generation or code snippets. [Required]
# The key is used as an identifier in `generated_elements` or `code_snippets`, the value is the path from the template directory.
template_file_source:
file: "file.mustache"
file_snippets: "file_snippets.mustache"
```
templates:
path: Path/To/Users/Templates

### Variable hierarchy

In `template.yml`
```yml
# [...]
variables:
# -> Default templates variables
generated_elements:
- name: element_name
# [...]
variables:
# -> Default Element variables
```

In `.ccios.yml`
```yml
variables:
# -> Config Global variables
templates_config:
repository:
variables:
# -> Config Template variables
element_variables:
element_name:
# -> Config Element variables
```

Templates will use variables in this order (first in this list is used):
- Config Template variables
- Default templates variables
- Config Global variables

Element will use variables in this order (first in this list is used): (For files, groups and code snippets)
- Config Element variables
- Default Element variables
- Config Template variables
- Default templates variables
- Config Global variables
Loading