All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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