Skip to content

Commit

Permalink
Merge pull request #240 from fedorka/conditionally-allow-invalid-depe…
Browse files Browse the repository at this point in the history
…ndency-coordinates

DependencyLockExtension: add property to disable coordinate validation
  • Loading branch information
OdysseusLives authored Apr 11, 2022
2 parents 1dc1a05 + 0fcf59a commit 1fd83d4
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class DependencyLockPlugin : Plugin<Project> {
const val GLOBAL_LOCK_FILE = "dependencyLock.globalLockFile"
const val LOCK_AFTER_EVALUATING = "dependencyLock.lockAfterEvaluating"
const val UPDATE_DEPENDENCIES = "dependencyLock.updateDependencies"
const val VALIDATE_DEPENDENCY_COORDINATES = "dependencyLock.updateDependenciesFailOnInvalidCoordinates"
const val OVERRIDE = "dependencyLock.override"
const val OVERRIDE_FILE = "dependencyLock.overrideFile"
const val GENERATE_GLOBAL_LOCK_TASK_NAME = "generateGlobalLock"
Expand Down Expand Up @@ -199,7 +200,8 @@ class DependencyLockPlugin : Plugin<Project> {

val updates = if (project.hasProperty(UPDATE_DEPENDENCIES)) parseUpdates(project.property(UPDATE_DEPENDENCIES) as String) else extension.updateDependencies
if(updates != null && updates.isNotEmpty()) {
UpdateDependenciesValidator.validate(updates, extension.updateDependenciesFailOnInvalidCoordinates)
val validateCoordinates = if (project.hasProperty(VALIDATE_DEPENDENCY_COORDINATES)) project.property(VALIDATE_DEPENDENCY_COORDINATES).toString().toBoolean() else extension.updateDependenciesFailOnInvalidCoordinates
UpdateDependenciesValidator.validate(updates, validateCoordinates)
}
val projectCoord = "${project.group}:${project.name}"
if (hasUpdateTask && updates.any { it == projectCoord }) {
Expand Down Expand Up @@ -249,8 +251,11 @@ class DependencyLockPlugin : Plugin<Project> {
}
}

/**
* Split the string on comma, dropping any empty entries (allows for comma seperated environment variables which may be empty)
*/
private fun parseUpdates(updates: String): Set<String> =
updates.split(",").toSet()
updates.split(",").filter {it.isNotEmpty()} .toSet()

private fun applyLock(conf: Configuration, dependenciesLock: File, updates: Set<String> = emptySet()) {
LOGGER.info("Using ${dependenciesLock.name} to lock dependencies in $conf")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ class UpdateDependenciesValidator {
fun validate(updateDependencies: Set<String>, failOnError: Boolean) {
val errors = mutableListOf<String>()
updateDependencies.forEach { coordinate ->
if(coordinate.split(":").size == 1) {
if(coordinate.isEmpty()) {
errors.add("An empty element exists in the list")
}
else if(coordinate.split(":").size == 1) {
errors.add("$coordinate does not contain groupId:module. Only has one element")
}
if(coordinate.split(":").size > 2) {
else if(coordinate.split(":").size > 2) {
errors.add("$coordinate contains more elements than groupId:module. Version and classifiers are not supported")
}
if(coordinate.contains(";")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,99 @@ class DependencyLockLauncherSpec extends IntegrationSpec {
Throwables.getRootCause(result.failure).message == 'Dependency locks cannot be updated. An update was requested for a project dependency (test:sub1)'
}

def 'update fails if updateDependencies has malformed coordiantes'() {
def dependenciesLock = new File(projectDir, 'dependencies.lock')
dependenciesLock << FOO_LOCK
buildFile << BUILD_GRADLE

when:
def result = runTasks('-PdependencyLock.updateDependencies=test.example:foo:2.0.1', '-PdependencyLock.override=test.example:foo:2.0.1', 'updateLock', 'saveLock')


then:
def message = Throwables.getRootCause(result.failure).message
message.contains("updateDependencies list is invalid")
message.contains("test.example:foo:2.0.1 contains more elements than groupId:module")
}

def 'command line override respected while updating lock with malformed coordinates with extension'() {
def dependenciesLock = new File(projectDir, 'dependencies.lock')
dependenciesLock << FOO_LOCK
buildFile << """
apply plugin: 'java'
apply plugin: 'nebula.dependency-lock'
repositories { maven { url '${Fixture.repo}' } }
dependencies {
implementation 'test.example:foo:1.+'
}
dependencyLock {
updateDependenciesFailOnInvalidCoordinates = false
}
""".stripIndent()

when:
runTasksSuccessfully('-PdependencyLock.updateDependencies=test.example:foo:2.0.1', '-PdependencyLock.override=test.example:foo:2.0.1', 'updateLock', 'saveLock')

then:
new File(projectDir, 'dependencies.lock').text == NEW_FOO_LOCK
}

def 'command line override respected while updating lock with malformed coordinates allowed by property'() {
def dependenciesLock = new File(projectDir, 'dependencies.lock')
dependenciesLock << FOO_LOCK
buildFile << BUILD_GRADLE

when:
runTasksSuccessfully('-PdependencyLock.updateDependencies=test.example:foo:2.0.1', '-PdependencyLock.override=test.example:foo:2.0.1', '-PdependencyLock.updateDependenciesFailOnInvalidCoordinates=false', 'updateLock', 'saveLock')

then:
new File(projectDir, 'dependencies.lock').text == NEW_FOO_LOCK
}

def 'updateDependenciesFailOnInvalidCoordinates command line override respected while updating lock with malformed coordinates allowed by extension'() {
def dependenciesLock = new File(projectDir, 'dependencies.lock')
dependenciesLock << FOO_LOCK
buildFile << """
apply plugin: 'java'
apply plugin: 'nebula.dependency-lock'
repositories { maven { url '${Fixture.repo}' } }
dependencies {
implementation 'test.example:foo:1.+'
}
dependencyLock {
updateDependenciesFailOnInvalidCoordinates = false
}
""".stripIndent()

when:
runTasksSuccessfully('-PdependencyLock.updateDependencies=test.example:foo:2.0.1', '-PdependencyLock.override=test.example:foo:2.0.1', '-PdependencyLock.updateDependenciesFailOnInvalidCoordinates=false', 'updateLock', 'saveLock')

then:
new File(projectDir, 'dependencies.lock').text == NEW_FOO_LOCK
}

def 'updateDependenciesFailOnInvalidCoordinates prefers property over extension'() {
def dependenciesLock = new File(projectDir, 'dependencies.lock')
dependenciesLock << FOO_LOCK
buildFile << """
apply plugin: 'java'
apply plugin: 'nebula.dependency-lock'
repositories { maven { url '${Fixture.repo}' } }
dependencies {
implementation 'test.example:foo:1.+'
}
dependencyLock {
updateDependenciesFailOnInvalidCoordinates = true
}
""".stripIndent()

when:
runTasksSuccessfully('-PdependencyLock.updateDependencies=test.example:foo:2.0.1', '-PdependencyLock.override=test.example:foo:2.0.1', '-PdependencyLock.updateDependenciesFailOnInvalidCoordinates=false', 'updateLock', 'saveLock')

then:
new File(projectDir, 'dependencies.lock').text == NEW_FOO_LOCK
}

def 'generateLock interacts well with resolution rules'() {
buildFile << """\
buildscript {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,21 @@ class DependencyLockPluginSpec extends ProjectSpec {
foo.moduleVersion == '2.0.1'
}

def 'command line override of a dependency accepts empty entries'() {
stockTestSetup()

project.ext.set('dependencyLock.override', 'test.example:foo:2.0.1,')

when:
project.apply plugin: pluginName
triggerAfterEvaluate()
def resolved = project.configurations.compileClasspath.resolvedConfiguration

then:
def foo = resolved.firstLevelModuleDependencies.find { it.moduleName == 'foo' }
foo.moduleVersion == '2.0.1'
}

def 'command line override of a dependency with forces in place'() {
stockTestSetup()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,13 @@ class UpdateDependenciesValidatorSpec extends Specification {
exception.message.contains("netflix:my-module;2:latest.release contains more elements than groupId:module. Version and classifiers are not supported")
exception.message.contains("netflix:my-module;2:latest.release contains ; which is invalid")
}
}

def 'should not fail if invalid coordinates but disabled validation'() {
when:
Set<String> modules = ["netflix", "netflix:my-module:1.+", "netflix:my-module-2:latest.release", "netflix:my-module;2:latest.release"]
UpdateDependenciesValidator.validate(modules,false)

then:
notThrown(DependencyLockException)
}
}

0 comments on commit 1fd83d4

Please sign in to comment.