#!/bin/bash # # $Id: maintain_current_git.sh,v 1.17 2022/02/11 08:44:56 eha Exp eha $ # # Maintain slackware64-current updates in git. # # Examples of use: # + A crontab entry which checks for updates every night at 06:00, and # updates the local git repository (if updates were found): # 00 6 * * * /usr/local/bin/maintain_current_git.sh # + Do not let this script run in parallel with the mirror-slackware-current # script. In cron, schedule this script immediately after the mirror script # so that you know that the local mirror is up to date. # # =========================================================================== # # - Check the local mirror to see if the ChangeLog.txt is newer than our # most recent git commit. # - If older, then no further actions are needed (abort script) # - If ChangeLog.txt has changed since our last run, do the following: # * rsync the updates in slackware64-current tree to a local tree # * generate RSS file from the ChangeLog.txt # * update local git repository with the modifications # # Author: Eric Hameleers # # =========================================================================== # Read configuration file if it exists; # - commonly called 'maintain_current_git.conf' CONFFILE=${CONFFILE:-"$(dirname $0)/$(basename $0 .sh).conf"} [ -f ${CONFFILE} ] && . ${CONFFILE} # The script's basename will be displayed in the RSS feed: BASENAME=$( basename $0 ) # Try not to be verbose by default: DEBUG=${DEBUG:-0} # Location of the original script: ORIGSCR="http://www.slackware.com/~alien/tools/maintain_current_git.sh" # We prevent this script from running more than one instance: # If you have a reason to want to run multiple instances at the same time, just # make a symlink to this script and run the script using the symlinked name. # This will create a unique PIDFILE name. PIDFILE=/var/tmp/$(basename $0 .sh).pid # The script's revision number will be displayed in the RSS feed: REV=$( echo "$Revision: 1.17 $" | cut -d' ' -f2 ) # Where we will write temporary files (like the downloaded ChangeLog.txt): TMP=${TMP:-/tmp} # --------------------------------------------------------------------------- # Distro related variables: # Name of our distro: DISTRO=${DISTRO:-slackware} # Architecture can be 'x86_64' meaning 64bit or 'x86' for 32bit. # The value of ARCH determines the name of the slackware directories. # This value can be overruled via the '-a' commandline parameter; ARCH=${ARCH:-"x86_64"} # The slackware release we're mirroring (defaults to 'current'). # You can use the script's '-r' switch to alter this to another release, # for instance mirror Slackware 15.0 by passing '-r 15.0' to the script. RELEASE=${RELEASE:-"current"} # Where is the local mirror? The Slackware directory tree below # should be named ${SLACKROOTDIR}/${SLACKRELEASE} # This value can be overruled via the '-l' commandline parameter; SLACKROOTDIR=${SLACKROOTDIR:-"/mirrors/${DISTRO}"} # Normally, when no update is found in the ChangeLog.txt, the script exits # without touching the git repository. To force that regardless, you set # the variable FORCE to "yes" (or pass the '-f' switch to the script). FORCE=${FORCE:-"no"} # By default, the script will start with cloning the remote repository in # case it discovers that you do not have a local git repository clone yet. # If you prefer to start with an empty new local git repository (or if the # remote repository does not yet exist) then set the variable INITNEW # to "yes" (or pass the '-i' switch to the script). INITNEW=${INITNEW:-"no"} # By default, the script updates the git repository when updates are found. # Set the variable ONLYDIFF to '1 or pass '-n' to the script # to merely get notified about changes in the ChangeLog.txt: ONLYDIFF=${ONLYDIFF:-0} # --------------------------------------------------------------------------- # Git related variables: # Default author/committer for this git repository: AUTHOR_NAME=${AUTHOR_NAME:-"Patrick J Volkerding"} AUTHOR_EMAIL=${AUTHOR_EMAIL:-"volkerdi@slackware.com"} COMMITTER_NAME=${COMMITTER_NAME:-"Eric Hameleers"} COMMITTER_EMAIL=${COMMITTER_EMAIL:-"alien@slackware.com"} # Name of the git repository storing the updates to the source tree: REPONAME=${REPONAME:-current} # Default branch to update is 'master'; use this variable or "-b" to alter that: BRANCH=${BRANCH:-"master"} # Path to the local slackware64-current git repository: GITDIR=${GITDIR:-"/home/git/repositories/${REPONAME}"} # URI of the remote slackware64-current git repository: GITURI=${GITURI:-"git://slackware.nl"} # Browser-accessible web URL to the git repository: GITURL=${GITURL:-"https://git.slackware.nl"} # You can specify a custom commit message instead of using the latest # update to the ChangeLog.txt by setting 'CUSTOM_COMMIT' to a filename # or specifying the "-m" parameter: CUSTOM_COMMIT=${CUSTOM_COMMIT:-""} # --------------------------------------------------------------------------- # Variables for RSS feed generation: # The title of the generated RSS feed: RSS_TITLE=${RSS_TITLE:-"${DISTRO^}-${RELEASE} (${ARCH}) ChangeLog.txt"} # The logo picture used for the RSS feed: RSS_ICON=${RSS_ICON:-"http://www.slackware.com/~alien/graphics/blueorb.png"} # The URL linked to when clicking on the logo: RSS_LINK=${RSS_LINK:-"http://www.slackware.com/"} # URL to the full changelog.txt: RSS_CLURL=${RSS_CLURL:-"${GITURL}/${REPONAME}/tree/ChangeLog.txt"} # The descriptive text for the RSS feed: RSS_DESCRIPTION=${RSS_DESCRIPTION:-"Tracking ${DISTRO^} development in git."} # Maximum number of RSS feed entries to display, '0' means no limit: RSS_FEEDMAX=${RSS_FEEDMAX:-"0"} # The RSS generator must use a unique feed identifier. # Generate one for your feed by using the string returned by "uuidgen -t": RSS_UUID=${RSS_UUID:-"c964f45e-6732-11e8-bbe5-107b4450212f"} # --------------------------------------------------------------------------- # Function definitions: # # Generate RSS from the ChangeLog.txt # function rss_changelog { # Create a RSS feed out of the ChangeLog.txt # Argument #1 : full path to a directory # Argument #2 : a filename (defaults to 'ChangeLog.txt') # Argument #2 : a filename (defaults to 'ChangeLog.rss') if [ ! -d "$1" ]; then echo "Required argument '$1' must be an existing directory!" exit 1 fi DIR=$1 INFILE=${DIR}/${2:-ChangeLog.txt} RSSFILE=${DIR}/${3:-ChangeLog.rss} if [ -e $RSSFILE -a ! -w $RSSFILE ]; then echo "Can not write to RSS file ${RSSFILE}!" exit 1 fi # These values are all set in the beginning (can be user-overridden): TITLE="$RSS_TITLE" LINK="$RSS_LINK" ICON="$RSS_ICON" CLURL="$RSS_CLURL" DESCRIPTION="$RSS_DESCRIPTION" FEEDMAX=$RSS_FEEDMAX UUID="$RSS_UUID" PUBDATE="" LASTBUILDDATE=$(LC_ALL=C TZ=GMT date +"%a, %e %b %Y %H:%M:%S GMT") # The 'date -R' RFC-2822 compliant string # does not work for Thunderbird! counter=0 # Parse the input file cat ${INFILE} | while IFS= read cline ; do if [ "$PUBDATE" == "" ]; then # PUBDATE is empty, means we're reading the first line of input. # The first line contains the most recent pubdate. # For backward compatibility, if the file starts with # "+--------------------------+" then we just skip that. [ "$cline" == "+--------------------------+" ] && read cline PUBDATE=$(LC_ALL=C TZ=GMT date +"%a, %e %b %Y %H:%M:%S GMT" -d "$cline") rm -f ${RSSFILE} cat <<-_EOT_ > ${RSSFILE} ${TITLE} ${LINK} ${DISTRO^} ${ICON} ${LINK} ${DESCRIPTION} en-us urn:uuid:${UUID} ${PUBDATE} ${LASTBUILDDATE} ${BASENAME} v ${REV} ${PUBDATE} ${PUBDATE} ${GITURL}/${REPONAME}/tag/?h=$(LC_ALL=C TZ=UTC date -d "${PUBDATE}" +%Y%m%d%H%M%S) $(LC_ALL=C TZ=UTC date -d "${PUBDATE}" +%Y%m%d%H%M%S) _EOT_ elif [ "$cline" == "+--------------------------+" ]; then # This line masrks the start of a new entry. # Only dump a certain amount of recent entries. [ $FEEDMAX -gt 0 -a $counter -gt $FEEDMAX ] && break # Close the previous entry: cat <<-_EOT_ >> ${RSSFILE} ]]> _EOT_ # Next line is the pubdate for the next entry: read PUBDATE PUBDATE=$(LC_ALL=C TZ=GMT date +"%a, %e %b %Y %H:%M:%S GMT" -d "$PUBDATE") # Write the header for the next entry: cat <<-_EOT_ >> ${RSSFILE} ${PUBDATE} ${PUBDATE} ${GITURL}/${REPONAME}/tag/?h=$(LC_ALL=C TZ=UTC date -d "${PUBDATE}" +%Y%m%d%H%M%S) $(LC_ALL=C TZ=UTC date -d "${PUBDATE}" +%Y%m%d%H%M%S) _EOT_ counter=$(( ${counter}+1 )) else # Add a line of description [ "${cline}" != "" ] && echo "${cline}" >> ${RSSFILE} fi done # Close the last entry: cat <<-_EOT_ >> ${RSSFILE} ]]> _EOT_ # Close the XML output: cat <<-_EOT_ >> ${RSSFILE} _EOT_ } # # Output a mknod commandline for a 'tar tvf' input line of a device file: # function tarline2mknod() { # Example line which should be passed as arguments (no quotes): # "brw-r----- root/root 36,3 2009-06-16 00:59 dev/eda3" local LINE=$(echo $* | tr -s ' ') local TYPE=$(echo $LINE |cut -c1) local MAJ=$(echo $LINE |cut -d' ' -f3 |cut -d, -f1) local MIN=$(echo $LINE |cut -d' ' -f3 |cut -d, -f2) local DEVNAM="$(echo $LINE |cut -d' ' -f6)" local UMOD=$(echo $LINE |cut -c2-4 |tr 'rwx-' '1110') local GMOD=$(echo $LINE |cut -c5-7 |tr 'rwx-' '1110') local OMOD=$(echo $LINE |cut -c8-10 |tr 'rwx-' '1110') echo "mkdir -p $(dirname $DEVNAM)" echo "mknod -m $((2#${UMOD}))$((2#${GMOD}))$((2#${OMOD})) $DEVNAM $TYPE $MAJ $MIN" } # # Generate script which re-creates tarball device-nodes (requires root): # function mknodescript() { # This script calls 'tarline2mknod' function. local _ARCHIVE="$1" local _SCRIPT="$2" rm -f ${_SCRIPT} 2>/dev/null mkdir -p $(dirname ${_SCRIPT}) echo "# Run this script in the root of the skeleton tree" > ${_SCRIPT} echo "# to re-create the required device nodes" >> ${_SCRIPT} tar tvf ${_ARCHIVE} | grep -E '^(b|c)' \ | while read TARDEV ; do \ tarline2mknod $TARDEV \ >> ${_SCRIPT} done chmod 755 ${_SCRIPT} } # # Decompression routine: # function _decompress() { SOURCE=$1 if $(file ${SOURCE} | grep -qi ": XZ"); then [ $DEBUG -gt 1 ] && echo "-- Decompress: xz -d ${SOURCE}" xz -d ${SOURCE} elif $(file ${SOURCE} | grep -qi ": gzip"); then [ $DEBUG -gt 1 ] && echo "-- Decompress: gunzip -d ${SOURCE}" gunzip -d ${SOURCE} elif $(file ${SOURCE} | grep -qi ": bzip2"); then [ $DEBUG -gt 1 ] && echo "-- Decompress: bunzip2 -d ${SOURCE}" bunzip2 -d ${SOURCE} elif $(file ${SOURCE} | grep -qi ": zip"); then [ $DEBUG -gt 1 ] && echo "-- Decompress: unzip ${SOURCE}" unzip ${SOURCE} elif $(file ${SOURCE} | grep -qi ": lzip"); then [ $DEBUG -gt 1 ] && echo "-- Decompress: lzip -d ${SOURCE}" lzip -d ${SOURCE} else [ $DEBUG -gt 1 ] && echo "** Unknown compression type for '${1}'" fi } # Required to call the functions with xargs, and use variables in a subshell: export -f _decompress export DISTRO DEBUG # --------------------------------------------------------------------------- # Start the work. # Make sure the PID file is removed when we kill the process trap 'rm -f $PIDFILE; exit 1' TERM INT while getopts "a:b:cg:hil:m:nqr:v" Option do case $Option in h ) cat <<-"EOH" ----------------------------------------------------------------- $Id: maintain_current_git.sh,v 1.17 2022/02/11 08:44:56 eha Exp eha $ ----------------------------------------------------------------- EOH echo "Usage:" echo " $0 [OPTION] ..." echo "or:" echo " SLACKROOTDIR=/your/repository/dir $0 [OPTION] ..." echo "" echo "The SLACKROOTDIR is the directory that contains the directories" echo " slackware- and slackware--iso" echo "Current value of SLACKROOTDIR : $SLACKROOTDIR" echo "" echo "You can change the script defaults in a file '$(basename $0 .sh).conf'" echo "" echo "The script's parameters are:" echo " -h This help." echo " -a Architecture to mirror (defaults to '$ARCH'," echo " values can be 'x86' or 'x86_64')." echo " -b Specify branch other than '$BRANCH' to update." echo " Branch (-b) and release (-r) need to match." echo " -c Check for newer version of this script." echo " -g The directory where you keep your local" echo " git repository." echo " -i Initialize an empty local git repository instead" echo " of cloning an existing remote repository first." echo " -l The root directory where you keep your local" echo " Slackware mirror; this directory contains" echo " slackware- or slackware64-" echo " -m Filename containing custom git commit message." echo " -n Only show the changes in the ChangeLog.txt" echo " but don't sync anything and don't update git" echo " -r Release ('$RELEASE' by default); use '-r 14.2'" echo " if you work with a slackware 14.2 repository." echo " Branch (-b) and release (-r) need to match." echo " -q Non-verbose output (for cron jobs)." echo " -v Verbose progress indications." exit ;; a ) ARCH=${OPTARG} ;; b ) BRANCH=${OPTARG} ;; c ) CHECKVER="yes" ;; f ) FORCE="yes" ;; g ) GITDIR=$(readlink -f ${OPTARG}) ;; i ) INITNEW="yes" ;; l ) SLACKROOTDIR=$(readlink -f ${OPTARG}) ;; m ) CUSTOM_COMMIT=$(readlink -f ${OPTARG}) ;; n ) ONLYDIFF=1 ;; q ) # No output at all if we are already in sync DEBUG=0 ;; r ) RELEASE=${OPTARG} ;; v ) echo "Enabling verbose output...." DEBUG=$(($DEBUG + 1)) ;; * ) echo "You passed an illegal switch ($Option) to the program!" echo "Run '$0 -h' for more help." exit ;; # DEFAULT esac done # End of option parsing. shift $(($OPTIND - 1)) # $1 now references the first non option item supplied on the command line # if one exists. # --------------------------------------------------------------------------- # The suffix for the file where we keep the timestamps. # Transforms 'current' to 'CURRENT' and '14.2 to '142': LSUFF="$(echo ${RELEASE^^} | tr -d '.')" # Check for an updated version of this script: if [ "$CHECKVER" == "yes" ]; then if [ $DEBUG -ne 0 ]; then echo "#" echo "# Checking version of '${ORIGSCR}' ..." echo "#" fi CVRS=$(cat ${0} | grep 'Id: ' | head -1 | \ sed -e 's/^.*Id: maintain_current_git.sh,v \([0-9.]*\) .*$/\1/') NVRS=$(wget -T 10 -q -O - ${ORIGSCR} | grep 'Id: ' | \ head -1 | \ sed -e 's/^.*Id: maintain_current_git.sh,v \([0-9.]*\) .*$/\1/') if [ -z "$CVRS" -o -z "$NVRS" ]; then echo "# Cannot compare version against the script's original;" echo "# Your script version reports '$CVRS', the original reports '$NVRS'" if [ -z "$NVRS" ]; then echo "# Possible cause is a failure to retrieve the remote script:" echo "# '${ORIGSCR}'." fi elif [ "$CVRS" != "$NVRS" ]; then echo "# Your version of this script is '$CVRS', while version '$NVRS' is reported" echo "# by remote '${ORIGSCR}'" elif [ "$CVRS" == "$NVRS" ]; then echo "# You have the most recent version of this script" fi fi if [ "$ARCH" = "x86_64" ]; then SLACKRELEASE="${SLACKRELEASE:-${DISTRO}64-${RELEASE}}" PKGMAIN="${DISTRO}64" else SLACKRELEASE="${SLACKRELEASE:-${DISTRO}-${RELEASE}}" PKGMAIN="${DISTRO}" fi if [ ! -d ${SLACKROOTDIR}/${SLACKRELEASE} ]; then echo "$(date) [$$]: Cannot find '${SLACKROOTDIR}/${SLACKRELEASE}' directory" echo "** Aborting now..." exit 1 fi if [ ! -d ${SLACKROOTDIR}/${SLACKRELEASE}/${PKGMAIN} ]; then echo "$(date) [$$]: Cannot find '${SLACKROOTDIR}/${SLACKRELEASE}/${PKGMAIN}' directory" echo "** Did you specify an incorrect architecture ($ARCH)?" echo "** Aborting now..." exit 1 fi if [ ! -d ${GITDIR} ]; then if ! mkdir -p ${GITDIR} ; then echo "$(date) [$$]: Failed creating directory '${GITDIR}'!" echo "** Aborting now..." exit 1 else if [ $DEBUG -ne 0 ]; then if [ "$INITNEW" = "yes" ]; then echo "$(date) [$$]: Creating empty git repository '${GITDIR}'..." else echo "$(date) [$$]: Cloning remote git repository '${GITURI}/${REPONAME}.git' into '${GITDIR}'..." fi fi cd ${GITDIR} if [ "$INITNEW" = "yes" ]; then git init --quiet else git clone --quiet ${GITURI}/${REPONAME}.git . fi echo "Tracking updates in ${SLACKRELEASE}" > .git/description echo "LATEST_ADDITION_TO_${LSUFF}" > .gitignore cat < .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = ${GITURI}/${REPONAME}.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master [user] name = ${AUTHOR_NAME} email = ${AUTHOR_EMAIL} EOT if [ "$INITNEW" = "no" ]; then if [ $DEBUG -ne 0 ]; then echo "$(date) [$$]: Fetching remote branches and tags from '${GITURI}/${REPONAME}.git'..." fi git branch -r | grep -v '\->' | \ while read remote; do git branch -q --track "${remote#origin/}" "$remote" 2>/dev/null done git fetch -q --all git pull -q --all git fetch -q --tags fi cd - 1>/dev/null fi fi # We have made sure that there's a ${GITDIR} and if we had to create it, # we also initialized a git repository. However, things can still be goofy: if [ ! -d ${GITDIR}/.git ]; then echo "$(date) [$$]: Directory '${GITDIR}' doesn't contain a git repository!" echo "** Aborting now..." exit 1 else cd ${GITDIR}/.git if [ "$(git rev-parse --is-inside-git-dir)" = "false" ]; then echo "$(date) [$$]: Directory '${GITDIR}/.git' is not a git repository!" echo "** Aborting now..." exit 1 fi cd - 1>/dev/null fi # OK we do have a git repository, but it may have multiple branches. if [ $DEBUG -ne 0 ]; then echo "$(date) [$$]: Checking out '${BRANCH}' branch" fi cd ${GITDIR} git checkout -q ${BRANCH} 2>/dev/null if [ -f ChangeLog.txt -a ! -f LATEST_ADDITION_TO_${LSUFF} ]; then if [ "$INITNEW" = "no" ]; then # If we just cloned the remote repository we need to create this # to prevent an empty check-in further down: if [ $DEBUG -ne 0 ]; then echo "$(date) [$$]: writing 'LATEST_ADDITION_TO_${LSUFF}'..." fi head -n 40 ChangeLog.txt | grep -Ei "^(mon|tue|wed|thu|fri|sat|sun)" \ | head -n 1 > LATEST_ADDITION_TO_${LSUFF} fi fi cd - 1>/dev/null if ! grep -q LATEST_ADDITION_TO_${LSUFF} ${GITDIR}/.gitignore ; then echo "LATEST_ADDITION_TO_${LSUFF}" >> ${GITDIR}/.gitignore fi if [ $DEBUG -ge 3 ]; then VRSYNC="-v" else VRSYNC=" " fi # --------------------------------------------------------------------------- if [ -e $PIDFILE ]; then echo "**" echo "** Another instance ($(cat $PIDFILE)) still running?" echo "** If you are sure that no other instance is running, then you should" echo "** delete the lockfile '${PIDFILE}' and re-start this script." echo "** Aborting now..." echo "**" exit 1 else echo $$ > $PIDFILE umask 022 # First get the ChangeLog.txt # (no further action needed when there are no changes in this file): if [ $DEBUG -ne 0 ]; then echo "$(date) [$$]: Comparing ChangeLog.txt..." fi # Find the latest slackware-current update: LATEST_ADD=$(head -n 40 ${SLACKROOTDIR}/${SLACKRELEASE}/ChangeLog.txt|grep -Ei "^(mon|tue|wed|thu|fri|sat|sun)"|head -n 1) echo ${LATEST_ADD} > ${TMP}/LATEST_ADDITION_TO_${LSUFF}_$$ # If ${GITDIR}/LATEST_ADDITION_TO_${LSUFF} doesn't exist, it might mean # that this is a first-time run. To prevent the script from aborting, # we create an empty file... if [ ! -e ${GITDIR}/LATEST_ADDITION_TO_${LSUFF} ]; then touch ${GITDIR}/LATEST_ADDITION_TO_${LSUFF} fi diff -b ${GITDIR}/LATEST_ADDITION_TO_${LSUFF} ${TMP}/LATEST_ADDITION_TO_${LSUFF}_$$ 1>/dev/null 2>/dev/null STATUS="$?" if [ "$STATUS" == "2" ]; then echo "$(date) [$$]: Trouble when running diff, aborting..." rm -f ${TMP}/LATEST_ADDITION_TO_${LSUFF}_$$ rm -f $PIDFILE exit 1 elif [ "$STATUS" == 0 ]; then [ $DEBUG -ne 0 ] && echo -n "$(date) [$$]: No difference found" if [ $FORCE == "yes" ]; then # we will continue as requested [ $DEBUG -ne 0 ] && echo ", continuing anyway..." else # quit the script now. [ $DEBUG -ne 0 ] && echo ", exiting now...." rm -f ${TMP}/LATEST_ADDITION_TO_${LSUFF}_$$ rm -f $PIDFILE exit 0 fi else echo -n "$(date) [$$]: ${DISTRO^}-${RELEASE} ChangeLog.txt has updates" if [ $ONLYDIFF -eq 1 ]; then # quit the script now. echo " (${LATEST_ADD}), that's all you wanted to know...." rm -f ${TMP}/LATEST_ADDITION_TO_${LSUFF}_$$ rm -f $PIDFILE exit 0 else # we will continue. echo ", committing updates to the tracking git repository." fi fi # Start the collection and update process: if [ -n "${CUSTOM_COMMIT}" ]; then # Custom commit text specified: COMMSG="${CUSTOM_COMMIT}" TAG_ADD="" TAG_REB="" TAG_REM="" TAG_UPD="" TAG_CRT="" TAG_MSG="${LATEST_ADD}" else # Save ChangeLog.txt update to file to use later as the git commit message: TMPFILE=$(mktemp -t curr2git.XXXXXX) echo -e "${LATEST_ADD}\n" > ${TMPFILE} sed -n '2,/+--------------------------+/p' "${SLACKROOTDIR}/${SLACKRELEASE}/ChangeLog.txt" | head -n -1 >> ${TMPFILE} COMMSG="${TMPFILE}" TAG_ADD="$(grep ': *Added.$' ${COMMSG} |wc -l)" TAG_REB="$(grep ': *Rebuilt.$' ${COMMSG} |wc -l)" TAG_REM="$(grep ': *Removed.$' ${COMMSG} |wc -l)" TAG_UPD="$(grep ': *Upgraded.$' ${COMMSG} |wc -l)" TAG_CRT="$(grep -F '(* Security fix *)' ${COMMSG} |wc -l)" TAG_MSG="${LATEST_ADD}: ${TAG_UPD} upgrades, ${TAG_REB} rebuilds, ${TAG_ADD} additions, ${TAG_REM} removals" if [ ${TAG_CRT} -ne 0 ]; then TAG_MSG="${TAG_MSG}, plus ${TAG_CRT} critical security fixes!" fi fi # Capture the timestamp of the latest addition: echo ${LATEST_ADD} > ${GITDIR}/LATEST_ADDITION_TO_${LSUFF} if [ $DEBUG -ge 1 ]; then echo "+--------------------------+" sed -n '2,/+--------------------------+/p' "${SLACKROOTDIR}/${SLACKRELEASE}/ChangeLog.txt" fi # Copy the files we want to keep under revision control: [ $DEBUG -ne 0 ] && echo "$(date) [$$]: Syncing the changes in ${DISTRO^} to git-dir" rsync ${VRSYNC} --delete -rlptD \ --exclude=".git*" --exclude=LATEST_ADDITION_TO_${LSUFF} \ --exclude="*,v" \ --exclude="*.tar.?z" --exclude="*.tar.bz2" --exclude="*.t?z" \ --exclude="*.zip" \ --exclude="CHECKSUMS*" --exclude="FILE_LIST" --exclude="FILELIST.txt" \ --exclude="MANIFEST.**" --exclude="PACKAGES.TXT" \ --exclude="*.bin" --exclude="*.img" --exclude="*.iso" --exclude="*.dsk" \ --exclude="*.rpm" \ --exclude="*.efi" --exclude="*.EFI" --exclude="*.s" \ --exclude="*.exe" --exclude="*.EXE" \ --exclude="*.exe.?z" --exclude="*.EXE.?z" \ --exclude="*.asc" --exclude="*.sig" --exclude="*.sign" --exclude="*.pgp" \ --exclude="*.md5 --exclude=*.sha256 --exclude=*.sha512" \ ${SLACKROOTDIR}/${SLACKRELEASE}/ ${GITDIR}/ # Extract the package preload tarballs (_.tar.gz in the sourcedir): cd ${SLACKROOTDIR}/${SLACKRELEASE} find source extra/source pasture/source -type f -name "_*.tar.gz" \ | while read TBALL ; do TDIR="$(dirname $TBALL)" TBASE="$(basename $TBALL .tar.gz)" if [ -z "$TDIR" -o -z "$TBASE" ]; then continue; fi rm -rf ${GITDIR}/${TDIR}/${TBASE} 2>/dev/null mkdir -p ${GITDIR}/${TDIR}/${TBASE} tar \ -C ${GITDIR}/${TDIR}/${TBASE} \ -xf ${SLACKROOTDIR}/${SLACKRELEASE}/${TBALL} \ 2>/dev/null # Silence the 'mknod' warnings if [ $? -ne 0 ]; then # Non-zero exit code means the tarball contains device nodes. # Generate script which will re-create device-nodes (requires root): mknodescript ${TBALL} \ ${GITDIR}/${TDIR}/${TBASE}/dev/mknodes.sh fi done cd - 1>/dev/null # Extract the skeleton initrd if we find one. # Note that device files in /dev/ cannot be extracted from the skeleton, # since that would require root (to run 'mknod'). # Instead we will generate a script from the tarball that recreates them. INITRD=$(find ${SLACKROOTDIR}/${SLACKRELEASE}/source -name skeleton_initrd.tar.gz) if [ -n "${INITRD}" ]; then [ $DEBUG -ne 0 ] && echo "$(date) [$$]: Extracting skeleton initrd" rm -rf ${GITDIR}/source/installer/sources/initrd mkdir -p ${GITDIR}/source/installer/sources/initrd tar -C ${GITDIR}/source/installer/sources/initrd --exclude=dev/* \ -xf ${INITRD} tar -C ${GITDIR}/source/installer/sources/initrd --occurrence=1 \ -xf ${INITRD} dev/makedevs.sh # Generate script which will re-create the device-nodes (requires root): mknodescript ${INITRD} \ ${GITDIR}/source/installer/sources/initrd/dev/mknodes.sh fi # Clean out unwanted files (i.e. txt files in the package directories): [ $DEBUG -ne 0 ] && echo "$(date) [$$]: Cleaning out any unwanted files" rm -f ${GITDIR}/${PKGMAIN}/*/*.txt rm -f ${GITDIR}/extra/*/*.txt rm -f ${GITDIR}/pasture/*.txt rm -f ${GITDIR}/testing/packages/*.txt rm -f ${GITDIR}/testing/packages/*/*.txt # Remove empty directories: find ${GITDIR} -type d -depth | grep -v .git \ | xargs rmdir --ignore-fail-on-non-empty 2>/dev/null # Create a script the user can run to re-compress all the files # that we are going to de-compress shortly: cat < ${GITDIR}/recompress.sh #!/bin/sh # # Run this script in the root directory of the repository to re-compress # all patches and scripts that were un-compressed to make a better git commit: # EOT ( cd ${GITDIR} find . -type f -name "*.gz" | sed -e 's/^/gzip /' -e 's/.gz$//' \ >> ${GITDIR}/recompress.sh find . -type f -name "*.lz" | sed -e 's/^/lzip /' -e 's/.lz$//' \ >> ${GITDIR}/recompress.sh find . -type f -name "*.bz2" | sed -e 's/^/bzip2 /' -e 's/.bz2$//' \ >> ${GITDIR}/recompress.sh ) chmod +x ${GITDIR}/recompress.sh # Generate the list of compressed files we need to decompress: [ $DEBUG -ne 0 ] && echo "$(date) [$$]: Decompressing files before commit" find ${GITDIR} -type f \ \( -name "*.?z" -o -name "*.bz2" \) \ -print0 \ | xargs -0 -r -I FILE bash -c "_decompress FILE" # Generate the RSS file: [ $DEBUG -ne 0 ] && echo "$(date) [$$]: Generating RSS file in git" rss_changelog ${GITDIR} # And finally, the actual git commit: [ $DEBUG -ne 0 ] && echo "$(date) [$$]: Committing updates to git" ( cd ${GITDIR} git add -A . GIT_COMMITTER_NAME="${COMMITTER_NAME}" \ GIT_COMMITTER_EMAIL="${COMMITTER_EMAIL}" \ git commit --quiet -F ${COMMSG} \ --author="${AUTHOR_NAME} <${AUTHOR_EMAIL}>" \ --date="${LATEST_ADD}" # Tag the commit so we can point to it with a clean URL: if [ "${BRANCH}" = "master" ]; then TAG_NAME="$(LC_ALL=C TZ=UTC date -d "${LATEST_ADD}" +%Y%m%d%H%M%S)" else TAG_NAME="$(LC_ALL=C TZ=UTC date -d "${LATEST_ADD}" +%Y%m%d%H%M%S)_${BRANCH}" fi if ! git tag | grep -q ${TAG_NAME} ; then # Tag does not yet exist: GIT_COMMITTER_NAME="${COMMITTER_NAME}" \ GIT_COMMITTER_EMAIL="${COMMITTER_EMAIL}" \ GIT_COMMITTER_DATE="${LATEST_ADD}" \ git tag -m "${TAG_MSG}" "${TAG_NAME}" fi ) # You can define the function 'post_current()' in the configuration file # 'maintain_current_git.conf'. It will then be executed here. # Employ this for instance to push your local commits to a remote: if type post_current 1>/dev/null 2>/dev/null ; then [ $DEBUG -ne 0 ] && echo "$(date) [$$]: Running custom function 'post_current'" post_current fi echo "$(date) [$$]: Done!" # Cleanup: rm -f $PIDFILE rm -f ${TMP}/LATEST_ADDITION_TO_${LSUFF}_$$ rm -f ${TMPFILE} fi