Skip to content
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
24 changes: 14 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ jobs:
- run: go test ./...
- run: go vet ./...
- run: go build -trimpath ./cmd/foundry
- name: Embedded generation smoke check
if: runner.os == 'Linux'
run: make smoke

formatting:
name: Formatting
Expand All @@ -34,7 +37,7 @@ jobs:
with:
go-version: '1.23.x'
cache: true
- run: test -z "$(gofmt -l .)"
- run: make format-check

cross-compile:
name: Cross-compile release targets
Expand All @@ -45,7 +48,7 @@ jobs:
with:
go-version: '1.23.x'
cache: true
- run: ./scripts/build-release.sh ci
- run: make release VERSION=ci

web-templates:
name: Web template (${{ matrix.template }}, Node ${{ matrix.node }})
Expand Down Expand Up @@ -86,6 +89,8 @@ jobs:
toolchain: '1.85.0'
env:
RUSTDOCFLAGS: -D warnings
RUSTUP_TOOLCHAIN: ${{ matrix.toolchain }}
CARGO_NET_OFFLINE: 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
Expand All @@ -96,13 +101,12 @@ jobs:
run: rustup toolchain install ${{ matrix.toolchain }} --profile minimal --component rustfmt --component clippy
- name: Generate the bundled template
run: go run ./cmd/foundry new rust-check --template rust --destination "${{ runner.temp }}/foundry-rust" --no-hooks
- run: cargo +${{ matrix.toolchain }} fmt --all -- --check
- name: Rust quality gate (POSIX)
if: runner.os != 'Windows'
run: bash scripts/check.sh
working-directory: ${{ runner.temp }}/foundry-rust
- run: cargo +${{ matrix.toolchain }} test --locked --offline
working-directory: ${{ runner.temp }}/foundry-rust
- run: cargo +${{ matrix.toolchain }} clippy --locked --offline --all-targets -- -D warnings
working-directory: ${{ runner.temp }}/foundry-rust
- run: cargo +${{ matrix.toolchain }} doc --locked --offline --no-deps
working-directory: ${{ runner.temp }}/foundry-rust
- run: cargo +${{ matrix.toolchain }} build --release --locked --offline
- name: Rust quality gate (PowerShell)
if: runner.os == 'Windows'
shell: pwsh
run: ./scripts/check.ps1
working-directory: ${{ runner.temp }}/foundry-rust
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ jobs:
else
echo "value=$INPUT_VERSION" >> "$GITHUB_OUTPUT"
fi
- name: Test
run: go test ./...
- name: Check Foundry
run: make check
- name: Build archives and checksums
env:
RELEASE_VERSION: ${{ steps.version.outputs.value }}
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Unreleased

- Align quality command meanings across the CLI repository and all five foundations; retain existing Make/Melos aliases.
- Add comprehensive command/workflow documentation, script help, CWD-independent helpers, and native PowerShell Rust checks.
- Make Go contract generation explicit, isolate smoke tests, and checksum only the current release's six executable archives.
- Correct use-case argument parsing so a trailing --project flag is honored; return success for command help.

- Add embedded Rust 2024 foundations with a thin CLI, reusable library, feature modules, typed errors, unit/integration/doc tests, rustfmt, and Clippy.
- Validate generated Rust projects across Linux, macOS, Windows, and the minimum Rust version.

Expand Down
56 changes: 29 additions & 27 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
BINARY := bin/foundry
VERSION ?= dev
LDFLAGS := -s -w -X github.com/jabahum/foundry/internal/cli.Version=$(VERSION)
.DEFAULT_GOAL := help

.PHONY: build test fmt fmt-check vet check smoke install release-snapshot clean
.PHONY: help build test format format-check lint check ci smoke install release clean fmt fmt-check vet release-snapshot

build:
help: ## Show commands; see docs/commands.md for prerequisites and side effects.
@awk 'BEGIN {FS = ":.*## "; print "Foundry commands:"} /^[a-zA-Z_-]+:.*## / {printf " make %-18s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

build: ## Build bin/foundry for this machine (VERSION defaults to dev).
mkdir -p bin
CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o $(BINARY) ./cmd/foundry

test:
test: ## Run Foundry tests, including embedded generation for all five templates.
go test ./...

fmt:
gofmt -w cmd internal
format: ## Format Foundry's Go source; does not format generated template projects.
gofmt -w assets.go cmd internal

fmt-check:
test -z "$$(gofmt -l .)"
format-check: ## Check Foundry formatting without rewriting source.
test -z "$$(gofmt -l assets.go cmd internal)"

vet:
lint: ## Run go vet on Foundry packages.
go vet ./...

check: fmt-check test vet

