Skip to content

Commit 4fa3245

Browse files
author
Test
committed
feat: Enhance argument parsing and configuration management
- Added global argument parser to handle global options and subcommand detection in the CLI. - Introduced new environment variables for temperature and context window size for AI responses. - Improved the configuration management script to support additional commands and better error handling. - Implemented argument parsing for the changelog, document, and message subcommands, allowing for more flexible command usage. - Enhanced the summary command to work with real Git repositories and added tests for various edge cases. - Updated tests to cover new functionality and ensure robust error handling across commands. - Created a new configuration file format to streamline project settings and API configurations.
1 parent 7d20c66 commit 4fa3245

17 files changed

+584
-258
lines changed

.giv/config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ GIV_PROJECT_DESCRIPTION="cli tool"
66
GIV_PROJECT_URL="giv is a CLI utility for generating changelogs and summaries."
77
GIV_API_URL="http://localhost:11434/v1/chat/completions"
88
GIV_API_MODEL="devstral"
9-
GIV_API_KEY="ollama"
109
GIV_INITIALIZED="true"
10+
project.title="Test Value With Spaces"

.giv/config.x

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
project.type="custom"
2+
project.version_file="src/lib/system.sh"
3+
project.version_pattern="version[[:space:]]*=[[:space:]]*([0-9]+\.[0-9]+\.[0-9]+)"
4+
project.title="giv"
5+
project.description="cli tool"
6+
project.url="giv is a CLI utility for generating changelogs and summaries."
7+
api.url="http://localhost:11434/v1/chat/completions"
8+
api.model="devstral"
9+
api.key="ollama"
10+
initialized="true"

src/commands/changelog.sh

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,53 @@ if [ -z "$output_version" ]; then
2525
output_version=$(get_metadata_value "version" "HEAD" 2>/dev/null || echo "Unreleased")
2626
fi
2727

