Skip to content

Commit eb0db18

Browse files
committed
copilot feedback
1 parent 4587441 commit eb0db18

File tree

6 files changed

+33
-13
lines changed

6 files changed

+33
-13
lines changed

go/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Follow these steps to embed the CLI:
7979
1. Run `go get -tool github.com/github/copilot-sdk/go/cmd/bundler`. This is a one-time setup step per project.
8080
2. Run `go tool bundler` in your build environment just before building your application.
8181

82-
That's it! When your application calls `copilot.NewClient` without a `CLIPath` nor the `COPILOT_CLI_PATH` environment variable, the SDK will automatically install the embedded CLI to a temporary directory and use it for all operations. Subsequent calls to `copilot.NewClient`, even from different processes, will reuse the same installed CLI binary.
82+
That's it! When your application calls `copilot.NewClient` without a `CLIPath` nor the `COPILOT_CLI_PATH` environment variable, the SDK will automatically install the embedded CLI to a cache directory and use it for all operations.
8383

8484
## API Reference
8585

go/client.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ type Client struct {
103103
// })
104104
func NewClient(options *ClientOptions) *Client {
105105
opts := ClientOptions{
106-
CLIPath: "copilot",
106+
CLIPath: "",
107107
Cwd: "",
108108
Port: 0,
109109
LogLevel: "info",
@@ -183,9 +183,6 @@ func NewClient(options *ClientOptions) *Client {
183183
// Check environment variable for CLI path
184184
if cliPath := os.Getenv("COPILOT_CLI_PATH"); cliPath != "" {
185185
opts.CLIPath = cliPath
186-
} else if embeddedPath := embeddedcli.Path(); embeddedPath != "" && opts.CLIPath == "copilot" {
187-
// Use the unpacked embedded CLI if available and no custom path was set
188-
opts.CLIPath = embeddedPath
189186
}
190187

191188
client.options = opts
@@ -1317,6 +1314,15 @@ func (c *Client) verifyProtocolVersion(ctx context.Context) error {
13171314
// This spawns the CLI server as a subprocess using the configured transport
13181315
// mode (stdio or TCP).
13191316
func (c *Client) startCLIServer(ctx context.Context) error {
1317+
cliPath := c.options.CLIPath
1318+
if cliPath == "" {
1319+
// If no CLI path is provided, attempt to use the embedded CLI if available
1320+
cliPath = embeddedcli.Path()
1321+
}
1322+
if cliPath == "" {
1323+
// Default to "copilot" in PATH if no embedded CLI is available and no custom path is set
1324+
cliPath = "copilot"
1325+
}
13201326
args := []string{"--headless", "--no-auto-update", "--log-level", c.options.LogLevel}
13211327

13221328
// Choose transport mode
@@ -1343,10 +1349,10 @@ func (c *Client) startCLIServer(ctx context.Context) error {
13431349

13441350
// If CLIPath is a .js file, run it with node
13451351
// Note we can't rely on the shebang as Windows doesn't support it
1346-
command := c.options.CLIPath
1347-
if strings.HasSuffix(c.options.CLIPath, ".js") {
1352+
command := cliPath
1353+
if strings.HasSuffix(cliPath, ".js") {
13481354
command = "node"
1349-
args = append([]string{c.options.CLIPath}, args...)
1355+
args = append([]string{cliPath}, args...)
13501356
}
13511357

13521358
c.process = exec.CommandContext(ctx, command, args...)

go/cmd/bundler/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,10 @@ func downloadCLIBinary(npmPlatform, binaryName, cliVersion, destDir string) (str
406406
}
407407
}
408408

409-
stat, _ := os.Stat(binaryPath)
409+
stat, err := os.Stat(binaryPath)
410+
if err != nil {
411+
return "", fmt.Errorf("failed to stat binary: %w", err)
412+
}
410413
sizeMB := float64(stat.Size()) / 1024 / 1024
411414
fmt.Printf("Downloaded %s (%.1f MB)\n", binaryName, sizeMB)
412415

go/embeddedcli/installer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import "github.com/github/copilot-sdk/go/internal/embeddedcli"
55
// Config defines the inputs used to install and locate the embedded Copilot CLI.
66
//
77
// Cli and CliHash are required. If Dir is empty, the CLI is installed into the
8-
// system temp directory. Version is used to suffix the installed binary name to
8+
// system cache directory. Version is used to suffix the installed binary name to
99
// allow multiple versions to coexist. License, when provided, is written next
1010
// to the installed binary.
1111
type Config = embeddedcli.Config

go/internal/embeddedcli/embeddedcli.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
// Config defines the inputs used to install and locate the embedded Copilot CLI.
1919
//
2020
// Cli and CliHash are required. If Dir is empty, the CLI is installed into the
21-
// system temp directory. Version is used to suffix the installed binary name to
21+
// system cache directory. Version is used to suffix the installed binary name to
2222
// allow multiple versions to coexist. License, when provided, is written next
2323
// to the installed binary.
2424
type Config struct {
@@ -35,6 +35,9 @@ func Setup(cfg Config) {
3535
if cfg.Cli == nil {
3636
panic("Cli reader is required")
3737
}
38+
if len(cfg.CliHash) != sha256.Size {
39+
panic(fmt.Sprintf("CliHash must be a SHA-256 hash (%d bytes), got %d bytes", sha256.Size, len(cfg.CliHash)))
40+
}
3841
setupMu.Lock()
3942
defer setupMu.Unlock()
4043
if setupDone {
@@ -81,7 +84,12 @@ func install() (path string) {
8184
}
8285
installDir := config.Dir
8386
if installDir == "" {
84-
installDir = os.TempDir()
87+
var err error
88+
if installDir, err = os.UserCacheDir(); err != nil {
89+
// Fall back to temp dir if UserCacheDir is unavailable
90+
installDir = os.TempDir()
91+
}
92+
installDir = filepath.Join(installDir, "copilot-sdk")
8593
}
8694
path, err := installAt(installDir)
8795
if err != nil {
@@ -131,6 +139,9 @@ func installAt(installDir string) (string, error) {
131139
if err1 := f.Close(); err1 != nil && err == nil {
132140
err = err1
133141
}
142+
if closer, ok := config.Cli.(io.Closer); ok {
143+
closer.Close()
144+
}
134145
if err != nil {
135146
return "", fmt.Errorf("writing binary file: %w", err)
136147
}

go/internal/flock/flock.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import "os"
55
// Acquire opens (or creates) the lock file at path and blocks until the lock is acquired.
66
// It returns a release function to unlock and close the file.
77
func Acquire(path string) (func() error, error) {
8-
f, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC, 0644)
8+
f, err := os.OpenFile(path, os.O_CREATE, 0644)
99
if err != nil {
1010
return nil, err
1111
}

0 commit comments

Comments
 (0)