Skip to content

Commit

Permalink
Dry run at config
Browse files Browse the repository at this point in the history
test fails
  • Loading branch information
pigalot committed May 12, 2018
1 parent 8088fcf commit 760da5d
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 40 deletions.
98 changes: 98 additions & 0 deletions LibGit2Sharp.Tests/ConfigurationBackendFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LibGit2Sharp.Tests.TestHelpers;
using Xunit;

namespace LibGit2Sharp.Tests
{
public class ConfigurationBackendFixture : BaseFixture
{
[Fact]
public void CanCreateInMemoryRepositoryWithBackend()
{
using (var repo = new Repository())
{
repo.Config.AddBackend(new MockConfigurationBackend(), ConfigurationLevel.Local);

Assert.True(repo.Info.IsBare);
Assert.Null(repo.Info.Path);
Assert.Null(repo.Info.WorkingDirectory);

Assert.Throws<BareRepositoryException>(() => { var idx = repo.Index; });
}
}

#region MockBackend

private class MockConfigurationBackend : ConfigurationBackend<string, MockConfigurationIterator>
{
protected override ConfigBackendOperations SupportedOperations
{
get { return ConfigBackendOperations.Open; }
}

public override int Open(ConfigurationLevel level)
{
return 0;
}

public override int Get(string key, out ConfigurationEntry<string> configurationEntry)
{
throw new NotImplementedException();
}

public override int Set(string key, string value)
{
throw new NotImplementedException();
}

public override int SetMultivar(string Name, string regexp, string value)
{
throw new NotImplementedException();
}

public override int Del(string key)
{
throw new NotImplementedException();
}

public override int DelMultivar(string Name, string regexp)
{
throw new NotImplementedException();
}

public override int Iterator(out MockConfigurationIterator iterator)
{
throw new NotImplementedException();
}

public override int Snapshot(out ConfigurationBackend<string, MockConfigurationIterator> configSnapshot)
{
throw new NotImplementedException();
}

public override int Lock()
{
throw new NotImplementedException();
}

public override int Unlock(out bool success)
{
throw new NotImplementedException();
}
}

private class MockConfigurationIterator : ConfigurationIterator<string>
{
public override int Next(out ConfigurationEntry<string> configurationEntry)
{
throw new NotImplementedException();
}
}

#endregion
}
}
28 changes: 25 additions & 3 deletions LibGit2Sharp/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class Configuration : IDisposable,
private readonly FilePath systemConfigPath;
private readonly FilePath programDataConfigPath;

private readonly RepositoryHandle repositoryHandle;
private ConfigurationHandle configHandle;

/// <summary>
Expand All @@ -31,15 +32,16 @@ protected Configuration()

internal Configuration(Repository repository, bool isInMemory)
{
repositoryHandle = repository.Handle;
if (isInMemory)
{
configHandle = Proxy.git_config_new();

Proxy.git_repository_set_config(repository.Handle, configHandle);
Proxy.git_repository_set_config(repositoryHandle, configHandle);
}
else
{
configHandle = Proxy.git_repository_config(repository.Handle);
configHandle = Proxy.git_repository_config(repositoryHandle);
}

repository.RegisterForCleanup(configHandle);
Expand All @@ -52,6 +54,7 @@ internal Configuration(
string xdgConfigurationFileLocation,
string systemConfigurationFileLocation)
{
repositoryHandle = repository.Handle;
if (repositoryConfigurationFileLocation != null)
{
repoConfigPath = NormalizeConfigPath(repositoryConfigurationFileLocation);
Expand All @@ -78,7 +81,7 @@ private void Init(Repository repository)
string repoConfigLocation = Path.Combine(repository.Info.Path, "config");
Proxy.git_config_add_file_ondisk(configHandle, repoConfigLocation, ConfigurationLevel.Local);

Proxy.git_repository_set_config(repository.Handle, configHandle);
Proxy.git_repository_set_config(repositoryHandle, configHandle);
}
else if (repoConfigPath != null)
{
Expand Down Expand Up @@ -135,6 +138,25 @@ private FilePath NormalizeConfigPath(FilePath path)
throw new FileNotFoundException("Cannot find repository configuration file", path.Native);
}

/// <summary>
/// Adds the provided backend to the config.
/// <para>
/// If the provided backend implements <see cref="IDisposable"/>, the <see cref="IDisposable.Dispose"/>
/// method will be honored and invoked upon the disposal of the repository.
/// </para>
/// </summary>
/// <typeparam name="TConfigurationValue"></typeparam>
/// <typeparam name="TConfigurationIterator"></typeparam>
/// <param name="backend"></param>
/// <param name="level"></param>
public virtual void AddBackend<TConfigurationValue, TConfigurationIterator>(ConfigurationBackend<TConfigurationValue, TConfigurationIterator> backend, ConfigurationLevel level)
where TConfigurationValue : class where TConfigurationIterator : ConfigurationIterator<TConfigurationValue>
{
Ensure.ArgumentNotNull(backend, "backend");

Proxy.git_config_add_backend(configHandle, backend.GitConfigBackendPointer, level, repositoryHandle);
}

/// <summary>
/// Access configuration values without a repository.
/// <para>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using LibGit2Sharp.Core;

namespace LibGit2Sharp
{
public abstract class ConfigBackend
public abstract class ConfigurationBackend<TConfigurationValue, TConfigurationIterator> where TConfigurationValue : class where TConfigurationIterator : ConfigurationIterator<TConfigurationValue>
{
/// <summary>
/// Invoked by libgit2 when this backend is no longer needed.
Expand All @@ -29,9 +27,9 @@ internal void Free()
/// </summary>
protected abstract ConfigBackendOperations SupportedOperations { get; }

public abstract int Open(LogLevel level);
public abstract int Open(ConfigurationLevel level);

public abstract int Get(string key, out ConfigurationEntry<string> configurationEntry);
public abstract int Get(string key, out ConfigurationEntry<TConfigurationValue> configurationEntry);

public abstract int Set(string key, string value);

Expand All @@ -41,9 +39,9 @@ internal void Free()

public abstract int DelMultivar(string Name, string regexp);

public abstract int Iterator(out object iterator); // ToDo: impliment iterator
public abstract int Iterator(out TConfigurationIterator iterator);

public abstract int Snapshot(out ConfigBackend configSnapshot);
public abstract int Snapshot(out ConfigurationBackend<TConfigurationValue, TConfigurationIterator> configSnapshot);

public abstract int Lock();

Expand Down Expand Up @@ -142,32 +140,32 @@ private static class BackendEntryPoints
public static readonly GitConfigBackend.unlock_callback UnlockCallback = Unlock;
public static readonly GitConfigBackend.free_callback FreeCallback = Free;

private static ConfigBackend MarshalConfigBackend(IntPtr backendPtr)
private static ConfigurationBackend<TConfigurationValue, TConfigurationIterator> MarshalConfigurationBackend(IntPtr backendPtr)
{

var intPtr = Marshal.ReadIntPtr(backendPtr, GitConfigBackend.GCHandleOffset);
var configBackend = GCHandle.FromIntPtr(intPtr).Target as ConfigBackend;
var configBackend = GCHandle.FromIntPtr(intPtr).Target as ConfigurationBackend<TConfigurationValue, TConfigurationIterator>;

if (configBackend == null)
{
Proxy.giterr_set_str(GitErrorCategory.Reference, "Cannot retrieve the managed ConfigBackend.");
Proxy.giterr_set_str(GitErrorCategory.Reference, "Cannot retrieve the managed ConfigurationBackend.");
return null;
}

return configBackend;
}

private static int Open(IntPtr backend, LogLevel level)
private static int Open(IntPtr backend, uint level)
{
ConfigBackend configBackend = MarshalConfigBackend(backend);
var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
}

try
{
int toReturn = configBackend.Open(level);
int toReturn = configBackend.Open((ConfigurationLevel)level);

if (toReturn != 0)
{
Expand All @@ -187,27 +185,23 @@ private static unsafe int Get(IntPtr backend, string key, out GitConfigEntry ent
{
entry = default(GitConfigEntry);

ConfigBackend configBackend = MarshalConfigBackend(backend);
var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
}

try
{
ConfigurationEntry<string> configurationEntry;
ConfigurationEntry<TConfigurationValue> configurationEntry;
int toReturn = configBackend.Get(key, out configurationEntry);

if (toReturn != 0)
{
return toReturn;
}

var namePtr = EncodingMarshaler.FromManaged(Encoding.UTF8, configurationEntry.Key);
var valuePtr = EncodingMarshaler.FromManaged(Encoding.UTF8, configurationEntry.Value);
var level = (uint)configurationEntry.Level;

entry = new GitConfigEntry { namePtr = (char*)namePtr, valuePtr = (char*)valuePtr, level = level };
entry = configurationEntry.GetGitConfigEntry();
}
catch (Exception ex)
{
Expand All @@ -220,7 +214,7 @@ private static unsafe int Get(IntPtr backend, string key, out GitConfigEntry ent

private static int Set(IntPtr backend, string key, string value)
{
ConfigBackend configBackend = MarshalConfigBackend(backend);
var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
Expand All @@ -239,7 +233,7 @@ private static int Set(IntPtr backend, string key, string value)

private static int SetMultivar(IntPtr backend, string name, string regexp, string value)
{
ConfigBackend configBackend = MarshalConfigBackend(backend);
var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
Expand All @@ -258,7 +252,7 @@ private static int SetMultivar(IntPtr backend, string name, string regexp, strin

private static int Del(IntPtr backend, string key)
{
ConfigBackend configBackend = MarshalConfigBackend(backend);
var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
Expand All @@ -277,7 +271,7 @@ private static int Del(IntPtr backend, string key)

private static int DelMultivar(IntPtr backend, string name, string regexp)
{
ConfigBackend configBackend = MarshalConfigBackend(backend);
var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
Expand All @@ -296,19 +290,59 @@ private static int DelMultivar(IntPtr backend, string name, string regexp)

private static int Iterator(out IntPtr iterator, IntPtr backend)
{
// Impliment iterator
// https://github.com/libgit2/libgit2/blob/0d723f39decff4ff77def8a4acf3b7a656af59b2/include/git2/sys/config.h line 34
throw new NotImplementedException();
iterator = IntPtr.Zero;

var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
}

try
{
TConfigurationIterator configurationIterator;
configBackend.Iterator(out configurationIterator);

iterator = configurationIterator.GitConfigBackendPointer;
}
catch (Exception ex)
{
Proxy.giterr_set_str(GitErrorCategory.Config, ex);
return (int)GitErrorCode.Error;
}

return (int)GitErrorCode.Ok;
}

private static int Snapshot(out IntPtr snapshot, IntPtr backend)
{
throw new NotImplementedException();
snapshot = IntPtr.Zero;

var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
}

try
{
ConfigurationBackend<TConfigurationValue, TConfigurationIterator> configurationBackend;
configBackend.Snapshot(out configurationBackend);

snapshot = configurationBackend.GitConfigBackendPointer;
}
catch (Exception ex)
{
Proxy.giterr_set_str(GitErrorCategory.Config, ex);
return (int)GitErrorCode.Error;
}

return (int)GitErrorCode.Ok;
}

private static int Lock(IntPtr backend)
{
ConfigBackend configBackend = MarshalConfigBackend(backend);
var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
Expand All @@ -328,7 +362,7 @@ private static int Lock(IntPtr backend)
private static int Unlock(IntPtr backend, out int success)
{
success = 0;
ConfigBackend configBackend = MarshalConfigBackend(backend);
var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return (int)GitErrorCode.Error;
Expand Down Expand Up @@ -357,7 +391,7 @@ private static int Unlock(IntPtr backend, out int success)

private static void Free(IntPtr backend)
{
ConfigBackend configBackend = MarshalConfigBackend(backend);
var configBackend = MarshalConfigurationBackend(backend);
if (configBackend == null)
{
return;
Expand Down
Loading

0 comments on commit 760da5d

Please sign in to comment.