refactor: Adapt to new repository

This commit is contained in:
T. R. Bernstein
2025-09-30 18:48:15 +02:00
parent 17af3bace1
commit 6811c71bd6
66 changed files with 224 additions and 622 deletions

View File

@@ -2,7 +2,8 @@ name: Danger
on: on:
push: push:
branches: master branches:
- main
pull_request: pull_request:
jobs: jobs:
@@ -10,10 +11,10 @@ jobs:
name: Danger Check name: Danger Check
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Setup Ruby name: Setup Ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:

View File

@@ -2,7 +2,8 @@ name: Lint Cocoapods
on: on:
push: push:
branches: master branches:
- main
pull_request: pull_request:
jobs: jobs:
@@ -10,10 +11,10 @@ jobs:
name: Pod Lint name: Pod Lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Setup Ruby name: Setup Ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:

View File

@@ -2,7 +2,8 @@ name: SwiftLint
on: on:
push: push:
branches: master branches:
- main
pull_request: pull_request:
jobs: jobs:
@@ -10,10 +11,10 @@ jobs:
name: SwiftLint name: SwiftLint
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Setup Ruby name: Setup Ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:

View File

@@ -7,24 +7,6 @@ on:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
cocoapods:
name: Push To CocoaPods
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
-
name: Push to CocoaPods
run: bundle exec rake release:cocoapods
env:
COCOAPODS_TRUNK_TOKEN: ${{secrets.COCOAPODS_TRUNK_TOKEN}}
github: github:
name: GitHub Release name: GitHub Release
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -2,7 +2,8 @@ name: Test SPM
on: on:
push: push:
branches: master branches:
- main
pull_request: pull_request:
jobs: jobs:
@@ -11,10 +12,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: swiftgen/swift:5.6 container: swiftgen/swift:5.6
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
# Note: we can't use `ruby/setup-ruby` on custom docker images, so we # Note: we can't use `ruby/setup-ruby` on custom docker images, so we
# have to do our own caching # have to do our own caching
name: Cache gems name: Cache gems
@@ -24,7 +25,7 @@ jobs:
key: ${{ runner.os }}-gems-${{ hashFiles('Gemfile.lock') }} key: ${{ runner.os }}-gems-${{ hashFiles('Gemfile.lock') }}
restore-keys: | restore-keys: |
${{ runner.os }}-gems- ${{ runner.os }}-gems-
- -
name: Cache SPM name: Cache SPM
uses: actions/cache@v3 uses: actions/cache@v3
with: with:
@@ -45,15 +46,15 @@ jobs:
name: Test SPM macOS name: Test SPM macOS
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Setup Ruby name: Setup Ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:
bundler-cache: true bundler-cache: true
- -
name: Cache SPM name: Cache SPM
uses: actions/cache@v3 uses: actions/cache@v3
with: with:

View File

@@ -1,4 +1,4 @@
swiftlint_version: 0.48.0 swiftlint_version: 0.61.0
opt_in_rules: opt_in_rules:
- accessibility_label_for_image - accessibility_label_for_image
@@ -104,14 +104,6 @@ closure_body_length:
conditional_returns_on_newline: conditional_returns_on_newline:
if_only: true if_only: true
file_header:
required_pattern: |
\/\/
\/\/ Stencil
\/\/ Copyright © 2022 Stencil
\/\/ MIT Licence
\/\/
indentation_width: indentation_width:
indentation_width: 2 indentation_width: 2

View File

