Last active
October 23, 2018 00:09
-
-
Save DanielThomas/e10b97c8d3dc98ca46fb150f535dc8d8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.netflix.lint.rule.nebula | |
import com.netflix.nebula.lint.FileMode | |
import com.netflix.nebula.lint.rule.GradleLintRule | |
import com.netflix.nebula.lint.rule.GradleModelAware | |
import org.codehaus.groovy.ast.ClassNode | |
import java.security.MessageDigest | |
import static java.nio.file.Files.isSymbolicLink | |
class UpdateNebulaWrapperRule extends GradleLintRule implements GradleModelAware { | |
static WRAPPER_DIRS = ['gradle', 'gradle/wrapper'] | |
static WRAPPER_FILES = ['gradlew', 'gradlew.bat', 'gradle/wrapper/gradle-wrapper.properties', 'gradle/wrapper/gradle-wrapper.jar'] | |
static ALL_WRAPPER_FILES = WRAPPER_FILES + WRAPPER_DIRS | |
static downloadLatestNebula(File toDir) { | |
def tempDir = new File(toDir, "latestNebula-${new Date().time}") | |
WRAPPER_DIRS.each { new File(tempDir, it).mkdirs() } | |
WRAPPER_FILES.each { | |
def out = new File(tempDir, it) | |
def url = new URL("<raw-scm-request-url>/$it?raw") | |
out << url.openStream() | |
if (it.contains('gradlew')) out.setExecutable(true) | |
} | |
return tempDir | |
} | |
static md5(File file) { | |
if (!file.exists()) { | |
return null | |
} | |
return MessageDigest.getInstance("MD5").digest(file.bytes).encodeHex().toString() | |
} | |
static pathContainsSymbolicLink(File baseDir, File file) { | |
File curr = file.parentFile | |
while (curr != baseDir) { | |
if (isSymbolicLink(curr.toPath())) return true | |
curr = curr.parentFile | |
} | |
return false | |
} | |
@Override | |
protected void visitClassComplete(ClassNode node) { | |
if (!project.rootDir.equals(project.projectDir)) { | |
return // only execute for the root project | |
} | |
def rootDir = project.rootDir | |
def gitIgnore = new File(rootDir, '.gitignore') | |
if (gitIgnore.exists()) { | |
gitIgnore.readLines().eachWithIndex { String ignoreEntry, Integer index -> | |
if (ALL_WRAPPER_FILES.contains(ignoreEntry)) { | |
def lineToDelete = index + 1 | |
addLintViolation("Nebula wrapper file is ignored using '$ignoreEntry' in .gitignore", gitIgnore, index) | |
.deleteLines(gitIgnore, lineToDelete..lineToDelete) | |
} | |
} | |
} | |
def latestNebulaRoot = downloadLatestNebula(project.buildDir) | |
WRAPPER_DIRS.each { dir -> | |
def examinedDir = new File(rootDir, dir) | |
if (examinedDir.exists()) { | |
if (examinedDir.isFile()) { | |
addLintViolation("Nebula wrapper directory '$dir' is a regular file", examinedDir, 0).deleteFile(examinedDir) | |
} else if (isSymbolicLink(examinedDir.toPath())) { | |
addLintViolation("Nebula wrapper directory '$dir' must not be a symbolic link", examinedDir, 0).deleteFile(examinedDir) | |
} | |
} | |
} | |
WRAPPER_FILES.each { file -> | |
def examinedFile = new File(rootDir, file) | |
def targetFile = new File(latestNebulaRoot, file) | |
def fileType = file.contains('gradlew') ? FileMode.Executable : FileMode.Regular | |
if (!examinedFile.exists() || pathContainsSymbolicLink(rootDir, examinedFile)) { | |
addLintViolation("Nebula wrapper file '$file' does not exist", examinedFile, 0).createFile(examinedFile, targetFile.text, fileType) | |
} else if (isSymbolicLink(examinedFile.toPath())) { | |
addLintViolation("Nebula wrapper file '$file' must not be a symbolic link", examinedFile, 0).deleteFile(examinedFile).createFile(examinedFile, targetFile.text, fileType) | |
} else if (md5(examinedFile) != md5(targetFile)) { | |
addLintViolation("Nebula wrapper file '$file' is out-of-date", examinedFile, 0).deleteFile(examinedFile).createFile(examinedFile, targetFile.text, fileType) | |
} else if (fileType == FileMode.Executable && !examinedFile.canExecute()) { | |
addLintViolation("Nebula wrapper file '$file' is not executable", examinedFile, 0).deleteFile(examinedFile).createFile(examinedFile, targetFile.text, fileType) | |
} | |
} | |
} | |
@Override | |
String getDescription() { | |
return 'ensure the latest Nebula wrapper is being used' | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment