Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.0] - 2026-01-08
### Changed
- **Major Redesign**: `gsw` now defaults to **Session-scoped switching** (current terminal tab only) for improved safety.
- `gsw <config>`: Switches configuration for the current session by default.
- `gsw -g <config>` or `gsw --global <config>`: Switches the global configuration.
- Simplified help and usage messages to reflect the new session-first approach.

### Removed
- `gsw-local` command has been completely removed (its functionality is now the default behavior of `gsw`).

## [0.2.0] - 2026-01-07
### Added
- `--help` / `-h` flag for both `gsw` and `gsw-local` commands.
Expand Down
17 changes: 4 additions & 13 deletions LLMS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,21 @@ gsw is a lightweight Bash/Zsh plugin for switching between gcloud configurations

### gsw

Switch the GLOBAL active gcloud configuration.
Switch the gcloud configuration. Defaults to the current shell session.

```
gsw <config_name> # Switch to specified configuration
gsw <config_name> # Switch for current session (sets CLOUDSDK_ACTIVE_CONFIG_NAME)
gsw -g <config_name> # Switch GLOBALLY (changes default active config)
gsw # List available configurations and show usage
gsw --help # Show help (static, no gcloud call)
gsw --version # Show version
```

### gsw-local

Switch configuration ONLY for the current shell session.

```
gsw-local <config_name> # Switch locally (sets CLOUDSDK_ACTIVE_CONFIG_NAME)
gsw-local # List available configurations and show usage
gsw-local --help # Show help
```

## Environment Variables

| Variable | Description | Set by |
|----------|-------------|--------|
| `CLOUDSDK_ACTIVE_CONFIG_NAME` | Overrides global config for current shell | `gsw-local` |
| `CLOUDSDK_ACTIVE_CONFIG_NAME` | Overrides global config for current shell | `gsw` (default) |

## Exit Codes

Expand Down
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@

> Switch Google Cloud configurations instantly.

`gsw` is a lightweight Bash/Zsh plugin that makes switching between Google Cloud SDK configurations effortless. It supports both **Global** switching (changing the default for all shells) and **Local** switching (changing only for the current shell session).
`gsw` is a lightweight Bash/Zsh plugin that makes switching between Google Cloud SDK configurations effortless. It defaults to **Session** switching (changing only for the current terminal tab), with an option for **Global** switching.

## Why gsw?

Managing multiple Google Cloud projects usually involves `gcloud config configurations activate ...`, which changes the global state. This becomes dangerous when you have multiple terminals open—running a command in one terminal might target the wrong project because you switched configs in another tab.

`gsw` solves this by offering:
1. **Safety**: `gsw-local` limits configuration changes to only the *current shell session* (using `CLOUDSDK_ACTIVE_CONFIG_NAME`).
2. **Speed**: Shorter aliases (`gsw`, `gsw-local`) with tab completion save you keystrokes.
3. **Simplicity**: No complex setup or dependencies. Just shell functions.
1. **Safety by Default**: `gsw <config>` limits configuration changes to only the *current shell session* (using `CLOUDSDK_ACTIVE_CONFIG_NAME`).
2. **Global Control**: Use `gsw -g <config>` when you actually want to change the default for all terminals.
3. **Speed**: Shorter command with tab completion saves you keystrokes.
4. **Simplicity**: No complex setup or dependencies. Just shell functions.

## Features

- **Fast Switching**: `gsw <config>` to switch globally.
- 🛡️ **Local Isolation**: `gsw-local <config>` to switch *only* in the current terminal tab (perfect for multi-project workflows).
- 🛡️ **Session Isolation**: `gsw <config>` switches *only* in the current terminal tab (perfect for multi-project workflows).
- **Global Switch**: `gsw -g <config>` to switch globally when needed.
- 🧠 **Auto-Completion**: Tab completion for your existing gcloud configurations (Bash & Zsh).
- 📦 **Zero Dependencies**: Pure Shell functions.

Expand Down Expand Up @@ -69,18 +70,18 @@ use = ["gsw.sh"]

## Usage

### Global Switch (`gsw`)
Changes the active configuration for **all** open terminals (that rely on the global config).
### Session Switch (Default)
Changes the active configuration **only for the current shell session**. This sets the `CLOUDSDK_ACTIVE_CONFIG_NAME` environment variable.

```bash
gsw my-work-profile
```

### Local Switch (`gsw-local`)
Changes the active configuration **only for the current shell session**. This sets the `CLOUDSDK_ACTIVE_CONFIG_NAME` environment variable.
### Global Switch (`-g`)
Changes the active configuration for **all** open terminals.

