Last active
December 20, 2019 16:05
-
-
Save sneppy/94a3cf95b7cebd9602e368c73e8e3a38 to your computer and use it in GitHub Desktop.
A simple shell script based on splitsh-lite to sync split repos with the parent monorepo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#================================ | |
# A git subtree util to split | |
# a packagist monorepo in multiple | |
# manyrepos and sync version (tags) | |
# | |
# Usage: | |
# Download the script and call it | |
# inside the root folder of your | |
# master repo | |
# | |
# You must specify the folder in | |
# which to find the modules with | |
# -P <path> | |
# | |
# By default, the master branch | |
# is used as the target. To change | |
# this use -b <target_branch>. Tag | |
# and changes are pulled from the | |
# current local active branch | |
#================================ | |
#-------------------------------- | |
# Variables | |
# Parse arguments | |
while getopts ":s:P:b:" o; do | |
case "$o" in | |
P) PREFIX=$OPTARG;; | |
b) TARGET_BRANCH=$OPTARG;; | |
*) exit 0 | |
esac | |
done | |
# Remove redundant slash from prefix | |
PREFIX="${PREFIX%/}" | |
# Currently active local branch | |
LOCAL_ACTIVE_BRANCH=$(git rev-parse --abbrev-ref HEAD) | |
# Default active branch | |
: "${TARGET_BRANCH:=master}" | |
#-------------------------------- | |
# Functions | |
# Log message | |
# | |
# $1 content to log | |
# $2 file to log to | |
log () { | |
file="$2" | |
if [ -n "$file" -a -e "$file" ]; then | |
echo "$1" >> "$file" | |
else | |
echo "$1" | |
fi | |
} | |
# Notify error and exit | |
# | |
# $1 error message | |
# $2 file to write to | |
err () { | |
file="$2" | |
if [ -n "$file" -a -e "$file" ]; then | |
echo "$1" >> "$file" | |
else | |
echo "$1" >&2 | |
fi | |
# Exit with code 1 | |
exit 1 | |
} | |
# Convert input to lower case | |
# | |
# $1 content | |
lc () { | |
if [ -n "$1" ]; then | |
echo "$1" | tr "[:upper:]" "[:lower:]" | |
fi | |
} | |
# Split module | |
# Push changes and tags | |
# | |
# $1 folder path | |
# $2 module name (also branch and remote name) | |
split () { | |
path="$1" | |
module="$2" | |
log "\n" | |
log "=== $module ===" | |
log "\n" | |
# Run splitsh-lite | |
splitsh-lite --prefix="${path}" --target=refs/heads/"${module}" \ | |
|| err "fatal: could not split ${path} as ${module}" | |
log "✓ split ${path} as ${module}" | |
# Push changes | |
git push -f "$module" "${module}:${TARGET_BRANCH}" \ | |
|| err "fatal: could not push to ${module}/${TARGET_BRANCH}" | |
log "✓ pushed ${module} to ${module}/${TARGET_BRANCH}" | |
# If tag exists | |
if [ -n "$TAG" ]; then | |
# Push tag | |
git tag -f "$TAG" "$module" \ | |
|| err "fatal: could not tag to ${module} with tag ${TAG}" | |
log "✓ tagged ${module} with tag ${TAG}" | |
git push -f "$module" "$TAG" \ | |
|| err "fatal: could not push tag ${TAG} to ${module}/${TARGET_BRANCH}" | |
log "✓ pushed tag ${TAG} to ${module}/${TARGET_BRANCH}" | |
# Reset tag | |
git tag -f "$TAG" "$LOCAL_ACTIVE_BRANCH" | |
fi | |
} | |
# Iterate over prefixes | |
map () { | |
# Find all modules | |
for i in "${PREFIX}"/* ; do | |
path="$i" | |
# If path is directory | |
if [[ -d "$path" ]]; then | |
folder=$(basename "$i") | |
module=$(lc "$folder") | |
# Split | |
split "$path" "$module" | |
fi | |
done | |
} | |
#-------------------------------- | |
# Run | |
# Retrieve current tag | |
TAG=$(git describe --tags --abbrev=0) | |
# Iterate | |
map |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment