From e0cdbc9e5244434cf879a4c9909c789b53a90566 Mon Sep 17 00:00:00 2001 From: Adrasteon Dev Date: Thu, 4 May 2023 07:45:18 +0200 Subject: [PATCH 1/2] feat: Better recognition of the Godot command and support of Godot 4 --- README.md | 53 ++++-- generate_reference | 193 +++++++++++++++------- generate_reference.bat | 53 +++++- godot-scripts/CollectorGd4.gd | 128 ++++++++++++++ godot-scripts/README.md | 2 +- godot-scripts/ReferenceCollectorCLIGd4.gd | 20 +++ godot-scripts/ReferenceCollectorGd4.gd | 30 ++++ 7 files changed, 398 insertions(+), 81 deletions(-) create mode 100644 godot-scripts/CollectorGd4.gd create mode 100644 godot-scripts/ReferenceCollectorCLIGd4.gd create mode 100644 godot-scripts/ReferenceCollectorGd4.gd diff --git a/README.md b/README.md index aafec56..94d2937 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,9 @@ Although to use the shell script that simplifies creating the reference, `genera Docstring or doc-comments in GDScript don't have any special markup. -You can document classes, properties, and functions with comment blocks placed on the line before their definition: +You can document classes, properties, and functions with comment blocks placed on the line before their definition. + +Example of docstrings for Godot 3: ```gdscript # A linear and angular amount of acceleration. @@ -76,12 +78,31 @@ func reset() -> void: angular = 0.0 ``` -If you need long docstrings, you can use multiple commented lines: +Example of docstrings for Godot 4: + +```gdscript +## A linear and angular amount of acceleration. +class_name GSTTargetAcceleration + + +## Linear acceleration +var linear: = Vector3.ZERO +## Angular acceleration +var angular: = 0.0 + +## Resets the accelerations to zero +func reset() -> void: + linear = Vector3.ZERO + angular = 0.0 ``` -# A specialized steering agent that updates itself every frame so the user does -# not have to using a KinematicBody2D -# category: Specialized agents + +If you need long docstrings, you can use multiple commented lines: + +```gdscript +## A specialized steering agent that updates itself every frame so the user does +## not have to using a KinematicBody2D +## category: Specialized agents extends GSAISpecializedAgent class_name GSAIKinematicBody2DAgent ``` @@ -105,13 +126,13 @@ project.godot file. Options: --h/--help -- Display this help message. --o/--output-directory -- directory path to output the documentation into. --d/--directory -- Name of a directory to find files and generate the code reference in the Godot project. - You can use the option multiple times to generate a reference for multiple directories. --f/--format -- Either `markdown` or `hugo`. If `hugo`, the output document includes a TOML front-matter - at the top. Default: `markdown`. --a/--author -- If --format is `hugo`, controls the author property in the TOML front-matter. +-h -- Display this help message. +-o -- directory path to output the documentation into. +-d -- Name of a directory to find files and generate the code reference in the Godot project. + You can use the option multiple times to generate a reference for multiple directories. +-f -- Either `markdown` or `hugo`. If `hugo`, the output document includes a TOML front-matter + at the top. Default: `markdown`. +-a -- If -f is `hugo`, controls the author property in the TOML front-matter. Usage example: @@ -131,7 +152,7 @@ To use them: You can output markdown files for [hugo](https://gohugo.io/), the static website engine. -To do so, call GDScript docs maker with the `--format hugo` option. You can use two extra flags with this: +To do so, call GDScript docs maker with the `-f hugo` option. You can use two extra flags with this: ```bash --date YYYY-MM-DD, the date in iso format, if you want the documents to have a date other than today. Default: datetime.date.today() @@ -148,8 +169,10 @@ python3 -m gdscript_docs_maker $HOME/Repositories/godot-steering-toolkit/project If you want to generate the JSON and convert it manually, there are three steps involved: -1. Copying the GDScript files `./godot-scripts/Collector.gd` and `./godot-scripts/ReferenceCollectorCLI.gd` or `./godot-scripts/ReferenceCollectorCLI.gd` to your Godot 3.2 project. -2. Running the GDScript code with Godot, either from the editor (`ReferenceCollector.gd`) or by calling Godot from the command line (`ReferenceCollectorCLI.gd`). +1. Copying the GDScript files to your Godot project: + - `./godot-scripts/Collector.gd` and `./godot-scripts/ReferenceCollectorCLI.gd` or `./godot-scripts/ReferenceCollectorCLI.gd` for Godot 3 + - `./godot-scripts/CollectorGd4.gd` and `./godot-scripts/ReferenceCollectorCLIGd4.gd` or `./godot-scripts/ReferenceCollectorCLIGd4.gd` for Godot 4 +2. Running the GDScript code with Godot, either from the editor (`ReferenceCollector.gd` / `ReferenceCollectorGd4.gd`) or by calling Godot from the command line (`ReferenceCollectorCLI.gd` / `ReferenceCollectorCLIGd4.gd`). 3. Running `gdscript_docs_maker` on the reference.json file that Godot generated in the previous step. diff --git a/generate_reference b/generate_reference index 3d6f0ed..d1dfa36 100755 --- a/generate_reference +++ b/generate_reference @@ -20,13 +20,13 @@ echo_help() { Options: - -h/--help -- Display this help message. - -o/--output-directory -- directory path to output the documentation into. - -d/--directory -- Name of a directory to find files and generate the code reference in the Godot project. - You can use the option multiple times to generate a reference for multiple directories. - -f/--format -- Either `markdown` or `hugo`. If `hugo`, the output document includes a TOML front-matter - at the top. Default: `markdown`. - -a/--author -- If --format is `hugo`, controls the author property in the TOML front-matter. + -h -- Display this help message. + -o -- directory path to output the documentation into. + -d -- Name of a directory to find files and generate the code reference in the Godot project. + You can use the option multiple times to generate a reference for multiple directories. + -f -- Either `markdown` or `hugo`. If `hugo`, the output document includes a TOML front-matter + at the top. Default: `markdown`. + -a -- If -f is `hugo`, controls the author property in the TOML front-matter. Usage example: @@ -39,41 +39,73 @@ EOT exit 0 } +get_godot_cmd() { + if command -v godot > /dev/null + then + echo godot + else + godotcmd="" + + if [ "$(echo $OSTYPE | head -c 6)" = "darwin" ] + then + godotcmd=$(find $(echo $PATH | tr ":" " ") -name "Godot*.app" -maxdepth 1 2>/dev/null | head -n 1 | tr -d '\n') + if [ "$(echo $godotcmd | tr -d '\n' | tail -c 4)" = ".app" ] + then + godotcmd="$godotcmd/Contents/MacOS/Godot" + fi + fi + + if [ "$godotcmd" = "" ] + then + if command -v zsh > /dev/null + then + godotcmd=$(zsh -c "whence -ap -m 'Godot*' | head -n 1") + elif command -v bash > /dev/null + then + godotcmd=$(bash -c "compgen -c Godot | head -n 1") + fi + fi + + if [ "$godotcmd" = "" ] + then + echo godot + else + echo $godotcmd + fi + fi +} + # Interpret arguments -arguments=$(getopt --name "generate_reference" -o "h,o:,d:,f:,a:" -l "help,output-directory:,directories:" -- "$@") - -eval set -- "$arguments" -while true; do - case "$1" in - -h | --help) - echo_help - shift - ;; - -o | --output-directory) - output_directory=$2 - shift 2 - ;; - -d | --directory) - directories_override="$directories_override $2" - shift 2 - ;; - -f | --format) - format=$2 - shift 2 - ;; - -a | --author) - author=$2 - shift 2 - ;; - --) - shift - break - ;; - *) - echo "Missing arguments. Try 'generate_reference --help' for more information" - exit 1 - ;; +if [ $(echo $1 | head -c 1) != "-" ] +then + shift 1 +fi + +while getopts ':ho:d:f:a:' OPTION; do + case "$OPTION" in + h) + echo_help + ;; + o) + output_directory=$OPTARG + ;; + d) + directories_override="$directories_override $OPTARG" + ;; + f) + format=$OPTARG + ;; + a) + author=$OPTARG + ;; + --) + break + ;; + ?) + echo "Missing arguments. Try 'generate_reference -h' for more information" + exit 1 + ;; esac done @@ -96,32 +128,69 @@ if ! test -f "$godot_project_file"; then fi - +ERROR_LOG=$(mktemp) +LOG=$(mktemp) godot_project_dir=$(dirname "$godot_project_file") +godot=$(get_godot_cmd) -path_ref_collector="godot-scripts/ReferenceCollectorCLI.gd" -path_collector="godot-scripts/Collector.gd" +$godot --version 2>"$ERROR_LOG" >/dev/null +test $? -eq 0 -o $? -eq 255 +godot_exec_ok=$? -# Override the content of the directories variable in ReferenceCollectorCLI.gd if we got --directory arguments -file_ref_collector=$(mktemp) -cat $path_ref_collector > "$file_ref_collector" -if test "$directories_override" != ""; then - echo "Setting directories" - args=$(echo "$directories_override" | sed -r 's#([-/._a-zA-Z0-9]+)#"res://\1",#g' | sed -r 's/,$//') - sed -ri "s#^var directories.+#var directories := [$args]#" "$file_ref_collector" +if [ $godot_exec_ok -eq 0 ] +then + version=$($godot --version | tail -n 1 | cut -c1-1) + + if [ "$version" = "3" ] + then + ref_collector="ReferenceCollectorCLI.gd" + path_collector="godot-scripts/Collector.gd" + path_ref_collector="godot-scripts/ReferenceCollectorCLI.gd" + else + ref_collector="ReferenceCollectorCLIGd4.gd" + path_collector="godot-scripts/CollectorGd4.gd" + path_ref_collector="godot-scripts/ReferenceCollectorCLIGd4.gd" + fi + + # Override the content of the directories variable in ReferenceCollectorCLI.gd if we got -d arguments + file_ref_collector=$(mktemp) + cat $path_ref_collector > "$file_ref_collector" + if test "$directories_override" != ""; then + echo "Setting directories" + args=$(echo "$directories_override" | sed -r 's#([-/._a-zA-Z0-9]+)#"res://\1",#g' | sed -r 's/,$//') + + if [ "$(echo $OSTYPE | head -c 6)" = "darwin" ] + then + sed -i "" -r "s#^var directories.+#var directories := [$args]#" "$file_ref_collector" + else + sed -ri "s#^var directories.+#var directories := [$args]#" "$file_ref_collector" + fi + fi + + echo "Copying collectors to project directory" + + cp "$file_ref_collector" "$godot_project_dir/$(basename $path_ref_collector)" >/dev/null + cp $path_collector "$godot_project_dir" >/dev/null + + echo "Generating reference json data..." + + if [ "$version" = "3" ] + then + $godot --editor --quit --no-window --script $ref_collector \ + --path "$godot_project_dir" 2>"$ERROR_LOG" >"$LOG" + else + $godot --editor --quit --headless --script $ref_collector \ + --path "$godot_project_dir" 2>"$ERROR_LOG" >"$LOG" + fi + + godot_exec_ok=1 + if grep -q -F "Saved data to res://reference.json" "$LOG" >/dev/null 2>/dev/null + then + godot_exec_ok=0 + fi fi -echo "Copying collectors to project directory" - -cp "$file_ref_collector" "$godot_project_dir/$(basename $path_ref_collector)" >/dev/null -cp $path_collector "$godot_project_dir" >/dev/null - -echo "Generating reference json data..." - -ERROR_LOG=$(mktemp) - -if ! godot --editor --quit --no-window --script ReferenceCollectorCLI.gd \ - --path "$godot_project_dir" 2>"$ERROR_LOG" >/dev/null +if [ $godot_exec_ok -ne 0 ] then ERRORS=$(cat "$ERROR_LOG") cat </dev/null +rm "$LOG" >/dev/null rm "$godot_project_dir/$(basename $path_ref_collector)" >/dev/null rm "$godot_project_dir/$(basename $path_collector)" >/dev/null rm "$godot_project_dir/reference.json" >/dev/null diff --git a/generate_reference.bat b/generate_reference.bat index 6ffc510..8d90329 100644 --- a/generate_reference.bat +++ b/generate_reference.bat @@ -8,8 +8,44 @@ setlocal enabledelayedexpansion where /q godot* if ERRORLEVEL 1 goto no-godot else ( - for /f "delims=" %%F in ('where godot*') do set godot=%%F + for /f "delims=" %%F in ('where godot*') do ( + ::Search a command called "godot" in path + echo.%%F | findstr "godot\." 1>nul + if !ERRORLEVEL! == 0 ( + for /f %%i in ('%%F -q --version') do ( + set v=%%i + set v=!v:~0,1! + if !v! == 3 ( + set is_godot_3=0 + set godot=%%F + ) + if !v! == 4 ( + set is_godot_3=1 + set godot=%%F + ) + ) + )else ( + echo.%%F | findstr "Godot_v3" 1>nul + + ::The console exe should not be used (especially when using Godot 3.5) + if !ERRORLEVEL! == 0 ( + set is_godot_3=0 + echo.%%F | findstr "_console.cmd" 1>nul + if !ERRORLEVEL! == 1 ( + set godot=%%F + ) + )else ( + set is_godot_3=1 + echo.%%F | findstr "_console.exe" 1>nul + if !ERRORLEVEL! == 1 ( + set godot=%%F + ) + ) + ) + ) ) +if not defined godot goto no-godot + ::Test for python where /q python if ERRORLEVEL 1 goto no-python @@ -110,8 +146,13 @@ goto end :tail set gdscript_path=godot-scripts -set gdscript_1=ReferenceCollectorCLI.gd -set gdscript_2=Collector.gd +if %is_godot_3% == 0 ( + set gdscript_1=ReferenceCollectorCLI.gd + set gdscript_2=Collector.gd +) else ( + set gdscript_1=ReferenceCollectorCLIGd4.gd + set gdscript_2=CollectorGd4.gd +) ::Copy CLI scripts to project location to be found in res:// copy /Y "%gdscript_path%\%gdscript_1%" "%project_path%\%gdscript_1%" > nul @@ -120,7 +161,11 @@ copy /Y "%gdscript_path%\%gdscript_2%" "%project_path%\%gdscript_2%" > nul echo Generating reference... ::Run godot in editor mode and runs the collector script -%godot% -e -q -s --no-window --path "%project_path%" %gdscript_1% > nul +if %is_godot_3% == 0 ( + %godot% -e -q -s --no-window --path "%project_path%" %gdscript_1% > nul +) else ( + %godot% -e -q --quit -s --headless --path "%project_path%" %gdscript_1% 2> nul > nul +) ::Clean up erase /Q "%project_path%\%gdscript_1%" diff --git a/godot-scripts/CollectorGd4.gd b/godot-scripts/CollectorGd4.gd new file mode 100644 index 0000000..3ac66f3 --- /dev/null +++ b/godot-scripts/CollectorGd4.gd @@ -0,0 +1,128 @@ +## Finds and generates a code reference from gdscript files. +@tool +extends SceneTree + +var warnings_regex := RegEx.new() + + +func _init() -> void: + var pattern := "^\\s?(warning-ignore(-all|):\\w+|warnings-disable)\\s*$" + var error := warnings_regex.compile(pattern) + if error != OK: + printerr("Failed to compile '%s' to a regex pattern." % pattern) + + +## Returns a list of file paths found in the directory. +## +## **Arguments** +## +## - dirpath: path to the directory from which to search files. +## - patterns: an array of string match patterns, where "*" matches zero or more +## arbitrary characters and "?" matches any single character except a period +## ("."). You can use it to find files by extensions. To find only GDScript +## files, ["*.gd"] +## - is_recursive: if `true`, walks over subdirectories recursively, returning all +## files in the tree. +func find_files( + dirpath := "", patterns := PackedStringArray(), is_recursive := false, do_skip_hidden := true +) -> PackedStringArray: + var file_paths := PackedStringArray() + + if not DirAccess.dir_exists_absolute(dirpath): + printerr("The directory does not exist: %s" % dirpath) + return file_paths + + var directory := DirAccess.open(dirpath) + if directory == null: + printerr("Could not open the following dirpath: %s" % dirpath) + return file_paths + + directory.list_dir_begin() + var file_name := directory.get_next() + var subdirectories := PackedStringArray() + while file_name != "": + if file_name != "." and file_name != "..": + if directory.current_is_dir() and is_recursive: + var subdirectory := dirpath.path_join(file_name) + file_paths.append_array(find_files(subdirectory, patterns, is_recursive)) + else: + for pattern in patterns: + if file_name.match(pattern): + file_paths.append(dirpath.path_join(file_name)) + file_name = directory.get_next() + + directory.list_dir_end() + return file_paths + + +## Saves text to a file. +func save_text(path := "", content := "") -> void: + var dirpath := path.get_base_dir() + var basename := path.get_file() + if dirpath == null or dirpath.is_empty(): + printerr("Couldn't save: the path %s is invalid." % path) + return + if not basename.is_valid_filename(): + printerr("Couldn't save: the file name, %s, contains invalid characters." % basename) + return + + if not DirAccess.dir_exists_absolute(dirpath): + DirAccess.make_dir_absolute(dirpath) + + var file = FileAccess.open(path, FileAccess.WRITE) + file.store_string(content) + file.close() + print("Saved data to %s" % path) + + +## Parses a list of GDScript files and returns a list of dictionaries with the +## code reference data. +## +## If `refresh_cache` is true, will refresh Godot's cache and get fresh symbols. +func get_reference(files := PackedStringArray(), refresh_cache := false) -> Dictionary: + var version := "n/a" + if ProjectSettings.has_setting("application/config/version"): + version = ProjectSettings.get_setting("application/config/version") + var data := { + name = ProjectSettings.get_setting("application/config/name"), + description = ProjectSettings.get_setting("application/config/description"), + version = version, + classes = [] + } + var workspace = Engine.get_singleton('GDScriptLanguageProtocol').get_workspace() + for file in files: + if not file.ends_with(".gd"): + continue + if refresh_cache: + workspace.parse_local_script(file) + var symbols: Dictionary = workspace.generate_script_api(file) + if symbols.has("name") and symbols["name"] == "": + symbols["name"] = file.get_file() + remove_warning_comments(symbols) + data["classes"].append(symbols) + return data + + +## Directly removes 'warning-ignore', 'warning-ignore-all', and 'warning-disable' +## comments from all symbols in the `symbols` dictionary passed to the function. +func remove_warning_comments(symbols: Dictionary) -> void: + symbols["description"] = remove_warnings_from_description(symbols["description"]) + for meta in ["constants", "members", "signals", "methods", "static_functions"]: + for metadata in symbols[meta]: + metadata["description"] = remove_warnings_from_description(metadata["description"]) + + for sub_class in symbols["sub_classes"]: + remove_warning_comments(sub_class) + + +func remove_warnings_from_description(description: String) -> String: + var lines := description.strip_edges().split("\n") + var clean_lines := PackedStringArray() + for line in lines: + if not warnings_regex.search(line): + clean_lines.append(line) + return "\n".join(clean_lines) + + +func print_pretty_json(reference: Dictionary) -> String: + return JSON.stringify(reference, " ") diff --git a/godot-scripts/README.md b/godot-scripts/README.md index 307cb8e..ddc24fc 100644 --- a/godot-scripts/README.md +++ b/godot-scripts/README.md @@ -2,7 +2,7 @@ Godot, since version 3.2, has a tool to create a class reference from GDScript code, through its language server. -This folder contains a tool script, `ReferenceCollector.gd`, to run directly from within your Godot projects and get the class reference as JSON using File->Run in the script editor. +This folder contains a tool script (`ReferenceCollector.gd` for Godot 3, `ReferenceCollectorGd4.gd` for Godot 4) to run directly from within your Godot projects and get the class reference as JSON using File->Run in the script editor. You can find more detailed instructions inside the GDScript code itself. diff --git a/godot-scripts/ReferenceCollectorCLIGd4.gd b/godot-scripts/ReferenceCollectorCLIGd4.gd new file mode 100644 index 0000000..df3a765 --- /dev/null +++ b/godot-scripts/ReferenceCollectorCLIGd4.gd @@ -0,0 +1,20 @@ +## Finds and generates a code reference from gdscript files. +@tool +extends SceneTree + + +var Collector: SceneTree = load("CollectorGd4.gd").new() +## A list of directories to collect files from. +var directories := ["res://"] +## If true, explore each directory recursively +var is_recursive: = true +## A list of patterns to filter files. +var patterns := ["*.gd"] + + +func _init() -> void: + var files := PackedStringArray() + for dirpath in directories: + files.append_array(Collector.find_files(dirpath, patterns, is_recursive)) + var json: String = Collector.print_pretty_json(Collector.get_reference(files)) + Collector.save_text("res://reference.json", json) diff --git a/godot-scripts/ReferenceCollectorGd4.gd b/godot-scripts/ReferenceCollectorGd4.gd new file mode 100644 index 0000000..208962f --- /dev/null +++ b/godot-scripts/ReferenceCollectorGd4.gd @@ -0,0 +1,30 @@ +## Finds and generates a code reference from gdscript files. +## +## To use this tool: +## +## - Place this script and Collector.gd in your Godot project folder. +## - Open the script in the script editor. +## - Modify the properties below to control the tool's behavior. +## - Go to File -> Run to run the script in the editor. +@tool +extends EditorScript +class_name ReferenceCollector + + +var Collector: SceneTree = load("CollectorGd4.gd").new() +## A list of directories to collect files from. +var directories := ["res://src"] +## If true, explore each directory recursively +var is_recursive: = true +## A list of patterns to filter files. +var patterns := ["*.gd"] +## Output path to save the class reference. +var save_path := "res://reference.json" + + +func _run() -> void: + var files := PackedStringArray() + for dirpath in directories: + files.append_array(Collector.find_files(dirpath, patterns, is_recursive)) + var json: String = Collector.print_pretty_json(Collector.get_reference(files)) + Collector.save_text(save_path, json) From dd807db8df63f6acdfed90ff1569c823228b4e7c Mon Sep 17 00:00:00 2001 From: Adrasteon Dev Date: Sat, 6 May 2023 10:24:50 +0200 Subject: [PATCH 2/2] fix: Addition of long options and better use of the sed command --- README.md | 16 ++++---- generate_reference | 99 +++++++++++++++++++++++++++++----------------- 2 files changed, 71 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 94d2937..8a97937 100644 --- a/README.md +++ b/README.md @@ -126,13 +126,13 @@ project.godot file. Options: --h -- Display this help message. --o -- directory path to output the documentation into. --d -- Name of a directory to find files and generate the code reference in the Godot project. - You can use the option multiple times to generate a reference for multiple directories. --f -- Either `markdown` or `hugo`. If `hugo`, the output document includes a TOML front-matter - at the top. Default: `markdown`. --a -- If -f is `hugo`, controls the author property in the TOML front-matter. +-h/--help -- Display this help message. +-o/--output-directory -- directory path to output the documentation into. +-d/--directory -- Name of a directory to find files and generate the code reference in the Godot project. + You can use the option multiple times to generate a reference for multiple directories. +-f/--format -- Either `markdown` or `hugo`. If `hugo`, the output document includes a TOML front-matter + at the top. Default: `markdown`. +-a/--author -- If --format is `hugo`, controls the author property in the TOML front-matter. Usage example: @@ -152,7 +152,7 @@ To use them: You can output markdown files for [hugo](https://gohugo.io/), the static website engine. -To do so, call GDScript docs maker with the `-f hugo` option. You can use two extra flags with this: +To do so, call GDScript docs maker with the `--format hugo` option. You can use two extra flags with this: ```bash --date YYYY-MM-DD, the date in iso format, if you want the documents to have a date other than today. Default: datetime.date.today() diff --git a/generate_reference b/generate_reference index d1dfa36..4c38c73 100755 --- a/generate_reference +++ b/generate_reference @@ -20,13 +20,13 @@ echo_help() { Options: - -h -- Display this help message. - -o -- directory path to output the documentation into. - -d -- Name of a directory to find files and generate the code reference in the Godot project. - You can use the option multiple times to generate a reference for multiple directories. - -f -- Either `markdown` or `hugo`. If `hugo`, the output document includes a TOML front-matter - at the top. Default: `markdown`. - -a -- If -f is `hugo`, controls the author property in the TOML front-matter. + -h/--help -- Display this help message. + -o/--output-directory -- directory path to output the documentation into. + -d/--directory -- Name of a directory to find files and generate the code reference in the Godot project. + You can use the option multiple times to generate a reference for multiple directories. + -f/--format -- Either `markdown` or `hugo`. If `hugo`, the output document includes a TOML front-matter + at the top. Default: `markdown`. + -a/--author -- If --format is `hugo`, controls the author property in the TOML front-matter. Usage example: @@ -75,6 +75,11 @@ get_godot_cmd() { fi } +is_gnu_sed(){ + sed --version >/dev/null 2>&1 +} + + # Interpret arguments if [ $(echo $1 | head -c 1) != "-" ] @@ -82,31 +87,53 @@ then shift 1 fi -while getopts ':ho:d:f:a:' OPTION; do - case "$OPTION" in - h) - echo_help - ;; - o) - output_directory=$OPTARG - ;; - d) - directories_override="$directories_override $OPTARG" - ;; - f) - format=$OPTARG - ;; - a) - author=$OPTARG - ;; - --) - break - ;; - ?) - echo "Missing arguments. Try 'generate_reference -h' for more information" - exit 1 - ;; - esac +while getopts ':hodfa-:' OPTION; do + # Support of long options with this syntax: --format=hugo + if [ "$OPTION" = "-" ]; then + OPTION="${OPTARG%%=*}" + OPTARG="${OPTARG#$OPTION}" + OPTARG="${OPTARG#=}" + fi + + # Support of long options with this syntax: --format hugo + if [ "$OPTARG" = "" ] + then + OPTARG="$(eval echo \${$OPTIND})"; OPTIND=$(( $OPTIND + 1 )) + fi + if [ "$(echo $OPTARG | cut -c1)" = "-" ] + then + OPTARG="" + OPTIND=$(( $OPTIND - 1 )) + fi + + # Option processing + if [ "$OPTION" = "h" -o "$OPTION" = "help" ] + then + echo_help + elif [ "$OPTARG" = "" ] + then + echo "Missing value for option $OPTION. Try 'generate_reference --help' for more information" + exit 1 + else + case "$OPTION" in + o | output-directory) + output_directory="$OPTARG" + ;; + d | directory) + directories_override="$directories_override $OPTARG" + ;; + f | format) + format="$OPTARG" + ;; + a | author) + author="$OPTARG" + ;; + ?) + echo "Missing arguments. Try 'generate_reference --help' for more information" + exit 1 + ;; + esac + fi done echo "Checking parameters" @@ -152,18 +179,18 @@ then path_ref_collector="godot-scripts/ReferenceCollectorCLIGd4.gd" fi - # Override the content of the directories variable in ReferenceCollectorCLI.gd if we got -d arguments + # Override the content of the directories variable in ReferenceCollectorCLI.gd if we got --directory arguments file_ref_collector=$(mktemp) cat $path_ref_collector > "$file_ref_collector" if test "$directories_override" != ""; then echo "Setting directories" args=$(echo "$directories_override" | sed -r 's#([-/._a-zA-Z0-9]+)#"res://\1",#g' | sed -r 's/,$//') - if [ "$(echo $OSTYPE | head -c 6)" = "darwin" ] + if is_gnu_sed then - sed -i "" -r "s#^var directories.+#var directories := [$args]#" "$file_ref_collector" - else sed -ri "s#^var directories.+#var directories := [$args]#" "$file_ref_collector" + else + sed -i "" -r "s#^var directories.+#var directories := [$args]#" "$file_ref_collector" fi fi