Tuesday, August 21, 2007

Cygwin BASH wrapper for Maven deploy:deploy-file

I frequently use Maven's deploy:deploy-file mojo for building project-local repositories.

Many interesting 3rd-party Java libraries are not (yet) available from public Maven repositories (the otherwise excellent dev.java.net projects are particularly weak in this respect), but I want to use them in my project POM. What to do?

I store them with my project. This is not an ideal solution, but it is practical.

To help me deploying jars, sources and javadocs I wrote a simple BASH wrapper script for Cygwin (to run under Linux/UNIX requires a trivial change). Here is typical use:

$ mvn-file-deploy ~/IdeaProjects/Scratch/lib cool-library-1.0.4.jar org.cool.library:cool-library:1.0.4
$ mvn-file-deploy -S ~/IdeaProjects/Scratch/lib cool-library-1.0.4-sources.jar org.cool.library:cool-library:1.0.4
$ mvn-file-deploy -J ~/IdeaProjects/Scratch/lib cool-library-1.0.4-javadocs.jar org.cool.library:cool-library:1.0.4

And the script itself:

#!/bin/bash

function help()
{
    cat <<'EOH' | fmt
Usage: mvn-file-deploy [options] REPO_PATH FILE_PATH DESCRIPTOR [CLASSIFIER]

Use mvn-file-deploy as a helper for 'mvn deploy:deploy-file' when using Cygwin.

EOH
    cat <<'EOH'
Options:
  -h, --help          Print this help message
      --version       Print program version
  -S, --sources       Deploy sources
  -J, --javadocs      Deploy javadocs
  -q, --quiet         Do not print maven command
EOH
    cat <<'EOH' | fmt

Other options are passed to Maven.  (BROKEN)

Examples:

The most common use is to run it like this:

    $ mvn-file-deploy C:/my/project/lib C:/some/interesting.jar groupId:artifactId:version

Or if you use a classifier (e.g., jdk5):

But sometimes like this.

    $ mvn-file-deploy C:/my/project/lib C:/some/interesting.jar groupId:artifactId:version classifier

Report bugs to <binkley@alumni.rice.edu>.
EOH
}

function version()
{
    cat <<'EOV' | fmt
mvn-file-deploy 1.0
Copyright (C) 2007 JPMorganChase, Inc.  All rights reserved.
EOV
}

function fatal()
{
    echo "$0: $*" >&2
    exit 2
}

function usage() 
{
    cat <<'EOU' | fmt >&2
usage: mvn-file-deploy [options] REPO_PATH FILE_PATH DESCRIPTOR [CLASSIFIER]
EOU
}

eval set -- "$(getopt -o hJSq --long help,javadocs,sources,quiet,version -n "$0" -- "$@")"

declare -a maven_opts
declare -a args

for opt
do
    shift
    case "$opt" in
        -h|--help ) help ; exit 0 ;;
        -J|--javadocs ) classifier=-Dclassifier=javadocs ;;
        -S|--sources ) classifier=-Dclassifier=sources ;;
        --version ) version ; exit 0 ;;
        -q|--quiet ) quiet=t ; maven_opts=("${maven_opts[@]}" "$opt") ;;
        -- ) break ;;
        -* ) maven_opts=("${maven_opts[@]}" "$opt") ;;
    esac
done

case $# in
    3 ) repo_path="$1"
        file_path="$2"
        descriptor="$3" ;;
    4 ) repo_path="$1"
        file_path="$2"
        descriptor="$3"
        classifier=-Dclassifier="$4" ;;
    * ) usage ; exit 2 ;;
esac

(cd "$repo_path" 2>/dev/null) || \
    fatal "No such repository path: $repo_path"

repo_url="file://$(cygpath -am "$repo_path")"
file_path="$(cygpath -am "$file_path")"

[[ -r "$file_path" ]] || \
    fatal "No such artifact: $file_path"

triplet=($(echo $descriptor | tr : ' '))

(( 3 == ${#triplet[*]} )) || \
    fatal "Descriptor not groupId:artifactId:version format: $descriptor"

packaging=-Dpackaging="${file_path##*.}"

[[ -n "$quiet" ]] ||
    echo mvn "${maven_opts[@]}" deploy:deploy-file -Durl="$repo_url" \
        -DrepositoryId=project -Dfile="$file_path" -DgroupId=${triplet[0]} \
        -DartifactId=${triplet[1]} -Dversion=${triplet[2]} \
        $packaging $classifier
exec mvn "${maven_opts[@]}" deploy:deploy-file -Durl="$repo_url" \
    -DrepositoryId=project -Dfile="$file_path" -DgroupId=${triplet[0]} \
    -DartifactId=${triplet[1]} -Dversion=${triplet[2]} \
    $packaging $classifier

No comments: