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

Commit aa313ab

Browse files
committed
Merge pull request #2 from GitTools/feature/extensionmethods
Added extensions methods
2 parents 549a169 + 9de105f commit aa313ab

15 files changed

+519
-3
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace GitTools.Tests
2+
{
3+
using NUnit.Framework;
4+
using Shouldly;
5+
6+
[TestFixture]
7+
public class StringExtensionsFacts
8+
{
9+
[TestCase("/develop", false)]
10+
[TestCase("/master", false)]
11+
[TestCase("/pr/25", true)]
12+
[TestCase("/pull/25", true)]
13+
[TestCase("/pull-requests/25", true)]
14+
public void TheIsPullRequestMethod(string input, bool expectedValue)
15+
{
16+
var actualValue = input.IsPullRequest();
17+
18+
actualValue.ShouldBe(expectedValue);
19+
}
20+
}
21+
}

src/GitTools.Core.Tests/GitTools.Core.Tests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
<HintPath>..\..\lib\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
4040
<Private>True</Private>
4141
</Reference>
42+
<Reference Include="Shouldly, Version=2.5.0.0, Culture=neutral, PublicKeyToken=6042cbcb05cbc941, processorArchitecture=MSIL">
43+
<HintPath>..\..\lib\Shouldly.2.5.0\lib\net40\Shouldly.dll</HintPath>
44+
<Private>True</Private>
45+
</Reference>
4246
<Reference Include="System" />
4347
<Reference Include="System.Core" />
4448
<Reference Include="System.Xml.Linq" />
@@ -54,6 +58,7 @@
5458
<Compile Include="ArgumentParserFacts.cs" />
5559
<Compile Include="ContextFacts.cs" />
5660
<Compile Include="Context\Context.cs" />
61+
<Compile Include="Extensions\StringExtensionsFacts.cs" />
5762
<Compile Include="GlobalInitialization.cs" />
5863
<Compile Include="ModuleInitializer.cs" />
5964
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -70,6 +75,7 @@
7075
<ItemGroup>
7176
<None Include="packages.config" />
7277
</ItemGroup>
78+
<ItemGroup />
7379
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
7480
<Import Project="..\..\lib\Fody.1.28.3\build\Fody.targets" Condition="Exists('..\..\lib\Fody.1.28.3\build\Fody.targets')" />
7581
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

src/GitTools.Core.Tests/packages.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
<package id="Fody" version="1.28.3" targetFramework="net45" developmentDependency="true" />
44
<package id="ModuleInit.Fody" version="1.5.6.0" targetFramework="net45" developmentDependency="true" />
55
<package id="NUnit" version="2.6.4" targetFramework="net45" />
6+
<package id="Shouldly" version="2.5.0" targetFramework="net45" />
67
</packages>

src/GitTools.Core/Constants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
namespace GitTools
22
{
3-
// TODO: Constants go here
3+
// TODO: constants classes go here
44
}

