diff --git a/.gitignore b/.gitignore index 321d933..9d0d353 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,5 @@ dist gih_dev .worktrees/ -tasks/ \ No newline at end of file +tasks/ +.claude/improve-memory-md/ diff --git a/AGENTS.md b/AGENTS.md index 9e3e12b..2272ce1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,28 +1,17 @@ # Repository Guidelines -## Project Structure & Module Organization -`gih/main.go` is the CLI entry point. Core behavior lives in `syncer/`: `dir.go` discovers direct child repositories, `git.go` runs git commands, and `syncer.go` coordinates parallel execution. Output formatting lives in `printer/`. Tests sit next to the code as `*_test.go`. CI and templates are under `.github/`. - ## Build, Test, and Development Commands -Use Go 1.26. - -- `make build`: builds a development binary as `./gih_dev`. -- `make install`: installs `gih` from `./gih`. -- `make test`: runs `go test -v -race ./...`. -- `make lint`: runs `golangci-lint` as used in CI. -- `make tidy`: normalizes `go.mod` and `go.sum`. -- `DEBUG=* go run ./gih status`: handy for manual CLI checks. - -Before opening a PR, run `make build && make test && make lint`. +Before opening a PR, run `make build && make test && make lint` (`make lint` matches CI). ## Coding Style & Naming Conventions -Follow standard Go formatting with `gofmt`; keep packages small and focused. Prefer the standard library over new dependencies when possible. Use clear package scopes such as `feat(syncer)` or `fix(printer)` when naming changes. Keep filenames lowercase, and keep tests in the same package unless black-box coverage is required. +Prefer the standard library over new dependencies when possible. Keep tests in the same package unless black-box coverage is required. +Repositories are processed in parallel, so every public `printer.Printer` method must hold `p.mu` while writing; cover new ones with a `*_ConcurrentSafe` test. ## Testing Guidelines -This repository uses Go’s `testing` package plus `github.com/matryer/is`. Write focused tests with `t.Run(...)`; avoid table-driven tests here. Use `t.Parallel()` whenever the case is safe to parallelize. Name receiver-related tests as `Test{Struct}_Xxx`, for example `TestSync_Execute`. Run targeted checks with `go test -v ./syncer/` and use `go test -cover ./...` when touching behavior broadly. +This repository uses Go’s `testing` package plus `github.com/matryer/is`. Write focused tests with `t.Run(...)`; avoid table-driven tests here. Use `t.Parallel()` whenever the case is safe to parallelize. Name receiver-related tests as `Test{Struct}_Xxx`, for example `TestSync_Execute`. ## Commit & Pull Request Guidelines -Recent history follows Conventional Commits, for example `feat(gih): ...`, `refactor(syncer): ...`, and `fix(printer): ...`. Keep commit titles in English and scoped when helpful. PRs should follow `.github/PULL_REQUEST_TEMPLATE.md` with `## Issue` and `## Overview`, link the related issue, and describe behavioral changes briefly in Japanese. Include tests for functional changes and update `README.md` when CLI behavior changes. +Follow Conventional Commits with English titles, scoped by package when helpful, for example `feat(gih): ...`, `refactor(syncer): ...`, and `fix(printer): ...`. PRs should follow `.github/PULL_REQUEST_TEMPLATE.md` with `## Issue` and `## Overview`, link the related issue, and describe behavioral changes briefly in Japanese. Include tests for functional changes and update `README.md` when CLI behavior changes. ## Worktree Workflow Do not work directly on the default branch (currently `master`). Start each non-trivial change from a dedicated branch and worktree under `.worktrees/`, for example `git worktree add .worktrees/feat-x -b feat/x`. diff --git a/README.md b/README.md index 866cc83..3deded5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![unittest](https://github.com/takecy/git-here/workflows/unittest/badge.svg) [![Go Report Card](https://goreportcard.com/badge/github.com/takecy/git-here)](https://goreportcard.com/report/github.com/takecy/git-here) -![Go Version](https://img.shields.io/badge/golang-1.26+-blue.svg?style=flat-square) +![Go Version](https://img.shields.io/badge/golang-1.27+-blue.svg?style=flat-square) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/takecy/git-here) **Efficiently run git commands across multiple repositories in parallel** @@ -29,19 +29,20 @@ I created it because I was tired of managing dozens of microservice repositories prints a bordered summary table with totals at the end: ``` -==> Running pull origin master on 3 repositories -✓ takecy/git-here Already up to date. 0.4s -✗ takecy/adk-test fatal: couldn't find remote ref master 1.2s -✓ takecy/another-repo Already up to date. 0.5s +$ gih pull +==> Running pull on 3 repositories +✓ workspace/api-server Already up to date. 0.4s +✓ workspace/docs Updating a17b0e2..c52d9f4 0.7s +✓ workspace/web-frontend Updating 3f9c2a1..8d4e7b6 1.1s ==> Summary -+-------------------------+--------+----------+----------------------------------------+ -| Repository | Status | Duration | Message | -+-------------------------+--------+----------+----------------------------------------+ -| takecy/git-here | ✓ | 0.4s | Already up to date. | -| takecy/adk-test | ✗ | 1.2s | fatal: couldn't find remote ref master | -| takecy/another-repo | ✓ | 0.5s | Already up to date. | -+-------------------------+--------+----------+----------------------------------------+ -Total: 3 Success: 2 Failed: 1 Timeout: 0 Elapsed: 1.2s ++------------------------+--------+----------+---------------------------+ +| Repository | Status | Duration | Message | ++------------------------+--------+----------+---------------------------+ +| workspace/api-server | ✓ | 0.4s | Already up to date. | +| workspace/docs | ✓ | 0.7s | Updating a17b0e2..c52d9f4 | +| workspace/web-frontend | ✓ | 1.1s | Updating 3f9c2a1..8d4e7b6 | ++------------------------+--------+----------+---------------------------+ +Total: 3 Success: 3 Failed: 0 Timeout: 0 Elapsed: 1.1s ``` Failed rows are colored red and timed-out rows yellow when the output diff --git a/go.mod b/go.mod index 1badbcc..4a78235 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,16 @@ module github.com/takecy/git-here -go 1.26 +go 1.27 require ( github.com/fatih/color v1.19.0 github.com/matryer/is v1.4.0 github.com/pkg/errors v0.9.1 - golang.org/x/sync v0.20.0 + golang.org/x/sync v0.23.0 ) require ( - github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-isatty v0.0.21 // indirect - golang.org/x/sys v0.43.0 // indirect + github.com/mattn/go-colorable v0.1.15 // indirect + github.com/mattn/go-isatty v0.0.24 // indirect + golang.org/x/sys v0.48.0 // indirect ) diff --git a/go.sum b/go.sum index cacd604..7fac81a 100644 --- a/go.sum +++ b/go.sum @@ -2,13 +2,13 @@ github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs= -github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= +github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY= +github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= +github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=