goalline How it worksClaude Code hookGitHub ActionBenchmarkCommandsGitHub

goalline / Benchmark

Replaying 400 merged pull requests of pallets/click and pallets/jinja

goalline history ran goalpost on the last 200 pull requests merged into main of pallets/click and pallets/jinja. 126 edited an existing test, and 31 were flagged with their old and new values. Every flag was a deliberate change that its PR explains in one line, and 4 changed what users see without the changelog saying so.

goalline on pallets/click, the last 200 merged PRs: 84 edited an existing test, 63 kept every old test passing, 19 were flagged with their old and new values, 2 were low risk, 0 could not be judged.
pallets/clickpallets/jinja
Merged PRs replayed200200
Edited an existing test (a "test changed" alarm fires on every one)8442
Needs a look: an old expectation moved, shown with its old and new values1910
Low risk: the old test fails, but the PR only added lines to it20
Kept every old test passing6329
Could not be judged03
Machine timeabout 3 minutesabout 2 minutes

What users see, and the changelog doesn't say

Every flag was a deliberate change. These 4 also changed what users see, and the changelog doesn't mention them: a reviewer sees them only because the old test ran.

Every flag, and why

The reasons come from each PR's title and text, its changelog lines and click's docs. Test plumbing is a test that imported a private helper the PR removed: nothing users see changed.

pallets/jinja

PRWhat movedWhyKind
#1621 use posixpath.join when loading template namespackage template file names end in foo/test.html, not foo\test.htmltemplate names are joined with / on every OS nowintended (shows on Windows only)
#1544 remove deprecated codeoverriding the legacy resolve no longer warns (DID NOT WARN)the deprecated legacy code it warned about was removedintended
#1393 deprecate legacy resolve modeoverriding resolve raises a DeprecationWarningthe deprecation itself (jinja's tests turn warnings into errors)intended
#1392 async support doesn't require patchingthe old test files import jinja2.asyncsupport, which is gonethe module was removed; async support is built inintended
#1391 Markup and escape should be imported from markupsafejinja2.Markup and jinja2.escape raise a DeprecationWarningthe re-exports are deprecated in favour of markupsafeintended
#1389 unify/rename context function decoratorscontextfunction and its siblings raise a DeprecationWarningrenamed to pass_context, pass_eval_context and pass_environmentintended
#1383 add 'is filter' and 'is test' testsno filter named 'f' became No filter named 'f'. and No filter named 'f' found.filters and tests share their code now; the new error text is in neither the PR text nor the changelogintended, not in the changelog
#1243 deprecate 'autoescape' and 'with' extensions for removal in 3.1the autoescape and with extensions raise a DeprecationWarningboth are built in nowintended
#1136 Drop Python 2the undefined-variable warning missing is undefined became 'missing' is undefined; old files import the removed jinja2._compatPython 2 support removed and f-strings used everywhere; the new warning text is in neither the PR text nor the changelogintended, not in the changelog
#1133 Revert "Rename to Jinja"the old test files import jinjathe package rename was reverted to jinja2intended

pallets/click

