Let config.env preset the project details

Eight optional keys (PROJECT_NAME, PROJECT_DESCRIPTION, PROJECT_VISIBILITY,
GITEA_OWNER, USE_GITHUB, GITHUB_OWNER, PROJECT_DIRECTORY, ENABLE_PLAN_GATE)
are read and checked with the validators the prompts use. A key that is
present counts as set (only the description may be empty); it is not asked
and the summary marks it "(from config.env)". An invalid value stops the
run before any request and names the key. USE_GITHUB=no skips the GitHub
owner and warns about a stray GITHUB_OWNER. The confirmations stay
interactive. Keys and an example are documented; tests cover every key.

Task: MIL-004#1
Task: MIL-004#2
Task: MIL-004#3
Task: MIL-004#4
Task: MIL-004#5
Closes #27
Closes #28
Closes #29
Closes #30
Closes #31

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 22:06:45 +08:00
co-authored by Claude Sonnet 5.5
parent de78fb195f
commit 75e8e91f9a
6 changed files with 423 additions and 27 deletions
+56 -24
View File
@@ -4,34 +4,59 @@
#
# Part of create-project.sh: sourced by it, never run on its own.
#
# Provides: collect_project_details, yes_no, credential_state, print_summary
# Provides: preset_detail, collect_project_details, collect_github_details, source_note, yes_no, credential_state, print_summary
# preset_detail KEY NAME: a detail set in config.env is used and not asked;
# the value is returned in REPLY and marked in PRESET[NAME].
preset_detail() {
[[ -n ${CONFIG[$1]+set} ]] || return 1
REPLY="${CONFIG[$1]}"
PRESET[$2]=1
}
# Ask for each project detail, except those set in config.env.
collect_project_details() {
prompt_value "Repository name" "" is_valid_repo_name \
"use letters, digits, '.', '_' or '-' (at most 100), not ending in .git"
preset_detail PROJECT_NAME name ||
prompt_value "Repository name" "" is_valid_repo_name "$HINT_REPO_NAME"
PROJECT[name]="$REPLY"
prompt_value "Description (optional)" "" is_valid_description \
"at most $MAX_DESCRIPTION_LENGTH characters and no control characters"
preset_detail PROJECT_DESCRIPTION description ||
prompt_value "Description (optional)" "" is_valid_description "$HINT_DESCRIPTION"
PROJECT[description]="$REPLY"
prompt_choice "Visibility" private private public
preset_detail PROJECT_VISIBILITY visibility ||
prompt_choice "Visibility" private private public
PROJECT[visibility]="$REPLY"
prompt_value "Gitea owner (user or organization)" "" is_valid_gitea_owner \
"use letters, digits, '.', '_' or '-' (at most 39)"
preset_detail GITEA_OWNER gitea_owner ||
prompt_value "Gitea owner (user or organization)" "" is_valid_gitea_owner "$HINT_GITEA_OWNER"
PROJECT[gitea_owner]="$REPLY"
prompt_yes_no "Also create a GitHub repository (applies the AGPL license)" y
collect_github_details
preset_detail PROJECT_DIRECTORY directory ||
prompt_value "Local directory" "./${PROJECT[name]}" is_valid_directory "$HINT_DIRECTORY"
PROJECT[directory]="$REPLY"
if preset_detail ENABLE_PLAN_GATE is_plan_gate_enabled; then
[[ $REPLY == yes ]] && REPLY=1 || REPLY=0
else
prompt_yes_no "Enable the plan gate" n
fi
PROJECT[is_plan_gate_enabled]="$REPLY"
}
# Whether GitHub is used, and its owner. A GITHUB_OWNER set while GitHub is
# not used is ignored, with a warning.
collect_github_details() {
if preset_detail USE_GITHUB has_github; then
[[ $REPLY == yes ]] && REPLY=1 || REPLY=0
else
prompt_yes_no "Also create a GitHub repository (applies the AGPL license)" y
fi
PROJECT[has_github]="$REPLY"
PROJECT[github_owner]=""
if ((PROJECT[has_github])); then
prompt_value "GitHub owner (user or organization)" \
"${CREDENTIALS[GITHUB_USER]:-}" is_valid_github_owner \
"use letters, digits or '-' (at most 39)"
preset_detail GITHUB_OWNER github_owner ||
prompt_value "GitHub owner (user or organization)" "${CREDENTIALS[GITHUB_USER]:-}" is_valid_github_owner "$HINT_GITHUB_OWNER"
PROJECT[github_owner]="$REPLY"
elif [[ -n ${CONFIG[GITHUB_OWNER]+set} ]]; then
warn "GITHUB_OWNER in $CONFIG_FILE is ignored because GitHub is not used"
fi
prompt_value "Local directory" "./${PROJECT[name]}" is_valid_directory \
"must not be empty, start with '-' or contain control characters"
PROJECT[directory]="$REPLY"
prompt_yes_no "Enable the plan gate" n
PROJECT[is_plan_gate_enabled]="$REPLY"
}
yes_no() {
@@ -50,20 +75,27 @@ credential_state() {
fi
}
# source_note NAME: the marker shown after a value that came from config.env.
source_note() {
if [[ -n ${PRESET[$1]:-} ]]; then
printf ' (from config.env)'
fi
}
print_summary() {
say ""
say "$PROJECT_NAME $VERSION"
say "Collected details:"
say " Repository : ${PROJECT[name]} (${PROJECT[visibility]})"
say " Description : ${PROJECT[description]:-(none)}"
say " Gitea : ${CONFIG[GITEA_URL]}/${PROJECT[gitea_owner]}/${PROJECT[name]}"
say " Repository : ${PROJECT[name]}$(source_note name) (${PROJECT[visibility]}$(source_note visibility))"
say " Description : ${PROJECT[description]:-(none)}$(source_note description)"
say " Gitea : ${CONFIG[GITEA_URL]}/${PROJECT[gitea_owner]}/${PROJECT[name]}$(source_note gitea_owner)"
if ((PROJECT[has_github])); then
say " GitHub : ${CONFIG[GITHUB_WEB_URL]}/${PROJECT[github_owner]}/${PROJECT[name]} (AGPL license applied)"
say " GitHub : ${CONFIG[GITHUB_WEB_URL]}/${PROJECT[github_owner]}/${PROJECT[name]} (AGPL license applied)$(source_note github_owner)"
else
say " GitHub : not used"
say " GitHub : not used$(source_note has_github)"
fi
say " Directory : ${PROJECT[directory]}"
say " Plan gate : $(yes_no "${PROJECT[is_plan_gate_enabled]}")"
say " Directory : ${PROJECT[directory]}$(source_note directory)"
say " Plan gate : $(yes_no "${PROJECT[is_plan_gate_enabled]}")$(source_note is_plan_gate_enabled)"
say "Credentials : GITEA_TOKEN $(credential_state GITEA_TOKEN)," \
"GITHUB_PAT $(credential_state GITHUB_PAT)"
}