Skip to content

Commit ce79e55

Browse files
committed
Dynamic repositories now are created in %tmp%
1 parent fb6e497 commit ce79e55

File tree

3 files changed

+168
-61
lines changed

3 files changed

+168
-61
lines changed

GitVersionExe.Tests/GitPreparerTests.cs

Lines changed: 99 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.IO;
1+
using System;
2+
using System.IO;
3+
using System.Linq;
24
using GitVersion;
35
using LibGit2Sharp;
46
using NUnit.Framework;
@@ -24,58 +26,119 @@ public GitPreparerTests()
2426
[TestCase(SpecificBranchName, SpecificBranchName, true)]
2527
public void WorksCorrectlyWithRemoteRepository(string branchName, string expectedBranchName, bool checkConfig)
2628
{
27-
var tempDir = Path.GetTempPath();
29+
var repoName = Guid.NewGuid().ToString();
30+
var tempPath = Path.GetTempPath();
31+
var tempDir = Path.Combine(tempPath, repoName);
32+
Directory.CreateDirectory(tempDir);
33+
string dynamicRepositoryPath = null;
2834

29-
using (var fixture = new EmptyRepositoryFixture(new Config()))
35+
try
3036
{
31-
fixture.Repository.MakeCommits(5);
32-
33-
if (checkConfig)
37+
using (var fixture = new EmptyRepositoryFixture(new Config()))
3438
{
35-
fixture.Repository.CreateFileAndCommit("GitVersionConfig.yaml");
36-
}
39+
var expectedDynamicRepoLocation = Path.Combine(tempPath, fixture.RepositoryPath.Split('\\').Last());
3740

38-
fixture.Repository.CreateBranch(SpecificBranchName);
41+
fixture.Repository.MakeCommits(5);
42+
fixture.Repository.CreateFileAndCommit("TestFile.txt");
3943

40-
if (checkConfig)
41-
{
42-
fixture.Repository.Refs.UpdateTarget(fixture.Repository.Refs.Head, fixture.Repository.Refs["refs/heads/" + SpecificBranchName]);
44+
if (checkConfig)
45+
{
46+
fixture.Repository.CreateFileAndCommit("GitVersionConfig.yaml");
47+
}
4348

44-
fixture.Repository.CreateFileAndCommit("GitVersionConfig.yaml");
49+
fixture.Repository.CreateBranch(SpecificBranchName);
4550

46-
fixture.Repository.Refs.UpdateTarget(fixture.Repository.Refs.Head, fixture.Repository.Refs["refs/heads/" + DefaultBranchName]);
47-
}
51+
if (checkConfig)
52+
{
53+
fixture.Repository.Refs.UpdateTarget(fixture.Repository.Refs.Head, fixture.Repository.Refs["refs/heads/" + SpecificBranchName]);
4854

49-
var arguments = new Arguments
50-
{
51-
TargetPath = tempDir,
52-
TargetUrl = fixture.RepositoryPath
53-
};
55+
fixture.Repository.CreateFileAndCommit("GitVersionConfig.yaml");
5456

55-
if (!string.IsNullOrWhiteSpace(branchName))
56-
{
57-
arguments.TargetBranch = branchName;
58-
}
57+
fixture.Repository.Refs.UpdateTarget(fixture.Repository.Refs.Head, fixture.Repository.Refs["refs/heads/" + DefaultBranchName]);
58+
}
59+
60+
var arguments = new Arguments
61+
{
62+
TargetPath = tempDir,
63+
TargetUrl = fixture.RepositoryPath
64+
};
5965

60-
var gitPreparer = new GitPreparer(arguments);
61-
var dynamicRepositoryPath = gitPreparer.Prepare();
66+
// Copy contents into working directory
67+
File.Copy(Path.Combine(fixture.RepositoryPath, "TestFile.txt"), Path.Combine(tempDir, "TestFile.txt"));
6268

63-
dynamicRepositoryPath.ShouldBe(Path.Combine(tempDir, "_dynamicrepository", ".git"));
64-
gitPreparer.IsDynamicGitRepository.ShouldBe(true);
69+
if (!string.IsNullOrWhiteSpace(branchName))
70+
{
71+
arguments.TargetBranch = branchName;
72+
}
6573

66-
using (var repository = new Repository(dynamicRepositoryPath))
67-
{
68-
var currentBranch = repository.Head.CanonicalName;
74+
var gitPreparer = new GitPreparer(arguments);
75+
gitPreparer.InitialiseDynamicRepositoryIfNeeded();
76+
dynamicRepositoryPath = gitPreparer.GetDotGitDirectory();
6977

70-
currentBranch.EndsWith(expectedBranchName).ShouldBe(true);
78+
gitPreparer.IsDynamicGitRepository.ShouldBe(true);
79+
gitPreparer.DynamicGitRepositoryPath.ShouldBe(expectedDynamicRepoLocation + "\\.git");
7180

72-
if (checkConfig)
81+
using (var repository = new Repository(dynamicRepositoryPath))
7382
{
74-
var expectedConfigPath = Path.Combine(dynamicRepositoryPath, "..\\GitVersionConfig.yaml");
75-
File.Exists(expectedConfigPath).ShouldBe(true);
83+
var currentBranch = repository.Head.CanonicalName;
84+
85+
currentBranch.EndsWith(expectedBranchName).ShouldBe(true);
86+
87+
if (checkConfig)
88+
{
89+
var expectedConfigPath = Path.Combine(dynamicRepositoryPath, "..\\GitVersionConfig.yaml");
90+
File.Exists(expectedConfigPath).ShouldBe(true);
91+
}
7692
}
7793
}
7894
}
95+
finally
96+
{
97+
Directory.Delete(tempDir, true);
98+
if (dynamicRepositoryPath != null)
99+
DeleteHelper.DeleteGitRepository(dynamicRepositoryPath);
100+
}
101+
}
102+
103+
[Test]
104+
public void PicksAnotherDirectoryNameWhenDynamicRepoFolderTaken()
105+
{
106+
var repoName = Guid.NewGuid().ToString();
107+
var tempPath = Path.GetTempPath();
108+
var tempDir = Path.Combine(tempPath, repoName);
109+
Directory.CreateDirectory(tempDir);
110+
string expectedDynamicRepoLocation = null;
111+
112+
try
113+
{
114+
using (var fixture = new EmptyRepositoryFixture(new Config()))
115+
{
116+
fixture.Repository.CreateFileAndCommit("TestFile.txt");
117+
File.Copy(Path.Combine(fixture.RepositoryPath, "TestFile.txt"), Path.Combine(tempDir, "TestFile.txt"));
118+
expectedDynamicRepoLocation = Path.Combine(tempPath, fixture.RepositoryPath.Split('\\').Last());
119+
Directory.CreateDirectory(expectedDynamicRepoLocation);
120+
121+
var arguments = new Arguments
122+
{
123+
TargetPath = tempDir,
124+
TargetUrl = fixture.RepositoryPath
125+
};
126+
127+
var gitPreparer = new GitPreparer(arguments);
128+
gitPreparer.InitialiseDynamicRepositoryIfNeeded();
129+
130+
gitPreparer.IsDynamicGitRepository.ShouldBe(true);
131+
gitPreparer.DynamicGitRepositoryPath.ShouldBe(expectedDynamicRepoLocation + "_1\\.git");
132+
}
133+
}
134+
finally
135+
{
136+
Directory.Delete(tempDir, true);
137+
if (expectedDynamicRepoLocation != null)
138+
Directory.Delete(expectedDynamicRepoLocation, true);
139+
if (expectedDynamicRepoLocation != null)
140+
DeleteHelper.DeleteGitRepository(expectedDynamicRepoLocation + "_1");
141+
}
79142
}
80143

