Skip to content

Commit

Permalink
feat: support fix and check commands (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
azz authored Oct 21, 2017
1 parent 14d2907 commit 226f20c
Show file tree
Hide file tree
Showing 24 changed files with 2,155 additions and 101 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": [["env", { "targets": { "node": "4.5" } }]]
}
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"es6": true
},
"globals": {
"process": true
"process": true,
"console": true
},
"rules": {
"curly": ["error"],
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
node_modules
.esm-cache
.vscode
dist
*.log
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ install:
- yarn
script:
- yarn lint
- yarn build
- yarn test
after_success:
- npm run semantic-release
Expand Down
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Or with `yarn`:
yarn add --dev prettier-tslint
```

## Confituration
## Configuration

`prettier-tslint` find and will respect:

Expand All @@ -37,17 +37,27 @@ yarn add --dev prettier-tslint

## CLI

```bash
pretttier-tslint file.ts
```
Commands:
fix Fix one or more files
check List files that aren't formatted
Options:
--version Show version number [boolean]
--help Show help [boolean]
Examples:
prettier-tslint fix file1.ts file2.ts Fix provided files
prettier-tslint fix '**/*.ts' Fix all TypeScript files
prettier-tslint check '**/*.ts' List all unformatted TypeScript files
```

## API


```js
import format from "prettier-eslint";
import { fix } from "prettier-tslint";

format("file.ts");
fix("file.ts");
```

Currently the `format` function will write to disk and not return anything. This behavior **will change** in a minor release before `1.0.0` is released.
Currently the `fix` function will write to disk and not return anything. This behavior **will change** in a minor release before `1.0.0` is released.
5 changes: 5 additions & 0 deletions __mocks__/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"env": {
"jest": true
}
}
37 changes: 37 additions & 0 deletions __mocks__/fs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import path from "path";

const actual = require.requireActual("fs");

let writes = {};

export const statSync = jest.fn(actual.statSync);
export const existsSync = jest.fn(actual.existsSync);

export const writeFileSync = jest.fn((filePath, content) => {
const relative = path.relative(process.cwd(), filePath);
writes[relative] = content;
});

export const readFileSync = jest.fn(filePath => {
const relative = path.relative(process.cwd(), filePath);
if (writes[relative]) {
return writes[relative];
}
return actual.readFileSync(filePath, "utf8");
});

export const __clear = () => {
writes = {};
existsSync.mockClear();
statSync.mockClear();
writeFileSync.mockClear();
readFileSync.mockClear();
};

export default {
__clear,
existsSync,
statSync,
readFileSync,
writeFileSync,
};
4 changes: 0 additions & 4 deletions index.js

This file was deleted.

