@@ -2,20 +2,18 @@ use super::helpers::*;
2
2
use crate :: config:: v1:: ci:: github:: GithubCiLayer ;
3
3
use crate :: config:: v1:: ci:: { CiLayer , CommonCiLayer } ;
4
4
use crate :: config:: v1:: layer:: { BoolOr , BoolOrOptExt } ;
5
- use axoasset:: toml_edit;
5
+ use axoasset:: toml_edit:: { self , DocumentMut , Item , Table } ;
6
6
7
7
pub fn apply ( table : & mut toml_edit:: Table , ci : & Option < CiLayer > ) {
8
8
let Some ( ci) = ci else {
9
9
// Nothing to do.
10
10
return ;
11
11
} ;
12
- let Some ( ci_table) = table. get_mut ( "ci" ) else {
13
- // Nothing to do.
14
- return ;
15
- } ;
16
- let toml_edit:: Item :: Table ( ci_table) = ci_table else {
17
- panic ! ( "Expected [dist.ci] to be a table" ) ;
18
- } ;
12
+ let ci_table = table
13
+ . entry ( "ci" )
14
+ . or_insert ( Item :: Table ( Table :: new ( ) ) )
15
+ . as_table_mut ( )
16
+ . expect ( "[dist.ci] should be a table" ) ;
19
17
20
18
apply_ci_common ( ci_table, & ci. common ) ;
21
19
@@ -42,12 +40,11 @@ pub fn apply(table: &mut toml_edit::Table, ci: &Option<CiLayer>) {
42
40
}
43
41
44
42
fn apply_ci_github ( ci_table : & mut toml_edit:: Table , github : & GithubCiLayer ) {
45
- let Some ( gh_table) = ci_table. get_mut ( "github" ) else {
46
- return ;
47
- } ;
48
- let toml_edit:: Item :: Table ( gh_table) = gh_table else {
49
- panic ! ( "Expected [dist.ci.github] to be a table" ) ;
50
- } ;
43
+ let gh_table = ci_table
44
+ . entry ( "github" )
45
+ . or_insert ( Item :: Table ( Table :: new ( ) ) )
46
+ . as_table_mut ( )
47
+ . expect ( "[dist.ci.github] should be a table" ) ;
51
48
52
49
apply_ci_common ( gh_table, & github. common ) ;
53
50
@@ -180,3 +177,173 @@ fn apply_ci_common(table: &mut toml_edit::Table, common: &CommonCiLayer) {
180
177
common. post_announce_jobs . as_ref ( ) ,
181
178
) ;
182
179
}
180
+
181
+ #[ cfg( test) ]
182
+ mod test {
183
+ use super :: * ;
184
+ use crate :: config:: JobStyle ;
185
+ use miette:: IntoDiagnostic ;
186
+
187
+ fn source ( ) -> toml_edit:: DocumentMut {
188
+ let src = axoasset:: SourceFile :: new ( "fake-dist-workspace.toml" , String :: new ( ) ) ;
189
+ let doc = src. deserialize_toml_edit ( ) . into_diagnostic ( ) . unwrap ( ) ;
190
+ doc
191
+ }
192
+
193
+ // Given a DocumentMut, make sure it has a [dist] table, and return
194
+ // a reference to that dist table.
195
+ fn dist_table ( doc : & mut toml_edit:: DocumentMut ) -> & mut toml_edit:: Table {
196
+ let dist = doc
197
+ . entry ( "dist" )
198
+ . or_insert ( Item :: Table ( Table :: new ( ) ) )
199
+ . as_table_mut ( )
200
+ . unwrap ( ) ;
201
+ // Don't show the empty top-level [dist].
202
+ dist. set_implicit ( true ) ;
203
+ // Return the table we just created.
204
+ dist
205
+ }
206
+
207
+ #[ test]
208
+ fn apply_ci_empty ( ) {
209
+ let expected = "" ;
210
+
211
+ let ci = Some ( CiLayer {
212
+ common : CommonCiLayer {
213
+ merge_tasks : None ,
214
+ fail_fast : None ,
215
+ cache_builds : None ,
216
+ build_local_artifacts : None ,
217
+ dispatch_releases : None ,
218
+ release_branch : None ,
219
+ pr_run_mode : None ,
220
+ tag_namespace : None ,
221
+ plan_jobs : None ,
222
+ build_local_jobs : None ,
223
+ build_global_jobs : None ,
224
+ host_jobs : None ,
225
+ publish_jobs : None ,
226
+ post_announce_jobs : None ,
227
+ } ,
228
+ github : None ,
229
+ } ) ;
230
+
231
+ let mut doc = source ( ) ;
232
+ let table = dist_table ( & mut doc) ;
233
+
234
+ apply ( table, & ci) ;
235
+
236
+ let toml_text = table. to_string ( ) ;
237
+ assert_eq ! ( toml_text, expected) ;
238
+ }
239
+
240
+ #[ test]
241
+ fn apply_ci_everything ( ) {
242
+ let expected = r#"
243
+ # CI configuration for dist
244
+ [dist.ci]
245
+ # Whether to run otherwise-parallelizable tasks on the same machine
246
+ merge-tasks = true
247
+ # Whether failing tasks should make us give up on all other tasks
248
+ fail-fast = true
249
+ # Whether builds should try to be cached in CI
250
+ cache-builds = true
251
+ # Whether CI should include auto-generated code to build local artifacts
252
+ build-local-artifacts = true
253
+ # Whether CI should trigger releases with dispatches instead of tag pushes
254
+ dispatch-releases = true
255
+ # Trigger releases on pushes to this branch instead of tag pushes
256
+ release-branch = "main"
257
+ # Which actions to run on pull requests
258
+ pr-run-mode = "skip"
259
+ # A prefix git tags must include for dist to care about them
260
+ tag-namespace = "some-namespace"
261
+ # Additional plan jobs to run in CI
262
+ plan-jobs = ["./plan-job"]
263
+ # Additional local artifacts jobs to run in CI
264
+ build-local-jobs = ["./build-local-job-1", "./build-local-job-2"]
265
+ # Additional global artifacts jobs to run in CI
266
+ build-global-jobs = ["./build-global-job"]
267
+ # Additional hosts jobs to run in CI
268
+ host-jobs = ["./host-job"]
269
+ # Additional publish jobs to run in CI
270
+ publish-jobs = ["./publish-job"]
271
+ # Additional jobs to run in CI, after the announce job finishes
272
+ post-announce-jobs = ["./post-announce-job"]
273
+ # Whether dist should generate workflows for GitHub CI
274
+ github = true
275
+ "# ;
276
+
277
+ let ci = Some ( CiLayer {
278
+ common : CommonCiLayer {
279
+ merge_tasks : Some ( true ) ,
280
+ fail_fast : Some ( true ) ,
281
+ cache_builds : Some ( true ) ,
282
+ build_local_artifacts : Some ( true ) ,
283
+ dispatch_releases : Some ( true ) ,
284
+ release_branch : Some ( "main" . to_string ( ) ) ,
285
+ pr_run_mode : Some ( dist_schema:: PrRunMode :: Skip ) ,
286
+ tag_namespace : Some ( "some-namespace" . to_string ( ) ) ,
287
+ plan_jobs : Some ( vec ! [
288
+ "./plan-job" . parse( ) . unwrap( ) ,
289
+ ] ) ,
290
+ build_local_jobs : Some ( vec ! [
291
+ "./build-local-job-1" . parse( ) . unwrap( ) ,
292
+ "./build-local-job-2" . parse( ) . unwrap( ) ,
293
+ ] ) ,
294
+ build_global_jobs : Some ( vec ! [
295
+ "./build-global-job" . parse( ) . unwrap( ) ,
296
+ ] ) ,
297
+ host_jobs : Some ( vec ! [
298
+ "./host-job" . parse( ) . unwrap( ) ,
299
+ ] ) ,
300
+ publish_jobs : Some ( vec ! [
301
+ "./publish-job" . parse( ) . unwrap( ) ,
302
+ ] ) ,
303
+ post_announce_jobs : Some ( vec ! [
304
+ "./post-announce-job" . parse( ) . unwrap( ) ,
305
+ ] ) ,
306
+ } ,
307
+ github : Some ( BoolOr :: Bool ( true ) ) ,
308
+ } ) ;
309
+
310
+ let mut doc = source ( ) ;
311
+ let table = dist_table ( & mut doc) ;
312
+
313
+ apply ( table, & ci) ;
314
+
315
+ let toml_text = doc. to_string ( ) ;
316
+ assert_eq ! ( expected, toml_text) ;
317
+ }
318
+
319
+ #[ test]
320
+ fn apply_ci_gh_complex ( ) {
321
+ let expected = r#"
322
+ # CI configuration for dist
323
+ [dist.ci]
324
+
325
+ # Configure generated workflows for GitHub CI
326
+ [dist.ci.github]
327
+ build-setup = "build-setup"
328
+ "# ;
329
+
330
+ let ci = Some ( CiLayer {
331
+ common : CommonCiLayer :: default ( ) ,
332
+ github : Some ( BoolOr :: Val ( GithubCiLayer {
333
+ common : CommonCiLayer :: default ( ) ,
334
+ build_setup : Some ( "build-setup" . to_string ( ) ) ,
335
+ permissions : None ,
336
+ runners : None ,
337
+ } ) ) ,
338
+ } ) ;
339
+
340
+ let mut doc = source ( ) ;
341
+ let table = dist_table ( & mut doc) ;
342
+
343
+ apply ( table, & ci) ;
344
+
345
+ let toml_text = doc. to_string ( ) ;
346
+ assert_eq ! ( expected, toml_text) ;
347
+
348
+ }
349
+ }
0 commit comments