Skip to content
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

--list and --only-errors options #6

Merged
merged 2 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 52 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Scanned 3 documents consisting of 3 operations (and 3 fragments). Visited 16
fields, 0 arguments, 3 named fragment spreads and 0 inline fragment spreads.

Errors: 0
Infractions: 0 (baseline removed: 3)
Infractions: 0 (ignored: 3)
```

Passing all these flags is a chore; instead, let's create a configuration file
Expand All @@ -101,7 +101,7 @@ Scanned 3 documents consisting of 3 operations (and 3 fragments). Visited 16
fields, 0 arguments, 3 named fragment spreads and 0 inline fragment spreads.

Errors: 0
Infractions: 0 (baseline removed: 3)
Infractions: 0 (ignored: 3)
```

## Exit status
Expand Down Expand Up @@ -338,6 +338,56 @@ schema SDL is.
You can also pass `-b baseline.json5` to identify your baseline file; and use
`-u` to update the baseline such that all current documents are allowed.

### Full usage

```
Usage:

gqlcheck [-s schema.graphqls] [-b baseline.json5] [-u] [-l] [-e] doc1.graphql doc2.graphql

Flags:

--help
-h

Output available CLI flags

--version
-v

Output the version

--config <configPath>
-C <configPath>

The path to the config file

--schema <sdlPath>
-s <sdlPath>

Path to the GraphQL schema SDL file

--baseline <jsonPath>
-b <jsonPath>

Path to the baseline file (.json or .json5)

--update-baseline
-u

Update the baseline.json file to allow all passed documents even if they break the rules.

--list
-l

Don't output any details, just list the affected source names.

--only-errors
-e

Only output details about errors (not infractions); combine with `-l` to list only the files with errors.
```

## FAQ

### Do I have to use the `.graphqls` extension for my schema?
Expand Down
2 changes: 1 addition & 1 deletion __tests__/depth-limit-basics/output.custom-baseline.ansi
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ SelfOtherSelf5.graphql:
Scanned 14 documents consisting of 14 operations (and 35 fragments). Visited 113 fields, 0 arguments, 36 named fragment spreads and 0 inline fragment spreads.

Errors: 4
Infractions: 8 (baseline removed: 1)
Infractions: 8 (ignored: 1)
2 changes: 1 addition & 1 deletion __tests__/depth-limit-basics/output.full-baseline.ansi
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ Invalid_FoFoFoFoF_wide_cycle.graphql:
Scanned 14 documents consisting of 14 operations (and 35 fragments). Visited 113 fields, 0 arguments, 36 named fragment spreads and 0 inline fragment spreads.

Errors: 4
Infractions: 0 (baseline removed: 9)
Infractions: 0 (ignored: 9)
7 changes: 7 additions & 0 deletions path/to/operations/doc1.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
query F {
currentUser {
friends {
name
}
}
}
20 changes: 20 additions & 0 deletions path/to/operations/doc2.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
query FoFoF {
currentUser {
...F1
}
}
fragment F1 on User {
friends {
...F2
}
}
fragment F2 on User {
friends {
...F3
}
}
fragment F3 on User {
friends {
name
}
}
17 changes: 17 additions & 0 deletions path/to/operations/doc3.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
query FoFoFoFoFoF {
currentUser {
friends {
friends {
friends {
friends {
friends {
friends {
name
}
}
}
}
}
}
}
}
23 changes: 23 additions & 0 deletions path/to/schema.graphqls
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
type Query {
currentUser: User
}
type User {
name: String
"Same object again"
self: User
otherSelf: User
friends: [User!]!
friendsConnection: UserConnection!
}
type UserConnection {
edges: [FriendEdge]!
pageInfo: PageInfo
}
type PageInfo {
hasNextPage: Boolean
}
type FriendEdge {
cursor: String!
node: User
}

45 changes: 44 additions & 1 deletion src/baseline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ function filterOutput(
);
if (operationCoordinates.length === 0) {
// Fully ignored
filtered++;
return null;
}
op.operationCoordinates = operationCoordinates;
return op;
})
.filter((o) => o != null);
if (operations.length === 0) {
filtered++;
return null;
} else {
e.operations = operations;
Expand All @@ -100,6 +100,30 @@ function filterOutput(
};
}

