1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
#!/usr/bin/env bash
set -e
# @meta dotenv
# @cmd Call the function
# @arg func![`_choice_func`] The function name
# @arg args~[?`_choice_func_args`] The function args
call() {
"./bin/$argc_func" "${argc_args[@]}"
}
# @cmd Build all artifacts
build() {
if [[ -f functions.txt ]]; then
argc build-declarations-json
fi
if [[ "$OS" = "Windows_NT" ]]; then
argc build-win-shims
fi
}
# @cmd Build declarations for specific functions
# @option --output=functions.json <FILE> Specify a file path to save the function declarations
# @option --names-file=functions.txt Specify a file containing function names
# @arg funcs*[`_choice_func`] The function names
build-declarations-json() {
if [[ "${#argc_funcs[@]}" -gt 0 ]]; then
names=("${argc_funcs[@]}" )
elif [[ -f "$argc_names_file" ]]; then
names=($(cat "$argc_names_file"))
fi
if [[ -z "$names" ]]; then
_die "error: no specific function"
fi
result=()
for name in "${names[@]}"; do
result+=("$(build-func-declaration "$name")")
done
echo "["$(IFS=,; echo "${result[*]}")"]" | jq '.' > "$argc_output"
echo "Build $argc_output"
}
# @cmd Build declaration for a single function
# @arg func![`_choice_func`] The function name
build-func-declaration() {
argc --argc-export bin/$1 | _parse_declaration
}
# @cmd Build shims for the functions
# Because Windows OS can't run bash scripts directly, we need to make a shim for each function
#
# @flag --clear Clear the shims
build-win-shims() {
funcs=($(_choice_func))
for func in "${funcs[@]}"; do
echo "Shim bin/${func}.cmd"
_win_shim > "bin/${func}.cmd"
done
}
# @cmd Install this repo to aichat functions_dir
install() {
functions_dir="$(aichat --info | grep functions_dir | awk '{print $2}')"
if [[ ! -e "$functions_dir" ]]; then
ln -s "$(pwd)" "$functions_dir"
echo "$functions_dir symlinked"
else
echo "$functions_dir already exists"
fi
}
# @cmd Show versions of required tools for bug reports.
version() {
argc --argc-version
jq --version
curl --version | head -n 1
}
_parse_declaration() {
jq -r '
def parse_description(flag_option):
if flag_option.describe == "" then
{}
else
{ "description": flag_option.describe }
end;
def parse_enum(flag_option):
if flag_option.choice.type == "Values" then
{ "enum": flag_option.choice.data }
else
{}
end;
def parse_property(flag_option):
[
{ condition: (flag_option.flag == true), result: { type: "boolean" } },
{ condition: (flag_option.multiple_occurs == true), result: { type: "array", items: { type: "string" } } },
{ condition: (flag_option.notations[0] == "INT"), result: { type: "integer" } },
{ condition: (flag_option.notations[0] == "NUM"), result: { type: "number" } },
{ condition: true, result: { type: "string" } } ]
| map(select(.condition) | .result) | first
| (. + parse_description(flag_option))
| (. + parse_enum(flag_option))
;
def parse_parameter(flag_options):
{
type: "object",
properties: (reduce flag_options[] as $item ({}; . + { ($item.id | sub("-"; "_"; "g")): parse_property($item) })),
required: [flag_options[] | select(.required == true) | .id],
};
{
name: (.name | sub("-"; "_"; "g")),
description: .describe,
parameters: parse_parameter([.flag_options[] | select(.id != "help" and .id != "version")])
}'
}
_win_shim() {
cat <<-'EOF'
@echo off
setlocal
set "script_dir=%~dp0"
set "script_name=%~n0"
for /f "delims=" %%a in ('argc --argc-shell-path') do set "_bash_prog=%%a"
"%_bash_prog%" --noprofile --norc "%script_dir%\%script_name%" %*
EOF
}
_choice_func() {
ls -1 bin | grep -v '\.cmd'
}
_choice_func_args() {
args=( "${argc__positionals[@]}" )
argc --argc-compgen generic "bin/${args[0]}" "${args[@]}"
}
_die() {
echo "$*"
exit 1
}
# See more details at https://github.com/sigoden/argc
eval "$(argc --argc-eval "$0" "$@")"
|