@@ -16,63 +16,77 @@ package com.google.firebase.gradle.plugins
16
16
17
17
import java.io.File
18
18
import java.net.URL
19
- import javax.xml.parsers.DocumentBuilder
20
19
import javax.xml.parsers.DocumentBuilderFactory
21
20
import org.gradle.api.DefaultTask
22
21
import org.gradle.api.GradleException
23
22
import org.gradle.api.provider.Property
24
23
import org.gradle.api.tasks.Input
25
24
import org.gradle.api.tasks.InputFile
26
25
import org.gradle.api.tasks.TaskAction
27
- import org.w3c.dom.Document
28
26
import org.w3c.dom.Element
29
- import org.w3c.dom.Node
30
- import org.w3c.dom.NodeList
31
27
28
+ /* *
29
+ * Ensures that pom dependencies are not accidently downgraded.
30
+ *
31
+ * Compares the latest pom at gmaven for the given artifact with the one generate for the current
32
+ * release.
33
+ *
34
+ * @throws GradleException if a dependency is found with a degraded version
35
+ *
36
+ * @property pomFile The pom file for the current release
37
+ * @property artifactId The artifactId for the pom parent
38
+ * @property groupId The groupId for the pom parent
39
+ */
32
40
abstract class PomValidator : DefaultTask () {
33
- @get:InputFile abstract val pomFilePath : Property <File >
41
+ @get:InputFile abstract val pomFile : Property <File >
34
42
@get:Input abstract val artifactId: Property <String >
35
43
@get:Input abstract val groupId: Property <String >
36
44
37
45
@TaskAction
38
46
fun run () {
39
- val gMavenHelper = GmavenHelper (groupId.get(), artifactId.get())
40
- val latestReleasedVersion = gMavenHelper.getLatestReleasedVersion()
41
- val releasedVersionPomUrl = gMavenHelper.getPomFileForVersion(latestReleasedVersion)
42
- var output: String = diffWithPomFileUrl(releasedVersionPomUrl).trim()
43
- if (output.isNotEmpty()) {
44
- throw GradleException (" ${output} \n Please fix the above errors" )
47
+ var diff = diffWithPomFromURL(getLatestReleasePomUrl())
48
+
49
+ if (diff.isNotEmpty()) {
50
+ throw GradleException (" Dependency version errors found:\n ${diff} " )
45
51
}
46
52
}
47
53
48
- fun getMapFromXml (pomNodeList : NodeList ): Map <String , String > {
49
- val pomMap = mutableMapOf<String , String >()
50
- for (i in 0 .. pomNodeList.length - 1 ) {
51
- val node: Node = pomNodeList.item(i)
52
- if (node.getNodeType() == Node .ELEMENT_NODE ) {
53
- val element = node as Element
54
- val artifact = element.getElementsByTagName(" artifactId" ).item(0 ).getTextContent()
55
- val version = element.getElementsByTagName(" version" ).item(0 ).getTextContent()
56
- pomMap[artifact] = version
57
- }
54
+ private fun getLatestReleasePomUrl () =
55
+ with (GmavenHelper (groupId.get(), artifactId.get())) {
56
+ getPomFileForVersion(getLatestReleasedVersion())
58
57
}
59
- return pomMap
60
- }
61
58
62
- fun diffWithPomFileUrl (pomUrl : String ): String {
63
- val factory: DocumentBuilderFactory = DocumentBuilderFactory .newInstance()
64
- val oldPomBuilder: DocumentBuilder = factory.newDocumentBuilder()
65
- val oldPomDoc: Document = oldPomBuilder.parse(URL (pomUrl).openStream())
66
- val currentPomBuilder: DocumentBuilder = factory.newDocumentBuilder()
67
- val currentPomDoc: Document = currentPomBuilder.parse(pomFilePath.get())
68
- val oldPomMap = getMapFromXml(oldPomDoc.getElementsByTagName(" dependency" ))
69
- val currentPomMap = getMapFromXml(currentPomDoc.getElementsByTagName(" dependency" ))
59
+ private fun getMapOfDependencies (doc : Element ) =
60
+ doc
61
+ .findElementsByTag(" dependency" )
62
+ .associate { it.textByTag(" artifactId" ) to it.textByTag(" version" ) }
63
+ .filter { it.key != " javax.inject" } // javax.inject doesn't respect SemVer and doesn't update
64
+ .mapValues {
65
+ ModuleVersion .fromStringOrNull(it.value)
66
+ ? : throw RuntimeException (" Invalid module version found for '${it.key} ': ${it.value} " )
67
+ }
68
+
69
+ data class DependencyDiff (
70
+ val artifactId : String ,
71
+ val oldVersion : ModuleVersion ,
72
+ val currentVersion : ModuleVersion
73
+ )
74
+
75
+ fun diffWithPomFromURL (url : String ): String {
76
+ val documentBuilder = DocumentBuilderFactory .newInstance().newDocumentBuilder()
77
+
78
+ val oldPom = documentBuilder.parse(URL (url).openStream())
79
+ val currentPom = documentBuilder.parse(pomFile.get())
80
+
81
+ val oldDependencies = getMapOfDependencies(oldPom.documentElement)
82
+ val currentDependencies = getMapOfDependencies(currentPom.documentElement)
70
83
71
- return currentPomMap
72
- .filter {
73
- (oldPomMap.get(it.key) != null ) && (oldPomMap.get(it.key)!! .trim()) > it.value.trim()
84
+ return currentDependencies
85
+ .map { DependencyDiff (it.key, oldDependencies.getOrDefault(it.key, it.value), it.value) }
86
+ .filter { it.oldVersion > it.currentVersion }
87
+ .map {
88
+ " Dependency on ${it.artifactId} has been degraded from ${it.oldVersion} to ${it.currentVersion} "
74
89
}
75
- .map { " Artifacts ${it.key} has been degraded to ${it.value} from ${oldPomMap.get(it.key)} " }
76
90
.joinToString(" \n " )
77
91
}
78
92
}
0 commit comments