@eclipse-glsp/cli 2.1.0-next.e32e40e.153 → 2.2.0-next.161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/bin/glsp +1 -1
- package/lib/app.d.ts.map +1 -1
- package/lib/app.js +5 -1
- package/lib/app.js.map +1 -1
- package/lib/commands/check-header.d.ts +3 -6
- package/lib/commands/check-header.d.ts.map +1 -1
- package/lib/commands/check-header.js +60 -110
- package/lib/commands/check-header.js.map +1 -1
- package/lib/commands/coverage-report.d.ts +1 -1
- package/lib/commands/coverage-report.js +12 -9
- package/lib/commands/coverage-report.js.map +1 -1
- package/lib/commands/generate-index.d.ts +46 -0
- package/lib/commands/generate-index.d.ts.map +1 -0
- package/lib/commands/generate-index.js +172 -0
- package/lib/commands/generate-index.js.map +1 -0
- package/lib/commands/release/common.d.ts +1 -1
- package/lib/commands/release/common.js +24 -24
- package/lib/commands/release/common.js.map +1 -1
- package/lib/commands/release/release-client.js +7 -27
- package/lib/commands/release/release-client.js.map +1 -1
- package/lib/commands/release/release-eclipse-integration.d.ts +2 -2
- package/lib/commands/release/release-eclipse-integration.d.ts.map +1 -1
- package/lib/commands/release/release-eclipse-integration.js +20 -40
- package/lib/commands/release/release-eclipse-integration.js.map +1 -1
- package/lib/commands/release/release-java-server.d.ts.map +1 -1
- package/lib/commands/release/release-java-server.js +9 -29
- package/lib/commands/release/release-java-server.js.map +1 -1
- package/lib/commands/release/release-server-node.d.ts +2 -2
- package/lib/commands/release/release-server-node.d.ts.map +1 -1
- package/lib/commands/release/release-server-node.js +13 -33
- package/lib/commands/release/release-server-node.js.map +1 -1
- package/lib/commands/release/release-theia-integration.d.ts +2 -2
- package/lib/commands/release/release-theia-integration.d.ts.map +1 -1
- package/lib/commands/release/release-theia-integration.js +13 -33
- package/lib/commands/release/release-theia-integration.js.map +1 -1
- package/lib/commands/release/release-vscode-integration.d.ts +2 -2
- package/lib/commands/release/release-vscode-integration.d.ts.map +1 -1
- package/lib/commands/release/release-vscode-integration.js +13 -33
- package/lib/commands/release/release-vscode-integration.js.map +1 -1
- package/lib/commands/release/release.d.ts +1 -1
- package/lib/commands/release/release.d.ts.map +1 -1
- package/lib/commands/release/release.js +20 -17
- package/lib/commands/release/release.js.map +1 -1
- package/lib/commands/update-next.d.ts +20 -0
- package/lib/commands/update-next.d.ts.map +1 -0
- package/lib/commands/update-next.js +146 -0
- package/lib/commands/update-next.js.map +1 -0
- package/lib/util/command-util.d.ts +2 -2
- package/lib/util/command-util.d.ts.map +1 -1
- package/lib/util/command-util.js +6 -26
- package/lib/util/command-util.js.map +1 -1
- package/lib/util/git-util.d.ts +1 -21
- package/lib/util/git-util.d.ts.map +1 -1
- package/lib/util/git-util.js +16 -90
- package/lib/util/git-util.js.map +1 -1
- package/lib/util/logger.d.ts +1 -1
- package/lib/util/logger.js +4 -4
- package/lib/util/logger.js.map +1 -1
- package/lib/util/validation-util.d.ts +0 -1
- package/lib/util/validation-util.d.ts.map +1 -1
- package/lib/util/validation-util.js +2 -3
- package/lib/util/validation-util.js.map +1 -1
- package/package.json +5 -4
- package/src/app.ts +5 -1
- package/src/commands/check-header.ts +60 -135
- package/src/commands/coverage-report.ts +2 -2
- package/src/commands/generate-index.ts +169 -0
- package/src/commands/release/common.ts +2 -2
- package/src/commands/release/release-client.ts +2 -2
- package/src/commands/release/release-eclipse-integration.ts +5 -5
- package/src/commands/release/release-java-server.ts +3 -3
- package/src/commands/release/release-server-node.ts +3 -3
- package/src/commands/release/release-theia-integration.ts +3 -3
- package/src/commands/release/release-vscode-integration.ts +5 -4
- package/src/commands/release/release.ts +4 -4
- package/src/commands/update-next.ts +129 -0
- package/src/util/command-util.ts +2 -2
- package/src/util/git-util.ts +2 -56
- package/src/util/logger.ts +1 -1
- package/src/util/validation-util.ts +1 -2
package/src/app.ts
CHANGED
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
********************************************************************************/
|
|
17
17
|
import { CheckHeaderCommand } from './commands/check-header';
|
|
18
18
|
import { CoverageReportCommand } from './commands/coverage-report';
|
|
19
|
+
import { GenerateIndex } from './commands/generate-index';
|
|
19
20
|
import { ReleaseCommand } from './commands/release/release';
|
|
21
|
+
import { UpdateNextCommand } from './commands/update-next';
|
|
20
22
|
import { baseCommand } from './util/command-util';
|
|
21
23
|
|
|
22
24
|
export const COMMAND_VERSION = '1.1.0-next';
|
|
@@ -26,6 +28,8 @@ const app = baseCommand() //
|
|
|
26
28
|
.name('glsp')
|
|
27
29
|
.addCommand(CoverageReportCommand)
|
|
28
30
|
.addCommand(ReleaseCommand)
|
|
29
|
-
.addCommand(CheckHeaderCommand)
|
|
31
|
+
.addCommand(CheckHeaderCommand)
|
|
32
|
+
.addCommand(UpdateNextCommand)
|
|
33
|
+
.addCommand(GenerateIndex);
|
|
30
34
|
|
|
31
35
|
app.parse(process.argv);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2024 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -19,20 +19,14 @@ import * as fs from 'fs';
|
|
|
19
19
|
import { glob } from 'glob';
|
|
20
20
|
import * as minimatch from 'minimatch';
|
|
21
21
|
import * as readline from 'readline-sync';
|
|
22
|
-
import
|
|
22
|
+
import sh from 'shelljs';
|
|
23
23
|
import { baseCommand, configureShell, getShellConfig } from '../util/command-util';
|
|
24
|
-
import {
|
|
25
|
-
getChangesOfLastCommit,
|
|
26
|
-
getFirstCommit,
|
|
27
|
-
getFirstModificationDate,
|
|
28
|
-
getInitialCommit,
|
|
29
|
-
getLastModificationDate,
|
|
30
|
-
getUncommittedChanges
|
|
31
|
-
} from '../util/git-util';
|
|
24
|
+
import { getChangesOfLastCommit, getLastModificationDate, getUncommittedChanges } from '../util/git-util';
|
|
32
25
|
|
|
26
|
+
import * as path from 'path';
|
|
33
27
|
import { LOGGER } from '../util/logger';
|
|
34
28
|
import { validateGitDirectory } from '../util/validation-util';
|
|
35
|
-
|
|
29
|
+
|
|
36
30
|
export interface HeaderCheckOptions {
|
|
37
31
|
type: CheckType;
|
|
38
32
|
exclude: string[];
|
|
@@ -40,24 +34,19 @@ export interface HeaderCheckOptions {
|
|
|
40
34
|
json: boolean;
|
|
41
35
|
excludeDefaults: boolean;
|
|
42
36
|
autoFix: boolean;
|
|
43
|
-
severity: Severity;
|
|
44
37
|
}
|
|
45
38
|
|
|
46
39
|
const checkTypes = ['full', 'changes', 'lastCommit'] as const;
|
|
47
|
-
type CheckType = typeof checkTypes[number];
|
|
48
|
-
|
|
49
|
-
const severityTypes = ['error', 'warn', 'ok'] as const;
|
|
50
|
-
|
|
51
|
-
type Severity = typeof severityTypes[number];
|
|
40
|
+
type CheckType = (typeof checkTypes)[number];
|
|
52
41
|
|
|
53
42
|
const DEFAULT_EXCLUDES = ['**/@(node_modules|lib|dist|bundle)/**'];
|
|
54
|
-
const YEAR_RANGE_REGEX = /\d{4}
|
|
55
|
-
const HEADER_PATTERN = 'Copyright \\([cC]\\) \\d{4}
|
|
43
|
+
const YEAR_RANGE_REGEX = /\d{4}/g;
|
|
44
|
+
const HEADER_PATTERN = 'Copyright \\([cC]\\) \\d{4}';
|
|
56
45
|
const AUTO_FIX_MESSAGE = 'Fix copyright header violations';
|
|
57
46
|
|
|
58
47
|
export const CheckHeaderCommand = baseCommand() //
|
|
59
48
|
.name('checkHeaders')
|
|
60
|
-
.description('Validates the copyright year range of license header files')
|
|
49
|
+
.description('Validates the copyright year range (end year) of license header files')
|
|
61
50
|
.argument('<rootDir>', 'The starting directory for the check', validateGitDirectory)
|
|
62
51
|
.addOption(
|
|
63
52
|
new Option(
|
|
@@ -80,11 +69,6 @@ export const CheckHeaderCommand = baseCommand() //
|
|
|
80
69
|
'Disables the default excludes patterns. Only explicitly passed exclude patterns (-e, --exclude) are considered'
|
|
81
70
|
)
|
|
82
71
|
.option('-j, --json', 'Also persist validation results as json file', false)
|
|
83
|
-
.addOption(
|
|
84
|
-
new Option('-s, --severity <severity>', 'The severity of validation results that should be printed.')
|
|
85
|
-
.choices(severityTypes)
|
|
86
|
-
.default('error', '"error" (only)')
|
|
87
|
-
)
|
|
88
72
|
.option('-a, --autoFix', 'Auto apply & commit fixes without prompting the user', false)
|
|
89
73
|
.action(checkHeaders);
|
|
90
74
|
|
|
@@ -127,17 +111,11 @@ function getFiles(rootDir: string, options: HeaderCheckOptions): string[] {
|
|
|
127
111
|
}
|
|
128
112
|
|
|
129
113
|
function validate(rootDir: string, files: string[], options: HeaderCheckOptions): ValidationResult[] {
|
|
130
|
-
// Derives all files with valid headers
|
|
114
|
+
// Derives all files with valid headers and all files with no or invalid headers
|
|
131
115
|
const filesWithHeader = sh.grep('-l', HEADER_PATTERN, files).stdout.trim().split('\n');
|
|
132
|
-
const copyrightYears = sh
|
|
133
|
-
.grep(HEADER_PATTERN, files)
|
|
134
|
-
.stdout.trim()
|
|
135
|
-
.split('\n')
|
|
136
|
-
.map(line => line.match(YEAR_RANGE_REGEX)!.map(string => Number.parseInt(string, 10)));
|
|
137
116
|
const noHeaders = files.filter(file => !filesWithHeader.includes(file));
|
|
138
117
|
|
|
139
118
|
const results: ValidationResult[] = [];
|
|
140
|
-
|
|
141
119
|
const allFilesLength = files.length;
|
|
142
120
|
|
|
143
121
|
// Create validation results for all files with no or invalid headers
|
|
@@ -147,7 +125,7 @@ function validate(rootDir: string, files: string[], options: HeaderCheckOptions)
|
|
|
147
125
|
}
|
|
148
126
|
noHeaders.forEach((file, i) => {
|
|
149
127
|
printFileProgress(i + 1, allFilesLength, `Validating ${file}`);
|
|
150
|
-
results.push({ file: path.resolve(rootDir, file), violation: 'noOrMissingHeader'
|
|
128
|
+
results.push({ file: path.resolve(rootDir, file), violation: 'noOrMissingHeader' });
|
|
151
129
|
});
|
|
152
130
|
|
|
153
131
|
// Performance optimization: avoid retrieving the dates for each individual file by precalculating the endYear if possible.
|
|
@@ -161,23 +139,24 @@ function validate(rootDir: string, files: string[], options: HeaderCheckOptions)
|
|
|
161
139
|
// Create validation results for all files with valid headers
|
|
162
140
|
filesWithHeader.forEach((file, i) => {
|
|
163
141
|
printFileProgress(i + 1 + noHeadersLength, allFilesLength, `Validating ${file}`);
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
expectedEndYear: defaultEndYear ?? getLastModificationDate(file, rootDir, AUTO_FIX_MESSAGE)!.getFullYear(),
|
|
170
|
-
file,
|
|
171
|
-
severity: 'ok',
|
|
172
|
-
violation: 'none'
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
if (result.expectedStartYear === result.expectedEndYear) {
|
|
176
|
-
validateSingleYear(result);
|
|
142
|
+
const copyrightLine = sh.head({ '-n': 2 }, file).stdout.trim().split('\n')[1];
|
|
143
|
+
const copyRightYears = copyrightLine.match(YEAR_RANGE_REGEX)!;
|
|
144
|
+
if (!copyRightYears) {
|
|
145
|
+
const result: ValidationResult = { file, violation: 'noYear', line: copyrightLine };
|
|
146
|
+
results.push(result);
|
|
177
147
|
} else {
|
|
178
|
-
|
|
148
|
+
const currentStartYear = Number.parseInt(copyRightYears[0], 10);
|
|
149
|
+
const currentEndYear = copyRightYears[1] ? Number.parseInt(copyRightYears[1], 10) : undefined;
|
|
150
|
+
const result: DateValidationResult = {
|
|
151
|
+
currentStartYear,
|
|
152
|
+
currentEndYear,
|
|
153
|
+
expectedEndYear: defaultEndYear ?? getLastModificationDate(file, rootDir, AUTO_FIX_MESSAGE)!.getFullYear(),
|
|
154
|
+
file,
|
|
155
|
+
violation: 'none'
|
|
156
|
+
};
|
|
157
|
+
validateEndYear(result);
|
|
158
|
+
results.push(result);
|
|
179
159
|
}
|
|
180
|
-
results.push(result);
|
|
181
160
|
});
|
|
182
161
|
|
|
183
162
|
results.sort((a, b) => a.file.localeCompare(b.file));
|
|
@@ -186,57 +165,16 @@ function validate(rootDir: string, files: string[], options: HeaderCheckOptions)
|
|
|
186
165
|
return results;
|
|
187
166
|
}
|
|
188
167
|
|
|
189
|
-
function
|
|
190
|
-
const { currentStartYear,
|
|
191
|
-
result.violation = '
|
|
192
|
-
result.severity = 'error';
|
|
193
|
-
|
|
194
|
-
if (!currentEndYear) {
|
|
195
|
-
if (currentStartYear === expectedStartYear) {
|
|
196
|
-
result.violation = 'none';
|
|
197
|
-
result.severity = 'ok';
|
|
198
|
-
}
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Cornercase: For files of the initial contribution the copyright header predates the first git modification date.
|
|
203
|
-
// => declare as warning if not part of the initial contribution.
|
|
204
|
-
if (expectedStartYear === currentEndYear && currentStartYear < expectedStartYear) {
|
|
205
|
-
if (getFirstCommit(result.file) === getInitialCommit()) {
|
|
206
|
-
result.violation = 'none';
|
|
207
|
-
result.severity = 'ok';
|
|
208
|
-
} else {
|
|
209
|
-
result.severity = 'warn';
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
168
|
+
function validateEndYear(result: DateValidationResult): void {
|
|
169
|
+
const { currentStartYear, expectedEndYear, currentEndYear } = result;
|
|
170
|
+
result.violation = 'invalidEndYear';
|
|
213
171
|
|
|
214
|
-
|
|
215
|
-
const { currentStartYear, expectedStartYear, expectedEndYear, currentEndYear } = result;
|
|
172
|
+
const valid = currentEndYear ? currentEndYear === expectedEndYear : currentStartYear === expectedEndYear;
|
|
216
173
|
|
|
217
|
-
|
|
218
|
-
result.severity = 'error';
|
|
219
|
-
if (!currentEndYear) {
|
|
220
|
-
result.severity = 'error';
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (currentStartYear === expectedStartYear && currentEndYear === expectedEndYear) {
|
|
174
|
+
if (valid) {
|
|
225
175
|
result.violation = 'none';
|
|
226
|
-
result.severity = 'ok';
|
|
227
176
|
return;
|
|
228
177
|
}
|
|
229
|
-
|
|
230
|
-
// Cornercase: For files of the initial contribution the copyright header predates the first git modification date.
|
|
231
|
-
// => declare as warning if not part of the initial contribution.
|
|
232
|
-
if (currentEndYear === expectedEndYear && currentStartYear < expectedEndYear) {
|
|
233
|
-
if (getFirstCommit(result.file) === getInitialCommit()) {
|
|
234
|
-
result.violation = 'none';
|
|
235
|
-
result.severity = 'ok';
|
|
236
|
-
} else {
|
|
237
|
-
result.severity = 'warn';
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
178
|
}
|
|
241
179
|
|
|
242
180
|
function printFileProgress(currentFileCount: number, maxFileCount: number, message: string, clear = true): void {
|
|
@@ -253,14 +191,9 @@ function printFileProgress(currentFileCount: number, maxFileCount: number, messa
|
|
|
253
191
|
export function handleValidationResults(rootDir: string, results: ValidationResult[], options: HeaderCheckOptions): void {
|
|
254
192
|
LOGGER.newLine();
|
|
255
193
|
LOGGER.info(`Header validation for ${results.length} files completed`);
|
|
256
|
-
const violations = results.filter(result => result.
|
|
194
|
+
const violations = results.filter(result => result.violation !== 'none');
|
|
257
195
|
// Adjust results to print based on configured severity level
|
|
258
|
-
|
|
259
|
-
if (options.severity === 'error') {
|
|
260
|
-
toPrint = violations;
|
|
261
|
-
} else if (options.severity === 'warn') {
|
|
262
|
-
toPrint = results.filter(result => result.severity !== 'ok');
|
|
263
|
-
}
|
|
196
|
+
const toPrint = violations;
|
|
264
197
|
|
|
265
198
|
LOGGER.info(`Found ${toPrint.length} copyright header violations:`);
|
|
266
199
|
LOGGER.newLine();
|
|
@@ -273,10 +206,11 @@ export function handleValidationResults(rootDir: string, results: ValidationResu
|
|
|
273
206
|
fs.writeFileSync(path.join(rootDir, 'headerCheck.json'), JSON.stringify(results, undefined, 2));
|
|
274
207
|
}
|
|
275
208
|
|
|
276
|
-
if (
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
209
|
+
if (
|
|
210
|
+
violations.length > 0 &&
|
|
211
|
+
(options.autoFix || readline.keyInYN('Do you want to automatically fix copyright year range violations?'))
|
|
212
|
+
) {
|
|
213
|
+
const toFix = violations.filter(violation => isDateValidationResult(violation)) as DateValidationResult[];
|
|
280
214
|
fixViolations(rootDir, toFix, options);
|
|
281
215
|
}
|
|
282
216
|
|
|
@@ -284,43 +218,35 @@ export function handleValidationResults(rootDir: string, results: ValidationResu
|
|
|
284
218
|
}
|
|
285
219
|
|
|
286
220
|
function toPrintMessage(result: ValidationResult): string {
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const expected =
|
|
298
|
-
result.expectedStartYear !== result.expectedEndYear
|
|
299
|
-
? `${result.expectedStartYear}-${result.expectedEndYear}`
|
|
300
|
-
: result.expectedStartYear.toString();
|
|
301
|
-
const actual = result.currentEndYear ? `${result.currentStartYear}-${result.currentEndYear}` : result.currentStartYear.toString();
|
|
302
|
-
const message = result.violation === 'incorrectCopyrightPeriod' ? 'Invalid copyright period' : 'Invalid copyright year';
|
|
303
|
-
return `${colors[result.severity]} ${message}! Expected '${expected}' but is '${actual}'`;
|
|
221
|
+
const error = '\x1b[31m';
|
|
222
|
+
const info = '\x1b[32m';
|
|
223
|
+
|
|
224
|
+
if (isDateValidationResult(result) && result.violation === 'invalidEndYear') {
|
|
225
|
+
const expected = result.expectedEndYear.toString();
|
|
226
|
+
const actual = result.currentEndYear
|
|
227
|
+
? `${result.currentEndYear} (${result.currentStartYear}-${result.currentEndYear})`
|
|
228
|
+
: result.currentStartYear.toString();
|
|
229
|
+
const message = 'Invalid copyright end year';
|
|
230
|
+
return `${error} ${message}! Expected end year '${expected}' but is '${actual}'`;
|
|
304
231
|
} else if (result.violation === 'noOrMissingHeader') {
|
|
305
|
-
return `${
|
|
232
|
+
return `${error} No or invalid copyright header!`;
|
|
233
|
+
} else if (result.violation === 'noYear') {
|
|
234
|
+
return `${error} No year found!${result.line ? ' (line: ' + result.line + ')' : ''}`;
|
|
306
235
|
}
|
|
307
236
|
|
|
308
|
-
return `${
|
|
237
|
+
return `${info} OK`;
|
|
309
238
|
}
|
|
310
239
|
|
|
311
240
|
function fixViolations(rootDir: string, violations: DateValidationResult[], options: HeaderCheckOptions): void {
|
|
312
241
|
LOGGER.newLine();
|
|
313
242
|
violations.forEach((violation, i) => {
|
|
314
243
|
printFileProgress(i + 1, violations.length, `Fix ${violation.file}`, false);
|
|
315
|
-
const fixedStartYear =
|
|
316
|
-
violation.currentStartYear < violation.expectedStartYear ? violation.currentStartYear : violation.expectedStartYear;
|
|
317
244
|
|
|
318
245
|
const currentRange = `${violation.currentStartYear}${violation.currentEndYear ? '-' + violation.currentEndYear : ''}`;
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
246
|
+
const fixedRange =
|
|
247
|
+
violation.currentEndYear || violation.currentStartYear < violation.expectedEndYear
|
|
248
|
+
? `${violation.currentStartYear}-${violation.expectedEndYear}`
|
|
249
|
+
: `${violation.expectedEndYear}`;
|
|
324
250
|
|
|
325
251
|
sh.sed('-i', RegExp('Copyright \\([cC]\\) ' + currentRange), `Copyright (c) ${fixedRange}`, violation.file);
|
|
326
252
|
});
|
|
@@ -337,19 +263,18 @@ function fixViolations(rootDir: string, violations: DateValidationResult[], opti
|
|
|
337
263
|
// Helper types
|
|
338
264
|
interface ValidationResult {
|
|
339
265
|
file: string;
|
|
340
|
-
severity: Severity;
|
|
341
266
|
violation: Violation;
|
|
267
|
+
line?: string;
|
|
342
268
|
}
|
|
343
269
|
|
|
344
270
|
interface DateValidationResult extends ValidationResult {
|
|
345
271
|
currentStartYear: number;
|
|
346
|
-
expectedStartYear: number;
|
|
347
272
|
currentEndYear?: number;
|
|
348
273
|
expectedEndYear: number;
|
|
349
274
|
}
|
|
350
275
|
|
|
351
276
|
function isDateValidationResult(object: ValidationResult): object is DateValidationResult {
|
|
352
|
-
return 'currentStartYear' in object && '
|
|
277
|
+
return 'currentStartYear' in object && 'expectedEndYear' in object;
|
|
353
278
|
}
|
|
354
279
|
|
|
355
|
-
type Violation = 'none' | 'noOrMissingHeader' | '
|
|
280
|
+
type Violation = 'none' | 'noOrMissingHeader' | 'invalidEndYear' | 'noYear';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022 EclipseSource and others.
|
|
2
|
+
* Copyright (c) 2022-2024 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import * as fs from 'fs';
|
|
18
18
|
import * as path from 'path';
|
|
19
|
-
import
|
|
19
|
+
import sh from 'shelljs';
|
|
20
20
|
import { baseCommand, fatalExec, getShellConfig } from '../util/command-util';
|
|
21
21
|
import { LOGGER } from '../util/logger';
|
|
22
22
|
import { validateDirectory } from '../util/validation-util';
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2023-2024 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { createOption } from 'commander';
|
|
18
|
+
import * as fs from 'fs';
|
|
19
|
+
import * as os from 'os';
|
|
20
|
+
import * as path from 'path';
|
|
21
|
+
import sh from 'shelljs';
|
|
22
|
+
import { baseCommand } from '../util/command-util';
|
|
23
|
+
import { LOGGER, configureLogger } from '../util/logger';
|
|
24
|
+
import { validateDirectory } from '../util/validation-util';
|
|
25
|
+
|
|
26
|
+
export interface GenerateIndexCmdOptions {
|
|
27
|
+
singleIndex: boolean;
|
|
28
|
+
forceOverwrite: boolean;
|
|
29
|
+
match: string[] | boolean;
|
|
30
|
+
ignore: string[] | boolean;
|
|
31
|
+
ignoreFile: string;
|
|
32
|
+
style: 'commonjs' | 'esm';
|
|
33
|
+
verbose: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Partial type of the globby imports since we can not use the esm type directly
|
|
37
|
+
interface GlobbyOptions {
|
|
38
|
+
ignore: string[];
|
|
39
|
+
cwd: string;
|
|
40
|
+
onlyFiles: boolean;
|
|
41
|
+
markDirectories: true;
|
|
42
|
+
ignoreFiles: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const GenerateIndex = baseCommand() //
|
|
46
|
+
.name('generateIndex')
|
|
47
|
+
.description('Generate index files in a given source directory.')
|
|
48
|
+
.argument('<rootDir...>', 'The source directory for index generation.')
|
|
49
|
+
.option('-s, --singleIndex', 'Generate a single index file in the source directory instead of indices in each sub-directory', false)
|
|
50
|
+
.option('-f, --forceOverwrite', 'Overwrite existing index files and remove them if there are no entries', false)
|
|
51
|
+
.option('-m, --match [match patterns...]', 'File patterns to consider during indexing', ['**/*.ts', '**/*.tsx'])
|
|
52
|
+
.option('-i, --ignore [ignore patterns...]', 'File patterns to ignore during indexing', ['**/*.spec.ts', '**/*.spec.tsx', '**/*.d.ts'])
|
|
53
|
+
.addOption(createOption('-s, --style <importStyle>', 'Import Style').choices(['commonjs', 'esm']).default('commonjs'))
|
|
54
|
+
.option('--ignoreFile <ignoreFile>', 'The file that is used to specify patterns that should be ignored during indexing', '.indexignore')
|
|
55
|
+
.option('-v, --verbose', 'Generate verbose output during generation', false)
|
|
56
|
+
.action(generateIndices);
|
|
57
|
+
|
|
58
|
+
export async function generateIndices(rootDirs: string[], options: GenerateIndexCmdOptions): Promise<void> {
|
|
59
|
+
const dirs = rootDirs.map(rootDir => validateDirectory(path.resolve(rootDir)));
|
|
60
|
+
const globby = await import('globby');
|
|
61
|
+
const ignoreFilter: (pattern: string[], options: GlobbyOptions) => string[] = (pattern, globbyOptions) =>
|
|
62
|
+
globby.globbySync(pattern, globbyOptions);
|
|
63
|
+
dirs.forEach(dir => generateIndex(dir, ignoreFilter, options));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function generateIndex(
|
|
67
|
+
rootDir: string,
|
|
68
|
+
ignoreFilter: (pattern: string[], options: GlobbyOptions) => string[],
|
|
69
|
+
options: GenerateIndexCmdOptions
|
|
70
|
+
): Promise<void> {
|
|
71
|
+
configureLogger(options.verbose);
|
|
72
|
+
LOGGER.debug('Run generateIndex for', rootDir, 'with the following options:', options);
|
|
73
|
+
sh.cd(rootDir);
|
|
74
|
+
const cwd = process.cwd();
|
|
75
|
+
|
|
76
|
+
// we want to match all given patterns and subdirectories and ignore all given patterns and (generated) index files
|
|
77
|
+
const pattern = typeof options.match === 'boolean' ? ['**/'] : [...options.match, '**/'];
|
|
78
|
+
const ignore = typeof options.ignore === 'boolean' ? ['**/index.ts'] : [...options.ignore, '**/index.ts'];
|
|
79
|
+
const globbyOptions: GlobbyOptions = {
|
|
80
|
+
ignore,
|
|
81
|
+
cwd,
|
|
82
|
+
onlyFiles: options.singleIndex,
|
|
83
|
+
markDirectories: true, // directories have '/' at the end
|
|
84
|
+
ignoreFiles: '**/' + options.ignoreFile // users can add this file in their directories to ignore files for indexing
|
|
85
|
+
};
|
|
86
|
+
LOGGER.debug('Search for children using the following globby options', globbyOptions);
|
|
87
|
+
const files = ignoreFilter(pattern, globbyOptions);
|
|
88
|
+
LOGGER.debug('All children considered in the input directory', files);
|
|
89
|
+
|
|
90
|
+
const relativeRootDirectory = '';
|
|
91
|
+
if (options.singleIndex) {
|
|
92
|
+
writeIndex(relativeRootDirectory, files.filter(isFile), options);
|
|
93
|
+
} else {
|
|
94
|
+
// sort by length so we deal with sub-directories before we deal with their parents to determine whether they are empty
|
|
95
|
+
const directories = [...files.filter(isDirectory), relativeRootDirectory].sort((left, right) => right.length - left.length);
|
|
96
|
+
const directoryChildren = new Map<string, string[]>();
|
|
97
|
+
for (const directory of directories) {
|
|
98
|
+
const children = files.filter(file => isDirectChild(directory, file, () => !!directoryChildren.get(file)?.length));
|
|
99
|
+
directoryChildren.set(directory, children);
|
|
100
|
+
writeIndex(directory, children, options);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function isDirectChild(parent: string, child: string, childHasChildren: () => boolean): boolean {
|
|
106
|
+
return isChildFile(parent, child) || (isChildDirectory(parent, child) && childHasChildren());
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function isDirectory(file: string): boolean {
|
|
110
|
+
return file.endsWith('/');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function isFile(file: string): boolean {
|
|
114
|
+
return !isDirectory(file);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function getLevel(file: string): number {
|
|
118
|
+
return file.split('/').length;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function isChild(parent: string, child: string): boolean {
|
|
122
|
+
return child.startsWith(parent);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function isChildDirectory(parent: string, child: string): boolean {
|
|
126
|
+
return isDirectory(child) && isChild(parent, child) && getLevel(child) === getLevel(parent) + 1;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function isChildFile(parent: string, child: string): boolean {
|
|
130
|
+
return isFile(child) && isChild(parent, child) && getLevel(child) === getLevel(parent);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function writeIndex(directory: string, exports: string[], options: GenerateIndexCmdOptions): void {
|
|
134
|
+
const indexFile = path.join(process.cwd(), directory, 'index.ts');
|
|
135
|
+
if (exports.length === 0) {
|
|
136
|
+
if (options.forceOverwrite && fs.existsSync(indexFile)) {
|
|
137
|
+
LOGGER.info('Remove index file', indexFile);
|
|
138
|
+
fs.rmSync(indexFile);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const exists = fs.existsSync(indexFile);
|
|
143
|
+
if (exists && !options.forceOverwrite) {
|
|
144
|
+
LOGGER.info("Do not overwrite existing index file. Use '-f' to force an overwrite.", indexFile);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const headerContent = exists ? extractReusableContent(fs.readFileSync(indexFile, { encoding: 'utf-8' })) : '';
|
|
149
|
+
const exportContent = exports.map(exported => createExport(directory, exported, options)).sort();
|
|
150
|
+
const content = headerContent + exportContent.join(os.EOL) + os.EOL; // end with an empty line
|
|
151
|
+
LOGGER.info((exists ? 'Overwrite' : 'Write') + ' index file', indexFile);
|
|
152
|
+
LOGGER.debug(' ' + content.split(os.EOL).join(os.EOL + ' '));
|
|
153
|
+
fs.writeFileSync(indexFile, content, { flag: 'w' });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function createExport(directory: string, relativePath: string, options: GenerateIndexCmdOptions): string {
|
|
157
|
+
// remove directory prefix, file extension and directory ending '/'
|
|
158
|
+
const parentPrefix = directory.length;
|
|
159
|
+
const suffix = isFile(relativePath) ? path.extname(relativePath).length : 1;
|
|
160
|
+
const relativeName = relativePath.substring(parentPrefix, relativePath.length - suffix);
|
|
161
|
+
const exportName = options.style === 'esm' && isFile(relativePath) ? relativeName + '.js' : relativeName;
|
|
162
|
+
const exportLine = `export * from './${exportName}';`;
|
|
163
|
+
return exportLine;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function extractReusableContent(fileContent: string): string {
|
|
167
|
+
// all code before any actual export lines are considered re-usable
|
|
168
|
+
return fileContent.match(/^(.*?)(?=^export)/ms)?.[0] ?? '';
|
|
169
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022 EclipseSource and others.
|
|
2
|
+
* Copyright (c) 2022-2024 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -19,7 +19,7 @@ import fetch from 'node-fetch';
|
|
|
19
19
|
import { resolve } from 'path';
|
|
20
20
|
import * as readline from 'readline-sync';
|
|
21
21
|
import * as semver from 'semver';
|
|
22
|
-
import
|
|
22
|
+
import sh from 'shelljs';
|
|
23
23
|
import { fatalExec, getShellConfig } from '../../util/command-util';
|
|
24
24
|
import { getLatestGithubRelease, getLatestTag, hasGitChanges, isGitRepository } from '../../util/git-util';
|
|
25
25
|
import { LOGGER } from '../../util/logger';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022 EclipseSource and others.
|
|
2
|
+
* Copyright (c) 2022-2024 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import
|
|
16
|
+
import sh from 'shelljs';
|
|
17
17
|
import { getShellConfig } from '../../util/command-util';
|
|
18
18
|
import { LOGGER } from '../../util/logger';
|
|
19
19
|
import { checkoutAndCd, commitAndTag, lernaSetVersion, publish, ReleaseOptions, updateLernaForDryRun, yarnInstall } from './common';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022 EclipseSource and others.
|
|
2
|
+
* Copyright (c) 2022-2024 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -14,22 +14,22 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
import sh from 'shelljs';
|
|
18
18
|
import { fatalExec, getShellConfig } from '../../util/command-util';
|
|
19
19
|
import { LOGGER } from '../../util/logger';
|
|
20
20
|
import {
|
|
21
|
+
ReleaseOptions,
|
|
22
|
+
ReleaseType,
|
|
21
23
|
asMvnVersion,
|
|
22
24
|
checkJavaServerVersion,
|
|
23
25
|
checkoutAndCd,
|
|
24
26
|
commitAndTag,
|
|
25
27
|
lernaSetVersion,
|
|
26
28
|
publish,
|
|
27
|
-
ReleaseOptions,
|
|
28
|
-
ReleaseType,
|
|
29
29
|
updateLernaForDryRun,
|
|
30
30
|
updateVersion,
|
|
31
31
|
yarnInstall
|
|
32
|
-
} from './common';
|
|
32
|
+
} from './common.js';
|
|
33
33
|
|
|
34
34
|
let REPO_ROOT: string;
|
|
35
35
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022 EclipseSource and others.
|
|
2
|
+
* Copyright (c) 2022-2024 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import
|
|
16
|
+
import sh from 'shelljs';
|
|
17
17
|
import { fatalExec, getShellConfig } from '../../util/command-util';
|
|
18
18
|
import { LOGGER } from '../../util/logger';
|
|
19
|
-
import { asMvnVersion, checkoutAndCd, commitAndTag, publish
|
|
19
|
+
import { ReleaseOptions, asMvnVersion, checkoutAndCd, commitAndTag, publish } from './common';
|
|
20
20
|
|
|
21
21
|
let REPO_ROOT: string;
|
|
22
22
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022 EclipseSource and others.
|
|
2
|
+
* Copyright (c) 2022-2024 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
import sh from 'shelljs';
|
|
18
18
|
import { LOGGER } from '../../util/logger';
|
|
19
19
|
import {
|
|
20
20
|
checkoutAndCd,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
updateLernaForDryRun,
|
|
26
26
|
updateVersion,
|
|
27
27
|
yarnInstall
|
|
28
|
-
} from './common';
|
|
28
|
+
} from './common.js';
|
|
29
29
|
|
|
30
30
|
let REPO_ROOT: string;
|
|
31
31
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022 EclipseSource and others.
|
|
2
|
+
* Copyright (c) 2022-2024 EclipseSource and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
-
import
|
|
17
|
+
import sh from 'shelljs';
|
|
18
18
|
import { LOGGER } from '../../util/logger';
|
|
19
19
|
import {
|
|
20
20
|
checkoutAndCd,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
updateLernaForDryRun,
|
|
26
26
|
updateVersion,
|
|
27
27
|
yarnInstall
|
|
28
|
-
} from './common';
|
|
28
|
+
} from './common.js';
|
|
29
29
|
|
|
30
30
|
let REPO_ROOT: string;
|
|
31
31
|
|