logout: rename --all to --all-contexts · Entire
logout: rename --all to --all-contexts
5bc6e49→main·
toothbrush·1mo ago·3 files·+24 added/-23 removed
--all was ambiguous next to --everywhere (all devices vs all logins). --all-contexts says what it does: drain every saved login context. Updates the flag, help text, doc comments, and tests. Also corrects stale "--all" wording in TestRunLogout_AllRevokesAllSessions, which exercises the --everywhere path.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
446db5e8b03dView transcript
[?
Refine logout Command with --all-contexts FlagClaude Code·1 step](/content/gh/entireio/cli/session/65e7cd20-dacf-4c93-a475-a4cd7e235c9c#timeline-446db5e8b03d/index.html)
Changes
3
cmd/entire/cli
auth
Mcontext_store.go+3/-3
Mlogout.go+10/-9
Mlogout_test.go+11/-11
54 unmodified lines
// RemoveContext deletes the named context from contexts.json and its keyring
tokens. A missing context is a no-op. Used by `logout --all` to drain every
saved login. File.Delete clears current_context when name was the active
one, so removing the current context this way also logs it out.
// tokens. A missing context is a no-op. Used by `logout --all-contexts` to
drain every saved login. File.Delete clears current_context when name was
the active one, so removing the current context this way also logs it out.
func RemoveContext(name string) error {
var svc, handle string
if err := contexts.Modify(contexts.DefaultConfigDir(), func(f *contexts.File) (bool, error) {
Mcmd/entire/cli/auth/context_store.go+3/-3
34 unmodified lines
func newLogoutCmd() *cobra.Command {
var insecureHTTPAuth bool
var everywhere bool
var all bool
var allContexts bool
cmd := &cobra.Command{
Use: "logout",
Short: "Log out of Entire",
"login server.\n\n" +
"Pass --everywhere to revoke every session on the active core server-side\n" +
"(all your devices), not just the current one.\n\n" +
"Pass --all to log out of every saved login (context) at once: each context's\n" +
"session is revoked server-side and the login is removed from this machine.\n" +
"Combine with --everywhere to revoke every session on every context's core.\n\n" +
"Without --all, logging out promotes the next saved login (if any) to active,\n" +
"so running `entire logout` repeatedly drains every saved login in turn.\n",
"Pass --all-contexts to log out of every saved login (context) at once: each\n" +
"context's session is revoked server-side and the login is removed from this\n" +
"machine. Combine with --everywhere to revoke every session on every context's\n" +
"core.\n\n" +
"Without --all-contexts, logging out promotes the next saved login (if any) to\n" +
"active, so running `entire logout` repeatedly drains every saved login in turn.",
RunE: func(cmd *cobra.Command, _ []string) error {
if err := requireSecureBaseURL(insecureHTTPAuth); err != nil {
return err
}
if all {
if allContexts {
return runLogoutAll(cmd.Context(), outW, errW, auth.Contexts,
auth.LoginTokenForContext, revokeForTarget, auth.RemoveContext,
auth.NewContextStore(), api.AuthBaseURL(), insecureHTTPAuth)
}
}
},
}
cmd.Flags().BoolVar(&everywhere, "everywhere", false, "Revoke every session server-side, not just the current one")
cmd.Flags().BoolVar(&all, "all", false, "Log out of every saved login (context), not just the active one")
cmd.Flags().BoolVar(&allContexts, "all-contexts", false, "Log out of every saved login (context), not just the active one")
addInsecureHTTPAuthFlag(cmd, &insecureHTTPAuth)
return cmd
}
// revokeTargetFunc revokes sessions on a specific core. The two production
// implementations are revokeCurrentSession (just the bearer's own session)
// and revokeAllSessions (every session on that core); logout --all picks
// and revokeAllSessions (every session on that core); logout --all-contexts picks
// one based on --everywhere and applies it to each saved context's core.
type revokeTargetFunc func(ctx context.Context, coreURL, token string) error
Mcmd/entire/cli/logout.go+10/-9
239 unmodified lines
if currentCalled { t.Error("--all should not call the current-session revoke") } if !allCalled { t.Error("--all should call the revoke-all path") } if !store.deleted["https://entire.io"] { t.Fatal("local token should still be deleted under --all") } if !strings.Contains(out.String(), "Logged out.") { t.Fatalf("stdout = %q, want to contain %q", out.String(), "Logged out.") }
// makeLogoutContexts builds a contextsProvider returning the given contexts
// with no active marker — `logout --all` ignores which one is current.
// with no active marker — `logout --all-contexts` ignores which one is current.
func makeLogoutContexts(cs ...*contexts.Context) contextsProvider {
return func() ([]*contexts.Context, string, error) { return cs, "", nil }
}
// TestLogoutCommand_FlagMatrix pins all four quadrants of the --all/--everywhere
// TestLogoutCommand_FlagMatrix pins all four quadrants of the --all-contexts/--everywhere
// matrix end-to-end through the cobra command, asserting which revoke shape each
// context's core actually received. Process-global env + keyring backend, so no
// t.Parallel(); subtests run sequentially, each with fresh state.
t.Run("--all: every context, current session each", func(t *testing.T) {
t.Run("--all-contexts: every context, current session each", func(t *testing.T) {
recA, recB := seedTwoContexts(t)
execLogout(t, "--all")
execLogout(t, "--all-contexts")
for name, rec := range map[string]*coreRecorder{"A": recA, "B": recB} {
if l, c, b := rec.snapshot(); l != 0 || c != 1 || b != 0 {
t.Errorf("context %s: want one current-session revoke, got list=%d current=%d byID=%d", name, l, c, b)
}
}
})
// added more test cases