Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ buildscript {
classpath 'com.palantir.jakartapackagealignment:jakarta-package-alignment:0.6.0'
classpath 'com.palantir.gradle.externalpublish:gradle-external-publish-plugin:1.11.0'
classpath 'com.palantir.javaformat:gradle-palantir-java-format:2.47.0'
classpath 'com.palantir.gradle.plugintesting:gradle-plugin-testing:0.10.0'
}
}

Expand All @@ -33,6 +34,7 @@ apply plugin: 'java-gradle-plugin'
apply plugin: 'java-library'
apply plugin: 'groovy'
apply plugin: 'com.palantir.external-publish-jar'
apply plugin: 'com.palantir.gradle-plugin-testing'

sourceCompatibility = 1.8

Expand All @@ -48,10 +50,12 @@ dependencies {

testImplementation platform('org.junit:junit-bom')
testImplementation 'com.netflix.nebula:nebula-test'
testImplementation "org.junit.jupiter:junit-jupiter"
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.assertj:assertj-core'
testRuntimeOnly "org.junit.vintage:junit-vintage-engine"
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-engine'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine'

annotationProcessor "org.immutables:value"
annotationProcessor "org.immutables:serial"
Expand All @@ -68,6 +72,7 @@ test {
environment = System.getenv().entrySet().stream()
.filter { entry -> entry.key != 'CIRCLE_TEST_REPORTS' }
.collect(Collectors.toMap({ it.key }, { it.value }))
systemProperty 'ignoreDeprecations', 'true'
}

gradlePlugin {
Expand Down
9 changes: 2 additions & 7 deletions src/main/java/org/revapi/gradle/ConjureProjectFilters.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import com.fasterxml.jackson.databind.node.ArrayNode;
import java.util.Optional;
import org.gradle.api.Project;

final class ConjureProjectFilters {
private static final ArrayNode CHECKS_FOR_CLIENT_PROJECTS = RevapiConfig.createArrayNode()
Expand All @@ -29,16 +28,12 @@ final class ConjureProjectFilters {

private ConjureProjectFilters() {}

public static RevapiConfig forProject(Project project) {
boolean isConjure = Optional.ofNullable(project.getParent())
.map(parentProject -> parentProject.getPluginManager().hasPlugin("com.palantir.conjure"))
.orElse(false);

public static RevapiConfig from(String projectName, boolean isConjure) {
if (!isConjure) {
return RevapiConfig.empty();
}

return checksForProjectName(project.getName())
return checksForProjectName(projectName)
.map(checks -> RevapiConfig.empty().withExtension(CheckWhitelist.EXTENSION_ID, checks))
.orElseGet(RevapiConfig::empty);
}
Expand Down
88 changes: 54 additions & 34 deletions src/main/java/org/revapi/gradle/GitVersionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,54 @@

package org.revapi.gradle;

import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.gradle.api.Project;
import javax.inject.Inject;
import org.gradle.api.file.Directory;
import org.gradle.api.file.ProjectLayout;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.process.ExecOutput;
import org.gradle.process.ExecResult;
import org.immutables.value.Value;

final class GitVersionUtils {
private GitVersionUtils() {}
public abstract class GitVersionUtils {

public static Stream<String> previousGitTags(Project project) {
return StreamSupport.stream(new PreviousGitTags(project), false)
.filter(tag -> !isInitial000Tag(project, tag))
@Inject
protected abstract ProviderFactory getProviderFactory();

@Inject
protected abstract ProjectLayout getProjectLayout();

public final Stream<String> previousGitTags() {
return StreamSupport.stream(
new PreviousGitTags(
getProviderFactory(), getProjectLayout().getProjectDirectory()),
false)
.filter(tag -> !isInitial000Tag(
getProviderFactory(), getProjectLayout().getProjectDirectory(), tag))
.map(GitVersionUtils::stripVFromTag);
}

private static Optional<String> previousGitTagFromRef(Project project, String ref) {
private static Optional<String> previousGitTagFromRef(
ProviderFactory providerFactory, Directory directory, String ref) {
String beforeLastRef = ref + "^";

GitResult beforeLastRefTypeResult = execute(project, "git", "cat-file", "-t", beforeLastRef);
GitResult beforeLastRefTypeResult = execute(providerFactory, directory, "git", "cat-file", "-t", beforeLastRef)
.get();

boolean thereIsNoCommitBeforeTheRef = !beforeLastRefTypeResult.stdout().equals("commit");
if (thereIsNoCommitBeforeTheRef) {
return Optional.empty();
}

GitResult describeResult = execute(project, "git", "describe", "--tags", "--abbrev=0", beforeLastRef);
GitResult describeResult = execute(
providerFactory, directory, "git", "describe", "--tags", "--abbrev=0", beforeLastRef)
.get();

if (describeResult.stderr().contains("No tags can describe")
|| describeResult.stderr().contains("No names found, cannot describe anything")) {
Expand All @@ -58,14 +73,15 @@ private static Optional<String> previousGitTagFromRef(Project project, String re
return Optional.of(describeResult.stdoutOrThrowIfNonZero());
}

private static boolean isInitial000Tag(Project project, String tag) {
private static boolean isInitial000Tag(ProviderFactory providerFactory, Directory directory, String tag) {
if (!tag.equals("0.0.0")) {
return false;
}

GitResult foo = execute(project, "git", "rev-parse", "--verify", "--quiet", "0.0.0^");
boolean parentDoesNotExist = foo.exitCode() != 0;
return parentDoesNotExist;
return execute(providerFactory, directory, "git", "rev-parse", "--verify", "--quiet", "0.0.0^")
.get()
.exitCode()
!= 0;
}

private static String stripVFromTag(String tag) {
Expand All @@ -76,22 +92,24 @@ private static String stripVFromTag(String tag) {
}
}

private static GitResult execute(Project project, String... command) {
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();

ExecResult execResult = project.exec(spec -> {
spec.setCommandLine(Arrays.asList(command));
spec.setStandardOutput(stdout);
spec.setErrorOutput(stderr);
spec.setIgnoreExitValue(true);
private static Provider<GitResult> execute(
ProviderFactory providerFactory, Directory directory, String... command) {
ExecOutput output = providerFactory.exec(execSpec -> {
execSpec.commandLine((Object[]) command);
execSpec.setIgnoreExitValue(true);
execSpec.setWorkingDir(directory);
});

return GitResult.builder()
.exitCode(execResult.getExitValue())
.stdout(new String(stdout.toByteArray(), StandardCharsets.UTF_8).trim())
.stderr(new String(stderr.toByteArray(), StandardCharsets.UTF_8).trim())
.build();
Provider<String> stdout = output.getStandardOutput().getAsText();
Provider<String> stderr = output.getStandardError().getAsText();
Provider<ExecResult> result = output.getResult();

return stdout.zip(stderr, (out, err) -> new Object[] {out, err})
.zip(result, (outErr, res) -> GitResult.builder()
.exitCode(res.getExitValue())
.stdout(((String) outErr[0]).trim())
.stderr(((String) outErr[1]).trim())
.build());
}

@Value.Immutable
Expand Down Expand Up @@ -124,16 +142,18 @@ static Builder builder() {
}

private static final class PreviousGitTags implements Spliterator<String> {
private final Project project;
private final ProviderFactory providerFactory;
private final Directory directory;
private String lastSeenRef = "HEAD";

PreviousGitTags(Project project) {
this.project = project;
PreviousGitTags(ProviderFactory providerFactory, Directory directory) {
this.providerFactory = providerFactory;
this.directory = directory;
}

@Override
public boolean tryAdvance(Consumer<? super String> action) {
Optional<String> tag = previousGitTagFromRef(project, lastSeenRef);
Optional<String> tag = previousGitTagFromRef(providerFactory, directory, lastSeenRef);

if (!tag.isPresent()) {
return false;
Expand Down
67 changes: 25 additions & 42 deletions src/main/java/org/revapi/gradle/RevapiAcceptBreakTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,70 +20,57 @@
import java.util.Optional;
import org.gradle.api.DefaultTask;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.options.Option;
import org.revapi.gradle.config.AcceptedBreak;
import org.revapi.gradle.config.GroupNameVersion;
import org.revapi.gradle.config.Justification;

public class RevapiAcceptBreakTask extends DefaultTask {
public abstract class RevapiAcceptBreakTask extends DefaultTask {
private static final String CODE_OPTION = "code";
private static final String OLD_OPTION = "old";
private static final String NEW_OPTION = "new";
private static final String JUSTIFICATION_OPTION = "justification";

private final Property<ConfigManager> configManager =
getProject().getObjects().property(ConfigManager.class);
private final Property<String> code = getProject().getObjects().property(String.class);
private final Property<String> oldElement = getProject().getObjects().property(String.class);
private final Property<String> newElement = getProject().getObjects().property(String.class);
private final Property<Justification> justification =
getProject().getObjects().property(Justification.class);

public RevapiAcceptBreakTask() {
getOutputs().upToDateWhen(_ignored -> false);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to doNotTrackState in RevapiPlugin.java

}

@Internal
final Property<ConfigManager> getConfigManager() {
return configManager;
}

@Input
@Option(option = CODE_OPTION, description = "Revapi change code")
public final void setCode(String codeString) {
this.code.set(codeString);
}
public abstract Property<String> getCode();

@Input
@Option(option = OLD_OPTION, description = "Old API element")
public final void setOldElement(String oldElementString) {
this.oldElement.set(oldElementString);
}
public abstract Property<String> getOldElement();

@Input
@Option(option = NEW_OPTION, description = "New API element")
public final void setNewElement(String newElementString) {
this.newElement.set(newElementString);
}
public abstract Property<String> getNewElement();

@Input
@Option(option = JUSTIFICATION_OPTION, description = "Justification for why these breaks are ok")
public final void setJustification(String justificationString) {
this.justification.set(Justification.fromString(justificationString));
}
public abstract Property<String> getJustificationString();

@Input
protected abstract Property<GroupNameVersion> getGroupNameVersion();

@Internal
protected abstract Property<ConfigManager> getConfigManager();

@TaskAction
public final void addVersionOverride() {
ensurePresent(code, CODE_OPTION);
ensurePresent(justification, JUSTIFICATION_OPTION);
ensurePresent(getCode(), CODE_OPTION);
ensurePresent(getJustificationString(), JUSTIFICATION_OPTION);

configManager
getConfigManager()
.get()
.modifyConfigFile(revapiConfig -> revapiConfig.addAcceptedBreaks(
oldGroupNameVersion(),
getGroupNameVersion().get(),
Collections.singleton(AcceptedBreak.builder()
.code(code.get())
.oldElement(Optional.ofNullable(oldElement.getOrNull()))
.newElement(Optional.ofNullable(newElement.getOrNull()))
.justification(justification.get())
.code(getCode().get())
.oldElement(Optional.ofNullable(getOldElement().getOrNull()))
.newElement(Optional.ofNullable(getNewElement().getOrNull()))
.justification(Justification.fromString(
getJustificationString().get()))
.build())));
}

Expand All @@ -92,8 +79,4 @@ private void ensurePresent(Property<?> prop, String option) {
throw new IllegalArgumentException("Please supply the --" + option + " param to this task");
}
}

private GroupNameVersion oldGroupNameVersion() {
return getProject().getExtensions().getByType(RevapiExtension.class).oldGroupNameVersion();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the use of getProject that was breaking configuration cache the rest of the changes are just about converting to an abstract class - can just remove this if we want a minimum PR

}
}
Loading