return null;
}
+ /**
+ * Return the main branch name.
+ *
+ * @return null if the SCM provider was not able to find the main branch.
+ * @since 8.8
+ */
+ @CheckForNull
+ public String getMainBranch(Path rootBaseDir) {
+ return null;
+ }
+
/**
* Return a map between paths given as argument and the corresponding line numbers which are new compared to the provided target branch.
* If nothing is returned for a file, the scanner will consider that the provider was unable to determine changes for that file and it will
private final InputComponentStore componentStore;
private final ScmConfiguration scmConfiguration;
+ private ScmProvider scmProvider;
+ private Path projectBasedir;
+
public MetadataPublisher(ProjectInfo projectInfo, InputModuleHierarchy moduleHierarchy, QualityProfiles qProfiles,
CpdSettings cpdSettings, ScannerPluginRepository pluginRepository, BranchConfiguration branchConfiguration,
ScmRevision scmRevision, ForkDateSupplier forkDateSupplier, InputComponentStore componentStore, ScmConfiguration scmConfiguration) {
addScmInformation(builder);
addForkPoint(builder);
addNotAnalyzedFileCountsByLanguage(builder);
- addMainBranch(builder);
for (QProfile qp : qProfiles.findAll()) {
builder.putQprofilesPerLanguage(qp.getLanguage(), ScannerReport.Metadata.QProfile.newBuilder()
.setUpdatedAt(pluginEntry.getValue().getUpdatedAt()).build());
}
+ scmProvider = scmConfiguration.provider();
+ projectBasedir = moduleHierarchy.root().getBaseDir();
+
addModulesRelativePaths(builder);
addMainBranch(builder);
}
private void addMainBranch(ScannerReport.Metadata.Builder builder) {
- builder.setGitDefaultMainBranch("");
+ if (scmProvider == null) {
+ return;
+ }
+ String mainBranch = scmProvider.getMainBranch(projectBasedir);
+ if (mainBranch != null && !mainBranch.isEmpty()) {
+ LOG.debug("The main branch for '{}' is '{}'", projectBasedir.toString(), mainBranch);
+ builder.setGitDefaultMainBranch(mainBranch);
+ } else {
+ LOG.debug("The main branch for '{}' has not been found", projectBasedir.toString());
+ }
}
private void addForkPoint(ScannerReport.Metadata.Builder builder) {
}
}
- ScmProvider scmProvider = scmConfiguration.provider();
if (scmProvider == null) {
return;
}
- Path projectBasedir = moduleHierarchy.root().getBaseDir();
try {
builder.setRelativePathFromScmRoot(toSonarQubePath(scmProvider.relativePathFromScmRoot(projectBasedir)));
} catch (UnsupportedOperationException e) {
return this.jgitBlameCommand;
}
+ @CheckForNull
+ @Override
+ public String getMainBranch(Path rootBaseDir) {
+ try (Repository repo = buildRepo(rootBaseDir)) {
+ Set<String> branches = repo.getConfig().getSubsections("branch");
+ if(!branches.isEmpty()) {
+ // .git/config file will have the default branch at the time of cloning as its first branch
+ return branches.iterator().next();
+ }
+ } catch (IOException e) {
+ LOG.debug("Couldn't build a repo in order to retrieve the default branch name", e);
+ }
+ return null;
+ }
+
@CheckForNull
@Override
public Set<Path> branchChangedFiles(String targetBranchName, Path rootBaseDir) {
ScannerReport.Metadata metadata = reader.readMetadata();
assertThat(metadata.getRelativePathFromScmRoot()).isEmpty();
}
+
+ @Test
+ public void addMainBranch_givenDefaultMainBranchSet_writeItToMetadata() throws IOException {
+ ScmProvider scmProvider = mock(ScmProvider.class);
+ when(scmProvider.getMainBranch(any())).thenReturn("Main");
+ when(scmProvider.relativePathFromScmRoot(any())).thenReturn(mock(Path.class));
+ when(scmConfiguration.provider()).thenReturn(scmProvider);
+
+ File outputDir = temp.newFolder();
+ underTest.publish(new ScannerReportWriter(outputDir));
+
+ ScannerReportReader reader = new ScannerReportReader(outputDir);
+ ScannerReport.Metadata metadata = reader.readMetadata();
+ assertThat(metadata.getGitDefaultMainBranch()).isEqualTo("Main");
+ }
+
+ @Test
+ public void addMainBranch_givenEmptyDefaultMainBranchSet_emptyDefaultMainBranchInMetadata() throws IOException {
+ ScmProvider scmProvider = mock(ScmProvider.class);
+ when(scmProvider.getMainBranch(any())).thenReturn("");
+ when(scmProvider.relativePathFromScmRoot(any())).thenReturn(mock(Path.class));
+ when(scmConfiguration.provider()).thenReturn(scmProvider);
+
+ File outputDir = temp.newFolder();
+ underTest.publish(new ScannerReportWriter(outputDir));
+
+ ScannerReportReader reader = new ScannerReportReader(outputDir);
+ ScannerReport.Metadata metadata = reader.readMetadata();
+ assertThat(metadata.getGitDefaultMainBranch()).isEmpty();
+ }
+
+ @Test
+ public void addMainBranch_givenNullMainBranchSet_emptyDefaultMainBranchInMetadata() throws IOException {
+ ScmProvider scmProvider = mock(ScmProvider.class);
+ when(scmProvider.getMainBranch(any())).thenReturn(null);
+ when(scmProvider.relativePathFromScmRoot(any())).thenReturn(mock(Path.class));
+ when(scmConfiguration.provider()).thenReturn(scmProvider);
+
+ File outputDir = temp.newFolder();
+ underTest.publish(new ScannerReportWriter(outputDir));
+
+ ScannerReportReader reader = new ScannerReportReader(outputDir);
+ ScannerReport.Metadata metadata = reader.readMetadata();
+ assertThat(metadata.getGitDefaultMainBranch()).isEmpty();
+ }
}
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger;
+
+import org.eclipse.jgit.api.CreateBranchCommand;
import org.eclipse.jgit.api.DiffCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.junit.Before;
import org.junit.Rule;
assertThat(provider.revisionId(projectDir)).isNull();
}
+ @Test
+ public void getMainBranch_givenRepoWithOneBranchCalledMain_returnMainBranchCalledMain() throws Exception {
+ //given
+ worktree = temp.newFolder().toPath();
+ Repository repo = FileRepositoryBuilder.create(worktree.resolve(".git").toFile());
+ repo.create();
+ git = new Git(repo);
+
+ addBranchInConfig("Main");
+
+ Path projectDir = worktree.resolve("project");
+ Files.createDirectory(projectDir);
+
+ GitScmProvider provider = newGitScmProvider();
+
+ //when
+ String mainBranch = provider.getMainBranch(projectDir);
+
+ //then
+ assertThat(mainBranch).isEqualTo("Main");
+ }
+
+ @Test
+ public void getMainBranch_givenRepoWithTwoBranches_returnFirstBranch() throws Exception {
+ //given
+ worktree = temp.newFolder().toPath();
+ Repository repo = FileRepositoryBuilder.create(worktree.resolve(".git").toFile());
+ repo.create();
+ git = new Git(repo);
+
+ addBranchInConfig("First");
+ addBranchInConfig("Second");
+
+ Path projectDir = worktree.resolve("project");
+ Files.createDirectory(projectDir);
+
+ GitScmProvider provider = newGitScmProvider();
+
+ //when
+ String mainBranch = provider.getMainBranch(projectDir);
+
+ //then
+ assertThat(mainBranch).isEqualTo("First");
+ }
+
+ @Test
+ public void getMainBranch_givenNoBranches_dontThrowException() throws Exception {
+ //given
+ worktree = temp.newFolder().toPath();
+ Repository repo = FileRepositoryBuilder.create(worktree.resolve(".git").toFile());
+ repo.create();
+ git = new Git(repo);
+
+ Path projectDir = worktree.resolve("project");
+ Files.createDirectory(projectDir);
+
+ GitScmProvider provider = newGitScmProvider();
+
+ //when
+ String mainBranch = provider.getMainBranch(projectDir);
+
+ //then no exception
+ assertThat(mainBranch).isNullOrEmpty();
+ }
+
+ @Test
+ public void getMainBranch_givenRepositoryNotFoundExceptionWhenBuildingRepo_returnNull() throws Exception {
+ //given
+
+ worktree = temp.newFolder().toPath();
+ Repository repo = FileRepositoryBuilder.create(worktree.resolve(".git").toFile());
+ repo.create();
+ git = new Git(repo);
+ repo.getObjectDatabase().close(); //This is here to force RepositoryBuilder to throw subclass of IOException
+
+ Path projectDir = worktree.resolve("project");
+ Files.createDirectory(projectDir);
+
+ GitScmProvider provider = newGitScmProvider();
+
+ //when
+ String mainBranch = provider.getMainBranch(projectDir);
+
+ //then no exception
+ assertThat(mainBranch).isNullOrEmpty();
+ }
+
+ @Test
+ public void getMainBranch_givenIOExceptionWhenBuildingRepo_returnNull() throws Exception {
+ //given
+
+ worktree = temp.newFolder().toPath();
+ Repository repo = FileRepositoryBuilder.create(worktree.resolve(".git").toFile());
+ repo.create();
+ git = new Git(repo);
+
+ Path projectDir = worktree.resolve("project");
+ Files.createDirectory(projectDir);
+
+ GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2) {
+ @Override
+ Repository buildRepo(Path basedir) throws IOException {
+ throw new IOException();
+ }
+ };
+
+ //when
+ String mainBranch = provider.getMainBranch(projectDir);
+
+ //then no exception
+ assertThat(mainBranch).isNullOrEmpty();
+ }
+
+ /**
+ * Normally after cloning the repository we would have at least one
+ * branch it git config. This method adds these branches without
+ * cloning any repository (because unit tests ought to be fast)
+ */
+ private void addBranchInConfig(String ... branches) throws IOException {
+ for(String branch : branches) {
+ git.getRepository().getConfig().setStringList("branch", branch, "remote", Arrays.asList("origin"));
+ git.getRepository().getConfig().setStringList("branch", branch, "merge", Arrays.asList("refs/head/" + branch));
+ }
+ git.getRepository().getConfig().save();
+ }
+
private String randomizedContent(String prefix, int numLines) {
StringBuilder sb = new StringBuilder();
for (int line = 0; line < numLines; line++) {