@@ -7,6 +7,10 @@ repo_toml_generate:
77 #!/usr/bin/env bash
88 set -euo pipefail
99
10+ shell_quote () {
11+ printf ' %q' " $1 "
12+ }
13+
1014 # Validate .repo.toml exists and passes cue validation
1115 if [[ ! -f .repo.toml ]]; then
1216 echo " {{RED}}Error: .repo.toml not found{{NORMAL}}"
@@ -22,26 +26,28 @@ repo_toml_generate:
2226 # Export JSON once
2327 JSON=$( cue export .repo.toml)
2428
25- # Extract all fields with safe defaults
26- DESCRIPTION=$( echo " $JSON " | jq -r ' .about.description // ""' )
27- LICENSE=$( echo " $JSON " | jq -r ' .about.license // ""' )
29+ # Extract all fields with @sh for safe shell escaping
30+ DESCRIPTION=$( echo " $JSON " | jq -r ' .about.description // "" | @sh ' )
31+ LICENSE=$( echo " $JSON " | jq -r ' .about.license // "" | @sh ' )
2832 TOPICS_JSON=$( echo " $JSON " | jq -r ' .about.topics // []' )
2933 TOPICS_ARRAY=$( echo " $TOPICS_JSON " | jq -r ' .[]' | sort)
30- TOPICS_CSV=$( echo " $TOPICS_ARRAY " | paste -sd ' ,' -)
34+ TOPICS_CSV=$( echo " $TOPICS_ARRAY " | grep -v ' ^$ ' | paste -sd ' ,' - || echo " " )
3135
32- GIT_SSH=$( echo " $JSON " | jq -r ' .urls.git_ssh // ""' )
33- WEB_URL=$( echo " $JSON " | jq -r ' .urls.web_url // ""' )
36+ GIT_SSH=$( echo " $JSON " | jq -r ' .urls.git_ssh // "" | @sh ' )
37+ WEB_URL=$( echo " $JSON " | jq -r ' .urls.web_url // "" | @sh ' )
3438
3539 # Derive org and repo name from web URL
3640 # Example: https://github.com/fini-net/template-repo -> fini-net, template-repo
37- ORG_NAME=$( echo " $WEB_URL " | sed -E ' s|https://github.com/([^/]+)/.*|\1|' )
38- REPO_NAME=$( echo " $WEB_URL " | sed -E ' s|https://github.com/[^/]+/(.+)|\1|' )
41+ # Extract raw URL separately from @sh-quoted version to avoid fragile sed stripping
42+ WEB_URL_RAW=$( echo " $JSON " | jq -r ' .urls.web_url // ""' )
43+ ORG_NAME=$( echo " $WEB_URL_RAW " | sed -E ' s|https://github.com/([^/]+)/.*|\1|' )
44+ REPO_NAME=$( echo " $WEB_URL_RAW " | sed -E ' s|https://github.com/[^/]+/(.+)|\1|' )
3945
4046 # Validate URL parsing succeeded
4147 if [[ -z " $ORG_NAME " ]] || [[ -z " $REPO_NAME " ]]; then
4248 echo " {{RED}}Error: Failed to parse organization and repository name from web_url{{NORMAL}}"
4349 echo " {{YELLOW}}Expected format: https://github.com/org-name/repo-name{{NORMAL}}"
44- echo " {{YELLOW}}Got: $WEB_URL {{NORMAL}}"
50+ echo " {{YELLOW}}Got: $WEB_URL_RAW {{NORMAL}}"
4551 exit 1
4652 fi
4753
@@ -52,34 +58,41 @@ repo_toml_generate:
5258 FLAG_STANDARD_RELEASE=$( echo " $JSON " | jq -r ' if .flags["standard-release"] == false then "false" else "true" end' )
5359
5460 # Generate .just/repo-toml.sh with all content
61+ # @sh-quoted string values already include proper shell quoting (e.g., 'value')
62+ # Flag values are bare true/false strings (no quoting needed)
63+ # shell_quote-d values use printf %q for safe embedding
64+ QUOTED_TOPICS_CSV=$( shell_quote " $TOPICS_CSV " )
65+ QUOTED_ORG_NAME=$( shell_quote " $ORG_NAME " )
66+ QUOTED_REPO_NAME=$( shell_quote " $REPO_NAME " )
67+
5568 {
5669 echo " # Auto-generated from .repo.toml by 'just repo_toml_generate'"
5770 echo " # DO NOT EDIT THIS FILE MANUALLY - regenerate with: just repo_toml_generate"
5871 echo " "
5972 echo " # About section"
60- echo " REPO_DESCRIPTION=\" ${DESCRIPTION} \" "
61- echo " REPO_LICENSE=\" ${LICENSE} \" "
62- echo " REPO_TOPICS=\" ${TOPICS_CSV} \" "
73+ echo " REPO_DESCRIPTION=${DESCRIPTION} "
74+ echo " REPO_LICENSE=${LICENSE} "
75+ echo " REPO_TOPICS=${QUOTED_TOPICS_CSV} "
6376 echo " "
6477 echo " # URLs section"
65- echo " REPO_GIT_SSH=\" ${GIT_SSH} \" "
66- echo " REPO_WEB_URL=\" ${WEB_URL} \" "
78+ echo " REPO_GIT_SSH=${GIT_SSH} "
79+ echo " REPO_WEB_URL=${WEB_URL} "
6780 echo " "
6881 echo " # Derived values"
69- echo " REPO_ORG_NAME=\" ${ORG_NAME} \" "
70- echo " REPO_REPO_NAME=\" ${REPO_NAME} \" "
82+ echo " REPO_ORG_NAME=${QUOTED_ORG_NAME} "
83+ echo " REPO_REPO_NAME=${QUOTED_REPO_NAME} "
7184 echo " "
7285 echo " # Feature flags (strings: \" true\" or \" false\" )"
73- echo " FLAG_CLAUDE=\" ${FLAG_CLAUDE} \" "
74- echo " FLAG_CLAUDE_REVIEW=\" ${FLAG_CLAUDE_REVIEW} \" "
75- echo " FLAG_COPILOT_REVIEW=\" ${FLAG_COPILOT_REVIEW} \" "
76- echo " FLAG_STANDARD_RELEASE=\" ${FLAG_STANDARD_RELEASE} \" "
86+ echo " FLAG_CLAUDE=${FLAG_CLAUDE} "
87+ echo " FLAG_CLAUDE_REVIEW=${FLAG_CLAUDE_REVIEW} "
88+ echo " FLAG_COPILOT_REVIEW=${FLAG_COPILOT_REVIEW} "
89+ echo " FLAG_STANDARD_RELEASE=${FLAG_STANDARD_RELEASE} "
7790 echo " "
7891 echo " # Topics as array (for iteration)"
7992 echo " REPO_TOPICS_ARRAY=("
8093 echo " $TOPICS_ARRAY " | while IFS= read -r topic; do
8194 if [[ -n " $topic " ]]; then
82- echo " \ "$topic \" "
95+ echo " $( shell_quote " $topic " ) "
8396 fi
8497 done
8598 echo " )"
0 commit comments