mirror of https://github.com/garrytan/gstack.git
Merge 551d0b13be into 7c9df1c568
This commit is contained in:
commit
6399dffad3
|
|
@ -257,6 +257,16 @@ resolve_user_slug() {
|
|||
printf '%s' "$_slug"
|
||||
}
|
||||
|
||||
read_config_value() {
|
||||
local key="$1"
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
return 0
|
||||
fi
|
||||
grep -E "^${key}:" "$CONFIG_FILE" 2>/dev/null \
|
||||
| tail -1 \
|
||||
| sed -E "s/^${key}:[[:space:]]*//; s/[[:space:]]+$//"
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
get)
|
||||
KEY="${2:?Usage: gstack-config get <key>}"
|
||||
|
|
@ -266,8 +276,7 @@ case "${1:-}" in
|
|||
echo "Error: key must contain only alphanumeric characters, underscores, and an optional @<hex-hash> suffix" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Use literal match for keys containing @ (sha hashes), regex otherwise
|
||||
VALUE=$(grep -F "${KEY}:" "$CONFIG_FILE" 2>/dev/null | grep -E "^${KEY%@*}(@[a-f0-9]+)?:" | grep -F "${KEY}:" | tail -1 | awk '{print $2}' | tr -d '[:space:]' || true)
|
||||
VALUE=$(read_config_value "$KEY" || true)
|
||||
if [ -z "$VALUE" ]; then
|
||||
VALUE=$(lookup_default "$KEY")
|
||||
fi
|
||||
|
|
@ -323,14 +332,15 @@ case "${1:-}" in
|
|||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
printf '%s' "$CONFIG_HEADER" > "$CONFIG_FILE"
|
||||
fi
|
||||
# Escape sed special chars in value and drop embedded newlines
|
||||
ESC_VALUE="$(printf '%s' "$VALUE" | head -1 | sed 's/[&/\]/\\&/g')"
|
||||
# Drop embedded newlines, then escape sed replacement metacharacters.
|
||||
SAFE_VALUE="$(printf '%s' "$VALUE" | head -1)"
|
||||
ESC_VALUE="$(printf '%s' "$SAFE_VALUE" | sed 's/[&/\]/\\&/g')"
|
||||
if grep -qE "^${KEY}:" "$CONFIG_FILE" 2>/dev/null; then
|
||||
# Portable in-place edit (BSD sed uses -i '', GNU sed uses -i without arg)
|
||||
_tmpfile="$(mktemp "${CONFIG_FILE}.XXXXXX")"
|
||||
sed "/^${KEY}:/s/.*/${KEY}: ${ESC_VALUE}/" "$CONFIG_FILE" > "$_tmpfile" && mv "$_tmpfile" "$CONFIG_FILE"
|
||||
else
|
||||
echo "${KEY}: ${VALUE}" >> "$CONFIG_FILE"
|
||||
echo "${KEY}: ${SAFE_VALUE}" >> "$CONFIG_FILE"
|
||||
fi
|
||||
# Auto-relink skills when prefix setting changes (skip during setup to avoid recursive call)
|
||||
if [ "$KEY" = "skill_prefix" ] && [ -z "${GSTACK_SETUP_RUNNING:-}" ]; then
|
||||
|
|
@ -348,7 +358,7 @@ case "${1:-}" in
|
|||
skill_prefix checkpoint_mode checkpoint_push explain_level \
|
||||
codex_reviews gstack_contributor skip_eng_review workspace_root \
|
||||
artifacts_sync_mode artifacts_sync_mode_prompted plan_tune_hooks; do
|
||||
VALUE=$(grep -E "^${KEY}:" "$CONFIG_FILE" 2>/dev/null | tail -1 | awk '{print $2}' | tr -d '[:space:]' || true)
|
||||
VALUE=$(read_config_value "$KEY" || true)
|
||||
SOURCE="default"
|
||||
if [ -n "$VALUE" ]; then
|
||||
SOURCE="set"
|
||||
|
|
|
|||
|
|
@ -88,3 +88,20 @@ describe('gstack-config explain_level', () => {
|
|||
expect(run('get', 'explain_level').stdout).toBe('default');
|
||||
});
|
||||
});
|
||||
|
||||
describe('gstack-config values with spaces', () => {
|
||||
test('workspace_root preserves internal spaces on set/get/list', () => {
|
||||
const value = path.join(os.tmpdir(), 'Conductor Workspaces');
|
||||
expect(run('set', 'workspace_root', value).status).toBe(0);
|
||||
|
||||
expect(run('get', 'workspace_root').stdout).toBe(value);
|
||||
|
||||
const listed = run('list');
|
||||
expect(listed.status).toBe(0);
|
||||
expect(
|
||||
listed.stdout
|
||||
.split('\n')
|
||||
.some((line) => line.includes('workspace_root:') && line.includes(value) && line.includes('(set)')),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue