CVS home dir

A small bash script to be run from your .bashrc. This is practical for multi-homed users - like myself - to keep ssh authorized keys, bookmarks, bash settings, aliases, etc. in sync amongst different accounts.

#!/bin/bash
#
# CVSHOME - small BASH script to be run from your .bashrc
# this is practical for multi-homed users - like myself -
# to keep ssh authorized keys, bookmarks, bash settings, 
# aliases, etc. in sync amongst different accounts.
#
# GPLv2 by Erno Rigo <mcree AT tricon DOT hu>
#
 
# you should place these exports in an external 
# file if you are planning to keep cvshome itself 
# in its own CVS repository!
 
export CVS_RSH=ssh # enter your favorite RSH here
export CVSROOT=:ext:tricon.hu/var/lib/cvs # enter your CVSROOT here... I'm combinig ssh-keychain with this so it's quite convenient - for me 8)
 
export CVSHOME_ROOT=~mcree/.cvshome_root # local scratchpad
export CVSHOME_FILES="/home/mcree/.bashrc /home/mcree/.crontab" # files to keep in cvs
export CVSHOME_SAFEFILES="/home/mcree/.ssh/authorized_keys2" # files to keep in cvs, keeps user asked before upgrades
export CVSHOME_KEY="trallalala" # cvs repository "key" - you should share this amongst your homes
export CVSHOME_EDITOR="$EDITOR" # your favourite editor (used for conflict management)
#export CVSHOME_DEBUG="yes" # comment out to disable DEBUG messages (recommended)
export CVSHOME_NOTICE="yes" # comment out to disable NOTICE messages (not recommended)
 
######################################################################################
# BEWARE - DO NOT CROSS THIS LINE
#
 
cvshome_debug() {
    if [ $CVSHOME_DEBUG ]; then 
	echo `date`" cvshome: DEBUG: "$@
    fi
}
 
cvshome_fatal() {
    echo `date`" cvshome: FATAL: "$@
}
 
cvshome_notice() {
    if [ $CVSHOME_NOTICE ]; then 
	echo `date`" cvshome: NOTICE: "$@
    fi
}
 
cvshome_update_base() {
    #copy files if they differ
    cvshome_debug "searching for repo changes..."
    for file in $CVSHOME_FILES; do 
	if ! cmp "$file" "$CVSHOME_ROOT"/repo/"$file" > /dev/null; then
    	    cvshome_debug "changed in repo: $file"
	    cp "$CVSHOME_ROOT"/repo/"$file" $file
	    touch "$CVSHOME_ROOT"/need_commit
	fi
    done	
 
    #take account of safe files
    for file in $CVSHOME_SAFEFILES; do 
	if ! cmp "$file" "$CVSHOME_ROOT"/repo/"$file" > /dev/null; then
    	    cvshome_debug "changed in repo (SAFE): $file"
	    mkdir -p "$CVSHOME_ROOT"/safe
	    cp --parents "$file" "$CVSHOME_ROOT"/safe
	    touch "$CVSHOME_ROOT"/need_commit
	fi
    done	
}
 
cvshome_update_repo() {
    #copy files if they differ
    cvshome_debug "searching for local changes..."
    for file in $CVSHOME_FILES $CVSHOME_SAFEFILES; do 
	if ! cmp "$file" "$CVSHOME_ROOT"/repo/"$file" > /dev/null; then
    	    cvshome_debug "changed locally: $file"
	    cp --parents $file "$CVSHOME_ROOT"/repo	
	    touch "$CVSHOME_ROOT"/need_commit
	fi
    done	
 
}
 
cvshome_update() {
    if [ -f "$CVSHOME_ROOT"/update_failed ]; then
	cvshome_fatal "last update failed, need manual cleanup!"
	return 0
    fi
    cvshome_update_repo
    cvshome_debug "uptading from repo..."
    pushd "$CVSHOME_ROOT"/repo > /dev/null
    updateres=`cvs -Q update -A 2>&1`
    if [ ! -z "$updateres"  ]; then
	cvshome_fatal "cannot update: $updateres"
	touch "$CVSHOME_ROOT"/update_failed
	return 0
    fi
    popd > /dev/null
    cvshome_update_base
    cvshome_commit
}
 