```bash
gsw-local my-personal-profile
gsw -g my-personal-profile
```

### List Configurations
Expand Down
Binary file modified demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 9 additions & 13 deletions demo.tape
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@ Type "setopt PROMPT_SUBST"
Enter
Type "setopt INTERACTIVE_COMMENTS"
Enter
# Mock gcloud for simple list usage if needed (though gsw mock handles most)
# Mock gcloud for simple list usage
Type "function gcloud() { :; }"
Enter

# OVERRIDE gsw/gsw-local
# Using single quotes for VHS 'Type' makes it much safer to define functions with double quotes internally
Type 'function gsw() { if [ -z "$1" ]; then echo "Available gcloud configurations:"; echo "NAME IS_ACTIVE ACCOUNT PROJECT"; echo "default True user@demo.com demo-project"; echo "work-project False worker@corp.com work-production"; echo "personal-side-hustle False me@gmail.com personal-app"; echo ""; echo "Usage: gsw <config_name>"; echo " Switches the GLOBAL active configuration."; else echo "Activated [$1]."; echo "✅ Switched to configuration: $1"; echo "Current Identity:"; echo "- user@demo.com"; echo "- $1-id"; export PS1="%F{blue}%1~%f %F{cyan}(gcloud:$1)%f %# "; fi }'
Type 'GSW_GLOBAL="default"; GSW_SESSION="";'
Enter

Type 'function gsw-local() { echo "✅ Switched LOCALLY to configuration: $1"; echo "(This change only affects this terminal tab)"; echo "Current Identity:"; echo "- user@demo.com"; echo "- $1-id"; export CLOUDSDK_ACTIVE_CONFIG_NAME="$1"; export PS1="%F{blue}%1~%f %F{cyan}(gcloud:$1)%f %# "; }'
# OVERRIDE gsw for demo (Mocks output and PS1 updates with state)
Type 'function gsw() { local is_global=false; local config=""; while [[ $# -gt 0 ]]; do case "$1" in -g|--global) is_global=true; shift ;; *) config="$1"; shift ;; esac; done; if [ -z "$config" ]; then echo "Available gcloud configurations:"; echo "NAME IS_ACTIVE ACCOUNT PROJECT"; echo "default True user@demo.com demo-project"; echo "work-project False worker@corp.com work-production"; echo "personal-side-hustle False me@gmail.com personal-app"; echo ""; echo "Usage: gsw [options] <config_name>"; return; fi; if [ "$is_global" = true ]; then GSW_GLOBAL="$config"; echo "✅ Switched GLOBALLY to configuration: $config"; else GSW_SESSION="$config"; export CLOUDSDK_ACTIVE_CONFIG_NAME="$config"; echo "✅ Switched SESSION to configuration: $config"; echo "(This change only affects this terminal tab)"; fi; local active=${GSW_SESSION:-$GSW_GLOBAL}; export PS1="%F{blue}%1~%f %F{cyan}(gcloud:$active)%f %# "; }'
Enter

# 2. Configure PS1 (Initial State)
Expand All @@ -46,23 +44,21 @@ Enter
Show

# Start the demo
# (Removed no-arg 'gsw' check as requested)

Type "# Switch global configuration easily"
Type "# First, switch the Global configuration"
Enter
Sleep 500ms
Type "gsw work-project"
Type "gsw -g work-project"
Enter
Sleep 2s

Type "# Or switch LOCALLY for just this shell session"
Type "# Now, switch SESSION for just this terminal tab"
Enter
Sleep 500ms
Type "gsw-local personal-side-hustle"
Type "gsw personal-side-hustle"
Enter
Sleep 2s

Type "# Verify: Only this shell session is affected (env var is set)"
Type "# Verify: Environment variable is set, overriding global"
Enter
Sleep 500ms
Type "echo $CLOUDSDK_ACTIVE_CONFIG_NAME"
Expand Down
124 changes: 51 additions & 73 deletions gsw.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,95 +2,75 @@

# gsw: Google Switch
# Easily switch between gcloud configurations
GSW_VERSION="v0.2.0"
GSW_VERSION="v0.3.0"

