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
32 changes: 32 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Environment (please complete the following information):**
- OS: [e.g. macOS, Linux]
- Shell: [e.g. bash, zsh]
- gsw version [if applicable]

**Additional context**
Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
33 changes: 33 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [INSERT EMAIL ADDRESS]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org
38 changes: 38 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Contributing to gsw

First off, thanks for taking the time to contribute! 🎉

The following is a set of guidelines for contributing to `gsw`. These are mostly guidelines, not rules. Use your best judgment and feel free to propose changes to this document in a pull request.

## How Can I Contribute?

### Reporting Bugs

This section guides you through submitting a bug report for `gsw`.

- **Check existing issues** to see if the bug has already been reported.
- **Use a clear and descriptive title** for the issue to identify the problem.
- **Describe the reproduction steps** in as much detail as possible.
- **Include your environment**: OS (macOS/Linux), Shell (Bash/Zsh), and `gcloud` version.

### Suggesting Enhancements

- **Use a clear and descriptive title** for the issue.
- **Provide a step-by-step description of the suggested enhancement** in as much detail as possible.
- **Explain why this enhancement would be useful** to most `gsw` users.

### Pull Requests

1. Fork the repo and create your branch from `main`.
2. If you've added code that should be tested, add tests.
3. Ensure your code passes existing tests: `./test/run_tests.sh` (if available) or verify manually.
4. Make sure your code lints with [ShellCheck](https://www.shellcheck.net/).
5. Issue that pull request!

## Styleguides

### Shell Scripts

- Use 2 spaces for indentation.
- Prefer `[[ ]]` over `[ ]` for tests in Bash/Zsh.
- Quoting variables is generally a good idea.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,31 @@

[![test](https://github.com/sakebook/gsw/actions/workflows/test.yml/badge.svg)](https://github.com/sakebook/gsw/actions/workflows/test.yml)

> Switch Google Cloud configurations as easily as valid
> 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).

## 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.

## 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).
- 🧠 **Auto-Completion**: Tab completion for your existing gcloud configurations (Bash & Zsh).
- 📦 **Zero Dependencies**: Pure Shell functions.

## Demo

<!-- Check out how easy it is to switch contexts! -->
![gsw demo](demo.gif)

## Installation

### Method 1: One-Line Install (Recommended)
Expand Down
Binary file added demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 70 additions & 0 deletions demo.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# demo.tape
# Created by VHS
# Install VHS: brew install vhs
# Run: vhs demo.tape

Output demo.gif

Set Shell "zsh"
Set FontSize 16
Set Width 800
Set Height 500
Set Padding 12
Set TypingSpeed 35ms
Set FontFamily "Menlo"
Set WindowBar Colorful
Set Theme "Catppuccin Frappe"

# Hide the setup commands so the viewer only sees the result
Hide
Type "source ./gsw.sh"
Enter
Type "autoload -Uz colors && colors"
Enter
Type "setopt PROMPT_SUBST"
Enter
Type "setopt INTERACTIVE_COMMENTS"
Enter
# Mock gcloud for simple list usage if needed (though gsw mock handles most)
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 }'
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 %# "; }'
Enter

# 2. Configure PS1 (Initial State)
Type "export PS1='%F{blue}%1~%f %F{cyan}(gcloud:default)%f %# '"
Enter
# Clear screen to start fresh
Type "clear"
Enter
Show

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

Type "# Switch global configuration easily"
Enter
Sleep 500ms
Type "gsw work-project"
Enter
Sleep 2s

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

Type "# Verify: Only this shell session is affected (env var is set)"
Enter
Sleep 500ms
Type "echo $CLOUDSDK_ACTIVE_CONFIG_NAME"
Enter
Sleep 3s
32 changes: 22 additions & 10 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ set -e

REPO_URL="https://github.com/sakebook/gsw.git"
INSTALL_DIR="$HOME/.gsw"
ZSHRC="$HOME/.zshrc"

echo "✨ Installing gsw..."

Expand All @@ -16,21 +15,34 @@ else
git clone --quiet "$REPO_URL" "$INSTALL_DIR"
fi

# 2. Add to .zshrc
SOURCE_CMD="source $INSTALL_DIR/gsw.sh"
# 2. Detect shell configuration files
SHELL_FILES=()
[ -f "$HOME/.zshrc" ] && SHELL_FILES+=("$HOME/.zshrc")
[ -f "$HOME/.bashrc" ] && SHELL_FILES+=("$HOME/.bashrc")
[ -f "$HOME/.bash_profile" ] && SHELL_FILES+=("$HOME/.bash_profile")

if grep -Fxq "$SOURCE_CMD" "$ZSHRC"; then
echo " Already configured in $ZSHRC"
if [ ${#SHELL_FILES[@]} -eq 0 ]; then
echo "⚠️ No shell configuration files (~/.zshrc, ~/.bashrc, or ~/.bash_profile) found."
echo " Please add 'source $INSTALL_DIR/gsw.sh' to your shell config manually."
else
echo " Adding source command to $ZSHRC..."
echo "" >> "$ZSHRC"
echo "# gsw: Google Switch" >> "$ZSHRC"
echo "$SOURCE_CMD" >> "$ZSHRC"
SOURCE_CMD="source $INSTALL_DIR/gsw.sh"
for RC_FILE in "${SHELL_FILES[@]}"; do
if grep -Fxq "$SOURCE_CMD" "$RC_FILE"; then
echo " Already configured in $(basename "$RC_FILE")"
else
echo " Adding source command to $(basename "$RC_FILE")..."
{
echo ""
echo "# gsw: Google Switch"
echo "$SOURCE_CMD"
} >> "$RC_FILE"
fi
done
fi

echo ""
echo "✅ Installation complete!"
echo " Please restart your terminal or run: source ~/.zshrc"
echo " Please restart your terminal or source your config file."
echo ""
echo " Try it: gsw"
echo ""