diff --git a/pkg/cli/credential.go b/pkg/cli/credential.go index eaf7665b..866ed4e5 100644 --- a/pkg/cli/credential.go +++ b/pkg/cli/credential.go @@ -9,6 +9,7 @@ import ( "time" cmd2 "github.com/gptscript-ai/cmd" + "github.com/gptscript-ai/gptscript/pkg/credentials" "github.com/gptscript-ai/gptscript/pkg/gptscript" "github.com/spf13/cobra" ) @@ -44,7 +45,12 @@ func (c *Credential) Run(cmd *cobra.Command, _ []string) error { } defer gptScript.Close(true) - store, err := gptScript.CredentialStoreFactory.NewStore(gptScript.DefaultCredentialContexts) + credCtxs := gptScript.DefaultCredentialContexts + if c.AllContexts { + credCtxs = []string{credentials.AllCredentialContexts} + } + + store, err := gptScript.CredentialStoreFactory.NewStore(credCtxs) if err != nil { return err } diff --git a/pkg/config/cliconfig.go b/pkg/config/cliconfig.go index 73741ab3..d7944d8e 100644 --- a/pkg/config/cliconfig.go +++ b/pkg/config/cliconfig.go @@ -11,6 +11,7 @@ import ( "github.com/adrg/xdg" "github.com/docker/cli/cli/config/types" + "github.com/gptscript-ai/gptscript/pkg/mvl" ) const ( @@ -24,6 +25,7 @@ const ( var ( // Helpers is a list of all supported credential helpers from github.com/gptscript-ai/gptscript-credential-helpers Helpers = []string{WincredCredHelper, OsxkeychainCredHelper, SecretserviceCredHelper, PassCredHelper} + log = mvl.Package() ) type AuthConfig types.AuthConfig @@ -85,9 +87,9 @@ func (c *CLIConfig) Save() error { } if c.auths != nil { - c.Auths = map[string]AuthConfig{} + c.Auths = make(map[string]AuthConfig, len(c.auths)) for k, v := range c.auths { - c.Auths[k] = (AuthConfig)(v) + c.Auths[k] = AuthConfig(v) } c.auths = nil } @@ -116,13 +118,21 @@ func (c *CLIConfig) GetAuthConfigs() map[string]types.AuthConfig { defer c.authsLock.Unlock() } + if err := c.readFileIntoConfig(c.location); err != nil { + // This is implementing an interface, so we can't return this error. + log.Warnf("Failed to read config file: %v", err) + } + if c.auths == nil { - c.auths = map[string]types.AuthConfig{} - for k, v := range c.Auths { - authConfig := (types.AuthConfig)(v) - c.auths[k] = authConfig - } + c.auths = make(map[string]types.AuthConfig, len(c.Auths)) + } + + // Assume that whatever was pulled from the file is more recent. + // The docker creds framework will save the file after creating or updating a credential. + for k, v := range c.Auths { + c.auths[k] = types.AuthConfig(v) } + return c.auths } @@ -142,17 +152,13 @@ func ReadCLIConfig(gptscriptConfigFile string) (*CLIConfig, error) { } } - data, err := readFile(gptscriptConfigFile) - if err != nil { - return nil, err - } result := &CLIConfig{ authsLock: &sync.Mutex{}, location: gptscriptConfigFile, - raw: data, } - if err := json.Unmarshal(data, result); err != nil { - return nil, fmt.Errorf("failed to unmarshal %s: %v", gptscriptConfigFile, err) + + if err := result.readFileIntoConfig(gptscriptConfigFile); err != nil { + return nil, err } if store := os.Getenv("GPTSCRIPT_CREDENTIAL_STORE"); store != "" { @@ -180,13 +186,18 @@ func (c *CLIConfig) setDefaultCredentialsStore() error { return c.Save() } -func readFile(path string) ([]byte, error) { +func (c *CLIConfig) readFileIntoConfig(path string) error { data, err := os.ReadFile(path) if os.IsNotExist(err) { - return []byte("{}"), nil + return nil } else if err != nil { - return nil, fmt.Errorf("failed to read user config %s: %w", path, err) + return fmt.Errorf("failed to read user config %s: %w", path, err) } - return data, nil + c.raw = data + if err := json.Unmarshal(data, c); err != nil { + return fmt.Errorf("failed to unmarshal %s: %v", path, err) + } + + return nil } diff --git a/pkg/credentials/store.go b/pkg/credentials/store.go index b839ad6d..be4be183 100644 --- a/pkg/credentials/store.go +++ b/pkg/credentials/store.go @@ -140,7 +140,7 @@ func (s Store) List(_ context.Context) ([]Credential, error) { } if len(s.credCtxs) > 0 && s.credCtxs[0] == AllCredentialContexts { - allCreds := make([]Credential, len(list)) + allCreds := make([]Credential, 0, len(list)) for serverAddress := range list { ac, err := store.Get(serverAddress) if err != nil {