@@ -298,6 +298,8 @@ x.install-tools() {
298298 " go install github.com/maxbrunsfeld/counterfeiter/v6@latest"
299299 " go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1"
300300 " go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2"
301+ # vacuum lint openapi.exploded.yaml -ed
302+ " go install github.com/daveshanley/vacuum@latest"
301303 )
302304 for command in " ${commands[@]} " ; do
303305 $command &
@@ -343,48 +345,13 @@ x.gen.pregen() {
343345 echo " Running generation"
344346
345347 # NOTE: swaggest won't generate for arrays of structs. use a struct with array fields instead.
346- generate_structs_map # structs might have been removed in the meantime
348+ generate_structs_map # spec structs or their content in rest package might have changed
347349
348- go build -o $BUILD_DIR /codegen cmd/codegen/main.go || mark_failed_tool_build # xo gen may create/update models.
350+ go build -o $BUILD_DIR /codegen cmd/codegen/main.go || mark_failed_tool_build
349351
350352 local rest_structs=() refs=() spec_schemas=()
351- declare -A rest_schema_lookup spec_schema_lookup
352353
353- go-utils.find_structs rest_structs " $REST_MODELS "
354- for schema in " ${rest_structs[@]} " ; do # only interested in generating rest models.spec.go schemas. let the rest fail normally.
355- rest_schema_lookup[" $schema " ]=1
356- done
357-
358- mapfile -t spec_schemas < <( yq eval ' .components.schemas[] | key' " $SPEC_PATH " )
359- for schema in " ${spec_schemas[@]} " ; do # only interested in generating rest models.spec.go schemas. let the rest fail.
360- spec_schema_lookup[" $schema " ]=1
361- done
362-
363- local missing_rest_models=()
364- mapfile -t refs < <( sed -nr " s/[^#]?.*\\ $ref : '#\/components\/schemas\/(.*)'/\1/p" $SPEC_PATH | sort | uniq)
365- for ref in " ${refs[@]} " ; do
366- if [[ -n " ${rest_schema_lookup["$ref"]} " && -z " ${spec_schema_lookup["$ref"]} " ]]; then
367- missing_rest_models+=(" $ref " )
368- fi
369- done
370-
371- if [[ ${# missing_rest_models[@]} -gt 0 ]]; then
372- echo " ${YELLOW} Generating missing rest package \$ ref's:"
373- printf " ${YELLOW} - %s\n" " ${missing_rest_models[@]} "
374- echo " ${OFF} "
375-
376- local new_schemas=" "
377- for ref in " ${missing_rest_models[@]} " ; do
378- new_schemas+=" \" $ref \" : {
379- \" x-gen-struct\" : \" $ref \" ,
380- \" x-is-generated\" : true
381- },"
382- done
383-
384- yq eval-all " .components.schemas += {
385- ${new_schemas% ,}
386- }" -i " $SPEC_PATH "
387- fi
354+ generate_missing_spec_schemas
388355
389356 codegen validate-spec -env=" .env.$X_ENV "
390357 # useless after merging models and db
@@ -394,40 +361,87 @@ x.gen.pregen() {
394361
395362 # ####### Ensure consistent style for future codegen
396363
397- echo " Applying PascalCase to operation IDs in $SPEC_PATH "
364+ pascal_case_spec_operation_ids
365+
366+ update_roles_and_scopes
367+
368+ validate_spec
369+ codegen pre -env=" .env.$X_ENV " -op-id-auth=" $OPID_AUTH_PATH "
370+ update_spec_with_structs
371+ remove_schemas_marked_for_deletion
372+ } 2>&4 | xlog >&3 ; } 4>&1 | xerr >&3 ; } 3>&1
373+ xsetup.backup.cleanup
374+ }
375+
376+ pascal_case_spec_operation_ids () {
377+ echo " Applying PascalCase to operation IDs"
398378
399- # outputs safe double-quoted paths for yq
400- # https://github.com/mikefarah/yq/issues/1295
401- mapfile -t opid_paths < <( yq e '
379+ # outputs safe double-quoted paths for yq
380+ # https://github.com/mikefarah/yq/issues/1295
381+ mapfile -t opid_paths < <( yq e '
402382 .paths[][].operationId
403383 | path
404384 | with(.[] | select(contains(".") or contains("/") or contains("{")); . = "\"" + . + "\"")
405385 | join(".")
406386 ' $SPEC_PATH )
407- mapfile -t opids < <( yq e " .paths[][].operationId" $SPEC_PATH )
387+ mapfile -t opids < <( yq e " .paths[][].operationId" $SPEC_PATH )
408388
409- local ops=" "
410- for i in ${! opids[@]} ; do
411- local new_opid=" "
412- to_pascal new_opid " ${opids[$i]} "
413- ops+=" .${opid_paths[$i]} =\" ${new_opid} \" |" # cant have space
414- done
389+ local ops=" "
390+ for i in ${! opids[@]} ; do
391+ local new_opid=" "
392+ to_pascal new_opid " ${opids[$i]} "
393+ ops+=" .${opid_paths[$i]} =\" ${new_opid} \" |" # cant have space
394+ done
395+
396+ yq_op=" ${ops% " |" } "
415397
416- yq_op=" ${ops% " |" } "
398+ yq e " $yq_op " -i " $SPEC_PATH "
399+ }
417400
418- yq e " $yq_op " -i " $SPEC_PATH "
401+ # ext vars: spec_schemas, rest_structs
402+ generate_missing_spec_schemas () {
403+ declare -A rest_schema_lookup spec_schema_lookup
419404
420- update_roles_and_scopes
405+ go-utils.find_structs rest_structs " $REST_MODELS "
406+ for schema in " ${rest_structs[@]} " ; do # only interested in generating rest models.spec.go schemas. let the rest fail normally.
407+ rest_schema_lookup[" $schema " ]=1
408+ done
421409
422- validate_spec
423- codegen pre -env=" .env.$X_ENV " -op-id-auth=" $OPID_AUTH_PATH " # should not edit spec
424- update_spec_with_structs
425- remove_schemas_marked_for_deletion
426- } 2>&4 | xlog >&3 ; } 4>&1 | xerr >&3 ; } 3>&1
427- xsetup.backup.cleanup
410+ mapfile -t spec_schemas < <( yq eval ' .components.schemas[] | key' " $SPEC_PATH " )
411+ for schema in " ${spec_schemas[@]} " ; do # only interested in generating rest models.spec.go schemas. let the rest fail.
412+ spec_schema_lookup[" $schema " ]=1
413+ done
414+
415+ local missing_rest_models=()
416+ mapfile -t refs < <( sed -nr " s/[^#]?.*\\ $ref : '#\/components\/schemas\/(.*)'/\1/p" $SPEC_PATH | sort | uniq)
417+ for ref in " ${refs[@]} " ; do
418+ if [[ -n " ${rest_schema_lookup["$ref"]} " && -z " ${spec_schema_lookup["$ref"]} " ]]; then
419+ missing_rest_models+=(" $ref " )
420+ fi
421+ done
422+
423+ if [[ ${# missing_rest_models[@]} -gt 0 ]]; then
424+ echo " ${YELLOW} Generating missing rest package \$ ref's:"
425+ printf " ${YELLOW} - %s\n" " ${missing_rest_models[@]} "
426+ echo " ${OFF} "
427+
428+ local new_schemas=" "
429+ for ref in " ${missing_rest_models[@]} " ; do
430+ new_schemas+=" \" $ref \" : {
431+ \" x-gen-struct\" : \" $ref \" ,
432+ \" x-is-generated\" : true
433+ },"
434+ done
435+
436+ yq eval-all " .components.schemas += {
437+ ${new_schemas% ,}
438+ }" -i " $SPEC_PATH "
439+ fi
428440}
429441
430442validate_spec () {
443+ echo " Validating spec $SPEC_PATH "
444+
431445 mapfile -t invalid_schemas < <( yq e ' .components.schemas[] | select(has("x-gen-struct") and (has("x-is-generated") | not)) | key' $SPEC_PATH )
432446 [[ ${# invalid_schemas[@]} -gt 0 ]] && err " x-gen-struct can only be used in generated schemas (x-is-generated). Found in:
433447$( join_by $' \n ' " ${invalid_schemas[@]} " ) "
@@ -465,7 +479,7 @@ $(join_by $'\n' "${services_prefix_clashes[@]}")"
465479}
466480
467481update_roles_and_scopes () {
468- echo " Updating roles and scopes in $SPEC_PATH "
482+ echo " Updating roles and scopes"
469483 # ####### Sync spec enums with external policy sources and validate existing schema enums.
470484 # ####### External json files are the source of truth, indexed by enum name
471485 # arrays can't be nested in bash
@@ -959,7 +973,7 @@ additional-imports:
959973EOF
960974 )
961975 # IMPORTANT: additional-imports packages affect x-go extensions
962- # see https://github.com/deepmap /oapi-codegen?tab=readme-ov-file#openapi-extensions
976+ # see https://github.com/oapi-codegen /oapi-codegen?tab=readme-ov-file#openapi-extensions
963977
964978 # TODO: we already have structs.gen.go indexed by "Models(models struct)" or plain rest type...
965979 # however this might be faster if the build is cached (templates unchanged). could construct internally as map set anyway
@@ -1086,7 +1100,7 @@ x.gen.frontend() {
10861100 mkdir -p frontend/src/types
10871101 rm -rf $FRONTEND_GEN
10881102
1089- yq ' explode(.)' $SPEC_PATH > $exploded_spec # js-lib won't support anchors - used by most gen libs
1103+ yq ' explode(.)' $SPEC_PATH > $exploded_spec # js-yaml wont support explicit tags - used by most gen libs
10901104
10911105 {
10921106 node frontend/scripts/generate-client-validator.js
@@ -1160,8 +1174,6 @@ x.gen() {
11601174
11611175 wait_without_error || err Failed jobs
11621176
1163- x.test.xo
1164-
11651177 {
11661178 x.gen.pregen
11671179 x.gen.client-server
@@ -1189,7 +1201,9 @@ x.gen() {
11891201# Build code generation custom tools.
11901202x.gen.build-tools () {
11911203 { { {
1192- generate_structs_map # openapi-go requires structs already compiled
1204+ # openapi-go via codegen cli requires structs already compiled, but we will rebuild
1205+ # right before codegen gen-schema since PublicStructs is not used anywhere else inside codegen
1206+ # generate_structs_map
11931207
11941208 out_dir=$BUILD_DIR
11951209
@@ -2536,6 +2550,7 @@ find_deleted_pkg_schemas() {
25362550 local pkg=" $2 "
25372551 local pkg_prefix=" "
25382552 to_pascal pkg_prefix " $pkg "
2553+
25392554 echo " Finding deleted structs or enums from package '$pkg_prefix '..."
25402555 mapfile -t spec_schemas < <( yq eval ' .components.schemas[] | key' " $SPEC_PATH " | grep -E " ^${pkg_prefix} " || true)
25412556
@@ -2552,6 +2567,8 @@ find_deleted_pkg_schemas() {
25522567}
25532568
25542569update_spec_with_structs () {
2570+ echo " Updating spec with rest package structs"
2571+
25552572 mapfile -t structs_to_generate < <( yq e ' .components.schemas[] | select(has("x-gen-struct")).x-gen-struct' $SPEC_PATH )
25562573
25572574 local rest_structs=()
@@ -2635,6 +2652,8 @@ update_spec_with_structs() {
26352652}
26362653
26372654remove_schemas_marked_for_deletion () {
2655+ echo " Removing schemas marked for deletion"
2656+
26382657 local paths_arr paths
26392658 paths_arr=$( yq e ' ..
26402659 | select(has("x-TO-BE-DELETED"))
0 commit comments