src/GitTools.Core/Extensions/LibGitExtensions.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,91 @@
22
{
33
using System;
44
using System.Collections.Generic;
5+
using System.IO;
56
using System.Linq;
67
using LibGit2Sharp;
8+
using Logging;
79

810
public static class LibGitExtensions
911
{
12+
private static readonly ILog Log = LogProvider.GetCurrentClassLogger();
13+
14+
public static DateTimeOffset When(this Commit commit)
15+
{
16+
return commit.Committer.When;
17+
}
18+
19+
public static Branch FindBranch(this IRepository repository, string branchName)
20+
{
21+
var exact = repository.Branches.FirstOrDefault(x => x.Name == branchName);
22+
if (exact != null)
23+
{
24+
return exact;
25+
}
26+
27+
return repository.Branches.FirstOrDefault(x => x.Name == "origin/" + branchName);
28+
}
29+
1030
public static bool IsDetachedHead(this Branch branch)
1131
{
1232
return branch.CanonicalName.Equals("(no branch)", StringComparison.OrdinalIgnoreCase);
1333
}
1434

35+
public static string GetRepositoryDirectory(this IRepository repository, bool omitGitPostFix = true)
36+
{
37+
var gitDirectory = repository.Info.Path;
38+
39+
gitDirectory = gitDirectory.TrimEnd('\\');
40+
41+
if (omitGitPostFix && gitDirectory.EndsWith(".git"))
42+
{
43+
gitDirectory = gitDirectory.Substring(0, gitDirectory.Length - ".git".Length);
44+
gitDirectory = gitDirectory.TrimEnd('\\');
45+
}
46+
47+
return gitDirectory;
48+
}
49+
50+
public static void CheckoutFilesIfExist(this IRepository repository, params string[] fileNames)
51+
{
52+
if (fileNames == null || fileNames.Length == 0)
53+
{
54+
return;
55+
}
56+
57+
Log.Info("Checking out files that might be needed later in dynamic repository");
58+
59+
foreach (var fileName in fileNames)
60+
{
61+
try
62+
{
63+
Log.Info(" Trying to check out '{0}'", fileName);
64+
65+
var headBranch = repository.Head;
66+
var tip = headBranch.Tip;
67+
68+
var treeEntry = tip[fileName];
69+
if (treeEntry == null)
70+
{
71+
continue;
72+
}
73+
74+
var fullPath = Path.Combine(repository.GetRepositoryDirectory(), fileName);
75+
using (var stream = ((Blob) treeEntry.Target).GetContentStream())
76+
{
77+
using (var streamReader = new BinaryReader(stream))
78+
{
79+
File.WriteAllBytes(fullPath, streamReader.ReadBytes((int)stream.Length));
80+
}
81+
}
82+
}
83+
catch (Exception ex)
84+
{
85+
Log.Warning(" An error occurred while checking out '{0}': '{1}'", fileName, ex.Message);
86+
}
87+
}
88+
}
89+
1590
public static IEnumerable<Branch> GetBranchesContainingCommit(this IRepository repository, string commitSha)
1691
{
1792
var directBranchHasBeenFound = false;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace GitTools
2+
{
3+
using System.Text;
4+
using JetBrains.Annotations;
5+
6+
public static class StringBuilderExtensions
7+
{
8+
[StringFormatMethod("format")]
9+
public static void AppendLineFormat(this StringBuilder stringBuilder, string format, params object[] args)
10+
{
11+
stringBuilder.AppendFormat(format, args);
12+
stringBuilder.AppendLine();
13+
}
14+
}
15+
}

src/GitTools.Core/FodyWeavers.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
LibGit2Sharp
66
</IncludeAssemblies>
77
</Costura>
8-
<ModuleInit/>
9-
<MethodTimer/>
8+
<ModuleInit />
9+
<MethodTimer />
10+
<JetBrainsAnnotations />
1011
</Weavers>

src/GitTools.Core/GitTools.Core.csproj

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
<DocumentationFile>..\..\output\release\GitTools.Core\GitTools.Core.XML</DocumentationFile>
3939
</PropertyGroup>
4040
<ItemGroup>
41+
<Reference Include="JetBrains.Annotations, Version=8.1.11.55, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
42+
<HintPath>..\..\lib\JetBrainsAnnotations.Fody.1.0.2\Lib\JetBrains.Annotations.dll</HintPath>
43+
<Private>False</Private>
44+
</Reference>
4145
<Reference Include="LibGit2Sharp, Version=0.21.0.176, Culture=neutral, processorArchitecture=MSIL">
4246
<HintPath>..\..\lib\LibGit2Sharp.0.21.0.176\lib\net40\LibGit2Sharp.dll</HintPath>
4347
<Private>True</Private>
@@ -60,6 +64,7 @@
6064
</Compile>
6165
<Compile Include="App_Packages\LibLog.4.2\LibLog.cs" />
6266
<Compile Include="Constants.cs" />
67+
<Compile Include="Testing\TestValues.cs" />
6368
<Compile Include="Context\ContextBase.cs" />
6469
<Compile Include="Context\Interfaces\IAuthenticationContext.cs" />
6570
<Compile Include="Context\Interfaces\IContext.cs" />
@@ -68,17 +73,23 @@
6873
<Compile Include="Exceptions\GitToolsException.cs" />
6974
<Compile Include="Extensions\IntExtensions.cs" />
7075
<Compile Include="Extensions\LibGitExtensions.cs" />
76+
<Compile Include="Extensions\StringBuilderExtensions.cs" />
7177
<Compile Include="Extensions\StringExtensions.cs" />
7278
<Compile Include="Git\GitDirFinder.cs" />
7379
<Compile Include="Git\GitPreparer.cs" />
7480
<Compile Include="Git\Interfaces\IRepositoryPreparer.cs" />
7581
<Compile Include="Git\RepositoryLoader.cs" />
7682
<Compile Include="Helpers\DeleteHelper.cs" />
7783
<Compile Include="Helpers\GitHelper.cs" />
84+
<Compile Include="Helpers\ProcessHelper.cs" />
7885
<Compile Include="IO\TemporaryFilesContext.cs" />
7986
<Compile Include="Logging\Extensions\LogExtensions.cs" />
8087
<Compile Include="ModuleInitializer.cs" />
8188
<Compile Include="Properties\AssemblyInfo.cs" />
89+
<Compile Include="Testing\Extensions\GitTestExtensions.cs" />
90+
<Compile Include="Testing\Fixtures\EmptyRepositoryFixture.cs" />
91+
<Compile Include="Testing\Fixtures\RemoteRepositoryFixture.cs" />
92+
<Compile Include="Testing\Fixtures\RepositoryFixtureBase.cs" />
8293
</ItemGroup>
8394
<ItemGroup>
8495
<EmbeddedResource Include="..\..\lib\LibGit2Sharp.0.21.0.176\lib\net40\NativeBinaries\amd64\git2-e0902fb.dll">
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
namespace GitTools
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Diagnostics;
6+
using System.IO;
7+
using System.Runtime.InteropServices;
8+
using System.Threading;
9+
10+
public static class ProcessHelper
11+
{
12+
private static volatile object _lockObject = new object();
13+
14+
// http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/f6069441-4ab1-4299-ad6a-b8bb9ed36be3
15+
public static Process Start(ProcessStartInfo startInfo)
16+
{
17+
Process process;
18+
19+
lock (_lockObject)
20+
{
21+
using (new ChangeErrorMode(ErrorModes.FailCriticalErrors | ErrorModes.NoGpFaultErrorBox))
22+
{
23+
process = Process.Start(startInfo);
24+
process.PriorityClass = ProcessPriorityClass.Idle;
25+
}
26+
}
27+
28+
return process;
29+
}
30+
31+
// http://csharptest.net/532/using-processstart-to-capture-console-output/
32+
public static int Run(Action<string> output, Action<string> errorOutput, TextReader input, string exe, string args, string workingDirectory, params KeyValuePair<string, string>[] environmentalVariables)
33+
{
34+
if (String.IsNullOrEmpty(exe))
35+
{
36+
throw new FileNotFoundException();
37+
}
38+
39+
if (output == null)
40+
{
41+
throw new ArgumentNullException("output");
42+
}
43+
44+
var psi = new ProcessStartInfo
45+
{
46+
UseShellExecute = false,
47+
RedirectStandardError = true,
48+
RedirectStandardOutput = true,
49+
RedirectStandardInput = true,
50+
WindowStyle = ProcessWindowStyle.Hidden,
51+
CreateNoWindow = true,
52+
ErrorDialog = false,
53+
WorkingDirectory = workingDirectory ?? Environment.CurrentDirectory,
54+
FileName = exe,
55+
Arguments = args
56+
};
57+
58+
foreach (var environmentalVariable in environmentalVariables)
59+
{
60+
if (!psi.EnvironmentVariables.ContainsKey(environmentalVariable.Key) && environmentalVariable.Value != null)
61+
psi.EnvironmentVariables.Add(environmentalVariable.Key, environmentalVariable.Value);
62+
if (psi.EnvironmentVariables.ContainsKey(environmentalVariable.Key) && environmentalVariable.Value == null)
63+
psi.EnvironmentVariables.Remove(environmentalVariable.Key);
64+
}
65+
66+
using (var process = Process.Start(psi))
67+
{
68+
using (var mreOut = new ManualResetEvent(false))
69+
{
70+
using (var mreErr = new ManualResetEvent(false))
71+
{
72+
process.EnableRaisingEvents = true;
73+
process.OutputDataReceived += (o, e) =>
74+
{
75+
// ReSharper disable once AccessToDisposedClosure
76+
if (e.Data == null)
77+
{
78+
mreOut.Set();
79+
}
80+
else
81+
{
82+
output(e.Data);
83+
}
84+
};
85+
process.BeginOutputReadLine();
86+
process.ErrorDataReceived += (o, e) =>
87+
{
88+
// ReSharper disable once AccessToDisposedClosure
89+
if (e.Data == null)
90+
{
91+
mreErr.Set();
92+
}
93+
else
94+
{
95+
errorOutput(e.Data);
96+
}
97+
};
98+
99+
process.BeginErrorReadLine();
100+
101+
string line;
102+
while (input != null && null != (line = input.ReadLine()))
103+
{
104+
process.StandardInput.WriteLine(line);
105+
}
106+
107+
process.StandardInput.Close();
108+
process.WaitForExit();
109+
110+
mreOut.WaitOne();
111+
mreErr.WaitOne();
112+
113+
return process.ExitCode;
114+
}
115+
}
116+
}
117+
}
118+
119+
[Flags]
120+
public enum ErrorModes
121+
{
122+
Default = 0x0,
123+
FailCriticalErrors = 0x1,
124+
NoGpFaultErrorBox = 0x2,
125+
NoAlignmentFaultExcept = 0x4,
126+
NoOpenFileErrorBox = 0x8000
127+
}
128+
129+
public struct ChangeErrorMode : IDisposable
130+
{
131+
private readonly int _oldMode;
132+
133+
public ChangeErrorMode(ErrorModes mode)
134+
{
135+
_oldMode = SetErrorMode((int)mode);
136+
}
137+
138+
void IDisposable.Dispose() { SetErrorMode(_oldMode); }
139+
140+
[DllImport("kernel32.dll")]
141+
static extern int SetErrorMode(int newMode);
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)