function gsw() {
if [ "$1" = "--version" ] || [ "$1" = "-v" ]; then
echo "gsw version $GSW_VERSION"
return 0
fi
local is_global=false
local config_name=""

if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
echo "Usage: gsw <config_name>"
echo " gsw --help"
echo " gsw --version"
echo ""
echo " Switches the GLOBAL active gcloud configuration."
echo ""
echo "Options:"
echo " <config_name> Name of the gcloud configuration to activate"
echo " --help, -h Show this help message"
echo " --version, -v Show version information"
echo ""
echo "💡 Tip: Run 'gsw' without arguments to see available configurations."
return 0
fi
while [[ $# -gt 0 ]]; do
case "$1" in
--version|-v)
echo "gsw version $GSW_VERSION"
return 0
;;
--help|-h)
echo "Usage: gsw [options] <config_name>"
echo ""
echo " Switches the gcloud configuration for the current session by default."
echo ""
echo "Options:"
echo " <config_name> Name of the gcloud configuration to activate"
echo " -g, --global Switch the GLOBAL active configuration"
echo " -h, --help Show this help message"
echo " -v, --version Show version information"
echo ""
echo "💡 Tip: Run 'gsw' without arguments to see available configurations."
return 0
;;
-g|--global)
is_global=true
shift
;;
-*)
echo "Error: Unknown option $1"
return 1
;;
*)
config_name="$1"
shift
;;
esac
done

if [ -z "$1" ]; then
if [ -z "$config_name" ]; then
echo "Available gcloud configurations:"
gcloud config configurations list
echo ""
echo "Usage: gsw <config_name>"
echo " gsw --help"
echo " gsw --version"
echo " Switches the GLOBAL active configuration."
echo "Usage: gsw [options] <config_name>"
echo " (Default switches only for this terminal session)"
echo ""
echo "💡 Tip: To switch automatically when entering a directory,"
echo " add this to your .envrc file:"
echo " export CLOUDSDK_ACTIVE_CONFIG_NAME=\"<config_name>\""
echo "Options:"
echo " -g, --global Switch the GLOBAL active configuration"
return
fi

# Check if the configuration exists
if ! gcloud config configurations describe "$1" > /dev/null 2>&1; then
echo "Error: Configuration '$1' does not exist."
if ! gcloud config configurations describe "$config_name" > /dev/null 2>&1; then
echo "Error: Configuration '$config_name' does not exist."
echo "Available configurations:"
gcloud config configurations list
return 1
fi

gcloud config configurations activate "$1"
echo "✅ Switched to configuration: $1"

# Optional: Show current active account and project for confirmation
echo "Current Identity:"
gcloud config list --format="value(core.account,core.project)" | tr '\t' '\n' | sed 's/^/- /'
}

# gsw-local: Switch ONLY in the current shell
# Uses environment variable CLOUDSDK_ACTIVE_CONFIG_NAME
function gsw-local() {
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
echo "Usage: gsw-local <config_name>"
echo " gsw-local --help"
echo ""
echo " Switches configuration ONLY for this terminal session."
echo " This sets the CLOUDSDK_ACTIVE_CONFIG_NAME environment variable."
echo ""
echo "Options:"
echo " <config_name> Name of the gcloud configuration to activate locally"
echo " --help, -h Show this help message"
echo ""
echo "💡 Tip: Run 'gsw-local' without arguments to see available configurations."
return 0
if [ "$is_global" = true ]; then
gcloud config configurations activate "$config_name"
echo "✅ Switched GLOBALLY to configuration: $config_name"
else
export CLOUDSDK_ACTIVE_CONFIG_NAME="$config_name"
echo "✅ Switched SESSION to configuration: $config_name"
echo "(This change only affects this terminal tab)"
fi

if [ -z "$1" ]; then
echo "Available gcloud configurations:"
gcloud config configurations list
echo ""
echo "Usage: gsw-local <config_name>"
echo " gsw-local --help"
echo " Switches configuration ONLY for this terminal tab."
echo ""
echo "💡 Tip: This sets the environment variable:"
echo " export CLOUDSDK_ACTIVE_CONFIG_NAME=\"<config_name>\""
return
fi

export CLOUDSDK_ACTIVE_CONFIG_NAME="$1"
echo "✅ Switched LOCALLY to configuration: $1"
echo "(This change only affects this terminal tab)"

echo "Current Identity:"
gcloud config list --format="value(core.account,core.project)" | tr '\t' '\n' | sed 's/^/- /'
Expand All @@ -111,7 +91,6 @@ if [ -n "$BASH_VERSION" ]; then
return 0
}
complete -F _gsw_bash_autocomplete gsw
complete -F _gsw_bash_autocomplete gsw-local

elif [ -n "$ZSH_VERSION" ]; then
# Zsh Completion
Expand All @@ -121,5 +100,4 @@ elif [ -n "$ZSH_VERSION" ]; then
compadd -a configs
}
compdef _gsw gsw
compdef _gsw gsw-local
fi
Loading