mirror of
https://github.com/gradle/wrapper-validation-action
synced 2024-11-27 10:42:03 +00:00
Merge branch 'master' into feat/JLL/homoglyph_detector
* master: Add : Build Rework output Let finding wrapper jars be predictable Ignore IDEA files
This commit is contained in:
commit
9f4cacc32b
6 changed files with 173 additions and 48 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -99,3 +99,5 @@ __tests__/runner/*
|
||||||
lib/**/*
|
lib/**/*
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,71 @@
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as validate from '../src/validate'
|
import * as validate from '../src/validate'
|
||||||
|
|
||||||
test('validates wrapper jars', async () => {
|
const baseDir = path.resolve('.')
|
||||||
const invalidWrapperJars = await validate.findInvalidWrapperJars(
|
|
||||||
path.resolve('.'),
|
test('succeeds if all found wrapper jars are valid', async () => {
|
||||||
3,
|
const result = await validate.findInvalidWrapperJars(baseDir, 3, false, [
|
||||||
false,
|
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||||
[]
|
])
|
||||||
|
|
||||||
|
expect(result.isValid()).toBe(true)
|
||||||
|
|
||||||
|
expect(result.toDisplayString()).toBe(
|
||||||
|
'✓ Found known Gradle Wrapper JAR files:\n' +
|
||||||
|
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
||||||
|
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
||||||
|
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
||||||
)
|
)
|
||||||
expect(invalidWrapperJars.length).toBe(2)
|
})
|
||||||
expect(invalidWrapperJars[0]).toEqual(
|
|
||||||
new validate.InvalidWrapperJar(
|
test('fails if invalid wrapper jars are found', async () => {
|
||||||
|
const result = await validate.findInvalidWrapperJars(baseDir, 3, false, [])
|
||||||
|
|
||||||
|
expect(result.isValid()).toBe(false)
|
||||||
|
|
||||||
|
expect(result.valid).toEqual([
|
||||||
|
new validate.WrapperJar(
|
||||||
|
'__tests__/data/valid/gradle-wrapper.jar',
|
||||||
|
'3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce'
|
||||||
|
)
|
||||||
|
])
|
||||||
|
|
||||||
|
expect(result.invalid).toEqual([
|
||||||
|
new validate.WrapperJar(
|
||||||
'__tests__/data/invalid/gradle-wrapper.jar',
|
'__tests__/data/invalid/gradle-wrapper.jar',
|
||||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||||
|
),
|
||||||
|
new validate.WrapperJar(
|
||||||
|
'__tests__/data/invalid/gradlе-wrapper.jar', // homoglyph
|
||||||
|
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
||||||
)
|
)
|
||||||
|
])
|
||||||
|
|
||||||
|
expect(result.toDisplayString()).toBe(
|
||||||
|
'✗ Found unknown Gradle Wrapper JAR files:\n' +
|
||||||
|
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
||||||
|
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
||||||
|
'✓ Found known Gradle Wrapper JAR files:\n' +
|
||||||
|
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('fails if not enough wrapper jars are found', async () => {
|
test('fails if not enough wrapper jars are found', async () => {
|
||||||
await expect(
|
const result = await validate.findInvalidWrapperJars(baseDir, 4, false, [])
|
||||||
validate.findInvalidWrapperJars(path.resolve('.'), 4, false, [])
|
|
||||||
).rejects.toThrowError(
|
expect(result.isValid()).toBe(false)
|
||||||
|
|
||||||
|
expect(result.errors).toEqual([
|
||||||
'Expected to find at least 4 Gradle Wrapper JARs but got only 3'
|
'Expected to find at least 4 Gradle Wrapper JARs but got only 3'
|
||||||
|
])
|
||||||
|
|
||||||
|
expect(result.toDisplayString()).toBe(
|
||||||
|
'✗ Found unknown Gradle Wrapper JAR files:\n' +
|
||||||
|
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
||||||
|
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
||||||
|
'✗ Other validation errors:\n' +
|
||||||
|
' Expected to find at least 4 Gradle Wrapper JARs but got only 3\n' +
|
||||||
|
'✓ Found known Gradle Wrapper JAR files:\n' +
|
||||||
|
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
66
dist/index.js
vendored
66
dist/index.js
vendored
|
@ -340,13 +340,12 @@ const validate = __importStar(__webpack_require__(474));
|
||||||
function run() {
|
function run() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
const minWrapperCount = +core.getInput('min-wrapper-count');
|
const result = yield validate.findInvalidWrapperJars(path.resolve('.'), +core.getInput('min-wrapper-count'), core.getInput('allow-snapshots') === 'true', core.getInput('allow-checksums').split(','));
|
||||||
const allowSnapshots = core.getInput('allow-snapshots') === 'true';
|
if (result.isValid()) {
|
||||||
const allowChecksums = core.getInput('allow-checksums').split(',');
|
core.info(result.toDisplayString());
|
||||||
const invalidWrapperJars = yield validate.findInvalidWrapperJars(path.resolve('.'), minWrapperCount, allowSnapshots, allowChecksums);
|
}
|
||||||
if (invalidWrapperJars.length > 0) {
|
else {
|
||||||
const list = invalidWrapperJars.map(invalid => `${invalid.checksum} ${invalid.path}`);
|
core.setFailed(result.toDisplayString());
|
||||||
core.setFailed(`Found unknown Gradle Wrapper JAR files\n${list.join('\n- ')}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
|
@ -976,32 +975,68 @@ const hash = __importStar(__webpack_require__(652));
|
||||||
function findInvalidWrapperJars(gitRepoRoot, minWrapperCount, allowSnapshots, allowChecksums) {
|
function findInvalidWrapperJars(gitRepoRoot, minWrapperCount, allowSnapshots, allowChecksums) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const wrapperJars = yield find.findWrapperJars(gitRepoRoot);
|
const wrapperJars = yield find.findWrapperJars(gitRepoRoot);
|
||||||
|
const result = new ValidationResult([], []);
|
||||||
if (wrapperJars.length < minWrapperCount) {
|
if (wrapperJars.length < minWrapperCount) {
|
||||||
throw new Error(`Expected to find at least ${minWrapperCount} Gradle Wrapper JARs but got only ${wrapperJars.length}`);
|
result.errors.push(`Expected to find at least ${minWrapperCount} Gradle Wrapper JARs but got only ${wrapperJars.length}`);
|
||||||
}
|
}
|
||||||
if (wrapperJars.length > 0) {
|
if (wrapperJars.length > 0) {
|
||||||
const validChecksums = yield checksums.fetchValidChecksums(allowSnapshots);
|
const validChecksums = yield checksums.fetchValidChecksums(allowSnapshots);
|
||||||
validChecksums.push(...allowChecksums);
|
validChecksums.push(...allowChecksums);
|
||||||
const invalidWrapperJars = [];
|
|
||||||
for (const wrapperJar of wrapperJars) {
|
for (const wrapperJar of wrapperJars) {
|
||||||
const sha = yield hash.sha256File(wrapperJar);
|
const sha = yield hash.sha256File(wrapperJar);
|
||||||
if (!validChecksums.includes(sha)) {
|
if (!validChecksums.includes(sha)) {
|
||||||
invalidWrapperJars.push(new InvalidWrapperJar(wrapperJar, sha));
|
result.invalid.push(new WrapperJar(wrapperJar, sha));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.valid.push(new WrapperJar(wrapperJar, sha));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return invalidWrapperJars;
|
|
||||||
}
|
}
|
||||||
return [];
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.findInvalidWrapperJars = findInvalidWrapperJars;
|
exports.findInvalidWrapperJars = findInvalidWrapperJars;
|
||||||
class InvalidWrapperJar {
|
class ValidationResult {
|
||||||
|
constructor(valid, invalid) {
|
||||||
|
this.errors = [];
|
||||||
|
this.valid = valid;
|
||||||
|
this.invalid = invalid;
|
||||||
|
}
|
||||||
|
isValid() {
|
||||||
|
return this.invalid.length === 0 && this.errors.length === 0;
|
||||||
|
}
|
||||||
|
toDisplayString() {
|
||||||
|
let displayString = '';
|
||||||
|
if (this.invalid.length > 0) {
|
||||||
|
displayString += `✗ Found unknown Gradle Wrapper JAR files:\n${ValidationResult.toDisplayList(this.invalid)}`;
|
||||||
|
}
|
||||||
|
if (this.errors.length > 0) {
|
||||||
|
if (displayString.length > 0)
|
||||||
|
displayString += '\n';
|
||||||
|
displayString += `✗ Other validation errors:\n ${this.errors.join(`\n `)}`;
|
||||||
|
}
|
||||||
|
if (this.valid.length > 0) {
|
||||||
|
if (displayString.length > 0)
|
||||||
|
displayString += '\n';
|
||||||
|
displayString += `✓ Found known Gradle Wrapper JAR files:\n${ValidationResult.toDisplayList(this.valid)}`;
|
||||||
|
}
|
||||||
|
return displayString;
|
||||||
|
}
|
||||||
|
static toDisplayList(wrapperJars) {
|
||||||
|
return ` ${wrapperJars.map(wj => wj.toDisplayString()).join(`\n `)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ValidationResult = ValidationResult;
|
||||||
|
class WrapperJar {
|
||||||
constructor(path, checksum) {
|
constructor(path, checksum) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.checksum = checksum;
|
this.checksum = checksum;
|
||||||
}
|
}
|
||||||
|
toDisplayString() {
|
||||||
|
return `${this.checksum} ${this.path}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.InvalidWrapperJar = InvalidWrapperJar;
|
exports.WrapperJar = WrapperJar;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
@ -1069,7 +1104,8 @@ function findWrapperJars(baseDir) {
|
||||||
const files = yield recursivelyListFiles(baseDir);
|
const files = yield recursivelyListFiles(baseDir);
|
||||||
return files
|
return files
|
||||||
.filter(file => unhomoglyph_1.default(file).endsWith('gradle-wrapper.jar'))
|
.filter(file => unhomoglyph_1.default(file).endsWith('gradle-wrapper.jar'))
|
||||||
.map(wrapperJar => path.relative(baseDir, wrapperJar));
|
.map(wrapperJar => path.relative(baseDir, wrapperJar))
|
||||||
|
.sort((a, b) => a.localeCompare(b));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.findWrapperJars = findWrapperJars;
|
exports.findWrapperJars = findWrapperJars;
|
||||||
|
|
|
@ -10,6 +10,7 @@ export async function findWrapperJars(baseDir: string): Promise<string[]> {
|
||||||
return files
|
return files
|
||||||
.filter(file => unhomoglyph(file).endsWith('gradle-wrapper.jar'))
|
.filter(file => unhomoglyph(file).endsWith('gradle-wrapper.jar'))
|
||||||
.map(wrapperJar => path.relative(baseDir, wrapperJar))
|
.map(wrapperJar => path.relative(baseDir, wrapperJar))
|
||||||
|
.sort((a, b) => a.localeCompare(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function recursivelyListFiles(baseDir: string): Promise<string[]> {
|
async function recursivelyListFiles(baseDir: string): Promise<string[]> {
|
||||||
|
|
22
src/main.ts
22
src/main.ts
|
@ -5,22 +5,16 @@ import * as validate from './validate'
|
||||||
|
|
||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const minWrapperCount = +core.getInput('min-wrapper-count')
|
const result = await validate.findInvalidWrapperJars(
|
||||||
const allowSnapshots = core.getInput('allow-snapshots') === 'true'
|
|
||||||
const allowChecksums = core.getInput('allow-checksums').split(',')
|
|
||||||
const invalidWrapperJars = await validate.findInvalidWrapperJars(
|
|
||||||
path.resolve('.'),
|
path.resolve('.'),
|
||||||
minWrapperCount,
|
+core.getInput('min-wrapper-count'),
|
||||||
allowSnapshots,
|
core.getInput('allow-snapshots') === 'true',
|
||||||
allowChecksums
|
core.getInput('allow-checksums').split(',')
|
||||||
)
|
)
|
||||||
if (invalidWrapperJars.length > 0) {
|
if (result.isValid()) {
|
||||||
const list = invalidWrapperJars.map(
|
core.info(result.toDisplayString())
|
||||||
invalid => `${invalid.checksum} ${invalid.path}`
|
} else {
|
||||||
)
|
core.setFailed(result.toDisplayString())
|
||||||
core.setFailed(
|
|
||||||
`Found unknown Gradle Wrapper JAR files\n${list.join('\n- ')}`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message)
|
core.setFailed(error.message)
|
||||||
|
|
|
@ -7,33 +7,80 @@ export async function findInvalidWrapperJars(
|
||||||
minWrapperCount: number,
|
minWrapperCount: number,
|
||||||
allowSnapshots: boolean,
|
allowSnapshots: boolean,
|
||||||
allowChecksums: string[]
|
allowChecksums: string[]
|
||||||
): Promise<InvalidWrapperJar[]> {
|
): Promise<ValidationResult> {
|
||||||
const wrapperJars = await find.findWrapperJars(gitRepoRoot)
|
const wrapperJars = await find.findWrapperJars(gitRepoRoot)
|
||||||
|
const result = new ValidationResult([], [])
|
||||||
if (wrapperJars.length < minWrapperCount) {
|
if (wrapperJars.length < minWrapperCount) {
|
||||||
throw new Error(
|
result.errors.push(
|
||||||
`Expected to find at least ${minWrapperCount} Gradle Wrapper JARs but got only ${wrapperJars.length}`
|
`Expected to find at least ${minWrapperCount} Gradle Wrapper JARs but got only ${wrapperJars.length}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (wrapperJars.length > 0) {
|
if (wrapperJars.length > 0) {
|
||||||
const validChecksums = await checksums.fetchValidChecksums(allowSnapshots)
|
const validChecksums = await checksums.fetchValidChecksums(allowSnapshots)
|
||||||
validChecksums.push(...allowChecksums)
|
validChecksums.push(...allowChecksums)
|
||||||
const invalidWrapperJars: InvalidWrapperJar[] = []
|
|
||||||
for (const wrapperJar of wrapperJars) {
|
for (const wrapperJar of wrapperJars) {
|
||||||
const sha = await hash.sha256File(wrapperJar)
|
const sha = await hash.sha256File(wrapperJar)
|
||||||
if (!validChecksums.includes(sha)) {
|
if (!validChecksums.includes(sha)) {
|
||||||
invalidWrapperJars.push(new InvalidWrapperJar(wrapperJar, sha))
|
result.invalid.push(new WrapperJar(wrapperJar, sha))
|
||||||
|
} else {
|
||||||
|
result.valid.push(new WrapperJar(wrapperJar, sha))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return invalidWrapperJars
|
|
||||||
}
|
}
|
||||||
return []
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InvalidWrapperJar {
|
export class ValidationResult {
|
||||||
|
valid: WrapperJar[]
|
||||||
|
invalid: WrapperJar[]
|
||||||
|
errors: string[] = []
|
||||||
|
|
||||||
|
constructor(valid: WrapperJar[], invalid: WrapperJar[]) {
|
||||||
|
this.valid = valid
|
||||||
|
this.invalid = invalid
|
||||||
|
}
|
||||||
|
|
||||||
|
isValid(): boolean {
|
||||||
|
return this.invalid.length === 0 && this.errors.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
toDisplayString(): string {
|
||||||
|
let displayString = ''
|
||||||
|
if (this.invalid.length > 0) {
|
||||||
|
displayString += `✗ Found unknown Gradle Wrapper JAR files:\n${ValidationResult.toDisplayList(
|
||||||
|
this.invalid
|
||||||
|
)}`
|
||||||
|
}
|
||||||
|
if (this.errors.length > 0) {
|
||||||
|
if (displayString.length > 0) displayString += '\n'
|
||||||
|
displayString += `✗ Other validation errors:\n ${this.errors.join(
|
||||||
|
`\n `
|
||||||
|
)}`
|
||||||
|
}
|
||||||
|
if (this.valid.length > 0) {
|
||||||
|
if (displayString.length > 0) displayString += '\n'
|
||||||
|
displayString += `✓ Found known Gradle Wrapper JAR files:\n${ValidationResult.toDisplayList(
|
||||||
|
this.valid
|
||||||
|
)}`
|
||||||
|
}
|
||||||
|
return displayString
|
||||||
|
}
|
||||||
|
|
||||||
|
private static toDisplayList(wrapperJars: WrapperJar[]): string {
|
||||||
|
return ` ${wrapperJars.map(wj => wj.toDisplayString()).join(`\n `)}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WrapperJar {
|
||||||
path: string
|
path: string
|
||||||
checksum: string
|
checksum: string
|
||||||
|
|
||||||
constructor(path: string, checksum: string) {
|
constructor(path: string, checksum: string) {
|
||||||
this.path = path
|
this.path = path
|
||||||
this.checksum = checksum
|
this.checksum = checksum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toDisplayString(): string {
|
||||||
|
return `${this.checksum} ${this.path}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue