Skip to content
Open
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
116 changes: 105 additions & 11 deletions .github/scripts/check-stale-docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,23 @@ DEAD=(
"gudusoft.dlineage.jar"
"src/main/java/demos/"
'src\main\java\demos\'
".;lib/*"
"build.xml"
"ftp.gudusoft.com"
"support.sqlparser.com"
"-Dexec.classpathScope"
)

WHY=(
"merged into pom.xml on 2026-07-28; build with 'mvn package -DskipTests'"
"the standalone jar is target/gsp_demo_java-1.0-SNAPSHOT-dlineage.jar"
"second package root removed 2026-07-27; demos are under src/main/java/gudusoft/gsqlparser/demos/"
"same, in Windows path form"
"lib/ was deleted on 2026-07-28; nothing needs a hand-written classpath, use the uber jar"
"both Ant builds were deleted on 2026-08-25; Maven and the .bat scripts are the two supported routes"
"does not resolve (NXDOMAIN, checked 2026-08-25)"
"does not resolve (NXDOMAIN, checked 2026-08-25)"
"unnecessary since the system-scope dependencies went; plain exec:java works"
)

# scan <file>... -- prints every hit, returns 1 if there was any
Expand All @@ -65,6 +75,42 @@ scan() {
return "$failed"
}

# check_links <file>... -- every relative markdown link must resolve
#
# Separate from the fixed-string scan above because it catches the other half of
# the same problem: not a document naming something deleted, but a document
# pointing at something that moved. Two had rotted unnoticed before this was
# written -- columnImpact linking ../dlineage from a directory where that
# resolves to antiSQLInjection/dlineage, and search linking ./visitors from
# inside search/ -- and neither was visible to any build.
check_links() {
python3 - "$@" <<'PY'
import os, re, sys

bad = []
for f in sys.argv[1:]:
base = os.path.dirname(f)
try:
text = open(f, encoding="utf-8").read()
except OSError as e:
bad.append((f, "", "unreadable: %s" % e))
continue
for m in re.finditer(r"\]\(([^)#\s]+)(?:#[^)\s]*)?\)", text):
target = m.group(1)
if target.startswith(("http://", "https://", "mailto:")):
continue
resolved = os.path.normpath(os.path.join(base, target))
if not os.path.exists(resolved):
bad.append((f, target, resolved))

for f, target, resolved in bad:
print(" %s -> %s" % (f, target))
print(" ^ resolves to %s, which does not exist\n" % resolved)

sys.exit(1 if bad else 0)
PY
}

