org.ajoberstar.gradle.stutter.GenerateStutterLocks Maven / Gradle / Ivy
The newest version!
package org.ajoberstar.gradle.stutter;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.gradle.api.DefaultTask;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.SetProperty;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.util.GradleVersion;
public abstract class GenerateStutterLocks extends DefaultTask {
public GenerateStutterLocks() {
// this task should always be out of date
this.getOutputs().upToDateWhen(t -> false);
}
@TaskAction
public void generate() {
var allVersions = getAllVersions();
var lockFilePath = getOutputFile().getAsFile().get().toPath();
try (var writer = Files.newBufferedWriter(lockFilePath)) {
writer.write("# DO NOT MODIFY: Generated by Stutter plugin.");
writer.newLine();
for (var matrix : getMatrices().get()) {
var gradleVersions = matrix.getGradleVersions().resolve(allVersions, getSparse().get())
.sorted()
.distinct()
.map(GradleVersion::getVersion)
.collect(Collectors.joining(","));
writer.write(String.format("%s=%s", matrix.getName(), gradleVersions));
writer.newLine();
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private Set getAllVersions() {
try {
URL serviceUrl = new URL("https://services.gradle.org/versions/all");
JsonNode versions = new ObjectMapper().readValue(serviceUrl, JsonNode.class);
return StreamSupport.stream(versions.spliterator(), false)
// don't include broken versions
.filter(node -> !node.get("broken").asBoolean())
// include final versions, rcs, and milestones
.filter(node -> {
/*
* The API doesn't return a simple stage field that would make this simpler. Instead it has a bunch
* of properties that indicate different kinds of pre-releases, and if any new one is added, it
* could cause us to treat it as final if we rely on their presence (e.g. when releaseNightly was
* added). So, we're determining it's final on our own, then relying on specific fields for other
* pre-release stages we want to include. It's not as big a deal if one of those breaks.
*/
GradleVersion version = GradleVersion.version(node.get("version").asText());
boolean finalVersion = version.equals(version.getBaseVersion());
boolean rcVersion = !node.get("rcFor").asText().isEmpty();
boolean milestoneVersion = !node.get("milestoneFor").asText().isEmpty();
return finalVersion || rcVersion || milestoneVersion;
})
.map(node -> node.get("version").asText())
.map(GradleVersion::version)
.collect(Collectors.toSet());
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Services url is invalid.", e);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Internal
public abstract SetProperty getMatrices();
@Internal
public abstract Property getSparse();
@OutputFile
public abstract RegularFileProperty getOutputFile();
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy