Add match and fix some bugs

This commit is contained in:
code liturgy 2022-11-11 17:08:45 -05:00
parent c85e4a72f5
commit 70ca1f65db
3 changed files with 144 additions and 33 deletions

View File

@ -10,6 +10,10 @@ public class AugeasTests
var rootDir = Environment.CurrentDirectory + "/root"; var rootDir = Environment.CurrentDirectory + "/root";
var lensDir = Environment.CurrentDirectory + "/lens"; var lensDir = Environment.CurrentDirectory + "/lens";
_augeas = new Augeas(new AugSettings(rootDir, lensDir)); _augeas = new Augeas(new AugSettings(rootDir, lensDir));
_augeas.LoadFile("/etc/apache2/sites-available/00-ci.codeliturgy.com.conf");
_augeas.LoadFile("/etc/apache2/sites-available/02-codeliturgy.com.conf");
// Load a bunch of files
} }
[Test] [Test]
@ -19,8 +23,7 @@ public class AugeasTests
_augeas.PrintVirtualHostTree(virtualHostConfig); _augeas.PrintVirtualHostTree(virtualHostConfig);
Assert.Pass(); Assert.Pass();
} }
[Test] [Test]
public void NoExceptionThrownWhenPrintingPreview() public void NoExceptionThrownWhenPrintingPreview()
{ {
@ -29,27 +32,34 @@ public class AugeasTests
Assert.Pass(); Assert.Pass();
} }
[Test] [Test]
public void GetPreviewReturnsValid() public void GetPreviewReturnsValid()
{ {
_ = _augeas.LoadFile("/etc/apache2/sites-available/00-ci.codeliturgy.com.conf");
var preview = _augeas.GetPreview("/files/etc/apache2/sites-available/00-ci.codeliturgy.com.conf/*"); var preview = _augeas.GetPreview("/files/etc/apache2/sites-available/00-ci.codeliturgy.com.conf");
var stringInvalid = string.IsNullOrEmpty(preview); var stringInvalid = string.IsNullOrEmpty(preview);
Assert.That(!stringInvalid); Assert.That(!stringInvalid);
} }
[Test] [Test]
public void GetTreeVirtualHostReturnsDictionaryWithKeys() public void MatchReturnsTwoSites()
{ {
var virtualHostConfig = "/etc/apache2/sites-available/00-ci.codeliturgy.com.conf"; var sites = _augeas.Match("/files/etc/apache2/sites-available/*");
var tree = _augeas.GetVirtualHostTree(virtualHostConfig); Assert.That(sites.Length == 2);
Assert.That(tree.Count > 0);
} }
[Test]
public void GetTreeVirtualHostReturnsDictionaryWithKeys()
{
var path = "/etc/apache2/sites-available/00-ci.codeliturgy.com.conf";
var tree = _augeas.GetVirtualHostTree(path);
Assert.That(tree.Count > 0);
}
} }

View File

