Repository navigation
fix(bin): preserve hold reasons and reject invalid completion inventories #6331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
1e644ad
e9a56f0
cf6527b
a1cb771
fadcf45
f0affec
3245997
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| #!/usr/bin/env bash | ||
| # fm-hold-reason-lib.sh - the one reversible encoding of a captain-hold reason. | ||
| # | ||
| # tasks-axi stores a hold reason as one markdown line inside a parenthesised tag, | ||
| # so its own `hold` refuses parentheses and line breaks. A decision reason is | ||
| # ordinary prose, so bin/fm-captain-hold.sh encodes the reason where it writes | ||
| # it and every reader that shows it decodes it again, instead of banning the | ||
| # characters. Stored reasons use the reserved fm-hold-v1: prefix followed by | ||
| # base64-encoded UTF-8 text. Unmarked reasons are plain text. Readers decode only | ||
| # the hold-reason field, once, and keep line breaks in quoted output strings. | ||
| # | ||
| # Source this file; it defines functions only. | ||
|
|
||
| # fm_hold_reason_encode <reason>: print the storable form, no trailing newline. | ||
| fm_hold_reason_encode() { | ||
| printf '%s' "$1" | perl -MMIME::Base64=encode_base64 -0777 -ne \ | ||
| 'print "fm-hold-v1:", encode_base64($_, "")' | ||
| } | ||
|
|
||
| # fm_hold_reason_decode_stream [toon|markdown|json]: decode marked reason fields. | ||
| fm_hold_reason_decode_stream() { | ||
| perl -MJSON::PP -MMIME::Base64=decode_base64 -MEncode=decode,FB_CROAK -e ' | ||
| use strict; | ||
| use warnings; | ||
| binmode STDIN, ":encoding(UTF-8)"; | ||
| binmode STDOUT, ":encoding(UTF-8)"; | ||
| my $format = shift; | ||
| my $json = JSON::PP->new->allow_nonref; | ||
| sub decode_reason { | ||
| my ($value) = @_; | ||
| return $value unless defined($value) && $value =~ s/^fm-hold-v1://; | ||
| return decode("UTF-8", decode_base64($value), FB_CROAK); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
An older, literal hold reason beginning with |
||
| } | ||
| sub decode_field { | ||
| my ($raw) = @_; | ||
| my $value = $raw =~ /^"/ ? $json->decode($raw) : $raw; | ||
| my $decoded = decode_reason($value); | ||
| return $decoded eq $value ? $raw : $json->encode($decoded); | ||
| } | ||
| if ($format eq "json") { | ||
| local $/; | ||
| my $snapshot = $json->decode(<STDIN>); | ||
| for my $record (@{$snapshot->{records}}) { | ||
| $record->{hold_reason} = decode_reason($record->{hold_reason}) | ||
| if exists $record->{hold_reason}; | ||
| } | ||
| print $json->encode($snapshot), "\n"; | ||
| exit; | ||
| } | ||
| my ($column, $task); | ||
| while (my $line = <STDIN>) { | ||
| if ($format eq "markdown") { | ||
| $line =~ s{^([-*] .*\(hold:\s*)(fm-hold-v1:[A-Za-z0-9+/]*={0,2})(\).*)$} | ||
| {$1 . decode_field($2) . $3}e; | ||
| } elsif ($line =~ /^tasks\[\d+\]\{([^}]*)\}:\n?$/) { | ||
| my @names = split /,/, $1; | ||
| ($column) = grep { $names[$_] eq "hold_reason" } 0 .. $#names; | ||
| $task = 0; | ||
| } elsif (defined($column) && $line =~ /^ (.*)\n?$/) { | ||
| my @fields = $1 =~ /("(?:[^"\\]|\\.)*"|[^,]+)/g; | ||
| $fields[$column] = decode_field($fields[$column]); | ||
| $line = " " . join(",", @fields) . "\n"; | ||
| } elsif ($task && $line =~ /^ hold_reason: (.*)\n?$/) { | ||
| $line = " hold_reason: " . decode_field($1) . "\n"; | ||
| } elsif ($line !~ /^ /) { | ||
| $column = undef; | ||
| $task = $line eq "task:\n"; | ||
| } | ||
| print $line; | ||
| } | ||
| ' "${1:-toon}" | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.