From 88938fa80a830248135f027ce137afda8967567b Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Sun, 11 Jan 2026 17:14:49 +0530 Subject: [PATCH 1/2] Add run-all command line tool --- run-all/README.md | 43 +++++++++++++++ run-all/install.sh | 63 +++++++++++++++++++++ run-all/run-all | 133 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 239 insertions(+) create mode 100644 run-all/README.md create mode 100644 run-all/install.sh create mode 100755 run-all/run-all diff --git a/run-all/README.md b/run-all/README.md new file mode 100644 index 0000000..9f159fa --- /dev/null +++ b/run-all/README.md @@ -0,0 +1,43 @@ +# run-all + +Run any command across multiple repositories. + +## Installation + +```bash +./install.sh +``` + +Or manually: + +```bash +chmod +x run-all +sudo cp run-all /usr/local/bin/ +``` + +## Usage + +```bash +run-all +``` + +### Options + +- `FOLDER=` - Starting folder (default: current directory) +- `MINDEPTH=` - Minimum search depth (default: 1) +- `MAXDEPTH=` - Maximum search depth (default: 3) +- `FILTER=` - Filter repositories by pattern + +### Examples + +```bash +run-all ls -la +run-all pwd +run-all git status +run-all git fetch +FOLDER=~/dev run-all git pull +FILTER='frontend|backend' run-all npm install +run-all make clean +``` + +For more options: `run-all --help` diff --git a/run-all/install.sh b/run-all/install.sh new file mode 100644 index 0000000..fd93b9b --- /dev/null +++ b/run-all/install.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# Installation script for run-all command-line tool + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SOURCE_FILE="${SCRIPT_DIR}/run-all" +INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}" +TARGET_FILE="${INSTALL_DIR}/run-all" + +echo -e "${YELLOW}Installing run-all command-line tool...${NC}" + +# Check if source file exists +if [ ! -f "${SOURCE_FILE}" ]; then + echo -e "${RED}Error: run-all file not found at ${SOURCE_FILE}${NC}" + exit 1 +fi + +# Check if install directory exists +if [ ! -d "${INSTALL_DIR}" ]; then + echo -e "${RED}Error: Install directory ${INSTALL_DIR} does not exist${NC}" + exit 1 +fi + +# Check if we need sudo +if [ ! -w "${INSTALL_DIR}" ]; then + SUDO="sudo" + echo -e "${YELLOW}Note: Installing to ${INSTALL_DIR} requires sudo privileges${NC}" +else + SUDO="" +fi + +# Make source file executable +echo "Making run-all executable..." +chmod +x "${SOURCE_FILE}" + +# Copy to install directory +echo "Copying run-all to ${INSTALL_DIR}..." +${SUDO} cp "${SOURCE_FILE}" "${TARGET_FILE}" + +# Verify installation +if [ -f "${TARGET_FILE}" ] && [ -x "${TARGET_FILE}" ]; then + echo -e "${GREEN}✓ Successfully installed run-all to ${TARGET_FILE}${NC}" + echo "" + echo -e "${GREEN}You can now use 'run-all' from anywhere!${NC}" + echo "" + echo "Examples:" + echo " run-all git status" + echo " FOLDER=~/dev run-all git fetch" + echo " FILTER='project' run-all git pull" + echo "" + echo "For more information, run: run-all --help" +else + echo -e "${RED}Error: Installation failed${NC}" + exit 1 +fi diff --git a/run-all/run-all b/run-all/run-all new file mode 100755 index 0000000..c297c5f --- /dev/null +++ b/run-all/run-all @@ -0,0 +1,133 @@ +#!/usr/bin/env bash + +# run-all - Run any command across multiple repositories +# +# Installation: +# chmod +x run-all +# sudo cp run-all /usr/local/bin/ +# or: ln -s $(pwd)/run-all /usr/local/bin/run-all + +colorize() { + printf "\x1b[${1}m" +} + +NC=$(colorize '0') # No Color +RED=$(colorize '0;31') +GREEN=$(colorize '0;32') +YELLOW=$(colorize '1;33') +BLUE=$(colorize '0;34') +CYAN=$(colorize '0;36') + +blue() { + printf "${BLUE}${1}${NC}" +} + +cyan() { + printf "${CYAN}${1}${NC}" +} + +green() { + printf "${GREEN}${1}${NC}" +} + +red() { + printf "${RED}${1}${NC}" +} + +yellow() { + printf "${YELLOW}${1}${NC}" +} + +if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + cat << EOF +$(red "** run-all - Run any command across multiple repositories **") + +$(yellow "USAGE:") + run-all [OPTIONS] + +$(yellow "DESCRIPTION:") + This tool finds all repositories within a specified folder (filtered by pattern) + and runs the specified command in each repository. + +$(yellow "OPTIONS:") + FOLDER= Starting folder to search (default: current directory) + MINDEPTH= Minimum depth for search (default: 1) + MAXDEPTH= Maximum depth for search (default: 3) + FILTER= Regex pattern to filter repository paths (default: none) + +$(yellow "EXAMPLES:") + run-all ls -la + run-all pwd + run-all git status + run-all git branch -vv + FOLDER=~/dev MINDEPTH=2 run-all git status + FOLDER=~/dev MINDEPTH=2 run-all npm install + FILTER=oss run-all git fetch + FILTER='oss|zsh|omz' run-all make test + +$(yellow "INSTALLATION:") + chmod +x run-all + sudo cp run-all /usr/local/bin/ + # or create a symlink: + sudo ln -s \$(pwd)/run-all /usr/local/bin/run-all +EOF + exit 0 +fi + +if [ $# -eq 0 ]; then + echo $(red "Error: No command specified") + echo "Use 'run-all --help' for usage information" + exit 1 +fi + +MINDEPTH=${MINDEPTH:-1} +MAXDEPTH=${MAXDEPTH:-3} +FOLDER="${FOLDER:-.}" +FILTER="${FILTER:-}" + +start_time=$(date +%s) +echo $(cyan "Script started at: $(date)") + +echo $(yellow "Finding git repos starting in folder '${FOLDER}' for a min depth of ${MINDEPTH} and max depth of ${MAXDEPTH}") +[ "${FILTER}" != '' ] && echo $(yellow "Filtering with: ${FILTER}") + +find_cmd=( + find "${FOLDER}" + -mindepth "${MINDEPTH}" -maxdepth "${MAXDEPTH}" + # Exclude specific directory patterns by pruning them + \( -path '*/tmp' -o -path '*/Library/Cache' \) -prune + # Or (-o), find .git directories, prune them (don't descend), and print their parent directory + -o + \( -name ".git" -type d -prune -exec dirname {} \; \) +) + +# Execute find, get parent directory, filter, and sort +# Use portable method instead of mapfile for compatibility +DIR_ARRAY=() +while IFS= read -r line; do + DIR_ARRAY+=("$line") +done < <("${find_cmd[@]}" 2>/dev/null | grep -iE "${FILTER}" | sort -u) + +TOTAL_COUNT=${#DIR_ARRAY[@]} + +if [ ${TOTAL_COUNT} -eq 0 ]; then + echo $(red "No git repositories found matching the criteria") + exit 0 +fi + +COUNT=1 +for dir in "${DIR_ARRAY[@]}"; do + if [ -d "${dir}" ] && [ ! -h "${dir}" ]; then + echo $(green ">>>>>>>>>>>>>>>>>>>>> [${COUNT} of ${TOTAL_COUNT}] '$*' (in '${dir}') <<<<<<<<<<<<<<<<<<<<") + # Use a subshell and "$@" for better argument handling and potentially less overhead than 'bash -c' + (cd "${dir}" && eval "$@") + COUNT=$((COUNT + 1)) + fi +done + +end_time=$(date +%s) +echo $(cyan "Script finished at: $(date)") + +duration=$((end_time - start_time)) +duration_formatted=$(printf "%02d:%02d:%02d" $((duration/3600)) $((duration%3600/60)) $((duration%60))) +echo $(cyan "Total execution time: ${duration_formatted} (HH:MM:SS)") From 8e36c0f08d86654c969c9be1a1da7e0a9d7531de Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Sun, 11 Jan 2026 17:25:39 +0530 Subject: [PATCH 2/2] Update main read me file --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e521aca..6e08024 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ -git_scripts -=========== +# git_scripts These are some scripts that I use constantly when dealing with multiple git repositories. To use, them, simply add the cloned folder to the `PATH` env var! ## run_all.sh ----------- + +--- + This script is typically run from the common parent directory. With the latest update, the `run_all.sh` script can be configured to run against any level of subdirectory. Examples: @@ -30,24 +31,59 @@ To see more features based on env vars (and a more complete description), please Note: **Any command can be run** (whether they are specific to the shell that you are currently using) or git commands. These commands are run within the context of each git repository that is matched after applying the filters. +### Command-line Tool: run-all + +A standalone command-line tool version is available in the [run-all](run-all/) directory. Install it system-wide for easier access: + +```bash +cd run-all +./install.sh +``` + +Then use from anywhere: + +```bash +run-all ls -la +run-all git status +FOLDER=~/dev run-all git fetch +``` + +See [run-all/README.md](run-all/README.md) for more details. + ![run_all.sh in action](./images/Screenshot.png "Screenshot of run_all.sh") ## clean_from_git_history ----------- + +--- + Script to permanently delete files/folders from your git repository. To use it, cd to your repository's root and then run the script with a list of paths you want to delete, e.g., `git-delete-history path1 path2` ## cleanup_all_gems ----------- + +--- + Script to cleanup all installed gems (if you do not want to simply delete the gem install directory) ## delete_merged_branches ----------- + +--- + After merging local changes into branches and pushing them to the respective remote-tracking branches, you might want to clean your local machine. This script is used to ensure the first is done and then will cleanly delete the synced branches from local. ## file_sizes ----------- + +--- + Script to see how much disk space each folder/item in your git repo is holding ## run_all.ps1 ----------- + +--- + Powershell clone of the `run_all.sh` - but, as yet, unmaintained since I do not have access to a Windows machine. + +## Contributors + +--- + +- [nvnkmrm](https://github.com/nvnkmrm)