self_test() {
local tmp rc pass=0 fail=0 i
tmp=$(mktemp -d)
Expand Down Expand Up @@ -92,6 +138,36 @@ self_test() {
fi
done

# The link half of the check, proved the same way.
mkdir -p "$tmp/sub"
printf 'see [the sub page](sub/page.md)\n' >"$tmp/links-ok.md"
printf 'placeholder\n' >"$tmp/sub/page.md"
if check_links "$tmp/links-ok.md" >/dev/null 2>&1; then
echo " ok a resolving relative link passes"
pass=$((pass + 1))
else
echo " FAIL a resolving relative link was reported as broken"
fail=$((fail + 1))
fi

printf 'see [the missing page](sub/gone.md)\n' >"$tmp/links-bad.md"
if check_links "$tmp/links-bad.md" >/dev/null 2>&1; then
echo " FAIL a broken relative link slipped through"
fail=$((fail + 1))
else
echo " ok a broken relative link is caught"
pass=$((pass + 1))
fi

printf 'see [the product site](https://www.sqlparser.com/nope)\n' >"$tmp/links-http.md"
if check_links "$tmp/links-http.md" >/dev/null 2>&1; then
echo " ok an http link is left alone"
pass=$((pass + 1))
else
echo " FAIL an http link was treated as a file path"
fail=$((fail + 1))
fi

echo
if [ "$fail" -gt 0 ]; then
echo "self-test: $fail of $((pass + fail)) cases FAILED"
Expand All @@ -107,28 +183,46 @@ if [ "${1:-}" = "--self-test" ]; then
exit $?
fi

all=()
while IFS= read -r f; do all+=("$f"); done < <(git ls-files '*.md')

if [ "${#all[@]}" -eq 0 ]; then
echo "::error::no markdown files found to check; is this a git checkout?"
exit 1
fi

# The dead-string scan skips ALLOW; the link check does not. A file may have a
# reason to name something that was removed, but never to link at something
# that is not there.
files=()
while IFS= read -r f; do
for f in "${all[@]}"; do
skip=0
for a in "${ALLOW[@]}"; do
if [ "$f" = "$a" ]; then skip=1; fi
done
if [ "$skip" -eq 0 ]; then files+=("$f"); fi
done < <(git ls-files '*.md')
done

if [ "${#files[@]}" -eq 0 ]; then
echo "::error::no markdown files found to check; is this a git checkout?"
exit 1
fi
rc=0

echo "checking ${#files[@]} markdown files for references to deleted things"
echo

if scan "${files[@]}"; then
echo "ok: no documentation points at anything that has been removed"
exit 0
else
echo "::error::documentation above still instructs the reader to use something that no longer exists"
echo "If a file's purpose is to record the removal, add it to ALLOW in $0."
rc=1
fi

echo
echo "checking relative links in ${#all[@]} markdown files"
echo
if check_links "${all[@]}"; then
echo "ok: every relative link resolves"
else
echo "::error::a relative link above points at a path that does not exist"
rc=1
fi

echo "::error::documentation above still instructs the reader to use something that no longer exists"
echo "If a file's purpose is to record the removal, add it to ALLOW in $0."
exit 1
exit "$rc"
6 changes: 5 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ jobs:
# produced. Someone evaluating GSP for the first time reasonably concluded
# the product was broken.
#
# It also resolves every relative markdown link, which is the other half of
# the same problem -- not a document naming something deleted, but one
# pointing at something that moved. Two had rotted unnoticed.
#
# --self-test runs first and on purpose: a fixed-string check that matches
# nothing looks identical to a clean repository.
- name: Documentation does not point at deleted things
- name: Documentation does not point at deleted or missing things
if: matrix.java == '21'
run: |
.github/scripts/check-stale-docs.sh --self-test
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ built-in Oracle query when no file is supplied.

If you have older notes telling you to add `-Dexec.classpathScope=compile`, you
no longer need it. It worked around `system`-scope dependencies that are gone.
Twenty demo readmes still carried it until 2026-08-25; `check-stale-docs.sh`
now keeps it out.

## The demos

Expand Down Expand Up @@ -431,7 +433,7 @@ than only building them.
|---|---|
| Parser version consistency | `set-parser-version.sh --check` across all four POMs |
| The pre-commit hook | `test-pre-commit-hook.sh`: a drifting bump is refused in a throwaway clone |
| Documentation | `check-stale-docs.sh`: no readme names `pom_dlineage.xml`, `gudusoft.dlineage.jar` or the old `demos` package root; `--self-test` first, so a check that matches nothing cannot pass as a clean repo |
| Documentation | `check-stale-docs.sh`: no readme names a deleted thing (`pom_dlineage.xml`, `gudusoft.dlineage.jar`, the old `demos` package root, the Ant builds, two dead download hosts, `-Dexec.classpathScope`), and every relative link resolves; `--self-test` first, so a check that matches nothing cannot pass as a clean repo |
| Licensed-only guard | `check-licensed-only-guard.sh`: each `licensed-only/*` module stops at `validate` **with the licence message**, not with `cannot find symbol` |
| Build and test | JDK 8 and 21; 156 tests, and a run that skipped everything fails |
| Demo smoke test | `checksyntax` against known SQL |
Expand Down
49 changes: 0 additions & 49 deletions build.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ java CallGraphDemo /f <path_to_sql_file> [/o <output file path>]

```bash
mvn -q exec:java -Dexec.mainClass=gudusoft.gsqlparser.demos.callgraph.CallGraphDemo \
-Dexec.args="/f samples/callgraph/sample_package.sql" -Dexec.classpathScope=compile
-Dexec.args="/f samples/callgraph/sample_package.sql"
```

```json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ works from a fresh clone with no database:

```bash
mvn -q exec:java -Dexec.mainClass=gudusoft.gsqlparser.demos.columninspect.ColumnInspect \
-Dexec.classpathScope=compile \
-Dexec.args="/t mssql /f samples/columninspect/sample.sql /metadata samples/columninspect/metadata.json /db testdb /schema dbo"
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ java EvaluatorDemo [/f <path_to_sql_file>] [/t <database type>]

```bash
mvn -q exec:java -Dexec.mainClass=gudusoft.gsqlparser.demos.evaluator.EvaluatorDemo \
-Dexec.args="/f q.sql /t oracle" -Dexec.classpathScope=compile
-Dexec.args="/f q.sql /t oracle"
```

```text
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/gudusoft/gsqlparser/demos/events/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ name, `}` into a single identifier token first.
Neither takes arguments; both are configured inline.

```bash
mvn -q exec:java -Dexec.mainClass=gudusoft.gsqlparser.demos.events.processTokenList \
-Dexec.classpathScope=compile
mvn -q exec:java -Dexec.mainClass=gudusoft.gsqlparser.demos.events.processTokenList
```

> **Both demos fail as shipped.**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ java findConstants <scriptfile> [/t <database type>]

```bash
mvn -q exec:java -Dexec.mainClass=gudusoft.gsqlparser.demos.findConstants.findConstants \
-Dexec.args="q.sql /t oracle" -Dexec.classpathScope=compile
-Dexec.args="q.sql /t oracle"
```

For `SELECT a.id, b.name, 100 AS n FROM ta a JOIN tb b ON a.id = b.id WHERE a.x > 1 AND 'k' = 'k';`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ prints exactly that.

```bash
mvn -q exec:java -Dexec.mainClass=gudusoft.gsqlparser.demos.findproceduralsql.FindProceduralSqlFiles \
-Dexec.args="oracle /path/to/scripts /path/to/procedural-only" \
-Dexec.classpathScope=compile
-Dexec.args="oracle /path/to/scripts /path/to/procedural-only"
```

Both directories are filesystem paths; the output directory receives copies, so
Expand Down
22 changes: 21 additions & 1 deletion src/main/java/gudusoft/gsqlparser/demos/formatsql/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,27 @@ WHERE ID = (SELECT sales_person
```

## Usage
`java formatsql sqlfile.sql`

The demo takes a bare filename — no `/f`:

```bash
mvn package -DskipTests
mvn -q exec:java -Dexec.mainClass=gudusoft.gsqlparser.demos.formatsql.formatsql \
-Dexec.args="your.sql"
```

Add `/tolerant` to keep formatting a file that contains statements the parser
rejects. `samples/formatsql/mixed-valid-invalid.sql` is checked in for exactly
that: without the flag it stops at the bad statement and tells you to add it,
and with it you get the formatted output plus `Formatter status:
OK_WITH_RECOVERY`.

```bash
mvn -q exec:java -Dexec.mainClass=gudusoft.gsqlparser.demos.formatsql.formatsql \
-Dexec.args="samples/formatsql/mixed-valid-invalid.sql /tolerant"
```

`formatsqlInHtml` in this directory writes the same output as HTML.

## [Format options](formatoptions.md)

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ be re-baselined after parser output changes.
```bash
mvn -q exec:java \
-Dexec.mainClass=gudusoft.gsqlparser.demos.generateLineage.GenerateLineageExpected \
-Dexec.args="<path to a *_lineage_test_cases.yaml>" \
-Dexec.classpathScope=compile
-Dexec.args="<path to a *_lineage_test_cases.yaml>"
```

The YAML it operates on is the library's own lineage fixture data
Expand Down
55 changes: 0 additions & 55 deletions src/main/java/gudusoft/gsqlparser/demos/gettablecolumns/build.xml

This file was deleted.

Loading
Loading