forked from elastic/eui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate-token-changelog.js
174 lines (144 loc) Β· 5.29 KB
/
update-token-changelog.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
const fs = require('fs');
const path = require('path');
const git = require('nodegit');
const semver = require('semver');
const repoDir = path.resolve(__dirname, '..');
const packagePath = path.resolve(repoDir, 'package.json');
const tokensPath = path.resolve(repoDir, 'i18ntokens.json');
const tokensChangelogPath = path.resolve(repoDir, 'i18ntokens_changelog.json');
const validVersionTypes = new Set(['patch', 'minor', 'major']);
const [, , versionIncrementType] = process.argv;
if (validVersionTypes.has(versionIncrementType) === false) {
console.error(`Invalid version increment "${versionIncrementType}" passed`);
process.exit(1);
}
const { version: oldPackageVersion } = require(packagePath);
const newPackageVersion = semver.inc(oldPackageVersion, versionIncrementType);
async function getFileContentsFromCommit(commit, filePath) {
// https://github.com/nodegit/nodegit/blob/master/examples/read-file.js
const entry = await commit.getEntry(filePath);
const entryBlob = await entry.getBlob();
return entryBlob.content().toString();
}
function getTokenMap(tokenInstances) {
// tokenInstances is the total set of tokens across all files
// reduce those down to a mapping of token -> defString
const tokenMap = new Map();
for (let i = 0; i < tokenInstances.length; i++) {
const { token, defString } = tokenInstances[i];
// we're assurred that overriding any `token` already encountered
// has an identical `defString` as the token generation script otherwise fails
tokenMap.set(token, defString);
}
return tokenMap;
}
function getTokenChanges(oldTokenInstances, newTokenInstances) {
// we're interested in added, modified, or deleted tokens
// addition or removal of a token in a single file is uninteresting unless that instance represents the whole usage of the token
const oldTokens = getTokenMap(oldTokenInstances);
const newTokens = getTokenMap(newTokenInstances);
const changes = [];
// check for token removals or modifications
oldTokens.forEach((value, key) => {
if (newTokens.has(key)) {
// check if definition has changed
const newValue = newTokens.get(key);
if (newValue !== value) {
// token has changed
changes.push({
token: key,
changeType: 'modified',
value: newValue,
});
}
} else {
// token has been removed
changes.push({
token: key,
changeType: 'deleted'
});
}
});
// check for new tokens
newTokens.forEach((value, key) => {
if (oldTokens.has(key) === false) {
// token is new
changes.push({
token: key,
changeType: 'added',
value,
});
}
});
return changes;
}
async function getDirtyFiles(repo) {
const diff = await git.Diff.indexToWorkdir(repo, null, { FLAGS: git.Diff.OPTION.INCLUDE_UNTRACKED });
const patches = await diff.patches();
return new Set(patches.map(patch => patch.oldFile().path()));
}
async function commitTokenChanges(repo) {
// add i18ntokens.json and i18ntokens_changelog.json if modified, and commit
// https://github.com/nodegit/nodegit/blob/master/examples/add-and-commit.js
const dirtyFiles = await getDirtyFiles(repo);
let createCommit = false;
const index = await repo.refreshIndex();
if (dirtyFiles.has('i18ntokens.json')) {
createCommit = true;
await index.addByPath('i18ntokens.json');
}
if (dirtyFiles.has('i18ntokens_changelog.json')) {
createCommit = true;
await index.addByPath('i18ntokens_changelog.json');
}
if (createCommit) {
await index.write();
const oid = await index.writeTree();
const head = await git.Reference.nameToId(repo, 'HEAD');
const parent = await repo.getCommit(head);
const userSignature = await repo.defaultSignature();
return repo.createCommit('HEAD', userSignature, userSignature, 'update i18ntokens', oid, [parent]);
}
}
async function getCommitForTagName(repo, tagname) {
const tag = await repo.getTagByName(tagname);
return git.Commit.lookup(repo, tag.targetId());
}
async function getPreviousI18nTokens(previousVersionCommit) {
try {
return JSON.parse(
await getFileContentsFromCommit(previousVersionCommit, 'i18ntokens.json')
);
} catch (err) {
// If failed, try with the previous path where it used to exist
return JSON.parse(
await getFileContentsFromCommit(
previousVersionCommit,
'src-docs/src/i18ntokens.json'
)
);
}
}
async function main() {
const repo = await git.Repository.open(repoDir);
const previousVersionCommit = await getCommitForTagName(repo, `v${oldPackageVersion}`);
// check for i18n token differences between the current file & the most recent EUI version
const originalTokens = await getPreviousI18nTokens(previousVersionCommit);
const newTokens = require(tokensPath);
const changes = getTokenChanges(originalTokens, newTokens);
// it's possible that no meaningful changes occurred
if (changes.length > 0) {
const changeLog = require(tokensChangelogPath);
changeLog.unshift({
version: newPackageVersion,
changes,
});
fs.writeFileSync(tokensChangelogPath, JSON.stringify(changeLog, null, 2));
}
// commit pending changes to i18ntokens.json or i18ntokens_changelog.json
await commitTokenChanges(repo);
}
main().catch(e => {
console.error(e);
process.exit(1);
});