Skip to content

Commit b03c9d1

Browse files
committed
Make Configuration.BuildFrom() able to probe for the local configuration file
1 parent 76e88dd commit b03c9d1

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
@@ -35,7 +35,11 @@ internal Configuration(Repository repository, string repositoryConfigurationFile
3535
{
3636
this.repository = repository;
3737

38-
repoConfigPath = repositoryConfigurationFileLocation;
38+
if (repositoryConfigurationFileLocation != null)
39+
{
40+
repoConfigPath = NormalizeConfigPath(repositoryConfigurationFileLocation);
41+
}
42+
3943
globalConfigPath = globalConfigurationFileLocation ?? Proxy.git_config_find_global();
4044
xdgConfigPath = xdgConfigurationFileLocation ?? Proxy.git_config_find_xdg();
4145
systemConfigPath = systemConfigurationFileLocation ?? Proxy.git_config_find_system();
@@ -79,13 +83,46 @@ private void Init()
7983
}
8084
}
8185

86+
private FilePath NormalizeConfigPath(FilePath path)
87+
{
88+
if (File.Exists(path.Native))
89+
{
90+
return path;
91+
}
92+
93+
if (!Directory.Exists(path.Native))
94+
{
95+
throw new FileNotFoundException("Cannot find repository configuration file", path.Native);
96+
}
97+
98+
var configPath = Path.Combine(path.Native, "config");
99+
100+
if (File.Exists(configPath))
101+
{
102+
return configPath;
103+
}
104+
105+
var gitConfigPath = Path.Combine(path.Native, ".git", "config");
106+
107+
if (File.Exists(gitConfigPath))
108+
{
109+
return gitConfigPath;
110+
}
111+
112+
throw new FileNotFoundException("Cannot find repository configuration file", path.Native);
113+
}
114+
82115
/// <summary>
83116
/// Access configuration values without a repository.
84117
/// <para>
85118
/// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
86119
/// </para>
120+
/// <para>
121+
/// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
122+
/// this can be the working directory, the .git directory or the directory containing a bare repository.
123+
/// </para>
87124
/// </summary>
88-
/// <param name="repositoryConfigurationFileLocation">Path to a Repository configuration file.</param>
125+
/// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
89126
/// <returns>An instance of <see cref="Configuration"/>.</returns>
90127
public static Configuration BuildFrom(
91128
string repositoryConfigurationFileLocation)
@@ -98,8 +135,12 @@ public static Configuration BuildFrom(
98135
/// <para>
99136
/// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
100137
/// </para>
138+
/// <para>
139+
/// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
140+
/// this can be the working directory, the .git directory or the directory containing a bare repository.
141+
/// </para>
101142
/// </summary>
102-
/// <param name="repositoryConfigurationFileLocation">Path to a Repository configuration file.</param>
143+
/// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
103144
/// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a Global configuration file will be probed.</param>
104145
/// <returns>An instance of <see cref="Configuration"/>.</returns>
105146
public static Configuration BuildFrom(
@@ -114,8 +155,12 @@ public static Configuration BuildFrom(
114155
/// <para>
115156
/// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
116157
/// </para>
158+
/// <para>
159+
/// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
160+
/// this can be the working directory, the .git directory or the directory containing a bare repository.
161+
/// </para>
117162
/// </summary>
118-
/// <param name="repositoryConfigurationFileLocation">Path to a Repository configuration file.</param>
163+
/// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
119164
/// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a Global configuration file will be probed.</param>
120165
/// <param name="xdgConfigurationFileLocation">Path to a XDG configuration file. If null, the default path for a XDG configuration file will be probed.</param>
121166
/// <returns>An instance of <see cref="Configuration"/>.</returns>
@@ -132,8 +177,12 @@ public static Configuration BuildFrom(
132177
/// <para>
133178
/// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
134179
/// </para>
180+
/// <para>
181+
/// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
182+
/// this can be the working directory, the .git directory or the directory containing a bare repository.
183+
/// </para>
135184
/// </summary>
136-
/// <param name="repositoryConfigurationFileLocation">Path to a Repository configuration file.</param>
185+
/// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
137186
/// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a Global configuration file will be probed.</param>
138187
/// <param name="xdgConfigurationFileLocation">Path to a XDG configuration file. If null, the default path for a XDG configuration file will be probed.</param>
139188
/// <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)