123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
- package Dpkg::ErrorHandling;
- use strict;
- use warnings;
- our $VERSION = '0.02';
- our @EXPORT_OK = qw(
- REPORT_PROGNAME
- REPORT_COMMAND
- REPORT_STATUS
- REPORT_DEBUG
- REPORT_INFO
- REPORT_NOTICE
- REPORT_WARN
- REPORT_ERROR
- report_pretty
- report_color
- report
- );
- our @EXPORT = qw(
- report_options
- debug
- info
- notice
- warning
- error
- errormsg
- syserr
- printcmd
- subprocerr
- usageerr
- );
- use Exporter qw(import);
- use Term::ANSIColor;
- use Dpkg ();
- use Dpkg::Gettext;
- my $quiet_warnings = 0;
- my $debug_level = 0;
- my $info_fh = \*STDOUT;
- my $use_color = 0;
- sub setup_color
- {
- my $mode = $ENV{'DPKG_COLORS'} // 'auto';
- if ($mode eq 'auto') {
- ## no critic (InputOutput::ProhibitInteractiveTest)
- $use_color = 1 if -t *STDOUT or -t *STDERR;
- } elsif ($mode eq 'always') {
- $use_color = 1;
- } else {
- $use_color = 0;
- }
- }
- setup_color();
- use constant {
- REPORT_PROGNAME => 1,
- REPORT_COMMAND => 2,
- REPORT_STATUS => 3,
- REPORT_INFO => 4,
- REPORT_NOTICE => 5,
- REPORT_WARN => 6,
- REPORT_ERROR => 7,
- REPORT_DEBUG => 8,
- };
- my %report_mode = (
- REPORT_PROGNAME() => {
- color => 'bold',
- },
- REPORT_COMMAND() => {
- color => 'bold magenta',
- },
- REPORT_STATUS() => {
- color => 'clear',
- # We do not translate this name because the untranslated output is
- # part of the interface.
- name => 'status',
- },
- REPORT_DEBUG() => {
- color => 'clear',
- # We do not translate this name because it is a developer interface
- # and all debug messages are untranslated anyway.
- name => 'debug',
- },
- REPORT_INFO() => {
- color => 'green',
- name => g_('info'),
- },
- REPORT_NOTICE() => {
- color => 'yellow',
- name => g_('notice'),
- },
- REPORT_WARN() => {
- color => 'bold yellow',
- name => g_('warning'),
- },
- REPORT_ERROR() => {
- color => 'bold red',
- name => g_('error'),
- },
- );
- sub report_options
- {
- my (%options) = @_;
- if (exists $options{quiet_warnings}) {
- $quiet_warnings = $options{quiet_warnings};
- }
- if (exists $options{debug_level}) {
- $debug_level = $options{debug_level};
- }
- if (exists $options{info_fh}) {
- $info_fh = $options{info_fh};
- }
- }
- sub report_name
- {
- my $type = shift;
- return $report_mode{$type}{name} // '';
- }
- sub report_color
- {
- my $type = shift;
- return $report_mode{$type}{color} // 'clear';
- }
- sub report_pretty
- {
- my ($msg, $color) = @_;
- if ($use_color) {
- return colored($msg, $color);
- } else {
- return $msg;
- }
- }
- sub _progname_prefix
- {
- return report_pretty("$Dpkg::PROGNAME: ", report_color(REPORT_PROGNAME));
- }
- sub _typename_prefix
- {
- my $type = shift;
- return report_pretty(report_name($type), report_color($type));
- }
- sub report(@)
- {
- my ($type, $msg) = (shift, shift);
- $msg = sprintf($msg, @_) if (@_);
- my $progname = _progname_prefix();
- my $typename = _typename_prefix($type);
- return "$progname$typename: $msg\n";
- }
- sub debug
- {
- my $level = shift;
- print report(REPORT_DEBUG, @_) if $level <= $debug_level;
- }
- sub info($;@)
- {
- print { $info_fh } report(REPORT_INFO, @_) if not $quiet_warnings;
- }
- sub notice
- {
- warn report(REPORT_NOTICE, @_) if not $quiet_warnings;
- }
- sub warning($;@)
- {
- warn report(REPORT_WARN, @_) if not $quiet_warnings;
- }
- sub syserr($;@)
- {
- my $msg = shift;
- die report(REPORT_ERROR, "$msg: $!", @_);
- }
- sub error($;@)
- {
- die report(REPORT_ERROR, @_);
- }
- sub errormsg($;@)
- {
- print { *STDERR } report(REPORT_ERROR, @_);
- }
- sub printcmd
- {
- my (@cmd) = @_;
- print { *STDERR } report_pretty(" @cmd\n", report_color(REPORT_COMMAND));
- }
- sub subprocerr(@)
- {
- my ($p) = (shift);
- $p = sprintf($p, @_) if (@_);
- require POSIX;
- if (POSIX::WIFEXITED($?)) {
- error(g_('%s gave error exit status %s'), $p, POSIX::WEXITSTATUS($?));
- } elsif (POSIX::WIFSIGNALED($?)) {
- error(g_('%s died from signal %s'), $p, POSIX::WTERMSIG($?));
- } else {
- error(g_('%s failed with unknown exit code %d'), $p, $?);
- }
- }
- my $printforhelp = g_('Use --help for program usage information.');
- sub usageerr(@)
- {
- my ($msg) = (shift);
- $msg = sprintf($msg, @_) if (@_);
- warn report(REPORT_ERROR, $msg);
- warn "\n$printforhelp\n";
- exit(2);
- }
- 1;
|