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
10 changes: 10 additions & 0 deletions java/.mvn/jvm.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
30 changes: 23 additions & 7 deletions java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
<parent>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-parent</artifactId>
<version>4.5.0</version>
<version>5.0.0-SNAPSHOT</version>
</parent>

<artifactId>ci-environment</artifactId>
<version>12.0.1-SNAPSHOT</version>
<version>13.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Cucumber CiEnvironment</name>
<description>Detect CI Environment from environment variables</description>
Expand Down Expand Up @@ -49,6 +49,12 @@

<dependencies>

<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
<version>1.0.0</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
Expand Down Expand Up @@ -109,10 +115,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- TODO: Pull up to parent pom-->
<parameters>true</parameters>
</configuration>
<executions>
<execution>
<id>generate-ci-environments</id>
Expand All @@ -127,6 +129,7 @@
</execution>
</executions>
</plugin>

<!-- Run the code generator -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
Expand All @@ -146,7 +149,7 @@
<additionalClasspathElements>
${project.build.directory}/codegen-classes
</additionalClasspathElements>
<mainClass>Generate</mainClass>
<mainClass>io.cucumber.cienvironment.Generate</mainClass>
<arguments>
<argument>${project.build.directory}/generated-sources/ci-environments/java</argument>
<argument>io/cucumber/cienvironment</argument>
Expand All @@ -173,6 +176,19 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package io.cucumber.cienvironment;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import freemarker.template.Configuration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import java.util.Collection;

import static java.util.Arrays.asList;

