X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=bin%2Fwanna-build;h=8e205569d88720368beb00e276e82a2b1e44d2c8;hb=bd340c3494a3b6fa95cdfaab05f54b78962ff9e7;hp=4ba644ebbdb4149adb1e30f1c8a496a79d389ab5;hpb=80adc1ea160f423e6cfbb348bf1efefbac89d332;p=wannabuild.git diff --git a/bin/wanna-build b/bin/wanna-build index 4ba644e..8e20556 100755 --- a/bin/wanna-build +++ b/bin/wanna-build @@ -44,7 +44,7 @@ use WannaBuild; our ($verbose, $mail_logs, $list_order, $list_state, $curr_date, $op_mode, $user, $real_user, $distribution, - $fail_reason, $opt_override, $import_from, $opt_create_db, + $fail_reason, $opt_override, $import_from, $export_to, $opt_create_db, %prioval, %sectval, $info_all_dists, $arch, $category, %catval, %short_category, @@ -173,15 +173,15 @@ my %options = code => sub { die "Argument of --min-age must be a non-zero number\n" if $list_min_age == 0; - $list_min_age *= 24*60*60; } }, "max-age" => { arg => \$list_min_age, code => sub { die "Argument of --max-age must be a non-zero number\n" if $list_min_age == 0; - $list_min_age *= -24*60*60; + $list_min_age *= -1; } }, # special actions + export => { arg => \$export_to, mode => "export" }, import => { arg => \$import_from, mode => "import" }, "manual-edit" => { mode => "manual-edit" }, ); @@ -251,7 +251,7 @@ if ($verbose) { print "wanna-build $version for $distribution on $arch\n"; } -if (!@ARGV && !isin( $op_mode, qw(list merge-quinn merge-partial-quinn import +if (!@ARGV && !isin( $op_mode, qw(list merge-quinn merge-partial-quinn import export merge-packages manual-edit merge-sources))) { warn "No packages given.\n"; @@ -303,7 +303,7 @@ END { } my $schema_suffix = ''; -if (isin( $op_mode, qw(list info)) && $distribution !~ /security/) { +if (isin( $op_mode, qw(list info)) && $distribution !~ /security/ && !(not -t and $user =~ /-/)) { $dbh = DBI->connect("DBI:Pg:service=wanna-build") || die "FATAL: Cannot open database: $DBI::errstr\n"; $schema_suffix = '_public'; @@ -418,6 +418,10 @@ sub process { read_db( $import_from ); last SWITCH; }; + /^export/ && do { + export_db( $export_to ); + last SWITCH; + }; die "Unexpected operation mode $op_mode\n"; } @@ -1760,19 +1764,10 @@ sub list_packages { my %scnt; my $ctime = time; - my $db = get_all_source_info(); + my $db = get_all_source_info(state => $state, user => $user, category => $category, list_min_age => $list_min_age); foreach $name (keys %$db) { next if $name =~ /^_/; - $pkg = $db->{$name}; - next if $state ne "all" && $pkg->{'state'} !~ /^\Q$state\E$/i; - next if $user && (lc($state) ne 'needs-build' and $pkg->{'builder'} ne $user); - next if $category && $pkg->{'state'} eq "Failed" && - $pkg->{'failed_category'} ne $category; - next if ($list_min_age > 0 && - ($ctime-parse_date($pkg->{'state_change'})) < $list_min_age)|| - ($list_min_age < 0 && - ($ctime-parse_date($pkg->{'state_change'})) > -$list_min_age); - push( @list, $pkg ); + push @list, $db->{$name}; } foreach $pkg (sort sort_list_func @list) { @@ -1831,7 +1826,7 @@ sub info_packages { foreach $dist (@dists) { my $pname = "$name" . ($info_all_dists ? "($dist)" : ""); - $pkg = get_source_info($name); + $pkg = get_readonly_source_info($name); if (!defined( $pkg )) { print "$pname: not registered\n"; next; @@ -1989,6 +1984,32 @@ sub check_entry { ) ); } +sub export_db { + my $file = shift; + my($name,$pkg,$key); + + print "Writing ASCII database to $file..." if $verbose >= 1; + open( F, ">$file" ) or + die "Can't open export $file: $!\n"; + + my $db = get_all_source_info(); + foreach $name (keys %$db) { + next if $name =~ /^_/; + my $pkg = $db->{$name}; + foreach $key (keys %{$pkg}) { + my $val = $pkg->{$key}; + next if !defined($val); + $val =~ s/\n*$//; + $val =~ s/^/ /mg; + $val =~ s/^ +$/ ./mg; + print F "$key: $val\n"; + } + print F "\n"; + } + close( F ); + print "done\n" if $verbose >= 1; +} + sub change_state { my $pkgr = shift; my $pkg = $$pkgr; @@ -2025,13 +2046,13 @@ sub log_ta { "changed from $prevstate to $pkg->{'state'} ". "by $real_user as $user"; - my $transactlog = db_transactlog(); - if (!open( LOG, ">>$transactlog" )) { - warn "Can't open log file $transactlog: $!\n"; - return; - } - print LOG "$curr_date: $str\n"; - close( LOG ); + $dbh->do('INSERT INTO ' . transactions_table_name() . + ' (package, distribution, version, action, ' . + ' prevstate, state, real_user, set_user, time) ' . + ' values (?, ?, ?, ?, ?, ?, ?, ?, ?)', + undef, $pkg->{'package'}, $distribution, + $pkg->{'version'}, $action, $prevstate, $pkg->{'state'}, + $real_user, $user, 'now()') or die $dbh->errstr; if (!($prevstate eq 'Failed' && $pkg->{'state'} eq 'Failed')) { $str .= " (with --override)" @@ -2063,10 +2084,6 @@ sub send_mail { close( PIPE ); } -sub db_transactlog { - return "$conf::basedir/$arch/$conf::transactlog"; -} - # for parsing input to dep-wait sub parse_deplist { my $deps = shift; @@ -2387,6 +2404,7 @@ Options: if -l is missing, set user name to be entered in db; usually automatically choosen --import FILE: Import database from a ASCII file FILE + --export FILE: Export database to a ASCII file FILE The remaining arguments (depending on operation) usually start with "name_version", the trailer is ignored. This allows to pass the names @@ -2417,19 +2435,62 @@ sub user_table_name { return '"' . $arch . $schema_suffix . '".users'; } +sub transactions_table_name { + return '"' . $arch . $schema_suffix . '".transactions'; +} + +sub get_readonly_source_info { + my $name = shift; + my $pkg = $dbh->selectrow_hashref('SELECT * FROM ' . + table_name() . ' WHERE package = ? AND distribution = ?', + undef, $name, $distribution); + return $pkg; +} + sub get_source_info { my $name = shift; my $pkg = $dbh->selectrow_hashref('SELECT * FROM ' . table_name() . ' WHERE package = ? AND distribution = ?' . - 'FOR UPDATE', + ' FOR UPDATE', undef, $name, $distribution); return $pkg; } sub get_all_source_info { - my $db = $dbh->selectall_hashref('SELECT * FROM ' . table_name() . - ' WHERE distribution = ?', - 'package', undef, $distribution); + my %options = @_; + + my $q = 'SELECT * FROM ' . table_name() + . ' WHERE distribution = ? '; + my @args = ($distribution); + if ($options{state} && uc($options{state}) ne "ALL") { + $q .= ' AND upper(state) = ? '; + push @args, uc($options{state}); + } + + if ($options{user}) { + #this basically means "this user, or no user at all": + $q .= ' AND (builder = ? OR upper(state) = ?)'; + push @args, $options{user}; + push @args, "NEEDS-BUILD"; + } + + if ($options{category}) { + $q .= ' AND failed_category <> ? AND upper(state) = ? '; + push @args, $options{category}; + push @args, "FAILED"; + } + + if ($options{list_min_age} > 0) { + $q .= ' AND age(state_change::timestamp) > ? '; + push @args, $options{list_min_age} . " days"; + } + + if ($options{list_min_age} < 0) { + $q .= ' AND age(state_change::timestamp) < ? days '; + push @args, -$options{list_min_age} . " days"; + } + + my $db = $dbh->selectall_hashref($q, 'package', undef, @args); return $db; }