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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
*.exe
monolize
go.sum
spark
spark_*
__pycache__/
**/__pycache__/
.task/
reports/
node_modules/
site/
package-lock.json
Expand Down
27 changes: 27 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ spark-cli/
│ ├── registry/ # repo 命令的扫描/读写/merge 逻辑
│ ├── script/ # 脚本发现(配置 + scripts/ 目录)与执行
│ ├── templates/ # 嵌入的 dotfiles(nvim + ghostty)
│ ├── testreport/ # Ginkgo JSON 报告 → 自包含 HTML 渲染器(含 BDD 测试)
│ └── witr/ # Why-Is-This-Running 进程诊断引擎
├── tools/
│ └── testreport/ # test-report CLI:读取 ginkgo --json-report 输出,生成 HTML
├── pkg/
│ └── witr/model/ # witr 的共享数据模型
├── docs/ # docmd 文档站点(中英双语)
Expand Down Expand Up @@ -207,6 +210,20 @@ spark
- `spark docs`(`cmd/docs/`)提供 `init` / `site`,用于 docmd 站点脚手架。
- `spark version`(`cmd/version.go`)打印 version / commit / build date。

### 7. Windows 测试与构建根治 (2026-10-20)
- **构建稳定**:`go.sum` 从 `.gitignore` 移除并提交(此前 fresh clone 必然构建失败);
`task build` 移除 sources/generates 指纹(此前二次运行会跳过安装)。
- **测试根治**(均为 Windows 平台假设错误,非删除用例):
- `TestAddNestedRepos`:`git update-index --cacheinfo` 拒绝反斜杠路径——
`AddExistingRepoAsSubmodule` 与 `isSubmoduleGitlink` 现统一 `filepath.ToSlash`,
`.gitmodules` 始终写正斜杠路径。
- `TestIntegration_ReadProcessNonexistent`:PID 0 在 Windows 是可读的 System Idle
Process——改用 `math.MaxInt32`(任何平台都不存在)。
- `TestGetCmdlineSelf`:ginkgo CLI 编译的测试二进制无 `.exe` 后缀——同时接受 `.test`。
- **HTML 测试报告**:`make test-report` / `task test-report` 全量跑 Ginkgo 并生成
`reports/test-report.html`(套件/用例状态、时长、失败详情、状态过滤 + 搜索)。
Ginkgo 在 Windows 上必须配 `--output-dir`(其内部 `path.Dir` bug),由 target 预建目录。

## CLI 命令完整参考

### 全局选项
Expand Down Expand Up @@ -697,6 +714,9 @@ spark witr nginx --json

### 构建命令

> 注意:`go.sum` 必须提交到仓库(不得加入 `.gitignore`),否则全新 clone 后 `go build` 会因
> "missing go.sum entry" 失败,导致 Windows/macOS/Linux 构建都不稳定。

