Skip to content

Commit c139452

Browse files
committed
chore: strengthen and improve forbidden-keywords.
1 parent b711c2b commit c139452

File tree

5 files changed

+151
-34
lines changed

5 files changed

+151
-34
lines changed

.travis.yml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ env:
4040
- secure: "fq/U7VDMWO8O8SnAQkdbkoSe2X92PVqg4d044HmRYVmcf6YbO48+xeGJ8yOk0pCBwl3ISO4Q2ot0x546kxfiYBuHkZetlngZxZCtQiFT9kyId8ZKcYdXaIW9OVdw3Gh3tQyUwDucfkVhqcs52D6NZjyE2aWZ4/d1V4kWRO/LMgo="
4141
matrix:
4242
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
43+
- MODE=lint
4344
- MODE=e2e
4445
- MODE=saucelabs_required
4546
- MODE=browserstack_required
@@ -52,23 +53,12 @@ matrix:
5253
- env: "MODE=saucelabs_optional"
5354
- env: "MODE=browserstack_optional"
5455

55-
before_install:
56-
- ./scripts/ci/install_dart.sh
57-
58-
5956
install:
6057
- npm install
6158
- npm run typings
6259

6360
before_script:
64-
# Necessary to run test on Travis CI that require a graphical interface.
65-
# See https://docs.travis-ci.com/user/gui-and-headless-browsers
66-
- "export DISPLAY=:99.0"
67-
- "sh -e /etc/init.d/xvfb start"
6861
- mkdir -p $LOGS_DIR
69-
- npm run tslint
70-
- "node ./scripts/ci/forbidden-identifiers.js"
71-
7262

7363
script:
7464
- ./scripts/ci/build-and-test.sh

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"url": "https://github.com/angular/material2.git"
99
},
1010
"scripts": {
11+
"ci:forbidden-identifiers": "node ./scripts/ci/forbidden-identifiers.js",
1112
"build": "ng build",
1213
"dartanalyzer": "cd dist/dart && pub install && cd ../.. && ts-node scripts/ci/dart_analyzer",
1314
"demo-app": "ng serve",

scripts/ci/build-and-test.sh

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ source scripts/ci/sources/mode.sh
1111
source scripts/ci/sources/tunnel.sh
1212

1313
# Setup environment.
14-
is_dart && source scripts/ci/sources/env_dart.sh
14+
if is_dart; then
15+
./scripts/ci/install_dart.sh
16+
source scripts/ci/sources/env_dart.sh
17+
fi
1518

1619
start_tunnel
1720
npm run build
@@ -20,9 +23,12 @@ echo
2023
is_dart && pub install
2124

2225
wait_for_tunnel
23-
if is_dart; then
26+
if is_lint; then
27+
npm run tslint
28+
npm run ci:forbidden-identifiers
29+
elif is_dart; then
2430
npm run dartanalyzer
25-
elif [[ "$MODE" = e2e* ]]; then
31+
elif is_e2e; then
2632
ng serve &
2733
sleep 20
2834
npm run e2e

scripts/ci/forbidden-identifiers.js

Lines changed: 132 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,142 @@
44
* It will search for blocked statements, which have been added in the commits and fail if present.
55
*/
66

7-
var child_process = require('child_process');
8-
var blocked_statements = [
9-
'ddescribe',
10-
'fdescribe',
11-
'iit',
12-
'fit',
13-
'xdescribe',
14-
'xit',
15-
'debugger;'
7+
const child_process = require('child_process');
8+
const fs = require('fs');
9+
10+
const exec = function(cmd) {
11+
return new Promise(function(resolve, reject) {
12+
child_process.exec(cmd, function(err, stdout /*, stderr */) {
13+
if (err) {
14+
reject(err);
15+
} else {
16+
resolve(stdout);
17+
}
18+
});
19+
});
20+
};
21+
22+
23+
const blocked_statements = [
24+
'\\bddescribe\\(',
25+
'\\bfdescribe\\(',
26+
'\\biit\\(',
27+
'\\bfit\\(',
28+
'\\bxdescribe\\(',
29+
'\\bxit\\(',
30+
'\\bdebugger;'
1631
];
1732

18-
var blockedRegex = new RegExp('\\+.*(' + blocked_statements.join('|') + ').*$', 'mg');
19-
var commit_range = process.env.TRAVIS_COMMIT_RANGE || 'HEAD~1';
33+
const blockedRegex = new RegExp(blocked_statements.join('|'), 'g');
34+
35+
/**
36+
* Find the fork point between HEAD of the current branch, and master.
37+
* @return {Promise<string>} A promise which resolves with the fork SHA (or reject).
38+
*/
39+
function findForkPoint() {
40+
return exec('git merge-base --fork-point HEAD master')
41+
.then(function(stdout) {
42+
return stdout.split('\n')[0];
43+
});
44+
}
45+
46+
/**
47+
* Get the commit range to evaluate when this script is run.
48+
* @return {Promise<string>} A commit range of the form ref1...ref2.
49+
*/
50+
function getCommitRange() {
51+
if (process.env['TRAVIS_COMMIT_RANGE']) {
52+
return Promise.resolve(process.env['TRAVIS_COMMIT_RANGE']);
53+
} else {
54+
return findForkPoint().then((forkPointSha) => `${forkPointSha}...HEAD`);
55+
}
56+
}
57+
58+
/**
59+
* List all the files that have been changed or added in the last commit range.
60+
* @returns {Promise<Array<string>>} Resolves with a list of files that are
61+
* added or changed.
62+
*/
63+
function findChangedFiles() {
64+
return getCommitRange()
65+
.then(function(range) {
66+
return exec(`git diff --name-status ${range} ./src ./e2e`);
67+
})
68+
.then(function(rawDiff) {
69+
// Ignore deleted files.
70+
return rawDiff.split('\n')
71+
.filter(function(line) {
72+
// Status: C## => Copied (##% confident)
73+
// R## => Renamed (##% confident)
74+
// D => Deleted
75+
// M => Modified
76+
// A => Added
77+
return line.match(/([CR][0-9]*|[AM])\s+/);
78+
})
79+
.map(function(line) {
80+
return line.split(/\s+/, 2)[1];
81+
});
82+
});
83+
}
2084

21-
var diff = child_process.execSync(`git diff --unified=0 ${commit_range} ./src ./e2e`).toString();
2285

23-
if (blockedRegex.test(diff)) {
86+
// Find all files, check for errors, and output every errors found.
87+
findChangedFiles()
88+
.then(function(fileList) {
89+
// Only match .js or .ts, and remove .d.ts files.
90+
return fileList.filter(function(name) {
91+
return name.match(/\.[jt]s$/) && !name.match(/\.d\.ts$/);
92+
});
93+
})
94+
.then(function(fileList) {
95+
// Read every file and return a Promise that will contain an array of
96+
// Object of the form { fileName, content }.
97+
return Promise.all(fileList.map(function(fileName) {
98+
return {
99+
fileName: fileName,
100+
content: fs.readFileSync(fileName, { encoding: 'utf-8' })
101+
};
102+
}));
103+
})
104+
.then(function(diffList) {
105+
// Reduce the diffList to an array of errors. The array will be empty if no errors
106+
// were found.
107+
return diffList.reduce(function(errors, diffEntry) {
108+
let fileName = diffEntry.fileName;
109+
let content = diffEntry.content.split('\n');
110+
let ln = 0;
24111

25-
console.warn('Warning: You are using a statement in your commit, which is not allowed.\n' +
26-
'Blocked Statements are: ' + blocked_statements.join(', ') + '\n' +
27-
'Please remove them, and the CI will continue.');
112+
// Get all the lines that start with `+`.
113+
content.forEach(function(line) {
114+
ln++;
28115

29-
process.exit(1);
116+
let m = line.match(blockedRegex);
117+
if (m) {
118+
// Accumulate all errors at once.
119+
errors.push({
120+
fileName: fileName,
121+
lineNumber: ln,
122+
statement: m[0]
123+
});
124+
}
125+
});
126+
return errors;
127+
}, []);
128+
})
129+
.then(function(errors) {
130+
if (errors.length > 0) {
131+
console.error('Error: You are using a statement in your commit, which is not allowed.');
132+
errors.forEach(function(entry) {
133+
console.error(` ${entry.fileName}@${entry.lineNumber}, Statement: ${entry.statement}.\n`);
134+
});
30135

31-
} else {
32-
console.log('Info: The commits have been analyzed and are valid!');
33-
}
136+
process.exit(1);
137+
}
138+
})
139+
.catch(function(err) {
140+
// An error occured in this script. Output the error and the stack.
141+
console.error('An error occured during execution:');
142+
console.error(err);
143+
console.error(err.stack);
144+
process.exit(2);
145+
});

scripts/ci/sources/mode.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,12 @@ source ./scripts/ci/sources/tunnel.sh
33

44
is_dart() {
55
[[ "$MODE" = dart* ]]
6+
}
7+
8+
is_e2e() {
9+
[[ "$MODE" = e2e ]]
10+
}
11+
12+
is_lint() {
13+
[[ "$MODE" = lint ]]
614
}

0 commit comments

Comments
 (0)