odftc 5.73 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail

svn_uri="https://tools.oasis-open.org/version-control/svn/office/"

function error() {
    echo "Error: $*" >&2
    exit 1
}

function find_exe() {
    local -r exepath=$(type -P "$1")
    local var="$1"
    [[ $# -eq 2 ]] && var="$2"
    [[ -z $exepath ]] && error "Cannot find executable '$1' needed by $exe."
    readonly $var=$exepath
}

readonly exe=${0##*/}
find_exe git
find_exe less
find_exe realpath
find_exe rm
find_exe svn
find_exe svnadmin
find_exe unzip
find_exe zip

# function definitions

function usage() {
    echo -n "\
Usage: $exe checkout VERSION ISSUE 
           Check out the branch for the given VERSION and ISSUE number.

       $exe create VERSION ISSUE
           Create a new branch for the given VERSION and ISSUE number.

       $exe delete VERSION ISSUE
           Delete the branch for the given VERSION and ISSUE number.

       $exe get-local-repo SVNDIR GITDIR
           Mirror the specification svn repository into a local svn repository
           in directory SVNDIR and check it out into the directory GITDIR.

       $exe init [REPOSITORY [DIR]]
           Initialize a local git checkout in DIR of the ODF specification
           subversion repository REPOSITORY.

       $exe list
           List all the branches in the ODF specification subversion.

       $exe log
           Show the subversion log for the ODF specification.

       $exe merge VERSION ISSUE
           Merge the given ISSUE into the given VERSION of the ODF
           specification.

       $exe rebase VERSION ISSUE
           Rebase the given ISSUE branch on the branch for the given VERSION of
           the ODF specification.
" >&2
    exit 1
}

# check out the repository, the repository uri is optional
function init() {
    [[ $# -gt 2 ]] && usage
    [[ $# -gt 1 ]] && svn_uri="$1"
    local git_dir=
    [[ $# -eq 2 ]] && git_dir="$2"
    "$git" svn clone --stdlayout "$svn_uri" "$git_dir"
}

function list() {
    [[ $# -gt 0 ]] && usage
    "$git" branch -r
}

function getSvnUri() {
    local -r msg="$exe must be run from an ODF specification checkout directory."
    [[ -d .git ]] || error "$msg"
    svn_uri=$("$git" config --get svn-remote.svn.url) || "$msg"
}

function parseVersionAndIssue() {
    [[ $# -ne 2 ]] && usage
    getSvnUri
    readonly version=$1
    readonly issue=$2
    [[ $issue =~ ^[0-9]+$ ]] || error "Issue '$issue' is not a number."
    readonly branch="$version"_OFFICE-$issue
}


# create a new branch
function create() {
    parseVersionAndIssue "$@"
    branchExists && error "Branch $branch already exists."
    "$svn" copy "$svn_uri/branches/$version" "$svn_uri/branches/$branch" -m "Create branch $branch"
    "$git" svn fetch
    "$git" checkout "origin/$branch"
}

function delete() {
    parseVersionAndIssue "$@"
    branchExists || error "Branch $branch does not exist."
    "$svn" rm "$svn_uri/branches/$branch" -m "Removing branch $branch."
    "$git" svn fetch
    "$git" checkout "origin/$version"
}

function checkout() {
    parseVersionAndIssue "$@"
    branchExists "$branch" || error "Branch $branch does not exist."
    # determine name of currently checked out branch
    local -r git_output=$("$git" name-rev --name-only HEAD)
    local -r name="${git_output##remotes/origin/}"
    # if the requested branch is not checked out, do so
    [[ $name == $branch ]] || "$git" checkout "origin/$branch"
}

function merge() {
    parseVersionAndIssue "$@"
    branchExists "$branch" || error "Branch $branch does not exist."
    "$git" checkout "origin/$version"
    "$git" merge --no-ff -m "Merge $branch with $version." "origin/$branch"
    "$git" svn dcommit
}

function rebase() {
    checkout "$@"
    "$git" merge --no-ff -m "Rebase $branch on $version." "origin/$version"
    "$git" svn dcommit
}

function log() {
    getSvnUri
    "$svn" log -v "$svn_uri" | "$less"
}

function branchExists() {
    # return 0 if the branch exists and non-zero if it does not exist
    "$git" rev-parse --verify "origin/$branch" &> /dev/null
}

function packOdt() {
    local -r dir=$1
    local -r odt="$dir.odt"
    [[ -e "$odt" ]] && "$rm" "$odt"
    cd "$dir"
    "$zip" -q -D -X -0 "../$odt" mimetype
    "$zip" -q -D -X -9 -r "../$odt" . -x mimetype \*/.\* .\* \*.png \*.jpg \*.jpeg
    "$zip" -q -D -X -0 -r "../$odt" . -i \*.png \*.jpg \*.jpeg
    cd ..
}

function unpackOdt() {
    local -r odt=$1
    local -r dir=${odt%.odt}
    "$rm" -rf "$dir"/*
    "$unzip" -d "$dir" "$odt"
}

function pack() {
    checkout "$@"
    for f in */content.xml; do
        packOdt "${f%/*}"
    done
}

function unpack() {
    [[ $# -eq 0 ]] || usage
    for f in *.odt; do
        unpackOdt "$f"
    done
}

function get-local-repo() {
    [[ $# -ne 2 ]] && usage
    local -r svn_dir=$("$realpath" "$1")
    local -r git_dir=$("$realpath" "$2")
    "$git" svn clone "$svn_uri" "$git_dir"-tmp
    svn_uri="file://$svndir"
    "$svnadmin" create "$svndir"
    "$svn" mkdir --parents "$svn_uri/trunk" "$svn_uri/branches" "$svn_uri/tags" -m 'Create branches.'
    "$git" svn clone "$svn_uri" "$git_dir"
    cd "$git_dir"
    "$git" fetch "$git_dir"-tmp master:tmp
    "$git" checkout tmp
    "$git" rebase master
    "$git" checkout master
    "$git" merge --ff-only tmp
    "$git" svn dcommit
    cd ..
    "$rm" -rf "$git_dir" "$git_dir"-tmp
    init "$svn_uri" "$git_dir"
}

# parse arguments
if [[ $# -eq 0 ]]; then
    usage
fi
readonly CMD=$1
shift

case $CMD in
    checkout|co) checkout "$@";;
    create)      create "$@";;
    delete)      delete "$@";;
    get-local-repo) get-local-repo "$@";;
    init)        init "$@";;
    list)        list "$@";;
    log)         log "$@";;
    merge)       merge "$@";;
    pack)        pack "$@";;
    rebase)      rebase "$@";;
    unpack)      unpack "$@";;
    *)           usage;;
esac