#compdef mvn mvnDebug # ------------------------------------------------------------------------------ # Copyright (c) 2010-2011 Julien Nicoulaud # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # ------------------------------------------------------------------------------ # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et # ------------------------------------------------------------------------------ _mvn() { local curcontext="$curcontext" state line cmds ret=1 mvn_version if _pick_variant maven3=Maven\ 3 maven2 --version; then version_specific_options=( '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -T --threads)'{-T+,--threads=}'[Thread count, for instance 2.0C where C is core multiplied]:thread-count:->thread-count' '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -t --toolchains)'{-t,--toolchains=}'[Alternate path for the user toolchains file]:toolchains-file:->toolchains-file' '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -l --log-file)'{-l,--log-file=}'[Log file to where all build output will go.]:log-file:->log-file' ) else version_specific_options=( '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -cpu --check-plugin-updates -up --update-plugins -npu --no-plugin-updates -o --offline)'{-cpu,--check-plugin-updates,-up,--update-plugins}'[Force upToDate check for any relevant registered plugins.]' '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -npr --no-plugin-registry)'{-npr,--no-plugin-registry}'[Don'\''t use ~/.m2/plugin-registry.xml for plugin versions.]' '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -npu --no-plugin-updates -cpu --check-plugin-updates -up --update-plugins)'{-npu,--no-plugin-updates}'[Suppress upToDate check for any relevant registered plugins.]' '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -r --reactor)'{-r,--reactor}'[Dynamically build reactor from subdirectories.]:reactor:->reactor' ) fi # FIXME -am and -amd should only be added if -pl is present _arguments -C \ '(- 1 *)'{-h,--help}'[Display help information]' \ '(- 1 *)'{-v,--version}'[Display version information]' \ '(- 1 *)'{-emp,--encrypt-master-password}'[Encrypt master security password]' \ '(- 1 *)'{-ep,--encrypt-password}'[Encrypt server password]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -B --batch-mode)'{-B,--batch-mode}'[Run in non-interactive (batch) mode]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -V --show-version)'{-V,--show-version}'[Display version information WITHOUT stopping build]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -q --quiet -X --debug)'{-q,--quiet}'[Quiet output - only show errors]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -X --debug -q --quiet)'{-X,--debug}'[Produce execution debug output]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -N --non-recursive)'{-N,--non-recursive}'[Do not recurse into sub-projects]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -C --strict-checksums -c --lax-checksums)'{-C,--strict-checksums}'[Fail the build if checksums don'\''t match]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -c --lax-checksums -C --strict-checksums)'{-c,--lax-checksums}'[Warn if checksums don'\''t match]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -e --errors)'{-e,--errors}'[Produce execution error messages]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -f --file)'{-f,--file=}'[Force the use of an alternate POM file.]:pom-file:->pom-file' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -s --settings)'{-s,--settings=}'[Alternate path for the user settings file]:settings-file:->settings-file' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -gs --global-settings)'{-gs,--global-settings=}'[Alternate path for the global settings file]:settings-file:->settings-file' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -fae --fail-at-end -ff --fail-fast -fn --fail-never)'{-fae,--fail-at-end}'[Only fail the build afterwards; allow all non-impacted builds to continue]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -ff --fail-fast -fae --fail-at-end -fn --fail-never)'{-ff,--fail-fast}'[Stop at first failure in reactorized builds]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -fn --fail-never -fae --fail-at-end -ff --fail-fast)'{-fn,--fail-never}'[NEVER fail the build, regardless of project result]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -P --activate-profiles)'{-P,--activate-profiles=}'[Comma-delimited list of profiles to activate]:profile:->profile' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -pl --projects)'{-pl,--projects=}'[Build specified reactor projects instead of all projects. A project can be specified by groupId:artifactId or by its relative path.]:project-list:->project-list' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -am --also-make)'{-am,--also-make}'[If project list is specified, also build projects required by the list]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -amd --also-make-dependents)'{-amd,--also-make-dependents}'[If project list is specified, also build projects that depend on projects on the list]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -rf --resume-from)'{-rf,--resume-from=}'[Resume reactor from specified project]:project:->project' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -o --offline -U --update-snapshots -cpu --check-plugin-updates -up --update-plugins)'{-o,--offline}'[Work offline]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -U --update-snapshots -nsu --no-snapshot-updates -o --offline)'{-U,--update-snapshots}'[Forces a check for updated releases and snapshots on remote repositories]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password -nsu --no-snapshot-updates -U --update-snapshots -o --offline)'{-nsu,--no-snapshot-updates}'[Supress SNAPSHOT updates]' \ '(-h --help -v --version -ep --encrypt-password -emp --encrypt-master-password)'{-D-,--define}'[Define a system property]:property:->property' \ "$version_specific_options[@]" \ '*: :->args' \ && ret=0 if [[ -n "$state" ]]; then case "$state" in pom-file) _wanted pom-files expl pom-file _mvn_pom_files && ret=0 ;; settings-file) _wanted settings-files expl settings-file _mvn_settings_files && ret=0 ;; profile) _wanted profiles expl profile _mvn_profiles && ret=0 ;; project) _wanted projects expl project _mvn_projects && ret=0 ;; project-list) _wanted project-lists expl project-list _mvn_project_lists && ret=0 ;; log-file) _wanted log-files expl log-file _mvn_log_files && ret=0 ;; toolchains-file) _wanted toolchains-files expl toolchains-file _mvn_toolchains_files && ret=0 ;; property) _wanted properties expl property _mvn_properties && ret=0 ;; reactor) _wanted reactors expl reactor _mvn_reactors && ret=0 ;; thread-count) _wanted thread-counts expl thread-count _mvn_thread_counts && ret=0 ;; args) _alternative \ 'phases:phase:_mvn_phases' \ 'goals:goal:_mvn_goals' \ && ret=0 ;; esac fi } _mvn_phases() { # FIXME Make it complete advanced phases only if the user started typing it. local ret=1 _values 'phase' \ 'pre-clean[executes\ processes\ needed\ prior\ to\ the\ actual\ project\ cleaning.]' \ 'clean[remove\ all\ files\ generated\ by\ the\ previous\ build.]' \ 'post-clean[executes\ processes\ needed\ to\ finalize\ the\ project\ cleaning.]' \ 'validate[validate\ the\ project\ is\ correct\ and\ all\ necessary\ information\ is\ available.]' \ 'initialize[initialize\ build\ state,\ e.g.\ set\ properties\ or\ create\ directories.]' \ 'generate-sources[generate\ any\ source\ code\ for\ inclusion\ in\ compilation.]' \ 'process-sources[process\ the\ source\ code,\ for\ example\ to\ filter\ any\ values.]' \ 'generate-resources[generate\ resources\ for\ inclusion\ in\ the\ package.]' \ 'process-resources[copy\ and\ process\ the\ resources\ into\ the\ destination\ directory,\ ready\ for\ packaging.]' \ 'compile[compile\ the\ source\ code\ of\ the\ project.]' \ 'process-classes[post-process\ the\ generated\ files\ from\ compilation,\ for\ example\ to\ do\ bytecode\ enhancement\ on\ Java\ classes.]' \ 'generate-test-sources[generate\ any\ test\ source\ code\ for\ inclusion\ in\ compilation.]' \ 'process-test-sources[process\ the\ test\ source\ code,\ for\ example\ to\ filter\ any\ values.]' \ 'generate-test-resources[create\ resources\ for\ testing.]' \ 'process-test-resources[copy\ and\ process\ the\ resources\ into\ the\ test\ destination\ directory.]' \ 'test-compile[compile\ the\ test\ source\ code\ into\ the\ test\ destination\ directory.]' \ 'process-test-classes[post-process\ the\ generated\ files\ from\ test\ compilation,\ for\ example\ to\ do\ bytecode\ enhancement\ on\ Java\ classes.\ For\ Maven\ 2.0.5\ and\ above.]' \ 'test[run\ tests\ using\ a\ suitable\ unit\ testing\ framework.\ These\ tests\ should\ not\ require\ the\ code\ be\ packaged\ or\ deployed.]' \ 'prepare-package[perform\ any\ operations\ necessary\ to\ prepare\ a\ package\ before\ the\ actual\ packaging.\ This\ often\ results\ in\ an\ unpacked,\ processed\ version\ of\ the\ package.]' \ 'package[take\ the\ compiled\ code\ and\ package\ it\ in\ its\ distributable\ format,\ such\ as\ a\ JAR.]' \ 'pre-integration-test[perform\ actions\ required\ before\ integration\ tests\ are\ executed.\ This\ may\ involve\ things\ such\ as\ setting\ up\ the\ required\ environment.]' \ 'integration-test[process\ and\ deploy\ the\ package\ if\ necessary\ into\ an\ environment\ where\ integration\ tests\ can\ be\ run.]' \ 'post-integration-test[perform\ actions\ required\ after\ integration\ tests\ have\ been\ executed.\ This\ may\ including\ cleaning\ up\ the\ environment.]' \ 'verify[run\ any\ checks\ to\ verify\ the\ package\ is\ valid\ and\ meets\ quality\ criteria.]' \ 'install[install\ the\ package\ into\ the\ local\ repository,\ for\ use\ as\ a\ dependency\ in\ other\ projects\ locally.]' \ 'deploy[done\ in\ an\ integration\ or\ release\ environment,\ copies\ the\ final\ package\ to\ the\ remote\ repository\ for\ sharing\ with\ other\ developers\ and\ projects.]' \ 'pre-site[executes\ processes\ needed\ prior\ to\ the\ actual\ project\ site\ generation.]' \ 'site[generates\ the\ projects\ site\ documentation.]' \ 'post-site[executes\ processes\ needed\ to\ finalize\ the\ site\ generation,\ and\ to\ prepare\ for\ site\ deployment.]' \ 'site-deploy[deploys\ the\ generated\ site\ documentation\ to\ the\ specified\ web\ server.]' \ && ret=0 } _mvn_goals(){ # TODO to be implemented local ret=1 #goals=( # 'release:clean' # 'release:prepare' # 'release:prepare-with-pom' # 'release:rollback' # 'release:perform' # 'release:stage' # 'release:branch' # 'release:update-versions' #) #_multi_parts ':' goals #_sep_parts } _mvn_reactors(){ # FIXME No idea what kind of value the "--reactor" is supposed to take local ret=1 _message -e reactors 'reactor' && ret=0 } _mvn_thread_counts(){ _message -e thread-counts 'thread count' && ret=0 } _mvn_pom_files(){ local ret=1 _files -g '*pom*\.xml*' && ret=0 } _mvn_toolchains_files(){ local ret=1 _files && ret=0 } _mvn_settings_files(){ local ret=1 _files -g '*settings*\.xml*' && ret=0 } _mvn_log_files(){ local ret=1 _files && ret=0 } _mvn_profiles() { # FIXME This could be done more reliabily using "mvn -f pom-file -N help:all-profiles" + caching. local ret=1 in_profile=false profiles for file in pom.xml ~/.m2/settings.xml; do for line in $(command cat $file 2>/dev/null); do if $in_profile && [[ $line == *''* ]]; then profiles+=("${${line##*}%%<\/id>*}[in $file]") in_profile=false elif [[ $line == *''* ]]; then in_profile=true fi done done _values -s , 'profile' "$profiles[@]" && ret=0 } _mvn_projects() { # TODO projects can also be given in the form [groupId:]artifactId. local ret=1 projects for project in $(command ls */(**~target)/pom.xml 2>/dev/null); do # FIXME Only recurse when needed ? projects+=("$(dirname $project)[]") # TODO: Add project name as description done _values 'project list' "$projects[@]" && ret=0 } _mvn_project_lists() { # TODO projects can also be given in the form [groupId:]artifactId. local ret=1 projects for project in $(command ls */(**~target)/pom.xml 2>/dev/null); do # FIXME Only recurse when needed ? projects+=("$(dirname $project)[]") # TODO: Add project name as description done _values -s , 'project' "$projects[@]" && ret=0 } _mvn_properties() { # TODO Complete some very common props like -DskipTests, etc. local ret=1 _message -e property-names 'property name' && ret=0 } _mvn "$@"