One test run, one verdict
What you get
Your agent starts a build, test or linter as usual, with greppy bash-smart -- in front. The first line is the verdict, and below it come exactly the errors and warnings. The rest of the log waits folded behind an expand ID. Exit code and raw output stay as the command delivered them.
Before and after
A small Python project has 300 tests. The tests log at DEBUG level, and one of them fails. The question: What is broken?
Without greppy
The agent starts the tests and gets the whole log: every test, every log line, and the failure at the end.
$ python3 -m unittest -v
test_empty_text_gives_defaults (tests.test_config.TestParseConfig.test_empty_text_gives_defaults) ... ok
test_port_override (tests.test_config.TestParseConfig.test_port_override) ... FAIL
test_tax_percent_00 (tests.test_config.TestParseConfig.test_tax_percent_00) ... ok
…
test_line_total_000 (tests.test_pricing.TestLineTotal.test_line_total_000) ... DEBUG shopcart.pricing: line_total: unit=100 qty=1
INFO shopcart.pricing: line_total: computed 100 cents
ok
…
FAIL: test_port_override (tests.test_config.TestParseConfig.test_port_override)
…
AssertionError: 80 != 8080
…
FAILED (failures=1)
With greppy
$ greppy bash-smart -- python3 -m unittest -v
FAILED — exit 1: 4 errors, 0 warnings
723 FAIL: test_port_override (tests.test_config.TestParseConfig.test_port_override)
725 Traceback (most recent call last):
…
727 self.assertEqual(cfg["port"], 8080)
728 ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
729 AssertionError: 80 != 8080
730
734 FAILED (failures=1)
…
test_tax_percent_18 (tests.test_config.TestParseConfig.test_tax_percent_18) ... ok
… lines 22-105 (84 collapsed lines) — greppy expand bbb7266558408ac3
…
… lines 199-674 (476 collapsed lines) — greppy expand bbb7266558408ac3
…
Verdict and error block sit at the top, with their line number in the log. Then come the beginning and the end of the output; the middle is folded.
| without greppy | with greppy | |
|---|---|---|
| Calls | 1 | 1 |
| Output lines | 734 | 98 |
| Output characters | 48,605 | 6,078 |
| Tokens | 13,094 | 1,651 |
| Exit code | 1 | 1 |
When the agent needs the whole log after all, it fetches the folded part with the expand ID from the same output. Each page names the ID of the next one at its end.
$ greppy expand bbb7266558408ac3
test_tax_percent_19 (tests.test_config.TestParseConfig.test_tax_percent_19) ... ok
test_tax_percent_20 (tests.test_config.TestParseConfig.test_tax_percent_20) ... ok
…
test_line_total_081 (tests.test_pricing.TestLineTotal.test_line_total_081) ... DEBUG shopcart.pricing: line_total: unit=181 qty=5
… 250 lines — greppy expand 6e6a4500016662ed continues at 425
How it works
bash-smart starts the command unchanged and captures stdout and stderr byte for byte. Its exit code is the command's exit code, so scripts and CI treat it like the original. The first line names the result, the exit code and the number of errors and warnings. Then come the error and warning blocks with their line number in the log, followed by the beginning and the end of the output. The middle waits behind an expand ID, and greppy expand ID returns it byte for byte, page by page. With -e REGEX you also pull out every line that matches a pattern of your own. Output of up to 80 lines appears in full after the verdict. You pass pipelines as one quoted expression, and they run with pipefail: a failing command before | tail stays a failure.
The commands
| Command | what it does |
|---|---|
greppy bash-smart -- CMD |
runs CMD unchanged: verdict, errors and warnings first, the rest folded, exit code as in the original |
greppy bash-smart -e REGEX -- CMD |
also pulls out every line that matches REGEX, with its line number; can be repeated |
greppy bash-smart -- 'EXPRESSION' |
shell expressions such as pipelines as one quoted expression, run in Bash with pipefail |
greppy expand ID |
the folded part of the log, byte for byte and page by page |
More in the docs
- Run builds and tests: verdict, folding, environment variables, pipelines and long runs
- Built-in agent: the agent runs every command through
bash-smart