Skip to content

Commit 73f4ad4

Browse files
authored
Sendable fixes and other cleanup (#135)
* Bump minimum Swift to 5.10, update docs and README, add Android CI * Take care of all Sendable warnings across the board. This mostly involves a lot of marking things Sendable, or marking things nonisolated(unsafe) in conjunction with a lock. LeafTag.defaultTags remains a distinct problem. Also got rid of the use of NonBlockingFileIO in NIOLeafFiles. Renamed Exports.swift -> Character+Identities.swift. * Get rid of all that mess for HTML escaping, it's actually slower most of the time than, and at best only equivalent to, just doing .replacing(_:with:) (in 6.0+) or .replacingOccurrences(of:with:) (in 5.10). * Silence retroactive conformance warning, clean up handling in tests of paths and dates (tests no longer fail for users in DST-active timezones) * A big ol' round of much needed code style/formatting/readability cleanup. * Do not assume Float80 is available anywhere other than on Intel or when running anything other than Darwin or a Glibc Linux (i.e. especially not Android) * Clean up imports (use FoundationEssentials when available, NIO -> NIOCore, alphabetize) * Finish cleaning up access modifiers. Fix a couple misspelled comments. * Slightly improve the path handling logic in NIOLeafFiles * Fix some build errors (can't use FoundationEssentials after all), use exclude instead of resources to silence SwiftPM about the test templates, use the NIO singletons in tests * Add a bunch of missing `self` keywords * Address PR feedback * Wipe out the .lazy case from LeafDataStorage and all the stuff that cascades from it. It is not used and was cluttering up the code to no purpose. Also cleaned up LeafDataStorage a lot in general and removed a chunk of other unused code on it and LeafData. * Although we are stuck with the terrible and ill-advised conformance of String to Error, we are not stuck with setting the bad example of actually using that conformance. Remove all such instances, using LeafError(.unknownError()) instead. * Clean up the tests using better async helpers, get rid of the internal-only testing support methods we don't need (there is no public interface to directly specify an unsearchable source, not sure why sources even have that feature), exclude all performance tests on Android (they break there), get rid of a few unnecessary force-unwraps, get rid of the last usages of .trimmingCharacters(in:) * One more test to disable temporarily on Android * Make the default dictFormatter's output deterministic
1 parent 902c512 commit 73f4ad4

42 files changed

Lines changed: 2393 additions & 2137 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,3 @@ updates:
99
dependencies:
1010
patterns:
1111
- "*"
12-
- package-ecosystem: "swift"
13-
directory: "/"
14-
schedule:
15-
interval: "daily"
16-
open-pull-requests-limit: 6
17-
allow:
18-
- dependency-type: all
19-
groups:
20-
all-dependencies:
21-
patterns:
22-
- "*"

.github/workflows/test.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ concurrency:
55
on:
66
pull_request: { types: [opened, reopened, synchronize, ready_for_review] }
77
push: { branches: [ main ] }
8-
env:
9-
SWIFT_DETERMINISTIC_HASHING: 1
108

119
jobs:
1210
unit-tests:
1311
uses: vapor/ci/.github/workflows/run-unit-tests.yml@main
1412
with:
1513
with_musl: true
14+
with_android: true
1615
ios_scheme_name: leaf-kit
1716
secrets: inherit
1817

Package.swift

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.9
1+
// swift-tools-version:5.10
22
import PackageDescription
33

44
let package = Package(
@@ -13,36 +13,35 @@ let package = Package(
1313
.library(name: "LeafKit", targets: ["LeafKit"])
1414
],
1515
dependencies: [
16-
.package(url: "https://github.com/apple/swift-nio.git", from: "2.2.0")
16+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.81.0"),
1717
],
1818
targets: [
1919
.target(
2020
name: "LeafKit",
2121
dependencies: [
22-
.product(name: "NIO", package: "swift-nio")
22+
.product(name: "NIO", package: "swift-nio"),
23+
.product(name: "_NIOFileSystem", package: "swift-nio"),
24+
.product(name: "NIOFoundationCompat", package: "swift-nio"),
2325
],
2426
swiftSettings: swiftSettings
2527
),
2628
.testTarget(
2729
name: "LeafKitTests",
2830
dependencies: [
29-
.target(name: "LeafKit")
31+
.target(name: "LeafKit"),
3032
],
31-
resources: [
32-
.copy("Templates")
33+
exclude: [
34+
"Templates",
3335
],
3436
swiftSettings: swiftSettings
3537
),
3638
]
3739
)
3840

39-
var swiftSettings: [SwiftSetting] {
40-
[
41-
.enableUpcomingFeature("ExistentialAny"),
42-
.enableUpcomingFeature("ConciseMagicFile"),
43-
.enableUpcomingFeature("ForwardTrailingClosures"),
44-
.enableUpcomingFeature("DisableOutwardActorInference"),
45-
.enableUpcomingFeature("StrictConcurrency"),
46-
.enableExperimentalFeature("StrictConcurrency=complete"),
47-
]
48-
}
41+
var swiftSettings: [SwiftSetting] { [
42+
.enableUpcomingFeature("ExistentialAny"),
43+
.enableUpcomingFeature("ConciseMagicFile"),
44+
.enableUpcomingFeature("ForwardTrailingClosures"),
45+
.enableUpcomingFeature("DisableOutwardActorInference"),
46+
.enableExperimentalFeature("StrictConcurrency=complete"),
47+
] }

README.md

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
11
<p align="center">
2-
<img
3-
src="https://user-images.githubusercontent.com/1342803/75629786-f9b64600-5bb2-11ea-856b-9ded8ea07450.png"
4-
height="64"
5-
alt="LeafKit"
6-
>
7-
<br>
8-
<br>
9-
<a href="https://docs.vapor.codes/4.0/">
10-
<img src="http://img.shields.io/badge/read_the-docs-2196f3.svg" alt="Documentation">
11-
</a>
12-
<a href="https://discord.gg/vapor">
13-
<img src="https://img.shields.io/discord/431917998102675485.svg" alt="Team Chat">
14-
</a>
15-
<a href="LICENSE">
16-
<img src="http://img.shields.io/badge/license-MIT-brightgreen.svg" alt="MIT License">
17-
</a>
18-
<a href="https://github.com/vapor/leaf-kit/actions">
19-
<img src="https://github.com/vapor/leaf-kit/workflows/test/badge.svg" alt="Continuous Integration">
20-
</a>
21-
<a href="https://swift.org">
22-
<img src="http://img.shields.io/badge/swift-5.2-brightgreen.svg" alt="Swift 5.2">
23-
</a>
2+
<img src="https://design.vapor.codes/images/vapor-leafkit.svg" height="96" alt="LeafKit">
3+
<br>
4+
<br>
5+
<a href="https://docs.vapor.codes/4.0/"><img src="https://design.vapor.codes/images/readthedocs.svg" alt="Documentation"></a>
6+
<a href="https://discord.gg/vapor"><img src="https://design.vapor.codes/images/discordchat.svg" alt="Team Chat"></a>
7+
<a href="LICENSE"><img src="https://design.vapor.codes/images/mitlicense.svg" alt="MIT License"></a>
8+
<a href="https://github.com/vapor/leaf-kit/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/vapor/leaf-kit/test.yml?event=push&style=plastic&logo=github&label=tests&logoColor=%23ccc" alt="Continuous Integration"></a>
9+
<a href="https://codecov.io/github/vapor/leaf-kit"><img src="https://img.shields.io/codecov/c/github/vapor/leaf-kit?style=plastic&logo=codecov&label=codecov"></a>
10+
<a href="https://swift.org"><img src="https://design.vapor.codes/images/swift510up.svg" alt="Swift 5.10+"></a>
2411
</p>
12+
13+
<br>
14+
15+
Leaf is a templating language for generating dynamic content such as HTML using a simple syntax.
16+
17+
## Overview
18+
19+
LeafKit is the main templating language for Vapor.
20+
21+
For more details, check out the [docs](https://docs.vapor.codes/leaf/getting-started/).
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/// Various helper identities for convenience
2+
extension Character {
3+
4+
// MARK: - LeafToken helpers
5+
6+
var isValidInTagName: Bool {
7+
self.isLowercaseLetter || self.isUppercaseLetter
8+
}
9+
10+
var isValidInParameter: Bool {
11+
self.isValidInTagName ||
12+
self.isValidOperator ||
13+
self.isValidInNumeric
14+
}
15+
16+
var canStartNumeric: Bool {
17+
(.zero ... .nine) ~= self
18+
}
19+
20+
var isValidInNumeric: Bool {
21+
self.canStartNumeric ||
22+
self == .underscore ||
23+
self == .binaryNotation ||
24+
self == .octalNotation ||
25+
self == .hexNotation ||
26+
self.isHexadecimal ||
27+
self == .period
28+
}
29+
30+
var isValidOperator: Bool {
31+
switch self {
32+
case .plus,
33+
.minus,
34+
.star,
35+
.forwardSlash,
36+
.percent,
37+
.equals,
38+
.exclamation,
39+
.lessThan,
40+
.greaterThan,
41+
.ampersand,
42+
.vertical:
43+
true
44+
default:
45+
false
46+
}
47+
}
48+
49+
// MARK: - General group-membership identities (Internal)
50+
51+
var isHexadecimal: Bool {
52+
(.zero ... .nine).contains(self) ||
53+
(.A ... .F).contains(self) ||
54+
(.a ... .f).contains(self) ||
55+
self == .hexNotation
56+
}
57+
58+
var isOctal: Bool {
59+
(.zero ... .seven).contains(self) || self == .octalNotation
60+
}
61+
62+
var isBinary: Bool {
63+
self == .zero || self == .one || self == .binaryNotation
64+
}
65+
66+
var isUppercaseLetter: Bool {
67+
(.A ... .Z).contains(self)
68+
}
69+
70+
var isLowercaseLetter: Bool {
71+
(.a ... .z).contains(self)
72+
}
73+
74+
// MARK: - General helpers
75+
76+
static let newLine: Self = "\n"
77+
static let quote: Self = "\""
78+
static let octothorpe: Self = "#"
79+
static let leftParenthesis: Self = "("
80+
static let backSlash: Self = "\\"
81+
static let rightParenthesis: Self = ")"
82+
static let comma: Self = ","
83+
static let space: Self = " "
84+
static let colon: Self = ":"
85+
static let period: Self = "."
86+
static let A: Self = "A"
87+
static let F: Self = "F"
88+
static let Z: Self = "Z"
89+
static let a: Self = "a"
90+
static let f: Self = "f"
91+
static let z: Self = "z"
92+
93+
static let zero: Self = "0"
94+
static let one: Self = "1"
95+
static let seven: Self = "7"
96+
static let nine: Self = "9"
97+
static let binaryNotation: Self = "b"
98+
static let octalNotation: Self = "o"
99+
static let hexNotation: Self = "x"
100+
101+
static let plus: Self = "+"
102+
static let minus: Self = "-"
103+
static let star: Self = "*"
104+
static let forwardSlash: Self = "/"
105+
static let percent: Self = "%"
106+
static let equals: Self = "="
107+
static let exclamation: Self = "!"
108+
static let lessThan: Self = "<"
109+
static let greaterThan: Self = ">"
110+
static let ampersand: Self = "&"
111+
static let vertical: Self = "|"
112+
static let underscore: Self = "_"
113+
}
Lines changed: 25 additions & 0 deletions
Loading
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"theme": {
3+
"aside": { "border-radius": "16px", "border-style": "double", "border-width": "3px" },
4+
"border-radius": "0",
5+
"button": { "border-radius": "16px", "border-width": "1px", "border-style": "solid" },
6+
"code": { "border-radius": "16px", "border-width": "1px", "border-style": "solid" },
7+
"color": {
8+
"leaf": { "dark": "hsl(136, 43%, 53%)", "light": "hsl(136, 33%, 48%)" },
9+
"documentation-intro-fill": "radial-gradient(circle at top, var(--color-leaf) 30%, #000 100%)",
10+
"documentation-intro-accent": "var(--color-leaf)",
11+
"documentation-intro-eyebrow": "white",
12+
"documentation-intro-figure": "white",
13+
"documentation-intro-title": "white",
14+
"logo-base": { "dark": "#fff", "light": "#000" },
15+
"logo-shape": { "dark": "#000", "light": "#fff" },
16+
"fill": { "dark": "#000", "light": "#fff" }
17+
},
18+
"icons": { "technology": "/leafkit/images/vapor-leafkit-logo.svg" }
19+
},
20+
"features": {
21+
"quickNavigation": { "enable": true },
22+
"i18n": { "enable": true }
23+
}
24+
}

0 commit comments

Comments
 (0)