-
Notifications
You must be signed in to change notification settings - Fork 492
feat: support LARKSUITE_CLI_PROFILE env var for multi-app selection #445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,7 @@ import ( | |
| "strings" | ||
| "unicode/utf8" | ||
|
|
||
| "github.com/larksuite/cli/internal/envvars" | ||
| "github.com/larksuite/cli/internal/keychain" | ||
| "github.com/larksuite/cli/internal/output" | ||
| "github.com/larksuite/cli/internal/validate" | ||
|
|
@@ -86,6 +87,52 @@ func (m *MultiAppConfig) CurrentAppConfig(profileOverride string) *AppConfig { | |
| return nil | ||
| } | ||
|
|
||
| // FindAppByID searches apps by appId and returns a pointer to the matching AppConfig. | ||
| // Returns a ConfigError listing available IDs if not found. | ||
| func FindAppByID(apps []AppConfig, appID string) (*AppConfig, error) { | ||
| for i := range apps { | ||
| if apps[i].AppId == appID { | ||
| return &apps[i], nil | ||
| } | ||
| } | ||
| ids := make([]string, len(apps)) | ||
| for i, a := range apps { | ||
| ids[i] = a.AppId | ||
| } | ||
| return nil, &ConfigError{ | ||
| Code: 2, | ||
| Type: "config", | ||
| Message: fmt.Sprintf("app %q not found in config; available: %s", appID, strings.Join(ids, ", ")), | ||
| Hint: "check LARKSUITE_CLI_PROFILE or run `lark-cli config init`", | ||
| } | ||
| } | ||
|
Comment on lines
+90
to
+108
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| // ActiveApp returns the active app from a MultiAppConfig. | ||
| // Resolution priority: LARKSUITE_CLI_PROFILE env var > CurrentApp field > Apps[0]. | ||
| func ActiveApp(multi *MultiAppConfig) (*AppConfig, error) { | ||
| if len(multi.Apps) == 0 { | ||
| return nil, &ConfigError{Code: 2, Type: "config", Message: "no apps configured", Hint: "run `lark-cli config init`"} | ||
| } | ||
| if envProfile := os.Getenv(envvars.CliProfile); envProfile != "" { | ||
| app := multi.CurrentAppConfig(envProfile) | ||
| if app == nil { | ||
| return nil, &ConfigError{ | ||
| Code: 2, | ||
| Type: "config", | ||
| Message: fmt.Sprintf("profile %q not found", envProfile), | ||
| Hint: fmt.Sprintf("available profiles: %s", formatProfileNames(multi.ProfileNames())), | ||
| } | ||
| } | ||
| return app, nil | ||
| } | ||
| // Fall back to CurrentAppConfig's own resolution (CurrentApp field > Apps[0]). | ||
| app := multi.CurrentAppConfig("") | ||
| if app == nil { | ||
| return nil, &ConfigError{Code: 2, Type: "config", Message: "no apps configured", Hint: "run `lark-cli config init`"} | ||
|
Comment on lines
+128
to
+131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don’t collapse a stale When Suggested fix // Fall back to CurrentAppConfig's own resolution (CurrentApp field > Apps[0]).
app := multi.CurrentAppConfig("")
if app == nil {
- return nil, &ConfigError{Code: 2, Type: "config", Message: "no apps configured", Hint: "run `lark-cli config init`"}
+ return nil, &ConfigError{
+ Code: 2,
+ Type: "config",
+ Message: fmt.Sprintf("profile %q not found", multi.CurrentApp),
+ Hint: fmt.Sprintf("available profiles: %s", formatProfileNames(multi.ProfileNames())),
+ }
}🤖 Prompt for AI Agents |
||
| } | ||
| return app, nil | ||
| } | ||
|
|
||
| // FindApp looks up an app by name, then by appId. Returns nil if not found. | ||
| // Name match takes priority: if profile A has Name "X" and profile B has AppId "X", | ||
| // FindApp("X") returns profile A. | ||
|
|
@@ -239,14 +286,24 @@ func RequireConfigForProfile(kc keychain.KeychainAccess, profileOverride string) | |
|
|
||
| // ResolveConfigFromMulti resolves a single-app config from an already-loaded MultiAppConfig. | ||
| // This avoids re-reading the config file when the caller has already loaded it. | ||
| // Resolution priority: profileOverride > LARKSUITE_CLI_PROFILE env var > config.CurrentApp > Apps[0]. | ||
| func ResolveConfigFromMulti(raw *MultiAppConfig, kc keychain.KeychainAccess, profileOverride string) (*CliConfig, error) { | ||
| app := raw.CurrentAppConfig(profileOverride) | ||
| if app == nil { | ||
| return nil, &ConfigError{ | ||
| Code: 2, | ||
| Type: "config", | ||
| Message: fmt.Sprintf("profile %q not found", profileOverride), | ||
| Hint: fmt.Sprintf("available profiles: %s", formatProfileNames(raw.ProfileNames())), | ||
| var app *AppConfig | ||
| if profileOverride != "" { | ||
| app = raw.CurrentAppConfig(profileOverride) | ||
| if app == nil { | ||
| return nil, &ConfigError{ | ||
| Code: 2, | ||
| Type: "config", | ||
| Message: fmt.Sprintf("profile %q not found", profileOverride), | ||
| Hint: fmt.Sprintf("available profiles: %s", formatProfileNames(raw.ProfileNames())), | ||
| } | ||
| } | ||
| } else { | ||
| var err error | ||
| app, err = ActiveApp(raw) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
In github.com/spf13/pflag, does FlagSet.StringVar set the destination variable to the provided default value immediately when the flag is registered?💡 Result:
Yes, in github.com/spf13/pflag, FlagSet.StringVar sets the destination variable to the provided default value immediately when the flag is registered.
Citations:
🏁 Script executed:
Repository: larksuite/cli
Length of output: 3125
The env-selected profile is overwritten when flags are registered in root.go.
The bootstrap correctly extracts the profile from the environment and passes it via
inv.Profile. However, incmd/root.go, a newGlobalOptionsis created with that profile value, then immediately passed toRegisterGlobalFlags. WhenRegisterGlobalFlagscallsfs.StringVar(&opts.Profile, "profile", "", ...), the hardcoded""default immediately overwritesopts.Profileback to empty. Any code that later readsglobals.Profilewill miss the environment variable.Fix
🤖 Prompt for AI Agents