diff --git a/src/main/groovy/nebula/plugin/dependencylock/DependencyLockReader.groovy b/src/main/groovy/nebula/plugin/dependencylock/DependencyLockReader.groovy index 5f9b3bbf..d7777e5c 100644 --- a/src/main/groovy/nebula/plugin/dependencylock/DependencyLockReader.groovy +++ b/src/main/groovy/nebula/plugin/dependencylock/DependencyLockReader.groovy @@ -27,9 +27,9 @@ class DependencyLockReader { locks = locks.collectEntries { configurationName, deps -> [(configurationName): deps.findAll { coord, info -> def notUpdate = !updates.contains(coord) - def notTransitive = info.transitive == null - def hasRequestedVersion = info.requested != null - notUpdate && notTransitive && hasRequestedVersion + def isFirstLevel = info.transitive == null && info.requested != null + def isFirstLevelTransitive = info.transitive.any { deps[it].project } + notUpdate && (isFirstLevel || isFirstLevelTransitive) }] } } diff --git a/src/test/groovy/nebula/plugin/dependencylock/DependencyLockLauncherSpec.groovy b/src/test/groovy/nebula/plugin/dependencylock/DependencyLockLauncherSpec.groovy index 55e80894..9cf71248 100644 --- a/src/test/groovy/nebula/plugin/dependencylock/DependencyLockLauncherSpec.groovy +++ b/src/test/groovy/nebula/plugin/dependencylock/DependencyLockLauncherSpec.groovy @@ -1050,12 +1050,75 @@ class DependencyLockLauncherSpec extends IntegrationSpec { ) when: - def results = runTasksSuccessfully('updateLock', '-PdependencyLock.updateDependencies=test.example:qux') + runTasksSuccessfully('updateLock', '-PdependencyLock.updateDependencies=test.example:qux') then: new File(projectDir, 'build/dependencies.lock').text == updatedLock } + def 'project first level transitives are kept locked during update'() { + setupCommonMultiproject() + addSubproject('sub3', """\ + dependencies { + compile project(':sub4') + } + """.stripIndent()) + + addSubproject('sub4', """\ + dependencies { + compile project(':sub2') + } + """.stripIndent()) + def lockFile = new File(new File(projectDir, 'sub3'), 'dependencies.lock') + def lockText = LockGenerator.duplicateIntoConfigs('''\ + "test.example:foo": { + "locked": "1.0.0", + "transitive": [ + "test:sub2" + ], + "viaOverride": "1.0.0" + }, + "test:sub2": { + "project": true, + "transitive": [ + "test:sub4" + ] + }, + "test:sub4": { + "project": true + } + '''.stripIndent()) + + when: + runTasksSuccessfully('generateLock', 'saveLock', '-PdependencyLock.override=test.example:foo:1.0.0') + + then: + lockFile.text == lockText + + when: + runTasksSuccessfully('updateLock', 'saveLock', '-PdependencyLock.updateDependencies=test.example:qux') + + then: + def updateLockText = LockGenerator.duplicateIntoConfigs('''\ + "test.example:foo": { + "locked": "1.0.0", + "transitive": [ + "test:sub2" + ] + }, + "test:sub2": { + "project": true, + "transitive": [ + "test:sub4" + ] + }, + "test:sub4": { + "project": true + } + '''.stripIndent()) + lockFile.text == updateLockText + } + def 'generateLock interacts well with resolution rules'() { buildFile << """\ plugins { @@ -1263,14 +1326,15 @@ class DependencyLockLauncherSpec extends IntegrationSpec { allprojects { ${applyPlugin(DependencyLockPlugin)} group = 'test' + + dependencyLock { + includeTransitives = true + } } subprojects { apply plugin: 'java' repositories { maven { url '${Fixture.repo}' } } } - dependencyLock { - includeTransitives = true - } """.stripIndent() } }