#! /bin/bash
#                               -*- Mode: Sh -*- 
# cvs-inject --- 
# Author           : Manoj Srivastava ( srivasta@tiamat.datasync.com ) 
# Created On       : Mon May 26 14:23:17 1997
# Created On Node  : tiamat.datasync.com
# Last Modified By : Manoj Srivastava
# Last Modified On : Wed Mar 22 01:15:46 2000
# Last Machine Used: glaurung.green-gryphon.com
# Update Count     : 297
# Status           : Unknown, Use with caution!
# HISTORY          : 
# Description      : 
# $Id: cvs-inject,v 1.20 2000/03/22 07:25:46 srivasta Exp $
# 

# Make sure we abort on error
set -e

declare -a argv

progname="`basename \"$0\"`"
pversion='$Revision: 1.20 $'

setq() {
    # Variable Value Doc string
    if [ "x$2" = "x" ]; then
	echo >&2 "$progname: Unable to determine $3"
	exit 1;
    else
	if [ ! "x$Verbose" = "x" ]; then
	    echo "$progname: $3 is $2";
	fi
	eval "$1=\"\$2\"";
    fi
}

withecho () {
        echo " $@" >&2
        "$@"
}

usageversion () {
        cat >&2 <<END
Usage: $progname  [options] <package>.dsc
Options: 
  -h           print this message
  -F           Force removal of CVS directories and symbolic links
               before import. This should be used with caution!!
  -M<module>   CVS module name.
  -R<root dir> Root directory.
  -W<work dir> Working directory.
  -d<digit>    Set Debug Level
  -n           "Dry-run" mode - No action taken, only print commands.
  -v           Make the command verbose
  -ctp         Include <package>_ at start of CVS tag.
  -x<prefix>   CVS default module prefix.

Note that the current behaviour of cvs-inject is to ignore any files
that match the default list of file name patterns to be ignored (this
is built into cvs); and that any .cvsignore files in the upstream
sources shall be honoured.

END
}

# We need a debian source control file
if [ $# = 0 ]; then
    usageversion; 
    exit 1;
fi

# The defaults
rootdir='/usr/local/src/Packages'
tmpdir="temp-$progname"

docmd='YES'
action='withecho'


DEBUG=0
VERBOSE=0

# parse Command line
while [ $# != 0 ]; do
    value="`echo x\"$1\" | sed -e 's/^x-.//'`"
    case "$1" in
        -h)  usageversion; exit 0          ;;
	-F)  opt_forceclean=1              ;;
        -M*) opt_cvsmodule="$value"        ;;
        -R*) opt_rootdir="$value"          ;;
        -W*) opt_workdir="$value"          ;;
	-n)  action='echo';docmd='NO'      ;;
	-v)  VERBOSE=1                     ;;
	-d*) opt_DEBUG="$value"            ;;
	-x*) opt_prefix="$value"           ;;
       -ctp) opt_packageintag=1            ;;
	-*) echo >&2 "Unknown option $1."
	    usageversion; exit 1           ;;
	*.dsc) 
	    if [ "X$opt_dsc" = "X" ]; then
		opt_dsc="$1";
	    else
		echo >&2 "I can only deal with one Debian Source Control"
		echo >&2 "file at a time. I think I already have one "
		echo >&2 "in $opt_dsc. So, whats this $1 ?"
		exit 1
	    fi
	    ;;
	*)  echo >&2 "Unknown argument $1. I understand only a"
	    echo >&2 "Debian Source Control file name as an argument"
	    usageversion; exit 1 ;;
    esac
    shift
done

CVS_QUIET="-Q"
TAR_QUIET=""

if [ $VERBOSE -gt 0 ]; then
    echo "Initializing ..."
    CVS_QUIET="-q"
    TAR_QUIET="v"
fi

# did the user specify a dsc file?
if [ "X$opt_dsc" = "X" ]; then
    echo "package descscription file needs to be specified" 1>&2
    usageversion; 
    exit 1
fi

