Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2sharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2015-06-06 12:19:38 +0300
committernulltoken <emeric.fermas@gmail.com>2015-06-06 12:19:38 +0300
commit01b4c5e8e976befb15845190d4719ba80a81bb78 (patch)
tree03403a23b8e0ea3efff120af1b77483e82abc85a
parent7202df7e971c1cbb32a7e26236064cde326a4e5a (diff)
parentca4d15ee5e5588fa1c82b3c9398a5c26a828660a (diff)
Merge pull request #1042 from libgit2/ntk/config_frompaths
Should we allow Configuration to parse a local repository config?
-rw-r--r--LibGit2Sharp.Tests/ConfigurationFixture.cs74
-rw-r--r--LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs10
-rw-r--r--LibGit2Sharp/Configuration.cs143
-rw-r--r--LibGit2Sharp/Repository.cs2
4 files changed, 182 insertions, 47 deletions
diff --git a/LibGit2Sharp.Tests/ConfigurationFixture.cs b/LibGit2Sharp.Tests/ConfigurationFixture.cs
index 78cb71c0..50b6fdc7 100644
--- a/LibGit2Sharp.Tests/ConfigurationFixture.cs
+++ b/LibGit2Sharp.Tests/ConfigurationFixture.cs
@@ -1,8 +1,10 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using LibGit2Sharp.Tests.TestHelpers;
using Xunit;
+using Xunit.Extensions;
namespace LibGit2Sharp.Tests
{
@@ -14,35 +16,6 @@ namespace LibGit2Sharp.Tests
AssertValueInConfigFile(configFilePath, regex);
}
- private static string RetrieveGlobalConfigLocation()
- {
- string[] variables = { "HOME", "USERPROFILE", };
-
- foreach (string variable in variables)
- {
- string potentialLocation = Environment.GetEnvironmentVariable(variable);
- if (string.IsNullOrEmpty(potentialLocation))
- {
- continue;
- }
-
- string potentialPath = Path.Combine(potentialLocation, ".gitconfig");
-
- if (File.Exists(potentialPath))
- {
- return potentialPath;
- }
- }
-
- throw new InvalidOperationException("Unable to determine the location of '.gitconfig' file.");
- }
-
- private static void AssertValueInGlobalConfigFile(string regex)
- {
- string configFilePath = RetrieveGlobalConfigLocation();
- AssertValueInConfigFile(configFilePath, regex);
- }
-
[Fact]
public void CanUnsetAnEntryFromTheLocalConfiguration()
{
@@ -256,7 +229,7 @@ namespace LibGit2Sharp.Tests
[Fact]
public void SettingLocalConfigurationOutsideAReposThrows()
{
- using (var config = new Configuration(null, null, null))
+ using (var config = Configuration.BuildFrom(null, null, null, null))
{
Assert.Throws<LibGit2SharpException>(() => config.Set("unittests.intsetting", 3));
}
@@ -395,5 +368,46 @@ namespace LibGit2Sharp.Tests
Assert.Null(repo.Config.Get<string>("MCHammer.You-cant-touch-this", ConfigurationLevel.System));
}
}
+
+ public static IEnumerable<object[]> ConfigAccessors
+ {
+ get
+ {
+ return new List<object[]>
+ {
+ new[] { new Func<string, string>(p => Path.Combine(p, ".git", "config")) },
+ new[] { new Func<string, string>(p => Path.Combine(p, ".git")) },
+ new[] { new Func<string, string>(p => p) },
+ };
+ }
+ }
+
+ [Theory, PropertyData("ConfigAccessors")]
+ public void CanAccessConfigurationWithoutARepository(Func<string, string> localConfigurationPathProvider)
+ {
+ var path = SandboxStandardTestRepoGitDir();
+
+ string globalConfigPath = CreateConfigurationWithDummyUser(Constants.Signature);
+ var options = new RepositoryOptions { GlobalConfigurationLocation = globalConfigPath };
+
+ using (var repo = new Repository(path, options))
+ {
+ repo.Config.Set("my.key", "local");
+ repo.Config.Set("my.key", "mouse", ConfigurationLevel.Global);
+ }
+
+ using (var config = Configuration.BuildFrom(localConfigurationPathProvider(path), globalConfigPath))
+ {
+ Assert.Equal("local", config.Get<string>("my.key").Value);
+ Assert.Equal("mouse", config.Get<string>("my.key", ConfigurationLevel.Global).Value);
+ }
+ }
+
+ [Fact]
+ public void PassingANonExistingLocalConfigurationFileToBuildFromthrowss()
+ {
+ Assert.Throws<FileNotFoundException>(() => Configuration.BuildFrom(
+ Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())));
+ }
}
}
diff --git a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs
index 01740476..08d7daf0 100644
--- a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs
+++ b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs
@@ -336,19 +336,19 @@ namespace LibGit2Sharp.Tests.TestHelpers
protected string CreateConfigurationWithDummyUser(string name, string email)
{
SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
- Directory.CreateDirectory(scd.DirectoryPath);
- string configFilePath = Path.Combine(scd.DirectoryPath, "global-config");
- using (Configuration config = new Configuration(configFilePath))
+ string configFilePath = Touch(scd.DirectoryPath, "fake-config");
+
+ using (Configuration config = Configuration.BuildFrom(configFilePath))
{
if (name != null)
{
- config.Set("user.name", name, ConfigurationLevel.Global);
+ config.Set("user.name", name);
}
if (email != null)
{
- config.Set("user.email", email, ConfigurationLevel.Global);
+ config.Set("user.email", email);
}
}
diff --git a/LibGit2Sharp/Configuration.cs b/LibGit2Sharp/Configuration.cs
index 47b14fb3..b9924c95 100644
--- a/LibGit2Sharp/Configuration.cs
+++ b/LibGit2Sharp/Configuration.cs
@@ -15,12 +15,11 @@ namespace LibGit2Sharp
public class Configuration : IDisposable,
IEnumerable<ConfigurationEntry<string>>
{
+ private readonly FilePath repoConfigPath;
private readonly FilePath globalConfigPath;
private readonly FilePath xdgConfigPath;
private readonly FilePath systemConfigPath;
- private readonly Repository repository;
-
private ConfigurationSafeHandle configHandle;
/// <summary>
@@ -29,19 +28,22 @@ namespace LibGit2Sharp
protected Configuration()
{ }
- internal Configuration(Repository repository, string globalConfigurationFileLocation,
+ internal Configuration(Repository repository, string repositoryConfigurationFileLocation, string globalConfigurationFileLocation,
string xdgConfigurationFileLocation, string systemConfigurationFileLocation)
{
- this.repository = repository;
+ if (repositoryConfigurationFileLocation != null)
+ {
+ repoConfigPath = NormalizeConfigPath(repositoryConfigurationFileLocation);
+ }
globalConfigPath = globalConfigurationFileLocation ?? Proxy.git_config_find_global();
xdgConfigPath = xdgConfigurationFileLocation ?? Proxy.git_config_find_xdg();
systemConfigPath = systemConfigurationFileLocation ?? Proxy.git_config_find_system();
- Init();
+ Init(repository);
}
- private void Init()
+ private void Init(Repository repository)
{
configHandle = Proxy.git_config_new();
@@ -56,6 +58,10 @@ namespace LibGit2Sharp
Proxy.git_repository_set_config(repository.Handle, configHandle);
}
+ else if (repoConfigPath != null)
+ {
+ Proxy.git_config_add_file_ondisk(configHandle, repoConfigPath, ConfigurationLevel.Local);
+ }
if (globalConfigPath != null)
{
@@ -73,12 +79,126 @@ namespace LibGit2Sharp
}
}
+ private FilePath NormalizeConfigPath(FilePath path)
+ {
+ if (File.Exists(path.Native))
+ {
+ return path;
+ }
+
+ if (!Directory.Exists(path.Native))
+ {
+ throw new FileNotFoundException("Cannot find repository configuration file", path.Native);
+ }
+
+ var configPath = Path.Combine(path.Native, "config");
+
+ if (File.Exists(configPath))
+ {
+ return configPath;
+ }
+
+ var gitConfigPath = Path.Combine(path.Native, ".git", "config");
+
+ if (File.Exists(gitConfigPath))
+ {
+ return gitConfigPath;
+ }
+
+ throw new FileNotFoundException("Cannot find repository configuration file", path.Native);
+ }
+
+ /// <summary>
+ /// Access configuration values without a repository.
+ /// <para>
+ /// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
+ /// </para>
+ /// <para>
+ /// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
+ /// this can be the working directory, the .git directory or the directory containing a bare repository.
+ /// </para>
+ /// </summary>
+ /// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
+ /// <returns>An instance of <see cref="Configuration"/>.</returns>
+ public static Configuration BuildFrom(
+ string repositoryConfigurationFileLocation)
+ {
+ return BuildFrom(repositoryConfigurationFileLocation, null, null, null);
+ }
+
+ /// <summary>
+ /// Access configuration values without a repository.
+ /// <para>
+ /// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
+ /// </para>
+ /// <para>
+ /// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
+ /// this can be the working directory, the .git directory or the directory containing a bare repository.
+ /// </para>
+ /// </summary>
+ /// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
+ /// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a Global configuration file will be probed.</param>
+ /// <returns>An instance of <see cref="Configuration"/>.</returns>
+ public static Configuration BuildFrom(
+ string repositoryConfigurationFileLocation,
+ string globalConfigurationFileLocation)
+ {
+ return BuildFrom(repositoryConfigurationFileLocation, globalConfigurationFileLocation, null, null);
+ }
+
+ /// <summary>
+ /// Access configuration values without a repository.
+ /// <para>
+ /// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
+ /// </para>
+ /// <para>
+ /// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
+ /// this can be the working directory, the .git directory or the directory containing a bare repository.
+ /// </para>
+ /// </summary>
+ /// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
+ /// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a Global configuration file will be probed.</param>
+ /// <param name="xdgConfigurationFileLocation">Path to a XDG configuration file. If null, the default path for a XDG configuration file will be probed.</param>
+ /// <returns>An instance of <see cref="Configuration"/>.</returns>
+ public static Configuration BuildFrom(
+ string repositoryConfigurationFileLocation,
+ string globalConfigurationFileLocation,
+ string xdgConfigurationFileLocation)
+ {
+ return BuildFrom(repositoryConfigurationFileLocation, globalConfigurationFileLocation, xdgConfigurationFileLocation, null);
+ }
+
+ /// <summary>
+ /// Access configuration values without a repository.
+ /// <para>
+ /// Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
+ /// </para>
+ /// <para>
+ /// <paramref name="repositoryConfigurationFileLocation"/> can either contains a path to a file or a directory. In the latter case,
+ /// this can be the working directory, the .git directory or the directory containing a bare repository.
+ /// </para>
+ /// </summary>
+ /// <param name="repositoryConfigurationFileLocation">Path to an existing Repository configuration file.</param>
+ /// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a Global configuration file will be probed.</param>
+ /// <param name="xdgConfigurationFileLocation">Path to a XDG configuration file. If null, the default path for a XDG configuration file will be probed.</param>
+ /// <param name="systemConfigurationFileLocation">Path to a System configuration file. If null, the default path for a System configuration file will be probed.</param>
+ /// <returns>An instance of <see cref="Configuration"/>.</returns>
+ public static Configuration BuildFrom(
+ string repositoryConfigurationFileLocation,
+ string globalConfigurationFileLocation,
+ string xdgConfigurationFileLocation,
+ string systemConfigurationFileLocation)
+ {
+ return new Configuration(null, repositoryConfigurationFileLocation, globalConfigurationFileLocation, xdgConfigurationFileLocation, systemConfigurationFileLocation);
+ }
+
/// <summary>
/// Access configuration values without a repository. Generally you want to access configuration via an instance of <see cref="Repository"/> instead.
/// </summary>
/// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a global configuration file will be probed.</param>
+ [Obsolete("This method will be removed in the next release. Please use Configuration.BuildFrom(string, string) instead.")]
public Configuration(string globalConfigurationFileLocation)
- : this(null, globalConfigurationFileLocation, null, null)
+ : this(null, null, globalConfigurationFileLocation, null, null)
{ }
/// <summary>
@@ -86,8 +206,9 @@ namespace LibGit2Sharp
/// </summary>
/// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a global configuration file will be probed.</param>
/// <param name="xdgConfigurationFileLocation">Path to a XDG configuration file. If null, the default path for a XDG configuration file will be probed.</param>
+ [Obsolete("This method will be removed in the next release. Please use Configuration.BuildFrom(string, string, string) instead.")]
public Configuration(string globalConfigurationFileLocation, string xdgConfigurationFileLocation)
- : this(null, globalConfigurationFileLocation, xdgConfigurationFileLocation, null)
+ : this(null, null, globalConfigurationFileLocation, xdgConfigurationFileLocation, null)
{ }
/// <summary>
@@ -96,10 +217,10 @@ namespace LibGit2Sharp
/// <param name="globalConfigurationFileLocation">Path to a Global configuration file. If null, the default path for a global configuration file will be probed.</param>
/// <param name="xdgConfigurationFileLocation">Path to a XDG configuration file. If null, the default path for a XDG configuration file will be probed.</param>
/// <param name="systemConfigurationFileLocation">Path to a System configuration file. If null, the default path for a system configuration file will be probed.</param>
+ [Obsolete("This method will be removed in the next release. Please use Configuration.BuildFrom(string, string, string, string) instead.")]
public Configuration(string globalConfigurationFileLocation, string xdgConfigurationFileLocation, string systemConfigurationFileLocation)
- : this(null, globalConfigurationFileLocation, xdgConfigurationFileLocation, systemConfigurationFileLocation)
- {
- }
+ : this(null, null, globalConfigurationFileLocation, xdgConfigurationFileLocation, systemConfigurationFileLocation)
+ { }
/// <summary>
/// Determines which configuration file has been found.
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index 79c9077b..51120408 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -125,7 +125,7 @@ namespace LibGit2Sharp
config =
new Lazy<Configuration>(
() =>
- RegisterForCleanup(new Configuration(this, configurationGlobalFilePath, configurationXDGFilePath,
+ RegisterForCleanup(new Configuration(this, null, configurationGlobalFilePath, configurationXDGFilePath,
configurationSystemFilePath)));
odb = new Lazy<ObjectDatabase>(() => new ObjectDatabase(this));
diff = new Diff(this);