Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #42, #48: Allow for arg > 0, add arg sorting, and warning message… #63

Merged
merged 1 commit into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 77 additions & 14 deletions shdoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ BEGIN {

styles["github", "/code", "to"] = "```"

styles["github", "argN", "from"] = "^(\\$[0-9]) (\\S+)"
styles["github", "argN", "to"] = "**\\1** (\\2):"
styles["github", "argN", "from"] = "^(\\$[0-9]+)[[:blank:]]+(\\S+)[[:blank:]]+"
styles["github", "argN", "to"] = "**\\1** (\\2): "

styles["github", "arg@", "from"] = "^\\$@ (\\S+)"
styles["github", "arg@", "to"] = "**...** (\\1):"
styles["github", "arg@", "from"] = "^\\$@[[:blank:]]+(\\S+)[[:blank:]]+"
styles["github", "arg@", "to"] = "**...** (\\1): "

styles["github", "set", "from"] = "^(\\S+) (\\S+)"
styles["github", "set", "to"] = "**\\1** (\\2):"
Expand All @@ -52,6 +52,27 @@ BEGIN {
debug_file = "/dev/fd/" debug_fd
}

# @description Display the given error message with its line number on stderr.
# and exit with error.
# @arg $message string A error message.
# @exitcode 1
function error(message) {
error_message_color="\033[1;31m"
color_clear="\033[1;0m"
printf("%sline %4s, error : %s%s\n",\
error_message_color, NR, message, color_clear) > "/dev/stderr"
exit 1
}

# @description Display the given warning message with its line number on stderr.
# @arg $message string A warning message.
function warn(message) {
warn_message_color="\033[1;34m"
color_clear="\033[1;0m"
printf("%sline %4s, warning : %s%s\n", \
warn_message_color, NR, message, color_clear) > "/dev/stderr"
}

function render(type, text) {
return gensub( \
styles[style, type, "from"],
Expand Down Expand Up @@ -170,6 +191,14 @@ function join(arr) {
return result
}

# @description Remove leading and trailing space from line(s) of text.
# @arg text A text.
# @return The trimmed text.
function trim(text) {
gsub(/(^[[:blank:]]+|[[:blank:]]+$)/, "", text)
return text
}

function docblock_set(key, value) {
docblock[key] = value
}
Expand Down Expand Up @@ -218,16 +247,21 @@ function render_docblock(func_name, description, docblock) {

if ("arg" in docblock) {
push(lines, render("h4", "Arguments") "\n")
for (i in docblock["arg"]) {
item = docblock["arg"][i]

# Sort args by indexes (i.e. by argument number.)
asorti(docblock["arg"], sorted_indexes)
for (i in sorted_indexes) {
item = docblock["arg"][sorted_indexes[i]]
# Render numbered arguments ($[0-9]+).
item = render("argN", item)
# Render catch-all argument ($@).
item = render("arg@", item)
item = render("li", item)
if (i == length(docblock["arg"])) {
item = item "\n"
}
push(lines, item)
}

# Add empty line to signal end of list in markdown.
push(lines, "")
}

if ("noargs" in docblock) {
Expand Down Expand Up @@ -392,19 +426,48 @@ in_example {

}

/^[[:space:]]*# @arg/ {
# Select @arg lines with content.
/^[[:blank:]]*#[[:blank:]]+@arg[[:blank:]]+[^[:blank:]]/ {
debug("→ @arg")
sub(/^[[:space:]]*# @arg /, "")

arg_text = $0

docblock_push("arg", $0)
# Remove '# @arg ' tag.
sub(/^[[:blank:]]*#[[:blank:]]+@arg[[:blank:]]+/, "", arg_text)

next
# Trim text.
arg_text = trim(arg_text)

# Test if @arg is a numbered item (or $@).
if(match(arg_text, /^\$([0-9]+|@)[[:space:]]/, contents)) {
debug(" → → found arg $" arg_number)

# Fetch matched values.
arg_number = contents[1]

# Zero pad argument number for sorting.
if(arg_number ~ /[0-9]+/){
arg_number = sprintf("%03d", arg_number)
}

# Add arg description to arg docblock.
# arg_number is used as indice for sorting.
docblock["arg"][arg_number] = arg_text

# Stop processing current line, and process next line.
next
}

# Ignore badly formated @arg.
warn("Invalid format: @arg " arg_text)
}

/^[[:space:]]*# @noargs/ {
# Select @noargs line with no additionnal text.
/^[[:space:]]*#[[:blank:]]+@noargs[[:blank:]]*$/ {
debug("→ @noargs")
docblock["noargs"] = 1

# Stop processing current line, and process next line.
next
}

Expand Down
80 changes: 80 additions & 0 deletions tests/testcases/numbered-arguments.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/bin/bash
# @file test/testcases/@numbered-arguments.test.sh
# @author Pierre-Yves Landuré < contact at biapy dot fr >
# @brief Test cases for @arg keyword.
# @description
# Test these @arg comportements:
# - arg numbers in disorder.
# - arg numbers > 10
# - arg message with indentation and trailing spaces.
# - appears between @example and @set sections.

tests:put input <<EOF
# @name shdoc @arg tests
# @brief Test @arg functionnality.
# @description Tests for shdoc processing of @arg keyword.
# @arg \$4 int 4th arg.
# @arg \$6 string 6th arg.
# @set ARG_TESTED A variable set by the function.
# @arg \$5 int 5th arg.
# @arg \$@ string All other arguments.
# @arg \$1 string 1st arg.
# @example
# test-arg 'my-tested-argument'
#
# @arg \$3 bool 3rd arg with indentation and trailing spaces.
# @arg \$2 string 2nd arg.
# @arg \$7 string 7th arg with indentation before #.
# @arg \$8 array[] 8th arg with indentation between # and @arg.
# @arg \$9 string 9th arg with indentation between @arg and number.
# @arg \$10 string 10th arg.
# @arg \$11 string 11th arg.
test-arg() {
}
EOF

tests:put expected <<EOF
# shdoc @arg tests

Test @arg functionnality.

## Overview

Tests for shdoc processing of @arg keyword.

## Index

* [test-arg](#test-arg)

### test-arg

Tests for shdoc processing of @arg keyword.

#### Example

\`\`\`bash
test-arg 'my-tested-argument'
\`\`\`

#### Arguments

* **\$1** (string): 1st arg.
* **\$2** (string): 2nd arg.
* **\$3** (bool): 3rd arg with indentation and trailing spaces.
* **\$4** (int): 4th arg.
* **\$5** (int): 5th arg.
* **\$6** (string): 6th arg.
* **\$7** (string): 7th arg with indentation before #.
* **\$8** (array[]): 8th arg with indentation between # and @arg.
* **\$9** (string): 9th arg with indentation between @arg and number.
* **\$10** (string): 10th arg.
* **\$11** (string): 11th arg.
* **...** (string): All other arguments.

#### Variables set

* **ARG_TESTED** (A): variable set by the function.

EOF

assert