- Timestamp:
- 10/10/2009 01:12:56 (3 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 8 edited
-
Makefile.am (modified) (1 diff)
-
confman.8.in (modified) (3 diffs)
-
confman.conf.5.in (modified) (1 diff)
-
confman.conf.in (modified) (1 diff)
-
confman.in (modified) (5 diffs)
-
confmancommon.sh.in (modified) (1 diff)
-
confmandoc.sh (modified) (3 diffs)
-
confmanlib.sh.in (modified) (4 diffs)
-
recipe.template (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Makefile.am
r457 r462 15 15 sysconf_DATA = confman.conf.sample 16 16 sysconfdefaults_DATA = confman.conf 17 dist_sysconfdefaults_DATA = recipe.template 17 18 bashcomp_DATA = confman_completion 18 19 man_MANS = confman.8 confman.conf.5 -
trunk/confman.8.in
r460 r462 36 36 .Op Fl v | Cm version 37 37 .Nm 38 . Ar command Oo Ar command_opts Oc Op Ar command_args38 .Oo Ar flags Oc Ar command Oo Ar command_opts Oc Op Ar command_args 39 39 .Sh DESCRIPTION 40 40 The … … 96 96 operations can bring the system up-to-date. 97 97 .El 98 .\" TODO 98 .Ss FLAGS 99 The following flags can be specified before the commands: 100 .Bl -tag -width indent 101 .It Fl h Op Ar command 102 Synonymous to the 103 .Ar help 104 command below. 105 .It Fl v 106 Causes 107 .Nm 108 to print the version string and exit. 109 .It Fl m Ar message 110 The string in the 111 .Ar message 112 argument will be used instead of prompting the user for a log message for 113 .Cm commit 114 and 115 .Cm install 116 operations. 117 .It Fl F Ar filename 118 Like 119 .Fl m , 120 except the log's contents are read from 121 .Ar filename 122 instead of the command line. 123 .El 99 124 .Ss COMMANDS 100 125 The following commands are supported by … … 184 209 .Brq Cm get | list 185 210 .It Cm recipe 186 .Brq Cm create |edit | print | remove | set211 .Brq Cm create [ Fl R Ar filename ] | Cm edit | print | remove | set 187 212 .Ar recipe 188 213 .Bl -tag -width indent 189 214 .It Cm create 190 215 Create a recipe named 191 .Ar recipe 216 .Ar recipe. 217 Use -R to specify a file with the recipe's contents to bypass interactive 218 mode. 192 219 .It Cm edit 193 220 Open -
trunk/confman.conf.5.in
r438 r462 137 137 .It CONF_WARNING 138 138 This is the first line of confman banners for managed files. 139 .It LOG_TEMPLATE 140 If defined, the contents of this file will be the default log message visible 141 in a user's editor for repository commits. This can be useful if you use 142 hooks to log commits into an external issue tracker and you want to remind 143 your users to fill in the ticket number. 144 .It RECIPE_TEMPLATE 145 When new recipes are created, the contents of this file will be used. The 146 string 147 .Ar __NAME__ 148 will be replaced with the name of the recipe. This defaults to 149 @sysconfdefaultsdir@/recipe.template. 139 150 .It DEFAULT_MODE_DIRECTORY 140 151 Defaults to "0555". When new directories are created in -
trunk/confman.conf.in
r435 r462 45 45 # The template for log messages 46 46 LOG_TEMPLATE="/dev/null" 47 48 # The template for new recipes 49 RECIPE_TEMPLATE="@sysconfdefaultsdir@/recipe.template" 47 50 48 51 # The warning message for all files -
trunk/confman.in
r454 r462 111 111 } 112 112 113 # Either by prompting or respecting -m/-F, returns a filename on stdout 114 # with a log message in it 115 # $1 contains a file with the output of svn status to display in interactive 116 # log messages 117 # Returns 1 if an abort was requested by the user 118 # Returns 0 if the returned filename is good for a commit 119 function get_log { 120 local status="$1" 121 local finished=false 122 local ignoreline="--This line, and those below, will be ignored--" 123 local orig_log logfile 124 125 # local seems to return true, overwriting the return of the nested 126 # call for && evaluation 127 logfile=$(conf_log_message) && finished=true 128 129 if $finished ; then 130 echo "$logfile" 131 return 0 132 fi 133 134 orig_log=$(conf_tmp_file) 135 printf "\n$ignoreline\n" >> "$logfile" 136 cat "$status" >> "$logfile" 137 cp "$logfile" "$orig_log" 138 139 # I apologize for the redirect, but stdout is being written into a 140 # variable, and at least vim (probably other editors too) gets cranky when 141 # stdout doesn't go to the user. Luckily, the fork in the common section 142 # leaves a copy of the original stdout in fd 3. 143 ${EDITOR} "$logfile" >&3 144 145 while diff "$logfile" "$orig_log" >/dev/null 2>&1 ; do 146 echo "Log message unchanged. (E)dit / (a)bort / (c)ontinue?" 147 read response 148 case "$response" in 149 [cC]*) break;; 150 [aA]*) return 1;; 151 ""|[eE]*) ${EDITOR} "$logfile";; 152 esac 153 done 154 rm -f "$orig_log" 155 ${sed_cmd} -i '' -e "/${ignoreline}/,\$d" "$logfile" 2>/dev/null 156 echo "$logfile" 157 return 0 158 } 159 160 # Arguments are full paths to files within $WORK_PATH to check via svn status. 161 # Returns 1 if the files are unchanged 162 # Returns 0 if the files are changed and prints a filename to stdout 163 # with status info suitable for log message footers 164 function get_status { 165 local status=$(conf_tmp_file) 166 local ABS_WORK=$(${readlink_cmd} -m "$WORK_PATH") 167 168 # Using a subshell to preserve CWD 169 ( 170 cd "$WORK_PATH" 171 until [ -z "$1" ] ; do 172 @SVN@ status "${1#${ABS_WORK}/}" >> "$status" 173 shift 174 done 175 ) 176 177 if [ $(wc -l < "$status") -eq 0 ] ; then 178 rm -f "$status" 179 return 1 180 fi 181 182 echo "$status" 183 return 0 184 } 185 113 186 function commit { 114 187 if [ -z "$*" ] ; then … … 116 189 conf_lock_system 117 190 conf_lock_wcopy 118 local msg=$(conf_tmp_file) 119 local orig_msg=$(conf_tmp_file) 120 local status=$(conf_tmp_file) 121 local modules=$(conf_get_recipe | tr '\n' ',') 122 local ignoreline="--This line, and those below, will be ignored--" 123 # Moved up per Ian's request. 191 local msg status modules module modpath 192 local nocommit=true 193 194 for module in $(conf_get_recipe) ; do 195 modpath=$(${readlink_cmd} -m ${WORK_PATH}/${module}) 196 modules=${modules:+${modules} }${modpath} 197 done 198 124 199 $SUDO ${SUDO:+-v} 125 cat $LOG_TEMPLATE > $msg 126 printf "\n${ignoreline}\n" >> $msg 127 conf_get_recipe | tr ' ' '\n' | xargs -I % @SVN@ status \ 128 ${WORK_PATH}/% >> $status 129 cat $status >> $msg 130 cp $msg $orig_msg 131 if [ $(wc -l < $status) -gt 0 ] ; then 132 ${EDITOR} $msg 133 if diff $msg $orig_msg >/dev/null 2>&1 ; then 134 echo "Log message unchanged. (a)bort / (C)ontinue?" 135 read response 136 if [ "${response}" = "a" ] ; then 137 conf_unlock_wcopy 138 conf_unlock_system 139 return 1 140 fi 141 fi 142 fi 143 rm -f $status $orig_msg 144 ${sed_cmd} -i '' -e '/'"$ignoreline"'/,$d' $msg 2>/dev/null 200 conf_update_tree || conf_cleanExit 201 202 if status=$(get_status $modules) ; then 203 nocommit=false 204 msg=$(get_log "$status") || conf_cleanExit 205 rm -f "$status" 206 fi 207 145 208 $SUDO ${SUDO:+-v} 146 209 147 #Changed this from just update to fix locking issue - arjun148 conf_update_tree || conf_cleanExit149 150 210 echo "Commit operation started" >&2 151 conf_commit "$(conf_get_recipe)" $msg || return $?211 $nocommit || conf_commit "$(conf_get_recipe)" $msg || return $? 152 212 for layer in $(conf_get_recipe) ; do 153 213 echo "Rolling on $layer..." … … 178 238 conf_lock_wcopy 179 239 conf_lock_system 180 local msg=$(conf_tmp_file) 181 local orig_msg=$(conf_tmp_file) 182 local status=$(conf_tmp_file) 183 local modules=$(conf_get_recipe | tr '\n' ',') 184 local ignoreline="---Everything after this line will be ignored---" 185 local files 186 # Moved up per Ian's request. 187 cat $LOG_TEMPLATE > $msg 188 printf "\n${ignoreline}\n" >> $msg 240 local msg status files file 241 local nocommit=true 242 189 243 for file in "$@"; do 190 if [ -L "$file" ]; then 191 files="$files `${readlink_cmd} -m $file`" 192 fi 193 files="$files $file" 194 done 195 @SVN@ status $files >> $status 196 cat $status >> $msg 197 cp $msg $orig_msg 198 if [ $(wc -l < $status) -gt 0 ] ; then 199 ${EDITOR} $msg 200 if diff $msg $orig_msg >/dev/null 2>&1 ; then 201 echo "Log message unchanged. (a)bort / (C)ontinue?" 202 read response 203 if [ "${response}" = "a" ] ; then 204 conf_unlock_wcopy 205 conf_unlock_system 206 return 1 207 fi 208 fi 209 fi 210 rm $status $orig_msg 211 ${sed_cmd} -i '' -e '/'"$ignoreline"'/,$d' $msg 2>/dev/null 244 files="${files:+${files} }$(${readlink_cmd} -m "$file")" 245 done 246 247 212 248 $SUDO ${SUDO:+-v} 213 #changed from update to conf_update_tree to implement locking - arjun214 249 conf_update_tree || conf_cleanExit 215 250 251 if status=$(get_status $files) ; then 252 nocommit=false 253 msg=$(get_log "$status") || conf_cleanExit 254 rm -f "$status" 255 fi 256 216 257 echo "Installation operation started." >&2 217 conf_commit_file "$msg" "$files" || return $?258 $nocommit || conf_commit_file "$msg" "$files" || return $? 218 259 for layer in $(conf_get_recipe) ; do 219 260 conf_install $layer "$@" … … 896 937 if [ -z "$1" ] ; then print_usage 1 ; fi 897 938 local recipe="$1" 898 local recipe_file=$(conf_tmp_file) 899 cat "$(conf_recipe_dir)/${recipe}" > "$recipe_file" 900 $EDITOR "$recipe_file" 901 for module in $(conf_get_recipe ${recipe_file}) ; do 902 if ! [ -d "${WORK_PATH}/${module}" ] ; then 903 echo "Error: recipe references non-existent module $module" >&2 939 local new_recipe_file=$(conf_tmp_file) 940 local recipe_file=$(conf_recipe_dir)/${recipe} 941 local repeat msg status 942 943 cat "$recipe_file" > "$new_recipe_file" 944 $EDITOR "$new_recipe_file" 945 until conf_recipe_verify "$new_recipe_file" ; do 946 echo -n "(E)dit / (c)ancel? " 947 read repeat 948 case "$repeat" in 949 [Cc]*) return 1;; 950 *) $EDITOR "$new_recipe_file";; 951 esac 952 done 953 954 cat "$new_recipe_file" > "$recipe_file" 955 956 if status=$(get_status "${recipe_file#${WORK_PATH}/}") ; then 957 msg=$(get_log "$status") || return 1 958 conf_commit_recipe "$recipe" "$msg" 959 fi 960 rm -f "$new_recipe_file" 961 } 962 963 function recipe_create { 964 local recipe recipe_file opt OPTIND msg status 965 local recipe_file 966 while getopts ":R:" opt ; do 967 case $opt in 968 R) new_recipe_file="$OPTARG" ;; 969 *) echo "Invalid option '-${OPTARG}' for recipe create." >&4 970 print_usage 1 971 ;; 972 esac 973 done 974 975 eval recipe=\$$OPTIND 976 recipe_file=$(conf_recipe_dir)/${recipe} 977 978 if [ -z "$recipe" ] ; then 979 print_usage 1 980 fi 981 982 conf_recipe_create "$recipe" || return 1 983 984 if [ -z "$new_recipe_file" ] ; then 985 if ! recipe_edit "$recipe" ; then 986 conf_rm_file --force "${new_recipe_file}" 904 987 return 1 905 988 fi 906 done 907 conf_update_recipe "$recipe" "$recipe_file" 908 rm -f "$recipe_file" 909 } 910 911 function recipe_create { 912 if [ -z "$1" ] ; then print_usage 1 ; fi 913 local recipe="$1" 914 conf_recipe_create "$recipe" 915 recipe_edit "$recipe" 989 return 0 990 fi 991 992 if conf_recipe_verify "$new_recipe_file" ; then 993 cp "$new_recipe_file" "$recipe_file" 994 if status=$(get_status "${recipe_file#${WORK_PATH}/}") ; then 995 msg=$(get_log "$status") || return 1 996 conf_commit_recipe "$recipe" "$msg" 997 fi 998 return 0 999 else 1000 conf_rm_file --force "${recipe_file}" 1001 return 1 1002 fi 916 1003 } 917 1004 … … 973 1060 974 1061 # Debug mode? 975 while getopts " hdv-" opt ; do1062 while getopts ":h:dvm:F:-" opt ; do 976 1063 case $opt in 977 d) DEBUG="true" ; shift ;;978 h) shift ; print_help "$@" ; conf_cleanExit 0 ;;1064 d) DEBUG="true" ;; 1065 h) print_help "$OPTARG" ; conf_cleanExit 0 ;; 979 1066 v) print_version ; conf_cleanExit 0 ;; 980 *) print_usage 1 ;; 1067 m) LOG_MESSAGE="$OPTARG"; LOG_MESSAGE_SET="true" ;; 1068 F) LOG_FILE="$OPTARG" ;; 1069 *) echo "Invalid options '-${OPTARG}'." >&4 1070 print_usage 1 1071 ;; 981 1072 esac 982 1073 done 983 1074 1075 # Argument checking 1076 if [ -n "$LOG_FILE" ] && ! [ -r "$LOG_FILE" ] ; then 1077 echo "Log file $LOG_FILE does not exist or is not readable." >&4 1078 conf_cleanExit 1 1079 fi 1080 1081 if $LOG_MESSAGE_SET && [ -n "$LOG_FILE" ] ; then 1082 echo "Cannot specify both a message with -m and a file with -F." >&4 1083 conf_cleanExit 1 1084 fi 1085 984 1086 # Dispatch the subcommand. This must happen last and in the global context. 985 subcommand=$1 986 shift 1087 eval subcommand=\$$OPTIND 1088 shift $OPTIND 1089 987 1090 trap "conf_interrupt_trap" HUP INT QUIT TERM 988 1091 case $subcommand in -
trunk/confmancommon.sh.in
r437 r462 40 40 # we re-spawn confman inside a pipe. 41 41 if (true >&5) 2>/dev/null ; then 42 exec 4>&2 2>&5 >&3 -42 exec 4>&2 2>&5 >&3 43 43 else 44 44 exec 3>&1 -
trunk/confmandoc.sh
r453 r462 224 224 225 225 Usage: 226 $MYNAMEcommit226 $MYNAME [ -F filename | -m message ] commit 227 227 228 228 The commit command causes your changes to take effect. This means that … … 238 238 ORDER OF APPEARANCE. 239 239 240 If -F or -m are used, the log message will be read from the filename or 241 the commandline, respectively, instead of prompting the user. 242 240 243 EOF 241 244 ;; … … 257 260 258 261 Usage: 259 $MYNAME install workingfile [ workingfile ...]262 $MYNAME [-F filename | -m message] install workingfile [workingfile [...]] 260 263 261 264 The install subcommand allows you to roll out a single file from your working 262 265 copy. 266 267 If -F or -m are used, the log message will be read from the filename or 268 the commandline, respectively, instead of prompting the user. 263 269 264 270 EOF -
trunk/confmanlib.sh.in
r460 r462 32 32 WCOPY_DIRTY="false" 33 33 CONF_EXPORT="false" 34 LOG_MESSAGE_SET="false" 34 35 35 36 VERSION='@VERSION@' … … 698 699 699 700 function conf_rm_file { 700 @SVN@ rm $*701 @SVN@ rm "$@" 701 702 } 702 703 … … 963 964 return 1 964 965 fi 965 touch"$recipe_file"966 ${sed_cmd} -e "s:__NAME__:${recipe}:" $RECIPE_TEMPLATE > "$recipe_file" 966 967 @SVN@ add "$recipe_file" 967 968 } 968 969 969 function conf_update_recipe { 970 function conf_recipe_verify { 971 local recipe_file="$1" 972 local module 973 for module in $(conf_get_recipe ${recipe_file}) ; do 974 if ! [ -d "${WORK_PATH}/${module}" ] ; then 975 echo "Error: recipe references non-existent module $module" >&2 976 return 1 977 fi 978 done 979 return 0 980 } 981 982 function conf_commit_recipe { 970 983 local recipe="$1" 971 local recipe_file="$2" 972 cat "$recipe_file" > "$(conf_recipe_dir)/${recipe}" 973 @SVN@ commit "$(conf_recipe_dir)/${recipe}" 984 local logfile="$2" 985 @SVN@ commit -F "$logfile" "$(conf_recipe_dir)/${recipe}" 974 986 } 975 987 … … 1015 1027 } 1016 1028 1029 # Implements logic for selecting logfile based on -m/-F or interactive mode 1030 # Returns 0 if the log is "complete", 1 if the log needs editing 1031 # Prints filename containing the log on stdout 1032 function conf_log_message { 1033 local logfile 1034 1035 if [ -n "$LOG_FILE" ] ; then 1036 echo "$LOG_FILE" 1037 return 0 1038 fi 1039 1040 logfile=$(conf_tmp_file) 1041 echo "$logfile" 1042 1043 if $LOG_MESSAGE_SET ; then 1044 echo "$LOG_MESSAGE" > "$logfile" 1045 else 1046 cat "$LOG_TEMPLATE" > "$logfile" 1047 return 1 1048 fi 1049 return 0 1050 } 1051 1017 1052 # Because an exit doesn't help much when things are in subshells, we 1018 1053 # provide a nice, easy way to halt execution. The result is the clean
Note: See TracChangeset
for help on using the changeset viewer.
