/* The MIT License (MIT) Copyright © 2025 xce Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package main import ( "fmt" "os" "strings" "xcecli/config" logger "xcecli/config" cmd "xcecli/router" "go.uber.org/zap" ) // GitCommit and BuildTime are injected at link time via // `-ldflags "-X main.GitCommit=... -X main.BuildTime=..."` (see // src/tools/go_build and src/frontend/Makefile's build-cli target). The // "unknown" defaults matter: a bare `go build`/`go run` that bypasses that // ldflags injection must still report "unknown" rather than an empty // string, matching this feature's unknown-fallback requirement (see // xce_version_field() in src/lib/utils.c for the equivalent C-side // convention). // // DirtyFingerprint is injected the same way (`-X main.DirtyFingerprint=...`, // see src/tools/go_build task 4.1) but its default is a deliberately EMPTY // string, not "unknown" -- matching dirty_fingerprint's convention // everywhere else in the dirty-content-fingerprint feature (empty means // "no fingerprint available", distinct from GitCommit/BuildTime's // "unknown" sentinel for "not injected at all"). var ( GitCommit = "unknown" BuildTime = "unknown" DirtyFingerprint = "" ) // composeVersionDisplay applies the dirty-content-fingerprint feature's // strip-and-append rule to gitCommit: if dirtyFingerprint is non-empty, a // trailing "-dirty" suffix on gitCommit is stripped (an anchored suffix // check via strings.TrimSuffix, not a blind substring replace) and // "-" is appended in its place; otherwise gitCommit is // returned exactly as-is (already correctly showing "-dirty" or not, per // the original build-time-versioning feature). Mirrors // xce_compose_version_ex() in src/lib/utils.c (task 3.1) and apiserver's // own composeVersionDisplay (task 4.4), the equivalent implementations // already approved for the other version-displaying components. // // xcecli has no startup log to protect (already established as out of // scope by the original build-time-versioning feature, see that feature's // own task 4.5 commit fb09afe), so this result feeds the ONLY consumption // point below: the version string passed into router.Execute(cm, version), // which sets rootCmd.Version for Cobra's native --version/-v handling. func composeVersionDisplay(gitCommit, dirtyFingerprint string) string { if dirtyFingerprint == "" { return gitCommit } return strings.TrimSuffix(gitCommit, "-dirty") + "-" + dirtyFingerprint } func main() { // init logger if err := logger.InitLogger(); err != nil { fmt.Println(strings.ToLower(err.Error())) os.Exit(1) } logger.Info("********** Initialize Logger on client side done!") // initialize the config manager configManager, err := config.NewConfigManager() if err != nil { fmt.Println("failed to initialize the config manager", zap.Error(err)) os.Exit(1) } // ensure the config manager is initialized correctly if configManager == nil { fmt.Println("failed to initialize the config manager") os.Exit(1) } // execute the command version := fmt.Sprintf("%s built %s", composeVersionDisplay(GitCommit, DirtyFingerprint), BuildTime) if err := cmd.Execute(configManager, version); err != nil { fmt.Println(strings.ToLower(err.Error())) os.Exit(1) } }