Skip to content
Merged
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: 3 additions & 7 deletions src/GitVersionCore.Tests/GitVersionExecutorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void CacheKeySameAfterReNormalizing()
}

[Test]
public void GitPreparerShouldFailWhenTargetPathNotInitialized()
public void GitPreparerShouldNotFailWhenTargetPathNotInitialized()
{
RepositoryScope((fixture, vv) =>
{
Expand All @@ -88,10 +88,6 @@ public void GitPreparerShouldFailWhenTargetPathNotInitialized()
TargetPath = null
};
var options = Options.Create(arguments);
Should.Throw<NullReferenceException>(() => new GitPreparer(log, environment, options));

arguments.TargetPath = fixture.RepositoryPath;

Should.NotThrow(() => new GitPreparer(log, environment, options));
});
}
Expand Down Expand Up @@ -413,7 +409,7 @@ public void GetProjectRootDirectoryWorkingDirectoryWithWorktree()

var gitPreparer = new GitPreparer(log, environment, Options.Create(arguments));

gitPreparer.GetProjectRootDirectory().TrimEnd('/', '\\').ShouldBe(worktreePath);
gitPreparer.GetProjectRootDirectoryInternal().TrimEnd('/', '\\').ShouldBe(worktreePath);
}
finally
{
Expand All @@ -437,7 +433,7 @@ public void GetProjectRootDirectoryNoWorktree()

var gitPreparer = new GitPreparer(log, environment, Options.Create(arguments));
var expectedPath = fixture.RepositoryPath.TrimEnd('/', '\\');
gitPreparer.GetProjectRootDirectory().TrimEnd('/', '\\').ShouldBe(expectedPath);
gitPreparer.GetProjectRootDirectoryInternal().TrimEnd('/', '\\').ShouldBe(expectedPath);
});
}

Expand Down
4 changes: 3 additions & 1 deletion src/GitVersionCore/Cache/GitVersionCacheKeyFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Text;
using GitVersion.Configuration;
using GitVersion.Logging;
using GitVersion.Extensions;

