update-bzr (4064B)
1 #!/bin/zsh 2 setopt no_unset warn_create_global extended_glob 3 zmodload -F zsh/stat b:zstat || exit $? 4 zmodload -m -F zsh/files b:zf_\* || exit $? 5 zmodload zsh/zutil || exit $? 6 7 die_ret() { 8 local ret 9 ret=$1 10 shift 11 echo >&2 "$@" 12 exit $ret 13 } 14 die() { 15 die_ret 1 "$@" 16 } 17 cd $0:h || exit $? 18 19 pretend() { 20 : "$@" 21 } 22 typeset -ft pretend 23 24 brz=${commands[brz]:-bzr} 25 26 load_sources() { 27 unset repo_sources 28 typeset -gA repo_sources 29 unset repos 30 typeset -ga repos 31 32 local name url 33 <./bzr/sources while IFS=$'\t' read name url; do 34 [[ -n "$name" && -n "$url" ]] || die "Malformed sources file" 35 (( $+repo_sources[$name] )) && die "Duplicate repo name: ${(qqq)name}" 36 repo_sources[$name]=$url 37 repos+=( $name ) 38 done 39 } 40 41 make_revisions_new() { 42 unset revisions_new 43 typeset -gA revisions_new 44 45 local name url 46 local -a info 47 for name in $repos; do 48 info=( $($brz version-info $repo_sources[$name]) ) || 49 die_ret $? brz version-info failed 50 [[ $info[1] == "revision-id:" ]] || 51 die malformed brz version-info output 52 revisions_new[$name]=$info[2] 53 printf '%s\t%s\n' $name $info[2] || exit $? 54 done 55 } 56 57 load_old_revisions() { 58 unset revisions_old 59 typeset -gA revisions_old 60 61 local name revid 62 <./bzr/revisions while IFS=$'\t' read name revid; do 63 [[ -n "$name" && -n "$revid" ]] || die "Malformed revisions file" 64 (( $+revisions_old[$name] )) && die "Duplicate repo name: ${(qqq)name}" 65 revisions_old[$name]=$revid 66 done 67 } 68 69 compare_revisions() { 70 unset repo_status 71 typeset -gA repo_status 72 typeset -ga repos_modified repos_added repos_deleted repos_same 73 74 local name old_revid 75 for name in $repos; do 76 if ! (($+revisions_old[$name])); then 77 repo_status[$name]=A 78 repos_added+=( $name ) 79 elif [[ $revisions_new[$name] != $revisions_old[$name] ]]; then; 80 repo_status[$name]=M 81 repos_modified+=( $name ) 82 else 83 repos_same+=( $name ) 84 fi 85 done 86 for name in "${(@k)revisions_old}"; do 87 if ! (($+revisions_new[$name])); then 88 repo_status[$name]=D 89 repos_deleted+=( $name ) 90 fi 91 done 92 } 93 94 bzrlog() { 95 # first argument needs to be revision range 96 $brz log --show-diff --long --forward -r "$@" 97 } 98 99 show_diffs() { 100 local name next_revid 101 for name in $repos_modified; do 102 printf "== showing differences for %s == %s -> %s ==\n" $name $revisions_old[$name] $revisions_new[$name] 103 104 # Displayed revision range is inclusive, but we already have the first revision. 105 next_revid=$( 106 bzr log --long --forward --show-ids \ 107 -r "revid:$revisions_old[$name]..revid:$revisions_new[$name]" \ 108 $repo_sources[$name] \ 109 | awk '/^revision-id: /{if(x){print $2;exit};x=1}' 110 ) 111 bzrlog "revid:$next_revid..revid:$revisions_new[$name]" $repo_sources[$name] 112 done 113 for name in $repos_added; do 114 printf "== showing differences for %s == %s -> %s ==\n" $name start $revisions_new[$name] 115 bzrlog "..revid:$revisions_new[$name]" $repo_sources[$name] 116 done 117 echo --- 118 printf '%d repositories modified' $#repos_modified 119 (( $#repos_modified )) && printf ': %s' "$repos_modified" 120 print 121 122 printf '%d repositories added' $#repos_added 123 (( $#repos_added )) && printf ': %s' "$repos_added" 124 print 125 126 printf '%d repositories deleted' $#repos_deleted 127 (( $#repos_deleted )) && printf ': %s' "$repos_deleted" 128 print 129 130 printf '%d repositories same' $#repos_same 131 (( $#repos_same )) && printf ': %s' "$repos_same" 132 print 133 } 134 135 prompt_commit() { 136 local REPLY 137 local -a msg 138 diff -u ./bzr/revisions ./bzr/revisions.new 139 echo -n "Apply and commit changes? " 140 read -q || exit 0 141 echo 142 msg=( 143 "Update bzr repositories." 144 "Added: "$^repos_added 145 "Changed: "$^repos_modified 146 "Deleted: "$^repos_deleted 147 ) 148 mv -v ./bzr/revisions.new ./bzr/revisions || exit $? 149 git add ./bzr/revisions || exit $? 150 git commit -m "${(F)msg}" ./bzr/revisions || exit $? 151 } 152 153 main() { 154 load_sources 155 make_revisions_new >bzr/revisions.new 156 157 load_old_revisions 158 compare_revisions 159 #printf "%s\t%s\n" "${(@vk)repo_status}" 160 show_diffs | less --quit-if-one-screen 161 if ! (( $#repos_added + $#repos_modified + $#repos_deleted )); then 162 echo "Nothing to do" 163 exit 0 164 fi 165 prompt_commit 166 } 167 #typeset -ft main 168 main