if [ "X$CVSROOT" = "X" ]; then
    echo "You should have set the CVSROOT env variable."  1>&2
    usageversion; 
    exit 1
fi

# can we read the dsc file?
if [ ! -r $opt_dsc ]; then
    echo "package descscription file $opt_dsc is not available" 1>&2
    usageversion; 
    exit 1
fi

# Load site defaults and over rides.
if [ -f /etc/cvsdeb.conf ]; then
    . /etc/cvsdeb.conf
fi

# Load user defaults and over rides.
if [ -f ~/.cvsdeb.conf ]; then
    . ~/.cvsdeb.conf
fi

# If asked to debug on command line, that's what we get
if [ ! "x$opt_DEBUG" = "x" ]; then
    DEBUG="$opt_DEBUG"
fi

if [ "$DEBUG" -gt 0 ]; then
    CVS_QUIET=""
    TAR_QUIET="vv"
fi



# Command line, env variable, config file, or default
if [ ! "x$opt_rootdir" = "x" ]; then
    rootdir="$opt_rootdir"
elif [ ! "x$CVSDEB_ROOTDIR" = "x" ]; then
    rootdir="$CVSDEB_ROOTDIR"
elif [ ! "x$conf_rootdir" = "x" ]; then
    rootdir="$conf_rootdir"
fi

# Command line, env variable, config file, or default
if [ ! "x$opt_prefix" = "x" ]; then
    prefix="$opt_prefix"
elif [ ! "x$CVSDEB_PREFIX" = "x" ]; then
    prefix="$CVSDEB_PREFIX"
elif [ ! "x$conf_prefix" = "x" ]; then
    prefix="$conf_prefix"
else
    prefix=""
fi

# Command line, env variable, config file, or default
if [ ! "x$opt_packageintag" = "x" ]; then
    packageintag="$opt_packageintag"
elif [ ! "x$CVSDEB_PACKAGEINTAG" = "x" ]; then
    packageintag="$CVSDEB_PACKAGEINTAG"
elif [ ! "x$conf_packageintag" = "x" ]; then
    packageintag="$conf_packageintag"
else
    packageintag=""
fi



# put a slash at the end of the prefix
if [ "X$prefix" != "X" ]; then
    prefix="$prefix/";
    prefix=`echo $prefix | sed 's://:/:g'`;
fi


filename=`basename $opt_dsc .dsc`
package=`cat $opt_dsc | perl -wnle 'm/^\s*Source\s*:\s*(\S+)/io && print $1;'`
version=`cat $opt_dsc | perl -wnle 'm/^\s*Version\s*:\s*(\S+)/io && print $1;' | head -1`

# Command line, env variable, or default
if [ ! "x$opt_cvsmodule" = "x" ]; then
    cvsmodule="$opt_cvsmodule"
elif [ ! "x$CVSDEB_MODULE" = "x" ]; then
    cvsmodule="$CVSDEB_MODULE"
else
    cvsmodule="${prefix}$package"
fi

non_epoch_version=`echo "$version" | perl -pe 's/^\d+://'`
upstream_version=`echo "$non_epoch_version" | sed  -e 's/-[^-]*$//'`

cvstag=`echo "debian_version_$non_epoch_version" | tr . _ `
cvs_upstream_tag=`echo "upstream_version_$upstream_version" | tr . _ `
if [ "x$packageintag" != x ]; then
    cvstag="${package}_$cvstag"
    cvs_upstream_tag="${package}_$cvs_upstream_tag"
fi

if [ "X$version" != "X$upstream_version" ]; then
   debian_version=`echo $non_epoch_version|perl -nle 'm/-([^-]*)$/ && print $1'` 
   DEB_ONLY='FALSE'
else
    DEB_ONLY='TRUE'
fi

if [ $VERBOSE -gt 0 ]; then
    echo ""
    echo "Debian only package"
fi

if [ $DEBUG ]; then
    echo "package=${package} cvsmodule=$cvsmodule"
    echo "upstream_version=${upstream_version} "
    echo "cvs_upstream_tag=${cvs_upstream_tag} "
    if [ "X$DEB_ONLY" = "XTRUE" ]; then
	echo "Debian only package"
    else
	echo "debian_version=${debian_version} cvstag=${cvstag}"
    fi