smoke: build
./$(BINARY) version
./$(BINARY) list
rm -rf .tmp-smoke
./$(BINARY) new .tmp-smoke --template go --module example.com/smoke --no-hooks
test -f .tmp-smoke/go.mod
grep -q 'module example.com/smoke' .tmp-smoke/go.mod
./$(BINARY) add migration create_smoke --project .tmp-smoke
test -f .tmp-smoke/migrations/000007_create_smoke.up.sql
./$(BINARY) add service smoke --project .tmp-smoke
test -f .tmp-smoke/api/proto/smoke/v1/smoke.proto
rm -rf .tmp-smoke

install:
check: format-check lint test build ## Check formatting, lint, tests, and the native build.

ci: check smoke ## Run Foundry checks and the isolated generation/add smoke test.

smoke: build ## Generate all five templates and exercise Go add commands in a temporary folder.
./scripts/smoke.sh

install: ## Install Foundry into GOBIN or GOPATH/bin.
go install -trimpath -ldflags "$(LDFLAGS)" ./cmd/foundry

release-snapshot:
release: ## Build six executable archives and checksums; does not publish (VERSION=dev).
./scripts/build-release.sh "$(VERSION)"

clean:
rm -rf bin dist .tmp-smoke
clean: ## Remove local bin/ and dist/ artifacts.
rm -rf bin dist

# Compatibility aliases. Prefer the canonical names above in new automation.
fmt: format
fmt-check: format-check
vet: lint
release-snapshot: release
76 changes: 38 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Install directly from source with Go 1.23 or newer:
go install github.com/jabahum/foundry/cmd/foundry@latest
```

For the complete CLI, script, template, and release reference, see [Commands and workflows](docs/commands.md). Each generated template also documents its own commands in its README.

For local development:

```bash
Expand Down Expand Up @@ -68,14 +70,20 @@ foundry new users-service \
--module github.com/your-org/users-service
```

Flutter app:
Flutter workspace and app:

```bash
foundry new mediguide \
--template flutter \
--org ug.go.health
foundry new mediguide --template flutter --no-hooks
cd mediguide
bash scripts/setup.sh
fvm dart pub global run mason_cli:mason make flutter_app \
--name mediguide --organization ug.go.health
# Add apps/mediguide to workspace: in pubspec.yaml.
fvm dart pub get
```

Configure native platform folders, permissions, and signing in the app before a platform build. The template README explains the remaining app setup.

Vanilla JavaScript:

```bash
Expand Down Expand Up @@ -108,7 +116,7 @@ cargo lint

The Rust starter has no third-party dependencies. Its toolchain file selects stable Rust with rustfmt and Clippy, and its minimum supported version is Rust 1.85. Domain rules live in feature modules, with CLI input/output at the boundary. Foundry does not run Cargo automatically.

All templates are available offline. Optional generation hooks may invoke installed SDKs and their package managers; use `--no-hooks` to skip them.
All templates are available offline. For the FVM/Mason workflow, generate Flutter with `--no-hooks` and run `bash scripts/setup.sh` explicitly. Optional generation hooks may invoke installed SDKs and their package managers; use `--no-hooks` to skip them.

## Extend an existing project

Expand Down Expand Up @@ -150,33 +158,27 @@ Template changes ship with a new Foundry build/release. There is no external tem

To update a template, edit its source files and rebuild Foundry with `make build`.

## Commands
## Commands and workflows

```text
foundry
foundry new <name> --template <go|flutter|vanilla-js|react|rust>
foundry add service <name>
foundry add migration <name>
foundry add feature <name>
foundry add package <name>
[The command reference](docs/commands.md) documents every CLI command and flag, each template's native commands, setup requirements, generated outputs, side effects, Windows alternatives, and CI/release behavior.

```sh
foundry help
foundry new --help
foundry template list
foundry list
foundry info <template>
foundry doctor
foundry version
make help
```

## Project-generation flags
The shared quality workflow is format → lint/analyze → test → build where a generic build exists:

```text
--module Go module path
--org Flutter organization identifier
--package Flutter package token
--version require this bundled template version
--destination output path
--force generate into a non-empty directory
--no-hooks skip post-generation hooks
```
| Project | Full quality gate |
| --- | --- |
| Foundry / generated Go | `make check` |
| Flutter workspace | `fvm dart run melos run check` (build the chosen app/platform separately) |
| Vanilla JS / React | `npm run check` |
| Rust | `bash scripts/check.sh` or `./scripts/check.ps1` |

Formatting checks do not fix source; regeneration is explicit. Use `make format`, `npm run format`, `fvm dart run melos run format`, or `cargo fmt --all` to fix formatting. Existing `fmt`, `fmt-check`, `vet`, `proto`, `run`, `quality`, and `release-snapshot` aliases remain available in their relevant projects.

## Architecture

Expand All @@ -200,29 +202,27 @@ Foundry CLI
`-- doctor
```

Authentication/RBAC choices belong to the generated Go foundation, not to Foundry itself. Flutter's platform folders are generated using the installed Flutter SDK before the foundation overlay is applied when Flutter is available.
Authentication/RBAC choices belong to the generated Go foundation, not to Foundry itself. Legacy Flutter hooks use the installed Flutter executable before the foundation overlay, only when hooks are enabled. The recommended FVM-first setup is explicit after `--no-hooks`.

## Development

```bash
make fmt
make check
make build
make smoke
make format
make ci
```

`go test ./...` checks generation of all five bundled templates, project setting substitution, CLI behavior, and the Go/Flutter add generators. Web-template CI generates fresh projects and runs `npm ci` and `npm run check` on Node 22 and 24. Rust-template CI runs formatting, tests, Clippy, documentation, and release builds on stable Rust across Linux/macOS/Windows and on Rust 1.85 for minimum-version compatibility.
`go test ./...` checks generation of all five bundled templates, project setting substitution, CLI behavior, and the Go/Flutter add generators. Web-template CI generates fresh projects and runs `npm ci` and `npm run check` on Node 22 and 24. Rust-template CI invokes the same POSIX/PowerShell check scripts for formatting, tests, Clippy, documentation, and release builds on stable Rust across Linux/macOS/Windows and on Rust 1.85 for minimum-version compatibility.

### Releases

Create all supported archives and checksums locally:

```bash
make clean
make release-snapshot VERSION=1.2.0
make ci
make release VERSION=1.2.0
```

Pushing a tag such as `v1.2.0` runs tests, produces static Linux, macOS, and
Pushing a tag such as `v1.2.0` runs Foundry checks, produces static Linux, macOS, and
Windows archives, injects the tag into `foundry version`, generates SHA-256
checksums, and publishes a GitHub Release. The release workflow can also be run
manually to validate packaging without publishing a release.
Expand All @@ -245,8 +245,8 @@ foundry add usecase orders create
foundry add proto billing
```

Flutter Mason bricks can be invoked consistently through Foundry:
With a Mason executable configured on PATH, Foundry forwards brick arguments to `mason make`:

```bash
foundry mason feature --name profile
foundry mason feature --app mediguide --name profile
```
6 changes: 3 additions & 3 deletions assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ import "embed"
//go:embed all:templates/flutter_foundations/pubspec.lock
//go:embed all:templates/flutter_foundations/pubspec.yaml
//go:embed all:templates/flutter_foundations/scripts
//go:embed templates/vanilla-js-foundations/src templates/vanilla-js-foundations/index.html templates/vanilla-js-foundations/package*.json
//go:embed templates/vanilla-js-foundations/src templates/vanilla-js-foundations/scripts templates/vanilla-js-foundations/index.html templates/vanilla-js-foundations/package*.json
//go:embed templates/vanilla-js-foundations/*.config.js templates/vanilla-js-foundations/README.md all:templates/vanilla-js-foundations/public
//go:embed templates/vanilla-js-foundations/.editorconfig templates/vanilla-js-foundations/.env.example templates/vanilla-js-foundations/.gitignore
//go:embed templates/vanilla-js-foundations/.nvmrc templates/vanilla-js-foundations/.prettierignore templates/vanilla-js-foundations/.prettierrc.json
//go:embed templates/react-foundations/src templates/react-foundations/index.html templates/react-foundations/package*.json
//go:embed templates/react-foundations/src templates/react-foundations/scripts templates/react-foundations/index.html templates/react-foundations/package*.json
//go:embed templates/react-foundations/*.config.js templates/react-foundations/README.md all:templates/react-foundations/public
//go:embed templates/react-foundations/.editorconfig templates/react-foundations/.env.example templates/react-foundations/.gitignore
//go:embed templates/react-foundations/.nvmrc templates/react-foundations/.prettierignore templates/react-foundations/.prettierrc.json
//go:embed templates/rust-foundations/src templates/rust-foundations/tests templates/rust-foundations/Cargo.*
//go:embed templates/rust-foundations/src templates/rust-foundations/tests templates/rust-foundations/scripts templates/rust-foundations/Cargo.*
//go:embed templates/rust-foundations/rust-toolchain.toml templates/rust-foundations/README.md
//go:embed templates/rust-foundations/.gitignore templates/rust-foundations/.editorconfig templates/rust-foundations/.cargo
var Templates embed.FS
Loading
Loading