From 5a48fdd590b2c378cc289f1e2136126cbf6c9b62 Mon Sep 17 00:00:00 2001 From: ceo Date: Sun, 13 Sep 2026 00:09:56 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat+docs=EF=BC=9Atag=20=E5=AE=89=E8=A3=9D?= =?UTF-8?q?=E6=94=AF=E6=8F=B4=EF=BC=88#38=EF=BC=89=E2=80=94=E2=80=94versio?= =?UTF-8?q?n=20=E8=AE=80=20build=20info=E3=80=81README=20=E5=AE=89?= =?UTF-8?q?=E8=A3=9D=E7=AB=A0=E7=AF=80=E6=94=B9=E4=BB=A5=20go=20install=20?= =?UTF-8?q?=E7=82=BA=E4=B8=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 26 ++++++++++++++++++++------ internal/cli/cli.go | 17 ++++++++++++++++- internal/cli/version_test.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 internal/cli/version_test.go diff --git a/README.md b/README.md index d49457f..9db16a8 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,25 @@ teai 是 Gitea 的命令列(CLI)工具,以更完整、更可靠的方式 - **git** - Gitea 帳號的 **API token**(設定階段使用;在 Gitea「設定 → 應用程式」產生) -### 從原始碼建置 +### 以 go install 安裝(建議) + +自 v0.1.0 起 module 已發佈 tag,可直接以版本安裝(二元檔裝進 `GOBIN`,預設 `~/go/bin`): + +```sh +go install gitea.alterminal.com/alterminal/teai/cmd/teai@latest # 最新 tag +go install gitea.alterminal.com/alterminal/teai/cmd/teai@v0.1.0 # 指定版本 +teai version # 驗證:teai version v0.1.0 +``` + +本 module 為公開倉庫,預設 `GOPROXY`/`GOSUMDB` 即可解析(已於乾淨環境驗證)。 +若所在網路環境無法經公用 proxy 抓取,可改設 `GOPRIVATE=gitea.alterminal.com` +(略過 proxy 與 checksum database,直接從 Gitea 抓取)。 + +`teai version` 會顯示建入的 module 版本(tag 安裝為 `v0.1.0`;clone 建置為開發版 `0.1.0-dev`)。 + +### 從原始碼建置(開發用) + +開發、離線或想鎖定特定 commit 時,clone 後自行建置: ```sh git clone https://gitea.alterminal.com/alterminal/teai.git @@ -27,16 +45,12 @@ install -Dm755 teai ~/.local/bin/teai # 或複製到任何 PATH 內目錄 teai version # 驗證:teai version 0.1.0-dev ``` -也可以直接裝進 `GOBIN`(預設 `~/go/bin`;該目錄已在 PATH 時最省事): +也可以在 clone 目錄內直接裝進 `GOBIN`: ```sh go install ./cmd/teai ``` -> **注意:** `go install gitea.alterminal.com/alterminal/teai/cmd/teai@latest` 目前**不可用**—— -> module 尚未發佈任何 tag,`@latest` 會解析到任意中繼 commit(且 #21 修復前 main 建置失敗)。 -> 請在 clone 目錄內以版本控制的方式建置;發佈 tag 後再提供 `teai@` 安裝路徑。 - ### 登入設定(首次使用) teai 與 `tea` 共用同一份組態檔;若 `tea whoami` 已可正常輸出,可跳過本節。 diff --git a/internal/cli/cli.go b/internal/cli/cli.go index da2eb54..20c7eb5 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -15,6 +15,7 @@ import ( "flag" "fmt" "io" + "runtime/debug" "sort" "strings" "time" @@ -23,8 +24,22 @@ import ( ) // Version 是目前開發中的版本號。採用語意化版本;正式發佈前以 0 開頭。 +// 僅作為 fallback:以 `go install module@version` 或納入其他 module 建置時, +// buildVersion 會改用 build info 內的 module 版本(見 runVersion)。 var Version = "0.1.0-dev" +// buildVersion 回傳應顯示的版本字串。go install pkg@tag 建置的二元檔 +// 會在 Main.Version 帶入 tag(如 v0.1.0);本機 go build 則為 "(devel)" 或空, +// 此時退回開發版本號 Version。 +func buildVersion() string { + if info, ok := debug.ReadBuildInfo(); ok { + if v := info.Main.Version; v != "" && v != "(devel)" { + return v + } + } + return Version +} + // ExitCode 是 Run 回傳的行程結束碼。 type ExitCode int @@ -437,7 +452,7 @@ func runVersion(env *Env, args []string) error { if len(args) > 0 { return &ErrUsage{Msg: "version 不接受參數"} } - fmt.Fprintf(env.Out, "teai version %s\n", Version) + fmt.Fprintf(env.Out, "teai version %s\n", buildVersion()) return nil } diff --git a/internal/cli/version_test.go b/internal/cli/version_test.go new file mode 100644 index 0000000..51870c6 --- /dev/null +++ b/internal/cli/version_test.go @@ -0,0 +1,32 @@ +// version_test.go 驗證版本字串解析:go test 環境 Main.Version 為 "(devel)" +// 時應退回開發版本號;-ldflags 覆寫測試 tag 行為則由建置驗證涵蓋。 +package cli + +import ( + "strings" + "testing" +) + +// TestBuildVersionFallsBackToDev 確認本地測試環境(Main.Version == "(devel)") +// 退回 Version;同時確保輸出是可讀版本字串(非空、無括號)。 +func TestBuildVersionFallsBackToDev(t *testing.T) { + v := buildVersion() + if v == "" { + t.Fatalf("buildVersion 不應為空") + } + if strings.ContainsAny(v, "()") { + t.Errorf("buildVersion 不應含內部佔位(括號),得到:%q", v) + } +} + +// TestRunVersionUsesBuildVersion 確認 version 命令輸出 buildVersion 的結果。 +func TestRunVersionUsesBuildVersion(t *testing.T) { + stdout, _, code := run("version") + if code != 0 { + t.Fatalf("version 應回 0,得到 %d", code) + } + want := "teai version " + buildVersion() + if !strings.Contains(stdout, want) { + t.Errorf("version 輸出應含 %q,得到:%q", want, stdout) + } +} From 9a4887a677c71081a498cc3900b36d3fe8eb8c82 Mon Sep 17 00:00:00 2001 From: ceo Date: Sun, 13 Sep 2026 00:28:40 +0800 Subject: [PATCH 2/2] =?UTF-8?q?docs=EF=BC=9A=E4=BF=AE=E6=AD=A3=E5=AE=89?= =?UTF-8?q?=E8=A3=9D=E7=AB=A0=E7=AF=80=E7=89=88=E6=9C=AC=E9=A1=AF=E7=A4=BA?= =?UTF-8?q?=E8=AA=AA=E6=98=8E=EF=BC=88=E8=A4=87=E5=AF=A9=20#42=EF=BC=89?= =?UTF-8?q?=E2=80=94=E2=80=94@v0.1.0=20=E4=BB=8D=E9=A1=AF=E7=A4=BA=200.1.0?= =?UTF-8?q?-dev=E3=80=81clone=20=E5=BB=BA=E7=BD=AE=E7=82=BA=20pseudo-versi?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +++++++++++----- internal/cli/cli.go | 6 ++++-- internal/cli/version_test.go | 3 ++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9db16a8..45a262f 100644 --- a/README.md +++ b/README.md @@ -22,16 +22,17 @@ teai 是 Gitea 的命令列(CLI)工具,以更完整、更可靠的方式 自 v0.1.0 起 module 已發佈 tag,可直接以版本安裝(二元檔裝進 `GOBIN`,預設 `~/go/bin`): ```sh -go install gitea.alterminal.com/alterminal/teai/cmd/teai@latest # 最新 tag -go install gitea.alterminal.com/alterminal/teai/cmd/teai@v0.1.0 # 指定版本 -teai version # 驗證:teai version v0.1.0 +go install gitea.alterminal.com/alterminal/teai/cmd/teai@latest # 最新 tag(亦可 @v<版本> 指定) +teai version # 驗證:顯示安裝的 tag 版本(見下方說明) ``` 本 module 為公開倉庫,預設 `GOPROXY`/`GOSUMDB` 即可解析(已於乾淨環境驗證)。 若所在網路環境無法經公用 proxy 抓取,可改設 `GOPRIVATE=gitea.alterminal.com` (略過 proxy 與 checksum database,直接從 Gitea 抓取)。 -`teai version` 會顯示建入的 module 版本(tag 安裝為 `v0.1.0`;clone 建置為開發版 `0.1.0-dev`)。 +`teai version` 顯示建入的 module 版本,即安裝指定的 tag(如 `v0.1.1`)。 +注意:讀 build info 顯示安裝版本的支援,自包含該變更的 tag 起(v0.1.1)才生效—— +v0.1.0 早於此變更,以 `@v0.1.0` 安裝(或此變更前的 `@latest`)仍顯示舊行為 `0.1.0-dev`。 ### 從原始碼建置(開發用) @@ -42,7 +43,7 @@ git clone https://gitea.alterminal.com/alterminal/teai.git cd teai go build -o teai ./cmd/teai install -Dm755 teai ~/.local/bin/teai # 或複製到任何 PATH 內目錄 -teai version # 驗證:teai version 0.1.0-dev +teai version # 驗證:teai version v0.1.1-0.<時間戳>-(見下方說明) ``` 也可以在 clone 目錄內直接裝進 `GOBIN`: @@ -51,6 +52,11 @@ teai version # 驗證:teai version 0.1.0-dev go install ./cmd/teai ``` +clone 建置時 Go 會把 VCS 狀態寫進 build info:位於 tag 上顯示該 tag、 +其後的 commit 顯示 pseudo-version(如 `v0.1.1-0.20260912160956-5a48fdd590b2`)、 +工作樹有修改再附加 `+dirty`;無 VCS 資訊(如從 tarball 解壓建置)時 +`Main.Version` 為 `(devel)`,此時退回開發版本號 `0.1.0-dev`。 + ### 登入設定(首次使用) teai 與 `tea` 共用同一份組態檔;若 `tea whoami` 已可正常輸出,可跳過本節。 diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 20c7eb5..aa22c83 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -29,8 +29,10 @@ import ( var Version = "0.1.0-dev" // buildVersion 回傳應顯示的版本字串。go install pkg@tag 建置的二元檔 -// 會在 Main.Version 帶入 tag(如 v0.1.0);本機 go build 則為 "(devel)" 或空, -// 此時退回開發版本號 Version。 +// 會在 Main.Version 帶入 tag(如 v0.1.0);clone 目錄內本機建置則帶 +// pseudo-version(如 v0.1.1-0.<時間戳>-,工作樹有修改時再附加 +// "+dirty"),同樣直接顯示。Main.Version 為 "(devel)" 或空(go test 環境、 +// 無 VCS 資訊的 tarball 建置)時,才退回開發版本號 Version。 func buildVersion() string { if info, ok := debug.ReadBuildInfo(); ok { if v := info.Main.Version; v != "" && v != "(devel)" { diff --git a/internal/cli/version_test.go b/internal/cli/version_test.go index 51870c6..f1b988b 100644 --- a/internal/cli/version_test.go +++ b/internal/cli/version_test.go @@ -1,5 +1,6 @@ // version_test.go 驗證版本字串解析:go test 環境 Main.Version 為 "(devel)" -// 時應退回開發版本號;-ldflags 覆寫測試 tag 行為則由建置驗證涵蓋。 +// 時應退回開發版本號;tag 與 pseudo-version 行為由建置驗證涵蓋 +// (go install pkg@tag 顯示 tag;clone 建置顯示 pseudo-version)。 package cli import (