fi

# Command line, env variable, config file, or default
if [ ! "x$opt_workdir" = "x" ]; then
    workdir="$opt_workdir"
elif [ ! "x$CVSDEB_WORKDIR" = "x" ]; then
    workdir="$CVSDEB_WORKDIR"
elif [ ! "x$conf_workdir" = "x" ]; then
    workdir="$conf_workdir"
else
    workdir="$rootdir/$package"
fi

# Command line, env variable, config file, or default
if [ ! "x$opt_forceclean" = "x" ]; then
    forceclean="$opt_forceclean"
elif [ ! "x$CVSDEB_FORCECLEAN" = "x" ]; then
    forceclean="$CVSDEB_FORCECLEAN"
elif [ ! "x$conf_forceclean" = "x" ]; then
    forceclean="$conf_forceclean"
else
    forceclean=""
fi

# Command line, env variable, config file, or default
if [ ! "x$opt_use_changelog" = "x" ]; then
    use_changelog="$opt_use_changelog"
elif [ ! "x$CVSDEB_USE_CHANGELOG" = "x" ]; then
    use_changelog="$CVSDEB_USE_CHANGELOG"
elif [ ! "x$conf_use_changelog" = "x" ]; then
    use_changelog="$conf_use_changelog"
else
    use_changelog=""
fi

# env variable, or default
if [ ! "x$CVSDEB_IMPORTSUBSTMODE" = "x" ]; then
    importsubstmode="$CVSDEB_IMPORTSUBSTMODE"
else
    importsubstmode="-ko"
fi


sourcedir=`dirname $opt_dsc`
srcfile=`basename  $opt_dsc`

#set the absolute path name to the dsc file
if [ $VERBOSE -gt 0 ]; then
    echo ""
    echo "# Getting the absolute path name to the dsc file"
fi
cd "$sourcedir"
sourcedir=`pwd`
opt_dsc="$sourcedir/$srcfile"

if [ ! -d "$workdir" ]; then
    $action mkdir -p "$workdir"
fi

if [ "X$docmd" = "XYES" ]; then
    if [ ! -d "$workdir" ]; then
	echo "Could not create $workdir"
	exit 1;
    fi
fi

$action cd "$workdir"
if [ -e "$tmpdir" ]; then
    echo >&2 "$workdir/$tmpdir directory exists"
    echo >&2 "It shall be scribbled on if I continue"
    echo >&2 "Aborting"
    exit 1;
fi

$action mkdir "$tmpdir"
if [ "X$docmd" = "XYES" ]; then
    if [ ! -d "$tmpdir" ]; then
	echo >&2 "The working directory ($workdir) is not writable"
	exit 1
    fi
fi

$action cd "$tmpdir"

# extract the sources
if [ $VERBOSE -gt 0 ]; then
    echo ""
    echo "# Extracting the source"
fi
$action dpkg-source -su -x "$opt_dsc"
if [ $? != 0 ]; then
    echo "Error extracting package: exiting" 1>&2
    exit 1
fi

######################################################################
# clean up the temporary locations
clean_up() {
    if [ $VERBOSE -gt 0 ]; then
	echo ""
	echo "# Cleaning up"
    fi
    $action cd "${workdir}"
    if [ "X$docmd" = "XYES"  ]; then
	if [ -d "$tmpdir" ]; then
	    $action rm -rf $tmpdir
	fi
    else
	$action rm -rf "$tmpdir"
    fi
}