@ -6,9 +6,13 @@ namespace Sharp.Augeas
/// <summary> /// <summary>
/// Augeas Core containing the settings of this instance. /// Augeas Core containing the settings of this instance.
/// </summary> /// </summary>
public sealed class Augeas public sealed unsafe class Augeas
{ {
#region Flags #region Flags
/// <summary>
///
/// </summary>
public static int NONE = 0; public static int NONE = 0;
public static int SAVE_BACKUP = (1 << 0); public static int SAVE_BACKUP = (1 << 0);
public static int SAVE_NEWFILE = (1 << 1); public static int SAVE_NEWFILE = (1 << 1);
@ -20,6 +24,7 @@ namespace Sharp.Augeas
public static int NO_MODL_AUTOLOAD = (1 << 6); public static int NO_MODL_AUTOLOAD = (1 << 6);
public static int AUG_ENABLE_SPAN = (1 << 7); public static int AUG_ENABLE_SPAN = (1 << 7);
#endregion Flags #endregion Flags
private readonly IntPtr _augeas; private readonly IntPtr _augeas;
private HashSet<string> _loadedFiles = new(); private HashSet<string> _loadedFiles = new();
@ -81,8 +86,7 @@ namespace Sharp.Augeas
/// <summary> /// <summary>
/// Prints a preview of the desired segment in <see cref="matchPath"/> /// Prints a preview of the desired segment in <see cref="matchPath"/>
/// </summary> /// </summary>
/// <param name="matchPath">Augeas path to filter out the configuration</param> /// <param name="matchPath">Augeas path.</param>
/// <param name="filePath">The actual configuration file path</param>
public void PrintPreview(string matchPath) public void PrintPreview(string matchPath)
{ {
print_preview(_augeas, matchPath); print_preview(_augeas, matchPath);
@ -92,21 +96,13 @@ namespace Sharp.Augeas
/// Get the exact value of the matchPath. /// Get the exact value of the matchPath.
/// Returns a empty string if no match is valid. /// Returns a empty string if no match is valid.
/// </summary> /// </summary>
/// <param name="matchPath">Augeas path to filter out the configuration.</param> /// <param name="matchPath">Augeas path.</param>
public string GetNode(string matchPath) public string GetNode(string matchPath)
{ {
var res = get_node(_augeas, matchPath); var res = get_node(_augeas, matchPath);
return res != IntPtr.Zero ? Marshal.PtrToStringAnsi(res) : string.Empty; return res != IntPtr.Zero ? Marshal.PtrToStringAnsi(res) : string.Empty;
} }
/// <summary>
/// Loads a file.
/// </summary>
/// <param name="configurationFilePath"></param>
///
/// <summary> /// <summary>
/// Binding for aug_load_file /// Binding for aug_load_file
/// </summary> /// </summary>
@ -147,7 +143,7 @@ namespace Sharp.Augeas
/// <summary> /// <summary>
/// Returns the tree given the augeas configuration path. /// Returns the tree given the augeas configuration path.
/// </summary> /// </summary>
/// <param name="matchPath">configuration path.</param> /// <param name="matchPath">Configuration path.</param>
/// <returns>Dictionary with the Tree</returns> /// <returns>Dictionary with the Tree</returns>
private Dictionary<string,string> GetTree(string matchPath) private Dictionary<string,string> GetTree(string matchPath)
{ {
@ -166,13 +162,51 @@ namespace Sharp.Augeas
FreeString(raw); FreeString(raw);
return result; return result;
} }
/// <summary>
/// Sets a value of exactly one node.
/// </summary>
/// <param name="matchPath">Configuration path.</param>
/// <param name="value">The value to set.</param>
/// <returns>True if the value was set.</returns>
public bool SetNode(string matchPath, string value)
{
bool success = set_node(_augeas, matchPath, value);
return success;
}
/// <summary>
/// Removes a node from the tree given the <see cref="matchPath"/>
/// </summary>
/// <param name="matchPath">Configuration path.</param>
/// <returns>Removed nodes count.</returns>
public int RemoveNode(string matchPath)
{
int removedCount = rm_node(_augeas, matchPath);
return removedCount;
}
/// <summary>
/// Write all pending changes to disk. Only files that had any changes made to them are written.
/// If AUG_SAVE_NEWFILE is set in the FLAGS passed to AUG_INIT, create changed files as new files with the extension ".augnew", and leave the
/// original file unmodified. Otherwise, if AUG_SAVE_BACKUP is set in the FLAGS passed to the constructor,
/// move the original file to a new file with extension ".augsave".
/// If neither of these flags is set, overwrite the original file
/// </summary>
/// <returns> True on success. Only files that had any changes made to them are written.</returns>
public bool Save()
{
bool saved = save(_augeas);
return saved;
}
/// <summary> /// <summary>
/// Gets a preview of the configuration segment of <see cref="matchPath"/>. /// Gets a preview of the configuration segment of <see cref="matchPath"/>.
/// The file must be loaded first. /// The file must be loaded first.
/// </summary> /// </summary>
/// <param name="matchPath">Augeas path of the configuration</param> /// <param name="matchPath">Augeas path.</param>
/// <returns></returns> /// <returns></returns>
public string GetPreview(string matchPath) public string GetPreview(string matchPath)
{ {
@ -182,9 +216,45 @@ namespace Sharp.Augeas
return sb; return sb;
} }
#endregion #endregion
/// <summary>
/// Matches of the path expression PATH in AUG.
/// </summary>
/// <param name="matchPath">Augeas path.</param>
/// <returns></returns>
public string[] Match (string matchPath)
{
sbyte** result = null;
var count = match(_augeas, matchPath, &result);
var managedArray = GetStringsAndFreeAllocations(count, result);
result = null;
return managedArray;
}
private string[] GetStringsAndFreeAllocations(int count, sbyte** list)
{
var result = new string[count];
if (count <= 0) return Array.Empty<string>();
for (var i = 0; i < count; i++)
{
result[i] = Marshal.PtrToStringUTF8((IntPtr)list[i]);
Marshal.FreeCoTaskMem((IntPtr)list[i]);
}
return result;
}
/// <summary>
/// Given a <see cref="apacheSitePath"/>, prints the Virtual Host tree.
/// </summary>
/// <param name="apacheSitePath">Apache configuration file.</param>
public void PrintVirtualHostTree(string apacheSitePath) public void PrintVirtualHostTree(string apacheSitePath)
{ {
LoadFile(apacheSitePath); LoadFile(apacheSitePath);
@ -192,6 +262,11 @@ namespace Sharp.Augeas
PrintTree(virtualHostTree); PrintTree(virtualHostTree);
} }
/// <summary>
/// Given a <see cref="apacheSitePath"/>, gets a virtual host tree.
/// </summary>
/// <param name="apacheSitePath">Apache configuration file.</param>
/// <returns></returns>
public Dictionary<string,string> GetVirtualHostTree(string apacheSitePath) public Dictionary<string,string> GetVirtualHostTree(string apacheSitePath)
{ {
LoadFile(apacheSitePath); LoadFile(apacheSitePath);
@ -200,10 +275,14 @@ namespace Sharp.Augeas
} }
void PrintVirtualHostProxyTree(string configFilePath) /// <summary>
/// Given a <see cref="apacheSitePath"/>, prints the proxy segment of the configuration.
/// </summary>
/// <param name="configFilePath"></param>
void PrintVirtualHostProxyTree(string apacheSitePath)
{ {
LoadFile(configFilePath); LoadFile(apacheSitePath);
string virtualHostProxyMatchPath = $"/files{configFilePath}/VirtualHost/Proxy/*"; string virtualHostProxyMatchPath = $"/files{apacheSitePath}/VirtualHost/Proxy/*";
PrintTree(virtualHostProxyMatchPath); PrintTree(virtualHostProxyMatchPath);
} }

View File

@ -7,7 +7,7 @@ using Sharp.Augeas.Test;
namespace Sharp.Augeas namespace Sharp.Augeas
{ {
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
public static unsafe partial class AugeasExtern public static unsafe class AugeasExtern
{ {
[DllImport(_libName)] [DllImport(_libName)]
public static extern IntPtr init_aug(AugSettings settings, int flags); public static extern IntPtr init_aug(AugSettings settings, int flags);
@ -40,8 +40,30 @@ namespace Sharp.Augeas
[DllImport(_libName)] [DllImport(_libName)]
public static extern IntPtr get_node(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string matchPath); public static extern IntPtr get_node(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string matchPath);
[DllImport(_libName)] public static extern bool load_file(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string filePath);
[DllImport(_libName)]
public static extern int insert_node(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string matchPath, [MarshalAs(UnmanagedType.LPStr)] string label, int before);
[DllImport(_libName)]
public static extern bool set_node(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string matchPath, [MarshalAs(UnmanagedType.LPStr)] string value);
[DllImport(_libName)]
public static extern int rm_node(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string matchPath);
[DllImport(_libName)]
public static extern bool save(IntPtr augeas);
[DllImport(_libName)]
public static extern bool load_file(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string filePath);
[DllImport(_libName)]
internal static extern int match(IntPtr augeas, [MarshalAs(UnmanagedType.LPStr)] string matchPath, sbyte*** matches);
} }
} }