# File: Updater.pm # # Purpose: Migrates data files from older versions to newer versions. # # Updates data/configration files to new locations/formats based # on versioning information. Ensures data/configuration files are in the # proper location and using the latest data structure. # SPDX-FileCopyrightText: 2021 Pragmatic Software # SPDX-License-Identifier: MIT package PBot::Updater; use parent 'PBot::Class'; use PBot::Imports; use File::Basename; sub initialize { my ($self, %conf) = @_; $self->{data_dir} = $conf{data_dir}; $self->{update_dir} = $conf{update_dir}; } sub update { my ($self) = @_; $self->{pbot}->{logger}->log("Checking if update needed...\n"); my $current_version = $self->get_current_version; my $last_update_version = $self->get_last_update_version; $self->{pbot}->{logger}->log("Current version: $current_version; last update version: $last_update_version\n"); if ($last_update_version >= $current_version) { $self->{pbot}->{logger}->log("No update necessary.\n"); return $self->put_last_update_version($current_version); } my @updates = $self->get_available_updates($last_update_version); if (not @updates ) { $self->{pbot}->{logger}->log("No updates available.\n"); return $self->put_last_update_version($current_version); } foreach my $update (@updates) { $self->{pbot}->{logger}->log("Executing update script: $update\n"); my $output = `$update "$self->{data_dir}" $current_version $last_update_version`; my $exit = $? >> 8; foreach my $line (split /\n/, $output) { $self->{pbot}->{logger}->log(" $line\n"); } $self->{pbot}->{logger}->log("Update script completed " . ($exit ? "unsuccessfully (exit $exit)" : 'successfully') . "\n"); return $exit if $exit != 0; } return $self->put_last_update_version($current_version); } sub get_available_updates { my ($self, $last_update_version) = @_; my @updates = sort glob "$self->{update_dir}/*.pl"; return grep { my ($version) = split /_/, basename $_; $version > $last_update_version } @updates; } sub get_current_version { return PBot::VERSION::BUILD_REVISION; } sub get_last_update_version { my ($self) = @_; open(my $fh, '<', "$self->{data_dir}/last_update") or return 0; chomp(my $last_update = <$fh>); close $fh; return $last_update; } sub put_last_update_version { my ($self, $version) = @_; if (open(my $fh, '>', "$self->{data_dir}/last_update")) { print $fh "$version\n"; close $fh; return 0; } else { $self->{pbot}->{logger}->log("Could not save last update version to $self->{data_dir}/last_update: $!\n"); return 1; } } 1;