```bash
make build # 编译 + 打 version/commit/date ldflags + 安装到 ~/.local/bin/spark
make build-linux # 交叉编译 Linux amd64 (spark_linux)
Expand Down Expand Up @@ -730,9 +750,16 @@ spark --version # -> spark version v0.3.2
```bash
make test # go test ./... -v
make test-bdd # ginkgo -v ./internal/...
make test-report # ginkgo 全量 + 生成 HTML 报告 reports/test-report.html
make lint # go vet ./...
```

`test-report` 原理:Ginkgo CLI 以 `--output-dir=reports --json-report=ginkgo-report.json`
跑 `./...`(注意必须先用 `--output-dir` 预建目录——Ginkgo 内部用 `path.Dir` 而非
`filepath.Dir` 创建目录,在 Windows 上直接写 `reports/xxx.json` 会因目录不存在而失败),
再由 `tools/testreport` 把 JSON 渲染为自包含 HTML(汇总卡片、套件/用例表格、
失败详情、按状态过滤 + 文本搜索)。渲染器在 `internal/testreport`(含 BDD 测试)。

运行单个测试:

```bash
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- Stable cross-platform build — `go.sum` removed from `.gitignore` and committed so `go build` no longer fails with "missing go.sum entry" on fresh clones (fixes #21)
- `Taskfile.yml` — `build` task no longer skips rebuild/reinstall via sources/generates fingerprinting; `task build` always rebuilds and reinstalls, matching Makefile behavior
- `spark git submodule add` (folder mode) — nested repos on Windows no longer fail with "Invalid path": all git-facing submodule paths are normalized to forward slashes (`update-index --cacheinfo` rejects backslashes; `rm`/`ls-files` pathspecs silently fail to match them)
- Windows test stability — `TestIntegration_ReadProcessNonexistent` now uses `math.MaxInt32` instead of PID 0 (PID 0 is the readable System Idle Process on Windows); `TestGetCmdlineSelf` also accepts the `.test` binary suffix used by the ginkgo CLI

### Added

- HTML test report — `make test-report` / `task test-report` run all suites via Ginkgo and write a self-contained interactive HTML report (suite/spec states, durations, failure details, filtering) to `reports/test-report.html`; backed by `internal/testreport` (renderer + BDD tests) and `tools/testreport` (JSON→HTML converter)

## [0.3.2] - 2026-09-17

### Added
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ test:
test-bdd:
$(GINKGO) -v ./internal/...

test-report:
@mkdir -p reports
-$(GINKGO) -v --keep-going --output-dir=reports --json-report=ginkgo-report.json ./...
$(GO) run ./tools/testreport -in reports/ginkgo-report.json -out reports/test-report.html

lint:
$(GO) vet ./...

Expand Down Expand Up @@ -106,5 +111,6 @@ help:
@echo " build-darwin - Cross-compile for macOS (amd64)"
@echo " test - Run all tests"
@echo " test-bdd - Run tests with BDD output"
@echo " test-report - Run BDD tests and generate HTML report at reports/test-report.html"
@echo " lint - Run go vet"
@echo " clean - Remove binary and build artifacts"
16 changes: 11 additions & 5 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ tasks:
- cmd: 'bash scripts/verify-install.sh {{.BINARY_NAME}}{{exeExt}} $HOME/.local/bin'
platforms: [linux, darwin]
- echo 'Installed {{.BINARY_NAME}} to ~/.local/bin'
sources:
- '**/*.go'
- go.mod
generates:
- '{{.BINARY_NAME}}{{exeExt}}'

build:linux:
desc: Cross-compile for Linux (amd64)
Expand Down Expand Up @@ -112,6 +107,17 @@ tasks:
cmds:
- '{{.GO}} run github.com/onsi/ginkgo/v2/ginkgo -v ./internal/...'

test-report:
desc: Run BDD tests and generate an HTML report at reports/test-report.html
cmds:
- cmd: powershell -NoProfile -Command "New-Item -ItemType Directory -Force reports | Out-Null"
platforms: [windows]
- cmd: 'mkdir -p reports'
platforms: [linux, darwin]
- cmd: '{{.GO}} run github.com/onsi/ginkgo/v2/ginkgo -v --keep-going --output-dir=reports --json-report=ginkgo-report.json ./...'
ignore_error: true
- '{{.GO}} run ./tools/testreport -in reports/ginkgo-report.json -out reports/test-report.html'

lint:
desc: Run go vet
cmds:
Expand Down
5 changes: 3 additions & 2 deletions cmd/git/submodule.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ func addNestedRepos(repoPath, absFolder string) error {
continue
}

relPath := filepath.Join(relFolder, name)
// git submodule paths must use forward slashes on every platform.
relPath := filepath.ToSlash(filepath.Join(relFolder, name))

if isSubmoduleGitlink(repoPath, relPath) {
fmt.Printf("Skipping %s: already as submodule\n", relPath)
Expand All @@ -218,7 +219,7 @@ func addNestedRepos(repoPath, absFolder string) error {
// isSubmoduleGitlink reports whether path is already staged in the index of
// repoPath as a submodule gitlink (mode 160000).
func isSubmoduleGitlink(repoPath, path string) bool {
cmd := exec.Command("git", "ls-files", "--stage", "--", path)
cmd := exec.Command("git", "ls-files", "--stage", "--", filepath.ToSlash(path))
cmd.Dir = repoPath
out, err := cmd.Output()
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions cmd/git/submodule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ func TestAddNestedRepos(t *testing.T) {
t.Fatalf("read .gitmodules: %v", err)
}
for _, name := range repos {
path := filepath.Join("research", name)
// git submodule paths are always forward-slash (see .gitmodules spec).
path := filepath.ToSlash(filepath.Join("research", name))
if !strings.Contains(string(gm), fmt.Sprintf("path = %s", path)) {
t.Errorf(".gitmodules missing entry for %s:\n%s", path, gm)
}
Expand All @@ -59,7 +60,7 @@ func TestAddNestedRepos(t *testing.T) {
t.Fatalf("ls-files --stage: %v", err)
}
for _, name := range repos {
path := filepath.Join("research", name)
path := filepath.ToSlash(filepath.Join("research", name))
if !strings.Contains(string(out), "160000") || !strings.Contains(string(out), "\t"+path) {
t.Errorf("expected gitlink for %s, got:\n%s", path, out)
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/pterm/pterm v0.12.83
github.com/spf13/cobra v1.10.2
github.com/spf13/viper v1.21.0
go.yaml.in/yaml/v3 v3.0.4
modernc.org/sqlite v1.53.0
)

Expand Down Expand Up @@ -63,7 +64,6 @@ require (
github.com/spf13/pflag v1.0.10 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/mod v0.36.0 // indirect
golang.org/x/net v0.54.0 // indirect
golang.org/x/sync v0.20.0 // indirect
Expand Down
Loading
Loading