diff --git a/.github/script_helpers/extract_flags.awk b/.github/script_helpers/extract_flags.awk index ac0dc96f..e5d1eeb7 100644 --- a/.github/script_helpers/extract_flags.awk +++ b/.github/script_helpers/extract_flags.awk @@ -1,4 +1,68 @@ -/^flag / { flag=$2; in_desc=0 } -/^ *description:/ { in_desc=1; if ($0 ~ /\(experimental\)/) print flag; next } -in_desc && /^[[:space:]]+/ { if ($0 ~ /\(experimental\)/) print flag; next } -/^[^[:space:]]/ { in_desc=0 } +# Purpose: +# - If EXPERIMENTAL_ONLY is non-empty -> print flags that contain "(experimental)" +# - If EXPERIMENTAL_ONLY is empty -> print flags that contain NO parentheses at all + +# Per-flag state +# flag - current flag name +# in_desc - currently inside a description block +# experimental - description contains "(experimental)" +# has_parens - description contains ANY "(...)" +# +# Policy: +# experimental-only mode → only print flags marked experimental +# default mode → only print flags without ANY parentheses + +# Compiled regexes for readability +BEGIN { + exp_rx = "\\(experimental\\)" + paren_rx = "\\([^)]*\\)" +} + +# Decide whether to print the current flag +function should_print() { + if (EXPERIMENTAL_ONLY != "" && experimental) return 1 + if (EXPERIMENTAL_ONLY == "" && !has_parens) return 1 + return 0 +} + +# Output a completed flag if appropriate +function finalize_flag() { + if (flag != "" && should_print()) { + print flag + } +} + +# Start of flag block +/^flag[[:space:]]+/ { + finalize_flag() # finish previous flag first + flag = $2 + in_desc = 0 + experimental = 0 + has_parens = 0 + next +} + +# Description start line +/^ *description:/ { + in_desc = 1 + if ($0 ~ exp_rx) experimental = 1 + if ($0 ~ paren_rx) has_parens = 1 + next +} + +# Description continuation (indented) +/^[[:space:]]+/ && in_desc { + if ($0 ~ exp_rx) experimental = 1 + if ($0 ~ paren_rx) has_parens = 1 + next +} + +# Any non-indented line ends description +/^[^[:space:]]/ { + in_desc = 0 +} + +# EOF, finalize last flag +END { + finalize_flag() +} diff --git a/.github/scripts/add_experimental_flags.sh b/.github/scripts/add_experimental_flags.sh index f2eeca50..446d5e0f 100644 --- a/.github/scripts/add_experimental_flags.sh +++ b/.github/scripts/add_experimental_flags.sh @@ -17,15 +17,20 @@ fi MATRIX_JSON=$(sed -E 's/^matrix=//' <"$MATRIX_FILE") -readarray -t EXP_FLAGS < <(awk -f ./.github/script_helpers/extract_flags.awk "$CABAL_FILE") +readarray -t STABLE_FLAGS < <(awk -f ./.github/script_helpers/extract_flags.awk "$CABAL_FILE") +readarray -t EXP_FLAGS < <(awk -v EXPERIMENTAL_ONLY=1 -f ./.github/script_helpers/extract_flags.awk "$CABAL_FILE") -ORIGINAL=$(jq --arg label "stable" '.include[0] += {label: $label}' <<<"$MATRIX_JSON") +STABLE_FLAGS_STRING="" +if ! [[ ${#STABLE_FLAGS[@]} -eq 0 ]]; then + STABLE_FLAGS_STRING=$(printf '+%s ' "${STABLE_FLAGS[@]}") +fi +ORIGINAL=$(jq --arg flags "$STABLE_FLAGS_STRING" --arg label "stable" '.include[0] += {flags: $flags, label: $label}' <<<"$MATRIX_JSON") if [[ ${#EXP_FLAGS[@]} -eq 0 ]]; then UPDATED="$ORIGINAL" else EXP_FLAGS_STRING=$(printf '+%s ' "${EXP_FLAGS[@]}") - EXPERIMENTAL=$(jq --arg flags "$EXP_FLAGS_STRING" --arg label "experimental" \ + EXPERIMENTAL=$(jq --arg flags "$STABLE_FLAGS_STRING $EXP_FLAGS_STRING" --arg label "experimental" \ '.include[0] += {flags: $flags, label: $label}' <<<"$MATRIX_JSON") UPDATED=$(jq --argjson exp_include "$(jq '.include' <<<"$EXPERIMENTAL")" \ diff --git a/.github/scripts/configure_project.sh b/.github/scripts/configure_project.sh index f565327a..9b69ddb7 100644 --- a/.github/scripts/configure_project.sh +++ b/.github/scripts/configure_project.sh @@ -2,24 +2,15 @@ set -euo pipefail -IS_EXPERIMENTAL=0 - cabal configure --project-file cabal.project.release -O1 -if [[ "$LABEL" == "" ]]; then - echo "LABEL must be set" -elif [[ "$LABEL" == "experimental" ]]; then - IS_EXPERIMENTAL=1 -fi - -echo "package jbeam-edit" >>cabal.project.release.local -echo " tests: True" >>cabal.project.release.local +printf "package jbeam-edit\n tests: True\n" >>cabal.project.release.local if echo "$MATRIX_FLAGS" | grep -qa ' +transformation '; then echo " benchmarks: True" >>cabal.project.release.local fi -if [[ $IS_EXPERIMENTAL -eq 1 ]]; then +if ! [[ "$MATRIX_FLAGS" == "" ]]; then echo " flags: $MATRIX_FLAGS" >>cabal.project.release.local fi diff --git a/.github/scripts/extract_resolver_and_flags_for_stack.sh b/.github/scripts/extract_resolver_and_flags_for_stack.sh index 2e44f106..7b5e6d3e 100644 --- a/.github/scripts/extract_resolver_and_flags_for_stack.sh +++ b/.github/scripts/extract_resolver_and_flags_for_stack.sh @@ -4,15 +4,24 @@ set -euo pipefail CABAL_FILE="${CABAL_FILE:?Environment variable CABAL_FILE is required}" -readarray -t EXP_FLAGS < <(awk -f ./.github/script_helpers/extract_flags.awk "$CABAL_FILE") +readarray -t STABLE_FLAGS < <(awk -f ./.github/script_helpers/extract_flags.awk "$CABAL_FILE") +readarray -t EXP_FLAGS < <(awk -v EXPERIMENTAL_ONLY=1 -f ./.github/script_helpers/extract_flags.awk "$CABAL_FILE") echo "extracting experimental flags and setting them to true." echo "if this fails, please verify all flags in package.yaml are set to true/false in stack.yaml" -for flag in "${EXP_FLAGS[@]}"; do - pattern="^( *${flag})[[:space:]]*:[[:space:]]*(true|false)" - grep -qE "${pattern}" stack.yaml - sed -i -E "s/${pattern}/\1: true/g" stack.yaml -done + +update_flags() { + local flags=("$@") + for flag in "${flags[@]}"; do + local pattern="^( *${flag})[[:space:]]*:[[:space:]]*(true|false)" + if grep -qE "${pattern}" stack.yaml; then + sed -i -E "s/${pattern}/\1: true/g" stack.yaml + fi + done +} + +update_flags "${STABLE_FLAGS[@]}" +update_flags "${EXP_FLAGS[@]}" echo "contents of stack.yaml file:" cat stack.yaml diff --git a/README.md b/README.md index bc76b28a..2e611bd4 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,12 @@ cabal update cabal install jbeam-edit your-file.jbeam ``` +## Tags in flag descriptions + +- **(experimental)**: functionality under active development +- **(dev-only)**: tools and commands intended for developers +- **(windows-installer-only)**: used only in Windows installer builds +- Untagged flags are considered to be stable. ## Examples diff --git a/jbeam-edit.cabal b/jbeam-edit.cabal index 51edd933..a9fc3aa1 100644 --- a/jbeam-edit.cabal +++ b/jbeam-edit.cabal @@ -50,7 +50,7 @@ flag dump-ast manual: True flag lsp-server - description: Enable LSP server (experimental) + description: Enable LSP server default: False manual: True @@ -65,7 +65,7 @@ flag transformation flag windows-example-paths description: - Use executable-relative example paths (for Windows release builds) + Use executable-relative example paths (windows-installer-only) default: False manual: True diff --git a/package.yaml b/package.yaml index 106cf6cf..e687f17b 100644 --- a/package.yaml +++ b/package.yaml @@ -61,7 +61,7 @@ flags: manual: true default: false lsp-server: - description: Enable LSP server (experimental) + description: Enable LSP server manual: true default: false lsp-test-server: @@ -69,7 +69,7 @@ flags: manual: false default: false windows-example-paths: - description: Use executable-relative example paths (for Windows release builds) + description: Use executable-relative example paths (windows-installer-only) default: false manual: true