Skip to content

Commit a320a1e

Browse files
committed
Compute artifact differences
1 parent 0c57c71 commit a320a1e

File tree

7 files changed

+181
-38
lines changed

7 files changed

+181
-38
lines changed

src/main/scala/software/purpledragon/sbt/lock/DependencyUtils.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import java.time.Instant
2121
import sbt._
2222
import software.purpledragon.sbt.lock.model.{DependencyLockFile, DependencyRef, ResolvedArtifact, ResolvedDependency}
2323

24-
import scala.collection.{SortedSet, immutable, mutable}
24+
import scala.collection.{immutable, mutable, SortedSet}
2525

2626
object DependencyUtils {
2727
def resolve(updateReport: UpdateReport, configs: Seq[ConfigRef]): DependencyLockFile = {

src/main/scala/software/purpledragon/sbt/lock/model/ChangedDependency.scala

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,70 @@
1717
package software.purpledragon.sbt.lock.model
1818

1919
import scala.collection.SortedSet
20+
import scala.math.Ordered.orderingToOrdered
2021

2122
final case class ChangedDependency(
2223
org: String,
2324
name: String,
2425
oldVersion: String,
2526
newVersion: String,
26-
oldArtifacts: SortedSet[ResolvedArtifact],
27-
newArtifacts: SortedSet[ResolvedArtifact],
2827
oldConfigurations: SortedSet[String],
29-
newConfigurations: SortedSet[String]) {
28+
newConfigurations: SortedSet[String],
29+
addedArtifacts: SortedSet[ResolvedArtifact],
30+
removedArtifacts: SortedSet[ResolvedArtifact],
31+
changedArtifacts: SortedSet[ChangedArtifact]) {
3032

3133
def versionChanged: Boolean = oldVersion != newVersion
3234
def configurationsChanged: Boolean = oldConfigurations != newConfigurations
35+
def artifactsChanged: Boolean = addedArtifacts.nonEmpty || removedArtifacts.nonEmpty || changedArtifacts.nonEmpty
36+
}
37+
38+
object ChangedDependency {
39+
def apply(
40+
org: String,
41+
name: String,
42+
oldVersion: String,
43+
newVersion: String,
44+
oldConfigurations: SortedSet[String],
45+
newConfigurations: SortedSet[String],
46+
oldArtifacts: SortedSet[ResolvedArtifact],
47+
newArtifacts: SortedSet[ResolvedArtifact]): ChangedDependency = {
48+
49+
val oldArtifactsByName = oldArtifacts.map(a => a.name -> a).toMap
50+
val newArtifactsByName = newArtifacts.map(a => a.name -> a).toMap
51+
52+
val addedArtifacts = (newArtifactsByName.keySet -- oldArtifactsByName.keySet).map(newArtifactsByName.apply)
53+
val removedArtifacts = (oldArtifactsByName.keySet -- newArtifactsByName.keySet).map(oldArtifactsByName.apply)
54+
55+
val changedArtifacts =
56+
oldArtifactsByName.keySet.intersect(newArtifactsByName.keySet).foldLeft(Seq.empty[ChangedArtifact]) {
57+
(changes, name) =>
58+
val oldHash = oldArtifactsByName(name).hash
59+
val newHash = newArtifactsByName(name).hash
60+
61+
if (oldHash != newHash) {
62+
changes :+ ChangedArtifact(name, oldHash, newHash)
63+
} else {
64+
changes
65+
}
66+
}
67+
68+
ChangedDependency(
69+
org,
70+
name,
71+
oldVersion,
72+
newVersion,
73+
oldConfigurations,
74+
newConfigurations,
75+
addedArtifacts.to[SortedSet],
76+
removedArtifacts.to[SortedSet],
77+
changedArtifacts.to[SortedSet]
78+
)
79+
}
80+
}
81+
82+
final case class ChangedArtifact(name: String, oldHash: String, newHash: String) extends Ordered[ChangedArtifact] {
83+
override def compare(that: ChangedArtifact): Int = {
84+
(name, oldHash, newHash) compare (that.name, that.oldHash, that.newHash)
85+
}
3386
}

src/main/scala/software/purpledragon/sbt/lock/model/DependencyLockFile.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ final case class DependencyLockFile(
8080
depref.name,
8181
ourDep.version,
8282
otherDep.version,
83-
ourDep.artifacts,
84-
otherDep.artifacts,
8583
ourDep.configurations,
86-
otherDep.configurations)
84+
otherDep.configurations,
85+
ourDep.artifacts,
86+
otherDep.artifacts)
8787
} else {
8888
changes
8989
}

