# -- # 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::Command::Dev::Code::CPANUpdate; use strict; use warnings; use File::Path(); use parent qw(Kernel::System::Console::BaseCommand); our @ObjectDependencies = ( 'Kernel::Config', 'Kernel::System::Main', ); sub Configure { my ( $Self, %Param ) = @_; $Self->Description('Update dependencies in Kernel/cpan-lib.'); $Self->AddOption( Name => 'mode', Description => "Update all dependencies (development), or only critical ones (stable).", Required => 1, HasValue => 1, Multiple => 0, ValueRegex => qr/^stable$/smx, ); return; } sub Run { my ( $Self, %Param ) = @_; my $Home = $Kernel::OM->Get('Kernel::Config')->Get('Home'); my $Mode = $Self->GetOption('mode'); my $CPANDir = "$Home/Kernel/cpan-lib"; if ( $Mode eq 'stable' ) { MODULE_CONFIG: for my $ModuleConfig ( $Self->LoadModuleConfig() ) { next MODULE_CONFIG if !$ModuleConfig->{UpdateInStableMode}; $Self->InstallModule( ModuleConfig => $ModuleConfig, TargetPath => $CPANDir, ); } } elsif ( $Mode eq 'development' ) { my $CPAN2Dir = "$Home/Kernel/cpan-lib2"; # Delete Kernel/cpan-lib. if ( -d $CPAN2Dir ) { File::Path::remove_tree($CPAN2Dir) || die "Could not clean-up $CPAN2Dir: $!."; } File::Path::make_path($CPAN2Dir) || die "Could not create $CPAN2Dir: $!."; # Install modules. MODULE_CONFIG: for my $ModuleConfig ( $Self->LoadModuleConfig() ) { $Self->InstallModule( ModuleConfig => $ModuleConfig, TargetPath => $CPAN2Dir, ); } # Copy our own extension for Devel::REPL from previous cpan-lib folder. File::Path::make_path("$CPAN2Dir/Devel/REPL/Plugin"); system("cp -r $CPANDir/Devel/REPL/Plugin/OTRS.pm $CPAN2Dir/Devel/REPL/Plugin/OTRS.pm"); # Replace cpan-lib folder. File::Path::remove_tree($CPANDir) || die "Could not remove $CPANDir: $!."; rename $CPAN2Dir, $CPANDir || die "Could not replace $CPANDir: $!."; } # Clean-up unwanted files. File::Path::remove_tree("$CPANDir/Test/Selenium"); system("find $CPANDir -name *.pod -exec rm -f {} +"); system("find $CPANDir -name *.pl -exec rm -f {} +"); system("find $CPANDir -name *.so -exec rm -f {} +"); system("find $CPANDir -name *.exists -exec rm -f {} +"); # Fix unwanted 755 permissions. system("find $CPANDir -type f -exec chmod 640 {} +"); my $ReadmeContent = <Get('Kernel::System::Main')->FileWrite( Location => "$CPANDir/README.md", Content => \$ReadmeContent, ); return $Self->ExitCodeOk(); } sub InstallModule { my ( $Self, %Param ) = @_; my $Home = $Kernel::OM->Get('Kernel::Config')->Get('Home'); my $ModuleConfig = $Param{ModuleConfig}; my $TargetPath = $Param{TargetPath}; $Self->Print("Updating $ModuleConfig->{Module}...\n"); my $TmpDir = "$Home/var/tmp/CPANUpdate"; if ( -d $TmpDir ) { File::Path::remove_tree($TmpDir) || die "Could not clean-up $TmpDir: $!."; } File::Path::make_path($TmpDir) || die "Could not create $TmpDir: $!."; my $DownloadURL = `wget -q -O - https://fastapi.metacpan.org/v1/download_url/$ModuleConfig->{Module} | grep download_url | cut -d '"' -f4`; die "Error: Could not get DownloadURL." if !$DownloadURL; chomp $DownloadURL; system("cd $TmpDir; wget -q -O - $DownloadURL | tar -xz --strip 1"); if ( $ModuleConfig->{BuildBLib} ) { system("cd $TmpDir; perl Makefile.PL; make; cp -r $TmpDir/blib/lib/* $TargetPath"); return 1; } if ( -d "$TmpDir/lib" ) { system("cp -r $TmpDir/lib/* $TargetPath"); return 1; } my @ModuleParts = split( m{::}, $ModuleConfig->{Module} ); my $LastModuleLevel = pop @ModuleParts; my $ModulePath = join '/', @ModuleParts; if ( -f "$TmpDir/$LastModuleLevel.pm" ) { if ( !-d "$TargetPath/$ModulePath" ) { File::Path::make_path("$TargetPath/$ModulePath") || die "Could not create $TargetPath/$ModulePath: $!."; } system("cp -r $TmpDir/$LastModuleLevel.pm $TargetPath/$ModulePath"); return 1; } die "Download and/or file extraction of $DownloadURL failed."; } sub LoadModuleConfig { return ( { Module => 'CPAN::Audit', UpdateInStableMode => 1, }, { Module => 'Mozilla::CA', UpdateInStableMode => 1, }, ); } 1;