Skip to content

Fixed getting git metadata when started from a different dir to the project #385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private static void applySettingsPlugin(DevelocityAdapter develocity, ProviderFa

BuildScanAdapter buildScan = develocity.getBuildScan();
customDevelocityConfig.configureBuildScanPublishing(buildScan);
CustomBuildScanEnhancements buildScanEnhancements = new CustomBuildScanEnhancements(develocity, providers, settings.getGradle());
CustomBuildScanEnhancements buildScanEnhancements = new CustomBuildScanEnhancements(develocity, providers, settings.getGradle(), settings.getRootDir());
buildScanEnhancements.apply();

BuildCacheConfiguration buildCache = settings.getBuildCache();
Expand Down Expand Up @@ -146,7 +146,7 @@ private void applyProjectPlugin(Project project, DevelocityAdapter develocity) {

BuildScanAdapter buildScan = develocity.getBuildScan();
customDevelocityConfig.configureBuildScanPublishing(buildScan);
CustomBuildScanEnhancements buildScanEnhancements = new CustomBuildScanEnhancements(develocity, providers, project.getGradle());
CustomBuildScanEnhancements buildScanEnhancements = new CustomBuildScanEnhancements(develocity, providers, project.getGradle(), project.getRootDir());
buildScanEnhancements.apply();

// Build cache configuration cannot be accessed from a project plugin
Expand Down
33 changes: 19 additions & 14 deletions src/main/java/com/gradle/CustomBuildScanEnhancements.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;

import java.io.File;
import java.net.URI;
import java.util.AbstractMap;
import java.util.Arrays;
Expand Down Expand Up @@ -67,12 +68,14 @@ final class CustomBuildScanEnhancements {
private final BuildScanAdapter buildScan;
private final ProviderFactory providers;
private final Gradle gradle;
private final File projectDir;

CustomBuildScanEnhancements(DevelocityAdapter develocity, ProviderFactory providers, Gradle gradle) {
CustomBuildScanEnhancements(DevelocityAdapter develocity, ProviderFactory providers, Gradle gradle, File projectDir) {
this.develocity = develocity;
this.buildScan = develocity.getBuildScan();
this.providers = providers;
this.gradle = gradle;
this.projectDir = projectDir;
}

// Apply all build scan enhancements via custom tags, links, and values
Expand Down Expand Up @@ -395,17 +398,19 @@ public void execute(BuildResultAdapter buildResult) {

private void captureGitMetadata() {
// Run expensive computation in background
buildScan.background(new CaptureGitMetadataAction(providers, develocity));
buildScan.background(new CaptureGitMetadataAction(develocity, providers, projectDir));
}

private static final class CaptureGitMetadataAction implements Action<BuildScanAdapter> {

private final ProviderFactory providers;
private final DevelocityAdapter develocity;
private final ProviderFactory providers;
private final File projectDir;

private CaptureGitMetadataAction(ProviderFactory providers, DevelocityAdapter develocity) {
this.providers = providers;
private CaptureGitMetadataAction(DevelocityAdapter develocity, ProviderFactory providers, File projectDir) {
this.develocity = develocity;
this.providers = providers;
this.projectDir = projectDir;
}

@Override
Expand All @@ -414,11 +419,11 @@ public void execute(BuildScanAdapter buildScan) {
return;
}

String gitRepo = execAndGetStdOut("git", "config", "--get", "remote.origin.url");
String gitCommitId = execAndGetStdOut("git", "rev-parse", "--verify", "HEAD");
String gitCommitShortId = execAndGetStdOut("git", "rev-parse", "--short=8", "--verify", "HEAD");
String gitBranchName = getGitBranchName(() -> execAndGetStdOut("git", "rev-parse", "--abbrev-ref", "HEAD"));
String gitStatus = execAndGetStdOut("git", "status", "--porcelain");
String gitRepo = execAndGetStdOut(projectDir, "git", "config", "--get", "remote.origin.url");
String gitCommitId = execAndGetStdOut(projectDir, "git", "rev-parse", "--verify", "HEAD");
String gitCommitShortId = execAndGetStdOut(projectDir, "git", "rev-parse", "--short=8", "--verify", "HEAD");
String gitBranchName = getGitBranchName(projectDir, () -> execAndGetStdOut(projectDir, "git", "rev-parse", "--abbrev-ref", "HEAD"));
String gitStatus = execAndGetStdOut(projectDir, "git", "status", "--porcelain");

if (isNotEmpty(gitRepo)) {
buildScan.value("Git repository", redactUserInfo(gitRepo));
Expand Down Expand Up @@ -459,7 +464,7 @@ private boolean isGitInstalled() {
return execAndCheckSuccess("git", "--version");
}

private String getGitBranchName(Supplier<String> gitCommand) {
private String getGitBranchName(File projectDir, Supplier<String> gitCommand) {
if (isJenkins(providers) || isHudson(providers)) {
Optional<String> branchName = envVariable("BRANCH_NAME", providers);
if (branchName.isPresent()) {
Expand All @@ -468,7 +473,7 @@ private String getGitBranchName(Supplier<String> gitCommand) {

Optional<String> gitBranch = envVariable("GIT_BRANCH", providers);
if (gitBranch.isPresent()) {
Optional<String> localBranch = getLocalBranch(gitBranch.get());
Optional<String> localBranch = getLocalBranch(projectDir, gitBranch.get());
if (localBranch.isPresent()) {
return localBranch.get();
}
Expand Down Expand Up @@ -497,15 +502,15 @@ private String getGitBranchName(Supplier<String> gitCommand) {
return gitCommand.get();
}

private static Optional<String> getLocalBranch(String remoteBranch) {
private static Optional<String> getLocalBranch(File projectDir, String remoteBranch) {
// This finds the longest matching remote name. This is because, for example, a local git clone could have
// two remotes named `origin` and `origin/two`. In this scenario, we would want a remote branch of
// `origin/two/main` to match to the `origin/two` remote, not to `origin`
Function<String, Optional<String>> findLongestMatchingRemote = remotes -> Arrays.stream(remotes.split("\\R"))
.filter(remote -> remoteBranch.startsWith(remote + "/"))
.max(Comparator.comparingInt(String::length));

return Optional.ofNullable(execAndGetStdOut("git", "remote"))
return Optional.ofNullable(execAndGetStdOut(projectDir, "git", "remote"))
.filter(Utils::isNotEmpty)
.flatMap(findLongestMatchingRemote)
.map(remote -> remoteBranch.replaceFirst("^" + remote + "/", ""));
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/com/gradle/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
Expand Down Expand Up @@ -140,11 +141,17 @@ static boolean execAndCheckSuccess(String... args) {
}
}

static String execAndGetStdOut(String... args) {
/**
* Executes a command and returns the standard output as a string.
* @param dir the working directory of the subprocess, or null if the subprocess should inherit the working directory of the current process.
* @param args array containing the command to call and its arguments.
* @return the standard output of the command, or null if the command failed.
*/
static String execAndGetStdOut(File dir, String... args) {
Runtime runtime = Runtime.getRuntime();
Process process;
try {
process = runtime.exec(args);
process = runtime.exec(args, null, dir);
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down