Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f8f81fa
feat(router): 末尾セグメント *name の catch-all ルートを追加
redpeacock78 Jul 9, 2026
7da29dd
feat(dsl): hawk-libs desugar を @include 再帰追跡 + dist/ ツリー出力に変更
redpeacock78 Jul 9, 2026
f4d4488
feat(cli): desugar 生成物を dist/ に永続化 (一時ファイル削除を廃止)
redpeacock78 Jul 9, 2026
73e6a7a
fix(hawk-libs): desugar のPRレビュー指摘を修正
redpeacock78 Jul 9, 2026
57899f8
fix(hawk-libs): desugar 出力が source にエイリアスする問題を修正
redpeacock78 Jul 9, 2026
e197ba4
fix(hawk-libs): desugar 出力の scratch/mv 化とパス物理正規化
redpeacock78 Jul 10, 2026
9ea4a00
fix(hawk-libs): desugar の publish 順序・entry 循環・symlink source を修正
redpeacock78 Jul 10, 2026
d8dedff
fix(hawk-libs): @include パス正規化と closure 一括 publish
redpeacock78 Jul 10, 2026
fe177c0
fix(hawk-libs): desugar 出力先の保護と include 解決の厳密化
redpeacock78 Jul 10, 2026
e3f3e31
fix(hawk-libs): publish キューの配列化と別名 include の拒否
redpeacock78 Jul 10, 2026
a722a0b
fix(hawk-libs): 空白入り include パスの拒否と marker の事前検証
redpeacock78 Jul 10, 2026
2206ba4
test(desugar): alias_include 失敗時に何も publish されないことを検証
redpeacock78 Jul 10, 2026
a48f18a
fix(hawk-libs): marker の事前検証強化と scratch cleanup の quote 安全化
redpeacock78 Jul 10, 2026
620aa12
fix(hawk-libs): marker のrel単位記録・glob展開停止・rootテスト対応
redpeacock78 Jul 10, 2026
eb968d3
fix(hawk-libs): marker 予約名とプロジェクト内絶対パス include の拒否
redpeacock78 Jul 11, 2026
dec66f3
fix(hawk-libs): marker読込検証・grep引数保護・symlink解決の強化
redpeacock78 Jul 11, 2026
d44bdcd
fix(hawk-libs): プロジェクト内への hard link 絶対パス include を拒否
redpeacock78 Jul 11, 2026
cfd53fc
fix(hawk-libs): closure確定後のhard link照合・marker src_root記録・symlink dist検証
redpeacock78 Jul 14, 2026
5c5de88
fix(hawk-libs): .hawk-dist 配下の rel も予約名として拒否
redpeacock78 Jul 14, 2026
7e52112
fix(cli): check/emit を隔離した一時 dist に出力する
redpeacock78 Jul 14, 2026
6f40968
fix: emit 出力と dist 親を安全化
redpeacock78 Jul 15, 2026
238fb54
fix: emit の Bash 3.2 互換性を戻す
redpeacock78 Jul 15, 2026
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ libtest_gawk_import.a
.code-review-graph/

docs/superpowers/

dist/
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: MIT
.PHONY: run dev bench check emit test test-unit test-dsl test-dsl2 test-cli test-e2e lint clean help ci build-libs fetch-libs test-libs libs-clean ci-full
.PHONY: run dev bench check emit test test-unit test-dsl test-dsl2 test-cli test-desugar test-e2e lint clean help ci build-libs fetch-libs test-libs libs-clean ci-full

APP ?= app.awk
WORKERS ?= 4
Expand Down Expand Up @@ -38,7 +38,7 @@ check: ## DSL 型検査のみ (サーバー起動なし)
emit: ## desugar 済み AWK を stdout 出力
./bin/hawk emit $(if $(STRICT),--strict) $(APP)

test: test-unit test-dsl test-dsl2 test-cli test-e2e ## 全テスト
test: test-unit test-dsl test-dsl2 test-cli test-desugar test-e2e ## 全テスト

test-unit: ## awk 内 assert
@libs_args=""; libs_vars=""; \
Expand Down Expand Up @@ -67,6 +67,9 @@ test-dsl2: ## DSL v2 工程別 golden テスト
test-cli: ## CLI 単体テスト
./tests/unit/cli/run.sh

test-desugar: ## multi-file desugar テスト
./tests/unit/desugar/run.sh

test-e2e: ## サーバー起動 + curl
./tests/e2e/run.sh

