diff --git a/README.md b/README.md
index 7d5fb77b..c04af4f9 100644
--- a/README.md
+++ b/README.md
@@ -10,17 +10,12 @@
## Table of Contents
- [What is Talisman?](#what-is-talisman)
- [Installation](#installation)
- - [[Recommended approach]](#recommended-approach)
+ - [Install onto path (recommended approach)](#install-onto-path-recommended-approach)
- [Installation as a global hook template](#installation-as-a-global-hook-template)
- - [Handling existing hooks](#handling-existing-hooks)
- - [1. Pre-commit (Linux/Unix)](#1-pre-commit-linuxunix)
- - [2. Husky (Linux/Unix/Windows)](#2-husky-linuxunixwindows)
- - [Windows](#windows)
- - [Linux/Unix](#linuxunix)
- - [Windows](#windows-1)
- - [Linux/Unix](#linuxunix-1)
- [Installation to a single project](#installation-to-a-single-project)
- - [Handling existing hooks](#handling-existing-hooks-1)
+- [Using with hook frameworks](#using-with-hook-frameworks)
+ - [Pre-commit](#pre-commit)
+ - [Husky](#husky)
- [Upgrading](#upgrading)
- [Talisman in action](#talisman-in-action)
- [Validations](#validations)
@@ -41,13 +36,15 @@
- [Uninstallation](#uninstallation)
- [Uninstallation from a global hook template](#uninstallation-from-a-global-hook-template)
- [Uninstallation from a single repository](#uninstallation-from-a-single-repository)
- - [Contributing to Talisman](#contributing-to-talisman)
+- [Contributing to Talisman](#contributing-to-talisman)
# What is Talisman?
-Talisman is a tool that installs a hook to your repository to ensure that potential secrets or sensitive information do not leave the developer's workstation.
-It validates the outgoing changeset for things that look suspicious - such as potential SSH
-keys, authorization tokens, private keys etc.
+Talisman is a tool that scans git changesets to ensure that potential secrets
+or sensitive information do not leave the developer's workstation.
+
+It validates the outgoing changeset for things that look suspicious - such as
+potential SSH keys, authorization tokens, private keys etc.
# Installation
@@ -55,8 +52,9 @@ Talisman supports MAC OSX, Linux and Windows.
Talisman can be installed and used in one of the following ways:
-1. As a git hook as a global [git hook template](https://git-scm.com/docs/git-init#_template_directory) and a CLI utility (for git repo scanning)
-2. As a git hook into a single git repository
+1. As a standalone executable
+2. As a git hook as a global [git hook template](https://git-scm.com/docs/git-init#_template_directory) and a CLI utility (for git repo scanning)
+3. As a git hook into a single git repository
Talisman can be set up as either a pre-commit or pre-push hook on the git repositories.
@@ -64,11 +62,34 @@ Find the instructions below.
*Disclaimer: Secrets creeping in via a forced push in a git repository cannot be detected by Talisman. A forced push is believed to be notorious in its own ways, and we suggest git repository admins to apply appropriate measures to authorize such activities.*
+## Install onto path (recommended approach)
+
+We recommend installing `talisman` onto your path so that it is available for
+git hook frameworks and scripts. Pick the correct binary for your system from
+our [Releases Page](https://github.com/thoughtworks/talisman/releases), or run
+our [install script](https://github.com/thoughtworks/talisman/blob/main/install.sh):
+
+```
+bash -c "$(curl --silent https://raw.githubusercontent.com/thoughtworks/talisman/main/install.sh)"
+```
+
+Or set environment variable `INSTALL_LOCATION` to specify a custom location for
+the binary:
+
+```
+INSTALL_LOCATION=/usr/local/bin bash -c "$(curl --silent https://raw.githubusercontent.com/thoughtworks/talisman/main/install.sh)"
+```
+
+Or using linuxbrew in Linux and homebrew in macOS by running the following
+command in terminal:
+
+```
+brew install talisman
+```
-## [Recommended approach]
## Installation as a global hook template
-We recommend installing Talisman as a **pre-commit git hook template**, as that will cause
+We offer scripts that will install Talisman as a **pre-commit git hook template**, as that will cause
Talisman to be present, not only in your existing git repositories, but also in any new repository that you 'init' or
'clone'.
@@ -96,90 +117,11 @@ bash -c "$(curl --silent https://thoughtworks.github.io/talisman/scripts/install
If you choose to set the `$PATH` later, please export TALISMAN\_HOME=$HOME/.talisman/bin to the path.
-3. Choose a base directory where Talisman should scan for all git repositories, and setup a git hook (pre-commit or pre-push, as chosen in step 1) as a symlink.
- This script will not clobber pre-existing hooks. If you have existing hooks, [look for ways to chain Talisman into them.](#handling-existing-hooks)
+3. Choose a base directory where Talisman should scan for all git repositories, and set up a git hook (pre-commit or pre-push, as chosen in step 1) as a symlink.
+ This script will not clobber pre-existing hooks. If you have existing hooks you can add talisman through a [hook framework](#using-with-hook-frameworks)
- you can set SEARCH_ROOT environment variable with the path of the base directory before executing the installation so you don't need to input it manually during the installation
-
-#### Alternative installation using brew
-
-Talisman can also be installed using linuxbrew in Linux and homebrew in macOS by running the following command in terminal
-
- ```
-brew install talisman
-```
-
-
-### Handling existing hooks
-Installation of Talisman globally does not clobber pre-existing hooks on repositories.
-If the installation script finds any existing hooks, it will only indicate so on the console.
-To achieve running multiple hooks we suggest (but not limited to) the following two tools
-
-#### 1. Pre-commit (Linux/Unix)
-Use [pre-commit](https://pre-commit.com) tool to manage all the existing hooks along with Talisman.
-In the suggestion, it will prompt the following code to be included in .pre-commit-config.yaml
-
-```
- - repo: local
- hooks:
- - id: talisman-precommit
- name: talisman
- entry: bash -c 'if [ -n "${TALISMAN_HOME:-}" ]; then ${TALISMAN_HOME}/talisman_hook_script pre-commit; else echo "TALISMAN does not exist. Consider installing from https://github.com/thoughtworks/talisman . If you already have talisman installed, please ensure TALISMAN_HOME variable is set to where talisman_hook_script resides, for example, TALISMAN_HOME=${HOME}/.talisman/bin"; fi'
- language: system
- pass_filenames: false
- types: [text]
- verbose: true
-```
-
-#### 2. Husky (Linux/Unix/Windows)
-[husky](https://typicode.github.io/husky) is an npm module for managing git hooks.
-In order to use husky, make sure you have already set TALISMAN_HOME to `$PATH`.
-
-+ **Existing Users**
-
- If you already are using husky, add the following lines to husky pre-commit in package.json
-
- ###### Windows
-
- ```
- "bash -c '\"%TALISMAN_HOME%\\${TALISMAN_BINARY_NAME}\" --githook pre-commit'"
-```
-
- ###### Linux/Unix
-
- ```
- $TALISMAN_HOME/talisman_hook_script pre-commit
-```
-+ **New Users**
-
- If you want to use husky with multiple hooks along with talisman, add the following snippet to you package json.
-###### Windows
-
- ```
- {
- "husky": {
- "hooks": {
- "pre-commit": "bash -c '\"%TALISMAN_HOME%\\${TALISMAN_BINARY_NAME}\" --githook pre-commit'" && "other-scripts"
- }
- }
- }
-```
-
- ###### Linux/Unix
-
- ```
- {
- "husky": {
- "hooks": {
- "pre-commit": "$TALISMAN_HOME/talisman_hook_script pre-commit" && "other-scripts"
- }
- }
- }
-```
-
-
-
## Installation to a single project
```bash
@@ -197,24 +139,41 @@ cd my-git-project
~/install-talisman.sh pre-commit
```
-### Handling existing hooks
-Talisman will need to be chained with any existing git hooks.You can use [pre-commit](https://pre-commit.com) git hooks framework to handle this.
+*Disclaimer: Talisman cannot guarantee its functionality in Microsoft's unsupported versions of Windows. Anyway Talisman is successfully tested on Windows 7 and server 2008 R2, which might not work in future releases.*
+
+# Using with hook frameworks
+
+Globally installing talisman as a hook will not clobber any existing hooks. If
+the installation script finds any existing hooks, it will only indicate so on
+the console. To run multiple hooks we suggest using a hook framework, such as
+pre-commit or husky. These instructions assume that the talisman executable is
+installed somewhere on your system's path.
+
+## Pre-commit
-Add this to your `.pre-commit-config.yaml` (be sure to update `rev` to point to
-a real git revision!)
+Use [pre-commit](https://pre-commit.com) tool to manage all the existing hooks
+along with Talisman. In the suggestion, it will prompt the following code to be
+included in .pre-commit-config.yaml:
```yaml
- repo: https://github.com/thoughtworks/talisman
rev: 'v1.28.0' # Update me!
hooks:
- # either `commit` or `push` support
- # - id: talisman-push
- - id: talisman-commit
- entry: cmd --githook pre-commit
-
+ # both pre-commit and pre-push supported
+ # - id: talisman-push
+ - id: talisman-commit
+ entry: cmd --githook pre-commit
```
-*Disclaimer: Talisman cannot guarantee its functionality in Microsoft's unsupported versions of Windows. Anyway Talisman is successfully tested on Windows 7 and server 2008 R2, which might not work in future releases.*
+## Husky
+
+[husky](https://typicode.github.io/husky) is an npm module for managing hooks.
+Add the following line to the husky pre-commit configuration in your
+`package.json`:
+
+```
+talisman --githook pre-commit
+```
# Upgrading
Since release v0.4.4, Talisman automatically updates the binary to the latest release, when the hook is invoked (at pre-commit/pre-push, as set up). So, just sit back, relax, and keep using the latest Talisman without any extra efforts.
@@ -504,8 +463,8 @@ To run the checksum please "cd" into the root of your repository and run the fol
For Example:
`talisman --checksum="*.pem *.txt"`
-1. This command finds all the .pem files in the respository and calculates collective checksum of all those files and outputs a yaml format for .talismanrc. In the same way it deals with the .txt files.
-2. Multiple file names / patterns can be given with space seperation.
+1. This command finds all the .pem files in the repository and calculates collective checksum of all those files and outputs a yaml format for .talismanrc. In the same way it deals with the .txt files.
+2. Multiple file names / patterns can be given with space separation.
Example output:
@@ -591,6 +550,6 @@ When you installed Talisman, it must have created a pre-commit or pre-push hook
You can remove the hook manually by deleting the Talisman pre-commit or pre-push hook from .git/hooks folder in repository.
-## Contributing to Talisman
+# Contributing to Talisman
To contribute to Talisman, have a look at our [contributing guide](contributing.md).
diff --git a/install.sh b/install.sh
index 89b30327..dc1fb7b4 100755
--- a/install.sh
+++ b/install.sh
@@ -1,256 +1,138 @@
#!/bin/bash
-# Hello there! If you update the talisman version, please remember to:
-# - Test that this script works with no args, and the `pre-push` / `pre-commit` arg.
-# - also update `install.sh` in the gh_pages branch of this repo, so that
-# gets updated too.
-# Thanks!
-
set -euo pipefail
-DEBUG=${DEBUG:-''}
-HOOK_NAME="${1:-pre-push}"
-case "$HOOK_NAME" in
-pre-commit | pre-push) REPO_HOOK_TARGET=".git/hooks/${HOOK_NAME}" ;;
-*)
- echo "Unknown Hook name '${HOOK_NAME}'. Please check parameters"
- exit 1
- ;;
-esac
-
-# we call run() at the end of the script to prevent inconsistent state in case
-# user runs with curl|bash and curl fails in the middle of the download
-# (https://www.seancassidy.me/dont-pipe-to-your-shell.html)
-run() {
- declare TALISMAN_BINARY_NAME
-
- IFS=$'\n'
-
- GITHUB_URL="https://github.com/thoughtworks/talisman"
- VERSION=$(curl --silent "https://api.github.com/repos/thoughtworks/talisman/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
- BINARY_BASE_URL="$GITHUB_URL/releases/download/$VERSION"
- REPO_HOOK_BIN_DIR=".git/hooks/bin"
-
- DEFAULT_GLOBAL_TEMPLATE_DIR="$HOME/.git-templates"
-
- declare DOWNLOADED_BINARY
- TEMP_DIR=$(mktemp -d 2>/dev/null || mktemp -d -t 'talisman_setup')
- trap "rm -r ${TEMP_DIR}" EXIT
- chmod 0700 ${TEMP_DIR}
-
- E_HOOK_ALREADY_PRESENT=1
- E_CHECKSUM_MISMATCH=2
- E_USER_CANCEL=3
- E_HEADLESS=4
- E_UNSUPPORTED_ARCH=5
- E_DEPENDENCY_NOT_FOUND=6
-
- echo_error() {
- echo -ne $(tput setaf 1) >&2
- echo "$1" >&2
- echo -ne $(tput sgr0) >&2
- }
- export -f echo_error
+declare BINARY_NAME
- function echo_debug() {
- [[ -z "${DEBUG}" ]] && return
- echo -ne $(tput setaf 3) >&2
- echo "$1" >&2
- echo -ne $(tput sgr0) >&2
- }
- export -f echo_debug
+E_UNSUPPORTED_ARCH=5
+CHECKSUM_FILE_NAME='checksums'
- echo_success() {
- echo -ne $(tput setaf 2)
- echo "$1" >&2
- echo -ne $(tput sgr0)
- }
- export -f echo_success
-
- operating_system() {
- OS=$(uname -s)
- case $OS in
- "Linux")
- echo "linux"
- ;;
- "Darwin")
- echo "darwin"
- ;;
- MINGW32_NT-*)
- echo "windows"
- ;;
- MINGW64_NT-*)
- echo "windows"
- ;;
- MINGW64_NT-6.3*)
- echo "windows"
- ;;
- *)
- echo_error "Talisman currently only supports Windows, Linux and MacOS(darwin) systems."
- echo_error "If this is a problem for you, please open an issue: https://github.com/${INSTALL_ORG_REPO}/issues/new"
- exit $E_UNSUPPORTED_ARCH
- ;;
- esac
+DEBUG=${DEBUG:-''}
+VERSION=${VERSION:-'latest'}
+INSTALL_ORG_REPO=${INSTALL_ORG_REPO:-'thoughtworks/talisman'}
+INSTALL_LOCATION=${INSTALL_LOCATION:-'/usr/local/bin'}
+
+function echo_error() {
+ echo -ne "$(tput setaf 1)" >&2
+ echo "$1" >&2
+ echo -ne "$(tput sgr0)" >&2
}
- binary_arch_suffix() {
- declare OS
- OS=$(operating_system)
- ARCH=$(uname -m)
- case $ARCH in
- "x86_64")
- OS="${OS}_amd64"
- ;;
- "i686" | "i386")
- OS="${OS}_386"
- ;;
- "arm64")
- OS="${OS}_arm64"
- ;;
- *)
- echo_error "Talisman currently only supports x86 and x86_64 architectures."
- echo_error "If this is a problem for you, please open an issue: https://github.com/thoughtworks/talisman/issues/new"
- exit $E_UNSUPPORTED_ARCH
- ;;
- esac
-
- TALISMAN_BINARY_NAME="talisman_${OS}"
- if [[ $OS == *"windows"* ]]; then
- TALISMAN_BINARY_NAME="${TALISMAN_BINARY_NAME}.exe"
- fi
- }
-
- function download() {
- OBJECT=$1
- DOWNLOAD_URL=${BINARY_BASE_URL}/${OBJECT}
- echo "Downloading ${OBJECT} from ${DOWNLOAD_URL}"
- curl --location --silent ${DOWNLOAD_URL} >"$TEMP_DIR/${OBJECT}"
- }
-
- function verify_checksum() {
- FILE_NAME=$1
- CHECKSUM_FILE_NAME='checksums'
- echo_debug "Verifying checksum for ${FILE_NAME}"
- download ${CHECKSUM_FILE_NAME}
-
- pushd ${TEMP_DIR} >/dev/null 2>&1
- grep ${TALISMAN_BINARY_NAME} ${CHECKSUM_FILE_NAME} >${CHECKSUM_FILE_NAME}.single
-
- if ! command -v shasum &> /dev/null; then
- sha256sum -c ${CHECKSUM_FILE_NAME}.single
- else
- shasum -a 256 -c ${CHECKSUM_FILE_NAME}.single
- fi
- popd >/dev/null 2>&1
- echo_debug "Checksum verification successful!"
- echo
- }
-
- function download_and_verify() {
- binary_arch_suffix
- download "${TALISMAN_BINARY_NAME}"
- DOWNLOADED_BINARY="${TEMP_DIR}/${TALISMAN_BINARY_NAME}"
- verify_checksum "${TALISMAN_BINARY_NAME}"
- }
-
- install_to_repo() {
- if [[ -x "$REPO_HOOK_TARGET" ]]; then
- echo_error "Oops, it looks like you already have a ${HOOK_NAME} hook installed at '${REPO_HOOK_TARGET}'."
- echo_error "If this is expected, you should consider setting-up a tool to allow git hook chaining,"
- echo_error "like pre-commit (brew install pre-commit) or Husky or any other tool of your choice."
- echo_error "WARNING! Talisman hook not installed."
- exit $E_HOOK_ALREADY_PRESENT
- fi
-
- download_and_verify
-
- mkdir -p "$REPO_HOOK_BIN_DIR"
- TALISMAN_BIN_TARGET="${REPO_HOOK_BIN_DIR}/talisman"
- cp "$DOWNLOADED_BINARY" "$TALISMAN_BIN_TARGET"
- chmod +x "$TALISMAN_BIN_TARGET"
-
- cat >"$REPO_HOOK_TARGET" <&2
+ echo "$1" >&2
+ echo -ne "$(tput sgr0)" >&2
+}
- TEMPLATE_DIR=$(git config --global init.templatedir) || true
+function echo_success() {
+ echo -ne "$(tput setaf 2)"
+ echo "$1" >&2
+ echo -ne "$(tput sgr0)"
+}
- echo "Not running from inside a git repository... installing as a"
- echo "git template."
- echo
- echo "If you meant to install to a specific repo, 'cd' into that"
- echo "repo and run this script again."
- echo
- echo "Installing as a template will automatically add Talisman to"
- echo "any new repo that you 'init' or 'clone'."
- echo
+function operating_system() {
+ OS=$(uname -s)
+ case $OS in
+ "Linux")
+ echo "linux"
+ ;;
+ "Darwin")
+ echo "darwin"
+ ;;
+ MINGW32_NT-* | MINGW64_NT-* | MSYS_NT-*)
+ echo "windows"
+ ;;
+ *)
+ echo_error "Talisman currently only supports Windows, Linux, and MacOS (darwin) systems."
+ echo_error "If this is a problem for you, please open an issue: https://github.com/$INSTALL_ORG_REPO/issues/new"
+ exit $E_UNSUPPORTED_ARCH
+ ;;
+ esac
+}
- if [[ "$TEMPLATE_DIR" == "" ]]; then
- echo "No git template directory is configured. Let's add one."
- echo "(this will override any system git templates and modify your git config file)"
- echo
- read -u1 -p "Git template directory: ($DEFAULT_GLOBAL_TEMPLATE_DIR) " TEMPLATE_DIR
- echo
- TEMPLATE_DIR=${TEMPLATE_DIR:-$DEFAULT_GLOBAL_TEMPLATE_DIR}
- git config --global init.templatedir $TEMPLATE_DIR
- else
- echo "You already have a git template directory configured."
- echo
- read -u1 -p "Add Talisman to '$TEMPLATE_DIR/hooks?' (Y/n) " USE_EXISTING
- echo
+function architecture() {
+ ARCH=$(uname -m)
+ case $ARCH in
+ "x86_64")
+ echo "amd64"
+ ;;
+ "i686" | "i386")
+ echo "386"
+ ;;
+ "arm64" | "aarch64")
+ echo "arm64"
+ ;;
+ *)
+ echo_error "Talisman currently only supports x86 and x86_64 and arm64 architectures."
+ echo_error "If this is a problem for you, please open an issue: https://github.com/$INSTALL_ORG_REPO/issues/new"
+ exit $E_UNSUPPORTED_ARCH
+ ;;
+ esac
+}
- case "$USE_EXISTING" in
- Y | y | "") ;; # okay, continue
- *)
- echo_error "Not installing Talisman."
- echo_error "If you were trying to install into a single git repo, re-run this command from that repo."
- echo_error "You can always download/compile manually from our Github page: $GITHUB_URL"
- exit $E_USER_CANCEL
- ;;
- esac
- fi
+function set_binary_name() {
+ BINARY_NAME="talisman_$(operating_system)_$(architecture)"
+ if [ "$(operating_system)" = "windows" ]; then
+ BINARY_NAME="$BINARY_NAME.exe"
+ fi
+ echo_success "Selected $BINARY_NAME"
+}
- # Support '~' in path
- TEMPLATE_DIR=${TEMPLATE_DIR/#\~/$HOME}
+function download() {
+ ASSETS=$(curl -Ls https://api.github.com/repos/"$INSTALL_ORG_REPO"/releases/latest |
+ grep download_url | awk '{print $2}' | tr -d '"')
+ BINARY_URL=$(echo "$ASSETS" | grep "$BINARY_NAME")
+ CHECKSUM_URL=$(echo "$ASSETS" | grep $CHECKSUM_FILE_NAME)
+ echo_debug "Downloading $BINARY_NAME and from $BINARY_URL"
+ curl --location --silent "$BINARY_URL" >"$TEMP_DIR/$BINARY_NAME"
+ echo_debug "Downloading $CHECKSUM_FILE_NAME and from $CHECKSUM_URL"
+ curl --location --silent "$CHECKSUM_URL" >"$TEMP_DIR/$CHECKSUM_FILE_NAME"
+ echo_success "Downloaded talisman binary and checksums"
+}
- if [ -f "$TEMPLATE_DIR/hooks/${HOOK_NAME}" ]; then
- echo_error "Oops, it looks like you already have a ${HOOK_NAME} hook installed at '$TEMPLATE_DIR/hooks/${HOOK_NAME}'."
- echo_error "If this is expected, you should consider setting-up a tool to allow git hook chaining,"
- echo_error "like pre-commit (brew install pre-commit) or Husky or any other tool of your choice."
- echo_error "WARNING! Talisman hook not installed."
- exit $E_HOOK_ALREADY_PRESENT
- fi
+function verify_checksum() {
+ pushd "$TEMP_DIR" >/dev/null 2>&1
- mkdir -p "$TEMPLATE_DIR/hooks"
+ if ! command -v shasum &> /dev/null; then
+ sha256sum --ignore-missing -c $CHECKSUM_FILE_NAME
+ else
+ shasum -a 256 --ignore-missing -c $CHECKSUM_FILE_NAME
+ fi
- download_and_verify
+ popd >/dev/null 2>&1
+ echo_success "Checksum OK"
+}
- cp "$DOWNLOADED_BINARY" "$TEMPLATE_DIR/hooks/${HOOK_NAME}"
- chmod +x "$TEMPLATE_DIR/hooks/${HOOK_NAME}"
+function install() {
+ if (touch "$INSTALL_LOCATION/$BINARY_NAME" &>/dev/null); then
+ cp "$TEMP_DIR/$BINARY_NAME" "$INSTALL_LOCATION/$BINARY_NAME"
+ chmod +x "$INSTALL_LOCATION/$BINARY_NAME"
+ ln -s "$INSTALL_LOCATION/$BINARY_NAME" "$INSTALL_LOCATION/talisman"
+ elif (which sudo &>/dev/null); then
+ sudo cp "$TEMP_DIR/$BINARY_NAME" "$INSTALL_LOCATION/$BINARY_NAME"
+ sudo chmod +x "$INSTALL_LOCATION/$BINARY_NAME"
+ sudo ln -s "$INSTALL_LOCATION/$BINARY_NAME" "$INSTALL_LOCATION/talisman"
+ else
+ echo_error "Insufficient permission to install to $INSTALL_LOCATION"
+ exit 126
+ fi
+}
- echo_success "Talisman successfully installed."
- }
+function run() {
+ TEMP_DIR=$(mktemp -d 2>/dev/null || mktemp -d -t 'talisman_setup')
+ # shellcheck disable=SC2064
+ trap "rm -r $TEMP_DIR" EXIT
+ chmod 0700 "$TEMP_DIR"
- if [ ! -d "./.git" ]; then
- install_to_git_templates
- else
- install_to_repo
+ if [ ! -d "$INSTALL_LOCATION" ]; then
+ echo_error "$INSTALL_LOCATION is not a directory!"
+ exit 1
fi
+
+ set_binary_name
+ download
+ verify_checksum
+ install
}
-run $0 $@
+run