Skip to content

Commit d8789a4

Browse files
authoredOct 19, 2017
feat: warn when clang-format fails (#62)
Fixes #60
1 parent 0f8a049 commit d8789a4

File tree

8 files changed

+62
-33
lines changed

8 files changed

+62
-33
lines changed
 

‎package-lock.json

+7-13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"format-check": "./bin/format-check.sh",
2727
"format": "clang-format -i -style='{Language: JavaScript, BasedOnStyle: Google, ColumnLimit: 80}' src/*.ts test/*.ts",
2828
"lint": "tslint -c tslint.json --project . --type-check -t codeFrame",
29-
"lint-fix": "tslint -c tslint.json --project . --type-check -t codeFrame --fix",
29+
"lint-fix": "tslint -c tslint.json --project . --type-check -t codeFrame --fix",
3030
"prepare": "npm run compile",
3131
"test": "npm run compile && nyc ava build/test/test*.js",
3232
"posttest": "npm run lint && npm run format-check"
@@ -38,7 +38,7 @@
3838
"author": "Google Inc.",
3939
"license": "Apache-2.0",
4040
"dependencies": {
41-
"chalk": "^2.0.1",
41+
"chalk": "^2.2.0",
4242
"clang-format": "^1.0.53",
4343
"inquirer": "^3.2.1",
4444
"meow": "^3.7.0",
@@ -49,7 +49,6 @@
4949
"write-file-atomic": "^2.1.0"
5050
},
5151
"devDependencies": {
52-
"@types/chalk": "^0.4.31",
5352
"@types/glob": "^5.0.30",
5453
"@types/inquirer": "0.0.35",
5554
"@types/make-dir": "^1.0.1",

‎src/clean.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import * as chalk from 'chalk';
16+
import chalk from 'chalk';
1717

1818
import {Options} from './cli';
1919
import {getTSConfig, rimrafp} from './util';

‎src/cli.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ async function run(verb: string, files: string[]): Promise<boolean> {
8686
const format: VerbFilesFunction = require('./format').format;
8787
switch (verb) {
8888
case 'check':
89-
return (await lint(options, files) && await format(options, files));
89+
const passLint = await lint(options, files);
90+
const passFormat = await format(options, files);
91+
return passLint && passFormat;
9092
case 'fix':
9193
return (
9294
await lint(options, files, true) &&

‎src/format.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const baseArgs =
2727
* @param fix whether to automatically fix the format
2828
* @param files files to format
2929
*/
30-
export function format(
30+
export async function format(
3131
options: Options, files: string[] = [], fix = false): Promise<boolean> {
3232
const program = createProgram(options);
3333
const srcFiles = files.length > 0 ?
@@ -36,7 +36,16 @@ export function format(
3636
.map(sourceFile => sourceFile.fileName)
3737
.filter(f => !f.endsWith('.d.ts'));
3838

39-
return fix ? fixFormat(srcFiles) : checkFormat(srcFiles);
39+
if (fix) {
40+
return fixFormat(srcFiles);
41+
} else {
42+
const result = await checkFormat(srcFiles);
43+
if (!result) {
44+
options.logger.log(
45+
'clang-format reported errors... run `gts fix` to address.');
46+
}
47+
return result;
48+
}
4049
}
4150

4251
/**

‎src/init.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import * as chalk from 'chalk';
16+
import chalk from 'chalk';
1717
import * as cp from 'child_process';
1818
import * as inquirer from 'inquirer';
1919
import * as path from 'path';

‎test/fixtures/kitchen/src/server.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
const isThisTypeScript = true
1+
const isThisTypeScript = true

‎test/test-kitchen.ts

+36-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import test from 'ava';
2-
import * as chalk from 'chalk';
2+
import chalk from 'chalk';
33
import * as cp from 'child_process';
44
import * as fs from 'fs';
55
import * as ncp from 'ncp';
@@ -8,14 +8,36 @@ import * as pify from 'pify';
88
import * as rimraf from 'rimraf';
99
import * as tmp from 'tmp';
1010

11+
interface ExecResult {
12+
exitCode: number;
13+
stdout: string;
14+
stderr: string;
15+
}
16+
1117
const pkg = require('../../package.json');
1218

1319
const rimrafp = pify(rimraf);
1420
const mkdirp = pify(fs.mkdir);
15-
const execp = pify(cp.exec);
21+
const simpleExecp = pify(cp.exec);
1622
const renamep = pify(fs.rename);
1723
const ncpp = pify(ncp.ncp);
1824

25+
// cp.exec doesn't fit the (err ^ result) pattern because a process can write
26+
// to stdout/stderr and still exit with error code != 0.
27+
// In most cases simply promisifying cp.exec is adequate, but it's not if we
28+
// need to see console output for a process that exited with a non-zero exit
29+
// code, so we define a more exhaustive promsified cp.exec here.
30+
const execp =
31+
(command: string, execOptions?: cp.ExecOptions): Promise<ExecResult> => {
32+
return new Promise((resolve) => {
33+
cp.exec(
34+
command, execOptions || {},
35+
(err: Error&{code: number}, stdout, stderr) => {
36+
resolve({exitCode: err ? err.code : 0, stdout, stderr});
37+
});
38+
});
39+
};
40+
1941
const keep = !!process.env.GTS_KEEP_TEMPDIRS;
2042
const stagingDir = tmp.dirSync({keep: keep, unsafeCleanup: true});
2143
const stagingPath = stagingDir.name;
@@ -30,43 +52,46 @@ console.log(`${chalk.blue(`${__filename} staging area: ${stagingPath}`)}`);
3052
* to test on a fresh application.
3153
*/
3254
test.before(async () => {
33-
await execp('npm pack');
55+
await simpleExecp('npm pack');
3456
const tarball = `${pkg.name}-${pkg.version}.tgz`;
3557
await renamep(tarball, `${stagingPath}/gts.tgz`);
3658
await ncpp('test/fixtures', `${stagingPath}/`);
37-
await execp('npm install', execOpts);
59+
await simpleExecp('npm install', execOpts);
3860
});
3961

4062
test.serial('init', async t => {
41-
await execp('./node_modules/.bin/gts init -y', execOpts);
63+
await simpleExecp('./node_modules/.bin/gts init -y', execOpts);
4264
fs.accessSync(`${stagingPath}/kitchen/tsconfig.json`);
4365
t.pass();
4466
});
4567

4668
test.serial('check before fix', async t => {
47-
await t.throws(execp('npm run check', execOpts));
69+
const {exitCode, stdout} = await execp('npm run check', execOpts);
70+
t.deepEqual(exitCode, 1);
71+
t.notDeepEqual(stdout.indexOf('clang-format reported errors'), -1);
4872
t.pass();
4973
});
5074

5175
test.serial('fix', async t => {
5276
const preFix = fs.readFileSync(`${stagingPath}/kitchen/src/server.ts`, 'utf8')
5377
.split('\n');
54-
await execp('npm run fix', execOpts);
78+
await simpleExecp('npm run fix', execOpts);
5579
const postFix =
5680
fs.readFileSync(`${stagingPath}/kitchen/src/server.ts`, 'utf8')
5781
.split('\n');
5882
t.deepEqual(
59-
preFix[0] + ';', postFix[0]); // fix should have added a semi-colon
83+
preFix[0].trim() + ';',
84+
postFix[0]); // fix should have added a semi-colon
6085
t.pass();
6186
});
6287

6388
test.serial('check after fix', async t => {
64-
await execp('npm run check', execOpts);
89+
await simpleExecp('npm run check', execOpts);
6590
t.pass();
6691
});
6792

6893
test.serial('build', async t => {
69-
await execp('npm run compile', execOpts);
94+
await simpleExecp('npm run compile', execOpts);
7095
fs.accessSync(`${stagingPath}/kitchen/build/src/server.js`);
7196
fs.accessSync(`${stagingPath}/kitchen/build/src/server.js.map`);
7297
fs.accessSync(`${stagingPath}/kitchen/build/src/server.d.ts`);
@@ -78,7 +103,7 @@ test.serial('build', async t => {
78103
* output dir
79104
*/
80105
test.serial('clean', async t => {
81-
await execp('npm run clean', execOpts);
106+
await simpleExecp('npm run clean', execOpts);
82107
t.throws(() => {
83108
fs.accessSync(`${stagingPath}/kitchen/build`);
84109
});

0 commit comments

Comments
 (0)