28+
# Set defaults for revision and pathspec if not provided
29+
GIV_REVISION="${GIV_REVISION:---current}"
30+
GIV_PATHSPEC="${GIV_PATHSPEC:-}"
31+
export GIV_REVISION
32+
export GIV_PATHSPEC
33+
34+
# Parse arguments for the changelog subcommand
35+
parse_changelog_arguments() {
36+
while [ "$#" -gt 0 ]; do
37+
case "$1" in
38+
--revision)
39+
shift
40+
export GIV_REVISION="$1"
41+
;;
42+
--pathspec)
43+
shift
44+
export GIV_PATHSPEC="$1"
45+
;;
46+
--output-file)
47+
shift
48+
export GIV_OUTPUT_FILE="$1"
49+
;;
50+
--output-version)
51+
shift
52+
export GIV_OUTPUT_VERSION="$1"
53+
;;
54+
--*)
55+
echo "Error: Unknown option '$1' for changelog subcommand." >&2
56+
return 1
57+
;;
58+
*)
59+
# First non-option argument is the revision
60+
if [ -z "${GIV_REVISION_SET:-}" ]; then
61+
export GIV_REVISION="$1"
62+
export GIV_REVISION_SET="true"
63+
else
64+
echo "Error: Unknown positional argument '$1' for changelog subcommand." >&2
65+
return 1
66+
fi
67+
;;
68+
esac
69+
shift
70+
done
71+
72+
return 0
73+
}
74+
2875
# Summarize Git history
2976
summaries_file=$(portable_mktemp "summaries.XXXXXXX") || {
3077
printf 'Error: cannot create temp file for summaries\n' >&2

src/commands/config.sh

Lines changed: 57 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -44,92 +44,67 @@ quote_value() {
4444
giv_config() {
4545
cmd="$1"
4646
case "$cmd" in
47-
--list|list)
47+
--list|list|show)
4848
if [ ! -f "$GIV_CONFIG_FILE" ]; then
4949
printf '%s\n' "config file not found" >&2
5050
return 1
5151
fi
52-
# Check for malformed lines
53-
if [ -s "$GIV_CONFIG_FILE" ]; then
54-
# Updated malformed config check to ignore empty lines and lines with only whitespace
55-
# Simple validation: check for lines that don't contain = and aren't comments or empty
56-
while IFS= read -r line; do
57-
case "$line" in
58-
'#'*|'') continue ;; # Skip comments and empty lines
59-
*=*) continue ;; # Valid config line
60-
*)
61-
printf '%s\n' "Malformed config line: $line" >&2
62-
return 1
63-
;;
64-
esac
65-
done < "$GIV_CONFIG_FILE"
52+
53+
if [ ! -s "$GIV_CONFIG_FILE" ]; then
54+
printf '%s\n' "No configuration found." >&2
55+
return 0
6656
fi
67-
# Convert GIV_... keys to user keys for output from config file
68-
if [ -s "$GIV_CONFIG_FILE" ]; then
69-
while IFS= read -r line; do
70-
case "$line" in
71-
GIV_*)
72-
k=${line#GIV_}
73-
k=${k%%=*}
74-
key=$(printf '%s' "$k" | tr 'A-Z_' 'a-z.')
75-
value="${line#*=}"
76-
printf '%s\n' "$key=$value"
77-
;;
78-
*=*)
79-
printf '%s\n' "$line"
80-
;;
81-
*)
57+
58+
# Check for malformed lines
59+
while IFS= read -r line; do
60+
case "$line" in
61+
'#'*|'') continue ;; # Skip comments and empty lines
62+
*=*) continue ;; # Valid config line
63+
*)
64+
printf '%s\n' "Malformed config line: $line" >&2
65+
return 1
8266
;;
83-
esac
84-
done < "$GIV_CONFIG_FILE"
85-
fi
86-
87-
# Also show environment variables with GIV_ prefix that may have been loaded from --config-file
88-
for var in $(env | grep '^GIV_'); do
89-
case "$var" in
67+
esac
68+
done < "$GIV_CONFIG_FILE"
69+
70+
# Convert GIV_... keys to user keys for output from config file
71+
while IFS= read -r line; do
72+
case "$line" in
9073
GIV_*)
91-
k=${var#GIV_}
74+
k=${line#GIV_}
9275
k=${k%%=*}
9376
key=$(printf '%s' "$k" | tr 'A-Z_' 'a-z.')
94-
value="${var#*=}"
95-
# Only show if not already shown from config file
96-
if [ -z "$(grep "^GIV_$k=" "$GIV_CONFIG_FILE" 2>/dev/null)" ]; then
97-
printf '%s\n' "$key=$value"
98-
fi
77+
value="${line#*=}"
78+
printf '%s\n' "$key=$value"
79+
;;
80+
*=*)
81+
printf '%s\n' "$line"
9982
;;
10083
esac
101-
done
84+
done < "$GIV_CONFIG_FILE"
10285
;;
10386
--get|get)
10487
key="$2"
105-
# Validate key format
106-
env_key="$(normalize_key "$key")"
107-
if [ -z "$env_key" ]; then
108-
printf '%s\n' "Invalid key format: $key" >&2
109-
return 1
110-
fi
111-
# ENV override
112-
if [ -n "$env_key" ]; then
113-
eval "env_val=\"\${$env_key-}\""
114-
if [ -n "$env_val" ]; then
115-
printf '%s\n' "$env_val"
116-
return 0
117-
fi
118-
fi
88+
# Only support dot-separated keys in the config file
11989
if [ ! -f "$GIV_CONFIG_FILE" ]; then
12090
printf '%s\n' "config file not found" >&2
12191
return 1
12292
fi
123-
124-
# Try user key first, then GIV_ key
12593
val=$(grep -E "^$key=" "$GIV_CONFIG_FILE" | cut -d'=' -f2-)
126-
if [ -z "$val" ]; then
127-
givkey="$(normalize_key "$key")"
128-
val=$(grep -E "^$givkey=" "$GIV_CONFIG_FILE" | cut -d'=' -f2-)
129-
fi
130-
# Remove surrounding quotes if present (both single and double)
13194
val=$(printf '%s' "$val" | sed -e 's/^"\(.*\)"$/\1/' -e "s/^'\(.*\)'$/\1/")
132-
printf '%s\n' "$val"
95+
if [ -n "$val" ]; then
96+
printf '%s\n' "$val"
97+
return 0
98+
fi
99+
# Fallback to GIV_... env var
100+
env_key="$(normalize_key "$key")"
101+
env_val="$(printenv "$env_key" 2>/dev/null)"
102+
if [ -n "$env_val" ]; then
103+
printf '%s\n' "$env_val"
104+
return 0
105+
fi
106+
# Not found
107+
return 1
133108
;;
134109
--unset|unset)
135110
key="$2"
@@ -150,11 +125,8 @@ giv_config() {
150125
touch "$GIV_CONFIG_FILE"
151126
fi
152127
tmpfile=$(mktemp)
153-
givkey="$(normalize_key "$key")"
154-
grep -v -E "^($key|$givkey)=" "$GIV_CONFIG_FILE" | grep -v '^$' > "$tmpfile"
155-
# Always write in GIV_... format
156-
writekey="$(normalize_key "$key")"
157-
printf '%s=%s\n' "$writekey" "$(quote_value "$value")" >> "$tmpfile"
128+
grep -v -E "^$key=" "$GIV_CONFIG_FILE" | grep -v '^$' > "$tmpfile"
129+
printf '%s=%s\n' "$key" "$(quote_value "$value")" >> "$tmpfile"
158130
mv "$tmpfile" "$GIV_CONFIG_FILE"
159131
;;
160132
-*|help)
@@ -165,51 +137,39 @@ giv_config() {
165137
*)
166138
key="$1"
167139
value="${2:-}"
168-
# Validate key format
169-
env_key="$(normalize_key "$key")"
170-
if [ -z "$env_key" ]; then
171-
printf '%s\n' "Invalid key format: $key" >&2
172-
return 1
173-
fi
174140
if [ -z "$value" ]; then
175-
# ENV override
176-
if [ -n "$env_key" ]; then
177-
eval "env_val=\"\${$env_key-}\""
178-
if [ -n "$env_val" ]; then
179-
printf '%s\n' "$env_val"
180-
return 0
181-
fi
182-
fi
141+
# ENV override fallback for dot-separated keys
183142
if [ ! -f "$GIV_CONFIG_FILE" ]; then
184143
printf '%s\n' "config file not found" >&2
185144
return 1
186145
fi
187146
if [ -s "$GIV_CONFIG_FILE" ]; then
188-
# Updated malformed config check to ignore empty lines and lines with only whitespace
189147
if grep -qvE '^(#|[^=]+=.*|[[:space:]]*)$' "$GIV_CONFIG_FILE"; then
190148
printf '%s\n' "Malformed config" >&2
191149
return 1
192150
fi
193151
fi
194152
val=$(grep -E "^$key=" "$GIV_CONFIG_FILE" | cut -d'=' -f2-)
195-
if [ -z "$val" ]; then
196-
givkey="$(normalize_key "$key")"
197-
val=$(grep -E "^$givkey=" "$GIV_CONFIG_FILE" | cut -d'=' -f2-)
198-
fi
199-
# Remove surrounding quotes if present (both single and double)
200153
val=$(printf '%s' "$val" | sed -e 's/^"\(.*\)"$/\1/' -e "s/^'\(.*\)'$/\1/")
201-
printf '%s\n' "$val"
154+
if [ -n "$val" ]; then
155+
printf '%s\n' "$val"
156+
return 0
157+
fi
158+
env_key="$(normalize_key "$key")"
159+
env_val="$(printenv "$env_key" 2>/dev/null)"
160+
if [ -n "$env_val" ]; then
161+
printf '%s\n' "$env_val"
162+
return 0
163+
fi
164+
return 1
202165
else
203166
mkdir -p "$GIV_HOME"
204167
if [ ! -f "$GIV_CONFIG_FILE" ]; then
205168
touch "$GIV_CONFIG_FILE"
206169
fi
207170
tmpfile=$(mktemp)
208-
givkey="$(normalize_key "$key")"
209-
grep -v -E "^($key|$givkey)=" "$GIV_CONFIG_FILE" | grep -v '^$' > "$tmpfile"
210-
# Always write in GIV_... format
211-
writekey="$(normalize_key "$key")"
212-
printf '%s=%s\n' "$writekey" "$(quote_value "$value")" >> "$tmpfile"
171+
grep -v -E "^$key=" "$GIV_CONFIG_FILE" | grep -v '^$' > "$tmpfile"
172+
printf '%s=%s\n' "$key" "$(quote_value "$value")" >> "$tmpfile"
213173
mv "$tmpfile" "$GIV_CONFIG_FILE"
214174
fi
215175
;;

