diff options
Diffstat (limited to 'debian/extra/debhelper/dh_bash-completion')
-rwxr-xr-x | debian/extra/debhelper/dh_bash-completion | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/debian/extra/debhelper/dh_bash-completion b/debian/extra/debhelper/dh_bash-completion new file mode 100755 index 0000000..fabae58 --- /dev/null +++ b/debian/extra/debhelper/dh_bash-completion @@ -0,0 +1,177 @@ +#!/usr/bin/perl -w + +=head1 NAME + +dh_bash-completion - install bash completions for package + +=cut + +use strict; +use File::Find; +use Debian::Debhelper::Dh_Lib; + +=head1 SYNOPSIS + +B<dh_bash-completion> [S<I<debhelper options>>] + +=head1 DESCRIPTION + +dh_bash-completion is a debhelper program that is responsible for installing +completions for bash, usable installing the "bash-completion" package. + +In order to use it, you need to pass "--with bash-completion" to debhelper and +Build-depend on bash-completion. + +If a file named debian/package.bash-completion exists, then different actions +are performed, depending on its format. + +It can be a proper completion snippet, and in that case it would be installed +in the completion directory, and no other actions would be performed. + +It can also be a list of files, with an optionally specified name to call the +completion snippet after. The file format is as follows: + + my/path/to/foo-completion # this would be installed as "foo-completion" + my/path/to/bar-completion baz # this would be installed as "baz" + +=cut + +# This helper function tries to determine (using some poor man's +# heuristics) whether $file (its first and only argument) is a +# filelist containing a list of files to be installed by us, or a +# bash-completion script, which should itself be installed. +# +# If we're dealing with a filelist, return 1. Otherwise, return 0. +sub is_filelist { + # The file to be checked. + my ($file) = @_; + + open (DH_FILE, '<', $file) || error("cannot read $file: $!"); + + while (<DH_FILE>) { + # Get rid of lines containing just spaces or comments. + chomp; + s/^\s++//; + next if /^#/; + s/\s++$//; + + # We always ignore/permit empty lines + next if $_ eq ''; + + # This is the heart of the script. Here, we check for some + # well-known idioms on bash scripts, and try to determine if + # they're present in the file we're examining. We assume that + # if they are, then this means the file is a bash-completion + # script. + # + # The regexes check: + # + # - If we're calling the bash function "complete", which is a + # pretty common thing to do in bash-completion scripts, or + # + # - If we're using the $(program) way of executing a program. + # We don't take into account multi-line statements. Or + # + # - If we're calling the bash function "compgen", which is + # also a pretty common thing that bash-completion scripts + # do. Or + # + # - If we see an "if...then" construction in the file. We + # take into account multi-line statements. + if (/(^|[|&;])\s*complete.*-[A-Za-z].*/ + || /\$\(.*\)/ + || /\s*compgen.*-[A-Za-z].*/ + || /\s*if.*;.*then/s) { + return 0; + } + } + + # If we reached the end, this is not a bash-completion script. + return 1; +} + +init(); + +my $srcdir = '.'; +$srcdir = $dh{SOURCEDIR}."/" if defined $dh{SOURCEDIR}; + +# PROMISE: DH NOOP WITHOUT bash-completion cli-options() + +PKG: foreach my $package (@{$dh{DOPACKAGES}}) { + next if is_udeb($package); + + my $tmp = tmpdir($package); + my $bc_dir = "$tmp/usr/share/bash-completion/completions"; + my $completions = pkgfile($package,"bash-completion"); + + my @install; + my $name; + + if ($completions) { + install_dir($bc_dir); + + # Invoke our heuristic function to try and determine + # if we're dealing with a filelist or with a + # bash-completion script. + if (!is_filelist($completions)) { + verbose_print "detected $completions as a bash-completion script"; + install_file($completions, "$bc_dir/$package"); + next PKG + } + + # try parsing a list of files + @install = filedoublearray($completions); + foreach my $set (@install) { + my @filelist; + my @tmp = @$set; + if (@$set > 1) { + $name = pop @$set; + } + else { + $name = basename($tmp[0]); + } + verbose_print "installing $tmp[0] as $name"; + + my @found; + foreach my $glob (@$set) { + @found = glob "$srcdir/$glob"; + if (!compat(6)) { + # Fall back to looking into debian/tmp + if (!@found || !-e $found[0]) { + @found = glob "debian/tmp/$glob"; + } + } + + if (!@found || !-e $found[0]) { + warning "file-list parsing failed, installing as proper snippet"; + + install_file($completions, "$bc_dir/$package"); + next PKG + } + push @filelist, @found; + } + + if (!@filelist) { + error("$package missing files (@$set), aborting"); + } + + foreach my $src (@filelist) { + install_file($src, "$bc_dir/$name"); + } + } + } +} + +=head1 SEE ALSO + +L<debhelper(1)> + +This program is a part of bash-completion. + +L<bash(1)> + +=head1 AUTHOR + +David Paleino <d.paleino@gmail.com> + +=cut |