Skip to content

Commit

Permalink
feat: add zsh and dash support to prompt (automotiveMastermind#32)
Browse files Browse the repository at this point in the history
* restructure prompt repository to allow switching shells between:
  * sh/dash
  * bash
  * zsh
* move most scripts that are shell agnostic to sh and update shebang
* maintain feature parity between bash / zsh for:
  * prompt
  * color support
  * shell options
  * tab completion (including case-insensitive secondary match)
* update documentation for updated installation
* add `use-bash` command to enable changing the default shell to bash
* add `use-zsh` command to enable changing the default shell to zsh
* add `dark-mode` theme for macOS
* add support for installing older versions of prompt through bootstrap and `update-prompt` commands

NOTES:

Adding support for zsh allows new installations of macOS Catalina to
use the default shell, which was switched to zsh for this release.
Future builds of macOS are likely to drop built-in support for bash due
to the GPLv3 license.

When bootstrapping prompt from bash; prompt will update and use bash.
When bootstrapping prompt from zsh; prompt will update and use zsh.
When bootstrapping from any other shell, prompt will use bash by default.

A command line argument can be used to to select the prompt at install time.
Switching prompts can be done via new `use-bash` and `use-zsh` commands.

BREAKING CHANGE:

While this is not an actual breaking change, quite a bit has changed with
regard to how prompt actually works. We want to notify users that this may
result is some level of bugs as test coverage of scripts like this one is
incredibly difficult.
  • Loading branch information
dmccaffery committed Dec 17, 2019
1 parent 6e55c54 commit 275f62c
Show file tree
Hide file tree
Showing 135 changed files with 2,013 additions and 692 deletions.
47 changes: 26 additions & 21 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
version: 2

jobs:
macos:
macos:
xcode: "10.2.1"
xcode: "11.2.1"
steps:
- checkout
- run:
name: analyze
command: |
curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | bash
fossa init
fossa analyze
- run:
name: install
command: ./install.sh | tee log.txt
name: install-bash
command: ./install.sh bash | tee log.txt && bash -lc "git sha"
- run:
name: verify
command: bash -l -c "git sha"
name: install-zsh
command: ./install.sh zsh | tee -a log.txt && zsh -lc "git sha"
- store_artifacts:
path: log.txt
destination: logs/$CIRCLE_STAGE.txt
Expand Down Expand Up @@ -73,6 +68,19 @@ jobs:
path: log.txt
destination: logs/$CIRCLE_STAGE.txt

fedora-31:
docker:
- image: docker:stable
steps:
- setup_remote_docker
- checkout
- run:
name: install and verify
command: docker build --file docker/$CIRCLE_STAGE/Dockerfile . | tee log.txt
- store_artifacts:
path: log.txt
destination: logs/$CIRCLE_STAGE.txt

centos:
docker:
- image: docker:stable
Expand Down Expand Up @@ -112,21 +120,14 @@ jobs:
keys:
- yarn-packages-{{ checksum "yarn.lock" }}
- run:
name: configure
command: |
git config user.email $GIT_AUTHOR_EMAIL
git config user.name $GIT_AUTHOR_NAME
- run:
name: install
command: yarn install --frozen-lockfile
name: publish
command: ./publish.sh
- save_cache:
name: save yarn package cache
key: yarn-packages-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
- run:
name: release
command: yarn run release

workflows:
version: 2
install:
Expand All @@ -151,6 +152,10 @@ workflows:
filters:
branches:
ignore: master
- fedora-31:
filters:
branches:
ignore: master
- centos:
filters:
branches:
Expand Down
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,10 @@

artifacts/
node_modules/
docker/

*.md
*.lock
*.json
CODEOWNERS
LICENSE
5 changes: 1 addition & 4 deletions .fossa.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
# Generated by FOSSA CLI (https://github.com/fossas/fossa-cli)
# Visit https://fossa.com to learn more

version: 2
cli:
server: https://app.fossa.com
fetcher: custom
project: https://github.com/dmccaffery/prompt
project: promptMastermind
analyze:
modules:
- name: .
Expand Down
14 changes: 13 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,17 @@
},
"editor.trimAutoWhitespace": true,
"editor.formatOnSave": true,
"files.trimTrailingWhitespace": true
"files.trimTrailingWhitespace": true,
"cSpell.words": [
"dnvm",
"gcloud",
"keychain",
"macos",
"minikube",
"repos",
"symlink",
"toolchain",
"xcode",
"xplat"
]
}
69 changes: 50 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# promptMastermind

