Page MenuHomePhabricator

[lint] add a basic hh_client-parsing linter
Needs RevisionPublic

Authored by pieter on Aug 1 2014, 1:50 AM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Apr 3, 1:16 AM
Unknown Object (File)
Fri, Mar 29, 9:26 PM
Unknown Object (File)
Mar 10 2024, 12:46 PM
Unknown Object (File)
Mar 3 2024, 10:10 AM
Unknown Object (File)
Feb 3 2024, 12:17 AM
Unknown Object (File)
Feb 2 2024, 7:54 AM
Unknown Object (File)
Jan 10 2024, 9:22 AM
Unknown Object (File)
Jan 10 2024, 9:21 AM
This revision can not be accepted until the required legal agreements have been signed.

Details

Summary

Pretty minimal linter that parses
hh_client --json check repo_root_here output and turns it into
lint warnings.

It's worth noting that the typical type error is an inconsistency
between two parts of the code, so we have some choice of where
to raise the actual lint warning. Here, we resolve this by:

  • Raising every type error exactly once, at the first diff-relevant path that is mentioned in the Hack error...
  • ...and using error-level severity for the lint warnings to ensure that they show up (even if the corresponding line was not modified in this diff).

Caveats

The framework (...ExternalLinter) really wants to

run the binary for each file. For hh_client that's not really
necessary [many type errors cross file boundaries, so the checker
doesn't have a specific file input], but we end up
doing it anyway. In practice, repeat calls to hh_client are cheap,
but we're still wasting time repeatedly parsing the same json.

Along the same lines as ^, we rely on the framework to filter

identical errors, or this would end up being very noisy.

  1. This includes some borderline-unrelated hacky changes in the test base class to make hh_client happy (needs .php files; needs a .hhconfig in the 'repo' root).
Test Plan
arc linters # note hh_client
cd ~/devtools/arcanist/src/lint/linter/__tests__
arc unit . # note: SKIP for Hack linter
export PATH=$PATH:path/to/hh_client
arc unit . # note: Hack linter succeeds

Also:

haaaack.png (876×769 px, 75 KB)

Diff Detail

Repository
rARC Arcanist
Branch
hacklint
Lint
Lint Passed
Unit
Tests Passed
Build Status
Buildable 2104
Build 2108: [Placeholder Plan] Wait for 30 Seconds

Event Timeline

pieter retitled this revision from to [lint] add a basic hh_client-parsing linter.
pieter updated this object.
pieter edited the test plan for this revision. (Show Details)
pieter added a reviewer: epriestley.
pieter added a subscriber: johnclyde.

Classic: updated a git commit message with # for enumerated list; will fix my diff description momentarily.

pieter edited edge metadata.
pieter updated this object.
src/lint/linter/ArcanistHackLinter.php
12

pht() this

20

Write something more useful here? You can use arc linters to see other examples.

src/lint/linter/__tests__/ArcanistHackLinterTestCase.php
14

This seems like a weird requirement. Why does hh_client need this, if it accepts an empty file?

T5102 recently changed some of the # rules in an effort to be more markdown-compatible. Possibly the heuristic for deciding "header" vs "numbered list" needs to be stricter.

Thanks for instaresponse. Was just going to ask re: remarkup ;)

.hhconfig seems to be necessary for the server to decide where the repo root is. The check seems to happen
even if you specify a directory when calling hh_client, so the short answer appears to be 'yes.' My guess is
we used .arcconfig originally.

To fix the "it tries to run on every path" thing you could subclass ArcanistLinter directly. You'd lose some of the builtin support for adjusting flags and paths, but maybe that's unlikely to be important?

pieter edited edge metadata.

Extend ArcanistLinter directly; forgo some of the awesomeness
of the ExternalLinter.

Minor formatting fix for the lint warning output: indent the
message slightly; drop the File prefix for locations.

src/lint/linter/ArcanistHackLinter.php
72–76

Thoughts on the appropriate level of aggro welcome. I'm pretty much working under the assumption that anyone who uses this linter wants to keep a Hack-clean repo.

src/lint/linter/__tests__/hack/01_basic_error.lint-test
12

Will fix.

epriestley edited edge metadata.

Some minor nitpicks -- I think I caught one actual issue that's really our fault.

src/lint/linter/ArcanistHackLinter.php
9

Unused.

12

(I think this is correct not to pht().)

38

I think this method no longer exists. Currently, getVersion() has no callers if you're a direct ArcanistLinter subclass, I believe, so this code isn't reachable. We want to set minimum linter versions for the unit tests and allow them to be configured, but there are a couple outstanding diffs that hit issues and this is generally a bit gummy.

In any case, we expect this code to be reachable in the future so it's worth making an effort to implement it, but you may need to manually force it to execute for now.

Using %s and hh_client is probably good enough.

72–76

Just throw an exception instead:

throw new Exception(pht('yer hh_client dun work'));
118

pht()

131

Extra semicolon.

134

Add array typehint and call this $errors?

136

This is sort of overkill, but properly:

pht('%d type error(s):', new PhutilNumber(count($error)))

...and then if you really want to overachieve, add English translations to "Type error:" and "Type errors:".

138

Use pht() instead of sprintf().

src/lint/linter/__tests__/ArcanistLinterTestCase.php
25

For consistency with conventions, let's call this didCreateTemporaryDirectory() to signal that it's a post-action callback hook.

This revision now requires changes to proceed.Aug 5 2014, 3:01 PM
pieter edited edge metadata.

Rebase. Per @epriestley: fixed version; renamed callback; updated
error handling; adjusted messaging(s).

checkmarks

src/lint/linter/ArcanistHackLinter.php
9

72–76

118

131

134

136

I think this was just being lazy -- the correct interpretation is that this is
a single type error; Hack just reports each "participating" location separately
(for science).

138

src/lint/linter/__tests__/ArcanistLinterTestCase.php
25

This looks good to me, can you sign the CLA?

And/or get Facebook to sign or whatever - @jamesgpearce might be able to facilitate that. If Facebook signs the corporate one (L30) I can add an exemption for you on L28.

epriestley edited edge metadata.

See above.

This revision now requires changes to proceed.May 17 2015, 2:43 PM

Content Hidden

The content of this revision is hidden until the author has signed all of the required legal agreements.