From 2b07fc2c7e4e6311d35ae72c17b25e47680d61f6 Mon Sep 17 00:00:00 2001 From: sigoden Date: Fri, 7 Jun 2024 04:06:59 +0800 Subject: refactor: rename scripts (#29) --- .gitignore | 1 + Argcfile.sh | 12 ++--- scripts/bin.js | 80 ------------------------------- scripts/bin.py | 73 ----------------------------- scripts/bin.sh | 102 ---------------------------------------- scripts/create-tool.sh | 125 +++++++++++++++++++++++++++++++++++++++++++++++++ scripts/create.sh | 124 ------------------------------------------------ scripts/run-tool.js | 80 +++++++++++++++++++++++++++++++ scripts/run-tool.py | 73 +++++++++++++++++++++++++++++ scripts/run-tool.sh | 102 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 387 insertions(+), 385 deletions(-) delete mode 100755 scripts/bin.js delete mode 100755 scripts/bin.py delete mode 100755 scripts/bin.sh create mode 100755 scripts/create-tool.sh delete mode 100755 scripts/create.sh create mode 100755 scripts/run-tool.js create mode 100755 scripts/run-tool.py create mode 100755 scripts/run-tool.sh diff --git a/.gitignore b/.gitignore index 4dcff7e..801c799 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /functions.txt.test /functions.json /bin +/tools/test.* /.env *.cmd __pycache__ \ No newline at end of file diff --git a/Argcfile.sh b/Argcfile.sh index 5fb0d72..8b0317d 100644 --- a/Argcfile.sh +++ b/Argcfile.sh @@ -52,7 +52,7 @@ build-bin() { _build_win_shim $lang > "$bin_file" else bin_file="$BIN_DIR/$basename" - ln -s "$PWD/scripts/bin.$lang" "$bin_file" + ln -s "$PWD/scripts/run-tool.$lang" "$bin_file" fi else not_found_funcs+=("$name") @@ -111,7 +111,7 @@ build-single-declaration() { func="$1" lang="${func##*.}" cmd="$(_lang_to_cmd "$lang")" - LLM_FUNCTION_ACTION=declarate "$cmd" "scripts/bin.$lang" "$func" + LLM_FUNCTION_ACTION=declarate "$cmd" "scripts/run-tool.$lang" "$func" } # @cmd List functions that can be put into functions.txt @@ -151,8 +151,8 @@ test-functions() { echo -n "Test $cmd_path: " "$cmd_path" "$data" if ! _is_win; then - echo -n "Test $cmd scripts/bin.$lang $func: " - "$cmd" "scripts/bin.$lang" "$func" "$data" + echo -n "Test $cmd scripts/run-tool.$lang $func: " + "$cmd" "scripts/run-tool.$lang" "$func" "$data" fi fi done @@ -175,7 +175,7 @@ install() { # @cmd Create a boilplate tool script file. # @arg args~ create() { - ./scripts/create.sh "$@" + ./scripts/create-tool.sh "$@" } # @cmd Show pre-requisite tool versions @@ -219,7 +219,7 @@ set "bin_dir=%~dp0" for %%i in ("%bin_dir:~0,-1%") do set "script_dir=%%~dpi" set "script_name=%~n0" -$run "%script_dir%scripts\bin.$lang" "%script_name%.$lang" %* +$run "%script_dir%scripts\run-tool.$lang" "%script_name%.$lang" %* EOF } diff --git a/scripts/bin.js b/scripts/bin.js deleted file mode 100755 index c7a440c..0000000 --- a/scripts/bin.js +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env node - -const path = require("path"); -const fs = require("fs"); - -function parseArgv() { - let funcName = process.argv[1]; - let funcData = null; - - if (funcName.endsWith("bin.js")) { - funcName = process.argv[2]; - funcData = process.argv[3]; - } else { - funcName = path.basename(funcName); - funcData = process.argv[2]; - } - - if (funcName.endsWith(".js")) { - funcName = funcName.slice(0, -3); - } - - return [funcName, funcData]; -} - -function loadFunc(funcName) { - const funcFileName = `${funcName}.js`; - const funcPath = path.resolve( - process.env["LLM_FUNCTIONS_DIR"], - `tools/${funcFileName}`, - ); - try { - return require(funcPath); - } catch { - console.log(`Invalid function: ${funcFileName}`); - process.exit(1); - } -} - -function loadEnv(filePath) { - try { - const data = fs.readFileSync(filePath, "utf-8"); - const lines = data.split("\n"); - - lines.forEach((line) => { - if (line.trim().startsWith("#") || line.trim() === "") return; - - const [key, ...value] = line.split("="); - process.env[key.trim()] = value.join("=").trim(); - }); - } catch {} -} - -process.env["LLM_FUNCTIONS_DIR"] = path.resolve(__dirname, ".."); - -loadEnv(path.resolve(process.env["LLM_FUNCTIONS_DIR"], ".env")); - -const [funcName, funcData] = parseArgv(); - -process.env["LLM_FUNCTION_NAME"] = funcName; - -if (process.env["LLM_FUNCTION_ACTION"] == "declarate") { - const { declarate } = loadFunc(funcName); - console.log(JSON.stringify(declarate(), null, 2)); -} else { - if (!funcData) { - console.log("No json data"); - process.exit(1); - } - - let args; - try { - args = JSON.parse(funcData); - } catch { - console.log("Invalid json data"); - process.exit(1); - } - - const { execute } = loadFunc(funcName); - execute(args); -} diff --git a/scripts/bin.py b/scripts/bin.py deleted file mode 100755 index 0ea49ed..0000000 --- a/scripts/bin.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -import os -import json -import sys -import importlib.util - -def parse_argv(): - func_name = sys.argv[0] - func_data = None - - if func_name.endswith("bin.py"): - func_name = sys.argv[1] if len(sys.argv) > 1 else None - func_data = sys.argv[2] if len(sys.argv) > 2 else None - else: - func_name = os.path.basename(func_name) - func_data = sys.argv[1] if len(sys.argv) > 1 else None - - if func_name.endswith(".py"): - func_name = func_name[:-3] - - return func_name, func_data - -def load_func(func_name): - func_file_name = f"{func_name}.py" - func_path = os.path.join(os.environ["LLM_FUNCTIONS_DIR"], f"tools/{func_file_name}") - if os.path.exists(func_path): - spec = importlib.util.spec_from_file_location(f"{func_file_name}", func_path) - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - return module - else: - print(f"Invalid function: {func_file_name}") - sys.exit(1) - -def load_env(file_path): - try: - with open(file_path, 'r') as f: - for line in f: - line = line.strip() - if line.startswith('#') or line == '': - continue - - key, *value = line.split('=') - os.environ[key.strip()] = '='.join(value).strip() - except FileNotFoundError: - pass - -os.environ["LLM_FUNCTIONS_DIR"] = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - -load_env(os.path.join(os.environ["LLM_FUNCTIONS_DIR"], ".env")) - -func_name, func_data = parse_argv() - -os.environ["LLM_FUNCTION_NAME"] = func_name - -if os.getenv("LLM_FUNCTION_ACTION") == "declarate": - module = load_func(func_name) - print(json.dumps(module.declarate(), indent=2)) -else: - if not func_data: - print("No json data") - sys.exit(1) - - args = None - try: - args = json.loads(func_data) - except (json.JSONDecodeError, TypeError): - print("Invalid json data") - sys.exit(1) - - module = load_func(func_name) - module.execute(args) \ No newline at end of file diff --git a/scripts/bin.sh b/scripts/bin.sh deleted file mode 100755 index 807343a..0000000 --- a/scripts/bin.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env bash -set -e - -export LLM_FUNCTIONS_DIR="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)" - -if [[ -f "$LLM_FUNCTIONS_DIR/.env" ]]; then - source "$LLM_FUNCTIONS_DIR/.env" -fi - -if [[ "$0" == *bin.sh ]]; then - func_name="$1" - func_data="$2" -else - func_name="$(basename "$0")" - func_data="$1" -fi -if [[ "$func_name" == *.sh ]]; then - func_name="${func_name:0:$((${#func_name}-3))}" -fi - -export LLM_FUNCTION_NAME="$func_name" -func_file="$LLM_FUNCTIONS_DIR/tools/$func_name.sh" - -export JQ=jq -if [[ "$OS" == "Windows_NT" ]]; then - export JQ="jq -b" - func_file="$(cygpath -w "$func_file")" -fi - -if [[ "$LLM_FUNCTION_ACTION" == "declarate" ]]; then - argc --argc-export "$func_file" | \ - $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")]) - }' -else - if [[ -z "$func_data" ]]; then - echo "No json data" - exit 1 - fi - - data="$( - echo "$func_data" | \ - $JQ -r ' - to_entries | .[] | - (.key | split("_") | join("-")) as $key | - if .value | type == "array" then - .value | .[] | "--\($key)\n\(. | @json)" - elif .value | type == "boolean" then - if .value then "--\($key)" else "" end - else - "--\($key)\n\(.value | @json)" - end' - )" || { - echo "Invalid json data" - exit 1 - } - while IFS= read -r line; do - if [[ "$line" == '--'* ]]; then - args+=("$line") - else - args+=("$(echo "$line" | $JQ -r '.')") - fi - done <<< "$data" - "$func_file" "${args[@]}" -fi \ No newline at end of file diff --git a/scripts/create-tool.sh b/scripts/create-tool.sh new file mode 100755 index 0000000..40d2ef3 --- /dev/null +++ b/scripts/create-tool.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +set -e + +# @describe Create a boilplate tool script file. +# It automatically generate declaration json for `*.py` and `*.js` and generate `@option` tags for `.sh`. +# Examples: +# argc create abc.sh foo bar! baz+ qux* +# ./scripts/create-tool.sh test.py foo bar! baz+ qux* +# @arg name! The script file name. +# @arg params* The script parameters + +main() { + output="tools/$argc_name" + if [[ -f "$output" ]]; then + _die "$output already exists" + fi + ext="${argc_name##*.}" + support_exts=('.sh' '.js' '.py') + if [[ "$ext" == "$argc_name" ]]; then + _die "No extension name, pelease add one of ${support_exts[*]}" + fi + case $ext in + sh) create_sh ;; + js) create_js ;; + py) create_py ;; + *) _die "Invalid extension name: $ext, must be one of ${support_exts[*]}" ;; + esac +} + +create_sh() { + cat <<-'EOF' | sed 's/__DESCRIBE_TAG__/# @describe/g' > "$output" +#!/usr/bin/env bash +set -e + +__DESCRIBE_TAG__ +EOF + for param in "${argc_params[@]}"; do + echo "# @option --$(echo $param | sed 's/-/_/g')" >> "$output" + done + cat <<-'EOF' >> "$output" + +main() { + ( set -o posix ; set ) | grep ^argc_ # inspect all argc variables +} + +eval "$(argc --argc-eval "$0" "$@")" +EOF + chmod +x "$output" +} + +create_js() { + cat < "$output" +exports.declarate = function declarate() { + return $(build_schema) +} + +exports.execute = function execute(data) { + console.log(data) +} +EOF +} + +create_py() { + cat < "$output" +def declarate(): + return $(build_schema) + + +def execute(data): + print(data) +EOF +} + +build_schema() { + echo '{ + "name": "'"${argc_name%%.*}"'", + "description": "", + "parameters": '"$(build_properties)"' + }' | jq '.' | sed '2,$s/^/ /g' +} + +build_properties() { + required_params=() + properties='' + for param in "${argc_params[@]}"; do + if [[ "$param" == *'!' ]]; then + param="${param:0:$((${#param}-1))}" + required_params+=("$param") + property='{"'"$param"'":{"type":"string","description":""}}' + elif [[ "$param" == *'+' ]]; then + param="${param:0:$((${#param}-1))}" + required_params+=("$param") + property='{"'"$param"'":{"type":"array","description":"","items": {"type":"string"}}}' + elif [[ "$param" == *'*' ]]; then + param="${param:0:$((${#param}-1))}" + property='{"'"$param"'":{"type":"array","description":"","items": {"type":"string"}}}' + else + property='{"'"$param"'":{"type":"string","description":""}}' + fi + properties+="$property" + done + required='' + for param in "${required_params[@]}"; do + if [[ -z "$required" ]]; then + required=',"required":[' + fi + required+="\"$param\"," + done + if [[ -n "$required" ]]; then + required="${required:0:$((${#required}-1))}" + required+="]" + fi + echo '{ + "type": "object", + "properties": '"$(echo "$properties" | jq -s 'add')$required"' + }' | jq '.' +} + +_die() { + echo "$*" + exit 1 +} + +# See more details at https://github.com/sigoden/argc +eval "$(argc --argc-eval "$0" "$@")" \ No newline at end of file diff --git a/scripts/create.sh b/scripts/create.sh deleted file mode 100755 index 0d558fa..0000000 --- a/scripts/create.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env bash -set -e - -# @describe Create a boilplate tool script file. -# It automatically generate declaration json for `*.py` and `*.js` and generate `@option` tags for `.sh`. -# Examples: -# argc create abc.sh foo bar! baz+ qux* -# @arg name! The script file name. -# @arg params* The script parameters - -main() { - output="tools/$argc_name" - if [[ -f "$output" ]]; then - _die "$output already exists" - fi - ext="${argc_name##*.}" - support_exts=('.sh' '.js' '.py') - if [[ "$ext" == "$argc_name" ]]; then - _die "No extension name, pelease add one of ${support_exts[*]}" - fi - case $ext in - sh) create_sh ;; - js) create_js ;; - py) create_py ;; - *) _die "Invalid extension name: $ext, must be one of ${support_exts[*]}" ;; - esac -} - -create_sh() { - cat <<-'EOF' | sed 's/__DESCRIBE_TAG__/# @describe/g' > "$output" -#!/usr/bin/env bash -set -e - -__DESCRIBE_TAG__ -EOF - for param in "${argc_params[@]}"; do - echo "# @option --$(echo $param | sed 's/-/_/g')" >> "$output" - done - cat <<-'EOF' >> "$output" - -main() { - ( set -o posix ; set ) | grep ^argc_ # inspect all argc variables -} - -eval "$(argc --argc-eval "$0" "$@")" -EOF - chmod +x "$output" -} - -create_js() { - cat < "$output" -exports.declarate = function declarate() { - return $(build_schema) -} - -exports.execute = function execute(data) { - console.log(data) -} -EOF -} - -create_py() { - cat < "$output" -def declarate(): - return $(build_schema) - - -def execute(data): - print(data) -EOF -} - -build_schema() { - echo '{ - "name": "'"${argc_name%%.*}"'", - "description": "", - "parameters": '"$(build_properties)"' - }' | jq '.' | sed '2,$s/^/ /g' -} - -build_properties() { - required_params=() - properties='' - for param in "${argc_params[@]}"; do - if [[ "$param" == *'!' ]]; then - param="${param:0:$((${#param}-1))}" - required_params+=("$param") - property='{"'"$param"'":{"type":"string","description":""}}' - elif [[ "$param" == *'+' ]]; then - param="${param:0:$((${#param}-1))}" - required_params+=("$param") - property='{"'"$param"'":{"type":"array","description":"","items": {"type":"string"}}}' - elif [[ "$param" == *'*' ]]; then - param="${param:0:$((${#param}-1))}" - property='{"'"$param"'":{"type":"array","description":"","items": {"type":"string"}}}' - else - property='{"'"$param"'":{"type":"string","description":""}}' - fi - properties+="$property" - done - required='' - for param in "${required_params[@]}"; do - if [[ -z "$required" ]]; then - required=',"required":[' - fi - required+="\"$param\"," - done - if [[ -n "$required" ]]; then - required="${required:0:$((${#required}-1))}" - required+="]" - fi - echo '{ - "type": "object", - "properties": '"$(echo "$properties" | jq -s 'add')$required"' - }' | jq '.' -} - -_die() { - echo "$*" - exit 1 -} - -# See more details at https://github.com/sigoden/argc -eval "$(argc --argc-eval "$0" "$@")" \ No newline at end of file diff --git a/scripts/run-tool.js b/scripts/run-tool.js new file mode 100755 index 0000000..43a6587 --- /dev/null +++ b/scripts/run-tool.js @@ -0,0 +1,80 @@ +#!/usr/bin/env node + +const path = require("path"); +const fs = require("fs"); + +function parseArgv() { + let funcName = process.argv[1]; + let funcData = null; + + if (funcName.endsWith("run-tool.js")) { + funcName = process.argv[2]; + funcData = process.argv[3]; + } else { + funcName = path.basename(funcName); + funcData = process.argv[2]; + } + + if (funcName.endsWith(".js")) { + funcName = funcName.slice(0, -3); + } + + return [funcName, funcData]; +} + +function loadFunc(funcName) { + const funcFileName = `${funcName}.js`; + const funcPath = path.resolve( + process.env["LLM_FUNCTIONS_DIR"], + `tools/${funcFileName}`, + ); + try { + return require(funcPath); + } catch { + console.log(`Invalid function: ${funcFileName}`); + process.exit(1); + } +} + +function loadEnv(filePath) { + try { + const data = fs.readFileSync(filePath, "utf-8"); + const lines = data.split("\n"); + + lines.forEach((line) => { + if (line.trim().startsWith("#") || line.trim() === "") return; + + const [key, ...value] = line.split("="); + process.env[key.trim()] = value.join("=").trim(); + }); + } catch {} +} + +process.env["LLM_FUNCTIONS_DIR"] = path.resolve(__dirname, ".."); + +loadEnv(path.resolve(process.env["LLM_FUNCTIONS_DIR"], ".env")); + +const [funcName, funcData] = parseArgv(); + +process.env["LLM_FUNCTION_NAME"] = funcName; + +if (process.env["LLM_FUNCTION_ACTION"] == "declarate") { + const { declarate } = loadFunc(funcName); + console.log(JSON.stringify(declarate(), null, 2)); +} else { + if (!funcData) { + console.log("No json data"); + process.exit(1); + } + + let args; + try { + args = JSON.parse(funcData); + } catch { + console.log("Invalid json data"); + process.exit(1); + } + + const { execute } = loadFunc(funcName); + execute(args); +} diff --git a/scripts/run-tool.py b/scripts/run-tool.py new file mode 100755 index 0000000..30968a1 --- /dev/null +++ b/scripts/run-tool.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python + +import os +import json +import sys +import importlib.util + +def parse_argv(): + func_name = sys.argv[0] + func_data = None + + if func_name.endswith("run-tool.py"): + func_name = sys.argv[1] if len(sys.argv) > 1 else None + func_data = sys.argv[2] if len(sys.argv) > 2 else None + else: + func_name = os.path.basename(func_name) + func_data = sys.argv[1] if len(sys.argv) > 1 else None + + if func_name.endswith(".py"): + func_name = func_name[:-3] + + return func_name, func_data + +def load_func(func_name): + func_file_name = f"{func_name}.py" + func_path = os.path.join(os.environ["LLM_FUNCTIONS_DIR"], f"tools/{func_file_name}") + if os.path.exists(func_path): + spec = importlib.util.spec_from_file_location(f"{func_file_name}", func_path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + else: + print(f"Invalid function: {func_file_name}") + sys.exit(1) + +def load_env(file_path): + try: + with open(file_path, 'r') as f: + for line in f: + line = line.strip() + if line.startswith('#') or line == '': + continue + + key, *value = line.split('=') + os.environ[key.strip()] = '='.join(value).strip() + except FileNotFoundError: + pass + +os.environ["LLM_FUNCTIONS_DIR"] = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + +load_env(os.path.join(os.environ["LLM_FUNCTIONS_DIR"], ".env")) + +func_name, func_data = parse_argv() + +os.environ["LLM_FUNCTION_NAME"] = func_name + +if os.getenv("LLM_FUNCTION_ACTION") == "declarate": + module = load_func(func_name) + print(json.dumps(module.declarate(), indent=2)) +else: + if not func_data: + print("No json data") + sys.exit(1) + + args = None + try: + args = json.loads(func_data) + except (json.JSONDecodeError, TypeError): + print("Invalid json data") + sys.exit(1) + + module = load_func(func_name) + module.execute(args) \ No newline at end of file diff --git a/scripts/run-tool.sh b/scripts/run-tool.sh new file mode 100755 index 0000000..6f5befc --- /dev/null +++ b/scripts/run-tool.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +set -e + +export LLM_FUNCTIONS_DIR="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)" + +if [[ -f "$LLM_FUNCTIONS_DIR/.env" ]]; then + source "$LLM_FUNCTIONS_DIR/.env" +fi + +if [[ "$0" == *run-tool.sh ]]; then + func_name="$1" + func_data="$2" +else + func_name="$(basename "$0")" + func_data="$1" +fi +if [[ "$func_name" == *.sh ]]; then + func_name="${func_name:0:$((${#func_name}-3))}" +fi + +export LLM_FUNCTION_NAME="$func_name" +func_file="$LLM_FUNCTIONS_DIR/tools/$func_name.sh" + +export JQ=jq +if [[ "$OS" == "Windows_NT" ]]; then + export JQ="jq -b" + func_file="$(cygpath -w "$func_file")" +fi + +if [[ "$LLM_FUNCTION_ACTION" == "declarate" ]]; then + argc --argc-export "$func_file" | \ + $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")]) + }' +else + if [[ -z "$func_data" ]]; then + echo "No json data" + exit 1 + fi + + data="$( + echo "$func_data" | \ + $JQ -r ' + to_entries | .[] | + (.key | split("_") | join("-")) as $key | + if .value | type == "array" then + .value | .[] | "--\($key)\n\(. | @json)" + elif .value | type == "boolean" then + if .value then "--\($key)" else "" end + else + "--\($key)\n\(.value | @json)" + end' + )" || { + echo "Invalid json data" + exit 1 + } + while IFS= read -r line; do + if [[ "$line" == '--'* ]]; then + args+=("$line") + else + args+=("$(echo "$line" | $JQ -r '.')") + fi + done <<< "$data" + "$func_file" "${args[@]}" +fi \ No newline at end of file -- cgit v1.2.3