@@ -2,20 +2,18 @@ use super::helpers::*;
22use crate :: config:: v1:: ci:: github:: GithubCiLayer ;
33use crate :: config:: v1:: ci:: { CiLayer , CommonCiLayer } ;
44use crate :: config:: v1:: layer:: { BoolOr , BoolOrOptExt } ;
5- use axoasset:: toml_edit;
5+ use axoasset:: toml_edit:: { self , DocumentMut , Item , Table } ;
66
77pub fn apply ( table : & mut toml_edit:: Table , ci : & Option < CiLayer > ) {
88 let Some ( ci) = ci else {
99 // Nothing to do.
1010 return ;
1111 } ;
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" ) ;
1917
2018 apply_ci_common ( ci_table, & ci. common ) ;
2119
@@ -42,12 +40,11 @@ pub fn apply(table: &mut toml_edit::Table, ci: &Option<CiLayer>) {
4240}
4341
4442fn 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" ) ;
5148
5249 apply_ci_common ( gh_table, & github. common ) ;
5350
@@ -180,3 +177,173 @@ fn apply_ci_common(table: &mut toml_edit::Table, common: &CommonCiLayer) {
180177 common. post_announce_jobs . as_ref ( ) ,
181178 ) ;
182179}
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