Skip to content

Commit 44dd468

Browse files
authored
fix project root discovery and build diagnostics (#752)
1 parent 7de8a39 commit 44dd468

20 files changed

Lines changed: 570 additions & 107 deletions

docs/compiler/pipeline.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ builds, and the flag may be repeated or comma-separated. Discovery uses
2424
`**/*.gwdk` defaults when no root/module source is configured in the loaded
2525
config.
2626

27-
`gowdk build [--config <file>] [--target <name>] [--module <name>] [--out <dir>] [--app <dir>] [--bin <file>] [--worker-app <dir>] [--worker-bin <file>] [--cron-app <dir>] [--cron-bin <file>] [files...]` currently
27+
`gowdk build [--config <file>] [--project-root <dir>] [--target <name>] [--module <name>] [--out <dir>] [--app <dir>] [--bin <file>] [--worker-app <dir>] [--worker-bin <file>] [--cron-app <dir>] [--cron-bin <file>] [files...]` currently
2828
emits app-shell HTML, `gowdk-routes.json`, `gowdk-assets.json`, generated
2929
embedded app source, optional web/backend binaries, and optional contract
3030
worker/cron binaries for the selected source set. The current rendered page

docs/compiler/project-structure.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
## Current Inputs
44

55
Project-level CLI commands require `gowdk.config.go` in the current directory,
6-
or an explicit config passed with `--config <file>`, before they compile,
7-
validate, or inspect `.gwdk` code. Explicit `.gwdk` file paths narrow the input
8-
set, but they do not bypass the config requirement:
6+
a parent directory, the directory passed with `--project-root <dir>`, or an
7+
explicit config passed with `--config <file>`, before they compile, validate,
8+
or inspect `.gwdk` code. Explicit `.gwdk` file paths narrow the input set, but
9+
they do not bypass the config requirement. Explicit paths outside the selected
10+
project root are rejected:
911

1012
```sh
1113
go run ./cmd/gowdk check examples/pages/*.gwdk examples/actions/*.gwdk examples/partials/*.gwdk examples/api/*.gwdk examples/ssr/*.gwdk

docs/product/requirements.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ language references, compiler docs, and examples.
4949
| PRD-021 | Provide a dependency-free fast local development loop. | High | Implemented | `gowdk dev` polls discovered inputs without production dependencies, compares content hashes, caches watched input snapshots between ticks, rebuilds only on real input changes, incrementally renders page/component/layout affected SPA output when possible, falls back to full builds for config/CSS/source-set/app/binary/WASM changes, serves the generated output, live reloads browsers after successful rebuilds, keeps the last successful output after failed rebuilds, and can build/restart generated app targets. SPA/app generation skips identical file writes. |
5050
| PRD-022 | Allow generated app output to compile to a WASM deploy artifact. | Medium | Partial | `gowdk build --wasm <file>` and `Build.Targets[].WASM` compile the generated app with `GOOS=js GOARCH=wasm`. CI verifies the emitted artifact is a real WASM module by checking the WebAssembly magic header. This remains separate from component-level browser island assets emitted for `wasm` components; host runtime/loader integration is deploy-platform owned. |
5151
| PRD-023 | Keep current documentation aligned with implemented CLI, config, compiler, language, routing, deployment, and examples. | High | Implemented | `README.md`, `docs/getting-started.md`, `docs/cookbook/README.md`, reference docs, language docs, compiler docs, and `examples/README.md` describe current support, link to the right source of truth, and call out planned behavior. |
52-
| PRD-024 | Require project config before compiling or validating `.gwdk` code. | High | Implemented | `check`, `audit`, `manifest`, `sitemap`, `routes`, `build`, and `dev` require `gowdk.config.go` in the current directory or an explicit `--config <file>`, even when explicit `.gwdk` file paths are provided. Project-aware `build`, `check`, and `dev` execute importable configs through a cached native helper instead of serializing `gowdk.Config`. |
52+
| PRD-024 | Require project config before compiling or validating `.gwdk` code. | High | Implemented | `check`, `audit`, `manifest`, `sitemap`, `routes`, `build`, and `dev` require `gowdk.config.go` discovered upward from the current directory or explicit source paths, `--project-root <dir>`, or an explicit `--config <file>`, even when explicit `.gwdk` file paths are provided. Project-aware `build`, `check`, and `dev` execute importable configs through a cached native helper instead of serializing `gowdk.Config`. |
5353
| PRD-025 | Keep framework integrations optional and outside compiler/runtime core. | Medium | Implemented | Generated apps expose standard `net/http` handlers and framework-neutral code by default. Optional `runtime/adapters/chi`, `runtime/adapters/echo`, `runtime/adapters/gin`, and `runtime/adapters/fiber` nested modules wrap the same generated `http.Handler`; route-aware Chi/Echo/Gin mounting can consume generated OpenAPI metadata, and docs cover middleware overlap and Fiber adaptor caveats. |
5454
| PRD-026 | Provide declarative security posture and baseline audit gating. | High | Partial | `internal/securitymanifest` projects validated IR into a route/endpoint/contract/frontend posture, `internal/auditspec` evaluates the built-in baseline plus declared `*.audit.gwdk` policies, `gowdk audit` reports human/JSON findings with registry-backed severities and exits non-zero on error findings, and `gowdk build` evaluates the same baseline before writing output plus scans final emitted artifact files after generation. Production builds fail on error-severity findings unless `--allow-insecure` is set; non-production builds print a warning summary. The baseline covers action/command/state-changing API CSRF, guardless action/fragment/command/query endpoints, public-by-omission APIs, roleless contracts, bundle secret leaks, client-visible guardless routes, and raw-HTML sinks, and auth-addon session mode posture; policy rules can require headers. `gowdk audit --emit-tests` writes readable standalone `_test.go` posture tests without overwriting user-owned files unless `--force` is passed, and `--run` builds a temporary generated app and executes its generated app audit test through `runtime/testkit` without auto-authorizing app-owned custom guards. Richer role fixture injection and deeper browser/data-flow analysis remain planned; authentication, sessions, RBAC storage, and backend resource authorization stay app-owned by design. |
5555
| PRD-027 | Provide opt-in browser presentation-event fanout without adding WebSocket dependencies to the root module. | Medium | Implemented | `FeatureRealtime` and `addons/realtime` provide config and `gowdk add realtime` wiring for presentation-event fanout. Dependency-free SSE fanout remains in the root module through `runtime/contracts/sse` and `realtime.NewSSE`; WebSocket fanout remains isolated in the nested `runtime/contracts/websocketfanout` module. Docs cover SSE versus WebSocket setup, deployment caveats, and the M14 boundary for live DOM reactivity. |

docs/reference/cli.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,31 @@ gowdk add <addon> [--config <file>] [--base-url <url>]
1313
gowdk add --list [--registry] [--json]
1414
gowdk tokens <file.gwdk>
1515
gowdk fmt [--write] <files>
16-
gowdk check [--config <file>] [--env-file <file>] [--module <name>] [--json] [--warnings-as-errors] [--ssr] [files...]
17-
gowdk fix [--dry-run] [--code <diagnostic-code>] [--config <file>] [--env-file <file>] [--module <name>] [--ssr] [files...]
18-
gowdk manifest [--config <file>] [--env-file <file>] [--module <name>] [--ssr] [files...]
19-
gowdk sitemap [--config <file>] [--env-file <file>] [--module <name>] [--ssr] [files...]
20-
gowdk routes [--config <file>] [--env-file <file>] [--module <name>] [--ssr] [files...]
21-
gowdk endpoints [--config <file>] [--env-file <file>] [--module <name>] [--ssr] [files...]
22-
gowdk inspect ir|tree|endpoint-graph|asset-graph|go-bindings [--config <file>] [--env-file <file>] [--module <name>] [--json] [--ssr] [files...]
23-
gowdk generate stubs [--config <file>] [--env-file <file>] [--module <name>] [--ssr] [files...]
16+
gowdk check [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--json] [--warnings-as-errors] [--ssr] [files...]
17+
gowdk fix [--dry-run] [--code <diagnostic-code>] [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--ssr] [files...]
18+
gowdk manifest [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--ssr] [files...]
19+
gowdk sitemap [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--ssr] [files...]
20+
gowdk routes [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--ssr] [files...]
21+
gowdk endpoints [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--ssr] [files...]
22+
gowdk inspect ir|tree|endpoint-graph|asset-graph|go-bindings [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--json] [--ssr] [files...]
23+
gowdk generate stubs [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--ssr] [files...]
2424
gowdk explain [--json] <diagnostic-code>
25-
gowdk doctor [--config <file>] [--env-file <file>] [--module <name>] [--ssr] [--json] [files...]
25+
gowdk doctor [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--ssr] [--json] [files...]
2626
gowdk test [--config <file>] [--env-file <file>] [--module <name>] [--target <name>] [--stage <unit|app|binary|browser>] [--run <pattern>] [--timeout <duration>] [--count <n>] [--cover] [--json] [--keep-workdir] [--browser-command <command>] [--ssr] [files...]
27-
gowdk audit [--config <file>] [--env-file <file>] [--module <name>] [--ssr] [--json] [--sarif[=<file>]] [--diff <previous-report>] [--schema[=report|security]] [--emit-tests[=<file>]] [--check-tests[=<file>]] [--force] [--run] [--run-timeout=<duration>] [files...]
27+
gowdk audit [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--ssr] [--json] [--sarif[=<file>]] [--diff <previous-report>] [--schema[=report|security]] [--emit-tests[=<file>]] [--check-tests[=<file>]] [--force] [--run] [--run-timeout=<duration>] [files...]
2828
gowdk contracts [--json] [dir]
2929
gowdk graph [--json] [dir]
3030
gowdk trace <contract> [--json] [dir]
3131
gowdk list commands|queries|events|jobs [--json] [dir]
32-
gowdk build [--config <file>] [--env-file <file>] [--debug] [--timings[=<file>]] [--ssr] [--allow-missing-backend] [--allow-insecure] [--obfuscate-assets] [--target <name>] [--module <name>] [--out <dir>] [--app <dir>] [--bin <file>] [--docker] [--docker-base <distroless|scratch>] [--deploy-recipe <caddy|nginx|split|static|systemd>] [--wasm <file>] [--backend-app <dir>] [--backend-bin <file>] [--worker-app <dir>] [--worker-bin <file>] [--cron-app <dir>] [--cron-bin <file>] [files...]
32+
gowdk build [--config <file>] [--project-root <dir>] [--env-file <file>] [--debug] [--timings[=<file>]] [--ssr] [--allow-missing-backend] [--allow-insecure] [--obfuscate-assets] [--target <name>] [--module <name>] [--out <dir>] [--app <dir>] [--bin <file>] [--docker] [--docker-base <distroless|scratch>] [--deploy-recipe <caddy|nginx|split|static|systemd>] [--wasm <file>] [--backend-app <dir>] [--backend-bin <file>] [--worker-app <dir>] [--worker-bin <file>] [--cron-app <dir>] [--cron-bin <file>] [files...]
3333
gowdk clean [--config <file>] [--target <name>] [--out <dir>] [--dry-run] [--json]
3434
gowdk dev [--addr <addr>] [--interval <duration>] [build flags...]
3535
gowdk preview [--addr <addr>] [--hot] [build flags...]
3636
gowdk serve --dir <dir> [--addr <addr>]
3737
gowdk playground policy [--json]
3838
gowdk playground export --dir <project> --out <project.zip> [--json]
3939
gowdk playground run --dir <project> --out <dir> --allow-hosted-execution (--module-cache <dir> | --allow-shared-module-cache)
40-
gowdk lsp [--ssr]
40+
gowdk lsp [--config <file>] [--project-root <dir>] [--ssr]
4141
```
4242
4343
## Flags
@@ -148,6 +148,11 @@ gowdk lsp [--ssr]
148148
config file. Project-aware `build`, `check`, and `dev` execute importable
149149
configs through the generated native helper instead of the required default
150150
`gowdk.config.go`.
151+
- `--project-root`: supported by project-aware commands and `lsp`; selects the
152+
directory that owns `gowdk.config.go`. Without it, project-aware commands
153+
discover the root by walking upward from the current directory or explicit
154+
source paths. Explicit input files outside the selected project root are
155+
rejected.
151156
- `--env-file`: supported by project-aware compile/report commands that load
152157
`gowdk.config.go`, including `check`, `doctor`, `test`, `audit`, `manifest`,
153158
`sitemap`, `routes`, `endpoints`, `inspect`, `generate stubs`, and `build`;
@@ -316,9 +321,10 @@ generated outputs. The target's intermediate build output is inferred as
316321
writes only the config, `.gitignore`, one page, and one CSS file.
317322
318323
`check`, `audit`, `manifest`, `sitemap`, `routes`, `build`, and `dev` require a config
319-
file before they compile or validate `.gwdk` code. By default they load
320-
`gowdk.config.go` from the current directory; `--config <file>` can point at a
321-
different config for project examples or one-off checks.
324+
file before they compile or validate `.gwdk` code. By default they discover
325+
`gowdk.config.go` by walking upward from the current directory or explicit
326+
source paths; `--project-root <dir>` selects a root directory, and `--config
327+
<file>` can point at a different config for project examples or one-off checks.
322328
323329
These commands accept explicit file paths, but explicit paths do not remove the
324330
config requirement. If no files are passed, commands discover configured root

docs/reference/config.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,16 @@ type Config struct {
2121

2222
`gowdk.config.go` is required for CLI commands that compile, validate, inspect,
2323
or serve a development loop for `.gwdk` code: `check`, `manifest`, `sitemap`,
24-
`routes`, `inspect ir`, `build`, and `dev`. Those commands load
25-
`gowdk.config.go` from the current directory by default, or the file passed
26-
with `--config <file>`.
24+
`routes`, `inspect ir`, `build`, and `dev`. Those commands discover
25+
`gowdk.config.go` by walking upward from the current directory, use the
26+
directory passed with `--project-root <dir>`, or load the exact file passed with
27+
`--config <file>`.
2728

2829
`SourceConfig` has include and exclude patterns. Discovery support exists in
2930
`internal/discover`, and `gowdk build` reads `Source.Include` and
3031
`Source.Exclude` fields from the loaded config when no explicit files are
31-
supplied. Explicit file paths still require a loaded config.
32+
supplied. Explicit file paths still require a loaded config and must stay under
33+
the selected project root.
3234

3335
`Modules` declares named source groups. Build discovery treats modules as
3436
source selectors. Generated app and binary composition is controlled by the

docs/reference/validation.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ Use standalone mode for a `.gwdk` file that is not inside a configured project:
88
gowdk check --standalone path/to/page.gwdk
99
```
1010

11-
When explicit files are passed and the current directory has no
12-
`gowdk.config.go`, `gowdk check` selects standalone mode automatically. Text
13-
output reports `ok (standalone)` and JSON output includes
11+
When explicit files are passed and neither the current directory nor any parent
12+
directory contains `gowdk.config.go`, `gowdk check` selects standalone mode
13+
automatically. Text output reports `ok (standalone)` and JSON output includes
1414
`"mode": "standalone"`.
1515

1616
Standalone mode does not load or execute project config, addons, environment
1717
files, build functions, lifecycle hooks, or sibling Go packages. It checks
1818
syntax and source-local semantics independently for each file. A warning says
1919
`project context required` when a file uses bindings that need a configured
20-
project. Run the same check from the project root, or pass `--config`, for the
21-
authoritative project result.
20+
project. Run the same check from inside the project, pass `--project-root`, or
21+
pass `--config`, for the authoritative project result.
2222

2323
`--standalone` cannot be combined with `--config`, `--env-file`, `--module`, or
24-
`--ssr`.
24+
`--project-root`, or `--ssr`.
2525

2626
## Project check and build
2727

internal/gowdkcmd/audit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
"github.com/cssbruno/gowdk/internal/securitymanifest"
2727
)
2828

29-
const auditUsage = "usage: gowdk audit [--config <file>] [--env-file <file>] [--module <name>] [--ssr] [--json] [--sarif[=<file>]] [--diff <previous-report>] [--schema[=report|security]] [--emit-tests[=<file>]] [--check-tests[=<file>]] [--force] [--run] [--run-timeout=<duration>] [files...]"
29+
const auditUsage = "usage: gowdk audit [--config <file>] [--project-root <dir>] [--env-file <file>] [--module <name>] [--ssr] [--json] [--sarif[=<file>]] [--diff <previous-report>] [--schema[=report|security]] [--emit-tests[=<file>]] [--check-tests[=<file>]] [--force] [--run] [--run-timeout=<duration>] [files...]"
3030

3131
const (
3232
auditGeneratedMarker = "// Code generated by gowdk audit --emit-tests; DO NOT EDIT.\n"

0 commit comments

Comments
 (0)