From 73d47533e18c137190e997dfc9a27bffe78e164c Mon Sep 17 00:00:00 2001 From: Matthew Horsfall Date: Mon, 12 Aug 2019 22:12:15 -0400 Subject: [PATCH] Upgrade: Only check reactors/channels specified by config That way if new modules are added (but not used on the running instance of synergy) an upgrade will still (rightly) succeed. --- lib/Synergy/Hub.pm | 24 ++++++++++------ lib/Synergy/Reactor/Upgrade.pm | 51 ++++++++++++++++++++++++++++++---- t/basic.t | 6 ++-- t/dates.t | 6 ++-- t/exclusive.t | 6 ++-- t/httpendpoint.t | 6 ++-- t/https.t | 6 ++-- t/httpserver.t | 6 ++-- t/lp-task-spec.t | 6 ++-- t/page.t | 6 ++-- t/prometheus.t | 6 ++-- 11 files changed, 88 insertions(+), 41 deletions(-) diff --git a/lib/Synergy/Hub.pm b/lib/Synergy/Hub.pm index 581b95f7..97d293bd 100644 --- a/lib/Synergy/Hub.pm +++ b/lib/Synergy/Hub.pm @@ -24,6 +24,11 @@ use URI; use Scalar::Util qw(blessed); use Defined::KV; +has config_file => ( + is => 'ro', + isa => 'Maybe[Str]', +); + has name => ( is => 'ro', isa => 'Str', @@ -295,11 +300,10 @@ sub set_loop ($self, $loop) { return $loop; } -sub synergize { - my $class = shift; - my ($loop, $config) = @_ == 2 ? @_ - : @_ == 1 ? (undef, @_) - : confess("weird arguments passed to synergize"); +sub synergize ($class, $arg) { + my $loop = delete $arg->{loop}; + my $config = delete $arg->{config}; + my $config_file = delete $arg->{config_file}; $loop //= do { require IO::Async::Loop; @@ -321,6 +325,7 @@ sub synergize { defined_kv(tls_cert_file => $config->{tls_cert_file}), defined_kv(tls_key_file => $config->{tls_key_file}), defined_kv(state_dbfile => $config->{state_dbfile}), + config_file => $config_file, }); $directory->register_with_hub($hub); @@ -384,10 +389,11 @@ sub synergize_file { : $filename =~ /\.toml\z/ ? \&_slurp_toml_file : confess "don't know how to synergize_file $filename"; - return $class->synergize( - ($loop ? $loop : ()), - $reader->($filename), - ); + return $class->synergize({ + loop => $loop, + config => $reader->($filename), + config_file => $filename, + }); } has http_client => ( diff --git a/lib/Synergy/Reactor/Upgrade.pm b/lib/Synergy/Reactor/Upgrade.pm index f85857e3..854a9329 100644 --- a/lib/Synergy/Reactor/Upgrade.pm +++ b/lib/Synergy/Reactor/Upgrade.pm @@ -10,6 +10,8 @@ use namespace::clean; use File::pushd; use File::Find; use Path::Tiny; +use YAML::XS; +use Try::Tiny; has git_dir => ( is => 'ro', @@ -180,10 +182,48 @@ sub get_version_desc ($self) { $output; } -sub check_next { +sub check_next ($self, @) { + my $cf = $self->hub->config_file; + + # No config file? Huh. Do normal check + return $self->check_next_file_find unless $cf; + + my $reader = $cf =~ /\.ya?ml\z/ ? sub { YAML::XS::LoadFile($_[0]) } + : $cf =~ /\.json\z/ ? \&Synergy::Hub::_slurp_json_file + : $cf =~ /\.toml\z/ ? \&Synergy::Hub::_slurp_toml_file + : undef; + + return $self->check_next_file_find unless $reader; + + my ($config, $err); + + try { + $config = $reader->($cf); + } catch { + $err = "Failed to parse config ($cf): $_"; + }; + + return $err if $err; + + my %allowed; + + for my $thing (qw( channels reactors )) { + for my $thing_config (values %{ $config->{$thing} }) { + my $thing_class = delete $thing_config->{class}; + + next unless $thing_class; + + $allowed{$thing_class} = 1; + } + } + + return $self->check_next_file_find(\%allowed); +} + +sub check_next_file_find ($self, $allowed = {}) { my $data = "use lib qw(lib);\n"; - find(sub { wanted(\$data) }, 'lib/'); + find(sub { wanted($allowed, \$data) }, 'lib/'); my $f = Path::Tiny->tempfile; $f->spew($data); @@ -194,9 +234,7 @@ sub check_next { return; } -sub wanted { - my $data = shift; - +sub wanted ($allowed, $data) { return unless -f $_; return unless /\.pm$/; @@ -206,6 +244,9 @@ sub wanted { $name =~ s/\//::/g; $name =~ s/\.pm//; + # Only load channels/reactors referenced in config + return if %$allowed && $name =~ /Synergy::(Reactor|Channel)/ && ! $allowed->{$name}; + $$data .= "use $name;\n"; } diff --git a/t/basic.t b/t/basic.t index cf37b18f..4cf2b969 100644 --- a/t/basic.t +++ b/t/basic.t @@ -15,8 +15,8 @@ use Net::Async::HTTP; use Synergy::Hub; # Initialize Synergy. -my $synergy = Synergy::Hub->synergize( - { +my $synergy = Synergy::Hub->synergize({ + config => { user_directory => "t/data/users.yaml", channels => { 'test-channel' => { @@ -35,7 +35,7 @@ my $synergy = Synergy::Hub->synergize( pref => { class => 'Synergy::Reactor::Preferences' }, } } -); +}); # Tests begin here. testing_loop($synergy->loop); diff --git a/t/dates.t b/t/dates.t index cd57d025..82d18b92 100644 --- a/t/dates.t +++ b/t/dates.t @@ -18,8 +18,8 @@ use Net::Async::HTTP; use Synergy::Hub; # Initialize Synergy. -my $synergy = Synergy::Hub->synergize( - { +my $synergy = Synergy::Hub->synergize({ + config => { user_directory => "t/data/users.yaml", time_zone_names => { "America/New_York" => "🇺🇸", @@ -38,7 +38,7 @@ my $synergy = Synergy::Hub->synergize( echo => { class => 'Synergy::Reactor::Echo' }, } } -); +}); sub from_epoch { DateTime->from_epoch(epoch => $_[0]) } diff --git a/t/exclusive.t b/t/exclusive.t index b4fb8d4a..ebf6bdcf 100644 --- a/t/exclusive.t +++ b/t/exclusive.t @@ -15,8 +15,8 @@ use Net::Async::HTTP; use Synergy::Hub; # Initialize Synergy. -my $synergy = Synergy::Hub->synergize( - { +my $synergy = Synergy::Hub->synergize({ + config => { user_directory => "t/data/users.yaml", channels => { 'test-channel' => { @@ -33,7 +33,7 @@ my $synergy = Synergy::Hub->synergize( echo => { class => 'Synergy::Reactor::Echo' }, } } -); +}); # Tests begin here. testing_loop($synergy->loop); diff --git a/t/httpendpoint.t b/t/httpendpoint.t index 58be4d03..1fc5d8ec 100644 --- a/t/httpendpoint.t +++ b/t/httpendpoint.t @@ -41,8 +41,8 @@ package Synergy::Channel::Test::HTTPEndpointAuth { } # Initialize Synergy. -my $synergy = Synergy::Hub->synergize( - { +my $synergy = Synergy::Hub->synergize({ + config => { user_directory => "t/data/users.yaml", channels => { 'test-channel-endpoint' => { @@ -55,7 +55,7 @@ my $synergy = Synergy::Hub->synergize( }, }, } -); +}); # Tests begin here. testing_loop($synergy->loop); diff --git a/t/https.t b/t/https.t index 2787b617..f4158ff7 100644 --- a/t/https.t +++ b/t/https.t @@ -17,8 +17,8 @@ use Plack::Response; use Synergy::Hub; # Initialize Synergy. -my $synergy = Synergy::Hub->synergize( - { +my $synergy = Synergy::Hub->synergize({ + config => { user_directory => "t/data/users.yaml", channels => { 'test-channel' => { @@ -28,7 +28,7 @@ my $synergy = Synergy::Hub->synergize( tls_cert_file => "t/data/synergy.crt", tls_key_file => "t/data/synergy.key", } -); +}); $synergy->server->register_path('/ok', sub { return Plack::Response->new(200)->finalize; diff --git a/t/httpserver.t b/t/httpserver.t index c5d170c1..30e8bbd3 100644 --- a/t/httpserver.t +++ b/t/httpserver.t @@ -17,8 +17,8 @@ use Plack::Response; use Synergy::Hub; # Initialize Synergy. -my $synergy = Synergy::Hub->synergize( - { +my $synergy = Synergy::Hub->synergize({ + config => { user_directory => "t/data/users.yaml", channels => { 'test-channel' => { @@ -26,7 +26,7 @@ my $synergy = Synergy::Hub->synergize( } }, } -); +}); $synergy->server->register_path('/ok', sub { return Plack::Response->new(200)->finalize; diff --git a/t/lp-task-spec.t b/t/lp-task-spec.t index 779da8a4..0aae1715 100644 --- a/t/lp-task-spec.t +++ b/t/lp-task-spec.t @@ -13,8 +13,8 @@ use Synergy::Logger::Test '$Logger'; use Synergy::Hub; my $tmpfile = Path::Tiny->tempfile; -my $synergy = Synergy::Hub->synergize( - { +my $synergy = Synergy::Hub->synergize({ + config => { user_directory => "t/data/users-lp.yaml", channels => { 'test-channel' => { @@ -38,7 +38,7 @@ my $synergy = Synergy::Hub->synergize( }, state_dbfile => "$tmpfile", } -); +}); for my $to_set ( [ jetta => { lp => { 'default-project-shortcut' => 'pies' } } ], diff --git a/t/page.t b/t/page.t index a6d392c8..9319f9d6 100644 --- a/t/page.t +++ b/t/page.t @@ -20,8 +20,8 @@ my $PAGE = "Hello\n\nfriend."; my $tmpfile = Path::Tiny->tempfile; # Initialize Synergy. -my $synergy = Synergy::Hub->synergize( - { +my $synergy = Synergy::Hub->synergize({ + config => { user_directory => "t/data/users-page.yaml", channels => { 'test-1' => { @@ -49,7 +49,7 @@ my $synergy = Synergy::Hub->synergize( }, state_dbfile => "$tmpfile", } -); +}); # Tests begin here. testing_loop($synergy->loop); diff --git a/t/prometheus.t b/t/prometheus.t index c3be58e8..0f6fa3d0 100644 --- a/t/prometheus.t +++ b/t/prometheus.t @@ -16,8 +16,8 @@ use Net::Async::HTTP; use Synergy::Hub; # Initialize Synergy. -my $synergy = Synergy::Hub->synergize( - { +my $synergy = Synergy::Hub->synergize({ + config => { user_directory => "t/data/users.yaml", channels => { 'test-channel' => { @@ -33,7 +33,7 @@ my $synergy = Synergy::Hub->synergize( prometheus => { class => 'Synergy::Reactor::Prometheus' }, }, } -); +}); # Tests begin here. testing_loop($synergy->loop);