# check for symbolic links in the upstream sources
check_symlinks() {
    symbolic_links=$(find . -type l -print)
    if [ "X$symbolic_links" != "X" ]; then
	if [ "X$forceclean" != "X" ]; then
	    echo >&2 "You have asked me to remove symbolic links I find."
	    echo >&2 "since cvs import chokes on them. I have found"
	    echo >&2 "the following symbolic links:"
	    echo >&2 "$symbolic_links"
	    echo >&2 ""
	    while [ "X$ans" = "X" ]; do
		echo -n >&2 "Shall I remove the links?[y/n]"
		read ans;
		case $ans in
		    y*|Y*)
			$action rm -f $symbolic_links
			;;
		    *)
			echo >&2 "Please delete the following"
			echo >&2 "links and try again."
			echo >&2 "$symbolic_links"
			clean_up;
			exit 1
		esac
	    done
	else
	    echo >&2 "The upstream sources contain symbolic links."
	    echo >&2 "CVS ignores symblic links, you have to handle link "
	    echo >&2 "creation in the modules file (-e and -o args)"
	    echo >&2 "Since this causes an error on import, I can't."
	    echo >&2 "handle this. Please delete the following"
	    echo >&2 "links and try again."
	    echo >&2 "$symbolic_links"
	    clean_up;
	    exit 1
	fi
    fi
}

check_CVS_dirs() {
    CVS_dirs=$(find . -type d -name CVS -print)
    if [ "X$CVS_dirs" != "X" ]; then
	if [ "X$forceclean" != "X" ]; then
	    echo >&2 "You have asked me to remove CVS dirs I find."
	    echo >&2 "since cvs import chokes on them. I have found"
	    echo >&2 "the following dirs:"
	    echo >&2 "$CVS_dirs"
	    echo >&2 ""
	    while [ "X$ans" = "X" ]; do
		echo -n >&2 "Shall I remove the Directories?[y/n]"
		read ans;
		case $ans in
		    y*|Y*)
			$action rm -rf $CVS_dirs
			;;
		    *)
			echo >&2 "Please delete the following"
			echo >&2 "CVS directories and try again."
			echo >&2 "$CVS_dirs"
			clean_up;
			exit 1
		esac
	    done
	
	else
	    echo >&2 "The upstream sources contain CVS directories."
	    echo >&2 "This I can't handle. Please delete the following"
	    echo >&2 "directories and try again."
	    echo >&2 "$CVS_dirs"
	    clean_up;
	    exit 1
	fi
    fi
}
check_CVS_ignore() {
    CVS_ignores=$(find . -type f -name .cvsignore -print)
    if [ "X$CVS_ignores" != "X" ]; then
	if [ "X$forceclean" != "X" ]; then
	    echo >&2 "You have asked me to remove .cvsignore I find."
	    echo >&2 "since cvs import may be adversly affected.. "
	    echo >&2 "I have found the following dirfiles:"
	    echo >&2 "$CVS_ignores"
	    echo >&2 ""
	    while [ "X$ans" = "X" ]; do
		echo -n >&2 "Shall I remove the files?[y/n]"
		read ans;
		case $ans in
		    y*|Y*)
			$action rm -f $CVS_ignores
			;;
		    *)
			echo >&2 "Please delete the following"
			echo >&2 "CVS .ignore files and try again."
			echo >&2 "$CVS_ignores"
			clean_up;
			exit 1
		esac
	    done
	fi
    fi
}

# Importing the upstream sources
import_orig() {
    if [ $VERBOSE -gt 0 ]; then
	echo ""
	echo "# Import the original source tree"
    fi
    $action cd "$1"
    if [ "X$docmd" = "XYES" ]; then
	check_symlinks;
	check_CVS_dirs;
	check_CVS_ignore;
    fi
    if [ ! "X$use_changelog" = "X" -a -f debian/changelog ]; then
	changes=`dpkg-parsechangelog | grep '^  '`
    fi

    argv=(cvs $CVS_QUIET import ${importsubstmode} -m"Initial Import. $changes" "${cvsmodule}" source-dist "${cvs_upstream_tag}")
    $action "${argv[@]}"
    $action cd ..
}

