Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
Wanted to see if this approach was doable.  It is very much so!

An alternative which is likely better: a small output processor for
`cram` which converts to TAP, so we can then run with `prove`.
  • Loading branch information
tsibley committed Nov 13, 2024
1 parent 314c31b commit 766df85
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
21 changes: 21 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Usage: cramp [<OPTIONS> --] [<PATHS>]

Cram, in parallel.

If <OPTIONS> are given, they must be separated from test <PATHS> by "--".

cramp options:
-jN, --jobs=N number of tests to run in parallel
-h, --help show this help message and exit
-V, --version show version information and exit

cram options:
-q, --quiet don't print diffs
-v, --verbose show filenames and test status
-d, --debug write script output directly to the terminal
-E, --preserve-env don't reset common environment variables
--keep-tmpdir keep temporary directories
--shell=PATH shell to use for running tests (default: /bin/sh)
--shell-opts=OPTS arguments to invoke shell with
--indent=NUM number of spaces to use for indentation (default: 2)
--xunit-file=PATH path to write xUnit XML output
41 changes: 41 additions & 0 deletions cram-log-merge
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env perl
# Merge output from multiple invocations of Cram into one.
use strict;
use warnings;

$|++; # unbuffer stdout

my $ok = 0;
my $skip = 0;
my $fail = 0;
my $buf = "";
my $kept = "";

while (<<>>) {
if (/^# Ran (\d+) tests, (\d+) skipped, (\d+) failed[.]/) {
# End of a Cram run; track counts and print output.
$ok += $1;
$skip += $2;
$fail += $3;
chomp $buf if $buf =~ /^[.s!]+$/;
print $buf;
$buf = "";
}
elsif (/^# Kept temporary directory:/) {
# Hold --keep-tmpdir output till very end.
$kept .= $_;
}
else {
# Accumulate output from a Cram run
$buf .= $_;
}
}
die if $buf; # assert empty
print "\n";
print "# Ran $ok tests, $skip skipped, $fail failed.\n";
print $kept if $kept;
exit $fail;
81 changes: 81 additions & 0 deletions cramp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/bash
set -euo pipefail

main() {
# Separate options, if any, from paths. If options are given, they must be
# delimited from paths with "--".
local -a cram_opts
local job_opt="--jobs=+0"

if [[ $# -eq 0 ]]; then
exit-with-help
fi
if [[ "${1:-}" == -* ]]; then
while [[ $# -gt 0 ]]; do
case "$1" in
--help|-h)
exit-with-help;;

--version|-V)
exit-with-version;;

--jobs=?*|-j?*)
job_opt="$1"
shift;;

--jobs|-j)
job_opt="--jobs=$2"
shift 2;;

--interactive|-i|--yes|-y|--no|-n)
echo "cram's interactivity options (e.g. $1) are not supported under cramp" >&2
exit 1;;

--)
shift
break;;

*)
cram_opts+=("$1")
shift;;
esac
done
fi

find "$@" -type f -name '*.t' -print0 \
| sort --zero-terminated \
| parallel --null --line-buffer --keep-order "$job_opt" -- cram "${cram_opts[@]}" \
| "$(dirname "$0")"/cram-log-merge
}

exit-with-help() {
cram --help | sed -Ee '
/^Usage: /c Usage: cramp [<OPTIONS> --] [<PATHS>]
/^Options:/ {
i Cram, in parallel.
i
i If <OPTIONS> are given, they must be separated from test <PATHS> by "--".
i
i cramp options:
i \ \ -jN, --jobs=N number of tests to run in parallel
i \ \ -h, --help show this help message and exit
i \ \ -V, --version show version information and exit
i
c cram options:
}
/\s--(help|version)\s/d # takeover help and version
/\s--(interactive|yes|no)\s/d # no interactivity
'
exit
}

exit-with-version() {
echo "Cram, parallel (version 0)"
echo "Copyright 2024 Thomas Sibley <tom@zulutango.org>"
echo
cram --version
exit
}

main "$@"

0 comments on commit 766df85

Please sign in to comment.