chiark / gitweb /
working on updates for new theory/metadata
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 25 Feb 2012 13:11:15 +0000 (13:11 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 25 Feb 2012 13:11:15 +0000 (13:11 +0000)
FORMAT
THEORY
Topbloke.pm
tb-create.pl
tb-list.pl
topbloke-merge-driver

diff --git a/FORMAT b/FORMAT
index 75896b7..8e061cf 100644 (file)
--- a/FORMAT
+++ b/FORMAT
@@ -25,15 +25,15 @@ In-tree, there are metadata files in .topbloke
                        as either:
                                <topbloke patch name>
                                - <ref name including refs/heads/>
-                       exist only in base branch
+                       exists only in base branch
 
        deleted         exists (but empty) if patch is deleted
-                       exist only in tip branch
+                       exists only in tip branch
 
        topgit-         name of the topgit branch that this was
                        imported from and which we should merge from
                        (plus a newline)
-                       exist only in base branch
+                       exists only in base branch
 
        [^+]*-          another property that applies to this patch;
                        if not known to this version of topbloke then it
diff --git a/THEORY b/THEORY
index 83de604..4478fa0 100644 (file)
--- a/THEORY
+++ b/THEORY
@@ -1,7 +1,7 @@
 GENERAL
 
  C >= D                        C is descendant of D, partial order
C \haspatch D         C contains changes from D, partial order
D \isin C             C contains changes from D, partial order
  Patch P has two sets P+, P-
  Ancestors A(C,P) = { Ca \elem C | Ca \elem P }
  Ends E(C,P) = maximal elements of A(C,P)
index a7ecad5..741cecb 100644 (file)
@@ -189,11 +189,18 @@ sub check_clean_tree ($) {
 #----- configuring a tree -----
 
 sub setup_config () {
-    my (@files) = (qw(msg deps included props pprops));
+    my (@files) = (qw(msg patch base deps deleted topgit- lwildcard-
+                      +included +ends +iwildcard-));
     my $version = 1;
+    my $drvname = sub {
+       my ($file) = @_;
+       $file =~ s/^\+//;
+       $file =~ s/\-$//;
+       return $file;
+    };
     foreach my $iteration (qw(0 1)) {
        foreach my $file (@files) {
-           my $cfgname = "merge.topbloke-$file";
+           my $cfgname = "merge.topbloke-".$drvname->($file);
            my ($current, $current_estatus);
            run_git(\$current_estatus,
                    sub { $current = $_; },
@@ -208,35 +215,44 @@ sub setup_config () {
                    "topbloke-merge-driver --v$version".
                    " $file %O %A %B %L");
        }
-       my ($newattrs, $attrsfile);
+       my ($newattrsprefix, $newattrs, $attrsfile);
+
+       my $attrs = '';
+       my @needupdate;
        foreach my $file (@files) {
-           my $path = ".topbloke/$file";
-           my $current = run_git_1line(qw(check-attr merge), $path);
+           my ($pat,$check) = ($file, $file);
+           if ($file =~ m/wildcard/) {
+               $pat = ($file =~ m/^\+/ ? '+' : '[^+]').'*';
+               $check =~ s/\w.*/xxxunknown/ or die;
+           }
+           my $want = "topbloke-".$drvname->($file);
+           $attrs .= "$pat\tmerge=$want\n";
+           my $current = run_git_1line(qw(check-attr merge), $check);
            $current =~ s#^\Q$path\E: merge: ## or die "$file $current ?";
-           my $want = "topbloke-$file";
            next if $current eq $want;
            die "$file $current ?" unless $current eq 'unspecified';
-           die "$file $current ?" if $iteration;
-           if (!$newattrs) {
-               $attrsfile = git_dir()."/info/attributes";
-               $newattrs = new IO::File "$attrsfile.tmp", 'w'
+           push @needupdate, $file;
+       }
+       if (@needupdate) {
+           my $newattrsf = new IO::File "$attrsfile.tmp", 'w'
                    or die "$attrsfile.tmp: $!";
-               if (!open OA, '<', "$attrsfile") {
-                   die "$attrsfile $!" unless $!==&ENOENT;
-               } else {
-                   while (<OA>) {
-                       print $newattrs $_ or die $!;
-                       print "\n" or die $! unless chomp;
-                   }
-                   die $! if OA->error;
-                   die $! unless close OA;
+           die "@needupdate $current ?" if $iteration;
+           $attrsfile = git_dir()."/info/attributes";
+           if (!open OA, '<', "$attrsfile") {
+               die "$attrsfile $!" unless $!==ENOENT;
+           } else {
+               while (<OA>) {
+                   next if m#^\.topbloke/#;
+                   print $newattrsf $_ or die $!;
+                   print "\n" or die $! unless chomp;
                }
+               die $! if OA->error;
+               die $! unless close OA;
            }
-           print $newattrs "$path\tmerge=$want\n" or die $!;
+           print $newattrsf or die $!;
+           close $newattrs or die $!;
+           rename "$attrsfile.tmp", "$attrsfile" or die $!;
        }
-       last if !$newattrs;
-       close $newattrs or die $!;
-       rename "$attrsfile.tmp", "$attrsfile" or die $!;
     }
 }
 
@@ -372,43 +388,47 @@ sub patch_matches_spec ($$) {
 
 sub foreach_patch ($$$$) {
     my ($spec, $deleted_ok, $want, $body) = @_;
-    # runs $body->($patch, $parsedname, \%props, \%deps, \%pprops, \%included)
-    #                                   $want->[0]   1        2         3
-    # where $deps->{$fullname} etc. are 1 for true or nonexistent for false
-    #  and if $want->[$item] is not true, the corresponding item may be undef
+    # runs $body->($patch, $parsedname, \%props)
+    # where $props{<metadata filename>} is, for <metadata filename> in @$want:
+    #              undefined if metadata file doesn't exist
+    #              defined with contents of file
     # and $parsedname is only valid if $spec is not undef
     #  (say $spec { }  if you want the name parsed but no restrictions)
+    # entries in want may also be "<metadata filename>_"
+    #  which means "strip trailing newlines" (result key in %props is the same)
     my @want = @$want;
-    $want[0] ||= !$deleted_ok;
+    my $atfront = sub {
+       my $thing = @_;
+       @want = ($thing, grep { $_ ne $thing } @want);
+    };
+    $atfront->(' patch');
+    $atfront->('deleted') unless $deleted_ok;
     run_git(sub {
        debug("foreach_patch considering $_");
        m/ / or die "$_ ?";
        my $objname = $`;
-       my @out;
+       my %props;
+       my $parsedname;
        my $patch = substr($',19); #');
        my $wantix = 0;
-       foreach my $file (qw(props deps pprops included)) {
+       foreach my $wantent (@want) {
+           my $file = $wantent;
+           my $stripnl = ($file =~ s/_$//);
 
-           if ($file eq 'deps') {
-               # do this check after checking for deleted patches,
-               # so we don't parse deleted patches' names
-               # right, check the spec next
+           if ($file eq ' patch') {
                if ($spec) {
-                   my $have = parse_patch_name($patch);
+                   $parsedname = parse_patch_name($patch);
                    debug("foreach_patch  mismatch"), return
-                       unless patch_matches_spec($have, $spec);
-                   unshift @out, $have;
-               } else {
-                   unshift @out, undef;
+                       unless patch_matches_spec($parsedname, $spec);
                }
-           }
-
-           if (!$want[$wantix++]) {
-               push @out, undef;
                next;
            }
 
            my ($got, $data) = git_get_object("$objname:.topbloke/$file");
+
+xxx up to here new foreach_patch api
+xxx up to here new metadata in this function
+           
            die "$patch $file ?" unless defined $data;
            my %data;
            if ($file !~ m/props/) {
@@ -436,6 +456,8 @@ sub foreach_patch ($$$$) {
 
 #----- updating topbloke metadata -----
 
+xxx this section needs updating for new metadata
+
 sub propsfile_set_prop ($$$) {
     # set $value to undef to delete; returns old value
     my ($propsfile, $prop, $value) = @_;
index 68c571f..b01010b 100755 (executable)
@@ -1,6 +1,8 @@
 #!/usr/bin/perl
 # usage: tb-create <patch-spec>
 
+xxx needs updating for new metadata and new theory
+
 use warnings;
 use strict;
 
index 385e031..8b23d6d 100755 (executable)
@@ -2,6 +2,8 @@
 # usage: tb-list [<patch-spec>]
 #  lists all patches matching <patch-spec> and other criteria
 
+xxx needs updating for new metadata and new theory
+
 use warnings;
 use strict;
 
@@ -58,6 +60,7 @@ foreach $sort (@sort) {
 our %patches;
 
 foreach_patch($relatedto || $leaves || !$spec ? { } : $spec, 
+xxx new api for foreach_patch
              $deleted || $deleted_only, 
              [0, !!$leaves, 0, $toposort || !!$relatedto],
              sub { 
index a3d1999..1c0017f 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 set -e
 
+xxx new theory, new metadata, not yet done here
+
 fail () { echo >&2 "$0: $*"; exit 127; }
 
 case "$1" in