Skip to content

Commit ca4d15e

Browse files
committed
Make Configuration.BuildFrom() able to probe for the local configuration file
1 parent 5d9f53d commit ca4d15e

File tree

3 files changed

+81
-10
lines changed

3 files changed

+81
-10
lines changed

LibGit2Sharp.Tests/ConfigurationFixture.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34
using System.Linq;
45
using LibGit2Sharp.Tests.TestHelpers;
56
using Xunit;
7+
using Xunit.Extensions;
68

79
namespace LibGit2Sharp.Tests
810
{
@@ -367,8 +369,21 @@ public void CanTellIfASpecificStoreContainsAKey()
367369
}
368370
}
369371

370-
[Fact]
371-
public void CanAccessConfigurationWithoutARepository()
372+
public static IEnumerable<object[]> ConfigAccessors
373+
{
374+
get
375+
{
376+
return new List<object[]>
377+
{
378+
new[] { new Func<string, string>(p => Path.Combine(p, ".git", "config")) },
379+
new[] { new Func<string, string>(p => Path.Combine(p, ".git")) },
380+
new[] { new Func<string, string>(p => p) },
381+
};
382+
}
383+
}
384+
385+
[Theory, PropertyData("ConfigAccessors")]
386+
public void CanAccessConfigurationWithoutARepository(Func<string, string> localConfigurationPathProvider)
372387
{
373388
var path = SandboxStandardTestRepoGitDir();
374389

@@ -381,11 +396,18 @@ public void CanAccessConfigurationWithoutARepository()
381396
repo.Config.Set("my.key", "mouse", ConfigurationLevel.Global);
382397
}
383398

384-
using (var config = Configuration.BuildFrom(Path.Combine(path, ".git", "config"), globalConfigPath))
399+
using (var config = Configuration.BuildFrom(localConfigurationPathProvider(path), globalConfigPath))
385400
{
386401
Assert.Equal("local", config.Get<string>("my.key").Value);
387402
Assert.Equal("mouse", config.Get<string>("my.key", ConfigurationLevel.Global).Value);
388403
}
389404
}
405+
406+
[Fact]
407+
public void PassingANonExistingLocalConfigurationFileToBuildFromthrowss()
408+
{
409+
Assert.Throws<FileNotFoundException>(() => Configuration.BuildFrom(
410+
Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())));
411+
}
390412
}
391413
}

LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,8 @@ protected string CreateConfigurationWithDummyUser(Signature signature)
336336
protected string CreateConfigurationWithDummyUser(string name, string email)
337337
{
338338
SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
339-
Directory.CreateDirectory(scd.DirectoryPath);
340-
string configFilePath = Path.Combine(scd.DirectoryPath, "fake-config");
339+
340+
string configFilePath = Touch(scd.DirectoryPath, "fake-config");
341341

342342
using (Configuration config = Configuration.BuildFrom(configFilePath))
343343
{

LibGit2Sharp/Configuration.cs

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ protected Configuration()
3131
internal Configuration(Repository repository, string repositoryConfigurationFileLocation, string globalConfigurationFileLocation,
3232
string xdgConfigurationFileLocation, string systemConfigurationFileLocation)
3333
{
34-
repoConfigPath = repositoryConfigurationFileLocation;
34+
if (repositoryConfigurationFileLocation != null)
35+
{
36+
repoConfigPath = NormalizeConfigPath(repositoryConfigurationFileLocation);
37+
}
38+
3539
globalConfigPath = globalConfigurationFileLocation ?? Proxy.git_config_find_global();
3640
xdgConfigPath = xdgConfigurationFileLocation ?? Proxy.git_config_find_xdg();
3741
systemConfigPath = systemConfigurationFileLocation ?? Proxy.git_config_find_system();
@@ -75,13 +79,46 @@ private void Init(Repository repository)
7579
}
7680
}
7781

82+
private FilePath NormalizeConfigPath(FilePath path)
83+
{
84+
if (File.Exists(path.Native))
85+
{
86+
return path;
87+
}
88+
89+
if (!Directory.Exists(path.Native))
90+
{
91+
throw new FileNotFoundException("Cannot find repository configuration file", path.Native);
92+
}
93+
94+
var configPath = Path.Combine(path.Native, "config");
95+
96+
if (File.Exists(configPath))
97+
{
98+
return configPath;
99+
}
100+
101+
var gitConfigPath = Path.Combine(path.Native, ".git", "config");
102+
103+
if (File.Exists(gitConfigPath))
104+
{
105+
return gitConfigPath;
106+
}
107+
108+
throw new FileNotFoundException("Cannot find repository configuration file", path.Native);
109+
}
110+
78111
/// <summary>
79112
/// Access configuration values without a repository.
80113
/// <para>
81114
/// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
82115
/// </para>
116+
/// <para>
117+
/// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
118+
/// this can be the working directory, the .git directory or the directory containing a bare repository.
119+
/// </para>
83120
/// </summary>
84-
/// <param name="repositoryConfigurationFileLocation">Path to a Repository configuration file.</param>
121+
/// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
85122
/// <returns>An instance of <see cref="Configuration"/>.</returns>
86123
public static Configuration BuildFrom(
87124
string repositoryConfigurationFileLocation)
@@ -94,8 +131,12 @@ public static Configuration BuildFrom(
94131
/// <para>
95132
/// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
96133
/// </para>
134+
/// <para>
135+
/// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
136+
/// this can be the working directory, the .git directory or the directory containing a bare repository.
137+
/// </para>
97138
/// </summary>
98-
/// <param name="repositoryConfigurationFileLocation">Path to a Repository configuration file.</param>
139+
/// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
99140
/// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a Global configuration file will be probed.</param>
100141
/// <returns>An instance of <see cref="Configuration"/>.</returns>
101142
public static Configuration BuildFrom(
@@ -110,8 +151,12 @@ public static Configuration BuildFrom(
110151
/// <para>
111152
/// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
112153
/// </para>
154+
/// <para>
155+
/// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
156+
/// this can be the working directory, the .git directory or the directory containing a bare repository.
157+
/// </para>
113158
/// </summary>
114-
/// <param name="repositoryConfigurationFileLocation">Path to a Repository configuration file.</param>
159+
/// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
115160
/// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a Global configuration file will be probed.</param>
116161
/// <param name="xdgConfigurationFileLocation">Path to a XDG configuration file. If null, the default path for a XDG configuration file will be probed.</param>
117162
/// <returns>An instance of <see cref="Configuration"/>.</returns>
@@ -128,8 +173,12 @@ public static Configuration BuildFrom(
128173
/// <para>
129174
/// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
130175
/// </para>
176+
/// <para>
177+
/// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
178+
/// this can be the working directory, the .git directory or the directory containing a bare repository.
179+
/// </para>
131180
/// </summary>
132-
/// <param name="repositoryConfigurationFileLocation">Path to a Repository configuration file.</param>
181+
/// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
133182
/// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a Global configuration file will be probed.</param>
134183
/// <param name="xdgConfigurationFileLocation">Path to a XDG configuration file. If null, the default path for a XDG configuration file will be probed.</param>
135184
/// <param name="systemConfigurationFileLocation">Path to a System configuration file. If null, the default path for a System configuration file will be probed.</param>

0 commit comments

Comments
 (0)