@@ -2,7 +2,7 @@
### Enhancements ### Enhancements
- Prefer `DynamicMemberLookup` over KVC. - Prefer `DynamicMemberLookup` over KVC.
[##342](https://github.com/stencilproject/Stencil/pull/342) [##342](https://github.com/stencilproject/Stencil/pull/342)
[@art-divin](https://github.com/art-divin) [@art-divin](https://github.com/art-divin)
@@ -10,7 +10,7 @@
### Bug Fixes ### Bug Fixes
- Fix bug in `LazyValueWrapper`, causing it to never resolve. - Fix bug in `LazyValueWrapper`, causing it to never resolve.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#328](https://github.com/stencilproject/Stencil/pull/328) [#328](https://github.com/stencilproject/Stencil/pull/328)
@@ -18,59 +18,59 @@
### Breaking ### Breaking
- Drop support for Swift < 5. For Swift 4.2 support, you should use Stencil 0.14.2. - Drop support for Swift < 5. For Swift 4.2 support, you should use Stencil 0.14.2.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#323](https://github.com/stencilproject/Stencil/pull/323) [#323](https://github.com/stencilproject/Stencil/pull/323)
### Enhancements ### Enhancements
- Added support for trimming whitespace around blocks with Jinja2 whitespace control symbols. eg `{%- if value +%}`. - Added support for trimming whitespace around blocks with Jinja2 whitespace control symbols. eg `{%- if value +%}`.
[Miguel Bejar](https://github.com/bejar37) [Miguel Bejar](https://github.com/bejar37)
[Yonas Kolb](https://github.com/yonaskolb) [Yonas Kolb](https://github.com/yonaskolb)
[#92](https://github.com/stencilproject/Stencil/pull/92) [#92](https://github.com/stencilproject/Stencil/pull/92)
[#287](https://github.com/stencilproject/Stencil/pull/287) [#287](https://github.com/stencilproject/Stencil/pull/287)
- Added support for adding default whitespace trimming behaviour to an environment. - Added support for adding default whitespace trimming behaviour to an environment.
[Yonas Kolb](https://github.com/yonaskolb) [Yonas Kolb](https://github.com/yonaskolb)
[#287](https://github.com/stencilproject/Stencil/pull/287) [#287](https://github.com/stencilproject/Stencil/pull/287)
- Blocks now can be used repeatedly in the template. When block is rendered for the first time its content will be cached and it can be rendered again later using `{{ block.block_name }}`. - Blocks now can be used repeatedly in the template. When block is rendered for the first time its content will be cached and it can be rendered again later using `{{ block.block_name }}`.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#158](https://github.com/stencilproject/Stencil/issues/158) [#158](https://github.com/stencilproject/Stencil/issues/158)
[#182](https://github.com/stencilproject/Stencil/pull/182) [#182](https://github.com/stencilproject/Stencil/pull/182)
- Added `break` and `continue` tags to break or continue current loop. - Added `break` and `continue` tags to break or continue current loop.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#175](https://github.com/stencilproject/Stencil/pull/175) [#175](https://github.com/stencilproject/Stencil/pull/175)
- You can now access outer loop's scope by labeling it: `{% outer: for ... %}... {% for ... %} {{ outer.counter }} {% endfor %}{% endfor %}`. - You can now access outer loop's scope by labeling it: `{% outer: for ... %}... {% for ... %} {{ outer.counter }} {% endfor %}{% endfor %}`.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#175](https://github.com/stencilproject/Stencil/pull/175) [#175](https://github.com/stencilproject/Stencil/pull/175)
- Boolean expressions can now be rendered, i.e `{{ name == "John" }}` will render `true` or `false` depending on the evaluation result. - Boolean expressions can now be rendered, i.e `{{ name == "John" }}` will render `true` or `false` depending on the evaluation result.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#164](https://github.com/stencilproject/Stencil/pull/164) [#164](https://github.com/stencilproject/Stencil/pull/164)
[#325](https://github.com/stencilproject/Stencil/pull/325) [#325](https://github.com/stencilproject/Stencil/pull/325)
- Enable dynamic member lookup using a new `DynamicMemberLookup` marker protocol. Conform your own types to this protocol to support dynamic member from with contexts. - Enable dynamic member lookup using a new `DynamicMemberLookup` marker protocol. Conform your own types to this protocol to support dynamic member from with contexts.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#219](https://github.com/stencilproject/Stencil/issues/219) [#219](https://github.com/stencilproject/Stencil/issues/219)
[#246](https://github.com/stencilproject/Stencil/pull/246) [#246](https://github.com/stencilproject/Stencil/pull/246)
- Allow providing lazily evaluated context data, using the `LazyValueWrapper` structure. - Allow providing lazily evaluated context data, using the `LazyValueWrapper` structure.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#324](https://github.com/stencilproject/Stencil/pull/324) [#324](https://github.com/stencilproject/Stencil/pull/324)
### Bug Fixes ### Bug Fixes
- Fixed using `{{ block.super }}` inside nodes other than `block`. - Fixed using `{{ block.super }}` inside nodes other than `block`.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#266](https://github.com/stencilproject/Stencil/issues/266) [#266](https://github.com/stencilproject/Stencil/issues/266)
[#267](https://github.com/stencilproject/Stencil/pull/267) [#267](https://github.com/stencilproject/Stencil/pull/267)
### Internal Changes ### Internal Changes
- Updated internal maintenance scripts, and switched to GitHub actions. - Updated internal maintenance scripts, and switched to GitHub actions.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#321](https://github.com/stencilproject/Stencil/pull/321) [#321](https://github.com/stencilproject/Stencil/pull/321)
- Made the `tokens` property on a `Template` public. - Made the `tokens` property on a `Template` public.
[Stefanomondino](https://github.com/stefanomondino) [Stefanomondino](https://github.com/stefanomondino)
[#292](https://github.com/stencilproject/Stencil/pull/292) [#292](https://github.com/stencilproject/Stencil/pull/292)
- Made the `Template.render(_:)` method (that accepts a `Context`) public. - Made the `Template.render(_:)` method (that accepts a `Context`) public.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#322](https://github.com/stencilproject/Stencil/pull/322) [#322](https://github.com/stencilproject/Stencil/pull/322)
@@ -78,7 +78,7 @@
### Internal Changes ### Internal Changes
- Update Spectre (0.10) and PathKit to support Xcode 13. - Update Spectre (0.10) and PathKit to support Xcode 13.
[Astromonkee](https://github.com/astromonkee) [Astromonkee](https://github.com/astromonkee)
[#314](https://github.com/stencilproject/Stencil/pull/314) [#314](https://github.com/stencilproject/Stencil/pull/314)
@@ -86,7 +86,7 @@
### Bug Fixes ### Bug Fixes
- Fix for crashing range indexes when variable length is 1. - Fix for crashing range indexes when variable length is 1.
[Łukasz Kuczborski](https://github.com/lkuczborski) [Łukasz Kuczborski](https://github.com/lkuczborski)
[#306](https://github.com/stencilproject/Stencil/pull/306) [#306](https://github.com/stencilproject/Stencil/pull/306)
@@ -95,35 +95,35 @@
### Breaking ### Breaking
- Drop support for Swift < 4.2. For Swift 4 support, you should use Stencil 0.13.1. - Drop support for Swift < 4.2. For Swift 4 support, you should use Stencil 0.13.1.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#294](https://github.com/stencilproject/Stencil/pull/294) [#294](https://github.com/stencilproject/Stencil/pull/294)
### Enhancements ### Enhancements
- Added support for dynamic filter using `filter` filter. With that you can define a variable with a name of filter - Added support for dynamic filter using `filter` filter. With that you can define a variable with a name of filter
, i.e. `myfilter = "uppercase"` and then use it to invoke this filter with `{{ string|filter:myfilter }}`. , i.e. `myfilter = "uppercase"` and then use it to invoke this filter with `{{ string|filter:myfilter }}`.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#203](https://github.com/stencilproject/Stencil/pull/203) [#203](https://github.com/stencilproject/Stencil/pull/203)
### Bug Fixes ### Bug Fixes
- Fixed using parenthesis in boolean expressions, they now can be used without spaces around them. - Fixed using parenthesis in boolean expressions, they now can be used without spaces around them.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#254](https://github.com/stencilproject/Stencil/pull/254) [#254](https://github.com/stencilproject/Stencil/pull/254)
- Throw syntax error on empty variable tags (`{{ }}`) instead `fatalError`. - Throw syntax error on empty variable tags (`{{ }}`) instead `fatalError`.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#263](https://github.com/stencilproject/Stencil/pull/263) [#263](https://github.com/stencilproject/Stencil/pull/263)
### Internal Changes ### Internal Changes
- `Token` type converted to struct to allow computing token components only once. - `Token` type converted to struct to allow computing token components only once.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#256](https://github.com/stencilproject/Stencil/pull/256) [#256](https://github.com/stencilproject/Stencil/pull/256)
- Added SwiftLint to the project. - Added SwiftLint to the project.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#249](https://github.com/stencilproject/Stencil/pull/249) [#249](https://github.com/stencilproject/Stencil/pull/249)
- Updated to Swift 5. - Updated to Swift 5.
[Jungwon An](https://github.com/kawoou) [Jungwon An](https://github.com/kawoou)
[#268](https://github.com/stencilproject/Stencil/pull/268) [#268](https://github.com/stencilproject/Stencil/pull/268)
@@ -132,7 +132,7 @@
### Bug Fixes ### Bug Fixes
- Fixed a bug in Stencil 0.13 where tags without spaces were incorrectly parsed. - Fixed a bug in Stencil 0.13 where tags without spaces were incorrectly parsed.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#252](https://github.com/stencilproject/Stencil/pull/252) [#252](https://github.com/stencilproject/Stencil/pull/252)
@@ -141,46 +141,46 @@
### Breaking ### Breaking
- Now requires Swift 4.1 or newer. - Now requires Swift 4.1 or newer.
[Yonas Kolb](https://github.com/yonaskolb) [Yonas Kolb](https://github.com/yonaskolb)
[#228](https://github.com/stencilproject/Stencil/pull/228) [#228](https://github.com/stencilproject/Stencil/pull/228)
### Enhancements ### Enhancements
- You can now use parentheses in boolean expressions to change operator precedence. - You can now use parentheses in boolean expressions to change operator precedence.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#165](https://github.com/stencilproject/Stencil/pull/165) [#165](https://github.com/stencilproject/Stencil/pull/165)
- Added method to add boolean filters with their negative counterparts. - Added method to add boolean filters with their negative counterparts.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#160](https://github.com/stencilproject/Stencil/pull/160) [#160](https://github.com/stencilproject/Stencil/pull/160)
- Now you can conditionally render variables with `{{ variable if condition }}`, which is a shorthand for `{% if condition %}{{ variable }}{% endif %}`. You can also use `else` like `{{ variable1 if condition else variable2 }}`, which is a shorthand for `{% if condition %}{{ variable1 }}{% else %}{{ variable2 }}{% endif %}` - Now you can conditionally render variables with `{{ variable if condition }}`, which is a shorthand for `{% if condition %}{{ variable }}{% endif %}`. You can also use `else` like `{{ variable1 if condition else variable2 }}`, which is a shorthand for `{% if condition %}{{ variable1 }}{% else %}{{ variable2 }}{% endif %}`
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#243](https://github.com/stencilproject/Stencil/pull/243) [#243](https://github.com/stencilproject/Stencil/pull/243)
- Now you can access string characters by index or get string length the same was as if it was an array, i.e. `{{ 'string'.first }}`, `{{ 'string'.last }}`, `{{ 'string'.1 }}`, `{{ 'string'.count }}`. - Now you can access string characters by index or get string length the same was as if it was an array, i.e. `{{ 'string'.first }}`, `{{ 'string'.last }}`, `{{ 'string'.1 }}`, `{{ 'string'.count }}`.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#245](https://github.com/stencilproject/Stencil/pull/245) [#245](https://github.com/stencilproject/Stencil/pull/245)
### Bug Fixes ### Bug Fixes
- Fixed the performance issues introduced in Stencil 0.12 with the error log improvements. - Fixed the performance issues introduced in Stencil 0.12 with the error log improvements.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#230](https://github.com/stencilproject/Stencil/pull/230) [#230](https://github.com/stencilproject/Stencil/pull/230)
- Now accessing undefined keys in NSObject does not cause runtime crash and instead renders empty string. - Now accessing undefined keys in NSObject does not cause runtime crash and instead renders empty string.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#234](https://github.com/stencilproject/Stencil/pull/234) [#234](https://github.com/stencilproject/Stencil/pull/234)
- `for` tag: When iterating over a dictionary the keys will now always be sorted (in an ascending order) to ensure consistent output generation. - `for` tag: When iterating over a dictionary the keys will now always be sorted (in an ascending order) to ensure consistent output generation.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#240](https://github.com/stencilproject/Stencil/pull/240) [#240](https://github.com/stencilproject/Stencil/pull/240)
### Internal Changes ### Internal Changes
- Updated the codebase to use Swift 4 features. - Updated the codebase to use Swift 4 features.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#239](https://github.com/stencilproject/Stencil/pull/239) [#239](https://github.com/stencilproject/Stencil/pull/239)
- Update to Spectre 0.9.0. - Update to Spectre 0.9.0.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#247](https://github.com/stencilproject/Stencil/pull/247) [#247](https://github.com/stencilproject/Stencil/pull/247)
- Optimise Scanner performance. - Optimise Scanner performance.
[Eric Thorpe](https://github.com/trametheka) [Eric Thorpe](https://github.com/trametheka)
[Sébastien Duperron](https://github.com/Liquidsoul) [Sébastien Duperron](https://github.com/Liquidsoul)
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
@@ -191,7 +191,7 @@
### Internal Changes ### Internal Changes
- Updated the PathKit dependency to 0.9.0 in CocoaPods, to be in line with SPM. - Updated the PathKit dependency to 0.9.0 in CocoaPods, to be in line with SPM.
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#227](https://github.com/stencilproject/Stencil/pull/227) [#227](https://github.com/stencilproject/Stencil/pull/227)
@@ -200,23 +200,23 @@
### Enhancements ### Enhancements
- Added an optional second parameter to the `include` tag for passing a sub context to the included file. - Added an optional second parameter to the `include` tag for passing a sub context to the included file.
[Yonas Kolb](https://github.com/yonaskolb) [Yonas Kolb](https://github.com/yonaskolb)
[#214](https://github.com/stencilproject/Stencil/pull/214) [#214](https://github.com/stencilproject/Stencil/pull/214)
- Variables now support the subscript notation. For example, if you have a variable `key = "name"`, and an - Variables now support the subscript notation. For example, if you have a variable `key = "name"`, and an
object `item = ["name": "John"]`, then `{{ item[key] }}` will evaluate to "John". object `item = ["name": "John"]`, then `{{ item[key] }}` will evaluate to "John".
[David Jennes](https://github.com/djbe) [David Jennes](https://github.com/djbe)
[#215](https://github.com/stencilproject/Stencil/pull/215) [#215](https://github.com/stencilproject/Stencil/pull/215)
- Adds support for using spaces in filter expression. - Adds support for using spaces in filter expression.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#178](https://github.com/stencilproject/Stencil/pull/178) [#178](https://github.com/stencilproject/Stencil/pull/178)
- Improvements in error reporting. - Improvements in error reporting.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#167](https://github.com/stencilproject/Stencil/pull/167) [#167](https://github.com/stencilproject/Stencil/pull/167)
### Bug Fixes ### Bug Fixes
- Fixed using quote as a filter parameter. - Fixed using quote as a filter parameter.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#210](https://github.com/stencilproject/Stencil/pull/210) [#210](https://github.com/stencilproject/Stencil/pull/210)
@@ -225,62 +225,62 @@
### Enhancements ### Enhancements
- Added support for resolving superclass properties for not-NSObject subclasses. - Added support for resolving superclass properties for not-NSObject subclasses.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#152](https://github.com/stencilproject/Stencil/pull/152) [#152](https://github.com/stencilproject/Stencil/pull/152)
- The `{% for %}` tag can now iterate over tuples, structures and classes via - The `{% for %}` tag can now iterate over tuples, structures and classes via
their stored properties. their stored properties.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#173](https://github.com/stencilproject/Stencil/pull/173) [#173](https://github.com/stencilproject/Stencil/pull/173)
- Added `split` filter. - Added `split` filter.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#187](https://github.com/stencilproject/Stencil/pull/187) [#187](https://github.com/stencilproject/Stencil/pull/187)
- Allow default string filters to be applied to arrays. - Allow default string filters to be applied to arrays.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#190](https://github.com/stencilproject/Stencil/pull/190) [#190](https://github.com/stencilproject/Stencil/pull/190)
- Similar filters are suggested when unknown filter is used. - Similar filters are suggested when unknown filter is used.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#186](https://github.com/stencilproject/Stencil/pull/186) [#186](https://github.com/stencilproject/Stencil/pull/186)
- Added `indent` filter. - Added `indent` filter.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#188](https://github.com/stencilproject/Stencil/pull/188) [#188](https://github.com/stencilproject/Stencil/pull/188)
- Allow using new lines inside tags. - Allow using new lines inside tags.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#202](https://github.com/stencilproject/Stencil/pull/202) [#202](https://github.com/stencilproject/Stencil/pull/202)
- Added support for iterating arrays of tuples. - Added support for iterating arrays of tuples.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#177](https://github.com/stencilproject/Stencil/pull/177) [#177](https://github.com/stencilproject/Stencil/pull/177)
- Added support for ranges in if-in expression. - Added support for ranges in if-in expression.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#193](https://github.com/stencilproject/Stencil/pull/193) [#193](https://github.com/stencilproject/Stencil/pull/193)
- Added property `forloop.length` to get number of items in the loop. - Added property `forloop.length` to get number of items in the loop.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#171](https://github.com/stencilproject/Stencil/pull/171) [#171](https://github.com/stencilproject/Stencil/pull/171)
- Now you can construct ranges for loops using `a...b` syntax, i.e. `for i in 1...array.count`. - Now you can construct ranges for loops using `a...b` syntax, i.e. `for i in 1...array.count`.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#192](https://github.com/stencilproject/Stencil/pull/192) [#192](https://github.com/stencilproject/Stencil/pull/192)
### Bug Fixes ### Bug Fixes
- Fixed rendering `{{ block.super }}` with several levels of inheritance. - Fixed rendering `{{ block.super }}` with several levels of inheritance.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#154](https://github.com/stencilproject/Stencil/pull/154) [#154](https://github.com/stencilproject/Stencil/pull/154)
- Fixed checking dictionary values for nil in `default` filter. - Fixed checking dictionary values for nil in `default` filter.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#162](https://github.com/stencilproject/Stencil/pull/162) [#162](https://github.com/stencilproject/Stencil/pull/162)
- Fixed comparing string variables with string literals, in Swift 4 string literals became `Substring` and thus couldn't be directly compared to strings. - Fixed comparing string variables with string literals, in Swift 4 string literals became `Substring` and thus couldn't be directly compared to strings.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#168](https://github.com/stencilproject/Stencil/pull/168) [#168](https://github.com/stencilproject/Stencil/pull/168)
- Integer literals now resolve into Int values, not Float. - Integer literals now resolve into Int values, not Float.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#181](https://github.com/stencilproject/Stencil/pull/181) [#181](https://github.com/stencilproject/Stencil/pull/181)
- Fixed accessing properties of optional properties via reflection. - Fixed accessing properties of optional properties via reflection.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#204](https://github.com/stencilproject/Stencil/pull/204) [#204](https://github.com/stencilproject/Stencil/pull/204)
- No longer render optional values in arrays as `Optional(..)`. - No longer render optional values in arrays as `Optional(..)`.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#205](https://github.com/stencilproject/Stencil/pull/205) [#205](https://github.com/stencilproject/Stencil/pull/205)
- Fixed subscription tuples by value index, i.e. `{{ tuple.0 }}`. - Fixed subscription tuples by value index, i.e. `{{ tuple.0 }}`.
[Ilya Puchka](https://github.com/ilyapuchka) [Ilya Puchka](https://github.com/ilyapuchka)
[#172](https://github.com/stencilproject/Stencil/pull/172) [#172](https://github.com/stencilproject/Stencil/pull/172)
@@ -483,10 +483,10 @@
### Bug Fixes ### Bug Fixes
- Variables (`{{ variable.5 }}`) that reference an array index at an unknown - Variables (`{{ variable.5 }}`) that reference an array index at an unknown
index will now resolve to `nil` instead of causing a crash. index will now resolve to `nil` instead of causing a crash.
[#72](https://github.com/stencilproject/Stencil/issues/72) [#72](https://github.com/stencilproject/Stencil/issues/72)
- Templates can now extend templates that extend other templates. - Templates can now extend templates that extend other templates.
[#60](https://github.com/stencilproject/Stencil/issues/60) [#60](https://github.com/stencilproject/Stencil/issues/60)
- If comparisons will now treat 0 and below numbers as negative. - If comparisons will now treat 0 and below numbers as negative.

View File

@@ -4,13 +4,13 @@ source 'https://rubygems.org'
# The bare minimum for building, e.g. in Homebrew # The bare minimum for building, e.g. in Homebrew
group :build do group :build do
gem 'base64', '~> 0.3'
gem 'rake', '~> 13.0' gem 'rake', '~> 13.0'
gem 'xcpretty', '~> 0.3' gem 'xcpretty', '~> 0.3'
end end
# In addition to :build, for contributing # In addition to :build, for contributing
group :development do group :development do
gem 'cocoapods', '~> 1.11'
gem 'danger', '~> 8.4' gem 'danger', '~> 8.4'
gem 'rubocop', '~> 1.22' gem 'rubocop', '~> 1.22'
end end

View File

@@ -1,65 +1,16 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
CFPropertyList (3.0.5) addressable (2.8.7)
rexml public_suffix (>= 2.0.2, < 7.0)
activesupport (6.1.6.1) ast (2.4.3)
concurrent-ruby (~> 1.0, >= 1.0.2) base64 (0.3.0)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
ast (2.4.2)
atomos (0.1.3)
claide (1.1.0) claide (1.1.0)
claide-plugins (0.9.2) claide-plugins (0.9.2)
cork cork
nap nap
open4 (~> 1.3) open4 (~> 1.3)
cocoapods (1.11.3)
addressable (~> 2.8)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.11.3)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.4.0, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.8.0)
nap (~> 1.0)
ruby-macho (>= 1.0, < 3.0)
xcodeproj (>= 1.21.0, < 2.0)
cocoapods-core (1.11.3)
activesupport (>= 5.0, < 7)
addressable (~> 2.8)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
netrc (~> 0.11)
public_suffix (~> 4.0)
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.5)
cocoapods-downloader (1.6.3)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.1)
cocoapods-trunk (1.6.0)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored2 (3.1.2) colored2 (3.1.2)
concurrent-ruby (1.1.10)
cork (0.3.0) cork (0.3.0)
colored2 (~> 3.1) colored2 (~> 3.1)
danger (8.6.1) danger (8.6.1)
@@ -75,10 +26,7 @@ GEM
no_proxy_fix no_proxy_fix
octokit (~> 4.7) octokit (~> 4.7)
terminal-table (>= 1, < 4) terminal-table (>= 1, < 4)
escape (0.0.4) faraday (1.10.4)
ethon (0.15.0)
ffi (>= 1.15.0)
faraday (1.10.0)
faraday-em_http (~> 1.0) faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0) faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1) faraday-excon (~> 1.1)
@@ -91,94 +39,89 @@ GEM
faraday-retry (~> 1.0) faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4) ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0) faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0) faraday-em_synchrony (1.0.1)
faraday-excon (1.1.0) faraday-excon (1.1.0)
faraday-http-cache (2.4.0) faraday-http-cache (2.5.1)
faraday (>= 0.8) faraday (>= 0.8)
faraday-httpclient (1.0.1) faraday-httpclient (1.0.1)
faraday-multipart (1.0.4) faraday-multipart (1.1.1)
multipart-post (~> 2) multipart-post (~> 2.0)
faraday-net_http (1.0.1) faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0) faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0) faraday-patron (1.0.0)
faraday-rack (1.0.0) faraday-rack (1.0.0)
faraday-retry (1.0.3) faraday-retry (1.0.3)
ffi (1.15.5) git (1.19.1)
fourflusher (2.3.1) addressable (~> 2.8)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
git (1.11.0)
rchardet (~> 1.8) rchardet (~> 1.8)
httpclient (2.8.3) json (2.15.0)
i18n (1.12.0) kramdown (2.5.1)
concurrent-ruby (~> 1.0) rexml (>= 3.3.9)
json (2.6.2)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0) kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0) kramdown (~> 2.0)
minitest (5.16.2) language_server-protocol (3.17.0.5)
molinillo (0.8.0) lint_roller (1.1.0)
multipart-post (2.2.3) multipart-post (2.4.1)
nanaimo (0.3.0)
nap (1.1.0) nap (1.1.0)
netrc (0.11.0)
no_proxy_fix (0.1.2) no_proxy_fix (0.1.2)
octokit (4.25.1) octokit (4.25.1)
faraday (>= 1, < 3) faraday (>= 1, < 3)
sawyer (~> 0.9) sawyer (~> 0.9)
open4 (1.3.4) open4 (1.3.4)
parallel (1.22.1) parallel (1.27.0)
parser (3.1.2.0) parser (3.3.9.0)
ast (~> 2.4.1) ast (~> 2.4.1)
racc
prism (1.5.1)
public_suffix (4.0.7) public_suffix (4.0.7)
racc (1.8.1)
rainbow (3.1.1) rainbow (3.1.1)
rake (13.0.6) rake (13.3.0)
rchardet (1.8.0) rchardet (1.10.0)
regexp_parser (2.5.0) regexp_parser (2.11.3)
rexml (3.2.5) rexml (3.4.4)
rouge (2.0.7) rouge (3.28.0)
rubocop (1.32.0) rubocop (1.81.1)
json (~> 2.3) json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 3.1.0.0) parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0) regexp_parser (>= 2.9.3, < 3.0)
rexml (>= 3.2.5, < 4.0) rubocop-ast (>= 1.47.1, < 2.0)
rubocop-ast (>= 1.19.1, < 2.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0) unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.19.1) rubocop-ast (1.47.1)
parser (>= 3.1.1.0) parser (>= 3.3.7.2)
ruby-macho (2.5.1) prism (~> 1.4)
ruby-progressbar (1.11.0) ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5) ruby2_keywords (0.0.5)
sawyer (0.9.2) sawyer (0.9.2)
addressable (>= 2.3.5) addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3) faraday (>= 0.17.3, < 3)
terminal-table (3.0.2) terminal-table (1.6.0)
unicode-display_width (>= 1.1.1, < 3) unicode-display_width (3.2.0)
typhoeus (1.4.0) unicode-emoji (~> 4.1)
ethon (>= 0.9.0) unicode-emoji (4.1.0)
tzinfo (2.0.5) xcpretty (0.4.1)
concurrent-ruby (~> 1.0) rouge (~> 3.28.0)
unicode-display_width (2.2.0)
xcodeproj (1.22.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
xcpretty (0.3.0)
rouge (~> 2.0.7)
zeitwerk (2.6.0)
PLATFORMS PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
ruby ruby
x86-linux-gnu
x86-linux-musl
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES DEPENDENCIES
cocoapods (~> 1.11) base64 (~> 0.3)
danger (~> 8.4) danger (~> 8.4)
octokit (~> 4.7) octokit (~> 4.7)
rake (~> 13.0) rake (~> 13.0)
@@ -186,4 +129,4 @@ DEPENDENCIES
xcpretty (~> 0.3) xcpretty (~> 0.3)
BUNDLED WITH BUNDLED WITH
2.2.33 2.7.2

View File

@@ -1,4 +1,5 @@
Copyright (c) 2022, Kyle Fuller Copyright (c) 2022, Kyle Fuller as the original author
Copyright (c) 2025, Astzweig GmbH & Co. KG
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -1,15 +1,6 @@
{ {
"object": { "object": {
"pins": [ "pins": [
{
"package": "PathKit",
"repositoryURL": "https://github.com/kylef/PathKit.git",
"state": {
"branch": null,
"revision": "3bfd2737b700b9a36565a8c94f4ad2b050a5e574",
"version": "1.0.1"
}
},
{ {
"package": "Spectre", "package": "Spectre",
"repositoryURL": "https://github.com/kylef/Spectre.git", "repositoryURL": "https://github.com/kylef/Spectre.git",
@@ -18,6 +9,15 @@
"revision": "26cc5e9ae0947092c7139ef7ba612e34646086c7", "revision": "26cc5e9ae0947092c7139ef7ba612e34646086c7",
"version": "0.10.1" "version": "0.10.1"
} }
},
{
"package": "swiftpm-pathkit",
"repositoryURL": "https://github.com/astzweig/swiftpm-pathkit.git",
"state": {
"branch": null,
"revision": "5d164c34f35fa7241d77357e965acde80efcb6d9",
"version": "1.5.0"
}
} }
] ]
}, },

View File

@@ -7,7 +7,7 @@ let package = Package(
.library(name: "Stencil", targets: ["Stencil"]) .library(name: "Stencil", targets: ["Stencil"])
], ],
dependencies: [ dependencies: [
.package(url: "https://github.com/kylef/PathKit.git", from: "1.0.1"), .package(url: "https://github.com/astzweig/swiftpm-pathkit.git", from: "1.5.0"),
.package(url: "https://github.com/kylef/Spectre.git", from: "0.10.1") .package(url: "https://github.com/kylef/Spectre.git", from: "0.10.1")
], ],
targets: [ targets: [

View File

@@ -34,9 +34,7 @@ namespace :files do
) )
docs_package = Utils.first_match_in_file('docs/installation.rst', /\.package\(url: .+ from: "(.+)"/, 1) docs_package = Utils.first_match_in_file('docs/installation.rst', /\.package\(url: .+ from: "(.+)"/, 1)
replace("docs/installation.rst", replace("docs/installation.rst",
/\.package\(url: .+, from: "(.+)"/ => %Q(.package\(url: "https://github.com/stencilproject/Stencil.git", from: "#{version}"), /\.package\(url: .+, from: "(.+)"/ => %Q(.package\(url: "https://github.com/swiftstencil/swiftpm-stencil.git", from: "#{version}")
/pod 'Stencil', '.*'/ => %Q(pod 'Stencil', '~> #{version}'),
/github "stencilproject\/Stencil" ~> .*/ => %Q(github "stencilproject/Stencil" ~> #{version})
) )
end end

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
/// A container for template variables. /// A container for template variables.
public class Context { public class Context {
var dictionaries: [[String: Any?]] var dictionaries: [[String: Any?]]
@@ -61,6 +55,7 @@ public class Context {
/// Pop the last level off of the Context /// Pop the last level off of the Context
/// ///
/// - returns: The popped level /// - returns: The popped level
// swiftlint:disable:next discouraged_optional_collection
fileprivate func pop() -> [String: Any?]? { fileprivate func pop() -> [String: Any?]? {
dictionaries.popLast() dictionaries.popLast()
} }
@@ -78,7 +73,7 @@ public class Context {
} }
/// Flatten all levels of context data into 1, merging duplicate variables /// Flatten all levels of context data into 1, merging duplicate variables
/// ///
/// - returns: All collected variables /// - returns: All collected variables
public func flatten() -> [String: Any] { public func flatten() -> [String: Any] {
var accumulator: [String: Any] = [:] var accumulator: [String: Any] = [:]

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
/// Marker protocol so we can know which types support `@dynamicMemberLookup`. Add this to your own types that support /// Marker protocol so we can know which types support `@dynamicMemberLookup`. Add this to your own types that support
/// lookup by String. /// lookup by String.
public protocol DynamicMemberLookup { public protocol DynamicMemberLookup {

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
/// Container for environment data, such as registered extensions /// Container for environment data, such as registered extensions
public struct Environment { public struct Environment {
/// The class for loading new templates /// The class for loading new templates

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
public class TemplateDoesNotExist: Error, CustomStringConvertible { public class TemplateDoesNotExist: Error, CustomStringConvertible {
let templateNames: [String] let templateNames: [String]
let loader: Loader? let loader: Loader?

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
public protocol Expression: CustomStringConvertible, Resolvable { public protocol Expression: CustomStringConvertible, Resolvable {
func evaluate(context: Context) throws -> Bool func evaluate(context: Context) throws -> Bool
} }

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
/// Container for registered tags and filters /// Container for registered tags and filters
open class Extension { open class Extension {
typealias TagParser = (TokenParser, Token) throws -> NodeType typealias TagParser = (TokenParser, Token) throws -> NodeType

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
class FilterNode: NodeType { class FilterNode: NodeType {
let resolvable: Resolvable let resolvable: Resolvable
let nodes: [NodeType] let nodes: [NodeType]

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
func capitalise(_ value: Any?) -> Any? { func capitalise(_ value: Any?) -> Any? {
if let array = value as? [Any?] { if let array = value as? [Any?] {
return array.map { stringify($0).capitalized } return array.map { stringify($0).capitalized }

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation import Foundation
class ForNode: NodeType { class ForNode: NodeType {
@@ -231,7 +225,7 @@ struct LoopTerminationNode: NodeType {
self.token = token self.token = token
} }
static func parse(_ parser: TokenParser, token: Token) throws -> LoopTerminationNode { static func parse(_ parser: TokenParser, token: Token) throws -> Self {
let components = token.components let components = token.components
guard components.count <= 2 else { guard components.count <= 2 else {
@@ -241,7 +235,7 @@ struct LoopTerminationNode: NodeType {
throw TemplateSyntaxError("'\(token.contents)' can be used only inside loop body") throw TemplateSyntaxError("'\(token.contents)' can be used only inside loop body")
} }
return LoopTerminationNode(name: components[0], label: components.count == 2 ? components[1] : nil, token: token) return Self(name: components[0], label: components.count == 2 ? components[1] : nil, token: token)
} }
func render(_ context: Context) throws -> String { func render(_ context: Context) throws -> String {

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
enum Operator { enum Operator {
case infix(String, Int, InfixOperator.Type) case infix(String, Int, InfixOperator.Type)
case prefix(String, Int, PrefixOperator.Type) case prefix(String, Int, PrefixOperator.Type)
@@ -17,7 +11,7 @@ enum Operator {
} }
} }
static let all: [Operator] = [ static let all: [Self] = [
.infix("in", 5, InExpression.self), .infix("in", 5, InExpression.self),
.infix("or", 6, OrExpression.self), .infix("or", 6, OrExpression.self),
.infix("and", 7, AndExpression.self), .infix("and", 7, AndExpression.self),
@@ -118,6 +112,7 @@ final class IfExpressionParser {
private init(components: ArraySlice<String>, environment: Environment, token: Token) throws { private init(components: ArraySlice<String>, environment: Environment, token: Token) throws {
var parsedComponents = Set<Int>() var parsedComponents = Set<Int>()
var bracketsBalance = 0 var bracketsBalance = 0
// swiftlint:disable:next closure_body_length
self.tokens = try zip(components.indices, components).compactMap { index, component in self.tokens = try zip(components.indices, components).compactMap { index, component in
guard !parsedComponents.contains(index) else { return nil } guard !parsedComponents.contains(index) else { return nil }

View File

@@ -1,11 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit
class IncludeNode: NodeType { class IncludeNode: NodeType {
let templateName: Variable let templateName: Variable
let includeContext: String? let includeContext: String?

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
class BlockContext { class BlockContext {
class var contextKey: String { "block_context" } class var contextKey: String { "block_context" }
@@ -62,7 +56,7 @@ class ExtendsNode: NodeType {
} }
let parsedNodes = try parser.parse() let parsedNodes = try parser.parse()
guard (parsedNodes.any { $0 is ExtendsNode }) == nil else { guard (parsedNodes.any { $0 is Self }) == nil else {
throw TemplateSyntaxError("'extends' cannot appear more than once in the same template") throw TemplateSyntaxError("'extends' cannot appear more than once in the same template")
} }

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation import Foundation
/// A structure used to represent a template variable, and to resolve it in a given context. /// A structure used to represent a template variable, and to resolve it in a given context.

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
/// Used to lazily set context data. Useful for example if you have some data that requires heavy calculations, and may /// Used to lazily set context data. Useful for example if you have some data that requires heavy calculations, and may
/// not be used in every render possiblity. /// not be used in every render possiblity.
public final class LazyValueWrapper { public final class LazyValueWrapper {

View File

@@ -1,12 +1,10 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation import Foundation
// swiftlint:disable large_tuple
typealias Line = (content: String, number: UInt, range: Range<String.Index>) typealias Line = (content: String, number: UInt, range: Range<String.Index>)
/// Location in some content (text)
public typealias ContentLocation = (content: String, lineNumber: UInt, lineOffset: Int)
// swiftlint:enable large_tuple
struct Lexer { struct Lexer {
let templateName: String? let templateName: String?
@@ -257,6 +255,3 @@ extension String {
return String(self[first..<last]) return String(self[first..<last])
} }
} }
/// Location in some content (text)
public typealias ContentLocation = (content: String, lineNumber: UInt, lineOffset: Int)

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation import Foundation
import PathKit import PathKit
@@ -41,8 +35,8 @@ public class FileSystemLoader: Loader, CustomStringConvertible {
} }
public init(bundle: [Bundle]) { public init(bundle: [Bundle]) {
self.paths = bundle.map { bundle in self.paths = bundle.compactMap { bundle in
Path(bundle.bundlePath) Path(bundle.path)
} }
} }
@@ -52,13 +46,13 @@ public class FileSystemLoader: Loader, CustomStringConvertible {
public func loadTemplate(name: String, environment: Environment) throws -> Template { public func loadTemplate(name: String, environment: Environment) throws -> Template {
for path in paths { for path in paths {
let templatePath = try path.safeJoin(path: Path(name)) let templatePath = try path.safeJoin(path: name)
if !templatePath.exists { if !templatePath.exists {
continue continue
} }
let content: String = try templatePath.read() let content: String = try String(contentsOf: templatePath)
return environment.templateClass.init(templateString: content, environment: environment, name: name) return environment.templateClass.init(templateString: content, environment: environment, name: name)
} }
@@ -68,10 +62,10 @@ public class FileSystemLoader: Loader, CustomStringConvertible {
public func loadTemplate(names: [String], environment: Environment) throws -> Template { public func loadTemplate(names: [String], environment: Environment) throws -> Template {
for path in paths { for path in paths {
for templateName in names { for templateName in names {
let templatePath = try path.safeJoin(path: Path(templateName)) let templatePath = try path.safeJoin(path: templateName)
if templatePath.exists { if templatePath.exists {
let content: String = try templatePath.read() let content: String = try String(contentsOf: templatePath)
return environment.templateClass.init(templateString: content, environment: environment, name: templateName) return environment.templateClass.init(templateString: content, environment: environment, name: templateName)
} }
} }
@@ -108,10 +102,10 @@ public class DictionaryLoader: Loader {
} }
extension Path { extension Path {
func safeJoin(path: Path) throws -> Path { func safeJoin(path: String) throws -> Path {
let newPath = self + path let newPath = self / path
if !newPath.absolute().description.hasPrefix(absolute().description) { if !newPath.string.hasPrefix(self.string) {
throw SuspiciousFileOperation(basePath: self, path: newPath) throw SuspiciousFileOperation(basePath: self, path: newPath)
} }

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation import Foundation
/// Represents a parsed node /// Represents a parsed node
@@ -184,6 +178,8 @@ func unwrap(_ array: [Any?]) -> [Any] {
} else { } else {
return item return item
} }
} else { return item as Any } } else {
return item as Any
}
} }
} }

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
#if !os(Linux) #if !os(Linux)
import Foundation import Foundation

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
/// Creates a checker that will stop parsing if it encounters a list of tags. /// Creates a checker that will stop parsing if it encounters a list of tags.
/// Useful for example for scanning until a given "end"-node. /// Useful for example for scanning until a given "end"-node.
public func until(_ tags: [String]) -> ((TokenParser, Token) -> Bool) { public func until(_ tags: [String]) -> ((TokenParser, Token) -> Bool) {
@@ -98,7 +92,7 @@ public class TokenParser {
tokens.first?.whitespace?.leading tokens.first?.whitespace?.leading
} }
/// Insert a token /// Insert a token
public func prependToken(_ token: Token) { public func prependToken(_ token: Token) {
tokens.insert(token, at: 0) tokens.insert(token, at: 0)
if parsedTokens.last == token { if parsedTokens.last == token {

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation import Foundation
import PathKit import PathKit
@@ -47,13 +41,17 @@ open class Template: ExpressibleByStringLiteral {
/// Create a template with a file found at the given URL /// Create a template with a file found at the given URL
@available(*, deprecated, message: "Use Environment/FileSystemLoader instead") @available(*, deprecated, message: "Use Environment/FileSystemLoader instead")
public convenience init(URL: Foundation.URL) throws { public convenience init(URL: Foundation.URL) throws {
try self.init(path: Path(URL.path)) guard let path = Path(url: URL) else {
throw TemplateDoesNotExist(templateNames: [URL.lastPathComponent])
}
try self.init(path: path)
} }
/// Create a template with a file found at the given path /// Create a template with a file found at the given path
@available(*, deprecated, message: "Use Environment/FileSystemLoader instead") @available(*, deprecated, message: "Use Environment/FileSystemLoader instead")
public convenience init(path: Path, environment: Environment? = nil, name: String? = nil) throws { public convenience init(path: Path, environment: Environment? = nil, name: String? = nil) throws {
self.init(templateString: try path.read(), environment: environment, name: name) let value = try String(contentsOf: path)
self.init(templateString: value, environment: environment, name: name)
} }
// MARK: ExpressibleByStringLiteral // MARK: ExpressibleByStringLiteral
@@ -81,8 +79,8 @@ open class Template: ExpressibleByStringLiteral {
return try renderNodes(nodes, context) return try renderNodes(nodes, context)
} }
// swiftlint:disable discouraged_optional_collection
/// Render the given template /// Render the given template
// swiftlint:disable:next discouraged_optional_collection
open func render(_ dictionary: [String: Any]? = nil) throws -> String { open func render(_ dictionary: [String: Any]? = nil) throws -> String {
try render(Context(dictionary: dictionary ?? [:], environment: environment)) try render(Context(dictionary: dictionary ?? [:], environment: environment))
} }

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation import Foundation
extension String { extension String {
@@ -83,9 +77,9 @@ public struct SourceMap: Equatable {
self.location = location self.location = location
} }
static let unknown = SourceMap() static let unknown = Self()
public static func == (lhs: SourceMap, rhs: SourceMap) -> Bool { public static func == (lhs: Self, rhs: Self) -> Bool {
lhs.filename == rhs.filename && lhs.location == rhs.location lhs.filename == rhs.filename && lhs.location == rhs.location
} }
} }
@@ -100,7 +94,7 @@ public struct WhitespaceBehaviour: Equatable {
let leading: Behaviour let leading: Behaviour
let trailing: Behaviour let trailing: Behaviour
public static let unspecified = WhitespaceBehaviour(leading: .unspecified, trailing: .unspecified) public static let unspecified = Self(leading: .unspecified, trailing: .unspecified)
} }
public class Token: Equatable { public class Token: Equatable {

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation import Foundation
public struct TrimBehaviour: Equatable { public struct TrimBehaviour: Equatable {
@@ -30,13 +24,13 @@ public struct TrimBehaviour: Equatable {
} }
/// doesn't touch newlines /// doesn't touch newlines
public static let nothing = TrimBehaviour(leading: .nothing, trailing: .nothing) public static let nothing = Self(leading: .nothing, trailing: .nothing)
/// removes whitespace before a block and whitespace and a single newline after a block /// removes whitespace before a block and whitespace and a single newline after a block
public static let smart = TrimBehaviour(leading: .whitespace, trailing: .whitespaceAndOneNewLine) public static let smart = Self(leading: .whitespace, trailing: .whitespaceAndOneNewLine)
/// removes all whitespace and newlines before and after a block /// removes all whitespace and newlines before and after a block
public static let all = TrimBehaviour(leading: .whitespaceAndNewLines, trailing: .whitespaceAndNewLines) public static let all = Self(leading: .whitespaceAndNewLines, trailing: .whitespaceAndNewLines)
static func leadingRegex(trim: Trim) -> NSRegularExpression { static func leadingRegex(trim: Trim) -> NSRegularExpression {
switch trim { switch trim {
@@ -64,13 +58,18 @@ public struct TrimBehaviour: Equatable {
} }
} }
// swiftlint:disable force_try // swiftlint:disable:next force_try
private static let leadingWhitespaceAndNewlines = try! NSRegularExpression(pattern: "^\\s+") private static let leadingWhitespaceAndNewlines = try! NSRegularExpression(pattern: "^\\s+")
// swiftlint:disable:next force_try
private static let trailingWhitespaceAndNewLines = try! NSRegularExpression(pattern: "\\s+$") private static let trailingWhitespaceAndNewLines = try! NSRegularExpression(pattern: "\\s+$")
// swiftlint:disable:next force_try
private static let leadingWhitespaceAndOneNewLine = try! NSRegularExpression(pattern: "^[ \t]*\n") private static let leadingWhitespaceAndOneNewLine = try! NSRegularExpression(pattern: "^[ \t]*\n")
// swiftlint:disable:next force_try
private static let trailingWhitespaceAndOneNewLine = try! NSRegularExpression(pattern: "\n[ \t]*$") private static let trailingWhitespaceAndOneNewLine = try! NSRegularExpression(pattern: "\n[ \t]*$")
// swiftlint:disable:next force_try
private static let leadingWhitespace = try! NSRegularExpression(pattern: "^[ \t]*") private static let leadingWhitespace = try! NSRegularExpression(pattern: "^[ \t]*")
// swiftlint:disable:next force_try
private static let trailingWhitespace = try! NSRegularExpression(pattern: "[ \t]*$") private static let trailingWhitespace = try! NSRegularExpression(pattern: "[ \t]*$")
} }

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Foundation import Foundation
typealias Number = Float typealias Number = Float

View File

@@ -2,17 +2,16 @@
"name": "Stencil", "name": "Stencil",
"version": "0.15.1", "version": "0.15.1",
"summary": "Stencil is a simple and powerful template language for Swift.", "summary": "Stencil is a simple and powerful template language for Swift.",
"homepage": "https://stencil.fuller.li",
"license": { "license": {
"type": "BSD", "type": "BSD",
"file": "LICENSE" "file": "LICENSE"
}, },
"authors": { "authors": {
"Kyle Fuller": "kyle@fuller.li" "Thomas Bernstein": "developer@astzweig.kg"
}, },
"social_media_url": "https://twitter.com/kylefuller", "social_media_url": "https://twitter.com/trbernstein",
"source": { "source": {
"git": "https://github.com/stencilproject/Stencil.git", "git": "https://github.com/swiftstencil/swiftpm-stencil.git",
"tag": "0.15.1" "tag": "0.15.1"
}, },
"source_files": [ "source_files": [
@@ -23,14 +22,13 @@
"osx": "10.9", "osx": "10.9",
"tvos": "9.0" "tvos": "9.0"
}, },
"cocoapods_version": ">= 1.7.0",
"swift_versions": [ "swift_versions": [
"5.0" "5.0"
], ],
"requires_arc": true, "requires_arc": true,
"dependencies": { "dependencies": {
"PathKit": [ "PathKit": [
"~> 1.0.0" "~> 1.5.0"
] ]
} }
} }

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit import PathKit
import Spectre import Spectre
@testable import Stencil @testable import Stencil
@@ -17,7 +11,7 @@ final class EnvironmentBaseAndChildTemplateTests: XCTestCase {
override func setUp() { override func setUp() {
super.setUp() super.setUp()
let path = Path(#file as String) + ".." + "fixtures" let path = Path(#file as String)! / ".." / "fixtures"
let loader = FileSystemLoader(paths: [path]) let loader = FileSystemLoader(paths: [path])
environment = Environment(loader: loader) environment = Environment(loader: loader)
childTemplate = "" childTemplate = ""

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit import PathKit
import Spectre import Spectre
@testable import Stencil @testable import Stencil
@@ -17,7 +11,7 @@ final class EnvironmentIncludeTemplateTests: XCTestCase {
override func setUp() { override func setUp() {
super.setUp() super.setUp()
let path = Path(#file as String) + ".." + "fixtures" let path = Path(#file as String)! / ".." / "fixtures"
let loader = FileSystemLoader(paths: [path]) let loader = FileSystemLoader(paths: [path])
environment = Environment(loader: loader) environment = Environment(loader: loader)
template = "" template = ""

View File

@@ -1,10 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest
@@ -11,7 +5,7 @@ import XCTest
final class ExpressionsTests: XCTestCase { final class ExpressionsTests: XCTestCase {
private let parser = TokenParser(tokens: [], environment: Environment()) private let parser = TokenParser(tokens: [], environment: Environment())
private func makeExpression(_ components: [String]) -> Expression { private func makeExpression(_ components: [String]) -> Stencil.Expression {
do { do {
let parser = try IfExpressionParser.parser( let parser = try IfExpressionParser.parser(
components: components, components: components,

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
import Stencil import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit import PathKit
import Spectre import Spectre
@testable import Stencil @testable import Stencil
@@ -11,7 +5,7 @@ import XCTest
extension Expectation { extension Expectation {
@discardableResult @discardableResult
func toThrow<T: Error>() throws -> T { func toThrow<E: Error>() throws -> E {
var thrownError: Error? var thrownError: Error?
do { do {
@@ -21,7 +15,7 @@ extension Expectation {
} }
if let thrownError = thrownError { if let thrownError = thrownError {
if let thrownError = thrownError as? T { if let thrownError = thrownError as? E {
return thrownError return thrownError
} else { } else {
throw failure("\(thrownError) is not \(T.self)") throw failure("\(thrownError) is not \(T.self)")

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,16 +1,10 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit import PathKit
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest
final class IncludeTests: XCTestCase { final class IncludeTests: XCTestCase {
private let path = Path(#file as String) + ".." + "fixtures" private let path = Path(#file as String)! / ".." / "fixtures"
private lazy var loader = FileSystemLoader(paths: [path]) private lazy var loader = FileSystemLoader(paths: [path])
private lazy var environment = Environment(loader: loader) private lazy var environment = Environment(loader: loader)

View File

@@ -1,16 +1,10 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit import PathKit
import Spectre import Spectre
import Stencil import Stencil
import XCTest import XCTest
final class InheritanceTests: XCTestCase { final class InheritanceTests: XCTestCase {
private let path = Path(#file as String) + ".." + "fixtures" private let path = Path(#file as String)! / ".." / "fixtures"
private lazy var loader = FileSystemLoader(paths: [path]) private lazy var loader = FileSystemLoader(paths: [path])
private lazy var environment = Environment(loader: loader) private lazy var environment = Environment(loader: loader)

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit import PathKit
import Spectre import Spectre
@testable import Stencil @testable import Stencil
@@ -140,8 +134,8 @@ final class LexerTests: XCTestCase {
} }
func testPerformance() throws { func testPerformance() throws {
let path = Path(#file as String) + ".." + "fixtures" + "huge.html" let path = Path(#file as String)! / ".." / "fixtures" / "huge.html"
let content: String = try path.read() let content: String = try NSString(contentsOfFile: path.string, encoding: String.Encoding.utf8.rawValue).substring(from: 0) as String
measure { measure {
let lexer = Lexer(templateString: content) let lexer = Lexer(templateString: content)

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import PathKit import PathKit
import Spectre import Spectre
import Stencil import Stencil
@@ -11,7 +5,7 @@ import XCTest
final class TemplateLoaderTests: XCTestCase { final class TemplateLoaderTests: XCTestCase {
func testFileSystemLoader() { func testFileSystemLoader() {
let path = Path(#file as String) + ".." + "fixtures" let path = Path(#file as String)! / ".." / "fixtures"
let loader = FileSystemLoader(paths: [path]) let loader = FileSystemLoader(paths: [path])
let environment = Environment(loader: loader) let environment = Environment(loader: loader)

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
import Stencil import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
import Stencil import Stencil
import XCTest import XCTest

View File

@@ -1,9 +1,3 @@
//
// Stencil
// Copyright © 2022 Stencil
// MIT Licence
//
import Spectre import Spectre
@testable import Stencil @testable import Stencil
import XCTest import XCTest

View File

@@ -2,7 +2,7 @@
<p> <p>
<iframe <iframe
src="https://ghbtns.com/github-btn.html?user=stencilproject&repo=Stencil&type=watch&count=true&size=large" src="https://ghbtns.com/github-btn.html?user=swiftstencil&repo=swiftpm-stencil&type=watch&count=true&size=large"
allowtransparency="true" frameborder="0" scrolling="0" width="200px" height="35px"> allowtransparency="true" frameborder="0" scrolling="0" width="200px" height="35px">
</iframe> </iframe>
</p> </p>
@@ -12,22 +12,8 @@
<div class="social"> <div class="social">
<p> <p>
<iframe <iframe
src="https://ghbtns.com/github-btn.html?user=kylef&type=follow&count=false" src="https://ghbtns.com/github-btn.html?user=swiftstencil&type=follow&count=false"
allowtransparency="true" frameborder="0" scrolling="0" width="200" height="20"> allowtransparency="true" frameborder="0" scrolling="0" width="200" height="20">
</iframe> </iframe>
</p> </p>
<p>
<a href="https://twitter.com/kylefuller" class="twitter-follow-button" data-show-count="false">Follow @kylefuller</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
</p>
</div> </div>
<h3>Other Projects</h3>
<p>More <a href="https://fuller.li/">Kyle Fuller</a> projects:</p>
<ul>
<li><a href="https://github.com/kylef/Commander">Commander</a></li>
<li><a href="https://curassow.fuller.li/">Curassow</a></li>
<li><a href="https://github.com/kylef/Spectre">Spectre</a></li>
<li><a href="https://github.com/kylef/heroku-buildpack-swift">Heroku Swift buildpack</a></li>
</ul>

View File

@@ -50,7 +50,7 @@ master_doc = 'index'
# General information about the project. # General information about the project.
project = 'Stencil' project = 'Stencil'
copyright = '2022, Kyle Fuller' copyright = [ '2022, Kyle Fuller', '2025, Astzweig GmbH & Co. KG' ]
author = 'Kyle Fuller' author = 'Kyle Fuller'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for

View File

@@ -14,39 +14,6 @@ dependencies inside ``Package.swift``.
let package = Package( let package = Package(
name: "MyApplication", name: "MyApplication",
dependencies: [ dependencies: [
.package(url: "https://github.com/stencilproject/Stencil.git", from: "0.15.1"), .package(url: "https://github.com/swiftstencil/swiftpm-stencil.git", from: "0.15.1"),
] ]
) )
CocoaPods
---------
If you're using CocoaPods, you can add Stencil to your ``Podfile`` and then run
``pod install``.
.. code-block:: ruby
pod 'Stencil', '~> 0.15.1'
Carthage
--------
.. note:: Use at your own risk. We don't offer support for Carthage and instead recommend you use Swift Package Manager.
1) Add ``Stencil`` to your ``Cartfile``:
.. code-block:: text
github "stencilproject/Stencil" ~> 0.15.1
2) Checkout your dependencies, generate the Stencil Xcode project, and then use Carthage to build Stencil:
.. code-block:: shell
$ carthage update
$ (cd Carthage/Checkouts/Stencil && swift package generate-xcodeproj)
$ carthage build
3) Follow the Carthage steps to add the built frameworks to your project.
To learn more about this approach see `Using Swift Package Manager with Carthage <https://fuller.li/posts/using-swift-package-manager-with-carthage/>`_.

View File

@@ -42,7 +42,7 @@ def check_changelog
# Now, check that links [#nn](.../nn) have matching numbers in link title & URL # Now, check that links [#nn](.../nn) have matching numbers in link title & URL
wrong_links = line.scan(links).reject do |m| wrong_links = line.scan(links).reject do |m|
slug = m[0] || "stencilproject/#{current_repo}" slug = m[0] || "stencilproject/Stencil"
(slug == m[2]) && (m[1] == m[4]) (slug == m[2]) && (m[1] == m[4])
end end
all_warnings.concat Array(wrong_links.map do |m| all_warnings.concat Array(wrong_links.map do |m|

View File

@@ -5,9 +5,9 @@
namespace :lint do namespace :lint do
SWIFTLINT = 'rakelib/lint.sh' SWIFTLINT = 'rakelib/lint.sh'
SWIFTLINT_VERSION = '0.48.0' SWIFTLINT_VERSION = '0.61.0'
task :install do |task| task :install do |task|
next if check_version next if check_version
if OS.mac? if OS.mac?

View File

@@ -7,7 +7,7 @@ require 'json'
namespace :release do namespace :release do
desc 'Create a new release' desc 'Create a new release'
task :new => [:check_versions, :check_tag_and_ask_to_release, 'spm:test', :github, :cocoapods] task :new => [:check_versions, :check_tag_and_ask_to_release, 'spm:test', :github]
desc 'Check if all versions from the podspecs and CHANGELOG match' desc 'Check if all versions from the podspecs and CHANGELOG match'
task :check_versions do task :check_versions do
@@ -15,7 +15,7 @@ namespace :release do
Utils.table_header('Check', 'Status') Utils.table_header('Check', 'Status')
# Check if bundler is installed first, as we'll need it for the cocoapods task (and we prefer to fail early) # Check if bundler is installed first (we prefer to fail early)
`which bundler` `which bundler`
results << Utils.table_result( results << Utils.table_result(
$CHILD_STATUS.success?, $CHILD_STATUS.success?,
@@ -40,18 +40,14 @@ namespace :release do
# Check docs installation # Check docs installation
docs_package = Utils.first_match_in_file('docs/installation.rst', /\.package\(url: .+ from: "(.+)"/, 1) docs_package = Utils.first_match_in_file('docs/installation.rst', /\.package\(url: .+ from: "(.+)"/, 1)
docs_cocoapods = Utils.first_match_in_file('docs/installation.rst', /pod 'Stencil', '~> (.+)'/, 1)
docs_carthage = Utils.first_match_in_file('docs/installation.rst', /github ".+\/Stencil" ~> (.+)/, 1)
results << Utils.table_result(docs_package == v, 'Docs, package updated', 'Update the package version in docs/installation.rst') results << Utils.table_result(docs_package == v, 'Docs, package updated', 'Update the package version in docs/installation.rst')
results << Utils.table_result(docs_cocoapods == v, 'Docs, cocoapods updated', 'Update the cocoapods version in docs/installation.rst')
results << Utils.table_result(docs_carthage == v, 'Docs, carthage updated', 'Update the carthage version in docs/installation.rst')
# Check if entry present in CHANGELOG # Check if entry present in CHANGELOG
changelog_entry = Utils.first_match_in_file('CHANGELOG.md', /^## #{Regexp.quote(v)}$/) changelog_entry = Utils.first_match_in_file('CHANGELOG.md', /^## #{Regexp.quote(v)}$/)
results << Utils.table_result(changelog_entry, 'CHANGELOG, Entry added', "Add an entry for #{v} in CHANGELOG.md") results << Utils.table_result(changelog_entry, 'CHANGELOG, Entry added', "Add an entry for #{v} in CHANGELOG.md")
changelog_has_stable = system("grep -qi '^## Master' CHANGELOG.md") changelog_has_stable = system("grep -qi '^## Master' CHANGELOG.md")
results << Utils.table_result(!changelog_has_stable, 'CHANGELOG, No master', 'Remove section for master branch in CHANGELOG') results << Utils.table_result(!changelog_has_stable, 'CHANGELOG, No master', 'Remove section for main branch in CHANGELOG')
exit 1 unless results.all? exit 1 unless results.all?
end end
@@ -82,16 +78,10 @@ namespace :release do
tag = Utils.top_changelog_version tag = Utils.top_changelog_version
body = Utils.top_changelog_entry body = Utils.top_changelog_entry
raise 'Must be a valid version' if tag == 'Master' raise 'Must be a valid version' if tag == 'main'
repo_name = File.basename(`git remote get-url origin`.chomp, '.git').freeze repo_name = File.basename(`git remote get-url origin`.chomp, '.git').freeze
puts "Pushing release notes for tag #{tag}" puts "Pushing release notes for tag #{tag}"
client.create_release("stencilproject/#{repo_name}", tag, name: tag, body: body) client.create_release("swiftstencil/#{repo_name}", tag, name: tag, body: body)
end
desc "pod trunk push #{POD_NAME} to CocoaPods"
task :cocoapods do
Utils.print_header 'Pushing pod to CocoaPods Trunk'
sh "bundle exec pod trunk push #{POD_NAME}.podspec.json"
end end
end end

View File

@@ -55,7 +55,7 @@ class Utils
def self.spm_own_version(dep) def self.spm_own_version(dep)
dependencies = JSON.load(File.new('Package.resolved'))['object']['pins'] dependencies = JSON.load(File.new('Package.resolved'))['object']['pins']
dependencies.find { |d| d['package'] == dep }['state']['version'] dependencies.find { |d| d['package'] == dep }['state']['version']
end end
def self.spm_resolved_version(dep) def self.spm_resolved_version(dep)
dependencies = JSON.load(File.new('Package.resolved'))['object']['pins'] dependencies = JSON.load(File.new('Package.resolved'))['object']['pins']