@owenlamont/ryl 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/README.md +13 -0
  2. package/bin/ryl.js +195 -1
  3. package/package.json +35 -13
  4. package/.github/CODEOWNERS +0 -1
  5. package/.github/dependabot.yml +0 -13
  6. package/.github/workflows/ci.yml +0 -107
  7. package/.github/workflows/release.yml +0 -613
  8. package/.github/workflows/update_dependencies.yml +0 -61
  9. package/.github/workflows/update_linters.yml +0 -56
  10. package/.pre-commit-config.yaml +0 -87
  11. package/.yamllint +0 -4
  12. package/AGENTS.md +0 -200
  13. package/Cargo.lock +0 -908
  14. package/Cargo.toml +0 -32
  15. package/clippy.toml +0 -1
  16. package/docs/config-presets.md +0 -100
  17. package/img/benchmark-5x5-5runs.svg +0 -2176
  18. package/pyproject.toml +0 -42
  19. package/ruff.toml +0 -107
  20. package/rumdl.toml +0 -20
  21. package/rust-toolchain.toml +0 -3
  22. package/rustfmt.toml +0 -3
  23. package/scripts/benchmark_perf_vs_yamllint.py +0 -400
  24. package/scripts/coverage-missing.ps1 +0 -80
  25. package/scripts/coverage-missing.sh +0 -60
  26. package/src/bin/discover_config_bin.rs +0 -24
  27. package/src/cli_support.rs +0 -33
  28. package/src/conf/mod.rs +0 -85
  29. package/src/config.rs +0 -2099
  30. package/src/decoder.rs +0 -326
  31. package/src/discover.rs +0 -31
  32. package/src/lib.rs +0 -19
  33. package/src/lint.rs +0 -558
  34. package/src/main.rs +0 -535
  35. package/src/migrate.rs +0 -233
  36. package/src/rules/anchors.rs +0 -517
  37. package/src/rules/braces.rs +0 -77
  38. package/src/rules/brackets.rs +0 -77
  39. package/src/rules/colons.rs +0 -475
  40. package/src/rules/commas.rs +0 -372
  41. package/src/rules/comments.rs +0 -299
  42. package/src/rules/comments_indentation.rs +0 -243
  43. package/src/rules/document_end.rs +0 -175
  44. package/src/rules/document_start.rs +0 -84
  45. package/src/rules/empty_lines.rs +0 -152
  46. package/src/rules/empty_values.rs +0 -255
  47. package/src/rules/float_values.rs +0 -259
  48. package/src/rules/flow_collection.rs +0 -562
  49. package/src/rules/hyphens.rs +0 -104
  50. package/src/rules/indentation.rs +0 -803
  51. package/src/rules/key_duplicates.rs +0 -218
  52. package/src/rules/key_ordering.rs +0 -303
  53. package/src/rules/line_length.rs +0 -326
  54. package/src/rules/mod.rs +0 -25
  55. package/src/rules/new_line_at_end_of_file.rs +0 -23
  56. package/src/rules/new_lines.rs +0 -95
  57. package/src/rules/octal_values.rs +0 -121
  58. package/src/rules/quoted_strings.rs +0 -577
  59. package/src/rules/span_utils.rs +0 -37
  60. package/src/rules/trailing_spaces.rs +0 -65
  61. package/src/rules/truthy.rs +0 -420
  62. package/tests/brackets_carriage_return.rs +0 -114
  63. package/tests/build_global_cfg_error.rs +0 -23
  64. package/tests/cli_anchors_rule.rs +0 -143
  65. package/tests/cli_braces_rule.rs +0 -104
  66. package/tests/cli_brackets_rule.rs +0 -104
  67. package/tests/cli_colons_rule.rs +0 -65
  68. package/tests/cli_commas_rule.rs +0 -104
  69. package/tests/cli_comments_indentation_rule.rs +0 -61
  70. package/tests/cli_comments_rule.rs +0 -67
  71. package/tests/cli_config_data_error.rs +0 -30
  72. package/tests/cli_config_flags.rs +0 -66
  73. package/tests/cli_config_migrate.rs +0 -229
  74. package/tests/cli_document_end_rule.rs +0 -92
  75. package/tests/cli_document_start_rule.rs +0 -92
  76. package/tests/cli_empty_lines_rule.rs +0 -87
  77. package/tests/cli_empty_values_rule.rs +0 -68
  78. package/tests/cli_env_config.rs +0 -34
  79. package/tests/cli_exit_and_errors.rs +0 -41
  80. package/tests/cli_file_encoding.rs +0 -203
  81. package/tests/cli_float_values_rule.rs +0 -64
  82. package/tests/cli_format_options.rs +0 -316
  83. package/tests/cli_global_cfg_relaxed.rs +0 -20
  84. package/tests/cli_hyphens_rule.rs +0 -104
  85. package/tests/cli_indentation_rule.rs +0 -65
  86. package/tests/cli_invalid_project_config.rs +0 -39
  87. package/tests/cli_key_duplicates_rule.rs +0 -104
  88. package/tests/cli_key_ordering_rule.rs +0 -59
  89. package/tests/cli_line_length_rule.rs +0 -85
  90. package/tests/cli_list_files.rs +0 -29
  91. package/tests/cli_new_line_rule.rs +0 -141
  92. package/tests/cli_new_lines_rule.rs +0 -119
  93. package/tests/cli_octal_values_rule.rs +0 -60
  94. package/tests/cli_quoted_strings_rule.rs +0 -47
  95. package/tests/cli_toml_config.rs +0 -119
  96. package/tests/cli_trailing_spaces_rule.rs +0 -77
  97. package/tests/cli_truthy_rule.rs +0 -83
  98. package/tests/cli_yaml_files_negation.rs +0 -45
  99. package/tests/colons_rule.rs +0 -303
  100. package/tests/common/compat.rs +0 -114
  101. package/tests/common/fake_env.rs +0 -93
  102. package/tests/common/mod.rs +0 -1
  103. package/tests/conf_builtin.rs +0 -9
  104. package/tests/config_anchors.rs +0 -84
  105. package/tests/config_braces.rs +0 -121
  106. package/tests/config_brackets.rs +0 -127
  107. package/tests/config_commas.rs +0 -79
  108. package/tests/config_comments.rs +0 -65
  109. package/tests/config_comments_indentation.rs +0 -20
  110. package/tests/config_deep_merge_nonstring_key.rs +0 -24
  111. package/tests/config_document_end.rs +0 -54
  112. package/tests/config_document_start.rs +0 -55
  113. package/tests/config_empty_lines.rs +0 -48
  114. package/tests/config_empty_values.rs +0 -35
  115. package/tests/config_env_errors.rs +0 -23
  116. package/tests/config_env_invalid_inline.rs +0 -15
  117. package/tests/config_env_missing.rs +0 -63
  118. package/tests/config_env_shim.rs +0 -301
  119. package/tests/config_explicit_file_parse_error.rs +0 -55
  120. package/tests/config_extended_features.rs +0 -225
  121. package/tests/config_extends_inline.rs +0 -185
  122. package/tests/config_extends_sequence.rs +0 -18
  123. package/tests/config_find_project_home_boundary.rs +0 -54
  124. package/tests/config_find_project_two_files_in_cwd.rs +0 -47
  125. package/tests/config_float_values.rs +0 -34
  126. package/tests/config_from_yaml_paths.rs +0 -32
  127. package/tests/config_hyphens.rs +0 -51
  128. package/tests/config_ignore_errors.rs +0 -243
  129. package/tests/config_ignore_overrides.rs +0 -83
  130. package/tests/config_indentation.rs +0 -65
  131. package/tests/config_invalid_globs.rs +0 -16
  132. package/tests/config_invalid_types.rs +0 -19
  133. package/tests/config_key_duplicates.rs +0 -34
  134. package/tests/config_key_ordering.rs +0 -70
  135. package/tests/config_line_length.rs +0 -65
  136. package/tests/config_locale.rs +0 -111
  137. package/tests/config_merge.rs +0 -26
  138. package/tests/config_new_lines.rs +0 -89
  139. package/tests/config_octal_values.rs +0 -33
  140. package/tests/config_quoted_strings.rs +0 -195
  141. package/tests/config_rule_level.rs +0 -147
  142. package/tests/config_rules_non_string_keys.rs +0 -23
  143. package/tests/config_scalar_overrides.rs +0 -27
  144. package/tests/config_to_toml.rs +0 -110
  145. package/tests/config_toml_coverage.rs +0 -80
  146. package/tests/config_toml_discovery.rs +0 -304
  147. package/tests/config_trailing_spaces.rs +0 -152
  148. package/tests/config_truthy.rs +0 -77
  149. package/tests/config_yaml_files.rs +0 -62
  150. package/tests/config_yaml_files_all_non_string.rs +0 -15
  151. package/tests/config_yaml_files_empty.rs +0 -30
  152. package/tests/coverage_commas.rs +0 -46
  153. package/tests/decoder_decode.rs +0 -338
  154. package/tests/discover_config_bin_all.rs +0 -66
  155. package/tests/discover_config_bin_env_invalid_yaml.rs +0 -26
  156. package/tests/discover_config_bin_project_config_parse_error.rs +0 -24
  157. package/tests/discover_config_bin_user_global_error.rs +0 -26
  158. package/tests/discover_module.rs +0 -30
  159. package/tests/discover_per_file_dir.rs +0 -10
  160. package/tests/discover_per_file_project_config_error.rs +0 -21
  161. package/tests/float_values.rs +0 -43
  162. package/tests/lint_multi_errors.rs +0 -32
  163. package/tests/main_yaml_ok_filtering.rs +0 -30
  164. package/tests/migrate_module.rs +0 -259
  165. package/tests/resolve_ctx_empty_parent.rs +0 -16
  166. package/tests/rule_anchors.rs +0 -442
  167. package/tests/rule_braces.rs +0 -258
  168. package/tests/rule_brackets.rs +0 -217
  169. package/tests/rule_commas.rs +0 -205
  170. package/tests/rule_comments.rs +0 -197
  171. package/tests/rule_comments_indentation.rs +0 -127
  172. package/tests/rule_document_end.rs +0 -118
  173. package/tests/rule_document_start.rs +0 -60
  174. package/tests/rule_empty_lines.rs +0 -96
  175. package/tests/rule_empty_values.rs +0 -102
  176. package/tests/rule_float_values.rs +0 -109
  177. package/tests/rule_hyphens.rs +0 -65
  178. package/tests/rule_indentation.rs +0 -455
  179. package/tests/rule_key_duplicates.rs +0 -76
  180. package/tests/rule_key_ordering.rs +0 -207
  181. package/tests/rule_line_length.rs +0 -200
  182. package/tests/rule_new_lines.rs +0 -51
  183. package/tests/rule_octal_values.rs +0 -53
  184. package/tests/rule_quoted_strings.rs +0 -290
  185. package/tests/rule_trailing_spaces.rs +0 -41
  186. package/tests/rule_truthy.rs +0 -236
  187. package/tests/user_global_invalid_yaml.rs +0 -32
  188. package/tests/yamllint_compat_anchors.rs +0 -280
  189. package/tests/yamllint_compat_braces.rs +0 -411
  190. package/tests/yamllint_compat_brackets.rs +0 -364
  191. package/tests/yamllint_compat_colons.rs +0 -298
  192. package/tests/yamllint_compat_colors.rs +0 -80
  193. package/tests/yamllint_compat_commas.rs +0 -375
  194. package/tests/yamllint_compat_comments.rs +0 -167
  195. package/tests/yamllint_compat_comments_indentation.rs +0 -281
  196. package/tests/yamllint_compat_config.rs +0 -170
  197. package/tests/yamllint_compat_document_end.rs +0 -243
  198. package/tests/yamllint_compat_document_start.rs +0 -136
  199. package/tests/yamllint_compat_empty_lines.rs +0 -117
  200. package/tests/yamllint_compat_empty_values.rs +0 -179
  201. package/tests/yamllint_compat_float_values.rs +0 -216
  202. package/tests/yamllint_compat_hyphens.rs +0 -223
  203. package/tests/yamllint_compat_indentation.rs +0 -398
  204. package/tests/yamllint_compat_key_duplicates.rs +0 -139
  205. package/tests/yamllint_compat_key_ordering.rs +0 -170
  206. package/tests/yamllint_compat_line_length.rs +0 -375
  207. package/tests/yamllint_compat_list.rs +0 -127
  208. package/tests/yamllint_compat_new_line.rs +0 -133
  209. package/tests/yamllint_compat_newline_types.rs +0 -185
  210. package/tests/yamllint_compat_octal_values.rs +0 -172
  211. package/tests/yamllint_compat_quoted_strings.rs +0 -154
  212. package/tests/yamllint_compat_syntax.rs +0 -200
  213. package/tests/yamllint_compat_trailing_spaces.rs +0 -162
  214. package/tests/yamllint_compat_truthy.rs +0 -130
  215. package/tests/yamllint_compat_yaml_files.rs +0 -81
  216. package/typos.toml +0 -2
