Skip to content

Commit 5689faa

Browse files
committed
build: move breaking changes script away from gulp
The script that logs out the breaking changes that need to be cleaned up was barely using Gulp anyway. These changes make it so it doesn't depend on Gulp and the `package-tools`.
1 parent 31d8819 commit 5689faa

File tree

5 files changed

+112
-111
lines changed

5 files changed

+112
-111
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"e2e": "bazel test //src/... --test_tag_filters=e2e",
2525
"deploy": "echo 'Not supported yet. Tracked with COMP-230'",
2626
"webdriver-manager": "webdriver-manager",
27-
"breaking-changes": "gulp breaking-changes",
27+
"breaking-changes": "ts-node --project scripts scripts/breaking-changes.ts",
2828
"gulp": "gulp",
2929
"stage-release": "ts-node --project tools/release/ tools/release/stage-release.ts",
3030
"publish-release": "ts-node --project tools/release/ tools/release/publish-release.ts",

scripts/breaking-changes.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import {join, relative} from 'path';
2+
import {readFileSync} from 'fs';
3+
import {bold, red, green} from 'chalk';
4+
import * as ts from 'typescript';
5+
import * as tsutils from 'tsutils';
6+
7+
const projectRoot = process.cwd();
8+
9+
// Current version from the package.json. Splits it on the dash to ignore `-beta.x` suffixes.
10+
const packageVersion = require(join(projectRoot, 'package.json')).version.split('-')[0];
11+
12+
// Regex used to extract versions from a string.
13+
const versionRegex = /\d+\.\d+\.\d+/;
14+
15+
// Goes through all of the TypeScript files in the project and puts
16+
// together a summary of all of the pending and expired breaking changes.
17+
const configFile = ts.readJsonConfigFile(join(projectRoot, 'tsconfig.json'), ts.sys.readFile);
18+
const parsedConfig = ts.parseJsonSourceFileConfigFileContent(configFile, ts.sys, projectRoot);
19+
const summary: {[version: string]: string[]} = {};
20+
21+
// Go through all the TS files in the project.
22+
parsedConfig.fileNames.forEach(fileName => {
23+
const sourceFile = ts.createSourceFile(fileName, readFileSync(fileName, 'utf8'),
24+
configFile.languageVersion);
25+
const lineRanges = tsutils.getLineRanges(sourceFile);
26+
27+
// Go through each of the comments of the file.
28+
tsutils.forEachComment(sourceFile, (file, range) => {
29+
const comment = file.substring(range.pos, range.end);
30+
const versionMatch = comment.match(versionRegex);
31+
32+
// Don't do any extra work if the comment doesn't indicate a breaking change.
33+
if (!versionMatch || comment.indexOf('@breaking-change') === -1) {
34+
return;
35+
}
36+
37+
// Use a path relative to the project root, in order to make the summary more tidy.
38+
// Also replace escaped Windows slashes with regular forward slashes.
39+
const pathInProject = relative(projectRoot, sourceFile.fileName).replace(/\\/g, '/');
40+
const [version] = versionMatch;
41+
42+
summary[version] = summary[version] || [];
43+
summary[version].push(` ${pathInProject}: ${formatMessage(comment, range, lineRanges)}`);
44+
});
45+
});
46+
47+
// Go through the summary and log out all of the breaking changes.
48+
Object.keys(summary).forEach(version => {
49+
const isExpired = hasExpired(packageVersion, version);
50+
const status = isExpired ? red('(expired)') : green('(not expired)');
51+
const header = bold(`Breaking changes for ${version} ${status}:`);
52+
const messages = summary[version].join('\n');
53+
54+
console.log(isExpired ? red(header) : header);
55+
console.log(isExpired ? red(messages) : messages, '\n');
56+
});
57+
58+
/**
59+
* Formats a message to be logged out in the breaking changes summary.
60+
* @param comment Contents of the comment that contains the breaking change.
61+
* @param commentRange Object containing info on the position of the comment in the file.
62+
* @param lines Ranges of the lines of code in the file.
63+
*/
64+
function formatMessage(comment: string, commentRange: ts.CommentRange, lines: tsutils.LineRange[]) {
65+
const lineNumber = lines.findIndex(line => line.pos > commentRange.pos);
66+
const messageMatch = comment.match(/@deprecated(.*)|@breaking-change(.*)/);
67+
const message = messageMatch ? messageMatch[0] : '';
68+
const cleanMessage = message
69+
.replace(/[\*\/\r\n]|@[\w-]+/g, '')
70+
.replace(versionRegex, '')
71+
.trim();
72+
73+
return `Line ${lineNumber}, ${cleanMessage || 'No message'}`;
74+
}
75+
76+
77+
/** Converts a version string into an object. */
78+
function parseVersion(version: string) {
79+
const [major = 0, minor = 0, patch = 0] = version.split('.').map(segment => parseInt(segment));
80+
return {major, minor, patch};
81+
}
82+
83+
84+
/**
85+
* Checks whether a version has expired, based on the current version.
86+
* @param currentVersion Current version of the package.
87+
* @param breakingChange Version that is being checked.
88+
*/
89+
function hasExpired(currentVersion: string, breakingChange: string) {
90+
if (currentVersion === breakingChange) {
91+
return true;
92+
}
93+
94+
const current = parseVersion(currentVersion);
95+
const target = parseVersion(breakingChange);
96+
97+
return target.major < current.major ||
98+
(target.major === current.major && target.minor < current.minor) ||
99+
(
100+
target.major === current.major &&
101+
target.minor === current.minor &&
102+
target.patch < current.patch
103+
);
104+
}

scripts/tsconfig.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"compilerOptions": {
3+
"lib": ["es2016"],
4+
"types": ["node"],
5+
"strictNullChecks": true
6+
}
7+
}

tools/gulp/gulpfile.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ createPackageBuildTasks(momentAdapterPackage);
2121
createPackageBuildTasks(youTubePlayerPackage);
2222
createPackageBuildTasks(googleMapsPackage);
2323

24-
import './tasks/breaking-changes';
2524
import './tasks/ci';
2625
import './tasks/clean';
2726
import './tasks/default';

tools/gulp/tasks/breaking-changes.ts

Lines changed: 0 additions & 109 deletions
This file was deleted.

0 commit comments

Comments
 (0)