Fix all lint errors, adding a lint CI step (#175)

Test Plan:
Run `yarn lint` and `yarn travis` and observe success. Add something
that triggers a lint warning, like `const zzz = 3;`; re-run and observe
failures.

wchargin-branch: lint
This commit is contained in:
William Chargin 2018-04-30 14:52:28 -07:00 committed by GitHub
parent 22ca77ed05
commit f3a440244e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 43 additions and 63 deletions

14
.eslintrc.js Normal file
View File

@ -0,0 +1,14 @@
module.exports = {
extends: "react-app",
rules: {
"no-unused-vars": [
"warn",
{
argsIgnorePattern: "^_$|^_unused_",
varsIgnorePattern: "^_$|^_unused_",
caughtErrorsIgnorePattern: "^_$|^_unused_",
},
],
"no-use-before-define": ["off"],
},
};

View File

@ -1,5 +1,3 @@
"use strict";
const fs = require("fs");
const path = require("path");
const paths = require("./paths");

View File

@ -1,5 +1,3 @@
"use strict";
// This is a custom Jest transformer turning style imports into empty objects.
// http://facebook.github.io/jest/docs/en/webpack.html

View File

@ -1,5 +1,3 @@
"use strict";
const path = require("path");
// This is a custom Jest transformer turning file imports into filenames.

View File

@ -1,5 +1,3 @@
"use strict";
const path = require("path");
const fs = require("fs");
const url = require("url");

View File

@ -1,5 +1,3 @@
"use strict";
if (typeof Promise === "undefined") {
// Rejection tracking prevents a common issue where React gets into an
// inconsistent state due to an error, but it gets swallowed by a Promise,

View File

@ -1,6 +1,3 @@
"use strict";
const path = require("path");
const webpack = require("webpack");
const eslintFormatter = require("react-dev-utils/eslintFormatter");
const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin");
@ -68,6 +65,7 @@ module.exports = {
],
},
],
exprContextCritical: false,
},
plugins: [
new webpack.DefinePlugin({

View File

@ -1,5 +1,3 @@
"use strict";
const autoprefixer = require("autoprefixer");
const path = require("path");
const webpack = require("webpack");

View File

@ -1,5 +1,3 @@
"use strict";
const autoprefixer = require("autoprefixer");
const path = require("path");
const webpack = require("webpack");

View File

@ -1,5 +1,3 @@
"use strict";
const errorOverlayMiddleware = require("react-dev-utils/errorOverlayMiddleware");
const noopServiceWorkerMiddleware = require("react-dev-utils/noopServiceWorkerMiddleware");
const ignoredFiles = require("react-dev-utils/ignoredFiles");

View File

@ -62,7 +62,8 @@
"backend": "node scripts/backend.js",
"test": "node scripts/test.js --env=jsdom",
"flow": "flow",
"travis": "npm run check-pretty && npm run flow && CI=true npm run test"
"lint": "eslint src config --max-warnings 0",
"travis": "npm run check-pretty && npm run lint && npm run flow && CI=true npm run test"
},
"license": "MIT",
"lint-staged": {
@ -110,9 +111,6 @@
"react-app"
]
},
"eslintConfig": {
"extends": "react-app"
},
"devDependencies": {
"babel-plugin-flow-react-proptypes": "^18.0.0",
"enzyme": "^3.3.0",

View File

@ -55,7 +55,7 @@ describe("address", () => {
const actual = makeMap().getAll();
const expected = [mansion(), mattressStore()];
const sort = (xs) => sortBy(xs, (x) => stringify(x.address));
expect(sort(actual)).toEqual(sort(actual));
expect(sort(actual)).toEqual(sort(expected));
});
it("removes objects by key", () => {

View File

@ -305,7 +305,7 @@ describe("graph", () => {
demoData.crabLoopEdge()
);
const crabNeighbors = g.neighborhood(demoData.crabNode().address);
const crabLoops = crabNeighbors.filter(({edge, neighborAddress}) =>
const crabLoops = crabNeighbors.filter(({edge}) =>
deepEqual(edge, demoData.crabLoopEdge())
);
expect(crabLoops).toHaveLength(1);
@ -470,9 +470,7 @@ describe("graph", () => {
describe("neighborhood", () => {
const eg = new ExampleGraph();
const edges = (opts) =>
eg.graph
.neighborhood(eg.root, opts)
.map(({edge, neighborAddress}) => edge);
eg.graph.neighborhood(eg.root, opts).map(({edge}) => edge);
const allEdges = [
eg.inEdges.a1,
eg.inEdges.a2,
@ -1138,7 +1136,7 @@ describe("graph", () => {
expect(g1.equals(demoData.advancedMealGraph())).toBe(true);
});
function itAllowsUpcastingPayloadTypes(
function _unused_itAllowsUpcastingPayloadTypes(
g: Graph<{x: string, y: number}, boolean>
): Graph<{x: string}, ?boolean> {
return g.copy();

View File

@ -290,7 +290,7 @@ export const stringify = {
},
parameter(parameter: Parameter, ls: LayoutStrategy): string {
return ls.atom(`\$${parameter.name}: ${parameter.type}`);
return ls.atom(`$${parameter.name}: ${parameter.type}`);
},
fragmentDefinition(fragment: FragmentDefinition, ls: LayoutStrategy): string {
@ -388,7 +388,7 @@ export const stringify = {
},
variableValue(value: VariableValue, ls: LayoutStrategy): string {
return ls.atom(`\$${value.data}`);
return ls.atom(`$${value.data}`);
},
literalValue(value: LiteralValue, ls: LayoutStrategy): string {

View File

@ -105,9 +105,9 @@ export class ArtifactGraphEditor extends React.Component<Props, State> {
value={this.state.artifactInProgressName}
onChange={(e) => {
const value = e.target.value;
this.setState((state) => ({
this.setState({
artifactInProgressName: value,
}));
});
}}
/>
<button

View File

@ -2,8 +2,6 @@
import React from "react";
import {shallow} from "enzyme";
import enzymeToJSON from "enzyme-to-json";
import stringify from "json-stable-stringify";
import {Graph} from "../../../core/graph";
import {ArtifactGraphEditor} from "./ArtifactGraphEditor";

View File

@ -2,7 +2,6 @@
import React from "react";
import type {Address} from "../../../core/address";
import type {Node} from "../../../core/graph";
import {AdapterSet} from "./adapterSet";
import {Graph} from "../../../core/graph";
@ -100,7 +99,7 @@ export class ContributionList extends React.Component<Props, State> {
node.address.type === typeFilter.type
);
}
: (node) => true;
: (_) => true;
return (
<table>
<thead>

View File

@ -47,9 +47,7 @@ export class SettingsConfig extends React.Component<Props, State> {
onChange={(e) => {
const value = e.target.value;
this.setState(
(state) => ({
githubApiToken: value,
}),
{githubApiToken: value},
this._updateSettings.bind(this)
);
}}
@ -63,9 +61,7 @@ export class SettingsConfig extends React.Component<Props, State> {
onChange={(e) => {
const value = e.target.value;
this.setState(
(state) => ({
repoOwner: value,
}),
{repoOwner: value},
this._updateSettings.bind(this)
);
}}
@ -78,12 +74,7 @@ export class SettingsConfig extends React.Component<Props, State> {
value={this.state.repoName}
onChange={(e) => {
const value = e.target.value;
this.setState(
(state) => ({
repoName: value,
}),
this._updateSettings.bind(this)
);
this.setState({repoName: value}, this._updateSettings.bind(this));
}}
/>
</label>

View File

@ -77,10 +77,10 @@ function loadTree(git: GitDriver, treeHash: Hash): Tree {
git(["ls-tree", "--full-tree", "-z", treeHash])
.split("\0")
.filter((line) => line.length > 0)
.map((line) => {
.forEach((line) => {
// See `git help ls-tree`, section OUTPUT FORMAT, for details.
const [metadata, name] = line.split("\t");
const [mode, type, hash] = metadata.split(" ");
const [_unused_mode, type, hash] = metadata.split(" ");
if (type !== "blob" && type !== "commit" && type !== "tree") {
throw new Error(
`entry ${treeHash}[${JSON.stringify(name)}] ` +

View File

@ -3,7 +3,6 @@
import tmp from "tmp";
import {createExampleRepo} from "./demoData/exampleRepo";
import {makeUtils} from "./gitUtils";
import {loadRepository} from "./loadRepository";
const cleanups: (() => void)[] = [];

View File

@ -79,10 +79,14 @@ describe("GitHub porcelain API", () => {
describe("type coercion", () => {
it("type coercion works when typed correctly", () => {
const issue: Issue = Issue.from(issueOrPRByNumber(1));
const pr: PullRequest = PullRequest.from(issueOrPRByNumber(3));
const author: Author = Author.from(issueOrPRByNumber(3).authors()[0]);
const comment: Comment = Comment.from(issueOrPRByNumber(2).comments()[0]);
const _unused_issue: Issue = Issue.from(issueOrPRByNumber(1));
const _unused_pr: PullRequest = PullRequest.from(issueOrPRByNumber(3));
const _unused_author: Author = Author.from(
issueOrPRByNumber(3).authors()[0]
);
const _unused_comment: Comment = Comment.from(
issueOrPRByNumber(2).comments()[0]
);
});
it("type coercion throws error when typed incorrectly", () => {
expect(() => PullRequest.from(issueOrPRByNumber(1))).toThrowError(

View File

@ -788,7 +788,6 @@ function reviewCommentsFragment(): FragmentDefinition {
* fetch more pages of specific entity types.
*/
export function createFragments(): FragmentDefinition[] {
const b = build;
return [
whoamiFragment(),
issuesFragment(),

View File

@ -2,7 +2,6 @@
import type {Continuation} from "./graphql";
import {build} from "../../graphql/queries";
import {stringify, multilineLayout} from "../../graphql/queries";
import {
PAGE_LIMIT,
createQuery,

View File

@ -23,7 +23,6 @@ import type {
IssueJSON,
CommentJSON,
AuthorJSON,
PullRequestReviewCommentJSON,
} from "./graphql";
import type {Address} from "../../core/address";

View File

@ -126,10 +126,10 @@ export type EdgePayload =
| ContainsEdgePayload
| ReferencesEdgePayload;
(function staticAssertions() {
function _unused_staticAssertions() {
// Check that node & edge payload types are exhaustive.
(x: NodeType): $Keys<NodeTypes> => x;
(x: EdgeType): $Keys<EdgeTypes> => x;
const _unused_exhaustiveNode = (x: NodeType): $Keys<NodeTypes> => x;
const _unused_exhaustiveEdge = (x: EdgeType): $Keys<EdgeTypes> => x;
// Check that each type is associated with the correct ID type.
// Doesn't work because of a Flow bug; should work if that bug is
@ -142,4 +142,4 @@ export type EdgePayload =
// $ElementType<$ElementType<NodeTypes, T>, "id">,
// "type"
// > => x;
});
}