src/main/scala/software/purpledragon/sbt/lock/model/LockFileStatus.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ final case class LockFileDiffers(
140140
case (true, true) => "lock.status.full.dependency.changed.all"
141141
case (true, false) => "lock.status.full.dependency.changed.version"
142142
case (false, true) => "lock.status.full.dependency.changed.configs"
143-
case _ => "error"
143+
case _ => "lock.status.full.dependency"
144144
}
145145

146146
MessageUtil.formatMessage(
@@ -150,7 +150,10 @@ final case class LockFileDiffers(
150150
change.oldVersion,
151151
change.newVersion,
152152
change.oldConfigurations.mkString(","),
153-
change.newConfigurations.mkString(","))
153+
change.newConfigurations.mkString(",")
154+
)
155+
156+
// TODO arts
154157
}
155158

156159
errors += MessageUtil.formatPlural(

src/main/scala/software/purpledragon/sbt/lock/model/ResolvedArtifact.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ package software.purpledragon.sbt.lock.model
1818

1919
import java.io.File
2020

21-
import sbt.{File, Hash}
21+
import sbt.Hash
2222
import sbt.librarymanagement.Artifact
23-
import software.purpledragon.sbt.lock.DependencyUtils.hashFile
2423

2524
import scala.collection.mutable
2625
import scala.math.Ordered.orderingToOrdered

src/test/scala/software/purpledragon/sbt/lock/model/DependencyLockFileSpec.scala

Lines changed: 112 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,18 @@ import org.scalatest.matchers.should.Matchers
2424
import scala.collection.SortedSet
2525

2626
class DependencyLockFileSpec extends AnyFlatSpec with Matchers {
27+
private val Dependency1Artifact = ResolvedArtifact("package-1.jar", "hash-1")
28+
private val Dependency1 =
29+
ResolvedDependency("com.example", "package-1", "1.0.0", SortedSet(Dependency1Artifact), SortedSet("test-1"))
30+
private val Dependency2 =
31+
ResolvedDependency("com.example", "package-2", "1.2.0", SortedSet.empty, SortedSet("test-2"))
32+
2733
private val EmptyLockFile = DependencyLockFile(1, Instant.now(), Nil, Nil)
2834
private val TestLockFile = DependencyLockFile(
2935
1,
3036
Instant.now(),
3137
Seq("test-1", "test-2"),
32-
Seq(
33-
ResolvedDependency(
34-
"com.example",
35-
"package-1",
36-
"1.0.0",
37-
SortedSet(ResolvedArtifact("package-1.jar", "hash-1")),
38-
SortedSet("test-1")),
39-
ResolvedDependency("com.example", "package-2", "1.2.0", SortedSet.empty, SortedSet("test-2"))
40-
)
38+
Seq(Dependency1, Dependency2)
4139
)
4240

4341
"findChanges" should "return LockFileMatches for identical lockfiles" in {
@@ -78,12 +76,13 @@ class DependencyLockFileSpec extends AnyFlatSpec with Matchers {
7876
}
7977

8078
it should "return LockFileDiffers if dependency added" in {
81-
val newDependency = ResolvedDependency(
82-
"com.example",
83-
"package-3",
84-
"3.0",
85-
SortedSet(ResolvedArtifact("package-3.jar", "hash-3")),
86-
SortedSet("test-1"))
79+
val newDependency =
80+
ResolvedDependency(
81+
"com.example",
82+
"package-3",
83+
"3.0",
84+
SortedSet(ResolvedArtifact("package-3.jar", "hash-3")),
85+
SortedSet("test-1"))
8786

8887
val left = TestLockFile
8988
val right = left.copy(dependencies = left.dependencies :+ newDependency)
@@ -101,12 +100,8 @@ class DependencyLockFileSpec extends AnyFlatSpec with Matchers {
101100
it should "return LockFileDiffers if dependency changed" in {
102101
val left = TestLockFile
103102
val right = left.copy(
104-
dependencies = left.dependencies.tail :+ ResolvedDependency(
105-
"com.example",
106-
"package-1",
107-
"2.0.0",
108-
SortedSet(ResolvedArtifact("package-1.jar", "hash-1a")),
109-
SortedSet("test-1", "test-2"))
103+
dependencies = left.dependencies.head.copy(version = "2.0.0", configurations = SortedSet("test-1", "test-2")) +:
104+
left.dependencies.tail
110105
)
111106

112107
left.findChanges(right) shouldBe LockFileDiffers(
@@ -120,10 +115,103 @@ class DependencyLockFileSpec extends AnyFlatSpec with Matchers {
120115
"package-1",
121116
"1.0.0",
122117
"2.0.0",
123-
SortedSet(ResolvedArtifact("package-1.jar", "hash-1")),
124-
SortedSet(ResolvedArtifact("package-1.jar", "hash-1a")),
125118
SortedSet("test-1"),
126-
SortedSet("test-1", "test-2")
119+
SortedSet("test-1", "test-2"),
120+
SortedSet.empty,
121+
SortedSet.empty,
122+
SortedSet.empty
123+
))
124+
)
125+
}
126+
127+
it should "return LockFileDiffers if artifact changed" in {
128+
val left = TestLockFile
129+
val right = left.copy(
130+
dependencies = left.dependencies map { dep =>
131+
dep.copy(artifacts = dep.artifacts map { art =>
132+
art.copy(hash = art.hash + "a")
133+
})
134+
}
135+
)
136+
137+
left.findChanges(right) shouldBe LockFileDiffers(
138+
Nil,
139+
Nil,
140+
Nil,
141+
Nil,
142+
Seq(
143+
ChangedDependency(
144+
"com.example",
145+
"package-1",
146+
"1.0.0",
147+
"1.0.0",
148+
SortedSet("test-1"),
149+
SortedSet("test-1"),
150+
SortedSet.empty,
151+
SortedSet.empty,
152+
SortedSet(ChangedArtifact("package-1.jar", "hash-1", "hash-1a"))
153+
))
154+
)
155+
}
156+
157+
it should "return LockFileDiffers if artifact added" in {
158+
val left = TestLockFile
159+
160+
val right = left.copy(
161+
dependencies = Seq(
162+
Dependency1.copy(
163+
artifacts = SortedSet(
164+
Dependency1Artifact,
165+
ResolvedArtifact("package-1a.jar", "hash-1a")
166+
)),
167+
Dependency2
168+
))
169+
170+
left.findChanges(right) shouldBe LockFileDiffers(
171+
Nil,
172+
Nil,
173+
Nil,
174+
Nil,
175+
Seq(
176+
ChangedDependency(
177+
"com.example",
178+
"package-1",
179+
"1.0.0",
180+
"1.0.0",
181+
SortedSet("test-1"),
182+
SortedSet("test-1"),
183+
SortedSet(ResolvedArtifact("package-1a.jar", "hash-1a")),
184+
SortedSet.empty,
185+
SortedSet.empty
186+
))
187+
)
188+
}
189+
190+
it should "return LockFileDiffers if artifact removed" in {
191+
val left = TestLockFile
192+
193+
val right = left.copy(
194+
dependencies = Seq(
195+
Dependency1.copy(artifacts = SortedSet.empty),
196+
Dependency2
197+
))
198+
199+
left.findChanges(right) shouldBe LockFileDiffers(
200+
Nil,
201+
Nil,
202+
Nil,
203+
Nil,
204+
Seq(
205+
ChangedDependency(
206+
"com.example",
207+
"package-1",
208+
"1.0.0",
209+
"1.0.0",
210+
SortedSet("test-1"),
211+
SortedSet("test-1"),
212+
SortedSet.empty,
213+
SortedSet(ResolvedArtifact("package-1.jar", "hash-1")),
214+
SortedSet.empty
127215
))
128216
)
129217
}

src/test/scala/software/purpledragon/sbt/lock/model/LockFileStatusSpec.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,9 @@ class LockFileStatusSpec extends AnyFlatSpec with Matchers {
242242
name,
243243
oldVersion,
244244
newVersion,
245-
SortedSet.empty,
246-
SortedSet.empty,
247245
oldConfigurations,
248-
newConfigurations)
246+
newConfigurations,
247+
SortedSet.empty,
248+
SortedSet.empty)
249249
}
250250
}

0 commit comments

Comments
 (0)