cvshome_commit() {
    if [ -f "$CVSHOME_ROOT"/need_commit ]; then
	cvshome_debug "commiting..."
	pushd "$CVSHOME_ROOT"/repo > /dev/null
	cvs -Q commit -m `date +%s`
	popd > /dev/null
	rm -f "$CVSHOME_ROOT"/need_commit
    else
	cvshome_debug "no need to commit."
    fi
}
 
 
cvshome_bg() {
    cvshome_debug "background init..."
    mkdir -p "$CVSHOME_ROOT"
 
    export CVSHOME_REPO="cvshome_"$CVSHOME_KEY
 
    if [ ! -d "$CVSHOME_ROOT"/repo ]; then
	cvshome_debug "no local copy present trying to checkout..."
	pushd "$CVSHOME_ROOT" > /dev/null
	cvs -Q checkout -d repo -D now "$CVSHOME_REPO" 2>/dev/null 1>/dev/null
	popd > /dev/null
    fi
 
    if [ ! -d "$CVSHOME_ROOT"/repo ]; then
 
	cvshome_debug "no existing repository... creating one for you"
	mkdir -p "$CVSHOME_ROOT"/"$CVSHOME_REPO"
 
	for file in $CVSHOME_FILES $CVSHOME_SAFEFILES; do 
	    cvshome_debug "initial copy: $file"
	    cp --parents $file "$CVSHOME_ROOT"/"$CVSHOME_REPO"
	done	
 
	cvshome_debug "importing..."
	pushd "$CVSHOME_ROOT"/"$CVSHOME_REPO" > /dev/null
	cvs -Q import -m "initial" "$CVSHOME_REPO" "$CVSHOME_REPO" "initial" 
	popd > /dev/null
 
	cvshome_debug "checking out..."
	pushd "$CVSHOME_ROOT" > /dev/null
	cvs -Q checkout -d repo -D now "$CVSHOME_REPO"
	popd > /dev/null
 
	if [ ! -d "$CVSHOME_ROOT"/repo ]; then
	    cvshome_fatal "cannot checkout: cvs checkout -d repo -D now $CVSHOME_REPO"
	    return 0
	fi
 
	rm -rf "$CVSHOME_ROOT"/"$CVSHOME_REPO"
 
	cvshome_notice "new repository was created as $CVSHOME_REPO"
    fi
 
    cvshome_update
}
 
cvshome_prompt() {
    while read -p "$1 ["`echo "$2" | tr ' ' '/' `"] " ans; do
	for pos in $2; do
	    if [ "$pos" == "$ans" ]; then
		echo "$ans"
		return;
	    fi
	done
    done
}
 
cvshome_init() {
 
    # check for CVS conflicts
    if [ -f "$CVSHOME_ROOT"/update_failed ]; then
	cvshome_debug "previous update failed, searching for conflicts..."
	corrfile=`mktemp`
        echo "no" > $corrfile;
	exec 3<&0
	find "$CVSHOME_ROOT"/repo -regex ".*/Entries" | while read file; do 
	    grep -h "/[^/]*/[^/]*/[^+/]*+[^/]*/" "$file" | while read entry; do
		realdir=`dirname "$file"`
		realdir=`dirname "$realdir"`
		realfile="$realdir/"`echo "$entry" | cut -f2 -d '/'`
		ans=`cvshome_prompt "CVS conflict detected in: $realfile. Correct it?" "yes no" <&3`
		if [ "$ans" == "yes" ]; then
		    $CVSHOME_EDITOR "$realfile" <&3
		else
		    echo "yes" > $corrfile;
		fi
	    done
	done
	exec 3>&-
	if [ `cat $corrfile` == "no" ]; then
	    rm -f "$CVSHOME_ROOT"/update_failed
	fi
	rm -f $corrfile
    fi
 
    # check for changed SAFE files
    if [ -d "$CVSHOME_ROOT"/safe ]; then
	cvshome_debug "searching for changed SAFE files..."
	pushd "$CVSHOME_ROOT"/safe >/dev/null
	exec 3<&0
	find . -type f | while read file; do
	    diff -ruN "/$file" "$CVSHOME_ROOT"/repo/"$file"
	    ans=`cvshome_prompt "SAFE file changed: $file. Update locally?" "yes no abort" <&3`
	    if [ "$ans" == "abort" ]; then
		touch "$CVSHOME_ROOT"/update_failed
	    elif [ "$ans" == "no" ]; then
		cvshome_notice "forcing local file version to CVS"
		cp --parents "/$file" "$CVSHOME_ROOT"/repo/"$file"
		touch "$CVSHOME_ROOT"/need_commit
	    else
		cvshome_notice "upgrading file from CVS"
		rm -f "$CVSHOME_ROOT"/safe/"$file"
	    fi
	done
	exec 3>&-
	popd >/dev/null
    fi
}
 
# actions requiring user interaction
cvshome_init
# start background processing... for faster prompts 8)
cvshome_bg &

Linkbacks

Use the following URL for manually sending trackbacks: http://rigo.info/lib/plugins/linkback/exe/trackback.php/en:blog:cvs_home_dir
en/blog/cvs_home_dir.txt · Utolsó módosítás: 2009-04-14 00:00 (külső szerkesztés)
CC Attribution-Noncommercial-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0