# -- # Copyright (C) 2001-2019 OTRS AG, https://otrs.com/ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (GPL). If you # did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. # -- package Kernel::System::Console::BaseCommand; use strict; use warnings; use Getopt::Long(); use Term::ANSIColor(); use IO::Interactive(); use Encode::Locale(); use Kernel::System::VariableCheck qw(:all); our @ObjectDependencies = ( 'Kernel::Config', 'Kernel::System::Cache', 'Kernel::System::Encode', 'Kernel::System::Main', ); our $SuppressANSI = 0; =head1 NAME Kernel::System::Console::BaseCommand - command base class =head1 DESCRIPTION Base class for console commands. =head1 PUBLIC INTERFACE =head2 new() constructor for new objects. You should not need to reimplement this in your command, override L instead if you need to. =cut sub new { my ( $Type, %Param ) = @_; my $Self = {}; bless( $Self, $Type ); # for usage help $Self->{Name} = $Type; $Self->{Name} =~ s{Kernel::System::Console::Command::}{}smx; $Self->{ANSI} = 1; # Check if we are in an interactive terminal, disable colors otherwise. if ( !IO::Interactive::is_interactive() ) { $Self->{ANSI} = 0; } # Force creation of the EncodeObject as it initialzes STDOUT/STDERR for unicode output. $Kernel::OM->Get('Kernel::System::Encode'); # Call object specific configure method. We use an eval to trap any exceptions # that might occur here. Only if everything was ok we set the _ConfigureSuccessful # flag. eval { $Self->Configure(); $Self->{_ConfigureSuccessful} = 1; }; $Self->{_GlobalOptions} = [ { Name => 'help', Description => 'Display help for this command.', }, { Name => 'no-ansi', Description => 'Do not perform ANSI terminal output coloring.', }, { Name => 'quiet', Description => 'Suppress informative output, only retain error messages.', }, { Name => 'allow-root', Description => 'Allow root user to execute the command. This might damage your system; use at your own risk.', Invisible => 1, # hide from usage screen }, ]; return $Self; } =head2 Configure() initializes this object. Override this method in your commands. This method might throw exceptions. =cut sub Configure { return; } =head2 Name() get the Name of the current Command, e. g. 'Admin::User::SetPassword'. =cut sub Name { my ($Self) = @_; return $Self->{Name}; } =head2 Description() get/set description for the current command. Call this in your Configure() method. =cut sub Description { my ( $Self, $Description ) = @_; $Self->{Description} = $Description if defined $Description; return $Self->{Description}; } =head2 AdditionalHelp() get/set additional help text for the current command. Call this in your Configure() method. You can use color tags (see L) in your help tags. =cut sub AdditionalHelp { my ( $Self, $AdditionalHelp ) = @_; $Self->{AdditionalHelp} = $AdditionalHelp if defined $AdditionalHelp; return $Self->{AdditionalHelp}; } =head2 AddArgument() adds an argument that can/must be specified on the command line. This function must be called during Configure() by the command to indicate which arguments it can process. $CommandObject->AddArgument( Name => 'filename', Description => 'name of the file to be loaded', Required => 1, ValueRegex => qr{a-zA-Z0-9]\.txt}, ); Please note that required arguments have to be specified before any optional ones. The information about known arguments and options (see below) will be used to generate usage help and also to automatically verify the data provided by the user on the command line. =cut sub AddArgument { my ( $Self, %Param ) = @_; for my $Key (qw(Name Description ValueRegex)) { if ( !$Param{$Key} ) { $Self->PrintError("Need $Key."); die; } } for my $Key (qw(Required)) { if ( !defined $Param{$Key} ) { $Self->PrintError("Need $Key."); die; } } if ( $Self->{_ArgumentSeen}->{ $Param{Name} }++ ) { $Self->PrintError("Cannot register argument '$Param{Name}' twice."); die; } if ( $Self->{_OptionSeen}->{ $Param{Name} } ) { $Self->PrintError("Cannot add argument '$Param{Name}', because it is already registered as an option."); die; } $Self->{_Arguments} //= []; push @{ $Self->{_Arguments} }, \%Param; return; } =head2 GetArgument() fetch an argument value as provided by the user on the command line. my $Filename = $CommandObject->GetArgument('filename'); =cut sub GetArgument { my ( $Self, $Argument ) = @_; if ( !$Self->{_ArgumentSeen}->{$Argument} ) { $Self->PrintError("Argument '$Argument' was not configured and cannot be accessed."); return; } return $Self->{_ParsedARGV}->{Arguments}->{$Argument}; } =head2 AddOption() adds an option that can/must be specified on the command line. This function must be called during L by the command to indicate which arguments it can process. $CommandObject->AddOption( Name => 'iterations', Description => 'number of script iterations to perform', Required => 1, HasValue => 0, ValueRegex => qr{\d+}, Multiple => 0, # optional, allow more than one occurrence (only possible if HasValue is true) ); B