function filterOutputOnlyErrors(
output: CheckDocumentOutput,
): CheckDocumentOutput {
const { errors: rawErrors } = output;
let filtered = 0;

const errors = rawErrors
.map((e) => {
if ("infraction" in e) {
filtered++;
return null;
} else {
return e;
}
})
.filter((e) => e != null);

return {
...output,
errors,
filtered,
};
}

export function filterBaseline(
baseline: Baseline,
result: CheckOperationsResult,
Expand All @@ -120,3 +144,22 @@ export function filterBaseline(
filtered,
};
}

export function filterOnlyErrors(
result: CheckOperationsResult,
): CheckOperationsResult {
let filtered = 0;
const entries = Object.entries(result.rawResultsBySourceName)
.map(([sourceName, { output: rawOutput, sourceString }]) => {
const output = filterOutputOnlyErrors(rawOutput);
filtered += output.filtered;
return [sourceName, { output, sourceString }];
})
.filter((e) => e != null);
const resultsBySourceName = Object.fromEntries(entries);
return {
...result,
resultsBySourceName,
filtered,
};
}
43 changes: 39 additions & 4 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { parseArgs } from "node:util";
import JSON5 from "json5";
import { kjsonlLines } from "kjsonl";

import { filterBaseline, generateBaseline } from "./baseline.js";
import {
filterBaseline,
filterOnlyErrors,
generateBaseline,
} from "./baseline.js";
import type { SourceLike } from "./interfaces.js";
import { checkOperations } from "./main.js";
import { generateOutputAndCounts } from "./print.js";
Expand Down Expand Up @@ -51,6 +55,20 @@ const parseArgsConfig = {
description:
"Update the baseline.json file to allow all passed documents even if they break the rules.",
},
list: {
short: "l",
type: "boolean",
placeholder: undefined,
description:
"Don't output any details, just list the affected source names.",
},
"only-errors": {
short: "e",
type: "boolean",
placeholder: undefined,
description:
"Only output details about errors (not infractions); combine with `-l` to list only the files with errors.",
},
},
allowPositionals: true,
strict: true,
Expand Down Expand Up @@ -133,7 +151,7 @@ async function main() {
`
Usage:

gqlcheck [-s schema.graphqls] [-b baseline.json5] [-u] doc1.graphql doc2.graphql
gqlcheck [-s schema.graphqls] [-b baseline.json5] [-u] [-l] [-e] doc1.graphql doc2.graphql

Flags:

Expand All @@ -151,7 +169,14 @@ ${(Object.entries(parseArgsConfig.options) as Array<[key: keyof (typeof parseArg
...(values.baseline ? { baselinePath: values.baseline } : null),
};
let result = await checkOperations(getOperations, values.config, conf);
if (values["update-baseline"]) {
if (values["only-errors"]) {
if (values["update-baseline"]) {
throw new Error(
`--update-baseline cannot be combined with --only-errors`,
);
}
result = filterOnlyErrors(result);
} else if (values["update-baseline"]) {
const baselinePath = result.resolvedPreset.gqlcheck?.baselinePath;
if (!baselinePath) {
throw new Error(
Expand All @@ -168,7 +193,17 @@ ${(Object.entries(parseArgsConfig.options) as Array<[key: keyof (typeof parseArg
console.log();
}
const { output, errors, infractions } = generateOutputAndCounts(result);
console.log(output);
if (values["list"]) {
for (const [sourceName, { output }] of Object.entries(
result.resultsBySourceName,
)) {
if (output.errors.length > 0) {
console.log(sourceName);
}
}
} else {
console.log(output);
}
if (errors > 0) {
process.exitCode = 1;
}
Expand Down
6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import type {
VisitorsEvent,
} from "./interfaces.js";

export { filterBaseline, generateBaseline } from "./baseline.js";
export {
filterBaseline,
filterOnlyErrors,
generateBaseline,
} from "./baseline.js";
export {
Baseline,
CheckOperationsResult,
Expand Down
2 changes: 1 addition & 1 deletion src/print.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ ${parts.join("\n\n")}
${printCounts(result)}

Errors: ${errors}
Infractions: ${infractions}${result.filtered > 0 ? ` (baseline removed: ${result.filtered})` : ``}
Infractions: ${infractions}${result.filtered > 0 ? ` (ignored: ${result.filtered})` : ``}
`.trim(),
errors,
infractions,
Expand Down
Loading