namespace GitVersion.Cache
{
Expand Down Expand Up @@ -124,7 +125,8 @@ private static List<string> CalculateDirectoryContents(ILog log, string root)

private static string GetRepositorySnapshotHash(IGitPreparer gitPreparer)
{
var repositorySnapshot = gitPreparer.WithRepository(repo => {
var repositorySnapshot = gitPreparer.GetDotGitDirectory().WithRepository(repo =>
{
var head = repo.Head;
if (head.Tip == null)
{
Expand Down
6 changes: 3 additions & 3 deletions src/GitVersionCore/Configuration/ConfigFileLocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ protected ConfigFileLocator(IFileSystem fileSystem, ILog log)

public string SelectConfigFilePath(IGitPreparer gitPreparer)
{
var workingDirectory = gitPreparer.WorkingDirectory;
var workingDirectory = gitPreparer.GetWorkingDirectory();
var projectRootDirectory = gitPreparer.GetProjectRootDirectory();

if (HasConfigFileAt(workingDirectory))
Expand All @@ -50,14 +50,14 @@ public Config ReadConfig(string workingDirectory)

public void Verify(IGitPreparer gitPreparer)
{
if (!string.IsNullOrWhiteSpace(gitPreparer.TargetUrl))
if (!string.IsNullOrWhiteSpace(gitPreparer.GetTargetUrl()))
{
// Assuming this is a dynamic repository. At this stage it's unsure whether we have
// any .git info so we need to skip verification
return;
}

var workingDirectory = gitPreparer.WorkingDirectory;
var workingDirectory = gitPreparer.GetWorkingDirectory();
var projectRootDirectory = gitPreparer.GetProjectRootDirectory();

Verify(workingDirectory, projectRootDirectory);
Expand Down
4 changes: 2 additions & 2 deletions src/GitVersionCore/Configuration/ConfigFileLocatorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public ConfigFileLocatorFactory(IFileSystem fileSystem, ILog log, IOptions<Argum
{
this.fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
this.log = log ?? throw new ArgumentNullException(nameof(log));
this.options = options ?? throw new ArgumentNullException(nameof(fileSystem));
this.options = options ?? throw new ArgumentNullException(nameof(options));
}

public IConfigFileLocator Create()
Expand All @@ -24,4 +24,4 @@ public IConfigFileLocator Create()
: new NamedConfigFileLocator(fileSystem, log, options);
}
}
}
}
2 changes: 1 addition & 1 deletion src/GitVersionCore/Configuration/ConfigProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public ConfigProvider(IFileSystem fileSystem, ILog log, IConfigFileLocator confi

public Config Provide(bool applyDefaults = true, Config overrideConfig = null)
{
var workingDirectory = gitPreparer.WorkingDirectory;
var workingDirectory = gitPreparer.GetWorkingDirectory();
var projectRootDirectory = gitPreparer.GetProjectRootDirectory();

var rootDirectory = configFileLocator.HasConfigFileAt(workingDirectory) ? workingDirectory : projectRootDirectory;
Expand Down
8 changes: 4 additions & 4 deletions src/GitVersionCore/Configuration/NamedConfigFileLocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ namespace GitVersion.Configuration
{
public class NamedConfigFileLocator : ConfigFileLocator
{
private readonly IOptions<Arguments> options;

public NamedConfigFileLocator(IFileSystem fileSystem, ILog log, IOptions<Arguments> options) : base(fileSystem, log)
{
var filePath = options.Value.ConfigFile;
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException(nameof(filePath), "Empty file path provided!");
FilePath = filePath;
this.options = options ?? throw new ArgumentNullException(nameof(options));
}

public string FilePath { get; }
public string FilePath => options.Value.ConfigFile;

public override bool HasConfigFileAt(string workingDirectory) =>
FileSystem.Exists(Path.Combine(workingDirectory, FilePath));
Expand Down
6 changes: 6 additions & 0 deletions src/GitVersionCore/Extensions/LibGitExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ namespace GitVersion.Extensions
{
public static class LibGitExtensions
{
public static TResult WithRepository<TResult>(this string dotGitDirectory, Func<IRepository, TResult> action)
{
using var repo = new Repository(dotGitDirectory);
return action(repo);
}

public static DateTimeOffset When(this Commit commit)
{
return commit.Committer.When;
Expand Down
82 changes: 38 additions & 44 deletions src/GitVersionCore/GitPreparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,43 @@ public class GitPreparer : IGitPreparer
{
private readonly ILog log;
private readonly IEnvironment environment;
private readonly string dynamicRepositoryLocation;
private readonly Arguments arguments;
private readonly IOptions<Arguments> options;

private const string DefaultRemoteName = "origin";
private string dynamicGitRepositoryPath;
private string dotGitDirectory;
private string projectRootDirectory;

public string GetTargetUrl() => options.Value.TargetUrl;

public string GetWorkingDirectory() => options.Value.TargetPath.TrimEnd('/', '\\');

public string GetDotGitDirectory() => dotGitDirectory ??= GetDotGitDirectoryInternal();

public string GetProjectRootDirectory() => projectRootDirectory ??= GetProjectRootDirectoryInternal();

private bool IsDynamicGitRepository => !string.IsNullOrWhiteSpace(DynamicGitRepositoryPath);
private string DynamicGitRepositoryPath;

public GitPreparer(ILog log, IEnvironment environment, IOptions<Arguments> options)
{
this.log = log ?? throw new ArgumentNullException(nameof(log));
this.environment = environment;
arguments = options.Value;

TargetUrl = arguments.TargetUrl;
WorkingDirectory = arguments.TargetPath.TrimEnd('/', '\\');

dynamicRepositoryLocation = arguments.DynamicRepositoryLocation;
this.environment = environment ?? throw new ArgumentNullException(nameof(environment));
this.options = options ?? throw new ArgumentNullException(nameof(options));
}

public void Prepare(bool normalizeGitDirectory, string currentBranch, bool shouldCleanUpRemotes = false)
{
var arguments = options.Value;
var authentication = new AuthenticationInfo
{
Username = arguments.Authentication?.Username,
Password = arguments.Authentication?.Password
};
if (!string.IsNullOrWhiteSpace(TargetUrl))
if (!string.IsNullOrWhiteSpace(GetTargetUrl()))
{
var tempRepositoryPath = CalculateTemporaryRepositoryPath(TargetUrl, dynamicRepositoryLocation);
var tempRepositoryPath = CalculateTemporaryRepositoryPath(GetTargetUrl(), arguments.DynamicRepositoryLocation);

dynamicGitRepositoryPath = CreateDynamicRepository(tempRepositoryPath, authentication, TargetUrl, currentBranch);
DynamicGitRepositoryPath = CreateDynamicRepository(tempRepositoryPath, authentication, GetTargetUrl(), currentBranch);
}
else
{
Expand All @@ -52,62 +59,49 @@ public void Prepare(bool normalizeGitDirectory, string currentBranch, bool shoul
CleanupDuplicateOrigin();
}

NormalizeGitDirectory(authentication, currentBranch, GetDotGitDirectory(), IsDynamicGitRepository());
NormalizeGitDirectory(authentication, currentBranch, GetDotGitDirectoryInternal(), IsDynamicGitRepository);
}
}
}

public TResult WithRepository<TResult>(Func<IRepository, TResult> action)
private string GetDotGitDirectoryInternal()
{
using IRepository repo = new Repository(GetDotGitDirectory());
return action(repo);
}

public string GetDotGitDirectory()
{
var dotGitDirectory = IsDynamicGitRepository() ? dynamicGitRepositoryPath : Repository.Discover(WorkingDirectory);

dotGitDirectory = dotGitDirectory?.TrimEnd('/', '\\');
if (string.IsNullOrEmpty(dotGitDirectory))
throw new DirectoryNotFoundException("Can't find the .git directory in " + WorkingDirectory);
var gitDirectory = IsDynamicGitRepository ? DynamicGitRepositoryPath : Repository.Discover(GetWorkingDirectory());

if (dotGitDirectory.Contains(Path.Combine(".git", "worktrees")))
return Directory.GetParent(Directory.GetParent(dotGitDirectory).FullName).FullName;
gitDirectory = gitDirectory?.TrimEnd('/', '\\');
if (string.IsNullOrEmpty(gitDirectory))
throw new DirectoryNotFoundException("Can't find the .git directory in " + gitDirectory);

return dotGitDirectory;
return gitDirectory.Contains(Path.Combine(".git", "worktrees"))
? Directory.GetParent(Directory.GetParent(gitDirectory).FullName).FullName
: gitDirectory;
}

public string GetProjectRootDirectory()
public string GetProjectRootDirectoryInternal()
{
log.Info($"IsDynamicGitRepository: {IsDynamicGitRepository()}");
if (IsDynamicGitRepository())
log.Info($"IsDynamicGitRepository: {IsDynamicGitRepository}");
if (IsDynamicGitRepository)
{
log.Info($"Returning Project Root as {WorkingDirectory}");
return WorkingDirectory;
log.Info($"Returning Project Root as {GetWorkingDirectory()}");
return GetWorkingDirectory();
}

var dotGitDirectory = Repository.Discover(WorkingDirectory);
var dotGitDirectory = Repository.Discover(GetWorkingDirectory());

if (string.IsNullOrEmpty(dotGitDirectory))
throw new DirectoryNotFoundException($"Can't find the .git directory in {WorkingDirectory}");
throw new DirectoryNotFoundException($"Can't find the .git directory in {dotGitDirectory}");

using var repo = new Repository(dotGitDirectory);
var result = repo.Info.WorkingDirectory;
log.Info($"Returning Project Root from DotGitDirectory: {dotGitDirectory} - {result}");
return result;
}

public string TargetUrl { get; }

public string WorkingDirectory { get; }

private bool IsDynamicGitRepository() => !string.IsNullOrWhiteSpace(dynamicGitRepositoryPath);

private void CleanupDuplicateOrigin()
{
var remoteToKeep = DefaultRemoteName;

using var repo = new Repository(GetDotGitDirectory());
using var repo = new Repository(GetDotGitDirectoryInternal());

// check that we have a remote that matches defaultRemoteName if not take the first remote
if (!repo.Network.Remotes.Any(remote => remote.Name.Equals(DefaultRemoteName, StringComparison.InvariantCultureIgnoreCase)))
Expand Down Expand Up @@ -193,7 +187,7 @@ private void NormalizeGitDirectory(AuthenticationInfo auth, string targetBranch,
using (log.IndentLog($"Normalizing git directory for branch '{targetBranch}'"))
{
// Normalize (download branches) before using the branch
GitRepositoryHelper.NormalizeGitDirectory(log, environment, gitDirectory, auth, arguments.NoFetch, targetBranch, isDynamicRepository);
GitRepositoryHelper.NormalizeGitDirectory(log, environment, gitDirectory, auth, options.Value.NoFetch, targetBranch, isDynamicRepository);
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/GitVersionCore/GitVersionCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using GitVersion.Cache;
using GitVersion.Logging;
using Microsoft.Extensions.Options;
using GitVersion.Extensions;

namespace GitVersion
{
Expand All @@ -18,7 +19,7 @@ public class GitVersionCalculator : IGitVersionCalculator
private readonly IGitVersionFinder gitVersionFinder;
private readonly IGitPreparer gitPreparer;
private readonly IVariableProvider variableProvider;
private readonly Arguments arguments;
private readonly IOptions<Arguments> options;

public GitVersionCalculator(IFileSystem fileSystem, ILog log, IConfigFileLocator configFileLocator,
IConfigProvider configProvider,
Expand All @@ -34,11 +35,12 @@ public GitVersionCalculator(IFileSystem fileSystem, ILog log, IConfigFileLocator
this.gitVersionFinder = gitVersionFinder ?? throw new ArgumentNullException(nameof(gitVersionFinder));
this.gitPreparer = gitPreparer ?? throw new ArgumentNullException(nameof(gitPreparer));
this.variableProvider = variableProvider ?? throw new ArgumentNullException(nameof(variableProvider));
this.arguments = options.Value;
this.options = options ?? throw new ArgumentNullException(nameof(options));
}

public VersionVariables CalculateVersionVariables()
{
var arguments = options.Value;
var buildServer = buildServerResolver.Resolve();

// Normalize if we are running on build server
Expand Down Expand Up @@ -119,7 +121,7 @@ private VersionVariables ExecuteInternal(string targetBranch, string commitId, C
{
var configuration = configProvider.Provide(overrideConfig: overrideConfig);

return gitPreparer.WithRepository(repo =>
return gitPreparer.GetDotGitDirectory().WithRepository(repo =>
{
var gitVersionContext = new GitVersionContext(repo, log, targetBranch, configuration, commitId: commitId);
var semanticVersion = gitVersionFinder.FindVersion(gitVersionContext);
Expand Down
10 changes: 3 additions & 7 deletions src/GitVersionCore/IGitPreparer.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
using System;
using LibGit2Sharp;

namespace GitVersion
{
public interface IGitPreparer
{
void Prepare(bool normalizeGitDirectory, string currentBranch, bool shouldCleanUpRemotes = false);
TResult WithRepository<TResult>(Func<IRepository, TResult> action);
string GetDotGitDirectory();
string GetProjectRootDirectory();
string TargetUrl { get; }
string WorkingDirectory { get; }
string GetDotGitDirectory();
string GetTargetUrl();
string GetWorkingDirectory();
}
}
8 changes: 5 additions & 3 deletions src/GitVersionExe/ExecCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ public class ExecCommand : IExecCommand
private readonly IBuildServerResolver buildServerResolver;
private readonly ILog log;
private readonly IGitVersionCalculator gitVersionCalculator;
private readonly Arguments arguments;
private readonly IOptions<Arguments> options;
public static readonly string BuildTool = GetMsBuildToolPath();

public ExecCommand(IFileSystem fileSystem, IBuildServerResolver buildServerResolver, ILog log, IGitVersionCalculator gitVersionCalculator, IOptions<Arguments> arguments)
public ExecCommand(IFileSystem fileSystem, IBuildServerResolver buildServerResolver, ILog log, IGitVersionCalculator gitVersionCalculator, IOptions<Arguments> options)
{
this.fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
this.buildServerResolver = buildServerResolver ?? throw new ArgumentNullException(nameof(buildServerResolver));
this.log = log ?? throw new ArgumentNullException(nameof(log));
this.gitVersionCalculator = gitVersionCalculator ?? throw new ArgumentNullException(nameof(gitVersionCalculator));
this.arguments = arguments.Value;
this.options = options ?? throw new ArgumentNullException(nameof(options));
}

public void Execute()
Expand All @@ -39,6 +39,8 @@ public void Execute()

var variables = gitVersionCalculator.CalculateVersionVariables();

var arguments = options.Value;

switch (arguments.Output)
{
case OutputType.BuildServer:
Expand Down
10 changes: 6 additions & 4 deletions src/GitVersionExe/GitVersionApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,22 @@ internal class GitVersionApp : IHostedService
{
private readonly IHostApplicationLifetime applicationLifetime;
private readonly IGitVersionExecutor gitVersionExecutor;
private readonly Arguments arguments;
private readonly ILog log;
private readonly IOptions<Arguments> options;

public GitVersionApp(IHostApplicationLifetime applicationLifetime, IGitVersionExecutor gitVersionExecutor, ILog log, IOptions<Arguments> options)
{
this.arguments = options.Value;
this.options = options ?? throw new ArgumentNullException(nameof(options));
this.applicationLifetime = applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime));
this.gitVersionExecutor = gitVersionExecutor ?? throw new ArgumentNullException(nameof(gitVersionExecutor));

log.Verbosity = arguments.Verbosity;
this.log = log ?? throw new ArgumentNullException(nameof(log));
}
public Task StartAsync(CancellationToken cancellationToken)
{
try
{
var arguments = options.Value;
log.Verbosity = arguments.Verbosity;
gitVersionExecutor.Execute(arguments);
}
catch (Exception exception)
Expand Down