Skip to content

Commit

Permalink
Add project based libyear Mojo (#34)
Browse files Browse the repository at this point in the history
and some other fixes
  • Loading branch information
cstamas authored May 15, 2024
1 parent abb0204 commit 7498c1e
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 68 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2023-2024 Maveniverse Org.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*/
package eu.maveniverse.maven.toolbox.shared;

import java.util.List;
import java.util.function.BiFunction;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.version.Version;

/**
* Selector that selects artifact version.
*/
public interface ArtifactVersionSelector extends BiFunction<Artifact, List<Version>, String> {
/**
* Selector that returns artifact version.
*/
static ArtifactVersionSelector identity() {
return new ArtifactVersionSelector() {
@Override
public String apply(Artifact artifact, List<Version> versions) {
return artifact.getVersion();
}
};
}

/**
* Selector that return plan last version.
*/
static ArtifactVersionSelector last() {
return new ArtifactVersionSelector() {
@Override
public String apply(Artifact artifact, List<Version> versions) {
return versions.isEmpty()
? identity().apply(artifact, versions)
: versions.get(versions.size() - 1).toString();
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeSet;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.BiFunction;
import org.apache.maven.search.api.SearchBackend;
import org.apache.maven.search.api.SearchRequest;
Expand Down Expand Up @@ -86,7 +84,7 @@ public static LibYearSink libYear(
ToolboxSearchApiImpl toolboxSearchApi,
boolean quiet,
boolean allowSnapshots,
BiFunction<Artifact, List<Version>, Version> versionSelector) {
BiFunction<Artifact, List<Version>, String> versionSelector) {
return new LibYearSink(
output, context, toolboxResolver, toolboxSearchApi, quiet, allowSnapshots, versionSelector);
}
Expand All @@ -97,8 +95,8 @@ public static LibYearSink libYear(
private final ToolboxSearchApiImpl toolboxSearchApi;
private final boolean quiet;
private final boolean allowSnapshots;
private final BiFunction<Artifact, List<Version>, Version> versionSelector;
private final ConcurrentMap<Artifact, LibYear> libYear;
private final BiFunction<Artifact, List<Version>, String> versionSelector;
private final CopyOnWriteArraySet<Artifact> artifacts;

private LibYearSink(
Output output,
Expand All @@ -107,34 +105,35 @@ private LibYearSink(
ToolboxSearchApiImpl toolboxSearchApi,
boolean quiet,
boolean allowSnapshots,
BiFunction<Artifact, List<Version>, Version> versionSelector) {
BiFunction<Artifact, List<Version>, String> versionSelector) {
this.output = requireNonNull(output, "output");
this.context = requireNonNull(context, "context");
this.toolboxResolver = requireNonNull(toolboxResolver, "toolboxResolver");
this.toolboxSearchApi = requireNonNull(toolboxSearchApi, "toolboxSearchApi");
this.quiet = quiet;
this.allowSnapshots = allowSnapshots;
this.versionSelector = requireNonNull(versionSelector);
this.libYear = new ConcurrentHashMap<>();
this.artifacts = new CopyOnWriteArraySet<>();
}

public Map<Artifact, LibYear> getLibYear() {
return libYear;
@SuppressWarnings("unchecked")
public ConcurrentMap<Artifact, LibYear> getLibYear() {
return (ConcurrentMap<Artifact, LibYear>)
context.repositorySystemSession().getData().computeIfAbsent(LibYear.class, ConcurrentHashMap::new);
}

@Override
public void accept(Artifact artifact) throws IOException {
requireNonNull(artifact, "artifact");
libYear.computeIfAbsent(artifact, a -> {
getLibYear().computeIfAbsent(artifact, a -> {
String currentVersion = artifact.getVersion();
Instant currentVersionInstant = null;
String latestVersion = currentVersion;
Instant latestVersionInstant = null;
try {
currentVersionInstant = artifactPublishDate(artifact);
latestVersion = versionSelector
.apply(artifact, toolboxResolver.findNewerVersions(artifact, allowSnapshots))
.toString();
latestVersion =
versionSelector.apply(artifact, toolboxResolver.findNewerVersions(artifact, allowSnapshots));
latestVersionInstant = artifactPublishDate(artifact.setVersion(latestVersion));
} catch (VersionRangeResolutionException e) {
// ignore
Expand All @@ -143,30 +142,31 @@ public void accept(Artifact artifact) throws IOException {
}
return new LibYear(currentVersion, currentVersionInstant, latestVersion, latestVersionInstant);
});
artifacts.add(artifact);
}

@Override
public void close() throws DeploymentException {
float totalLibYears = 0;
int totalLibOutdated = 0;
TreeSet<String> timedOnes = new TreeSet<>(Collections.reverseOrder());
TreeMap<Float, List<String>> timedOnes = new TreeMap<>(Collections.reverseOrder());
TreeSet<String> outdated = new TreeSet<>();
if (!quiet) {
for (Map.Entry<Artifact, LibYear> entry : getLibYear().entrySet()) {
if (entry.getValue() != null) {
LibYear value = entry.getValue();
if (Objects.equals(value.getCurrentVersion(), value.getLatestVersion())) {
for (Artifact artifact : artifacts) {
LibYear libYear = getLibYear().get(artifact);
if (libYear != null) {
if (Objects.equals(libYear.getCurrentVersion(), libYear.getLatestVersion())) {
continue;
}
totalLibOutdated++;

LocalDate currentVersionDate = value.getCurrentVersionInstant() != null
? value.getCurrentVersionInstant()
LocalDate currentVersionDate = libYear.getCurrentVersionInstant() != null
? libYear.getCurrentVersionInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate()
: null;
LocalDate latestVersionDate = value.getLatestVersionInstant() != null
? value.getLatestVersionInstant()
LocalDate latestVersionDate = libYear.getLatestVersionInstant() != null
? libYear.getLatestVersionInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate()
: null;
Expand All @@ -175,30 +175,36 @@ public void close() throws DeploymentException {
long libWeeksOutdated = ChronoUnit.WEEKS.between(currentVersionDate, latestVersionDate);
float libYearsOutdated = libWeeksOutdated / 52f;
totalLibYears += libYearsOutdated;
timedOnes.add(String.format(
"%.2f years from %s %s (%s) => %s (%s)",
libYearsOutdated,
ArtifactIdUtils.toVersionlessId(entry.getKey()),
value.getCurrentVersion(),
currentVersionDate,
value.getLatestVersion(),
latestVersionDate));
timedOnes
.computeIfAbsent(libYearsOutdated, k -> new CopyOnWriteArrayList<>())
.add(String.format(
"%.2f years from %s %s (%s) => %s (%s)",
libYearsOutdated,
ArtifactIdUtils.toVersionlessId(artifact),
libYear.getCurrentVersion(),
currentVersionDate,
libYear.getLatestVersion(),
latestVersionDate));
} else {
outdated.add(String.format(
"%s %s (?) => %s (?)",
ArtifactIdUtils.toVersionlessId(entry.getKey()),
value.getCurrentVersion(),
value.getLatestVersion()));
ArtifactIdUtils.toVersionlessId(artifact),
libYear.getCurrentVersion(),
libYear.getLatestVersion()));
}
}
}
}

String indent = "";
output.normal("{}Outdated versions with known age", indent);
timedOnes.forEach(l -> output.normal("{}{}", indent, l));
if (!timedOnes.isEmpty()) {
output.normal("{}Outdated versions with known age", indent);
}
timedOnes.values().stream().flatMap(Collection::stream).forEach(l -> output.normal("{}{}", indent, l));
output.normal("{}", indent);
output.normal("{}Outdated versions", indent);
if (!outdated.isEmpty()) {
output.normal("{}Outdated versions", indent);
}
outdated.forEach(l -> output.normal("{}{}", indent, l));
output.normal("{}", indent);
output.normal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import eu.maveniverse.maven.toolbox.shared.ArtifactMatcher;
import eu.maveniverse.maven.toolbox.shared.ArtifactNameMapper;
import eu.maveniverse.maven.toolbox.shared.ArtifactSink;
import eu.maveniverse.maven.toolbox.shared.ArtifactVersionSelector;
import eu.maveniverse.maven.toolbox.shared.DependencyMatcher;
import eu.maveniverse.maven.toolbox.shared.Output;
import eu.maveniverse.maven.toolbox.shared.ResolutionRoot;
Expand Down Expand Up @@ -543,9 +544,16 @@ private boolean doResolveTransitive(
resolutionRoot.getManagedDependencies());
List<ArtifactResult> adjustedResults = resolutionRoot.isLoad()
? dependencyResult.getArtifactResults()
: dependencyResult
.getArtifactResults()
.subList(1, dependencyResult.getArtifactResults().size() - 1);
: (dependencyResult.getArtifactResults().size() == 1
? Collections.emptyList()
: dependencyResult
.getArtifactResults()
.subList(
1,
dependencyResult
.getArtifactResults()
.size()
- 1));
artifactSink.accept(
adjustedResults.stream().map(ArtifactResult::getArtifact).collect(Collectors.toList()));

Expand Down Expand Up @@ -802,24 +810,26 @@ public boolean libYear(
boolean allowSnapshots,
Output output)
throws Exception {
for (ResolutionRoot resolutionRoot : resolutionRoots) {
doResolveTransitive(
resolutionScope,
resolutionRoot,
false,
false,
false,
LibYearSink.libYear(
output,
context,
toolboxResolver,
toolboxSearchApi,
quiet,
allowSnapshots,
(a, l) -> l.get(l.size() - 1)),
output);
try (ArtifactSink sink = LibYearSink.libYear(
output,
context,
toolboxResolver,
toolboxSearchApi,
quiet,
allowSnapshots,
ArtifactVersionSelector.last())) {
for (ResolutionRoot resolutionRoot : resolutionRoots) {
doResolveTransitive(
resolutionScope,
resolutionRoot,
false,
false,
false,
ArtifactSinks.nonClosingArtifactSink(sink),
output);
}
}
return !resolutionRoots.isEmpty();
return true;
}

// Utils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import eu.maveniverse.maven.toolbox.shared.ResolutionRoot;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.maven.RepositoryUtils;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
Expand Down Expand Up @@ -55,4 +56,14 @@ protected ResolutionRoot projectAsResolutionRoot() {
}
return builder.build();
}

protected boolean isReactorDependency(Dependency dependency) {
return mavenSession.getAllProjects().stream()
.anyMatch(p -> Objects.equals(
p.getGroupId(), dependency.getArtifact().getGroupId())
&& Objects.equals(
p.getArtifactId(), dependency.getArtifact().getArtifactId())
&& Objects.equals(
p.getVersion(), dependency.getArtifact().getVersion()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,31 @@ public class GavLibYearMojo extends GavSearchMojoSupport {
@Parameter(property = "boms")
private String boms;

/**
* Make libyear quiet.
*/
@CommandLine.Option(
names = {"--quiet"},
description = "Make command quiet")
@Parameter(property = "quiet", defaultValue = "false")
private boolean quiet;

/**
* Make libyear allow to take into account snapshots.
*/
@CommandLine.Option(
names = {"--allowSnapshots"},
description = "Make libyear allow to take into account snapshots")
@Parameter(property = "allowSnapshots", defaultValue = "false")
private boolean allowSnapshots;

@Override
protected boolean doExecute(Output output, ToolboxCommando toolboxCommando) throws Exception {
return toolboxCommando.libYear(
ResolutionScope.parse(scope), toolboxCommando.loadGavs(slurp(gav), slurp(boms)), false, false, output);
ResolutionScope.parse(scope),
toolboxCommando.loadGavs(slurp(gav), slurp(boms)),
quiet,
allowSnapshots,
output);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public final class CopyMojo extends MPMojoSupport {
/**
* The dependency matcher spec.
*/
@Parameter(property = "depSpec", required = true)
@Parameter(property = "depSpec", defaultValue = "any()")
private String depSpec;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public final class CopyTransitiveMojo extends MPMojoSupport {
/**
* The dependency matcher spec.
*/
@Parameter(property = "depSpec", required = true)
@Parameter(property = "depSpec", defaultValue = "any()")
private String depSpec;

@Override
Expand Down
Loading

0 comments on commit 7498c1e

Please sign in to comment.