Add the local project, framework submodule, hooks and templates
After the repositories and the mirror, the script now creates the local project: the directory, git on main, credential-free origin (and github) remotes, and the license history from Gitea. Then it adds the framework as a submodule over SSH, installs its skills and git hooks once (plan gate optional), and copies the AGENTS.md and artifact registry templates. Nothing is overwritten without a yes: an existing directory, core.hooksPath, AGENTS.md or docs/artifact-registry.md each ask first (default no). Without SSH the framework steps can only be skipped, after a yes. No commit is made in the new project. New optional config key FRAMEWORK_REPO. New library files git.sh, localproject.sh and framework.sh. Tests run real git against local bare repositories that stand in for Gitea and the framework, with a private git configuration (769 checks). The README is now the full guide. Task: MIL-003#1 Task: MIL-003#2 Task: MIL-003#3 Task: MIL-003#4 Task: MIL-003#5 Refs #15 Refs #16 Refs #17 Refs #18 Refs #19 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
# shellcheck shell=bash
|
||||
# shellcheck disable=SC2004,SC2034,SC2154 # shared state and arrays are declared in constants.sh
|
||||
# localproject.sh - The local project: its directory, its git repository and its remotes.
|
||||
#
|
||||
# Part of create-project.sh: sourced by it, never run on its own.
|
||||
#
|
||||
# Provides: inspect_local_directory, confirm_local_directory, ensure_remote, checkout_gitea_history, create_local_project
|
||||
|
||||
# inspect_local_directory: record in STATE[local_dir] whether the project
|
||||
# directory is missing, empty or not_empty. It creates nothing.
|
||||
inspect_local_directory() {
|
||||
local dir="${PROJECT[directory]}"
|
||||
if [[ ! -e $dir ]]; then
|
||||
STATE[local_dir]="missing"
|
||||
elif [[ ! -d $dir ]]; then
|
||||
die "$dir already exists and is not a directory"
|
||||
elif [[ -z "$(find "$dir" -mindepth 1 -maxdepth 1 -print -quit)" ]]; then
|
||||
STATE[local_dir]="empty"
|
||||
else
|
||||
STATE[local_dir]="not_empty"
|
||||
fi
|
||||
}
|
||||
|
||||
# confirm_local_directory: an existing directory is only used after a yes.
|
||||
confirm_local_directory() {
|
||||
local dir="${PROJECT[directory]}" what="is empty"
|
||||
if [[ ${STATE[local_dir]} == missing ]]; then
|
||||
return 0
|
||||
fi
|
||||
if [[ ${STATE[local_dir]} == not_empty ]]; then
|
||||
what="already has files"
|
||||
fi
|
||||
prompt_yes_no "The directory $dir already exists and $what. Use it" n
|
||||
if ! ((REPLY)); then
|
||||
die "stopped: choose another directory or remove this one"
|
||||
fi
|
||||
}
|
||||
|
||||
# ensure_remote DIR NAME URL: add the remote, or accept one that already has
|
||||
# exactly this address. A different address is never overwritten.
|
||||
ensure_remote() {
|
||||
local dir="$1" name="$2" url="$3" existing
|
||||
# git config exits 1 when the remote is not set; that is the normal case.
|
||||
existing="$(git_project "$dir" config --get "remote.$name.url" || true)"
|
||||
if [[ -z $existing ]]; then
|
||||
git_project "$dir" remote add "$name" "$url"
|
||||
elif [[ $existing != "$url" ]]; then
|
||||
die "the remote '$name' in $dir already points to $existing; remove it or choose another directory"
|
||||
fi
|
||||
}
|
||||
|
||||
# checkout_gitea_history DIR: when the Gitea repository holds the license
|
||||
# commit, fetch it and start the local branch from it, so the local history
|
||||
# begins with that commit. Existing files are never overwritten: git refuses.
|
||||
checkout_gitea_history() {
|
||||
local dir="$1" err
|
||||
if ! fetch_origin "$dir" 2>/dev/null; then
|
||||
die "could not fetch the Gitea repository from $(origin_url); check your SSH key (or, over HTTPS, the token) and run the same command again"
|
||||
fi
|
||||
if ! git_project "$dir" rev-parse --verify -q refs/remotes/origin/main >/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
if git_project "$dir" rev-parse --verify -q HEAD >/dev/null 2>&1; then
|
||||
warn "$dir already has history: the Gitea content was fetched but not checked out"
|
||||
return 0
|
||||
fi
|
||||
make_temp_file
|
||||
err="$REPLY"
|
||||
if ! git_project "$dir" checkout -q -b main --track origin/main 2>"$err"; then
|
||||
die "git would overwrite files in $dir with the Gitea content; move them away and run again. Git said: $(head -n 2 "$err" | tr '\n' ' ')"
|
||||
fi
|
||||
}
|
||||
|
||||
# create_local_project: the directory, the git repository on main, the
|
||||
# remotes and, when GitHub is chosen, the license history. No commit is made.
|
||||
create_local_project() {
|
||||
local label="Local project" dir="${PROJECT[directory]}"
|
||||
begin_step "$label"
|
||||
mkdir -p -- "$dir"
|
||||
if [[ ! -e $dir/.git ]]; then
|
||||
git_project "$dir" init -q
|
||||
git_project "$dir" symbolic-ref HEAD "refs/heads/$DEFAULT_BRANCH"
|
||||
fi
|
||||
ensure_remote "$dir" origin "$(origin_url)"
|
||||
if ((PROJECT[has_github])); then
|
||||
ensure_remote "$dir" github "$(github_remote_url)"
|
||||
checkout_gitea_history "$dir"
|
||||
fi
|
||||
finish_step "$label" "created" "$dir (origin over $(origin_protocol))"
|
||||
}
|
||||
Reference in New Issue
Block a user