package/README.md CHANGED
@@ -13,7 +13,11 @@ Compatibility note:
13
13
  ## Quick Start
14
14
 
15
15
  ```bash
16
+ # Using uv (Python)
16
17
  uvx ryl .
18
+
19
+ # Using npx (Node.js)
20
+ npx @owenlamont/ryl .
17
21
  ```
18
22
 
19
23
  For `prek` / `pre-commit` integration, see
@@ -27,6 +31,12 @@ For `prek` / `pre-commit` integration, see
27
31
  uv tool install ryl
28
32
  ```
29
33
 
34
+ ### NPM
35
+
36
+ ```bash
37
+ npm install -g @owenlamont/ryl
38
+ ```
39
+
30
40
  ### pip
31
41
 
32
42
  ```bash
@@ -228,3 +238,6 @@ developer automation, especially:
228
238
  - [saphyr](https://github.com/saphyr-rs/saphyr) - ryl is built on saphyr and saphyr's
229
239
  developers were very patient in showing some of the nuance and complexity of parsing
230
240
  YAML which I was embarrassingly ignorant of when start ryl.
241
+ - [esbuild](https://github.com/evanw/esbuild) and
242
+ [biome](https://github.com/biomejs/biome) - for providing the "binary wrapper"
243
+ blueprint for distributing high-performance native tools via NPM.
package/bin/ryl.js CHANGED
@@ -1 +1,195 @@
1
- console.log('Initializing ryl...');
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const https = require('https');
6
+ const os = require('os');
7
+ const { spawnSync } = require('child_process');
8
+
9
+ const pkg = require('../package.json');
10
+ const version = pkg.version;
11
+ const binName = process.platform === 'win32' ? 'ryl.exe' : 'ryl';
12
+
13
+ // Support user-writable cache directory to avoid EACCES in global installs
14
+ function getCacheDir() {
15
+ if (process.platform === 'win32') {
16
+ return process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
17
+ }
18
+ if (process.platform === 'darwin') {
19
+ return path.join(os.homedir(), 'Library', 'Caches');
20
+ }
21
+ return process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');
22
+ }
23
+
24
+ const rylCacheDir = path.join(getCacheDir(), 'ryl', version);
25
+ const cacheBinPath = path.join(rylCacheDir, binName);
26
+ const localBinPath = path.join(__dirname, binName);
27
+
28
+ const PLATFORMS = {
29
+ darwin: {
30
+ arm64: 'aarch64-apple-darwin'
31
+ },
32
+ linux: {
33
+ x64: 'x86_64-unknown-linux-musl',
34
+ arm64: 'aarch64-unknown-linux-musl',
35
+ arm: 'armv7-unknown-linux-gnueabihf',
36
+ ia32: 'i686-unknown-linux-gnu',
37
+ ppc64: 'powerpc64le-unknown-linux-gnu',
38
+ s390x: 's390x-unknown-linux-gnu'
39
+ },
40
+ win32: {
41
+ x64: 'x86_64-pc-windows-msvc',
42
+ arm64: 'aarch64-pc-windows-msvc'
43
+ }
44
+ };
45
+
46
+ function getBinaryName() {
47
+ const platform = PLATFORMS[process.platform];
48
+ if (!platform) return null;
49
+ const target = platform[process.arch];
50
+ if (!target) return null;
51
+
52
+ if (process.platform === 'win32') {
53
+ return `ryl-${target}.zip`;
54
+ }
55
+ return `ryl-${target}.tar.gz`;
56
+ }
57
+
58
+ function download(url, dest) {
59
+ return new Promise((resolve, reject) => {
60
+ const file = fs.createWriteStream(dest);
61
+ https.get(url, (response) => {
62
+ if (response.statusCode === 302 || response.statusCode === 301) {
63
+ file.close(() => {
64
+ fs.unlink(dest, () => {
65
+ download(response.headers.location, dest).then(resolve).catch(reject);
66
+ });
67
+ });
68
+ return;
69
+ }
70
+ if (response.statusCode !== 200) {
71
+ file.close(() => {
72
+ fs.unlink(dest, () => {
73
+ reject(new Error(`Failed to download binary: ${response.statusCode}`));
74
+ });
75
+ });
76
+ return;
77
+ }
78
+ response.pipe(file);
79
+ file.on('finish', () => {
80
+ file.close();
81
+ resolve();
82
+ });
83
+ }).on('error', (err) => {
84
+ file.close(() => {
85
+ fs.unlink(dest, () => reject(err));
86
+ });
87
+ });
88
+ });
89
+ }
90
+
91
+ async function run() {
92
+ // 0. Try Environment Variable Override
93
+ if (process.env.RYL_BINARY_PATH) {
94
+ execute(process.env.RYL_BINARY_PATH);
95
+ return;
96
+ }
97
+
98
+ // 1. Try Local Bin (for dev/local installs)
99
+ if (fs.existsSync(localBinPath)) {
100
+ execute(localBinPath);
101
+ return;
102
+ }
103
+
104
+ // 2. Try Cache Bin
105
+ if (fs.existsSync(cacheBinPath)) {
106
+ execute(cacheBinPath);
107
+ return;
108
+ }
109
+
110
+ // 3. Install and Execute
111
+ await install();
112
+ execute(cacheBinPath);
113
+ }
114
+
115
+ async function install() {
116
+ const binaryAsset = getBinaryName();
117
+ if (!binaryAsset) {
118
+ console.error(`Unsupported platform/architecture: ${process.platform}/${process.arch}`);
119
+ process.exit(1);
120
+ }
121
+
122
+ // Ensure cache directory exists
123
+ try {
124
+ fs.mkdirSync(rylCacheDir, { recursive: true });
125
+ } catch (err) {
126
+ console.error(`Error creating cache directory ${rylCacheDir}: ${err.message}`);
127
+ process.exit(1);
128
+ }
129
+
130
+ const url = `https://github.com/owenlamont/ryl/releases/download/v${version}/${binaryAsset}`;
131
+ const archivePath = path.join(rylCacheDir, `${binaryAsset}.tmp`);
132
+ const extractDir = path.join(rylCacheDir, `extract-${Date.now()}`);
133
+
134
+ console.log(`Downloading ryl v${version} for ${process.platform}/${process.arch}...`);
135
+ console.log(`Installing to: ${cacheBinPath}`);
136
+
137
+ try {
138
+ await download(url, archivePath);
139
+ fs.mkdirSync(extractDir, { recursive: true });
140
+
141
+ if (process.platform === 'win32') {
142
+ spawnSync('powershell.exe', ['-Command', `Expand-Archive -Path "${archivePath}" -DestinationPath "${extractDir}" -Force`], { stdio: 'inherit' });
143
+ } else {
144
+ spawnSync('tar', ['-xzf', archivePath, '-C', extractDir], { stdio: 'inherit' });
145
+ }
146
+
147
+ const extractedBinPath = path.join(extractDir, binName);
148
+ if (!fs.existsSync(extractedBinPath)) {
149
+ throw new Error(`Binary not found in archive: ${binName}`);
150
+ }
151
+
152
+ // Atomic move
153
+ fs.renameSync(extractedBinPath, cacheBinPath);
154
+
155
+ // Cleanup
156
+ fs.unlinkSync(archivePath);
157
+ fs.rmSync(extractDir, { recursive: true, force: true });
158
+
159
+ if (process.platform !== 'win32') {
160
+ fs.chmodSync(cacheBinPath, 0o755);
161
+ }
162
+ console.log('Successfully installed ryl!');
163
+ } catch (err) {
164
+ console.error(`Error installing ryl binary: ${err.message}`);
165
+ // Cleanup on failure
166
+ if (fs.existsSync(archivePath)) fs.unlinkSync(archivePath);
167
+ if (fs.existsSync(extractDir)) fs.rmSync(extractDir, { recursive: true, force: true });
168
+
169
+ if (process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy) {
170
+ console.error('Note: You are using a proxy; please ensure your environment is configured correctly for Node.js https.get().');
171
+ }
172
+ process.exit(1);
173
+ }
174
+ }
175
+
176
+ function execute(binPath) {
177
+ const result = spawnSync(binPath, process.argv.slice(2), {
178
+ stdio: 'inherit',
179
+ windowsHide: true
180
+ });
181
+
182
+ if (result.error) {
183
+ console.error(`Error executing binary at ${binPath}: ${result.error.message}`);
184
+ process.exit(1);
185
+ }
186
+
187
+ if (result.status === null) {
188
+ console.error('Binary execution failed (no exit status)');
189
+ process.exit(1);
190
+ }
191
+
192
+ process.exit(result.status);
193
+ }
194
+
195
+ run();
package/package.json CHANGED
@@ -1,28 +1,50 @@
1
1
  {
2
- "name": "@owenlamont/ryl",
3
- "version": "0.4.1",
4
- "description": "Fast YAML linter inspired by yamllint",
5
- "main": "index.js",
2
+ "author": "Owen Lamont",
6
3
  "bin": {
7
4
  "ryl": "bin/ryl.js"
8
5
  },
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/owenlamont/ryl.git"
6
+ "bugs": {
7
+ "url": "https://github.com/owenlamont/ryl/issues"
8
+ },
9
+ "cpu": [
10
+ "x64",
11
+ "arm64",
12
+ "arm",
13
+ "ia32",
14
+ "ppc64",
15
+ "s390x"
16
+ ],
17
+ "description": "Fast YAML linter inspired by yamllint",
18
+ "engines": {
19
+ "node": ">=18.0.0"
12
20
  },
21
+ "files": [
22
+ "bin/",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "homepage": "https://github.com/owenlamont/ryl#readme",
13
27
  "keywords": [
14
28
  "yaml",
15
29
  "lint",
16
30
  "cli",
17
31
  "rust"
18
32
  ],
19
- "author": "Owen Lamont",
20
33
  "license": "MIT",
21
- "bugs": {
22
- "url": "https://github.com/owenlamont/ryl/issues"
23
- },
24
- "homepage": "https://github.com/owenlamont/ryl#readme",
34
+ "name": "@owenlamont/ryl",
35
+ "os": [
36
+ "darwin",
37
+ "linux",
38
+ "win32"
39
+ ],
25
40
  "publishConfig": {
26
41
  "access": "public"
27
- }
42
+ },
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/owenlamont/ryl.git"
46
+ },
47
+ "sideEffects": false,
48
+ "type": "commonjs",
49
+ "version": "0.4.2"
28
50
  }
@@ -1 +0,0 @@
1
- * @owenlamont
@@ -1,13 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: "github-actions"
4
- directory: "/"
5
- schedule:
6
- interval: "weekly"
7
- day: "friday"
8
- groups:
9
- actions-dependencies:
10
- patterns:
11
- - "*"
12
- cooldown:
13
- default-days: 7
@@ -1,107 +0,0 @@
1
- name: CI
2
- on:
3
- pull_request:
4
- jobs:
5
- checks:
6
- runs-on: ubuntu-latest
7
- permissions:
8
- contents: read
9
- pull-requests: write
10
- steps:
11
- - name: Checkout repository
12
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
13
-
14
- - name: Install uv
15
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78
16
-
17
- - name: Install prek
18
- run: uv tool install prek --force
19
-
20
- - name: Install yamllint
21
- run: |
22
- uv tool install yamllint --force
23
- yamllint --version
24
-
25
- - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
26
-
27
- - name: Install Rust components
28
- run: rustup component add rustfmt clippy llvm-tools-preview
29
-
30
- - name: Install cargo-nextest
31
- uses: taiki-e/install-action@6cc14f7f2f4b3129aff07a8b071d2d4f2733465d
32
- with:
33
- tool: cargo-nextest
34
-
35
- - name: Install cargo-llvm-cov
36
- uses: taiki-e/install-action@6cc14f7f2f4b3129aff07a8b071d2d4f2733465d
37
- with:
38
- tool: cargo-llvm-cov
39
-
40
- - name: Run prek hooks (lint and static checks)
41
- env:
42
- SKIP: no-commit-to-branch,nextest
43
- run: prek run --all-files
44
-
45
- - name: Run tests with coverage (nextest + cargo-llvm-cov)
46
- run: |
47
- set -euo pipefail
48
- echo '### Test Coverage (nextest + cargo-llvm-cov)' > coverage.md
49
- echo '```text' >> coverage.md
50
- cargo llvm-cov nextest --summary-only | tee -a coverage.md
51
- echo '```' >> coverage.md
52
- # Produce LCOV for detailed per-line/branch analysis
53
- cargo llvm-cov nextest --lcov --output-path lcov.info
54
- echo '' >> coverage.md
55
- echo '#### Missed Lines (per file)' >> coverage.md
56
- awk -F: '
57
- /^SF:/ {f=$2}
58
- /^DA:/ {split($2,a,","); if (a[2]==0) lines[f]=lines[f] a[1] ","}
59
- END {
60
- for (f in lines) {
61
- gsub(/,$/, "", lines[f]);
62
- printf("- %s: %s\n", f, lines[f]);
63
- }
64
- }
65
- ' lcov.info | sort >> coverage.md || true
66
- echo '' >> coverage.md
67
- if grep -q '^BRDA:' lcov.info; then
68
- echo '#### Missed Branches (per file)' >> coverage.md
69
- awk -F: '
70
- /^SF:/ {f=$2}
71
- /^BRDA:/ {
72
- split($2,a,",");
73
- # a[4] is taken count; treat 0 or - as missed
74
- if (a[4]=="-" || a[4]==0) {
75
- branches[f]=branches[f] sprintf("%s(b%s)", a[1], a[3]) ",";
76
- }
77
- }
78
- END {
79
- for (f in branches) {
80
- gsub(/,$/, "", branches[f]);
81
- printf("- %s: %s\n", f, branches[f]);
82
- }
83
- }
84
- ' lcov.info | sort >> coverage.md || true
85
- fi
86
-
87
- - name: Upload coverage artifacts
88
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
89
- with:
90
- name: coverage
91
- path: |
92
- coverage.md
93
- lcov.info
94
-
95
- - name: Comment coverage summary on PR
96
- if: github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork
97
- uses: marocchino/sticky-pull-request-comment@70d2764d1a7d5d9560b100cbea0077fc8f633987
98
- with:
99
- header: ryl-coverage
100
- path: coverage.md
101
-
102
- - name: Enforce coverage thresholds
103
- run: |
104
- # Enforce zero missed lines and regions
105
- cargo llvm-cov nextest --summary-only \
106
- --fail-uncovered-lines 0 \
107
- --fail-uncovered-regions 0