Skip to content

Commit e3d70a2

Browse files
author
Sergey Mashkov
committed
Introduce artifacts verifier verifyPublications task
1 parent 88adead commit e3d70a2

File tree

3 files changed

+164
-0
lines changed

3 files changed

+164
-0
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ allprojects {
5353
apply from: rootProject.file("gradle/native.gradle")
5454

5555
apply from: rootProject.file("gradle/publish.gradle")
56+
apply from: rootProject.file('gradle/verifier.gradle')
5657
}
5758

5859
kotlin {

gradle/publish.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ task stubJavadoc(type: Jar) {
1818
publishing {
1919
repositories {
2020
maven { url = 'https://kotlin.bintray.com/kotlinx' }
21+
maven { name = "testLocal"; url = "$rootProject.buildDir/m2"}
2122
}
2223
publications.all {
2324
pom.withXml(configureMavenCentralMetadata)

gradle/verifier.gradle

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
import groovy.io.FileType
2+
import groovy.json.JsonSlurper
3+
import org.xml.sax.ErrorHandler
4+
import org.xml.sax.SAXException
5+
import org.xml.sax.SAXParseException
6+
7+
task cleanPublications(type: Delete) {
8+
delete new File(rootProject.buildDir, 'm2')
9+
}
10+
11+
def isBadTextNode(node) {
12+
return node == null || node.size() != 1 || !node.text().trim()
13+
}
14+
15+
def isEmptyTagList(node) {
16+
return node == null || node.size() == 0
17+
}
18+
19+
def verifyArtifact(File versionDir, List<File> files, String ext) {
20+
if (files.count { it.name.toLowerCase().endsWith(ext) } == 0) {
21+
throw new GradleException("No $ext artifact found at $versionDir")
22+
}
23+
}
24+
25+
def validatePom(File file) {
26+
def parser = new XmlSlurper(false, true, false)
27+
def errors = []
28+
29+
parser.errorHandler = new ErrorHandler() {
30+
31+
@Override
32+
void warning(SAXParseException exception) throws SAXException {
33+
}
34+
35+
@Override
36+
void error(SAXParseException exception) throws SAXException {
37+
errors += exception
38+
}
39+
40+
@Override
41+
void fatalError(SAXParseException exception) throws SAXException {
42+
errors += exception
43+
}
44+
}
45+
46+
def xml = parser.parse(file)
47+
48+
if (!errors.isEmpty()) {
49+
throw errors[0]
50+
}
51+
52+
if (isBadTextNode(xml.name)) {
53+
errors += ['<name> tag is missing']
54+
}
55+
56+
if (isBadTextNode(xml.description)) {
57+
errors += ['<description> tag is missing']
58+
}
59+
60+
if (isBadTextNode(xml.url)) {
61+
errors += ['<url> tag is missing']
62+
}
63+
64+
def licenses = xml.licenses.license
65+
if (isEmptyTagList(licenses)) {
66+
errors += 'No licenses specified'
67+
} else if (licenses.any { isBadTextNode(it.name) || isBadTextNode(it.url) || isBadTextNode(it.distribution) }) {
68+
errors += 'License section is incomplete'
69+
}
70+
71+
def developers = xml.developers.developer
72+
if (isEmptyTagList(developers)) {
73+
errors += 'No developers specified'
74+
} else if (developers.any { isBadTextNode(it.id) || isBadTextNode(it.name) || isBadTextNode(it.organization) || isBadTextNode(it.organizationUrl)}) {
75+
errors += 'Developer section is incomplete'
76+
}
77+
78+
def scm = xml.scm.url
79+
if (isEmptyTagList(scm)) {
80+
errors += 'No scm specified'
81+
}
82+
83+
if (!errors.isEmpty()) {
84+
throw new GradleException("Pom verification failed for $file.name: ${errors.join(', ')}")
85+
}
86+
}
87+
88+
String packaging(File moduleDir) {
89+
def pomFile = moduleDir.listFiles()?.find { it.name.endsWith('.pom') }
90+
if (pomFile == null || !pomFile.exists()) {
91+
throw new GradleException("POM file is missing at $moduleDir")
92+
}
93+
94+
def packaing = new XmlSlurper(false, true, false).parse(pomFile).packaging.text()
95+
if (!packaing?.trim()) return 'jar'
96+
return packaing
97+
}
98+
99+
def kinds = kotlin.targets.collect { it.name }
100+
101+
task verifyPublications(dependsOn: { [cleanPublications] + kinds.collect { "publish${it.capitalize()}PublicationToTestLocalRepository" } }) {
102+
doLast {
103+
def m2 = new File(rootProject.buildDir, 'm2')
104+
def pomFiles = []
105+
def moduleFiles = []
106+
107+
m2.eachFileRecurse(FileType.FILES) { child ->
108+
if (child.name.toLowerCase() != 'maven-metadata.xml') {
109+
def ext = child.name.split(/\./).last().toLowerCase()
110+
switch (ext) {
111+
case 'pom':
112+
pomFiles += child
113+
break
114+
case 'module':
115+
moduleFiles += child
116+
break
117+
}
118+
}
119+
}
120+
121+
pomFiles.each { File file ->
122+
validatePom(file)
123+
}
124+
125+
def groupDir = new File(m2, project.group.replaceAll(/\./, File.separator))
126+
def verified = 0
127+
128+
groupDir.eachDir { artifactDir ->
129+
def versionDir = new File(artifactDir, project.version)
130+
131+
if (versionDir.exists()) {
132+
def files = versionDir.listFiles()?.findAll { it.isFile() } ?: []
133+
134+
def packaging = '.' + packaging(versionDir)
135+
verifyArtifact(versionDir, files, packaging)
136+
verifyArtifact(versionDir, files, '-javadoc.jar')
137+
verifyArtifact(versionDir, files, '-sources.jar')
138+
verifyArtifact(versionDir, files, '.module')
139+
140+
verified ++
141+
}
142+
}
143+
144+
if (verified == 0) {
145+
throw new GradleException("No installed modules were found at $groupDir")
146+
}
147+
148+
moduleFiles.each { File file ->
149+
def moduleFile = new JsonSlurper().parse(file)
150+
151+
if (moduleFile.variants.name.isEmpty()) {
152+
throw new GradleException("No variants found in module file $file")
153+
}
154+
}
155+
}
156+
}
157+
158+
tasks.whenTaskAdded { task ->
159+
if (task.name.startsWith('publish') && task.name.endsWith('TestLocalRepository')) {
160+
tasks.getByName('verifyPublications').dependsOn(task)
161+
}
162+
}

0 commit comments

Comments
 (0)