-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support checksyncrc files #812
Conversation
Codecov Report
@@ Coverage Diff @@
## main #812 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 28 34 +6
Lines 455 682 +227
Branches 85 145 +60
==========================================
+ Hits 455 682 +227
Continue to review full report at Codecov.
|
{ | ||
"$schema": "./src/checksync.schema.json", | ||
"$comment": "This is the config file for our integration tests. By not specifying it directly, we also test configuration file discovery.", | ||
"autoFix": false, | ||
"comments": [ | ||
"//", | ||
"#", | ||
"{/*" | ||
], | ||
"dryRun": false, | ||
"excludeGlobs": [ | ||
"**/excluded/**" | ||
], | ||
"ignoreFiles": [ | ||
"**/ignore-file.txt" | ||
], | ||
"json": false | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An example config file for checksync. Note that the schema can be specified at the top of the file as per JSON Schema specifications (the schema is shipped with the tool).
Note that folks don't need to include this - their configs will still be validated against this schema, regardless. However, for tools like VSCode, this tells it what schema to use and provides autocomplete/intellisense accordingly.
@@ -0,0 +1,55 @@ | |||
declare module "@hyperjump/json-schema" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pieced this together from typescript and reading the code.
@@ -0,0 +1,79 @@ | |||
{ | |||
"$schema": "https://json-schema.org/draft/2020-12/schema", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the JSON Schema definition file against which our config files will be compared.
// NOTE: minimist treats `no` on the front of a known flag | ||
// as a flag inversion of the none-`no` version. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I learned this the hard way. Nice default feature, if you know it exists.
const schema = await JsonSchema.get("file://./checksync.schema.json"); | ||
|
||
log.verbose(() => `Validating configuration`); | ||
const validation = await JsonSchema.validate( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validation does include details of the actual errors, but it requires some work to turn that into human readable info that can be acted upon, so I'm going to not do that for now.
export {default as checkSync} from "./check-sync.js"; | ||
export {default as loadConfigurationFile} from "./load-configuration-file.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checksync can now be used as an API. Should help with eslint integration, @kevinbarabash
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should improve performance of our eslint rule significantly.
src/string-logger.js
Outdated
*/ | ||
const regex = | ||
const rootDirRegex = new RegExp(escapeRegExp(ROOT_DIR), "g"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The verbose logging mode includes file paths - to make sure they pass, we strip the root dir off them.
|
||
const line = `${" ".repeat(this._groupIndent)}${args | ||
.map(normalize) | ||
.join("")}`.trimRight(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace isn't really relevant and it can be annoying in inline snapshots when saving as eslint/prettier autofixes away empty lines. So, we trim the trailing whitespace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've run into this elsewhere and agree, so annoying.
Thanks for adding support for config files. I'll have a look later this week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Supporting rc files is a great addition to checksync. I left a few comments, but nothing blocking.
@@ -38,6 +38,7 @@ | |||
"@babel/preset-env": "^7.16.4", | |||
"@babel/preset-flow": "^7.16.0", | |||
"@babel/register": "^7.16.0", | |||
"@hyperjump/json-schema": "^0.17.2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you pick @hyperjump/json-schema
over ajv
? Is it faster?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seemed to support more recent drafts of the spec and have a better rep over all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That and it was one of the first i landed on that did what I want (I found it via the jsonschema.org site). I could be persuaded to change it. It worked so I stopped looking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was curious about the speed because I tried to use ajv in the past and it was slow for the schema I had written. It could also been that my schema was overly complex. 🤷♂️
// Where our coverage data does and does not come from. | ||
collectCoverageFrom: ["src/**/*.js", "!src/__tests__/*.js"], | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's too bad jest doesn't automatically filter out test files from coverage.
src/checksync.schema.json
Outdated
"comments": { | ||
"description": "An array of the strings that identify the starts of comments in the files being parsed", | ||
"type": "array", | ||
"items": { | ||
"type": "string" | ||
}, | ||
"uniqueItems": true, | ||
"minLength": 0 | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like json-schema support default
s. If you end up generating docs from this schema file then including defaults might be useful. I'm not sure how schema parsing libraries deal with defaults. It would be nice if you could pass it an empty JSON object and it would return an object with all the defaults.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I seem to recall including defaults in an earlier version, but I decided against it. I don't recall why. I'll check.
export const optionsFromArgs = (args: minimistOutput): $Shape<Options> => { | ||
const options: $Shape<Options> = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe use Partial
instead of $Shape
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't work for this situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that Partial
was just a better version of $Shape
. Do they handle optionality differently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, so Partial
as I understand it, says "I am a type that is any combination of the values within this type" whereas $Shape
says, "I look like this type, but all my values are optional" or something along those lines.
So T
can be considered equal to $Shape<T>
it seems, but T
is not equal to Partial<T>
.
At least, that's my basic understanding.
const excludeGlobs = (args.ignore: any)?.split(";").filter((c) => !!c); | ||
if (excludeGlobs != null) { | ||
options.excludeGlobs = excludeGlobs; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can ignore
be false
like ignoreFiles
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it doesn't work that way - it's either a string, or its not provided. The main reason for the ?
is to work around the ambiguity of minimist typing and the fact that this argument may not be supplied.
if (args.dryRun != null) { | ||
options.dryRun = !!args.dryRun; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does minimist
not provide booleans or is this just to convince Flow that these values are actually booleans?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minimist
types args as boolean | string | void
, I believe. So we need to coerce them to booleans for Flow to recognize we did the right thing.
|
||
const line = `${" ".repeat(this._groupIndent)}${args | ||
.map(normalize) | ||
.join("")}`.trimRight(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've run into this elsewhere and agree, so annoying.
// Could be in the working directory too, so we add a fake child | ||
// to the path that ancesdir will cut off to start the search | ||
// in parent locations, which will then be the cwd. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: don't need to be so specific here since I added the helper method for this
const closestRCPath = checkSyncRcNames | ||
.map((rc) => { | ||
try { | ||
// Could be in the working directory too, so we add a fake child | ||
// to the path that ancesdir will cut off to start the search | ||
// in parent locations, which will then be the cwd. | ||
return path.join(ancesdirOrCurrentDir(process.cwd(), rc), rc); | ||
} catch (e) { | ||
return ""; | ||
} | ||
}) | ||
.filter((f) => f != "") | ||
.map((rcPath) => ({ | ||
rcPath, | ||
distance: path.relative(process.cwd(), rcPath).split(path.sep) | ||
.length, | ||
})) | ||
.reduce((acc, cur) => { | ||
if (acc == null || cur.distance < acc.distance) { | ||
return cur; | ||
} | ||
return acc; | ||
}, null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, if we execute just checksync
we want it to just work, and this caters to that. Means that even in webapp, we could just run it and it should work, even before it knows the root marker
if (!rcForValidation.$schema) { | ||
rcForValidation.$schema = "file://./checksync.schema.json"; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should still validate against our schema, but their tooling will probably complain (if it supports schemas, like vscode for example).
And yes, I believe we do need to set the schema still. The idea is we're asking "validate against this set of schema" and the reference tells it which of those schema to start at. Something like that. I know I had to do a few incantations to get things working.
export const optionsFromArgs = (args: minimistOutput): $Shape<Options> => { | ||
const options: $Shape<Options> = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, so Partial
as I understand it, says "I am a type that is any combination of the values within this type" whereas $Shape
says, "I look like this type, but all my values are optional" or something along those lines.
So T
can be considered equal to $Shape<T>
it seems, but T
is not equal to Partial<T>
.
At least, that's my basic understanding.
TODO: Add tests, and add validation that outputs info about bad configs
Also fixes some issues with the schema loading and makes sure that ancesdir checks the current directory
b4c19d2
to
037a0fc
Compare
Summary:
This adds support for configuration files so that we don't have to supply all options on the command line.
It also adds test coverage for our output sink class and some other light tweaks.
This is the last piece for CheckSync v3! (Though I may try addressing #666)
Note to reviewers:
Much of this diff is test and snapshots updates. I recommend filtering out
.snap
files and skipping over_test.js
files to look at the JSON and JS file changes.Fixes #664
Test plan:
yarn test
yarn flow