81144
[Test]
@@ -89,7 +152,7 @@ public void WorksCorrectlyWithLocalRepository()
89152
};
90153

91154
var gitPreparer = new GitPreparer(arguments);
92-
var dynamicRepositoryPath = gitPreparer.Prepare();
155+
var dynamicRepositoryPath = gitPreparer.GetDotGitDirectory();
93156

94157
dynamicRepositoryPath.ShouldBe(null);
95158
gitPreparer.IsDynamicGitRepository.ShouldBe(false);

GitVersionExe/GitPreparer.cs

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
namespace GitVersion
22
{
3+
using System;
34
using System.IO;
45
using System.Linq;
56
using LibGit2Sharp;
@@ -20,31 +21,76 @@ public bool IsDynamicGitRepository
2021

2122
public string DynamicGitRepositoryPath { get; private set; }
2223

23-
public string Prepare()
24+
public void InitialiseDynamicRepositoryIfNeeded()
2425
{
25-
var gitPath = arguments.TargetPath;
26+
if (string.IsNullOrWhiteSpace(arguments.TargetUrl)) return;
2627

27-
if (!string.IsNullOrWhiteSpace(arguments.TargetUrl))
28+
var targetPath = CalculateTemporaryRepositoryPath(arguments.TargetUrl);
29+
DynamicGitRepositoryPath = CreateDynamicRepository(targetPath, arguments.Authentication, arguments.TargetUrl, arguments.TargetBranch);
30+
}
31+
32+
string CalculateTemporaryRepositoryPath(string targetUrl)
33+
{
34+
var userTemp = Path.GetTempPath();
35+
var repositoryName = targetUrl.EndsWith(".git") ?
36+
targetUrl.Split('/', '\\').Last().Replace(".git", string.Empty) :
37+
targetUrl.Split('/', '\\').Last();
38+
var possiblePath = Path.Combine(userTemp, repositoryName);
39+
40+
// Verify that the existing directory is ok for us to use
41+
if (Directory.Exists(possiblePath))
42+
{
43+
if (!GitRepoHasMatchingRemote(possiblePath, targetUrl))
44+
{
45+
var i = 1;
46+
var originalPath = possiblePath;
47+
bool possiblePathExists;
48+
do
49+
{
50+
possiblePath = string.Concat(originalPath, "_", i++.ToString());
51+
possiblePathExists = Directory.Exists(possiblePath);
52+
} while (possiblePathExists && !GitRepoHasMatchingRemote(possiblePath, targetUrl));
53+
}
54+
}
55+
56+
return possiblePath;
57+
}
58+
59+
static bool GitRepoHasMatchingRemote(string possiblePath, string targetUrl)
60+
{
61+
try
62+
{
63+
using (var repository = new Repository(possiblePath))
64+
{
65+
return repository.Network.Remotes.Any(r => r.Url == targetUrl);
66+
}
67+
}
68+
catch (Exception)
2869
{
29-
gitPath = GetGitInfoFromUrl();
70+
return false;
3071
}
72+
73+
}
3174

32-
return GitDirFinder.TreeWalkForGitDir(gitPath);
75+
public string GetDotGitDirectory()
76+
{
77+
if (IsDynamicGitRepository)
78+
return DynamicGitRepositoryPath;
79+
80+
return GitDirFinder.TreeWalkForDotGitDir(arguments.TargetPath);
3381
}
3482

35-
string GetGitInfoFromUrl()
83+
static string CreateDynamicRepository(string targetPath, Authentication authentication, string repositoryUrl, string targetBranch)
3684
{
37-
var gitRootDirectory = Path.Combine(arguments.TargetPath, "_dynamicrepository");
38-
var gitDirectory = Path.Combine(gitRootDirectory, ".git");
39-
if (Directory.Exists(gitRootDirectory))
85+
var gitDirectory = Path.Combine(targetPath, ".git");
86+
if (Directory.Exists(targetPath))
4087
{
41-
Logger.WriteInfo(string.Format("Deleting existing .git folder from '{0}' to force new checkout from url", gitRootDirectory));
88+
Logger.WriteInfo(string.Format("Deleting existing .git folder from '{0}' to force new checkout from url", targetPath));
4289

43-
DeleteHelper.DeleteGitRepository(gitRootDirectory);
90+
DeleteHelper.DeleteGitRepository(targetPath);
4491
}
4592

4693
Credentials credentials = null;
47-
var authentication = arguments.Authentication;
4894
if (!string.IsNullOrWhiteSpace(authentication.Username) && !string.IsNullOrWhiteSpace(authentication.Password))
4995
{
5096
Logger.WriteInfo(string.Format("Setting up credentials using name '{0}'", authentication.Username));
@@ -56,9 +102,9 @@ string GetGitInfoFromUrl()
56102
};
57103
}
58104

59-
Logger.WriteInfo(string.Format("Retrieving git info from url '{0}'", arguments.TargetUrl));
105+
Logger.WriteInfo(string.Format("Retrieving git info from url '{0}'", repositoryUrl));
60106

61-
Repository.Clone(arguments.TargetUrl, gitDirectory,
107+
Repository.Clone(repositoryUrl, gitDirectory,
62108
new CloneOptions
63109
{
64110
IsBare = true,
@@ -67,11 +113,10 @@ string GetGitInfoFromUrl()
67113
});
68114

69115
// Normalize (download branches) before using the branch
70-
GitHelper.NormalizeGitDirectory(gitDirectory, arguments.Authentication);
116+
GitHelper.NormalizeGitDirectory(gitDirectory, authentication);
71117

72118
using (var repository = new Repository(gitDirectory))
73119
{
74-
var targetBranch = arguments.TargetBranch;
75120
if (string.IsNullOrWhiteSpace(targetBranch))
76121
{
77122
targetBranch = repository.Head.Name;
@@ -87,10 +132,10 @@ string GetGitInfoFromUrl()
87132

88133
if (newHead == null)
89134
{
90-
var remoteReference = GetRemoteReference(repository, targetBranch, arguments.TargetUrl);
135+
var remoteReference = GetRemoteReference(repository, targetBranch, repositoryUrl);
91136
if (remoteReference != null)
92137
{
93-
repository.Network.Fetch(arguments.TargetUrl, new[]
138+
repository.Network.Fetch(repositoryUrl, new[]
94139
{
95140
string.Format("{0}:{1}", remoteReference.CanonicalName, targetBranch)
96141
});
@@ -110,8 +155,6 @@ string GetGitInfoFromUrl()
110155
repository.CheckoutFilesIfExist("GitVersionConfig.yaml");
111156
}
112157

113-
DynamicGitRepositoryPath = gitDirectory;
114-
115158
return gitDirectory;
116159
}
117160

GitVersionExe/SpecifiedArgumentRunner.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,23 @@ class SpecifiedArgumentRunner
1212
public static void Run(Arguments arguments, IFileSystem fileSystem)
1313
{
1414
var gitPreparer = new GitPreparer(arguments);
15-
var gitDirectory = gitPreparer.Prepare();
16-
if (string.IsNullOrEmpty(gitDirectory))
15+
gitPreparer.InitialiseDynamicRepositoryIfNeeded();
16+
var dotGitDirectory = gitPreparer.GetDotGitDirectory();
17+
if (string.IsNullOrEmpty(dotGitDirectory))
1718
{
1819
throw new Exception(string.Format("Failed to prepare or find the .git directory in path '{0}'", arguments.TargetPath));
1920
}
2021
var applicableBuildServers = GetApplicableBuildServers(arguments.Authentication).ToList();
2122

2223
foreach (var buildServer in applicableBuildServers)
2324
{
24-
buildServer.PerformPreProcessingSteps(gitDirectory);
25+
buildServer.PerformPreProcessingSteps(dotGitDirectory);
2526
}
2627
VersionVariables variables;
2728
var versionFinder = new GitVersionFinder();
28-
var configuration = ConfigurationProvider.Provide(gitDirectory, fileSystem);
29+
var configuration = ConfigurationProvider.Provide(dotGitDirectory, fileSystem);
2930

30-
using (var repo = RepositoryLoader.GetRepo(gitDirectory))
31+
using (var repo = RepositoryLoader.GetRepo(dotGitDirectory))
3132
{
3233
var gitVersionContext = new GitVersionContext(repo, configuration, commitId: arguments.CommitId);
3334
var semanticVersion = versionFinder.FindVersion(gitVersionContext);

0 commit comments

Comments
 (0)