From e287f595aa0e4eab9544bd49907d20adc9b5e977 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 5 Feb 2016 17:32:03 +0000 Subject: [PATCH] commitid.scad.pl: argument parsing, git invocation, etc. --- commitid.scad.pl | 158 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 1 deletion(-) diff --git a/commitid.scad.pl b/commitid.scad.pl index 863e04d..b8d295a 100755 --- a/commitid.scad.pl +++ b/commitid.scad.pl @@ -4,7 +4,29 @@ use strict; $SIG{__WARN__} = sub { die @_; }; # xxx much of the comment below is TODO - +# +# Usage: +# +# .../commitid.scad.pl [OPTION...] [STRING...] >commitid.scad.new \ +# && mv -f commitid.scad.new commitid.scad +# +# Options: +# +# --git generate git commit indications, as shown below +# (this is the default if no strings are requested with -t) +# +# --git=object +# generate git commit indication based on commit object only +# (ie avoid counting commits) +# +# -i do not generate `+' if git-untracked files are present +# +# [-t[FORM]] TEXT +# generate a form FORM containing TEXT +# TEXT can contain newlines (final newline usually undesirable) +# if FORM not specified, generates Arg0 Arg1 Arg2 in sequence +# character set is SPC 0-9 a-f + * (`*' glyph is `=/='). +# # We generate a physical indication of which commit was used. # # We provide for scaling factors with dynamic variables: @@ -41,6 +63,8 @@ $SIG{__WARN__} = sub { die @_; }; # padded with zeroes; if too long we reduce mod 10^n # eg # Tiny4 1070 +# If tree is dirty, + or * is suffixed, reducing number of +# digits by 1. # # Tiny4Q: # Tiny6Q: @@ -55,15 +79,27 @@ $SIG{__WARN__} = sub { die @_; }; # git-rev-parse HEAD (prefix of requested length) # eg # Git6 82f2a2 +# If tree is dirty, + or * is suffixed to commitid, +# reducing number of hex digits by 1. +# Small3 # Small4 +# Small5 # Small6 +# Small7 # Small8 # git-rev-list --first-parent --count HEAD # git-rev-parse HEAD # eg # Small6 1070 # 82f2a2 +# If tree is dirty, + or * is suffixed to count (but not to +# commitid) reducing number of digits by 1. +# +# FontDemo +# +# Arg0, Arg1, ... +# Strings passed on command line sub p { print @_ or die $!; } @@ -188,8 +224,128 @@ sub parsefont () { parsefont(); +our $do_git; # contains may chars 'c' (count) and/or 'o' (object) +our $do_git_untracked = 1; +our $argcounter; + +sub rjustt ($$) { # right justify and truncate (ie, pad and truncate at left) + my ($sz, $whole) = @_; + my $lw = length $whole; + return $lw > $sz + ? substr($whole, $lw-$sz) + : sprintf "%${sz}s", $whole; +} + +sub ljustt ($$$) { # always includes $suffix + my ($sz, $whole, $suffix) = @_; + $sz -= length $suffix; + return sprintf "%-${sz}.${sz}s%s", $whole, $suffix; +} + +sub gentextmodule_plusq ($$) { + my ($form, $s) = @_; + my $l = length $s; + gentextmodule($form, $s); + if (!($l & 1) && $l>=4) { + gentextmodule("${form}Q", substr($s,0,$l/2), substr($s,$l/2)); + } +} + +our @gcmd; + +sub gitrun_start () { + open F, "-|", @gcmd or die "$gcmd[0]: start: $!"; +} + +sub gitrun_done (;$) { + my ($errok) = @_; + $?=0; $!=0; + return if close F; + return if $errok; + die $! if $!; + die "@gcmd failed ($?)\n"; +} + +sub gitoutput (@) { + (@gcmd) = (qw(git), @_); + gitrun_start; + $_ = ; + gitrun_done; + defined or die "@gcmd produced no output"; + chomp or die "@gcmd produced no final newline"; + $_; +} + +sub do_git () { + return unless $do_git; + + @gcmd = qw(git status --porcelain); + push @gcmd, qw(--untracked=no) unless $do_git_untracked; + + my $git_dirty = ''; + gitrun_start; + while () { + if (m/^\?\?/ && $do_git_untracked) { + $git_dirty = '+'; + next; + } + $git_dirty = '*'; + last; + } + gitrun_done($git_dirty eq '*'); + + my $git_count; + my $git_object; + + if ($do_git =~ m/c/) { + $git_count = gitoutput qw(rev-list --first-parent --count HEAD); + } + if ($do_git =~ m/o/) { + $git_object = gitoutput qw(rev-parse HEAD); + } + + foreach my $sz (3..8) { + gentextmodule_plusq("Tiny$sz", rjustt($sz, $git_count.$git_dirty)) + if defined $git_count; + + gentextmodule_plusq("Git$sz", ljustt($sz, $git_object, $git_dirty)) + if defined $git_object; + + gentextmodule("Small$sz", + rjustt($sz, $git_count.$git_dirty), + ljustt($sz, $git_object, '')) + if defined $git_count && defined $git_object; + } +} + +while (@ARGV) { + $_ = shift; + if (m/^--(no)?-git$/) { + $do_git = $1 ? '' : 'co'; + } elsif (m/^---git=object$/) { + $do_git = 'o'; + } elsif (m/^-i$/) { + $do_git_untracked = 0; + } elsif (m/^-t(.*)$/) { + my $form = $1; + die "bad usage: -t needs string argument\n"; + $_ = shift; + gentextmodule($form, split /\n/, $_); + $argcounter //= 0; + } elsif (m/^[^-]/) { + gentextmodule("Arg$argcounter", $_); + $argcounter++; + } else { + die "bad usage: unknown option \`$_'\n"; + } +} + +$do_git //= defined($argcounter) ? '' : 'co'; + gentextmodule('FontDemo', @demo); +do_git(); + flush STDOUT or die $!; close STDOUT or die $!; -- 2.30.2