PRWhat movedWhyKind
#3877 Add Parameter.spec and deprecate human_readable_nameoption 'my_option' is deprecated became The option '--my-option' is deprecated.messages name options as users type them; the changelog quotes the before and afterintended
#3866 Deprecate parameter names that are: not a Python identifier, or a Python Keyword, or not lower-casedan option named in raises a DeprecationWarningthe deprecation itselfintended
#3876 Merge stable into mainthe short help of 123 567 9. aaaa bbb is 123 567..., not 123 567 9.a period followed by a lowercase word no longer ends a sentence ("Fix short help abbreviation", in the changelog)intended
#3767 Refactor pager stream handlingoutput through the null pager to a non-terminal stream loses its colour codes; an internal helper returns a different shapepager streams unified; the PR's tests expect the colour change, but neither its text nor its changelog line mentions itintended, not in the changelog
#3704 Deprecate isolated_filesystem and document its limitsCliRunner.isolated_filesystem raises a DeprecationWarningthe deprecation itselfintended
#3695 Mark clearly functions private status. Deprecated Python 2 utilities.get_binary_stream, KeepOpenFile, LazyFile and make_default_short_help raise a DeprecationWarningPython 2 era utilities deprecatedintended
#3678 Fix parsing when a parameter is named helpto_info_dict() shows the help option under _click_default_helpthe help option's internal name changed so a parameter named help works; in the changelogintended
#3563 Merge stable into main after CHANGES rST to Markdown conversionthe old test file imports click._compat.MAC, which is gonea private constant used only to skip a test was removed while fixing a test racetest plumbing
#3479 Merge stable into maincase-insensitive Choice completion suggests au, not Aucompletion goes through normalize_choice() now; the changelog mentions Enum completion, not the lowercased suggestionsintended, not in the changelog
#3391 Add capture mode to CliRunner and revert default fileno exposureCliRunner streams no longer have a fileno()the revert in the title; a new capture mode brings it backintended
#3228 Add NoSuchCommand exception with suggestions for misspelled commandsNo such option: --foo became No such option '--foo'., and Did you mean --count? became Did you mean '--count'?error messages reformatted for consistency, as the PR saysintended
#3126 Fix: Ensure fish completion handles multiline help strings correctlyfish completion output escapes the newlines in helpthe fix itselfintended
#3363 Auto-detect type=UNPROCESSED when flag_value has non-basic typesenum, class and int flag values arrive as objects, not stringsthe point of the PRintended
#3239 Reconcile default value passing and default activationdefault=True with flag_value=False activates the flag: Flag [y/N] became Flag [Y/n], and Enter gives Truewhat default=True means for flags was redefinedintended
#3225 Fix callable flag_value being instantiated when used as a defaulta class used as flag_value arrives as the class, not an instancethe fix itselfintended
#2991 fix a race in click.testing.StreamMixer's finalization, seen in a multi-threaded contextthe captured streams close when isolation ends, so reading them afterwards failsthe race fix (in the changelog); the PR moved the tests' checks inside the blockintended
#2956 Fix reconciliation of envvar with default, flag_value and type parameters for flag optionsflag values from env vars and defaults (upper where it was False)the fixes the title listsintended
#2934 Raise an exception on end of input in CliRunnerprompts in CliRunner abort at the end of input (Aborted!) instead of reading empty stringsmatch a real terminal, where the end of input raisesintended
#2796 Expand Choice token normalization + make genericcustom ParamType.get_metavar() is called with ctx; Choice info dicts changedChoice made generic; the new ctx argument is in click's 'support multiple versions' guideintended
#3473 Add help parameter to argumentsto_info_dict() gains help for arguments (lines only added)the feature itselfintended (low risk)
#3371 ParamType and other typing improvementsimporting click also imports abc now (lines only added to the allowed list)ParamType became an abstract base classintended (low risk)

What it found in goalline itself

jinja found two sources of false flags in goalline, both fixed in 0.13.0. Re-run with both fixes, click's numbers did not change.

How it was run

Not judged on jinja:

A flag is not a bug report

In #3239, a click --flag option with prompt=True, default=True, flag_value=False went from Flag [y/N]: (Enter gives False) to Flag [Y/n]: (Enter gives True), with three lines of a test table edited to match and all 11 CI checks green. It was intended. That is the point: a reviewer sees the change and its values, not just a green check.

click was also judged as each PR was first opened (--first-heads, 199 PRs): no PR edited a test to hide a change that review then took back.

Reproduce it

Clone the project, install it, pytest and its test dependencies into a virtualenv, activate it, and run:

npx github:intikhab49/goalline history --from-git --limit 200 -- python -m pytest {files}

jinja's PRs from 2020 and early 2021 need the packages of that time (pytest 6.2.5, MarkupSafe 1.1.1): run those with a second virtualenv and --only <PR numbers> into the same --out folder.

Run it on your repository

npx github:intikhab49/goalline history --from-git -- npx jest {files}

It writes goalline-history/report.md: the PRs that need a look, with the old and new values, next to the number a 'test file changed' alarm would fire on. It runs one check at a time while the machine is idle, and resumes where it stopped.

Related