2 # usage: tb-list [<patch-spec>]
3 # lists all patches matching <patch-spec> and other criteria
11 Getopt::Long::Configure(qw(bundling));
20 GetOptions("d|deleted!" => \$deleted, # including deleted patches
21 "deleted-only!" => \$deleted_only, # only deleted patches
22 "r|related=s" => \$relatedto, # only patches related to this one
23 "l|last|leaf|leaves" => \$leaves, # only leaf patches
25 ) or die "bad options\n";
30 $spec = parse_patch_spec($ARGV[0]);
33 die "too many arguments\n";
36 our @sort = grep { /./ } split m/,/, $sort;
37 push @sort, 'topo' if !$spec;
38 push @sort, 'created';
40 foreach $sort (@sort) {
41 die "bad sort $sort\n" unless grep { $_ eq $sort }
42 qw(fullname created nick topo);
43 $toposort=1 if $sort eq $toposort;
48 foreach_patch($relatedto || $leaves || !$spec ? { } : $spec,
49 $deleted || $deleted_only,
50 [0, !!$leaves, 0, $toposort || !!$relatedto],
52 my ($patch,$parsedname,@info) = @_;
53 $patches{$patch}{Info} = \@info;
54 $patches{$patch}{ParsedName} = $parsedname;
58 foreach my $p (keys %patches) {
60 next if $v->{Info}[0]{Deleted};
61 foreach my $dep (keys %{ $v->{Info}[1] }) {
62 next unless exists $patches{$dep};
63 $patches{$dep}{NotLeaf} = 1;
69 foreach my $p (keys %patches) {
71 # mark Related=1 if any patch matching $relatedto includes us
72 foreach my $dep (keys %{ $v->{Info}[3] }) {
73 next unless exists $patches{$dep};
74 my $depv = $patches{$dep};
75 next unless patch_matches_spec($depv->{ParsedName}, $relatedto);
79 if (patch_matches_spec($v->{ParsedName}, $relatedto)) {
80 # if we match $relatedto, mark all our inclusions as Related=1
81 foreach my $dep (keys %{ $v->{Info}[3] }) {
82 next unless exists $patches{$dep};
83 $patches{$dep}{Related} = 1;
91 foreach my $p (keys %patches) {
93 next if !$deleted && $v->{Info}[0]{Deleted};
94 next if $deleted_only && !$v->{Info}[0]{Deleted};
95 next if $leaves && $v->{NotLeaf};
96 next if $relatedto && !$v->{Related};
101 my $txt = "sub sort_cmp {\n my \$r;\n";
105 foreach my $ab (qw(a b)) {
106 $txt .= " my \$v$ab = \$patches{\$$ab};\n";
111 $txt .= " \$r = $_[0];\n return \$r if \$r;\n";
113 my $by_parsed = sub {
115 $by_r->("\$va->{ParsedName}{$_[0]} cmp \$vb->{ParsedName}{$_[0]}");
118 foreach my $sort (@sort) {
119 next if $done{$sort}++;
120 if ($sort eq 'fullname') {
121 $by_r->('$a cmp $b');
122 } elsif ($sort eq 'created') {
123 $by_parsed->('Date');
124 } elsif ($sort eq 'nick') {
125 $by_parsed->('Nick');
126 } elsif ($sort eq 'topo') {
128 foreach my $ix (qw(0 1)) {
129 my $ab = (qw(a b))[$ix];
130 my $ba = (qw(b a))[$ix];
131 my $r = (qw(-1 1))[$ix];
132 $txt .= " return $r if \$v${ab}->{Info}[3]{\$$ba};\n";
138 $txt .= " return 0;\n}\n";
139 debug("sortsub | $_") foreach split /\n/, $txt;
142 eval sortsub()." 1;" or die "$@ ?";
144 @output = sort sort_cmp @output;
148 foreach my $p (@output) {
149 my $v = $patches{$p};
150 print Dumper($p, $v);