#
co_import() {
    # For non debian only packages
    if [ $VERBOSE -gt 0 ]; then
	echo ""
	echo "# Extracting the imported files"
    fi

    $action cvs co "${cvsmodule}"
    # Where did it go?
    if [ -d "${package}-${upstream_version}" ]; then
	$action cd "${package}-${upstream_version}";
    elif [ -d "${prefix}$package-${upstream_version}" ]; then
	mv "${prefix}$package-${upstream_version}" "${package}-${upstream_version}";
	$action cd "$package-${upstream_version}";
    fi
    
    if [ "X$docmd" = "XYES" ]; then
	tar cf - . | (cd "../${cvsmodule}"; tar "${TAR_QUIET}xf" -)
    else
	echo "tar cf - . | (cd ../${cvsmodule}; tar ${TAR_QUIET}xf -)"
    fi
    $action cd ..
}

# commit debianized tree (non debian only packages
commit_debianized() {
    # For non debian only packages
    if [ $VERBOSE -gt 0 ]; then
	echo ""
	echo "# Committing the Debianized version"
    fi
    $action cd "${cvsmodule}"
    $action cvs add debian
    if [ "X$docmd" = "XYES" ]; then
	done=""
	while [ "X$done" != "X1" ]; do
	    dirs=$(cvs -n update | sed -n 's:^\? ::p')
	    if [ "X$dirs" = "X" ]; then
		done=1
		break
	    fi
#	    for item in $(cvs -n update | sed -n 's:^\? ::p'); do
#		dir=$(dirname $item)
#		file=$(basename $item)
#		(cd $dir; cvs add $file)
#	    done
	    cvs -n update | sed -n 's:^\? ::p' | sed 's/ /\\ /g' | \
               xargs -n1 -i! -e sh -c '
                       dir=$(dirname "!");
                       file=$(basename "!"); 
                       cd $dir;
                       cvs add "$file"
               '
	done
    else
	echo "cvs add <other files found dynamically>"
    fi
    argv=(cvs commit -m'Added all debian changes')
    $action "${argv[@]}"
    $action cvs $CVS_QUIET tag -F "${cvstag}"
    $action cd "${workdir}/$tmpdir"
}


######################################################################

if [ "X$docmd" = "XYES" ]; then
    if [ ! -d "${package}-${upstream_version}" ]; then
	echo >&2 "No ${workdir}/$tmpdir/${package}-${upstream_version}"
	echo >&2 "Error extracting source"
	echo >&2 "Aborting"
	clean_up;
	exit 1
    fi
    
    if [ "X$DEB_ONLY" = "XFALSE" ]; then
	if [ ! -d "${package}-${upstream_version}.orig" ]; then
	    echo >&2 "Warning!!!!!!"
	    echo >&2 "No ${workdir}/$tmpdir/${package}-${upstream_version}"
	    echo >&2 "Though the version number indicates this is not a Debian"
	    echo >&2 "Native Package, it seems to be one. This is a policy"
	    echo >&2 "violation. This should be corrected."
	    ans=""
	    while [ "X$ans" = "X" ]; do
		echo -n >&2 "Do you wish to continue?[y/N]"
		read ans;
		case $ans in
		    y*|Y*)
			echo >&2 "OK. Continuing anyway."
			;;
		    *)
			echo >&2 "Aborting";
			clean_up;
			exit 1
		esac
	    done
	fi
    fi
fi


# import original source tree. 
if [ "X$DEB_ONLY" = "XFALSE" ]; then
    import_orig "${package}-${upstream_version}.orig";
    # extract the imported files, and add the debianized ones
    co_import;
    # And commit the debianized files
    commit_debianized;
else
    import_orig "${package}-${upstream_version}"
    if [ $VERBOSE -gt 0 ]; then
	echo ""
	echo "# Extracting imported files"
    fi
    $action cvs $CVS_QUIET co "${cvsmodule}"
    if [ $VERBOSE -gt 0 ]; then
	echo ""
	echo "# Tagging the files with debian version"
    fi
    $action cd  "${cvsmodule}"
    $action cvs $CVS_QUIET tag -F "${cvstag}"
    $action cd  "${workdir}/$tmpdir"
fi

clean_up

echo "$package registered under CVS"

exit 0






