1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 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
|