Expand Down
4 changes: 4 additions & 0 deletions core/router.awk
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ function _route_add(method, path, handler, pattern, params, parts, n, i, seg)
if (substr(seg, 1, 1) == ":") {
pattern = pattern "([^/]+)"
params = params (params == "" ? "" : ",") substr(seg, 2)
} else if (i == n && substr(seg, 1, 1) == "*" && length(seg) > 1) {
# 末尾セグメント *name -- catch-all。残りパス全体を 1 パラメータで捕捉
pattern = pattern "(.+)"
params = params (params == "" ? "" : ",") substr(seg, 2)
} else {
pattern = pattern _route_escape_re(seg)
}
Expand Down
13 changes: 13 additions & 0 deletions docs/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ BEGIN {
}
```

### Catch-all parameters

A trailing segment of the form `*name` matches the rest of the path
(one or more characters, including `/`):

```awk
hawk.app.get("/docs/*path", "docs_handler")
# GET /docs/guide/routing -> req["params:path"] = "guide/routing"
```

`*name` is only special in the final segment. Anywhere else it is
matched literally.

---

*For the full routing method reference, see [API Reference](api.md).*
8 changes: 7 additions & 1 deletion libexec/hawk-check
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ if [[ -f .env ]]; then
set +a
fi

# check は検証のみが目的。永続 dist に publish した後で strict 検証が走ると、
# 検証失敗でも成果物が更新済みになり、稼働中の hawk-serve が失敗した check の
# 出力を読んでしまう。呼び出し元の HAWK_DIST も使わず隔離した一時 dist に出す
HAWK_DIST="$(mktemp -d /tmp/hawk-check.XXXXXX)"
export HAWK_DIST
trap 'rm -rf "$HAWK_DIST"' EXIT

APP_AWK="$("$LIBS" desugar "$APP")"
trap "rm -f '$APP_AWK'" EXIT

if [[ "$STRICT" -eq 1 ]]; then
if ! gawk --sandbox -f "${HAWK_LIB}/dsl/adt.awk" -f "${HAWK_LIB}/dsl/type.awk" -f "${HAWK_LIB}/dsl/strict_stubs.awk" -f "$APP_AWK" < /dev/null >/dev/null 2>&1; then
Expand Down
32 changes: 30 additions & 2 deletions libexec/hawk-emit
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ if [[ -f .env ]]; then
set +a
fi

# emit は desugar 結果の出力のみが目的。永続 dist に publish した後で strict 検証が
# 走ると、検証失敗でも成果物が更新済みになり、稼働中の hawk-serve が失敗した emit の
# 出力を読んでしまう。呼び出し元の HAWK_DIST も使わず隔離した一時 dist に出す
HAWK_DIST="$(mktemp -d /tmp/hawk-emit.XXXXXX)"
export HAWK_DIST
trap 'rm -rf "$HAWK_DIST"' EXIT

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep emitted include dependencies available

When hawk emit is used on a multi-file app, desugar rewrites local includes to paths under this temporary HAWK_DIST, but the EXIT trap deletes that directory immediately after only the entry file is printed. For example, hawk emit main.awk > out.awk where main.awk includes x.awk produces an out.awk containing @include "/tmp/hawk-emit.../x.awk", and running it later fails because the helper was removed; emit should either output a self-contained closure or keep/rewrite dependencies to stable paths.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

対応しました。emit は隔離 dist 内のローカル @include を再帰的にインライン展開(重複 include は gawk の dedup と同じく1回だけ)し、外部 include はそのまま残す self-contained な出力にしています。一時 dist の削除後も出力単独で実行できます。テスト emit_multifile_self_contained(2ファイル構成の emit 出力に一時パスの @include が残らず、gawk で実行できること)を追加しています。


APP_AWK="$("$LIBS" desugar "$APP")"
trap "rm -f '$APP_AWK'" EXIT

if [[ "$STRICT" -eq 1 ]]; then
if ! gawk --sandbox -f "${HAWK_LIB}/dsl/adt.awk" -f "${HAWK_LIB}/dsl/type.awk" -f "${HAWK_LIB}/dsl/strict_stubs.awk" -f "$APP_AWK" < /dev/null >/dev/null 2>&1; then
Expand All @@ -37,4 +43,26 @@ if [[ "$STRICT" -eq 1 ]]; then
fi
fi

cat "$APP_AWK"
# desugar はローカル include を隔離 dist 内の絶対パスへ書き換えるが、
# emit の stdout は一時 dist を trap で削除した後も単独で実行できる必要がある。
# dist 内の include だけを再帰展開し、外部 include は gawk に任せてそのまま残す。
EMIT_SEEN=" "
EMIT_INCLUDE_RE='^[[:space:]]*@include[[:space:]]+"([^"]+)"'

emit_file() {
local file="$1" line inc
case "$EMIT_SEEN" in *" $file "*) return 0 ;; esac
EMIT_SEEN="$EMIT_SEEN$file "
while IFS= read -r line || [[ -n "$line" ]]; do
if [[ "$line" =~ $EMIT_INCLUDE_RE ]]; then
inc="${BASH_REMATCH[1]}"
if [[ "$inc" == "$HAWK_DIST"/* && -f "$inc" ]]; then
emit_file "$inc"
continue
fi
fi
printf '%s\n' "$line"
done < "$file"
}

emit_file "$APP_AWK"
Loading
Loading