summaryrefslogtreecommitdiffstats
path: root/debian/extra/debhelper/dh_bash-completion
diff options
context:
space:
mode:
Diffstat (limited to 'debian/extra/debhelper/dh_bash-completion')
-rwxr-xr-xdebian/extra/debhelper/dh_bash-completion174
1 files changed, 174 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..7999151
--- /dev/null
+++ b/debian/extra/debhelper/dh_bash-completion
@@ -0,0 +1,174 @@
+#!/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.
+
+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