]> git.donarmstrong.com Git - debbugs.git/blob - migrate/debbugs-upgradestatus
assume unknown encodings are UTF-8
[debbugs.git] / migrate / debbugs-upgradestatus
1 #! /usr/bin/perl -w
2 # Migrate from .status format version 1 to version 2. The new format uses
3 # RFC822-style name/value pairs to allow new fields to be added more easily.
4
5 use vars qw($gSpoolDir);
6
7 my $config_path = '/etc/debbugs';
8 my $lib_path = '/usr/lib/debbugs';
9
10 require "$config_path/config";
11 require "$lib_path/errorlib";
12
13 if (@ARGV < 1 or $ARGV[0] !~ /^(?:db-h|archive)$/) {
14     print <<EOF;
15 Usage: $0 db-h|archive (relative to $gSpoolDir)
16
17 debbugs-upgradestatus converts a debbugs database in-place to use version 2
18 of the bug status file format. Version 1 metadata files were stored in
19 .status files; version 2 metadata files are written to .summary files.
20
21 EOF
22     exit 0;
23 }
24
25 chdir $gSpoolDir or die "Can't chdir to $gSpoolDir: $!";
26
27 my $archive = $ARGV[0];
28 my $db = getlocationpath($archive);
29 opendir DB, $db or die "Can't opendir $db: $!";
30
31 my @files;
32 for (my $subdir = 0; $subdir < 100; ++$subdir) {
33     my $path = sprintf "$archive/%.2d", $subdir;
34     opendir DIR, $path or next;
35     my @list = grep /^\d+\.status$/, readdir DIR;
36     closedir DIR;
37     grep s/\.status$//, @list;
38     push @files, @list;
39 }
40
41 closedir DB;
42
43 @files = sort { $a <=> $b } @files;
44
45 my @v1fields = qw(originator date subject msgid package
46                   keywords done forwarded mergedwith severity);
47
48 sub v1readbug {
49     my ($lref, $location) = @_;
50     my $status = getbugcomponent($lref, 'status', $location);
51     return undef unless defined $status;
52     if (!open(S,$status)) { return undef; }
53
54     my %data;
55     my @lines;
56     local $_;
57
58     while (<S>) {
59         chomp;
60         push @lines, $_;
61     }
62
63     for my $field (@v1fields) {
64         if (@lines) {
65             $data{$field} = shift @lines;
66         } else {
67             $data{$field} = '';
68         }
69     }
70
71     close(S);
72
73     $data{severity} = 'normal' if $data{severity} eq '';
74
75     return \%data;
76 }
77
78 my $success = 0;
79 my $failure = 0;
80 for my $ref (@files) {
81     filelock("lock/$ref") unless $ENV{NO_LOCKING};
82     my $data = v1readbug($ref, $archive);
83     if (defined $data) {
84         if ($ENV{NO_LOCKING}) {
85             writebug($ref, $data, $archive, 2, 'disable bughook');
86         } else {
87             unlockwritebug($ref, $data, $archive, 2, 'disable bughook');
88         }
89
90         # Test new .summary file
91         my $newdata = readbug($ref, $archive);
92         my %jointkeys = map { $_ => 1 } (keys %$data), (keys %$newdata);
93         for my $key (keys %jointkeys) {
94             unless (exists $data->{$key}) {
95                 die "BUG: $ref: key '$key' in .summary but not .status!\n";
96             }
97             unless (exists $newdata->{$key}) {
98                 die "BUG: $ref: key '$key' in .status but not .summary!\n";
99             }
100             if ($data->{$key} ne $newdata->{$key}) {
101                 die "BUG: $ref: key '$key' different in " .
102                     ".status and .summary\n" .
103                     "     .status has '$data->{$key}';\n" .
104                     "     .summary has '$newdata->{$key}'!\n";
105             }
106         }
107
108         ++$success;
109     } else {
110         unfilelock() unless $ENV{NO_LOCKING};
111         ++$failure;
112     }
113 }
114
115 print "$success bugs converted successfully.\n" if $success;
116 print "Failed to convert $failure bugs.\n" if $failure;
117
118 exit !($success && !$failure);