After the templates are copied, create-project.sh adds /.claude, /.agents and /AGENTS.md to .git/info/exclude of the new project as its own step, "Git excludes". No .gitignore or tracked file changes and nothing is committed. The step is skipped when the framework steps are skipped, and a path git already tracks stays tracked and is named in the step. The .git/info/exclude code of exclude_env_file moves into the shared helper exclude_from_git (git.sh), which both now use; the .env behavior is unchanged. Refs #66 Task: MIL-009#2
87 lines
3.3 KiB
Bash
87 lines
3.3 KiB
Bash
# shellcheck shell=bash
|
|
# shellcheck disable=SC2004,SC2034,SC2154 # shared state and arrays are declared in constants.sh
|
|
# envfile.sh - The .env file of the new project: the one place a credential is written.
|
|
#
|
|
# Part of create-project.sh: sourced by it, never run on its own.
|
|
#
|
|
# Provides: env_file_keys, env_file_key_list, exclude_env_file, write_env_file, create_env_file
|
|
|
|
# env_file_keys: the credentials the new project needs, one per line: the
|
|
# Gitea token, and the GitHub token and account name when GitHub was chosen.
|
|
env_file_keys() {
|
|
printf '%s\n' GITEA_TOKEN
|
|
if ((PROJECT[has_github])); then
|
|
printf '%s\n' GITHUB_PAT GITHUB_USER
|
|
fi
|
|
}
|
|
|
|
# env_file_key_list: the same keys on one line, for messages.
|
|
env_file_key_list() {
|
|
local keys
|
|
keys="$(env_file_keys | tr '\n' ' ')"
|
|
printf '%s' "${keys% }"
|
|
}
|
|
|
|
# exclude_env_file DIR: make git ignore .env in DIR without touching a tracked
|
|
# file: the entry goes into .git/info/exclude, which is never committed. It
|
|
# does nothing when .env is already ignored.
|
|
exclude_env_file() {
|
|
local dir="$1"
|
|
exclude_from_git "$dir" "RepoFoundry: the credentials file of this project" "$ENV_FILE_NAME" ||
|
|
die "could not make git ignore $ENV_FILE_NAME in $dir; nothing was written to it"
|
|
}
|
|
|
|
# write_env_file DIR IS_REPLACE: write the credentials to DIR/.env. The file is
|
|
# created private (mode 600) from the start, never readable by others, even
|
|
# for a moment: it is written under umask 077 as a temporary file next to the
|
|
# target and moved into place. An existing file is only replaced when
|
|
# IS_REPLACE is 1, and a file that appears in the meantime is never replaced.
|
|
write_env_file() {
|
|
local dir="$1" is_replace="$2" target tmp key
|
|
target="$dir/$ENV_FILE_NAME"
|
|
tmp="$(umask 077 && mktemp "$dir/$ENV_FILE_NAME.XXXXXX")"
|
|
TEMP_FILES+=("$tmp")
|
|
{
|
|
while IFS= read -r key; do
|
|
printf '%s=%s\n' "$key" "${CREDENTIALS[$key]}"
|
|
done < <(env_file_keys)
|
|
} >"$tmp"
|
|
if ((is_replace)); then
|
|
mv -f -- "$tmp" "$target"
|
|
else
|
|
mv -n -- "$tmp" "$target"
|
|
if [[ -e $tmp ]]; then
|
|
die "$target appeared while it was being written; it was not replaced"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# create_env_file: the last step. Only after a yes (default no) is the .env
|
|
# written, and an existing one is only replaced after another yes. Nothing
|
|
# printed names a value, only the keys.
|
|
create_env_file() {
|
|
local label="Project .env" dir="${PROJECT[directory]}" keys is_replace=0
|
|
keys="$(env_file_key_list)"
|
|
begin_step "$label"
|
|
prompt_yes_no "Create a $ENV_FILE_NAME file in the project with the credentials it needs ($keys); only you can read it and git ignores it" n
|
|
if ! ((REPLY)); then
|
|
finish_step "$label" "skipped" "(you declined)"
|
|
return 0
|
|
fi
|
|
if git_project "$dir" ls-files --error-unmatch -- "$ENV_FILE_NAME" >/dev/null 2>&1; then
|
|
finish_step "$label" "skipped" "($ENV_FILE_NAME is tracked by git; it was not written)"
|
|
return 0
|
|
fi
|
|
if [[ -e $dir/$ENV_FILE_NAME || -L $dir/$ENV_FILE_NAME ]]; then
|
|
prompt_yes_no "$ENV_FILE_NAME already exists in the project. Replace it" n
|
|
if ! ((REPLY)); then
|
|
finish_step "$label" "kept" "(the existing $ENV_FILE_NAME was left as it was)"
|
|
return 0
|
|
fi
|
|
is_replace=1
|
|
fi
|
|
exclude_env_file "$dir"
|
|
write_env_file "$dir" "$is_replace"
|
|
finish_step "$label" "created" "($keys; only you can read it, git ignores it)"
|
|
}
|