Skip to content
This repository was archived by the owner on Jun 27, 2019. It is now read-only.

Commit fc0ec46

Browse files
Moved some classes over from GitVersion to support dynamic repositories
1 parent 98564e9 commit fc0ec46

File tree

8 files changed

+541
-3
lines changed

8 files changed

+541
-3
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace GitTools
2+
{
3+
using System;
4+
using System.Runtime.Serialization;
5+
6+
[Serializable]
7+
public class WarningException : Exception
8+
{
9+
public WarningException(string message)
10+
: base(message)
11+
{
12+
}
13+
14+
protected WarningException(SerializationInfo info, StreamingContext context)
15+
: base(info, context)
16+
{
17+
}
18+
}
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace GitTools.Git
2+
{
3+
using System.IO;
4+
using LibGit2Sharp;
5+
6+
public class GitDirFinder
7+
{
8+
public static string TreeWalkForDotGitDir(string currentDirectory)
9+
{
10+
var gitDirectory = Repository.Discover(currentDirectory);
11+
12+
if (gitDirectory != null)
13+
{
14+
return gitDirectory.TrimEnd(Path.DirectorySeparatorChar);
15+
}
16+
17+
return null;
18+
}
19+
}
20+
}
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
namespace GitTools.Git
2+
{
3+
using System;
4+
using System.IO;
5+
using System.Linq;
6+
using LibGit2Sharp;
7+
using Logging;
8+
9+
public class GitPreparer
10+
{
11+
private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
12+
13+
string targetUrl;
14+
string dynamicRepositoryLocation;
15+
AuthenticationInfo authentication;
16+
bool noFetch;
17+
string targetPath;
18+
19+
public GitPreparer(string targetUrl, string dynamicRepositoryLocation, AuthenticationInfo authentication, bool noFetch, string targetPath)
20+
{
21+
this.targetUrl = targetUrl;
22+
this.dynamicRepositoryLocation = dynamicRepositoryLocation;
23+
this.authentication = authentication ?? new AuthenticationInfo();
24+
this.noFetch = noFetch;
25+
this.targetPath = targetPath;
26+
}
27+
28+
public bool IsDynamicGitRepository
29+
{
30+
get { return !string.IsNullOrWhiteSpace(DynamicGitRepositoryPath); }
31+
}
32+
33+
public string DynamicGitRepositoryPath { get; private set; }
34+
35+
public void Initialise(bool normaliseGitDirectory, string currentBranch)
36+
{
37+
if (string.IsNullOrWhiteSpace(targetUrl))
38+
{
39+
if (normaliseGitDirectory)
40+
{
41+
GitHelper.NormalizeGitDirectory(GetDotGitDirectory(), authentication, noFetch, currentBranch);
42+
}
43+
return;
44+
}
45+
46+
var tempRepositoryPath = CalculateTemporaryRepositoryPath(targetUrl, dynamicRepositoryLocation);
47+
48+
DynamicGitRepositoryPath = CreateDynamicRepository(tempRepositoryPath, authentication, targetUrl, currentBranch, noFetch);
49+
}
50+
51+
static string CalculateTemporaryRepositoryPath(string targetUrl, string dynamicRepositoryLocation)
52+
{
53+
var userTemp = dynamicRepositoryLocation ?? Path.GetTempPath();
54+
var repositoryName = targetUrl.Split('/', '\\').Last().Replace(".git", string.Empty);
55+
var possiblePath = Path.Combine(userTemp, repositoryName);
56+
57+
// Verify that the existing directory is ok for us to use
58+
if (Directory.Exists(possiblePath))
59+
{
60+
if (!GitRepoHasMatchingRemote(possiblePath, targetUrl))
61+
{
62+
var i = 1;
63+
var originalPath = possiblePath;
64+
bool possiblePathExists;
65+
do
66+
{
67+
possiblePath = string.Concat(originalPath, "_", i++.ToString());
68+
possiblePathExists = Directory.Exists(possiblePath);
69+
} while (possiblePathExists && !GitRepoHasMatchingRemote(possiblePath, targetUrl));
70+
}
71+
}
72+
73+
return possiblePath;
74+
}
75+
76+
static bool GitRepoHasMatchingRemote(string possiblePath, string targetUrl)
77+
{
78+
try
79+
{
80+
using (var repository = new Repository(possiblePath))
81+
{
82+
return repository.Network.Remotes.Any(r => r.Url == targetUrl);
83+
}
84+
}
85+
catch (Exception)
86+
{
87+
return false;
88+
}
89+
}
90+
91+
public string GetDotGitDirectory()
92+
{
93+
if (IsDynamicGitRepository)
94+
{
95+
return DynamicGitRepositoryPath;
96+
}
97+
98+
return GitDirFinder.TreeWalkForDotGitDir(targetPath);
99+
}
100+
101+
public string GetProjectRootDirectory()
102+
{
103+
if (IsDynamicGitRepository)
104+
{
105+
return targetPath;
106+
}
107+
108+
return Directory.GetParent(GitDirFinder.TreeWalkForDotGitDir(targetPath)).FullName;
109+
}
110+
111+
static string CreateDynamicRepository(string targetPath, AuthenticationInfo authentication, string repositoryUrl, string targetBranch, bool noFetch)
112+
{
113+
if (string.IsNullOrWhiteSpace(targetBranch))
114+
{
115+
throw new Exception("Dynamic Git repositories must have a target branch (/b)");
116+
}
117+
118+
Log.Info(string.Format("Creating dynamic repository at '{0}'", targetPath));
119+
120+
var gitDirectory = Path.Combine(targetPath, ".git");
121+
if (Directory.Exists(targetPath))
122+
{
123+
Log.Info("Git repository already exists");
124+
GitHelper.NormalizeGitDirectory(gitDirectory, authentication, noFetch, targetBranch);
125+
126+
return gitDirectory;
127+
}
128+
129+
CloneRepository(repositoryUrl, gitDirectory, authentication);
130+
131+
// Normalize (download branches) before using the branch
132+
GitHelper.NormalizeGitDirectory(gitDirectory, authentication, noFetch, targetBranch);
133+
134+
return gitDirectory;
135+
}
136+
137+
private static void CloneRepository(string repositoryUrl, string gitDirectory, AuthenticationInfo authentication)
138+
{
139+
Credentials credentials = null;
140+
if (!string.IsNullOrWhiteSpace(authentication.Username) && !string.IsNullOrWhiteSpace(authentication.Password))
141+
{
142+
Log.Info(string.Format("Setting up credentials using name '{0}'", authentication.Username));
143+
144+
credentials = new UsernamePasswordCredentials
145+
{
146+
Username = authentication.Username,
147+
Password = authentication.Password
148+
};
149+
}
150+
151+
Log.Info(string.Format("Retrieving git info from url '{0}'", repositoryUrl));
152+
153+
try
154+
{
155+
Repository.Clone(repositoryUrl, gitDirectory,
156+
new CloneOptions
157+
{
158+
Checkout = false,
159+
CredentialsProvider = (url, usernameFromUrl, types) => credentials
160+
});
161+
}
162+
catch (LibGit2SharpException ex)
163+
{
164+
var message = ex.Message;
165+
if (message.Contains("401"))
166+
{
167+
throw new Exception("Unauthorised: Incorrect username/password");
168+
}
169+
if (message.Contains("403"))
170+
{
171+
throw new Exception("Forbidden: Possbily Incorrect username/password");
172+
}
173+
if (message.Contains("404"))
174+
{
175+
throw new Exception("Not found: The repository was not found");
176+
}
177+
178+
throw new Exception("There was an unknown problem with the Git repository you provided");
179+
}
180+
}
181+
}
182+
}

0 commit comments

Comments
 (0)