#!/bin/bash ################################################################################ # Copy or move all unversioned files from one category to another. ################################################################################ # # Exit Error Codes: # # The exit error codes are based on the /usr/include/sysexits.h for all # non-zero errors. An exit code of '0' is success. # ############################################################################### # # Bugs: # - Nothing to admit # ############################################################################### # # Todo: # - Add more Todo items # ############################################################################### ############################################################################### # Variables: Read-Only ######################################## # Error Codes readonly Error_Data=65 # EX_DATAERR readonly Error_NoInput=66 # EX_NOINPUT readonly Error_NoPerm=77 # EX_NOPERM readonly Error_TempFail=75 # EX_TEMPFAIL readonly Error_Unavailable=69 # EX_UNAVAILABLE readonly Error_Usage=64 # EX_USAGE ######################################## # Grep Exit Codes readonly Grep_Found_Match=0 readonly Grep_No_Match=1 readonly Grep_Error=2 ######################################## # Page Viewer if [ -n "`command -v less 2> /dev/null`" ] then readonly page_viewer="less --no-init --quit-if-one-screen" elif [ -n "`command -v more 2> /dev/null`" ] then readonly page_viewer="more" else readonly page_viewer="" fi ######################################## # Project Values readonly program_name=`basename $0` readonly project_path=$(fossil info | grep 'local-root:' | sed 's/.*: *\(.*\)[\/]/\1/') ############################################################################### # Variables: Internal action="" ############################################################################### # Variables: Arg Configurable category_new="" category_old="" debug_mode="" dry_run="" move_files="" separator=":" uv_file_list="" ############################################################################### main() { if [ -n "$dry_run" ] then action=ignore fi uv_file_list=$(fossil uv ls --glob "${category_old}${separator}*") if [ -n "$debug_mode" ] then echo "--- Internally Defined Values ---" echo " page_viewer: \"$page_viewer\"" echo " program_name: \"$program_name\"" echo " project_path: \"$project_path\"" echo " action: \"$action\"" echo "" echo "--- Argument Based Values ---" echo " category_old: \"$category_old\"" echo " category_new: \"$category_new\"" echo " dry_run: \"$dry_run\"" echo " move_files: \"$move_files\"" echo " separator: \"$separator\"" echo " uv_file_list: \"$uv_file_list\"" exit $Error_TempFail fi copy_files if [ -n "$move_files" ] then remove_files fi } ################################################################################ # Copy the unversioned files to the new category copy_files() { temp_dir=".$$" mkdir $temp_dir for uv_file in $uv_file_list do file=$(echo $uv_file | sed "s/${category_old}${separator}//") $action fossil uv export $uv_file $temp_dir/$file $action fossil uv add $temp_dir/$file --as $category_new$separator$file done rm -rf $temp_dir } ################################################################################ # Remove the unversioned files from the old category remove_files() { for uv_file in $uv_file_list do $action fossil uv remove $uv_file done } ################################################################################ # Do nothing and do it well ignore() { echo $* } ################################################################################ show_usage() { if [ -n "$page_viewer" ] then usage | $page_viewer else usage fi } ################################################################################ usage() { cat <<- USAGE_END Usage: $program_name [Options] Old_Category New_Category Options: --debug Display the internal values that would be used to create the requested class then exit. -h, --help Show this message and exit. -m, --move Instead of the default action of copying the unversioned files to the new category, the files will be moved. -n, --dry-run Only print what would be done. No file changes will be made. Note: The destination directory must exist to use this option. -s, --separator CHAR Specify the character that separates the category name from the file name in the repository. Default: ":" Arguments: Old_Category The name of the old category. New_Category The name of the new category. USAGE_END } ############################################################################### # Parse the args arg_list=() while [ "$1" != "" ] do case $1 in --debug) debug_mode="yes" ;; -h|--help) show_usage exit 0 ;; -m|--move) move_files="yes" ;; -n|--dry-run) dry_run="yes" ;; -s|--separator) shift separator="$1" ;; -*) echo "Error: Option \"$1\" is not supported." echo "Use \"-h\" for help:" echo " $program_name -h" exit $Error_Usage ;; *) arg_list+=($1) ;; esac shift done # Bash Array Syntax # ${array_name[@]} Get all elements # ${#array_name[@]} Count all elements # ${array_name[@]:I:N} Get N elements starting at I category_old=${arg_list[0]} category_new=${arg_list[1]} ############################################################################### # Make sure that all required information is present and valid ### Category: Source ### if [ -z "$category_old" ] then echo "Error: No old category name was provided" echo "Use \"-h\" for help:" echo " $program_name -h" exit $Error_NoInput fi category_list="$(fossil uv ls | sed "s/${separator}.*/ /" | sort -u)" echo "$category_list" | grep "^${category_old} " &> /dev/null if [ "$?" == "$Grep_No_Match" ] then echo "Error: Invalid old category, not found in repository" echo "Use \"-h\" for help:" echo " $program_name -h" exit $Error_Unavailable fi ### Category: Destination ### if [ -z "$category_new" ] then echo "Error: No new category name was provided" echo "Use \"-h\" for help:" echo " $program_name -h" exit $Error_NoInput fi ############################################################################### # Everything is now ready main exit 0