fix(cli): project init . — 폴더명으로 이름 유도 + 이름 정규화

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 14:40:41 +09:00
parent ec8aa1e349
commit 451c21c4c4

View File

@ -146,9 +146,17 @@ cmd_config() {
cmd_logout() { rm -f "$CONFIG_FILE"; secret_del YAKCLOUD_TOKEN; secret_del GITEA_TOKEN; echo "✓ 자격 삭제(설정 파일 + 키체인)"; } cmd_logout() { rm -f "$CONFIG_FILE"; secret_del YAKCLOUD_TOKEN; secret_del GITEA_TOKEN; echo "✓ 자격 삭제(설정 파일 + 키체인)"; }
# 프로젝트/워크로드/이미지에 안전한 이름 — 소문자, 영숫자·하이픈만, 앞뒤 하이픈 제거, 폴백 app.
_sanitize_name() {
local s; s="$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9-' '-' | sed 's/^-*//; s/-*$//')"
printf '%s' "${s:-app}"
}
cmd_project_init() { cmd_project_init() {
local name="" noninteractive=0 local name="" noninteractive=0
for a in "$@"; do case "$a" in -y|--yes|--no-wizard) noninteractive=1 ;; *) [ -z "$name" ] && name="$a" ;; esac; done for a in "$@"; do case "$a" in -y|--yes|--no-wizard) noninteractive=1 ;; *) [ -z "$name" ] && name="$a" ;; esac; done
# "." / "./" = 현재 폴더에 초기화(이름은 폴더명에서 유도) — 디렉터리 기호가 이름으로 박히지 않도록.
case "$name" in .|./) name="" ;; esac
[ -n "$name" ] && { mkdir -p "$name"; cd "$name"; } [ -n "$name" ] && { mkdir -p "$name"; cd "$name"; }
if [ -n "$(ls -A . 2>/dev/null | grep -v '^\.git$' || true)" ]; then if [ -n "$(ls -A . 2>/dev/null | grep -v '^\.git$' || true)" ]; then
die "폴더가 비어있지 않습니다. 빈 폴더에서 실행하거나 'yakcloud project init <name>'." die "폴더가 비어있지 않습니다. 빈 폴더에서 실행하거나 'yakcloud project init <name>'."
@ -166,14 +174,18 @@ cmd_project_init() {
rm -rf bin install.sh .yakcloud .claude README.md DATA-SOURCES.md rm -rf bin install.sh .yakcloud .claude README.md DATA-SOURCES.md
# 전역 엔진/스킬/명령 준비(최초 init 시에도 보장). # 전역 엔진/스킬/명령 준비(최초 init 시에도 보장).
install_global_assets 2>/dev/null || true install_global_assets 2>/dev/null || true
# 프로젝트명을 project·워크로드(배포)명·image 에 일괄 반영(고정 'web' 대신 프로젝트명). # 프로젝트명 = 지정 이름 or 현재 폴더명 → K8s/이미지 안전하게 정규화(소문자·영숫자·하이픈).
[ -n "$name" ] && [ -f yakcloud.yaml ] && { sed -i.bak "s/my-app/$name/g" yakcloud.yaml && rm -f yakcloud.yaml.bak; } local proj; proj="$(_sanitize_name "${name:-$(basename "$(pwd)")}")"
git rev-parse --git-dir >/dev/null 2>&1 || git init -q git rev-parse --git-dir >/dev/null 2>&1 || git init -q
echo "✓ 스캐폴딩 완료 ($(pwd))" echo "✓ 스캐폴딩 완료 ($(pwd))"
# 대화형 마법사(TTY + not --yes): 클러스터·앱·포트·헬스·CPU·메모리·replicas·env 를 물어 매니페스트에 반영. # 대화형 마법사(TTY + not --yes): 클러스터·앱·포트·헬스·CPU·메모리·replicas·env 를 물어 매니페스트에 반영.
# 마법사가 이름을 확정하므로 여기서 선-sed 하지 않는다(하면 my-app 이 먼저 치환돼 마법사의 재치환이 no-op → 이중 sed 클로버).
if [ "$noninteractive" = 0 ] && [ -t 0 ]; then if [ "$noninteractive" = 0 ] && [ -t 0 ]; then
_init_wizard "${name:-$(basename "$(pwd)")}" _init_wizard "$proj"
_maybe_login_prompt _maybe_login_prompt
else
# 비대화형(마법사 미실행): project·워크로드(배포)명·image 를 정규화된 프로젝트명으로 일괄 반영.
[ -f yakcloud.yaml ] && { sed -i.bak "s/my-app/$proj/g" yakcloud.yaml && rm -f yakcloud.yaml.bak; }
fi fi
echo " 다음: yakcloud project info · yakcloud domain <fqdn> · yakcloud project deploy" echo " 다음: yakcloud project info · yakcloud domain <fqdn> · yakcloud project deploy"
} }
@ -182,7 +194,7 @@ cmd_project_init() {
_init_wizard() { _init_wizard() {
local dflt_app="$1" app devc valc prodc pdom port health cpu mem reps path kv local dflt_app="$1" app devc valc prodc pdom port health cpu mem reps path kv
echo "── 프로젝트 설정 (엔터=기본값) · 개발 → 검증 → 운영 3단계 ──" echo "── 프로젝트 설정 (엔터=기본값) · 개발 → 검증 → 운영 3단계 ──"
printf "앱 이름 [%s]: " "$dflt_app"; read -r app; app="${app:-$dflt_app}" printf "앱 이름 [%s]: " "$dflt_app"; read -r app; app="$(_sanitize_name "${app:-$dflt_app}")"
printf "개발 클러스터(이름 또는 콘솔 id): "; read -r devc printf "개발 클러스터(이름 또는 콘솔 id): "; read -r devc
printf "검증 클러스터(선택, 엔터=생략): "; read -r valc printf "검증 클러스터(선택, 엔터=생략): "; read -r valc
printf "운영 클러스터 [%s]: " "${devc:-개발과 동일}"; read -r prodc; prodc="${prodc:-$devc}" printf "운영 클러스터 [%s]: " "${devc:-개발과 동일}"; read -r prodc; prodc="${prodc:-$devc}"