Skip to content

Commit 0549631

Browse files
committed
feat: add versioning information to build process, update heartbeat mode to polling, and enhance library management commands
1 parent 20f8b9f commit 0549631

12 files changed

Lines changed: 425 additions & 220 deletions

File tree

.vscode/launch.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"mode": "auto",
1313
"console": "integratedTerminal",
1414
"env": {
15-
"GPU_GO_HEARTBEAT_MODE": "long-polling",
15+
"GPU_GO_HEARTBEAT_MODE": "polling",
1616
"GPU_GO_ENDPOINT": "http://127.0.0.1:8787"
1717
},
1818
"args": [
@@ -28,11 +28,11 @@
2828
"mode": "auto",
2929
"console": "integratedTerminal",
3030
"env": {
31-
"GPU_GO_HEARTBEAT_MODE": "long-polling",
31+
"GPU_GO_HEARTBEAT_MODE": "polling",
3232
"GPU_GO_ENDPOINT": "http://127.0.0.1:8787"
3333
},
3434
"args": [
35-
"agent", "start"
35+
"deps", "sync"
3636
],
3737
"program": "${workspaceFolder}/cmd/ggo/main.go",
3838
}

Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,16 @@ BUILD_DIR=./bin
77
COVERAGE_DIR=./coverage
88
GO_VERSION=1.25.0
99

10+
# Version info (can be overridden via environment variables)
11+
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
12+
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
13+
BUILD_DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
14+
1015
# Build flags
11-
LDFLAGS=-s -w
16+
LDFLAGS=-s -w \
17+
-X 'github.com/NexusGPU/gpu-go/cmd/ggo/version.Version=$(VERSION)' \
18+
-X 'github.com/NexusGPU/gpu-go/cmd/ggo/version.Commit=$(COMMIT)' \
19+
-X 'github.com/NexusGPU/gpu-go/cmd/ggo/version.BuildDate=$(BUILD_DATE)'
1220
BUILD_FLAGS=-trimpath
1321

1422
# Default target

bin/ggo

-32 Bytes
Binary file not shown.

cmd/ggo/deps/deps.go

Lines changed: 149 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"os"
7+
"slices"
78

89
"github.com/NexusGPU/gpu-go/internal/api"
910
"github.com/NexusGPU/gpu-go/internal/deps"
@@ -12,9 +13,18 @@ import (
1213
)
1314

1415
var (
15-
cdnURL string
16-
apiURL string
17-
force bool
16+
cdnURL string
17+
apiURL string
18+
force bool
19+
verbose bool
20+
syncOS string
21+
syncArch string
22+
listOS string
23+
listArch string
24+
downloadName string
25+
downloadVersion string
26+
downloadOS string
27+
downloadArch string
1828
)
1929

2030
// NewDepsCmd creates the deps command
@@ -54,25 +64,46 @@ func newSyncCmd() *cobra.Command {
5464
mgr := getManager()
5565
ctx := context.Background()
5666

57-
fmt.Println("Syncing releases from API...")
58-
if err := mgr.SyncReleases(ctx); err != nil {
67+
targetOS := syncOS
68+
targetArch := syncArch
69+
if targetOS != "" || targetArch != "" {
70+
fmt.Printf("Syncing releases from API for platform %s/%s...\n", targetOS, targetArch)
71+
} else {
72+
fmt.Println("Syncing releases from API...")
73+
}
74+
75+
manifest, err := mgr.SyncReleases(ctx, targetOS, targetArch)
76+
if err != nil {
5977
cmd.SilenceUsage = true
6078
log.Error().Err(err).Msg("Failed to sync releases")
6179
return err
6280
}
6381

64-
// Load and display synced manifest
65-
manifest, err := mgr.LoadCachedManifest()
66-
if err != nil {
67-
log.Warn().Err(err).Msg("Failed to load cached manifest")
68-
} else if manifest != nil {
82+
if manifest != nil {
6983
fmt.Printf("Synced %d libraries (manifest version: %s)\n", len(manifest.Libraries), manifest.Version)
84+
85+
if verbose {
86+
fmt.Println("\nSynced libraries:")
87+
for _, lib := range manifest.Libraries {
88+
fmt.Printf(" Name: %s\n", lib.Name)
89+
fmt.Printf(" Version: %s\n", lib.Version)
90+
fmt.Printf(" Platform: %s/%s\n", lib.Platform, lib.Arch)
91+
fmt.Printf(" Size: %d bytes\n", lib.Size)
92+
fmt.Printf(" SHA256: %s\n", lib.SHA256)
93+
fmt.Printf(" URL: %s\n", lib.URL)
94+
fmt.Println()
95+
}
96+
}
7097
}
7198

7299
fmt.Println("Sync complete!")
73100
return nil
74101
},
75102
}
103+
104+
cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Print verbose synced data")
105+
cmd.Flags().StringVar(&syncOS, "os", "", "Target OS (linux, darwin, windows). Defaults to current OS")
106+
cmd.Flags().StringVar(&syncArch, "arch", "", "Target architecture (amd64, arm64). Defaults to current architecture")
76107
return cmd
77108
}
78109

