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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## v0.3.0 (August 5, 2026)
* Added `awsd init <shell>` — one line in your rc file (`eval "$(awsd init zsh)"`) now replaces the `awsd` alias, the completion `source`, and the persistence snippet from the README. [#53]
* Added fish support, and PowerShell tab completion.
* Added `awsd shellenv [shell]`, which prints the export/unset statements for the active profile and region. This is what the generated function evals.
* `~/.awsd` parsing now lives only in the Go code. `scripts/_awsd` and `scripts/powershell/awsd.ps1` are thin shims over `awsd shellenv`.
* Values are now shell-quoted, so profile names containing spaces or quotes work.
* **Behavior change:** `awsd <unknown-profile>` now writes its warning to stderr and exits 1, instead of writing to stdout and exiting 0. Scripts that relied on the old exit code need updating. This keeps the warning out of the command substitutions the shell integration evals, where ANSI color codes surfaced as `bad pattern: ^[[0` rather than a readable message.
* Deprecated `alias awsd="source _awsd"` and `source _awsd_autocomplete`. Both still work; use `awsd init` instead.

## v0.2.0 (April 27, 2026)
* Added region switching: `awsd set region [name]` (interactive picker if no name given), `awsd unset region`, `awsd list regions`.
* Added `awsd set profile [name]` and `awsd unset profile` as explicit forms — bare `awsd <profile>` still works.
Expand Down
22 changes: 11 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ install: ## Install Target
GOOS= GOARCH= GOARM= GOFLAGS= go build -o ${BINDIR}/_awsd_prompt
cp scripts/_awsd ${BINDIR}/_awsd
cp scripts/_awsd_autocomplete ${BINDIR}/_awsd_autocomplete
@echo " -=-=--=-=-=-=-=-=-=-=-=-=-=-=- "
@echo " "
@echo " To Finish Installation add "
@echo " "
@echo " alias awsd=\"source _awsd\" "
@echo " "
@echo " to your bash profile or zshrc "
@echo " then open new terminal or "
@echo " source that file "
@echo " "
@echo " -=-=--=-=-=-=-=-=-=-=-=-=-=-=- "
@echo " -=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- "
@echo " "
@echo " To Finish Installation add "
@echo " "
@echo " eval \"\$$(_awsd_prompt init zsh)\" "
@echo " "
@echo " to your zshrc (or bash profile, "
@echo " with 'init bash') then open a new "
@echo " terminal or source that file "
@echo " "
@echo " -=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- "

uninstall: ## Uninstall Target
rm -f ${BINDIR}/_awsd
Expand Down
116 changes: 74 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ awsd is a command-line utility that allows you to easily switch between AWS Prof
- [Makefile](#makefile)
- [To Finish Installation](#to-finish-installation)
- [Upgrading](#upgrading)
- [Upgrading from pre-v0.3.0](#upgrading-from-pre-v030)
- [Usage](#usage)
- [Switching AWS Profiles](#switching-aws-profiles)
- [Switching AWS Regions](#switching-aws-regions)
- [Persist Profile and Region across new shells](#persist-profile-and-region-across-new-shells)
- [Show your AWS Profile in your shell prompt](#show-your-aws-profile-in-your-shell-prompt)
- [Add autocompletion](#add-autocompletion)
- [TL;DR (full config example)](#tldr-full-config-example)
- [Why a shell function?](#why-a-shell-function)
- [Contributing](#contributing)
- [License](#license)

Expand All @@ -43,13 +43,35 @@ make install
```

### To Finish Installation
Add the following to your bash profile or zshrc then open new terminal or source that file
Add one line to your shell's startup file, then open a new terminal or source that file.

**zsh** (`~/.zshrc`):
```sh
alias awsd="source _awsd"
eval "$(awsd init zsh)"
```

Ex. `echo 'alias awsd="source _awsd"' >> ~/.zshrc`
**bash** (`~/.bashrc` or `~/.bash_profile`):
```sh
eval "$(awsd init bash)"
```

**fish** (`~/.config/fish/config.fish`):
```fish
awsd init fish | source
```

**PowerShell** (`$PROFILE`):
```powershell
awsd init powershell | Out-String | Invoke-Expression
```

Ex. `echo 'eval "$(awsd init zsh)"' >> ~/.zshrc`

That one line defines the `awsd` command, sets up tab completion, and applies the profile and
region you last selected to every new shell. Nothing else to configure.

If `awsd` isn't on your `PATH` yet (the binary installs as `_awsd_prompt`), use
`eval "$(_awsd_prompt init zsh)"` instead.

### Upgrading
Upgrading consists of just doing a brew update and brew upgrade.
Expand All @@ -58,6 +80,30 @@ Upgrading consists of just doing a brew update and brew upgrade.
brew update && brew upgrade radiusmethod/awsd/awsd
```

### Upgrading from pre-v0.3.0
Before v0.3.0 you needed a hand-written alias, a separate completion `source`, and a block of
shell copied out of this README to persist your profile across shells:

```sh
alias awsd="source _awsd" # no longer needed
source _awsd_autocomplete # no longer needed
if [ -f ~/.awsd ]; then ... # no longer needed
```

Replace all of it with `eval "$(awsd init zsh)"`. The old alias still works for now, but it is
deprecated and will be removed in a future release.

Two things to check when you upgrade:

- **Remove the old alias.** In zsh an alias shadows a function of the same name, so leaving
`alias awsd="source _awsd"` in place means the new `awsd` function never gets used. If the alias
is defined *before* the `eval` line, the eval fails outright with
`defining function based on alias 'awsd'`.
- **Put the `eval` line after any `PATH` changes** that point at your awsd install. It runs
`_awsd_prompt` at startup, so if an older copy is earlier in `PATH` at that moment you get
`(eval):1: bad pattern: ^[[0`. That is a pre-v0.3.0 binary printing `Profile init does not
exist` and zsh trying to eval the color codes. `type -a _awsd_prompt` shows you every copy.

## Usage

### Switching AWS Profiles
Expand Down Expand Up @@ -93,23 +139,8 @@ Region us-east-1 set.

Setting a region exports `AWS_REGION` and `AWS_DEFAULT_REGION` in the calling shell. Profile and region are independent — `awsd set profile` does not change your region, and vice versa.

### Persist Profile and Region across new shells
To persist the active profile (and region) when you open new terminal windows, add the following to your bash profile or zshrc. It handles both the current `key=value` format and the legacy single-line format.

```bash
if [ -f ~/.awsd ]; then
if grep -q '=' ~/.awsd; then
while IFS='=' read -r k v; do
case "$k" in
profile) [ -n "$v" ] && export AWS_PROFILE="$v" ;;
region) [ -n "$v" ] && export AWS_REGION="$v" AWS_DEFAULT_REGION="$v" ;;
esac
done < ~/.awsd
else
export AWS_PROFILE=$(cat ~/.awsd)
fi
fi
```
Your selection persists across new terminal windows automatically, since `awsd init` applies
whatever is in `~/.awsd` when each shell starts.

### Show your AWS Profile in your shell prompt
For better visibility into what your shell is set to it can be helpful to configure your prompt to show the value of the env variable `AWS_PROFILE`.
Expand All @@ -132,30 +163,31 @@ PROMPT='OTHER_PROMPT_STUFF $(aws_info)'
```

### Add autocompletion
Source the installed completion script from your bash profile or zshrc:
Tab completion comes with `awsd init`. It completes profile names on `awsd <TAB>`, the
`set`/`unset`/`list` subcommands, and their arguments, so `awsd set region <TAB>` lists regions
and `awsd set profile <TAB>` lists profiles.

```bash
source _awsd_autocomplete
## Why a shell function?

`awsd init` generates a shell function rather than shipping a plain binary, because a child
process cannot change its parent shell's environment. Anything that sets `AWS_PROFILE` for your
current shell has to run *in* that shell.

So the binary does the picking and writes your choice to `~/.awsd`, and the generated function
asks it for the matching shell code and evals that:

```sh
awsd() {
command _awsd_prompt "$@" || return
eval "$(command _awsd_prompt shellenv bash)"
}
```

This completes profile names on `awsd <TAB>`, the `set`/`unset`/`list` subcommands, and their arguments — e.g. `awsd set region <TAB>` lists regions, `awsd set profile <TAB>` lists profiles.
You can see exactly what gets eval'd at any time:

### TL;DR (full config example)
```bash
alias awsd="source _awsd"
source ~/bin/awsd_autocomplete.sh
if [ -f ~/.awsd ]; then
if grep -q '=' ~/.awsd; then
while IFS='=' read -r k v; do
case "$k" in
profile) [ -n "$v" ] && export AWS_PROFILE="$v" ;;
region) [ -n "$v" ] && export AWS_REGION="$v" AWS_DEFAULT_REGION="$v" ;;
esac
done < ~/.awsd
else
export AWS_PROFILE=$(cat ~/.awsd)
fi
fi
```sh
awsd init zsh # the whole integration
awsd shellenv zsh # just the exports for the current selection
```

## Contributing
Expand Down
4 changes: 3 additions & 1 deletion docs/awsd.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ awsd [flags]

### SEE ALSO

* [awsd init](awsd_init.md) - Print the shell integration for the given shell.
* [awsd list](awsd_list.md) - List AWS profiles or regions.
* [awsd set](awsd_set.md) - Set the active AWS profile or region.
* [awsd shellenv](awsd_shellenv.md) - Print the shell code that applies ~/.awsd to the current shell.
* [awsd unset](awsd_unset.md) - Unset the active AWS profile or region.
* [awsd version](awsd_version.md) - awsd version command

###### Auto generated by spf13/cobra on 27-Apr-2026
###### Auto generated by spf13/cobra on 5-Aug-2026
37 changes: 37 additions & 0 deletions docs/awsd_init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## awsd init

Print the shell integration for the given shell.

### Synopsis

Print the shell integration for the given shell: the awsd function, completion, and the hook that applies the profile/region in ~/.awsd to new shells.

awsd has to run inside your shell to export AWS_PROFILE, because a child process cannot change its parent's environment. Eval this from your rc file:

bash/zsh: eval "$(awsd init zsh)"
fish: awsd init fish | source
PowerShell: awsd init powershell | Out-String | Invoke-Expression

```
awsd init <shell> [flags]
```

### Examples

```
eval "$(awsd init zsh)"

# supported: bash, zsh, fish, powershell
```

### Options

```
-h, --help help for init
```

### SEE ALSO

* [awsd](awsd.md) - awsd - switch between AWS profiles.

###### Auto generated by spf13/cobra on 5-Aug-2026
2 changes: 1 addition & 1 deletion docs/awsd_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ awsd list [profiles|regions] [flags]

* [awsd](awsd.md) - awsd - switch between AWS profiles.

###### Auto generated by spf13/cobra on 27-Apr-2026
###### Auto generated by spf13/cobra on 5-Aug-2026
2 changes: 1 addition & 1 deletion docs/awsd_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ Set the active AWS profile or region. With no subcommand, prints help.
* [awsd set profile](awsd_set_profile.md) - Set the active AWS profile (interactive picker if no name given).
* [awsd set region](awsd_set_region.md) - Set the active AWS region (interactive picker if no region given).

###### Auto generated by spf13/cobra on 27-Apr-2026
###### Auto generated by spf13/cobra on 5-Aug-2026
2 changes: 1 addition & 1 deletion docs/awsd_set_profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ awsd set profile [name] [flags]

* [awsd set](awsd_set.md) - Set the active AWS profile or region.

###### Auto generated by spf13/cobra on 27-Apr-2026
###### Auto generated by spf13/cobra on 5-Aug-2026
2 changes: 1 addition & 1 deletion docs/awsd_set_region.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ awsd set region [region] [flags]

* [awsd set](awsd_set.md) - Set the active AWS profile or region.

###### Auto generated by spf13/cobra on 27-Apr-2026
###### Auto generated by spf13/cobra on 5-Aug-2026
23 changes: 23 additions & 0 deletions docs/awsd_shellenv.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## awsd shellenv

Print the shell code that applies ~/.awsd to the current shell.

### Synopsis

Print the export/unset statements for the active profile and region. Used by the function that `awsd init` generates; you should not need to call it directly. Defaults to POSIX (bash/zsh) syntax.

```
awsd shellenv [shell] [flags]
```

### Options

```
-h, --help help for shellenv
```

### SEE ALSO

* [awsd](awsd.md) - awsd - switch between AWS profiles.

###### Auto generated by spf13/cobra on 5-Aug-2026
2 changes: 1 addition & 1 deletion docs/awsd_unset.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ Clear the active AWS profile (back to default) or AWS region.
* [awsd unset profile](awsd_unset_profile.md) - Reset the active AWS profile to default.
* [awsd unset region](awsd_unset_region.md) - Clear the active AWS region.

###### Auto generated by spf13/cobra on 27-Apr-2026
###### Auto generated by spf13/cobra on 5-Aug-2026
2 changes: 1 addition & 1 deletion docs/awsd_unset_profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ awsd unset profile [flags]

* [awsd unset](awsd_unset.md) - Unset the active AWS profile or region.

###### Auto generated by spf13/cobra on 27-Apr-2026
###### Auto generated by spf13/cobra on 5-Aug-2026
2 changes: 1 addition & 1 deletion docs/awsd_unset_region.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ awsd unset region [flags]

* [awsd unset](awsd_unset.md) - Unset the active AWS profile or region.

###### Auto generated by spf13/cobra on 27-Apr-2026
###### Auto generated by spf13/cobra on 5-Aug-2026
2 changes: 1 addition & 1 deletion docs/awsd_version.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ awsd version [flags]

* [awsd](awsd.md) - awsd - switch between AWS profiles.

###### Auto generated by spf13/cobra on 27-Apr-2026
###### Auto generated by spf13/cobra on 5-Aug-2026
59 changes: 12 additions & 47 deletions scripts/_awsd
Original file line number Diff line number Diff line change
@@ -1,49 +1,14 @@
#!/usr/bin/env bash

# check if $1 is empty
if [ -z "$1" ]
then
# no argument passed
AWS_PROFILE="$AWS_PROFILE" _awsd_prompt
else
# argument passed, assume it's a profile name
AWS_PROFILE="$AWS_PROFILE" _awsd_prompt "$@"
fi

touch ~/.awsd

unset _awsd_profile _awsd_region _awsd_has_region

# Detect legacy single-line format (no '=' anywhere): whole file is a profile name.
if grep -q '=' ~/.awsd
then
while IFS='=' read -r _awsd_k _awsd_v
do
case "$_awsd_k" in
profile) _awsd_profile=$_awsd_v ;;
region) _awsd_region=$_awsd_v; _awsd_has_region=1 ;;
esac
done < ~/.awsd
else
_awsd_profile="$(cat ~/.awsd)"
#
# Deprecated. Prefer the generated integration, which also wires up completion
# and picks up the active profile in new shells:
#
# eval "$(awsd init bash)" # or: awsd init zsh
#
# This file is kept so existing `alias awsd="source _awsd"` setups keep
# working. It must be sourced, not executed. The ~/.awsd parsing that used to
# live here now lives in the binary, behind `_awsd_prompt shellenv`.

if _awsd_prompt "$@"; then
eval "$(_awsd_prompt shellenv bash)"
fi

if [ -z "$_awsd_profile" ]
then
unset AWS_PROFILE
else
export AWS_PROFILE="$_awsd_profile"
fi

if [ -n "$_awsd_has_region" ]
then
if [ -z "$_awsd_region" ]
then
unset AWS_REGION AWS_DEFAULT_REGION
else
export AWS_REGION="$_awsd_region"
export AWS_DEFAULT_REGION="$_awsd_region"
fi
fi

unset _awsd_profile _awsd_region _awsd_has_region _awsd_k _awsd_v
Loading