16 changes: 10 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,38 @@
"version": "0.0.0-development",
"author": "Lucas Azzola <@azz>",
"license": "MIT",
"main": "dist",
"bin": "./bin/prettier-tslint.js",
"files": [
"bin",
"src",
"index.js"
"dist"
],
"dependencies": {
"@std/esm": "^0.11.3",
"chalk": "^2.2.0",
"globby": "^6.1.0",
"ignore": "^3.3.5",
"minimist": "^1.2.0",
"tslint": "^5.7.0"
"tslint": "^5.7.0",
"yargs": "^9.0.1"
},
"peerDependencies": {
"prettier": "^1.7.4",
"typescript": "^2.5.3"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.6.1",
"eslint": "^4.9.0",
"eslint-config-prettier": "^2.6.0",
"eslint-plugin-prettier": "^2.3.1",
"jest": "^21.2.1",
"prettier": "1.7.4",
"semantic-release": "^8.0.3",
"typescript": "~2.5.3"
},
"scripts": {
"lint": "eslint .",
"test": "echo soon...",
"test": "jest",
"build": "babel --copy-files --out-dir dist src",
"semantic-release": "semantic-release pre && npm publish && semantic-release post"
},
"repository": {
Expand Down
8 changes: 8 additions & 0 deletions src/check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import runTsLint from "./run-tslint";
import runPrettier from "./run-prettier";

const check = filePath => {
return runPrettier(filePath, false) && runTsLint(filePath, false);
};

export default check;
56 changes: 56 additions & 0 deletions src/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* eslint no-console: 0 */

import chalk from "chalk";
import yargs from "yargs";

import fix from "./fix";
import check from "./check";
import expandGlob from "./expand-glob";
import filterIgnored from "./filter-ignored";

const cli = argv => {
const yargsInstance = yargs
// Fix
.command("fix", "Fix one or more files")
.example("prettier-tslint fix file1.ts file2.ts", "Fix provided files")
.example("prettier-tslint fix '**/*.ts'", "Fix all .ts files")
// Check
.command("check", "List files that aren't formatted")
.example("prettier-tslint check '**/*.ts'", "List unformatted .ts files")
// Meta
.demandCommand(1, "Command not provided.")
.help();

const args = yargsInstance.parse(argv);
const command = args._[0];
const patterns = args._.slice(1);

switch (command) {
case "fix":
return patterns.forEach(fixFiles);
case "check":
return patterns.forEach(checkFiles);
default:
yargs.showHelp();
console.error(`Unknown command: ${command}`);
}
};

const fixFiles = filePattern => {
const files = filterIgnored(expandGlob(filePattern));
files.forEach(file => {
const changed = !fix(file);
console.log(changed ? file : chalk.gray(file));
});
};

const checkFiles = filePattern => {
const files = filterIgnored(expandGlob(filePattern));
const invalid = files.filter(file => !check(file));
if (invalid.length) {
process.exitCode = 1;
}
invalid.forEach(file => console.error(chalk.red.bold(file)));
};

export default cli;
9 changes: 6 additions & 3 deletions src/expand-glob.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import globby from "globby";

const expandGlob = glob => {
return globby.sync(glob, {
dot: true,
});
return globby.sync(
[glob].concat(["!**/node_modules/**", "!./node_modules/**"]),
{
dot: true,
}
);
};

export default expandGlob;
10 changes: 10 additions & 0 deletions src/fix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import runTsLint from "./run-tslint";
import runPrettier from "./run-prettier";

const fix = filePath => {
const prettierCheck = runPrettier(filePath, true);
const tslintCheck = runTsLint(filePath, true);
return prettierCheck && tslintCheck;
};

export default fix;
27 changes: 3 additions & 24 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
import fs from "fs";
import minimist from "minimist";

import expandGlob from "./expand-glob";
import filterIgnored from "./filter-ignored";
import runTsLint from "./run-tslint";
import runPrettier from "./run-prettier";

const format = filePath => {
runPrettier(filePath);
runTsLint(filePath);
};

const formatFiles = filePattern => {
const files = filterIgnored(expandGlob(filePattern));
files.forEach(format);
};

const cliOpts = {};

export const cli = argv => {
const args = minimist(argv, cliOpts);
args._.forEach(formatFiles);
};

export default format;
export { default as cli } from "./cli";
export { default as fix } from "./fix";
export { default as check } from "./check";
19 changes: 16 additions & 3 deletions src/run-prettier.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import fs from "fs";
import prettier from "prettier";

const runPrettier = filepath => {
/**
* @returns true iff output === input
*/
const runPrettier = (filepath, fix) => {
const config = prettier.resolveConfig.sync(filepath);
const code = fs.readFileSync(filepath, "utf8");
const output = prettier.format(code, Object.assign({ filepath }, config));
fs.writeFileSync(filepath, output);
const options = Object.assign({ filepath }, config);

if (fix) {
const output = prettier.format(code, options);
if (output !== code) {
fs.writeFileSync(filepath, output);
return false;
}
return true;
} else {
return prettier.check(code, options);
}
};

export default runPrettier;
17 changes: 13 additions & 4 deletions src/run-tslint.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import fs from "fs";
import tslint from "tslint";
import * as tslint from "tslint";
import createProgram from "./create-program";

const runTsLint = filepath => {
/**
* @returns true iff output === input
*/
const runTsLint = (filepath, fix) => {
const code = fs.readFileSync(filepath, "utf8");
const config = tslint.Configuration.findConfiguration(null, filepath).results;

const program = createProgram(filepath);

// TODO(azz): This actually writes over the file, we don't really want that...
const linter = new tslint.Linter({ fix: true }, program);
const linter = new tslint.Linter({ fix }, program);

linter.lint(filepath, code, config);
const result = linter.getResult();
return result;
if (fix) {
// There were no fixes applied
return result.fixes.length === 0;
} else {
// There were no auto-fixable problems
return !result.failures.find(failure => failure.fix);
}
};

export default runTsLint;
5 changes: 5 additions & 0 deletions test/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"env": {
"jest": true
}
}
25 changes: 25 additions & 0 deletions test/__snapshots__/fix.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`fix() bad format, bad lint writes fix to disk 1`] = `
Array [
"test/fixture/bad-format-bad-lint.ts",
"throw new Error(\\"no-string-throw\\");
",
]
`;

exports[`fix() bad format, good lint writes fix to disk 1`] = `
Array [
"test/fixture/bad-format-good-lint.ts",
"throw new Error(\\"no-string-throw\\");
",
]
`;

exports[`fix() good format, bad lint writes fix to disk 1`] = `
Array [
"test/fixture/good-format-bad-lint.ts",
"throw new Error(\\"no-string-throw\\");
",
]
`;
16 changes: 16 additions & 0 deletions test/check.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import check from "../src/check";

describe("check()", () => {
test("good format, bad lint fails check", () => {
expect(check("test/fixture/good-format-bad-lint.ts")).toEqual(false);
});
test("bad format, good lint fails check", () => {
expect(check("test/fixture/bad-format-good-lint.ts")).toEqual(false);
});
test("bad format, bad lint fails check", () => {
expect(check("test/fixture/bad-format-bad-lint.ts")).toEqual(false);
});
test("good format, good lint passes check", () => {
expect(check("test/fixture/good-format-good-lint.ts")).toEqual(true);
});
});
Loading

0 comments on commit 226f20c

Please sign in to comment.