@@ -93,7 +124,7 @@ func newListCmd() *cobra.Command {
93124
if len(installed.Libraries) > 0 {
94125
fmt.Println("Installed libraries:")
95126
for name, lib := range installed.Libraries {
96-
fmt.Printf(" %s (version: %s)\n", name, lib.Version)
127+
fmt.Printf(" %s (version: %s, platform: %s/%s)\n", name, lib.Version, lib.Platform, lib.Arch)
97128
}
98129
fmt.Println()
99130
}
@@ -108,28 +139,80 @@ func newListCmd() *cobra.Command {
108139
return err
109140
}
110141

111-
libs := mgr.GetLibrariesForPlatform(manifest)
142+
// Determine if we should list all architectures or filter
143+
var libs []deps.Library
144+
var filterDesc string
145+
if listOS == "" && listArch == "" {
146+
// List all architectures
147+
libs = mgr.GetAllLibraries(manifest)
148+
filterDesc = "all platforms"
149+
} else {
150+
// Filter by specified OS/Arch (empty string means current platform)
151+
libs = mgr.GetLibrariesForPlatform(manifest, listOS, listArch)
152+
if listOS != "" && listArch != "" {
153+
filterDesc = fmt.Sprintf("%s/%s", listOS, listArch)
154+
} else if listOS != "" {
155+
filterDesc = fmt.Sprintf("%s/*", listOS)
156+
} else {
157+
filterDesc = fmt.Sprintf("*/%s", listArch)
158+
}
159+
}
160+
112161
if len(libs) == 0 {
113-
fmt.Println("No libraries available for this platform")
162+
if filterDesc != "all platforms" {
163+
fmt.Printf("No libraries available for platform %s\n", filterDesc)
164+
} else {
165+
fmt.Println("No libraries available")
166+
}
114167
return nil
115168
}
116169

117-
fmt.Printf("\nAvailable libraries (manifest version: %s):\n", manifest.Version)
118-
for _, lib := range libs {
119-
status := ""
120-
if installedLib, exists := installed.Libraries[lib.Name]; exists {
121-
if installedLib.Version == lib.Version {
122-
status = " [installed]"
123-
} else {
124-
status = fmt.Sprintf(" [update available: %s -> %s]", installedLib.Version, lib.Version)
170+
// Group by platform/arch if listing all or filtering by OS only
171+
shouldGroup := (listOS == "" && listArch == "") || (listOS != "" && listArch == "")
172+
if shouldGroup {
173+
// Group libraries by platform/arch
174+
grouped := make(map[string][]deps.Library)
175+
for _, lib := range libs {
176+
key := fmt.Sprintf("%s/%s", lib.Platform, lib.Arch)
177+
grouped[key] = append(grouped[key], lib)
178+
}
179+
180+
fmt.Printf("\nAvailable libraries for %s (manifest version: %s):\n", filterDesc, manifest.Version)
181+
for platformArch, platformLibs := range grouped {
182+
fmt.Printf("\n Platform: %s\n", platformArch)
183+
for _, lib := range platformLibs {
184+
status := ""
185+
if installedLib, exists := installed.Libraries[lib.Name]; exists {
186+
if installedLib.Version == lib.Version && installedLib.Platform == lib.Platform && installedLib.Arch == lib.Arch {
187+
status = " [installed]"
188+
} else if installedLib.Version != lib.Version {
189+
status = fmt.Sprintf(" [update available: %s -> %s]", installedLib.Version, lib.Version)
190+
}
191+
}
192+
fmt.Printf(" %s (version: %s, size: %d bytes)%s\n", lib.Name, lib.Version, lib.Size, status)
125193
}
126194
}
127-
fmt.Printf(" %s (version: %s, size: %d bytes)%s\n", lib.Name, lib.Version, lib.Size, status)
195+
} else {
196+
fmt.Printf("\nAvailable libraries for %s (manifest version: %s):\n", filterDesc, manifest.Version)
197+
for _, lib := range libs {
198+
status := ""
199+
if installedLib, exists := installed.Libraries[lib.Name]; exists {
200+
if installedLib.Version == lib.Version && installedLib.Platform == lib.Platform && installedLib.Arch == lib.Arch {
201+
status = " [installed]"
202+
} else if installedLib.Version != lib.Version {
203+
status = fmt.Sprintf(" [update available: %s -> %s]", installedLib.Version, lib.Version)
204+
}
205+
}
206+
fmt.Printf(" %s (version: %s, size: %d bytes)%s\n", lib.Name, lib.Version, lib.Size, status)
207+
}
128208
}
129209

130210
return nil
131211
},
132212
}
213+
214+
cmd.Flags().StringVar(&listOS, "os", "", "Filter by OS (linux, darwin, windows). Omit to list all architectures")
215+
cmd.Flags().StringVar(&listArch, "arch", "", "Filter by architecture (amd64, arm64). Omit to list all architectures")
133216
return cmd
134217
}
135218

@@ -150,28 +233,54 @@ func newDownloadCmd() *cobra.Command {
150233
return err
151234
}
152235

153-
libs := mgr.GetLibrariesForPlatform(manifest)
236+
// Determine target platform from flags or use current platform
237+
targetOS := downloadOS
238+
targetArch := downloadArch
239+
240+
// Get libraries for the target platform
241+
libs := mgr.GetLibrariesForPlatform(manifest, targetOS, targetArch)
154242
if len(libs) == 0 {
155-
fmt.Println("No libraries available for this platform")
243+
platformDesc := "this platform"
244+
if targetOS != "" || targetArch != "" {
245+
platformDesc = fmt.Sprintf("%s/%s", targetOS, targetArch)
246+
}
247+
fmt.Printf("No libraries available for %s\n", platformDesc)
156248
return nil
157249
}
158250

159-
// Filter by args if provided
160-
if len(args) > 0 {
161-
filtered := []deps.Library{}
162-
for _, lib := range libs {
163-
for _, name := range args {
164-
if lib.Name == name {
165-
filtered = append(filtered, lib)
166-
break
167-
}
251+
// Apply filters
252+
filtered := []deps.Library{}
253+
for _, lib := range libs {
254+
// Filter by name: --name flag takes precedence, otherwise use args
255+
if downloadName != "" {
256+
if lib.Name != downloadName {
257+
continue
258+
}
259+
} else if len(args) > 0 {
260+
// Match any of the provided names in args
261+
matched := slices.Contains(args, lib.Name)
262+
if !matched {
263+
continue
168264
}
169265
}
170-
libs = filtered
266+
267+
// Filter by version
268+
if downloadVersion != "" && lib.Version != downloadVersion {
269+
continue
270+
}
271+
272+
filtered = append(filtered, lib)
171273
}
172274

275+
if len(filtered) == 0 {
276+
fmt.Println("No libraries match the specified criteria")
277+
return nil
278+
}
279+
280+
libs = filtered
281+
173282
for _, lib := range libs {
174-
fmt.Printf("Downloading %s (version: %s)...\n", lib.Name, lib.Version)
283+
fmt.Printf("Downloading %s (version: %s, platform: %s/%s)...\n", lib.Name, lib.Version, lib.Platform, lib.Arch)
175284

176285
progressFn := func(downloaded, total int64) {
177286
if total > 0 {
@@ -195,6 +304,10 @@ func newDownloadCmd() *cobra.Command {
195304
}
196305

197306
cmd.Flags().BoolVarP(&force, "force", "f", false, "Force re-download even if cached")
307+
cmd.Flags().StringVar(&downloadName, "name", "", "Library name to download (e.g., libcuda.so.1)")
308+
cmd.Flags().StringVar(&downloadVersion, "version", "", "Library version to download")
309+
cmd.Flags().StringVar(&downloadOS, "os", "", "Target OS (linux, darwin, windows). Defaults to current OS")
310+
cmd.Flags().StringVar(&downloadArch, "cpuArch", "", "Target CPU architecture (amd64, arm64). Defaults to current architecture")
198311
return cmd
199312
}
200313

@@ -215,7 +328,7 @@ func newInstallCmd() *cobra.Command {
215328
return err
216329
}
217330

218-
libs := mgr.GetLibrariesForPlatform(manifest)
331+
libs := mgr.GetLibrariesForPlatform(manifest, "", "")
219332
if len(libs) == 0 {
220333
fmt.Println("No libraries available for this platform")
221334
return nil

cmd/ggo/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/NexusGPU/gpu-go/cmd/ggo/share"
1111
"github.com/NexusGPU/gpu-go/cmd/ggo/studio"
1212
"github.com/NexusGPU/gpu-go/cmd/ggo/use"
13+
"github.com/NexusGPU/gpu-go/cmd/ggo/version"
1314
"github.com/NexusGPU/gpu-go/cmd/ggo/worker"
1415
"github.com/NexusGPU/gpu-go/internal/log"
1516
"github.com/spf13/cobra"
@@ -52,6 +53,9 @@ func init() {
5253
rootCmd.AddCommand(auth.NewLoginCmd())
5354
rootCmd.AddCommand(auth.NewLogoutCmd())
5455
rootCmd.AddCommand(auth.NewAuthCmd())
56+
57+
// Version command
58+
rootCmd.AddCommand(version.NewVersionCmd())
5559
}
5660

5761
func main() {

cmd/ggo/version/version.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package version
2+
3+
import (
4+
"fmt"
5+
"runtime"
6+
7+
"github.com/spf13/cobra"
8+
)
9+
10+
var (
11+
// These variables are set via build flags (ldflags)
12+
Version = "dev"
13+
Commit = "unknown"
14+
BuildDate = "unknown"
15+
GoVersion = runtime.Version()
16+
)
17+
18+
// NewVersionCmd creates the version command
19+
func NewVersionCmd() *cobra.Command {
20+
cmd := &cobra.Command{
21+
Use: "version",
22+
Short: "Display version information",
23+
Long: `Display version and build metadata for ggo CLI.`,
24+
Run: func(cmd *cobra.Command, args []string) {
25+
fmt.Printf("ggo version %s\n", Version)
26+
fmt.Printf("Commit: %s\n", Commit)
27+
fmt.Printf("Build Date: %s\n", BuildDate)
28+
fmt.Printf("Go Version: %s\n", GoVersion)
29+
fmt.Printf("Platform: %s/%s\n", runtime.GOOS, runtime.GOARCH)
30+
},
31+
}
32+
return cmd
33+
}

internal/agent/device.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func DownloadOrFindAccelerator() (string, error) {
5959
// Step 1: Detect vendor (config has highest priority)
6060
vendor, version := detectVendor()
6161
if vendor == "" {
62-
vendor = "stub" // Fallback to stub if detection fails
62+
vendor = "example" // Fallback to stub if detection fails
6363
}
6464

6565
// Step 2: Try to find library locally
@@ -92,7 +92,7 @@ func DownloadOrFindAccelerator() (string, error) {
9292
// Find library in manifest matching platform and vendor
9393
var targetLib *deps.Library
9494
var candidateLibs []deps.Library
95-
platformLibs := depsMgr.GetLibrariesForPlatform(manifest)
95+
platformLibs := depsMgr.GetLibrariesForPlatform(manifest, "", "")
9696

9797
// Match library name pattern: contains "accelerator_{vendor}"
9898
vendorPattern := "accelerator_" + vendor
@@ -293,7 +293,8 @@ func CreateMockGPUs(count int) []api.GPUInfo {
293293
func getLibSuffix() string {
294294
switch runtime.GOOS {
295295
case "darwin":
296-
return ".dylib"
296+
// In provider build, we only build .so libraries, even for MacOS
297+
return ".so"
297298
case "windows":
298299
return ".dll"
299300
default:

0 commit comments

Comments
 (0)