src/commands/document.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,53 @@ if [ -n "${GIV_TEST_MOCKS:-}" ] && [ -f "${GIV_TEST_MOCKS:-}" ]; then
1111
. "$GIV_TEST_MOCKS"
1212
fi
1313

14+
# Set defaults for revision and pathspec if not provided
15+
GIV_REVISION="${GIV_REVISION:---current}"
16+
GIV_PATHSPEC="${GIV_PATHSPEC:-}"
17+
export GIV_REVISION
18+
export GIV_PATHSPEC
19+
20+
# Parse arguments for the document subcommand
21+
parse_document_arguments() {
22+
while [ "$#" -gt 0 ]; do
23+
case "$1" in
24+
--prompt-file)
25+
shift
26+
export GIV_PROMPT_FILE="$1"
27+
;;
28+
--revision)
29+
shift
30+
export GIV_REVISION="$1"
31+
;;
32+
--pathspec)
33+
shift
34+
export GIV_PATHSPEC="$1"
35+
;;
36+
--output-file)
37+
shift
38+
export GIV_OUTPUT_FILE="$1"
39+
;;
40+
*)
41+
echo "Error: Unknown option '$1' for document subcommand." >&2
42+
return 1
43+
;;
44+
esac
45+
shift
46+
done
47+
48+
# Set defaults if not provided
49+
export GIV_REVISION="${GIV_REVISION:---current}"
50+
export GIV_PATHSPEC="${GIV_PATHSPEC:-}" # Default to empty pathspec
51+
52+
# Validate required options
53+
if [ -z "${GIV_PROMPT_FILE:-}" ]; then
54+
echo "Error: --prompt-file is required for the document subcommand." >&2
55+
return 1
56+
fi
57+
58+
return 0
59+
}
60+
1461
# Function to generate documents based on a prompt template
1562
cmd_document() {
1663
# Use environment variables set by unified parser
@@ -21,6 +68,13 @@ cmd_document() {
2168
temp="${GIV_TEMPERATURE:-0.9}"
2269
ctx="${GIV_CONTEXT_WINDOW:-32768}"
2370

71+
# Debug: Log environment variables
72+
print_debug "GIV_PROMPT_FILE: ${GIV_PROMPT_FILE}"
73+
print_debug "GIV_REVISION: ${GIV_REVISION}"
74+
print_debug "GIV_PATHSPEC: ${GIV_PATHSPEC}"
75+
print_debug "GIV_OUTPUT_FILE: ${GIV_OUTPUT_FILE}"
76+
print_debug "GIV_TEMPERATURE: ${GIV_TEMPERATURE}"
77+
print_debug "GIV_CONTEXT_WINDOW: ${GIV_CONTEXT_WINDOW}"
2478

2579
# Validate template exists
2680
if [ ! -f "${prompt_tpl}" ]; then

0 commit comments

Comments
 (0)