Skip to content

Commit 3eac7b2

Browse files
committed
Fix updating global locks with updateDependencies set
Because dependencies are "transitive" in the global context, we need to ensure that anything a project directly depends on is not excluded from the list of forces.
1 parent 7399355 commit 3eac7b2

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

src/main/groovy/nebula/plugin/dependencylock/DependencyLockPlugin.groovy

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,22 @@ class DependencyLockPlugin implements Plugin<Project> {
371371
}
372372
}
373373

374+
boolean isTopLevel(info, deps) {
375+
// If this is not listed as being depended on at all, it must be a top-level dependency
376+
if (info.transitive == null) return true
377+
378+
// If a dependency is listed as being depended on by something that we know is a project, then it must be a top-level dependency
379+
return info.transitive.any {
380+
deps[it]?.project
381+
}
382+
}
383+
374384
void applyLock(File dependenciesLock, Map overrides, Collection<String> updates = []) {
375385
logger.info("Using ${dependenciesLock.name} to lock dependencies")
376386
def locks = loadLock(dependenciesLock)
377387

378388
if (updates) {
379-
locks = locks.collectEntries { configurationName, deps -> [(configurationName): deps.findAll { coord, info -> (info.transitive == null) && !updates.contains(coord) }]}
389+
locks = locks.collectEntries { configurationName, deps -> [(configurationName): deps.findAll { coord, info -> isTopLevel(info, deps) && !updates.contains(coord) }]}
380390
}
381391

382392
def isDeprecatedFormat = locks.every { it.key ==~ /[^:]+:.+/ } // in the old format, all first level props were groupId:artifactId

src/test/groovy/nebula/plugin/dependencylock/DependencyLockLauncherSpec.groovy

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,95 @@ class DependencyLockLauncherSpec extends IntegrationSpec {
12091209
new File(projectDir, 'build/dependencies.lock').text == updatedLock
12101210
}
12111211

1212+
def 'only the update dependency and its transitives are updated when using a global lock'() {
1213+
addSubproject('sub1', """\
1214+
dependencies {
1215+
compile 'test.example:bar:1.+'
1216+
compile 'test.example:qux:latest.release'
1217+
}
1218+
""".stripIndent())
1219+
buildFile << """\
1220+
allprojects {
1221+
${applyPlugin(DependencyLockPlugin)}
1222+
group = 'test'
1223+
}
1224+
subprojects {
1225+
apply plugin: 'java'
1226+
repositories { maven { url '${Fixture.repo}' } }
1227+
}
1228+
dependencyLock {
1229+
includeTransitives = true
1230+
}
1231+
""".stripIndent()
1232+
1233+
def lockFile = new File(projectDir, 'global.lock')
1234+
def lockText = '''\
1235+
{
1236+
"_global_": {
1237+
"test.example:bar": {
1238+
"locked": "1.0.0",
1239+
"requested": "1.+",
1240+
"transitive": [
1241+
"test:sub1"
1242+
]
1243+
},
1244+
"test.example:qux": {
1245+
"locked": "1.0.0",
1246+
"requested": "latest.release",
1247+
"transitive": [
1248+
"test:sub1"
1249+
]
1250+
},
1251+
"test.example:foo": {
1252+
"locked": "1.0.0",
1253+
"transitive": [
1254+
"test.example:bar",
1255+
"test.example:qux"
1256+
]
1257+
},
1258+
"test:sub1": {
1259+
"project": true
1260+
}
1261+
}
1262+
}'''.stripIndent()
1263+
lockFile.text = lockText
1264+
1265+
def updatedLock = '''\
1266+
{
1267+
"_global_": {
1268+
"test.example:bar": {
1269+
"locked": "1.1.0",
1270+
"transitive": [
1271+
"test:sub1"
1272+
]
1273+
},
1274+
"test.example:foo": {
1275+
"locked": "1.0.1",
1276+
"transitive": [
1277+
"test.example:bar",
1278+
"test.example:qux"
1279+
]
1280+
},
1281+
"test.example:qux": {
1282+
"locked": "1.0.0",
1283+
"transitive": [
1284+
"test:sub1"
1285+
]
1286+
},
1287+
"test:sub1": {
1288+
"project": true
1289+
}
1290+
}
1291+
}'''.stripIndent()
1292+
1293+
when:
1294+
def results = runTasksSuccessfully('updateGlobalLock', '-PdependencyLock.updateDependencies=test.example:bar')
1295+
1296+
then:
1297+
println results.standardOutput
1298+
new File(projectDir, 'build/global.lock').text == updatedLock
1299+
}
1300+
12121301
@Ignore
12131302
def 'diff the generated lock with the existing lock '() {
12141303
def dependenciesLock = new File(projectDir, 'dependencies.lock')

0 commit comments

Comments
 (0)