10 our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
14 @EXPORT = qw(parse_branch_spec current_tb_branch run_git_1line);
22 $xopts = ref $_[0] ? shift @_ : { };
23 open GIT, "-|", 'git', @_ or die $!;
26 if ($xopts->{ExitStatus}) {
30 chomp $l or die "@_ ?";
34 close GIT or die "git @_ failed ($?)\n";
35 chomp $l or die "@_ ?";
39 sub current_tb_branch () {
41 run_git_1line({ ExitStatus=>1 }, qw(symbolic-ref HEAD));
42 if ($estatus == 256) {
47 die "$estatus ?" if $estatus;
48 if ($ref =~ m#^refs/topbloke-(tip|base)s/([^/\@]*)\@([^/\@]*)/([^/]*)/#) {
56 DepSpec => "$2\@$3/$4/$'",
58 } elsif ($ref =~ m#^refs/heads/#) {
72 sub parse_branch_spec ($) {
75 my $spec = { }; # Email Domain DatePrefix DateNear Nick
77 my ($key,$val,$whats) = @_;
78 die "multiple $whats in branch spec\n" if exists $spec->{$key};
83 if (s#([^/\@]*)\@([^/\@]*)/##) {
84 $set->('Email', $1, "email local parts") if length $1;
85 $set->('Domain', $2, "email domains") if length $1;
86 } elsif (s#([^/]*\~[^/]*)/##) {
89 open DATE, "-|", 'date','+%s','-d',$dspec or die $!;
91 close DATE or die "date parsing failed\n";
93 $set->('DateNear', $l, 'nearby dates');
94 } elsif (s#^([0-9][^/]*)/##) {
97 m/^\d{4}(?:-\d\d(?:-\d\d(?:T(?:\d\d(?:\d\d(?:\d\d(?:Z)?)?)?)?)?)?)?$/
98 or die "bad date prefix \`$dspec'\n";
99 $set->('DatePrefix', $dspec, 'date prefixes');
102 } elsif (s#^\.\./##) {
109 if (defined $rel_levels) {
110 my $branch = current_tb_branch();
111 if (!defined $branch->{Nick}) {
112 die "relative branch spec \`$orig',".
113 " but current branch not a topbloke branch\n";
115 my ($ceaddr,$cdate,@l) = split /\//, $branch->{Nick};
117 die "relative branch spec \`$orig' has too many ../s\n";
118 $_ = (join '/', @l[0..$#l-$rel_levels]).'/'.$_;