Skip to content

Commit

Permalink
feat: Support relocated artifacts
Browse files Browse the repository at this point in the history
According to https://maven.apache.org/guides/mini/guide-relocation.html not all properties are required
  • Loading branch information
gastaldi authored Oct 22, 2024
1 parent 508c406 commit 15009ec
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import static org.junit.jupiter.api.Assertions.assertEquals;

class PomParserTest {

@Test
void parseSingle() throws Exception {
URL resource = getClass().getClassLoader().getResource("test-pom.xml");
MavenProject mavenProject = PomParser.createMavenProject(new File(resource.toURI()), Collections.emptySet());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.maven.model.License;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.Relocation;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.project.MavenProject;

Expand Down Expand Up @@ -153,101 +154,106 @@ public static void check(Logger log, MavenProject project, Configuration configu
} else if (fullModel.getVersion().contains("${")) {
errors.add("<version> contains an unresolved expression: " + fullModel.getVersion());
}

log.debug("Checking <name>");
if (isBlank(fullModel.getName())) {
String parentName = resolveParentName(project.getFile().getParentFile(), fullModel);
if (isBlank(parentName)) {
errors.add("<name> can not be blank.");
} else {
warnings.add("<name> is not defined in POM. Will use value from parent: " +
lineSeparator() + "\t" + parentName);
if (isRelocated(fullModel)) {
Relocation relocation = fullModel.getDistributionManagement().getRelocation();
if (isBlank(relocation.getGroupId()) && isBlank(relocation.getArtifactId()) && isBlank(relocation.getVersion())) {
errors.add("<distributionManagement>/<relocation> requires either <groupId>, <artifactId> or <version>.");
}
} else {
log.debug("Checking <name>");
if (isBlank(fullModel.getName())) {
String parentName = resolveParentName(project.getFile().getParentFile(), fullModel);
if (isBlank(parentName)) {
errors.add("<name> can not be blank.");
} else {
warnings.add("<name> is not defined in POM. Will use value from parent: " +
lineSeparator() + "\t" + parentName);
}
}
}

log.debug("Checking <description>");
if (isBlank(fullModel.getDescription())) {
errors.add("<description> can not be blank.");
}
if (isBlank(originalModel.getDescription())) {
warnings.add("<description> is not defined in POM. Will use value from parent: " +
lineSeparator() + "\t" + fullModel.getDescription());
}
log.debug("Checking <description>");
if (isBlank(fullModel.getDescription())) {
errors.add("<description> can not be blank.");
}
if (isBlank(originalModel.getDescription())) {
warnings.add("<description> is not defined in POM. Will use value from parent: " +
lineSeparator() + "\t" + fullModel.getDescription());
}

log.debug("Checking <url>");
if (isBlank(fullModel.getUrl())) {
errors.add("<url> can not be blank.");
}
if (isBlank(originalModel.getUrl())) {
warnings.add("<url> is not defined in POM. Will use computed value from parent: " +
lineSeparator() + "\t" + fullModel.getUrl());
}
log.debug("Checking <url>");
if (isBlank(fullModel.getUrl())) {
errors.add("<url> can not be blank.");
}
if (isBlank(originalModel.getUrl())) {
warnings.add("<url> is not defined in POM. Will use computed value from parent: " +
lineSeparator() + "\t" + fullModel.getUrl());
}

if (configuration.isRelease()) log.debug("Checking if version is not snapshot");
if (configuration.isRelease() && fullModel.getVersion().endsWith("-SNAPSHOT")) {
errors.add("<version> can not be -SNAPSHOT.");
}
if (configuration.isRelease()) log.debug("Checking if version is not snapshot");
if (configuration.isRelease() && fullModel.getVersion().endsWith("-SNAPSHOT")) {
errors.add("<version> can not be -SNAPSHOT.");
}

log.debug("Checking <licenses>");
if (fullModel.getLicenses() != null) {
if (!fullModel.getLicenses().isEmpty()) {
// verify that all licenses have <name> & <url>
for (int i = 0; i < fullModel.getLicenses().size(); i++) {
License license = fullModel.getLicenses().get(i);
if (isBlank(license.getName()) && isBlank(license.getUrl())) {
errors.add("License " + i + " must define <name> and <url>.");
log.debug("Checking <licenses>");
if (fullModel.getLicenses() != null) {
if (!fullModel.getLicenses().isEmpty()) {
// verify that all licenses have <name> & <url>
for (int i = 0; i < fullModel.getLicenses().size(); i++) {
License license = fullModel.getLicenses().get(i);
if (isBlank(license.getName()) && isBlank(license.getUrl())) {
errors.add("License " + i + " must define <name> and <url>.");
}
}
} else {
errors.add("<licenses> block is required but was left empty.");
}
} else {
errors.add("<licenses> block is required but was left empty.");
errors.add("<licenses> block is required but was left undefined.");
}
} else {
errors.add("<licenses> block is required but was left undefined.");
}

log.debug("Checking <developers>");
if (fullModel.getDevelopers() != null) {
if (!fullModel.getDevelopers().isEmpty()) {
// verify that all developers have at least one of [id, name, organization, organizationUrl]
for (int i = 0; i < fullModel.getDevelopers().size(); i++) {
Developer developer = fullModel.getDevelopers().get(i);
if (isBlank(developer.getId()) &&
isBlank(developer.getName()) &&
isBlank(developer.getOrganization()) &&
isBlank(developer.getOrganizationUrl())) {
errors.add("Developer " + i + " must define at least one of <id>, <name>, <organization>, <organizationUrl>.");
log.debug("Checking <developers>");
if (fullModel.getDevelopers() != null) {
if (!fullModel.getDevelopers().isEmpty()) {
// verify that all developers have at least one of [id, name, organization, organizationUrl]
for (int i = 0; i < fullModel.getDevelopers().size(); i++) {
Developer developer = fullModel.getDevelopers().get(i);
if (isBlank(developer.getId()) &&
isBlank(developer.getName()) &&
isBlank(developer.getOrganization()) &&
isBlank(developer.getOrganizationUrl())) {
errors.add("Developer " + i + " must define at least one of <id>, <name>, <organization>, <organizationUrl>.");
}
}
} else {
errors.add("<developers> block is required but was left empty.");
}
} else {
errors.add("<developers> block is required but was left empty.");
errors.add("<developers> block is required but was left undefined.");
}
} else {
errors.add("<developers> block is required but was left undefined.");
}

log.debug("Checking <scm>");
if (fullModel.getScm() == null) {
errors.add("The <scm> block is required.");
}
log.debug("Checking <scm>");
if (fullModel.getScm() == null) {
errors.add("The <scm> block is required.");
}

log.debug("Checking <repositories>");
if (null != originalModel.getRepositories() && !originalModel.getRepositories().isEmpty()) {
if (configuration.isStrict()) {
errors.add("The <repositories> block should not be present.");
} else {
warnings.add("The <repositories> block should not be present.");
log.debug("Checking <repositories>");
if (null != originalModel.getRepositories() && !originalModel.getRepositories().isEmpty()) {
if (configuration.isStrict()) {
errors.add("The <repositories> block should not be present.");
} else {
warnings.add("The <repositories> block should not be present.");
}
}
}

log.debug("Checking <pluginRepositories>");
if (null != originalModel.getPluginRepositories() && !originalModel.getPluginRepositories().isEmpty()) {
if (configuration.isStrict()) {
errors.add("The <pluginRepositories> block should not be present.");
} else {
warnings.add("The <pluginRepositories> block should not be present.");
log.debug("Checking <pluginRepositories>");
if (null != originalModel.getPluginRepositories() && !originalModel.getPluginRepositories().isEmpty()) {
if (configuration.isStrict()) {
errors.add("The <pluginRepositories> block should not be present.");
} else {
warnings.add("The <pluginRepositories> block should not be present.");
}
}
}

if (!warnings.isEmpty()) {
if (configuration.isFailOnWarning()) {
throw new PomCheckException(String.join(lineSeparator(), warnings));
Expand All @@ -258,12 +264,12 @@ public static void check(Logger log, MavenProject project, Configuration configu

if (!errors.isEmpty()) {
StringBuilder b = new StringBuilder(lineSeparator())
.append("The POM file")
.append(lineSeparator())
.append(project.getFile().getAbsolutePath())
.append(lineSeparator())
.append("cannot be uploaded to Maven Central due to the following reasons:")
.append(lineSeparator());
.append("The POM file")
.append(lineSeparator())
.append(project.getFile().getAbsolutePath())
.append(lineSeparator())
.append("cannot be uploaded to Maven Central due to the following reasons:")
.append(lineSeparator());
for (String s : errors) {
b.append(" * ").append(s).append(lineSeparator());
}
Expand All @@ -278,6 +284,16 @@ public static void check(Logger log, MavenProject project, Configuration configu
}
}

/**
* Checks if the model has been relocated.
*
* @param model the model to check
* @return {@code true} if the model has been relocated.
*/
private static boolean isRelocated(Model model) {
return model.getDistributionManagement() != null && model.getDistributionManagement().getRelocation() != null;
}

private static String resolveParentName(File directory, Model fullModel) {
Parent parent = fullModel.getParent();

Expand Down

0 comments on commit 15009ec

Please sign in to comment.