Open savetheclocktower opened 2 years ago
This is awesome!! :100: Thank you for doing this.
As far as the options goes I think it is best to only add options that are needed by users. If no one requests an option I don't see any reason to add it. The ones you have migrated look like a good start.
Once we get the tests migrated (at least some of them) I can setup semantic release to automatically release the package.
Thank you @savetheclocktower for converting my quickly thrown together gist into something that is much more sturdy! And thank you @UziTech for facilitating this :)
@savetheclocktower let me know when you think this is ready for release and I can setup semantic-release to release the first version.
After that is setup you can just use semantic commit messages to automate releases. If you have any questions about that feel free to ask.
I think I'll have it ready in a few more days. A few of the tests are not worth keeping, but it's still worth getting the rest to work.
@UziTech If you're set up to test on Windows, I think we'll be ready for a release if you can manually check the stuff described in #7, particularly the “Testing behavior with various ESLint versions” stuff. If you can't, let me know, and I'll see if I can do it this weekend.
I’m opening this issue to summarize the major changes between
linter-eslint
and this package, and to decide what else is worth changing.Some of the changes are necessary because of the new architecture; some of them are just opportunities to shed support for legacy stuff. I feel like there’s a better sense of project hygiene these days, such that someone who is using a very recent version of ESLint probably doesn’t need some of the oddball config options that
linter-eslint
offered.But then my use cases for
linter-eslint
were pretty bog-standard, so I’ll have to lean on others’ experiences here.(Before reading below, make sure you’ve read the README and understand why this package exists distinct from
linter-eslint
.)Architectural changes
I began with @scagood's work in this gist, then made changes as follows:
Worker script runs in the user’s own version of Node. The README specifies the several ways that this can be set. Out of the box this is just
node
, and in simple cases (no NVM,node
installed in common places) will probably do the right thing without further configuration.Main package and worker pass messages back-and-forth over stdout/stdin. Both use ndjson to properly chunk messages instead of relying on @scagood’s
jsonChunks
helper — which worked surprisingly well for how terse it is, but failed sometimes when especially large JSON payloads were being sent. A few dependencies, but this is a pure JS package and feels safe to use in an arbitrary Node environment. If it isn’t, we can figure out what to replace it with.With newline-delimited JSON,
PromiseQueue
is no longer needed as a way of enforcing one-JSON-chunk-at-a-time behavior. I switched to the systemlinter-eslint
uses: give each job a random ten-character hex string as a unique identifier.All configuration lookups now go through
Config
instead ofatom.config.get
.Config
is what handles the layering of.linter-eslint
files atopatom.config.get
so that package options can be specified either way.Config
has its ownget
method for lookups and anonDidChangeConfig
method for subscribing to changes.The
NodePathTester
object is what handles the sanity-checking of a value that the user gives us fornodeBin
. The goal is to check the value whenevernodeBin
changes just to guard against typos and whatnot. If$nodeBin --version
is successful, we assume it’s a valid Node; if not, we show a message to the user so they can correct it.I was worried that the value of
nodeBin
that this package sees could change at least once during startup as “patches” are overlaid on the core config — first by project-config or atomic-management (if one is installed), then by our own application of.linter-eslint
as a project-specific override.But
Config.initialize
, our first action upon activation, happens synchronously, so anything present in.linter-eslint
will be available from the get-go. Also, I imagine the late activation hook (core:loaded-shell-environment
) saves us from any other startup turmoil.I haven’t tested any of this on Windows yet. I have a Windows machine I could try it on, but I haven’t ever had occasion to set up a Node environment in Windows, so someone who’s well-versed in that would probably be better at identifying areas of improvement there.
You’ll see a lot of
console.log
and its siblings in here. The module exported byconsole.js
shadows the defaultconsole
methods and will skip actual logging unless the package is run in dev mode. I’m not saying that all those statements will stay in for a release, but the logging has been quite helpful in this pre-v1 phase as I’ve moved large parts of this thing around, so I’m in no hurry to take it out.Things I’ve done so far
Integrate new information into the “Debug” command
node
we’re usingDetect incompatible versions of ESLint
atom-package-deps
, but there’s no provision for “optional” dependencies that I can tell, and no way to “borrow” its UI for my use case. So the button just opens up https://atom.io/packages/linter-eslint in the user’s browser.Defer to linter-eslint if present for v7.x ESLint
Things I haven’t done yet and am not certain are worth doing
Fall back to package’s own version of ESLint?
.eslintrc
is found, so how common is it for someone to have an.eslintrc
defined but no local ESLint module?Integrate
consistent-path
?nodeBin
, but the package is read-only and hasn’t been touched in six years.For users who have told us exactly where their Node is, we’d be unnecessarily starting a shell session, including evaluating anything in their
.bashrc
or.zshrc
or whatever.For those who haven’t, it feels like a lot of work to do to guess a value they could honestly just tell us.
I haven’t decided if it’s better to have a robust heuristic here, or if it just complicates our “simply tell us where your Node is” guidance.
Tests
I wanted to pin down the architecture before porting over the specs, but I swear that’s on my agenda.
Options I’ve migrated
Fix on save
Disable when no .eslintrc
Ignore certain rules while typing
Ignore fixable rules while typing
fix
propertyDisable certain rules from auto-fixing
ESLint
construtor (fix: () => {}
)Options I’ve added
Path to Node binary (the big important one)
Warn about old ESLint versions
Options I think should be removed
Use global ESLint — bring-your-own-node means that the worker script ought to handle this properly, I hope? (check workingDir algorithm)
Global node path: again, presence of
nodeBin
makes this unnecessaryOptions I’m on the fence about
Lint HTML files
scopes
setting.Use custom .eslintrc path
ESLint
class to look in a different location for.eslintrc
, so I think we’d have to read in this path and bundle it into the options passed into theESLint
constructor. Plus be sure to clear the cache when this file changes. This would be a lot of work for an obscure use case.Disable caching — so far I’ve not had a need to micromanage caching the way that
linter-eslint
has. Maybe this could control whether we cacheESLint
instances in the worker script at all?Local
node_modules
path — I’ve got a code path for this, but haven’t tested it yet. In theory, this will work; but, again, is this a common use case?