From: Hugo Villeneuve Date: Thu, 17 Jul 2014 19:15:38 +0000 (-0400) Subject: Improve git-hg-sub-import to work with PROJRC and SUBPATHS X-Git-Url: http://gitweb.hugovil.com/?a=commitdiff_plain;h=d08b48276481596a71c4451b3667cd1de9abc3f7;p=hvutilities.git Improve git-hg-sub-import to work with PROJRC and SUBPATHS --- diff --git a/scripts/git-hg-sub-import b/scripts/git-hg-sub-import index 38f8621..4baf1bc 100755 --- a/scripts/git-hg-sub-import +++ b/scripts/git-hg-sub-import @@ -5,7 +5,10 @@ set -o errexit # http://felipec.wordpress.com/2012/11/13/git-remote-hg-bzr-2/ # Uncomment to have verbose debug output -debug=1 +#debug=1 + +PROJRC_COUNT=0 +SUBPATHS_COUNT=0 print_usage() { @@ -13,24 +16,118 @@ print_usage() echo "Usage: $(basename $0) [OPTIONS...]" } -# git-remote-hg doesn't work with Mercurial subpaths extension, -# so use it manually -hg_subpaths_config() { - subpaths=$(hg showconfig | grep "subpaths" | grep "HG_REPO") +# We parse the projrc file in the assembly (on the server), to check +# for any projrc substitutions. +# +# Arg 1: repository (path and name) +# +# Return the substitution key/values in arrays: +# PROJRC_KEY +# PROJRC_VAL +# PROJRC_COUNT will be greater than zero if any substitutions were found. +hg_parse_projrc() { + if [ ${#} -lt 1 ]; then + echo "Missing repository name" + fi + + # Repo name can have spaces in it, hence the use of ${*} + local repo_orig="${*}" + local repo="${*}" - echo "subpaths = ${subpaths}" + # Quote spaces + repo=${repo// /\\\\ } - if [ -n ${subpaths} ]; then - sp_src=${subpaths//subpaths./} - sp_src=${sp_src//=*/} - sp_src=${sp_src//\\/} # Remove windows separator (LSI) - sp_dst=${subpaths//*=/} + if [ -f "${repo}/.hg/projrc" ]; then + TMPF="/tmp/$(basename $0).projrc-$$.tmp" - if [ -n "${debug}" ]; then - echo "sp_src = $sp_src" - echo "sp_dst = $sp_dst" - fi + # Create temporary copy to replace backslashes with slashes. + # Make sure to only replace path backslashes, not backslashes for + # quoting spaces. + # \\[^ ] Match a backslash, not followed by a space + cat "${repo}/.hg/projrc" | sed 's/\\\([^ ]\)/\/\1/g' > ${TMPF} + + while read p; do + if echo ${p} | grep -q "\s=\s"; then + local key=$(echo ${p} | sed 's/^\(.*\) = .*/\1/') + local val=$(echo ${p} | sed 's/.* = \(.*\)/\1/') + + PROJRC_KEY[${PROJRC_COUNT}]="${key}" + PROJRC_VAL[${PROJRC_COUNT}]="${val}" + + if [ -n "${debug}" ]; then + echo "Parsing PROJRC entry: ${p}" + echo " key: ${key}" + echo " val: ${val}" + fi + + PROJRC_COUNT=$((PROJRC_COUNT + 1)) + fi + done < ${TMPF} + + rm ${TMPF} + fi +} + +# We parse the Mercurial configuration, to check +# for any SUBPATHS substitutions. +# +# Return the substitution key/values in arrays: +# SUBPATHS_KEY +# SUBPATHS_VAL +# SUBPATHS_COUNT will be greater than zero if any substitutions were found. +hg_parse_subpaths() { + subpaths=$(hg showconfig subpaths) + + if [ -n "${subpaths}" ]; then + for p in ${subpaths}; do + local key=$(echo ${p} | sed 's/^subpaths\.\(.*\)=.*/\1/') + local val=$(echo ${p} | sed 's/.*=\(.*\)/\1/') + + # Replace '\\' with '/' + key=${key//\\\\/\/} + # ^^ replace multiple times + + val=${val//\\\\/\/} + + SUBPATHS_KEY[${SUBPATHS_COUNT}]="${key}" + SUBPATHS_VAL[${SUBPATHS_COUNT}]="${val}" + + if [ -n "${debug}" ]; then + echo "Parsing SUBPATHS entry: ${p}" + echo " key: ${key}" + echo " val: ${val}" + fi + + SUBPATHS_COUNT=$((SUBPATHS_COUNT + 1)) + done + fi +} + +# Replace the given path with either entries from PROJRC or SUBPATHS +# Arg 1: path +apply_substitutions() { + # Repo name can have spaces in it, hence the use of ${*} + local path="${*}" + + if [ ${PROJRC_COUNT} -ne 0 ]; then + for s in $(seq 0 $((${PROJRC_COUNT} - 1))); do + local pattern=${PROJRC_KEY[${s}]} + local replacement=${PROJRC_VAL[${s}]} + + path=${path/${pattern}/${replacement}} + done fi + + if [ ${SUBPATHS_COUNT} -ne 0 ]; then + for s in $(seq 0 $((${SUBPATHS_COUNT} - 1))); do + local pattern=${SUBPATHS_KEY[${s}]} + local replacement=${SUBPATHS_VAL[${s}]} + + path=${path/${pattern}/${replacement}} + done + fi + + echo "${path}" } # git-remote-hg doesn't work with Mercurial projrc extension, @@ -115,7 +212,15 @@ if [ ! -f .gitignore ]; then echo ".gitignore" > .gitignore fi -hg_subpaths_config +asm=$(cat .git/config | grep "hg::" | sed "s/.*url = hg::\(.*\)/\1/") +hg_parse_projrc ${asm} + +hg_parse_subpaths + +HGSUB_TMP="/tmp/$(basename $0).hgsub-$$.tmp" + +# Create temporary copy to replace backslashes with slashes. +cat .hgsub | sed 's/\\/\//g' > ${HGSUB_TMP} # Read lines from .hgsub while read sub; do @@ -126,8 +231,12 @@ while read sub; do # Get subrepository URL src="${sub//*= /}" - # Replace using subpaths extension content - src=${src/${sp_src}/${sp_dst}} + # Replace using Mercurial subpaths substitutions (either projrc or from hgrc) + src=$(apply_substitutions ${src}) + + # Original name + repo=$(basename "${src}") + srcpath=$(dirname "${src}") # Get subrepository local alias or label dest="${sub// =*}" @@ -138,20 +247,12 @@ while read sub; do # Get revision of subrepository (remove CR from .hgsubstate) rev=$(cat .hgsubstate | tr -d '\r' | grep "${id}" | sed "s/ .*//") - # Original name - repo=$(basename "${src}") - srcpath=$(dirname "${src}") - - projrc_sub=$(hg_check_projrc_config "${src}") - src="${srcpath}/${projrc_sub}" - if [ -n "${debug}" ]; then echo "repo: ${repo}" - echo " path: ${srcpath}" - echo " id: ${id}" - echo " src: ${projrc_sub}" - echo " dest: ${dest}" - echo " rev: ${rev}" + echo " path: ${srcpath}" + echo " id: ${id}" + echo " local: ${dest}" + echo " rev: ${rev}" fi if [ ! -d "${dest}" ]; then @@ -197,4 +298,7 @@ while read sub; do fi fi fi -done < .hgsub +done < ${HGSUB_TMP} + +rm ${HGSUB_TMP} +