]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - modulemanager
Migrate SSL metadata and visible information (/whois line) to single module
[user/henk/code/inspircd.git] / modulemanager
index 126c7421876b57807702213ad32b5732a597e3dd..ec5e7dd94081386adc9117bcd1bcc85c92772452 100755 (executable)
@@ -12,10 +12,12 @@ my %installed;
 
 my %modules;
 # $modules{$name}{$version} = {
-#      url => URL of this version (or INSECURE/DEPRECATED)
+#      url => URL of this version
 #      depends => [ 'm_foo 1.2.0-1.3.0', ... ]
 #      conflicts => [ ]
 #      from => URL of source document
+#      mask => Reason for not installing (INSECURE/DEPRECATED)
+#      description => some string
 # }
 
 my %url_seen;
@@ -33,6 +35,7 @@ sub parse_url {
        my $mod;
        for (split /\n+/, $doc) {
                s/^\s+//; # ignore whitespace at start
+               next if /^#/;
                if (/^module (\S+) ([0-9.]+) (\S+)/) {
                        my($name, $ver, $url) = ($1,$2,$3);
                        if ($modules{$name}{$ver}) {
@@ -50,6 +53,10 @@ sub parse_url {
                        push @{$mod->{depends}}, $1;
                } elsif (/^conflicts (.*)/) {
                        push @{$mod->{conflicts}}, $1;
+               } elsif (/^description (.*)/) {
+                       $mod->{description} = $1;
+               } elsif (/^mask (.*)/) {
+                       $mod->{mask} = $1;
                } elsif (m#^source (http://\S+)#) {
                        parse_url $1;
                } else {
@@ -60,15 +67,14 @@ sub parse_url {
 
 open SRC, 'sources.list' or die "Could not open sources.list: $!";
 while (<SRC>) {
+       next if /^\s*#/;
        parse_url($_);
 }
 close SRC;
 
-getmodules();
+getmodules(1);
 
-open my $verfile, 'src/version.sh' or die "Cannot determine inspircd version: $!";
-$_ = join '', <$verfile>;
-die "Cannot determine inspircd version" unless /InspIRCd-([0-9.]+)/;
+`./src/version.sh` =~ /InspIRCd-([0-9.]+)/ or die "Cannot determine inspircd version";
 $installed{core} = $1;
 $modules{core}{$1} = {
        url => 'NONE',
@@ -76,12 +82,12 @@ $modules{core}{$1} = {
        conflicts => [],
        from => 'local file',
 };
-close $verfile;
 
 for my $modname (@modlist) {
        my $mod = "m_$modname";
        my $modfile = "src/modules/$mod.cpp";
        my $ver = getmodversion($modfile) || '0.0';
+       $ver =~ s/\$Rev: (.*) \$/$1/; # for storing revision in SVN
        $installed{$mod} = $ver;
        next if $modules{$mod}{$ver};
        $modules{$mod}{$ver} = {
@@ -112,24 +118,26 @@ sub ver_in_range {
        return 1 unless defined $range;
        if ($range =~ /(.*)-(.*)/) {
                my($l,$h) = ($1,$2);
-               return 0 unless ver_cmp($ver, $l) >= 0;
-               return 0 unless ver_cmp($ver, $h) <= 0;
+               return 0 if $l && ver_cmp($ver, $l) < 0;
+               return 0 if $h && ver_cmp($ver, $h) > 0;
                return 1;
        }
        return !ver_cmp($ver, $range);
 }
 
 sub find_mod_in_range {
-       my($mod,$vers) = @_;
+       my($mod, $vers, $force) = @_;
        my @versions = keys %{$modules{$mod}};
-       @versions = sort { ver_cmp() } @versions;
-       for my $ver (reverse @versions) {
+       @versions = sort { -ver_cmp() } @versions;
+       for my $ver (@versions) {
+               next if $modules{$mod}{$ver}{mask} && !$force;
                return $ver if ver_in_range($ver, $vers);
        }
        return undef;
 }
 
 sub resolve_deps {
+       my($trial) = @_;
        my $tries = 100;
        my $changes = 'INIT';
        my $fail = undef;
@@ -151,7 +159,7 @@ sub resolve_deps {
                                        $todo{$depmod} = $depver;
                                        $changes .= " $mod-$ver->$depmod-$depver";
                                } else {
-                                       $fail ||= "Could not find module $depmod $depver required by $mod $ver";
+                                       $fail ||= "Could not find module $depmod $depvers required by $mod $ver";
                                }
                        }
                        for my $dep (@{$info->{conflicts}}) {
@@ -159,10 +167,13 @@ sub resolve_deps {
                                my($depmod, $depvers) = ($1,$2);
                                next unless $todo{$depmod} && ver_in_range($todo{$depmod}, $depvers);
                                # if there are changes this round, maybe the conflict won't come up after they are resolved.
-                               $fail ||= "Cannot install: module $mod ($ver) conflicts with versions $depmod version $todo{depmod}";
+                               $fail ||= "Cannot install: module $mod ($ver) conflicts with $depmod version $todo{$depmod}";
                        }
                }
        }
+       if ($trial) {
+               return !($changes || $fail);
+       }
        if ($changes) {
                print "Infinite dependency loop:$changes\n";
                exit 1;
@@ -183,7 +194,7 @@ if ($action eq 'install') {
                        print "Cannot find module $mod\n";
                        exit 1;
                }
-               my $ver = find_mod_in_range($mod, $vers);
+               my $ver = find_mod_in_range($mod, $vers, $vers ? 1 : 0);
                unless ($ver) {
                        print "Cannot find suitable version of $mod\n";
                        exit 1;
@@ -191,15 +202,44 @@ if ($action eq 'install') {
                $todo{$mod} = $ver;
        }
 } elsif ($action eq 'upgrade') {
-       for my $mod (keys %installed) {
+       my @installed = sort keys %installed;
+       for my $mod (@installed) {
                next unless $mod =~ /^m_/;
+               my %saved = %todo;
                $todo{$mod} = find_mod_in_range($mod);
+               if (!resolve_deps(1)) {
+                       %todo = %saved;
+               }
+       }
+} elsif ($action eq 'list') {
+       my @all = sort keys %modules;
+       for my $mod (@all) {
+               my @vers = sort { ver_cmp() } keys %{$modules{$mod}};
+               my $desc = '';
+               for my $ver (@vers) {
+                       # latest defined description wins
+                       $desc = $modules{$mod}{$ver}{description} || $desc;
+               }
+               next if @vers == 1 && $modules{$mod}{$vers[0]}{url} eq 'NONE';
+               my $instver = $installed{$mod} || '';
+               my $vers = join ' ', map { $_ eq $instver ? "\e[1m$_\e[m" : $_ } @vers;
+               print "$mod ($vers) - $desc\n";
        }
 } else {
-       die "Unknown action $action"
+       print <<ENDUSAGE
+Use: $0 <action> <args>
+Action is one of the following
+ install   install new modules
+ upgrade   upgrade installed modules
+ list      lists available modules
+
+For installing a package, specify its name or name=version to force the
+installation of a specific version.
+ENDUSAGE
+;exit 1;
 }
 
-resolve_deps();
+resolve_deps(0);
 
 $| = 1; # immediate print of lines without \n
 
@@ -211,15 +251,11 @@ for my $mod (keys %installed) {
 for my $mod (sort keys %todo) {
        my $ver = $todo{$mod};
        my $oldver = $installed{$mod};
-       my $url = $modules{$mod}{$ver}{url};
-       if ($url eq 'INSECURE') {
-               print "WARNING: Version $ver of $mod is insecure!\n";
-               next;
-       } elsif ($url eq 'DEPRECATED') {
-               print "Note: version $ver of $mod is deprecated\n";
-               next;
+       if ($modules{$mod}{$ver}{mask}) {
+               print "Module $mod $ver is masked: $modules{$mod}{$ver}{mask}\n";
        }
        next if $oldver && $oldver eq $ver;
+       my $url = $modules{$mod}{$ver}{url};
        if ($oldver) {
                print "Upgrading $mod from $oldver to $ver using $url"
        } else {