8000 Merge pull request #1720 from kzu/multivar · crazygoodcode/libgit2sharp@0e8a3ca · GitHub
[go: up one dir, main page]

Skip to content

Commit 0e8a3ca

Browse files
authored
Merge pull request libgit2#1720 from kzu/multivar
Add support for adding and clearing multi-valued configuration
2 parents 6740402 + 4081885 commit 0e8a3ca

File tree

6 files changed

+200
-9
lines changed

6 files changed

+200
-9
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
language: csharp
55
dist: xenial
6-
dotnet: 2.1.506
6+
dotnet: 2.1.802
77
mono: none
88
osx_image: xcode8.3
99

LibGit2Sharp.Tests/ConfigurationFixture.cs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,119 @@ public void CanUnsetAnEntryFromTheGlobalConfiguration()
5050
}
5151
}
5252

53+
[Fact]
54+
public void CanAddAndReadMultivarFromTheLocalConfiguration()
55+
{
56+
string path = SandboxStandardTestRepo();
57+
using (var repo = new Repository(path))
58+
{
59+
Assert.Empty(repo.Config
60+
.OfType<ConfigurationEntry<string>>()
61+
.Where(x => x.Key == "unittests.plugin"));
62+
63+
repo.Config.Add("unittests.plugin", "value1", ConfigurationLevel.Local);
64+
repo.Config.Add("unittests.plugin", "value2", ConfigurationLevel.Local);
65+
66+
Assert.Equal(new[] { "value1", "value2" }, repo.Config
67+
.OfType<ConfigurationEntry<string>>()
68+
.Where(x => x.Key == "unittests.plugin" && x.Level == ConfigurationLevel.Local)
69+
.Select(x => x.Value)
70+
.ToArray());
71+
}
72+
}
73+
74+
[Fact]
75+
public void CanAddAndReadMultivarFromTheGlobalConfiguration()
76+
{
77+
string path = SandboxBareTestRepo();
78+
using (var repo = new Repository(path))
79+
{
80+
Assert.True(repo.Config.HasConfig(ConfigurationLevel.Global));
81+
Assert.Empty(repo.Config
82+
.OfType<ConfigurationEntry<string>>()
83+
.Where(x => x.Key == "unittests.plugin"));
84+
85+
repo.Config.Add("unittests.plugin", "value1", ConfigurationLevel.Global);
86+
repo.Config.Add("unittests.plugin", "value2", ConfigurationLevel.Global);
87+
88+
Assert.Equal(new[] { "value1", "value2" }, repo.Config
89+
.OfType<ConfigurationEntry<string>>()
90+
.Where(x => x.Key == "unittests.plugin")
91+
.Select(x => x.Value)
92+
.ToArray());
93+
}
94+
}
95+
96+
[Fact]
97+
public void CanUnsetAllFromTheGlobalConfiguration()
98+
{
99+
string path = SandboxBareTestRepo();
100+
using (var repo = new Repository(path))
101+
{
102+
Assert.True(repo.Config.HasConfig(ConfigurationLevel.Global));
103+
Assert.Empty(repo.Config
104+
.OfType<ConfigurationEntry<string>>()
105+
.Where(x => x.Key == "unittests.plugin")
106+
.Select(x => x.Value)
107+
.ToArray());
108+
109+
repo.Config.Add("unittests.plugin", "value1", ConfigurationLevel.Global);
110+
repo.Config.Add("unittests.plugin", "value2", ConfigurationLevel.Global);
111+
112+
Assert.Equal(2, repo.Config
113+
.OfType<ConfigurationEntry<string>>()
114+
.Where(x => x.Key == "unittests.plugin" && x.Level == ConfigurationLevel.Global)
115+
.Select(x => x.Value)
116+
.Count());
117+
118+
repo.Config.UnsetAll("unittests.plugin");
119+
120+
Assert.Equal(2, repo.Config
121+
.OfType<ConfigurationEntry<string>>()
122+
.Where(x => x.Key == "unittests.plugin" && x.Level == ConfigurationLevel.Global)
123+
.Select(x => x.Value)
124+
.Count());
125+
126+
repo.Config.UnsetAll("unittests.plugin", ConfigurationLevel.Global);
127+
128+
Assert.Empty(repo.Config
129+
.OfType<ConfigurationEntry<string>>()
130+
.Where(x => x.Key == "unittests.plugin")
131+
.Select(x => x.Value)
132+
.ToArray());
133+
}
134+
}
135+
136+
[Fact]
137+
public void CanUnsetAllFromTheLocalConfiguration()
138+
{
139+
string path = SandboxStandardTestRepo();
140+
using (var repo = new Repository(path))
141+
{
142+
Assert.True(repo.Config.HasConfig(ConfigurationLevel.Global));
143+
Assert.Empty(repo.Config
144+
.OfType<ConfigurationEntry<string>>()
145+
.Where(x => x.Key == "unittests.plugin")
146+
.Select(x => x.Value)
147+
.ToArray());
148+
149+
repo.Config.Add("unittests.plugin", "value1");
150+
repo.Config.Add("unittests.plugin", "value2");
151+
152+
Assert.Equal(2, repo.Config
153+
.OfType<ConfigurationEntry<string>>()
154+
.Where(x => x.Key == "unittests.plugin" && x.Level == ConfigurationLevel.Local)
155+
.Select(x => x.Value)
156+
.Count());
157+
158+
repo.Config.UnsetAll("unittests.plugin");
159+
160+
Assert.Empty(repo.Config
161+
.OfType<ConfigurationEntry<string>>()
162+
.Where(x => x.Key == "unittests.plugin"));
163+
}
164+
}
165+
53166
[Fact]
54167
public void CanReadBooleanValue()
55168
{

LibGit2Sharp/Configuration.cs

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,33 +233,47 @@ public void Dispose()
233233
/// Unset a configuration variable (key and value) in the local configuration.
234234
/// </summary>
235235
/// <param name="key">The key to unset.</param>
236-
public virtual void Unset(string key)
236+
public virtual bool Unset(string key)
237237
{
238-
Unset(key, ConfigurationLevel.Local);
238+
return Unset(key, ConfigurationLevel.Local);
239239
}
240240

241241
/// <summary>
242242
/// Unset a configuration variable (key and value).
243243
/// </summary>
244244
/// <param name="key">The key to unset.</param>
245245
/// <param name="level">The configuration file which should be considered as the target of this operation</param>
246-
public virtual void Unset(string key, ConfigurationLevel level)
246+
public virtual bool Unset(string key, ConfigurationLevel level)
247247
{
248248
Ensure.ArgumentNotNullOrEmptyString(key, "key");
249249

250250
using (ConfigurationHandle h = RetrieveConfigurationHandle(level, true, configHandle))
251251
{
252-
Proxy.git_config_delete(h, key);
252+
return Proxy.git_config_delete(h, key);
253253
}
254254
}
255255

256-
internal void UnsetMultivar(string key, ConfigurationLevel level)
256+
/// <summary>
257+
/// Unset all configuration values in a multivar variable (key and value) in the local configuration.
258+
/// </summary>
259+
/// <param name="key">The key to unset.</param>
260+
public virtual bool UnsetAll(string key)
261+
{
262+
return UnsetAll(key, ConfigurationLevel.Local);
263+
}
264+
265+
/// <summary>
266+
/// Unset all configuration values in a multivar variable (key and value).
267+
/// </summary>
268+
/// <param name="key">The key to unset.</param>
269+
/// <param name="level">The configuration file which should be considered as the target of this operation</param>
270+
public virtual bool UnsetAll(string key, ConfigurationLevel level)
257271
{
258272
Ensure.ArgumentNotNullOrEmptyString(key, "key");
259273

260274
using (ConfigurationHandle h = RetrieveConfigurationHandle(level, true, configHandle))
261275
{
262-
Proxy.git_config_delete_multivar(h, key);
276+
return Proxy.git_config_delete_multivar(h, key);
263277
}
264278
}
265279

@@ -634,6 +648,55 @@ public virtual void Set<T>(string key, T value, ConfigurationLevel level)
634648
}
635649
}
636650

651+
/// <summary>
652+
/// Adds a configuration value for a multivalue key in the local configuration. Keys are in the form 'section.name'.
653+
/// <para>
654+
/// For example in order to add the value for this in a .git\config file:
655+
///
656+
/// [test]
657+
/// plugin = first
658+
///
659+
/// You would call:
660+
///
661+
/// repo.Config.Add("test.plugin", "first");
662+
/// </para>
663+
/// </summary>
664+
/// <typeparam name="T">The configuration value type</typeparam>
665+
/// <param name="key">The key parts</param>
666+
/// <param name="value">The value</param>
667+
public virtual void Add(string key, string value)
668+
{
669+
Add(key, value, ConfigurationLevel.Local);
670+
}
671+
672+
/// <summary>
673+
/// Adds a configuration value for a multivalue key. Keys are in the form 'section.name'.
674+
/// <para>
675+
/// For example in order to add the value for this in a .git\config file:
676+
///
677+
/// [test]
678+
/// plugin = first
679+
///
680+
/// You would call:
681+
///
682+
/// repo.Config.Add("test.plugin", "first");
683+
/// </para>
684+
/// </summary>
685+
/// <typeparam name="T">The configuration value type</typeparam>
686+
/// <param name="key">The key parts</param>
687+
/// <param name="value">The value</param>
688+
/// <param name="level">The configuration file which should be considered as the target of this operation</param>
689+
public virtual void Add(string key, string value, ConfigurationLevel level)
690+
{
691+
Ensure.ArgumentNotNull(value, "value");
692+
Ensure.ArgumentNotNullOrEmptyString(key, "key");
693+
694+
using (ConfigurationHandle h = RetrieveConfigurationHandle(level, true, configHandle))
695+
{
696+
Proxy.git_config_add_string(h, key, value);
697+
}
698+
}
699+
637700
/// <summary>
638701
/// Find configuration entries matching <paramref name="regexp"/>.
639702
/// </summary>

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,13 @@ internal static extern unsafe int git_config_delete_multivar(
497497
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string name,
498498
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string regexp);
499499

500+
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
501+
internal static extern unsafe int git_config_set_multivar(
502+
git_config* cfg,
503+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string name,
504+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string regexp,
505+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string value);
506+
500507
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
501508
internal static extern int git_config_find_global(GitBuf global_config_path);
502509

LibGit2Sharp/Core/Proxy.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,14 @@ public static unsafe void git_config_set_string(ConfigurationHandle config, stri
601601
Ensure.ZeroResult(res);
602602
}
603603

604+
static readonly string non_existing_regex = Guid.NewGuid().ToString();
605+
606+
public static unsafe void git_config_add_string(ConfigurationHandle config, string name, string value)
607+
{
608+
int res = NativeMethods.git_config_set_multivar(config, name, non_existing_regex, value);
609+
Ensure.ZeroResult(res);
610+
}
611+
604612
public static unsafe ICollection<TResult> git_config_foreach<TResult>(
605613
ConfigurationHandle config,
606614
Func<IntPtr, TResult> resultSelector)

LibGit2Sharp/RemoteUpdater.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ private IEnumerable<string> GetFetchRefSpecs()
5656

5757
private void SetFetchRefSpecs(IEnumerable<string> value)
5858
{
59-
repo.Config.UnsetMultivar(string.Format("remote.{0}.fetch", remoteName), ConfigurationLevel.Local);
59+
repo.Config.UnsetAll(string.Format("remote.{0}.fetch", remoteName), ConfigurationLevel.Local);
6060

6161
foreach (var url in value)
6262
{
@@ -74,7 +74,7 @@ private IEnumerable<string> GetPushRefSpecs()
7474

7575
private void SetPushRefSpecs(IEnumerable<string> value)
7676
{
77-
repo.Config.UnsetMultivar(string.Format("remote.{0}.push", remoteName), ConfigurationLevel.Local);
77+
repo.Config.UnsetAll(string.Format("remote.{0}.push", remoteName), ConfigurationLevel.Local);
7878

7979
foreach (var url in value)
8080
{

0 commit comments

Comments
 (0)
0