> A spectacular (BaSH) prompt for macOS and *nix distributions
> A spectacular shell prompt for macOS and *nix distributions
![Preview][preview-image]

Expand All @@ -25,57 +25,87 @@ mint | 19 or greater

## Know It

promptMastermind is a prompt for BaSH on *nix distributions that includes a ton of useful functionality, including:
promptMastermind is a prompt for sh, bash, and zsh on *nix distributions that includes a ton of useful functionality,
including:

* A two-line prompt that displays username, hostname, and current path
* Git prompt support (that emits information about the current branch and status when in a git path)
* Better BaSH completion for git and git-flow
* Installation of dotnet-cli
* Better tab completion for git and git-flow
* Installation of dotnet sdk, aws sdk, and gcloud sdk
* Bookmarking support (cdable variables)
* Variables support (add vars without modifying profile)
* Flush DNS (on macOS)
* Ability to enable and disable hidden files in Finder (on macOS)
* Display of available colors (already set as variables for use elsewhere)
* ... and much more!

Note: All "extensions" are implemented as sourced function calls, so it should not interfere with existing
Note: All "extensions" are implemented as scripts added to the path, so it should not interfere with existing
customization (aside from the prompt).

### Use It

Install promptMastermind in one step:
Install promptMastermind in one step (choose one of the following options):

``` bash
curl -fsSL https://git.io/am-prompt | /usr/bin/env bash
``` sh
# install and use bash
curl -fsSL https://git.io/am-prompt | sh -s -- bash

# install and use zsh
curl -fsSL https://git.io/am-prompt | sh -s -- zsh
```

> NOTE: if you do not specify a shell, bash will be used by default
#### Specific Versions

Although it is **NOT** recommended, you can install a specific version of prompt using one of the following:

``` sh
# install and use bash with prompt v6.0.0
curl -fsSL https://git.io/am-prompt | sh -s -- --version v7.0.0 bash

# install and use zsh with prompt v7.0.0
curl -fsSL https://git.io/am-prompt | sh -s -- --version v7.0.0 zsh
```

(Optional) Open the included Monokai theme (currently only supported on macOS):
All available versions of prompt are available here: https://github.com/automotiveMastermind/prompt/releases

``` bash
theme
> NOTE: zsh is only available as of v7.0.0 -- older versions of prompt only support bash
(Optional) Open an included theme (currently only supported on macOS):

``` sh
theme monokai # general high quality theme that has been around for many years
```

OR

```sh
theme dark-mode # our own custom theme that is nice and bright for dark mode on macOS
```

Updating promptMastermind:

