1 #!/usr/bin/perl 2 # 3 # Licensed to the Apache Software Foundation (ASF) under one or more 4 # contributor license agreements. See the NOTICE file distributed with 5 # this work for additional information regarding copyright ownership. 6 # The ASF licenses this file to You under the Apache License, Version 2.0 7 # (the "License"); you may not use this file except in compliance with 8 # the License. You may obtain a copy of the License at 9 # 10 # http://www.apache.org/licenses/LICENSE-2.0 11 # 12 # Unless required by applicable law or agreed to in writing, software 13 # distributed under the License is distributed on an "AS IS" BASIS, 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 # See the License for the specific language governing permissions and 16 # limitations under the License. 17 # 18 # A script to allow Bash or Z-Shell to complete an Ant command-line. 19 # 20 # To install for Bash 2.0 or better, add the following to ~/.bashrc: 21 # 22 # $ complete -C complete-ant-cmd ant build.sh 23 # 24 # To install for Z-Shell 2.5 or better, add the following to ~/.zshrc: 25 # 26 # function ant_complete () { 27 # local args_line args 28 # read -l args_line 29 # set -A args $args_line 30 # set -A reply $(COMP_LINE=$args_line complete-ant-cmd ${args[1]} $1) 31 # } 32 # compctl -K ant_complete ant build.sh 33 # 34 # @author Mike Williams <mikew (at] cortexebusiness.com.au> 35 36 my $cmdLine = $ENV{'COMP_LINE'}; 37 my $antCmd = $ARGV[0]; 38 my $word = $ARGV[1]; 39 40 my @completions; 41 if ($word =~ /^-/) { 42 list( restrict( $word, getArguments() )); 43 } elsif ($cmdLine =~ /-(f|buildfile)\s+\S*$/) { 44 list( getBuildFiles($word) ); 45 } else { 46 list( restrict( $word, getTargets() )); 47 } 48 49 exit(0); 50 51 sub list { 52 for (@_) { 53 print "$_\n"; 54 } 55 } 56 57 sub restrict { 58 my ($word, @completions) = @_; 59 grep( /^\Q$word\E/, @completions ); 60 } 61 62 sub getArguments { 63 qw(-buildfile -debug -emacs -f -find -help -listener -logfile 64 -logger -projecthelp -quiet -verbose -version); 65 } 66 67 68 sub getBuildFiles { 69 my ($word) = @_; 70 grep( /\.xml$/, glob( "$word*" )); 71 } 72 73 sub getTargets { 74 75 # Look for build-file 76 my $buildFile = 'build.xml'; 77 if ($cmdLine =~ /-(f|buildfile)\s+(\S+)/) { 78 $buildFile = $2; 79 } 80 return () unless (-f $buildFile); 81 82 # Run "ant -projecthelp" to list targets. Keep a cache of results in a 83 # cache-file. 84 my $cacheFile = $buildFile; 85 $cacheFile =~ s|(.*/)?(.*)|${1}.ant-targets-${2}|; 86 if ((!-e $cacheFile) || (-M $buildFile) < (-M $cacheFile)) { 87 open( CACHE, '>'.$cacheFile ) || die "can\'t write $cacheFile: $!\n"; 88 open( HELP, "$antCmd -projecthelp -f '$buildFile'|" ) || return(); 89 my %targets; 90 while( <HELP> ) { 91 if (/^\s+(\S+)/) { 92 $targets{$1}++; 93 } 94 } 95 my @targets = sort keys %targets; 96 for (@targets) { print CACHE "$_\n"; } 97 return @targets; 98 } 99 100 # Read the target-cache 101 open( CACHE, $cacheFile ) || die "can\'t read $cacheFile: $!\n"; 102 my @targets; 103 while (<CACHE>) { 104 chop; 105 s/\r$//; # for Cygwin 106 push( @targets, $_ ); 107 } 108 close( CACHE ); 109 @targets; 110 111 } 112 113 114 115