-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
toast.yml
417 lines (367 loc) · 13.5 KB
/
toast.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
image: ubuntu:24.04
default: build
user: user
command_prefix: |
# Make not silently ignore errors.
set -euo pipefail
# Load the Rust startup file, if it exists.
if [ -f "$HOME/.cargo/env" ]; then
. "$HOME/.cargo/env"
fi
# Use this wrapper for `cargo` if network access is needed.
cargo-online () { cargo --locked "$@"; }
# Use this wrapper for `cargo` unless network access is needed.
cargo-offline () { cargo --frozen --offline "$@"; }
# Use this wrapper for formatting code or checking that code is formatted. We use a nightly Rust
# version for the `trailing_comma` formatting option [tag:rust_fmt_nightly_2024-09-06]. The
# nightly version was chosen as the latest available release with all components present
# according to this page:
# https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu.html
cargo-fmt () { cargo +nightly-2024-09-06 --frozen --offline fmt --all -- "$@"; }
# Load the NVM startup file, if it exists.
if [ -f "$HOME/.nvm/nvm.sh" ]; then
export NVM_DIR="$HOME/.nvm"
. "$HOME/.nvm/nvm.sh"
fi
# Make Bash log commands.
set -x
tasks:
install_packages:
description: Install system packages.
user: root
command: |
# Install the following packages:
#
# - build-essential - Used to link some crates
# - curl - Used for installing Tagref and Rust
# - gcc-aarch64-linux-gnu - Used for linking the binary for AArch64
# - gcc-x86-64-linux-gnu - Used for linking the binary for x86-64
# - ripgrep - Used for various linting tasks
# - shellcheck - Used for linting shell scripts
apt-get update
apt-get install --yes \
build-essential \
curl \
gcc-aarch64-linux-gnu \
gcc-x86-64-linux-gnu \
ripgrep \
shellcheck
install_tagref:
description: Install Tagref, a reference checking tool.
dependencies:
- install_packages
user: root
command: |
# Install Tagref using the official installer script.
curl https://raw.githubusercontent.com/stepchowfun/tagref/main/install.sh -LSfs | sh
create_user:
description: Create a user who doesn't have root privileges.
user: root
command: |
# Create a user named `user` with a home directory and with Bash as the login shell.
useradd user --create-home --shell /bin/bash
install_rust:
description: Install Rust, a systems programming language.
dependencies:
- install_packages
- create_user
command: |
# Install stable Rust [tag:rust_1.81.0].
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \
-y \
--default-toolchain 1.81.0 \
--profile minimal \
--component clippy
# Add Rust tools to `$PATH`.
. "$HOME/.cargo/env"
# Install nightly Rust [ref:rust_fmt_nightly_2024-09-06].
rustup toolchain install nightly-2024-09-06 --profile minimal --component rustfmt
install_node:
description: Install Node.js, a JavaScript runtime environment.
dependencies:
- install_packages
- create_user
command: |
# Install Node.js.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
export NVM_DIR="$HOME/.nvm"
. "$NVM_DIR/nvm.sh"
nvm install 18.17.0
install_tools:
description: Install the tools needed to build and validate the program.
dependencies:
- install_node
- install_rust
- install_tagref
fetch_crates:
description: Download and build Rust packages used by the program.
dependencies:
- install_tools
input_paths:
- Cargo.lock
- Cargo.toml
command: |
# Create a "hello world" project with the dependencies we want to fetch.
mv Cargo.lock Cargo.lock.og
mv Cargo.toml Cargo.toml.og
cargo-offline init --vcs none
mv Cargo.lock.og Cargo.lock
mv Cargo.toml.og Cargo.toml
# Ask Cargo to build the project in order to fetch the dependencies.
cargo-online build
cargo-online build --release
cargo-online clippy --all-features --all-targets --workspace
# Delete the build artifacts.
cargo-offline clean --package typical
cargo-offline clean --release --package typical
# Delete the "hello world" code.
rm -rf src
repository:
description: Import the repository.
dependencies:
- fetch_crates
input_paths:
- .
excluded_input_paths:
- .git
# [tag:excluded_input_paths] Keep this in sync with [file:.gitignore].
- artifacts
- examples/rust/target
- examples/typescript/dist
- examples/typescript/generated
- examples/typescript/node_modules
- benchmarks/rust/target
- benchmarks/typescript/dist
- benchmarks/typescript/generated
- benchmarks/typescript/node_modules
- integration_tests/rust/target
- integration_tests/typescript_node/dist
- integration_tests/typescript_node/generated
- integration_tests/typescript_node/node_modules
- integration_tests/typescript_web/dist
- integration_tests/typescript_web/generated
- integration_tests/typescript_web/node_modules
- target/
build:
description: Build the binary in non-release mode.
dependencies:
- repository
command: |
# Build the project with Cargo.
cargo-offline build
test_units:
description: Run the unit test suite.
dependencies:
- repository
command: |
# Run the tests with Cargo. The `NO_COLOR` variable is used to disable colored output for
# tests that make assertions regarding the output [tag:colorless_tests].
NO_COLOR=true cargo-offline test
test_rust_integration:
description: Run integration tests for the Rust code generator.
dependencies:
- build
command: |
# Add Typical to `$PATH`.
export PATH="$PWD/target/debug:$PATH"
# Validate and run the example project and the integration test.
for SCENARIO in benchmarks/rust examples/rust integration_tests/rust; do
echo "Validating $SCENARIO..."
(
cd "$SCENARIO" && \
cargo-offline check && \
cargo-offline clippy --all-features --all-targets --workspace && \
cargo-fmt --check && \
cargo-offline run
)
done
# Validate the data from the integration test.
cmp test_data/omnifile /tmp/omnifile-rust
test_typescript_integration:
description: Run integration tests for the TypeScript code generator.
dependencies:
- build
command: |
# Add Typical to `$PATH`.
export PATH="$PWD/target/debug:$PATH"
# Validate and run the example project and the integration test.
for SCENARIO in \
benchmarks/typescript \
examples/typescript \
integration_tests/typescript_node \
integration_tests/typescript_web
do
echo "Validating $SCENARIO..."
(cd "$SCENARIO" && npm ci && npm run main && npm run lint)
done
# Validate the data from the integration test.
cmp test_data/omnifile /tmp/omnifile-typescript
lint:
description: Run the linters.
dependencies:
- build
command: |
# Add Typical to `$PATH`.
export PATH="$PWD/target/debug:$PATH"
# Check references with Tagref.
tagref
# Lint shell files with ShellCheck.
find . -type f -name '*.sh' | xargs shellcheck
# Check the formatting of the schemas with Typical.
typical format --check benchmarks/types.t
typical format --check examples/rust/types.t
typical format --check examples/typescript/types.t
typical format --check integration_tests/types/types.t
# Lint the Rust projects.
for PROJECT_PATH in . benchmarks/rust examples/rust integration_tests/rust; do
(
cd "$PROJECT_PATH" &&
# Lint the code with Clippy.
cargo-offline clippy --all-features --all-targets --workspace &&
# Check code formatting with Rustfmt. See [ref:format_macros] for an explanation of the
# `rg` commands.
rg --type rust --files-with-matches '' src | xargs sed -i 's/!(/_(/g' &&
rg --type rust --files-with-matches '' src | xargs sed -i 's/^\([^ (]*\)_(/\1!(/g' &&
if ! cargo-fmt --check; then
echo 'ERROR: Please correct the formatting errors above.' 1>&2
exit 1
fi &&
rg --type rust --files-with-matches '' src | xargs sed -i 's/_(/!(/g'
# Forbid unconsolidated `use` declarations.
if rg --line-number --type rust --multiline \
'}[[:space]]*;[[:space:]]*\n[[:space:]]*use' \
src
then
echo 'Please consolidate these `use` declarations.' >&2
exit 1
fi
# Enforce that lines span no more than 100 columns.
if rg --line-number --type rust '.{101}' src; then
echo 'There are lines spanning more than 100 columns.' >&2
exit 1
fi
)
done
# Lint the TypeScript projects.
for PROJECT_PATH in \
benchmarks/typescript \
examples/typescript \
integration_tests/typescript_node \
integration_tests/typescript_web
do
(
cd "$PROJECT_PATH" &&
npm ci &&
npm run lint
)
done
run:
description: Run the program.
dependencies:
- build
command: |
# Run the program with Cargo.
cargo-offline run -- --help
format:
description: Format the source code.
dependencies:
- build
output_paths:
- benchmarks/rust/src
- benchmarks/types.t
- benchmarks/typescript/src
- examples/rust/src
- examples/rust/types.t
- examples/typescript/src
- examples/typescript/types.t
- integration_tests/rust/src
- integration_tests/types
- integration_tests/typescript_node/src
- integration_tests/typescript_web/src
- src
command: |
# Add Typical to `$PATH`.
export PATH="$PWD/target/debug:$PATH"
# Format the schemas with Typical.
typical format benchmarks/types.t
typical format examples/rust/types.t
typical format examples/typescript/types.t # Or `npm run format` in [dir:examples/typescript]
typical format integration_tests/types/types.t
# Format the Rust projects.
for PROJECT_PATH in . benchmarks/rust examples/rust integration_tests/rust; do
(
cd "$PROJECT_PATH" &&
# We temporarily convert macro invocations into function calls so Rustfmt's
# `trailing_comma` feature applies to macro arguments [tag:format_macros].
rg --type rust --files-with-matches '' src | xargs sed -i 's/!(/_(/g' &&
rg --type rust --files-with-matches '' src | xargs sed -i 's/^\([^ (]*\)_(/\1!(/g' &&
cargo-fmt &&
rg --type rust --files-with-matches '' src | xargs sed -i 's/_(/!(/g'
)
done
# Format the TypeScript projects.
for PROJECT_PATH in \
benchmarks/typescript \
examples/typescript \
integration_tests/typescript_node \
integration_tests/typescript_web
do
(cd "$PROJECT_PATH" && npm ci && npm run format)
done
release:
description: Build and output the release binaries for Linux.
dependencies:
- fetch_crates
input_paths:
- src
output_paths:
- artifacts
command: |
# Add the targets.
rustup target add x86_64-unknown-linux-gnu
rustup target add x86_64-unknown-linux-musl
rustup target add aarch64-unknown-linux-gnu
rustup target add aarch64-unknown-linux-musl
# Set the linkers.
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=x86_64-linux-gnu-gcc
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-gnu-gcc
# Build the project with Cargo for each Linux target.
cargo-online build --release --target x86_64-unknown-linux-gnu
cargo-online build --release --target x86_64-unknown-linux-musl
cargo-online build --release --target aarch64-unknown-linux-gnu
cargo-online build --release --target aarch64-unknown-linux-musl
# Move the binaries to a more conveniennt location for exporting.
mkdir artifacts
cp \
target/x86_64-unknown-linux-gnu/release/typical \
artifacts/typical-x86_64-unknown-linux-gnu
cp \
target/x86_64-unknown-linux-musl/release/typical \
artifacts/typical-x86_64-unknown-linux-musl
cp \
target/aarch64-unknown-linux-gnu/release/typical \
artifacts/typical-aarch64-unknown-linux-gnu
cp \
target/aarch64-unknown-linux-musl/release/typical \
artifacts/typical-aarch64-unknown-linux-musl
publish:
description: Publish the crate to crates.io.
dependencies:
- fetch_crates
environment:
CRATES_IO_TOKEN: null
input_paths:
- README.md
- src
command: |
# Fetch the program version.
VERSION="$(cargo-offline pkgid | grep --extended-regexp --only-matching '[0-9.]+$')"
# If this version of the package already exists on crates.io, there's nothing more to do.
if cargo-online search typical | grep "typical = \"$VERSION\"" > /dev/null; then
echo "Version $VERSION of crate already exists."
exit
fi
# Publish to crates.io.
cargo-online publish --token "$CRATES_IO_TOKEN"