class CiEnvironments {
final class CiEnvironments {
static final Collection<CiEnvironmentImpl> TEMPLATES = asList(
<#list ciEnvironments as ciEnvironment>
new CiEnvironmentImpl(
Expand All @@ -20,4 +20,8 @@ class CiEnvironments {
</#list>

);

private CiEnvironments(){
// Utility class
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@

public interface CiEnvironment {
String getName();

String getUrl();

Optional<String> getBuildNumber();

Optional<Git> getGit();

interface Git {
String getRemote();

String getRevision();

Optional<String> getBranch();

Optional<String> getTag();
}
}
22 changes: 12 additions & 10 deletions java/src/main/java/io/cucumber/cienvironment/CiEnvironmentImpl.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package io.cucumber.cienvironment;

import org.jspecify.annotations.Nullable;

import java.util.Objects;
import java.util.Optional;

import static java.util.Objects.requireNonNull;
import static java.util.Optional.ofNullable;

final class CiEnvironmentImpl implements CiEnvironment {
public String name;
public String url;
public String buildNumber;
public Git git;
private final String name;
private final String url;
private final @Nullable String buildNumber;
private final @Nullable Git git;

CiEnvironmentImpl(String name, String url, String buildNumber, Git git) {
CiEnvironmentImpl(String name, String url, @Nullable String buildNumber, @Nullable Git git) {
this.name = requireNonNull(name);
this.url = requireNonNull(url);
this.buildNumber = buildNumber;
Expand Down Expand Up @@ -63,12 +65,12 @@ public String toString() {
}

final static class Git implements CiEnvironment.Git {
public String remote;
public String revision;
public String branch;
public String tag;
private final String remote;
private final String revision;
private final @Nullable String branch;
private final @Nullable String tag;

Git(String remote, String revision, String branch, String tag) {
Git(String remote, String revision, @Nullable String branch, @Nullable String tag) {
this.remote = requireNonNull(remote);
this.revision = requireNonNull(revision);
this.branch = branch;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.cucumber.cienvironment;

import org.jspecify.annotations.Nullable;

import java.util.Map;
import java.util.Optional;

import static io.cucumber.cienvironment.VariableExpression.evaluate;
import static java.util.Optional.empty;
import static java.util.Optional.of;

public final class DetectCiEnvironment {
private DetectCiEnvironment() {
Expand All @@ -28,17 +28,17 @@ public static Optional<CiEnvironment> detectCiEnvironment(Map<String, String> en

private static Optional<CiEnvironment> detect(CiEnvironment ci, Map<String, String> env) {
String url = evaluate(ci.getUrl(), env);
if (url == null) return empty();
if (url == null) return Optional.empty();

return of(new CiEnvironmentImpl(
return Optional.of(new CiEnvironmentImpl(
ci.getName(),
url,
ci.getBuildNumber().map(buildNumber -> evaluate(buildNumber, env)).orElse(null),
detectGit(ci, env)
));
}

private static CiEnvironmentImpl.Git detectGit(CiEnvironment ci, Map<String, String> env) {
private static CiEnvironmentImpl.@Nullable Git detectGit(CiEnvironment ci, Map<String, String> env) {
String revision = evaluateRevision(ci, env);
if (revision == null) return null;

Expand All @@ -58,7 +58,7 @@ private static CiEnvironmentImpl.Git detectGit(CiEnvironment ci, Map<String, Str
);
}

private static String evaluateRevision(CiEnvironment ci, Map<String, String> env) {
private static @Nullable String evaluateRevision(CiEnvironment ci, Map<String, String> env) {
String revision = GithubEventParser.evaluateRevisionGithub(env);
if (revision != null) return revision;
return ci.getGit().map(git -> evaluate(git.getRevision(), env)).orElse(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package io.cucumber.cienvironment;

import org.jspecify.annotations.Nullable;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

final class GithubEventParser {


private GithubEventParser(){
// Utility class
}

/*
* Evaluate the current revision on GitHub.
*
Expand All @@ -19,16 +24,16 @@ final class GithubEventParser {
* * https://github.com/orgs/community/discussions/26325
* * https://github.com/cucumber/ci-environment/issues/86
*/
static String evaluateRevisionGithub(Map<String, String> env) {
static @Nullable String evaluateRevisionGithub(Map<String, String> env) {
if (!"pull_request".equals(env.get("GITHUB_EVENT_NAME"))) {
return null;
}
if (env.get("GITHUB_EVENT_PATH") == null) {
String path = env.get("GITHUB_EVENT_PATH");
if (path == null) {
return null;
}
try {
Path path = Paths.get(env.get("GITHUB_EVENT_PATH"));
String event = String.join(" ", Files.readAllLines(path));
String event = String.join(" ", Files.readAllLines(Paths.get(path)));
return parsePullRequestHeadSha(event);
} catch (IOException e) {
return null;
Expand Down Expand Up @@ -67,7 +72,7 @@ static String evaluateRevisionGithub(Map<String, String> env) {
// End of object
"}$");

static String parsePullRequestHeadSha(String eventJson) {
static @Nullable String parsePullRequestHeadSha(String eventJson) {
// Parse json using regex. Not ideal but works for the limited input.
Matcher matcher = GITHUB_EVENT_PATTERN.matcher(eventJson.trim());
if (!matcher.matches()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
import java.net.URISyntaxException;

final class RemoveUserInfo {

private RemoveUserInfo(){
// Utility class
}

static String fromUrl(String value) {
if (value == null) return null;
try {
URI uri = URI.create(value);
return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment()).toASCIIString();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.cucumber.cienvironment;

import org.jspecify.annotations.Nullable;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand All @@ -13,10 +15,10 @@ private VariableExpression() {

}

static String evaluate(String expression, Map<String, String> env) {
static @Nullable String evaluate(@Nullable String expression, Map<String, String> env) {
if (expression == null) return null;
Matcher variableMatcher = variablePattern.matcher(expression);
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
while (variableMatcher.find()) {
String variable = variableMatcher.group(1);
String value = getValue(env, variable);
Expand All @@ -43,7 +45,7 @@ static String evaluate(String expression, Map<String, String> env) {
return sb.toString();
}

private static String getValue(Map<String, String> env, String variable) {
private static @Nullable String getValue(Map<String, String> env, String variable) {
if (variable.contains("*")) {
Pattern pattern = Pattern.compile(variable.replace("*", ".*"));
// GoCD env var with dynamic "material" name
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@NullMarked
package io.cucumber.cienvironment;

import org.jspecify.annotations.NullMarked;
9 changes: 6 additions & 3 deletions java/src/test/java/io/cucumber/CiEnvironmentExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import io.cucumber.cienvironment.CiEnvironment;

import java.util.Optional;

import static io.cucumber.cienvironment.DetectCiEnvironment.detectCiEnvironment;

public class CiEnvironmentExample {
public final class CiEnvironmentExample {

private CiEnvironmentExample(){
// Demo
}

public static void main(String[] args) {
CiEnvironment ciEnvironment = detectCiEnvironment(System.getenv()).orElseThrow(() -> new RuntimeException("No CI environment detected"));
System.out.println("ciEnvironment = " + ciEnvironment);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.cucumber.cienvironment;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.converter.ArgumentConversionException;
Expand Down Expand Up @@ -30,7 +29,7 @@

class DetectCiEnvironmentTest {

private static List<Path> acceptance_tests_pass() throws IOException {
static List<Path> acceptance_tests_pass() throws IOException {
List<Path> paths = new ArrayList<>();
try (DirectoryStream<Path> testdata = newDirectoryStream(Paths.get("..", "testdata", "src"), "*.txt")){
testdata.forEach(paths::add);
Expand Down Expand Up @@ -62,14 +61,18 @@ public CiEnvironment getExpected() {

static class Converter implements ArgumentConverter {
@Override
public Expectation convert(Object source, ParameterContext context) throws ArgumentConversionException {
public Expectation convert(@Nullable Object source, @Nullable ParameterContext context) throws ArgumentConversionException {
if (source == null) {
throw new ArgumentConversionException("Could not convert null");
}

Path path = (Path) source;
Map<String, String> env = new HashMap<>();

try (BufferedReader in = newBufferedReader(path)){
String line;
while ((line = in.readLine()) != null) {
String[] parts = line.split("=");
String[] parts = line.split("=", 2);

if (parts.length == 1) {
env.put(parts[0], "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.Map;

import static io.cucumber.cienvironment.DetectCiEnvironment.detectCiEnvironment;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;

class GitHubPullRequestIntegrationTest {
Expand All @@ -28,7 +29,8 @@ private static String parseRevisionWithRegularExpression(Map<String, String> env
}

private static String parsePullRequestHeadShaWithJackson(Map<String, String> env) throws IOException {
File file = new File(env.get("GITHUB_EVENT_PATH"));
String githubEventPath = requireNonNull(env.get("GITHUB_EVENT_PATH"));
File file = new File(githubEventPath);
JsonNode event = Jackson.OBJECT_MAPPER.readTree(file);
return event.get("pull_request").get("head").get("sha").textValue();
}
Expand Down
Loading
Loading