``` bash
``` sh
update-prompt
```

If you already have the latest version of prompt installed, the ```update-prompt``` command will not re-install the
If you already have the latest version of prompt installed, the `update-prompt` command will not re-install the
current version.

**NOTE**: The installer simply creates a new folder (.am) under the home folder and copies all of the files
there. It will backup this folder first. It wires up the "extensions" by adding a source command for
```$HOME/.am/prompt/bashrc``` to ```$HOME/.bash_profile```. It will not duplicate itself, so you can re-run the
installer or use the ```upgrade-prompt``` command to upgrade at any time.
`$HOME/.am/prompt/bashrc` to `$HOME/.bash_profile`. It will not duplicate itself, so you can re-run the
installer or use the `upgrade-prompt` command to upgrade at any time.

The backup folder is located at: ```$HOME/.am/prompt/backup/[date]```.
The backup folder is located at: `$HOME/.am/backup/prompt/[date]`.

The ```$HOME/.bash_profile``` is also backed up to ```$HOME/.am/prompt/backup/[date]/.bash_profile```.
All profile and rc scripts such as `$HOME/.bash_profile` are also backed up to `$HOME/.am/backup/prompt/[date]/`.

## Build It

In order to test the installation routine for promptMastermind, we use a set of docker images for each of the supported *nix platforms. The build script in the `docker/` folder can be used to build all of the images, or specific ones:
In order to test the installation routine for promptMastermind, we use a set of docker images for each of the supported
*nix platforms. The build script in the `docker/` folder can be used to build all of the images, or specific ones:

```sh
# build all of the platforms (this will take a while)
Expand All @@ -88,7 +118,8 @@ In order to test the installation routine for promptMastermind, we use a set of
./docker/build.sh mint
```

In addition, [circleci][circleci-uri] is used to build all platforms, including macOS as part of our pull request validation. Special thanks to [circleci][circleci-uri] for providing the build agents!
In addition, [circleci][circleci-uri] is used to build all platforms, including macOS as part of our pull request
validation. Special thanks to [circleci][circleci-uri] for providing the build agents!

## Copyright and License

Expand Down
108 changes: 89 additions & 19 deletions bootstrap.sh
Original file line number Diff line number Diff line change
@@ -1,33 +1,103 @@
#!/usr/bin/env bash
#!/usr/bin/env sh

__am-prompt-bootstrap()
set -e

__am_prompt_update()
{
local CURL_OPT='-s'
if [ ! -z "${GH_TOKEN:-}" ]; then
CURL_OPT='$CURL_OPT -H "Authorization: token $GH_TOKEN"'
local CLR_FAIL=${CLR_FAIL:-"\033[1;31m"} # BRIGHT RED
local CLR_SUCCESS=${CLR_SUCCESS:-"\033[1;32m"} # BRIGHT GREEN
local CLR_WARN=${CLR_WARN:-"\033[1;33m"} # BRIGHT YELLOW
local CLR_CLEAR=${CLR_CLEAR:-"\033[0m"} # DEFAULT COLOR

local GH_TOKEN=${GH_TOKEN:-}
local PROMPT_TOKEN=${PROMPT_TOKEN:-}
local PROMPT_TOKEN=${PROMPT_TOKEN:-$GH_TOKEN}
local PROMPT_CURL_OPT=${PROMPT_CURL_OPT:-'-s'}
local PROMPT_COMMIT_REF=${PROMPT_COMMIT_REF:-"master"}
local PROMPT_SHELL=${PROMPT_SHELL:-"bash"}
local PROMPT_DRY_RUN=${PROMPT_DRY_RUN:-}

while :; do
case $1 in
-t|--token)
PROMPT_TOKEN=$2
shift
;;
-v|--version)
PROMPT_COMMIT_REF=$2
shift
;;
-dr|--dry-run)
PROMPT_DRY_RUN=1
;;
-f|--force)
rm -rf "$HOME/.am/prompt/.sha" 1>/dev/null 2>&1
;;
--debug)
set -x
;;
?*)
PROMPT_SHELL=$1
;;
*)
break
;;
esac
shift
done

if [ ! -z "${PROMPT_TOKEN:-}" ]; then
PROMPT_CURL_OPT='$PROMPT_CURL_OPT -H "Authorization: token $PROMPT_TOKEN"'
fi

local SHA_URI="https://api.github.com/repos/automotiveMastermind/prompt/commits/master"
local PROMPT_SHA=$(curl $CURL_OPT $SHA_URI | grep sha | head -n 1 | sed 's#.*\:.*"\(.*\).*",#\1#')
local SHA_PATH=$HOME/.am/prompt/$PROMPT_SHA
local PROMPT_SHA_URI="https://api.github.com/repos/automotiveMastermind/prompt/commits/$PROMPT_COMMIT_REF"
local PROMPT_SHA=$(curl $PROMPT_CURL_OPT $PROMPT_SHA_URI | grep sha | head -n 1 | sed 's#.*\:.*"\(.*\).*",#\1#')

if [ -f $SHA_PATH ]; then
echo "prompt: latest version already installed: $PROMPT_SHA"
exit 0
# detect if sha could be located
if [ -z ${PROMPT_SHA:-} ]; then
echo "${CLR_FAIL}prompt: cannot retrieve SHA of latest version. Are you connected to the internet?${CLR_CLEAR}"
return 1
fi

local INSTALL_URI="https://github.com/automotiveMastermind/prompt/archive/master.tar.gz"
local INTALL_TEMP=$(mktemp -d)
local EXTRACT_TEMP="$INTALL_TEMP/extract"
local PROMPT_SHA_PATH=$HOME/.am/prompt/.sha

pushd $INTALL_TEMP 1>/dev/null
curl -skL $INSTALL_URI | tar zx
# detect if sha file exists
if [ -f "$PROMPT_SHA_PATH" ]; then

# get the value of the sha file
PROMPT_CURRENT_SHA=$(cat "$PROMPT_SHA_PATH")

# print latest version already installed
if [ "${PROMPT_SHA}" = "${PROMPT_CURRENT_SHA}" ]; then
echo "${CLR_SUCCESS}prompt: latest version already installed: ${PROMPT_SHA}.${CLR_CLEAR}"
echo " - run update-prompt with the --force flag to reinstall ${CLR_CLEAR}"
exit 0
fi
fi

if [ ! -z "${PROMPT_DRY_RUN:-}" ]; then
echo "${CLR_WARN}prompt: a new version of prompt is available: ${PROMPT_SHA}."
echo " - run the update-prompt command line tool to upgrade${CLR_CLEAR}"
return 0
fi

remove-backup

local PROMPT_CHANGELOG_URI="https://github.com/automotivemastermind/prompt/blob/$PROMPT_COMMIT_REF/CHANGELOG.md"
local PROMPT_INSTALL_URI="https://github.com/automotiveMastermind/prompt/archive/$PROMPT_COMMIT_REF.tar.gz"
local PROMPT_INTALL_TEMP=$(mktemp -d)
local PROMPT_EXTRACT_TEMP="$PROMPT_INTALL_TEMP/extract"

pushd $PROMPT_INTALL_TEMP 1>/dev/null
curl -skL $PROMPT_INSTALL_URI | tar zx
pushd prompt-master 1>/dev/null
./install.sh
./install.sh $PROMPT_SHELL
popd 1>/dev/null
popd 1>/dev/null

rm -rf $INTALL_TEMP 1>/dev/null
rm -rf $PROMPT_INTALL_TEMP 1>/dev/null

open-url $CHANGELOG_URI 1>/dev/null
}

__am-prompt-bootstrap
__am_prompt_update $@
6 changes: 5 additions & 1 deletion docker/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
REPO_DIR=$(dirname "$SCRIPT_DIR")
LOGS_DIR="$REPO_DIR/artifacts/logs"

# enable buildkit by default
export DOCKER_BUILDKIT=${DOCKER_BUILDKIT:-1}

PLATFORMS=( "$@" )

if [ -z "${PLATFORMS:-}" ]; then
Expand All @@ -18,5 +21,6 @@ for platform in "${PLATFORMS[@]}"; do
dockerfile="$SCRIPT_DIR/$platform/Dockerfile"
tag="prompt:$platform"

docker build --file "$dockerfile" --tag $tag "$REPO_DIR" | tee "$LOGS_DIR/$platform.log"
rm -f "$LOGS_DIR/$platform.log" 1>/dev/null 2>&1 || true
docker build --file "$dockerfile" --tag $tag "$REPO_DIR" | tee -a "$LOGS_DIR/$platform.log"
done
Loading

0 comments on commit 275f62c

Please sign in to comment.