Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ${WinGetConfigRoot} variable expansion #3237

Merged
merged 3 commits into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ winapifamily
windir
windowsdeveloper
winerror
wingetconfigroot
wingetcreate
wingetdev
wingetutil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.Management.Configuration.Processor.Exceptions
using System;

/// <summary>
/// A setting uses the config root variable and the Origin was not set in the ConfigurationSet.
/// A setting uses the config root variable and the Path was not set in the ConfigurationSet.
/// </summary>
internal class UnitSettingConfigRootException : Exception
{
Expand All @@ -19,7 +19,7 @@ internal class UnitSettingConfigRootException : Exception
/// <param name="unitName">Unit name.</param>
/// <param name="setting">Setting.</param>
public UnitSettingConfigRootException(string unitName, string setting)
: base($"Unit: {unitName} Setting {setting} requires the ConfigurationSet Origin")
: base($"Unit: {unitName} Setting {setting} requires the ConfigurationSet Path")
{
this.HResult = ErrorCodes.WinGetConfigUnitSettingConfigRoot;
this.UnitName = unitName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Microsoft.Management.Configuration.Processor.Helpers
{
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Management.Configuration.Processor.Constants;
using Microsoft.Management.Configuration.Processor.Exceptions;
using Microsoft.PowerShell.Commands;
Expand All @@ -19,24 +20,24 @@ namespace Microsoft.Management.Configuration.Processor.Helpers
/// </summary>
internal class ConfigurationUnitInternal
{
private static string configRoot = "$WinGetConfigRoot";
private static string configRootVar = "$WinGetConfigRoot";
msftrubengu marked this conversation as resolved.
Show resolved Hide resolved

private readonly string origin;
private readonly string configurationFilePath;
private readonly Dictionary<string, object> normalizedDirectives = new ();

/// <summary>
/// Initializes a new instance of the <see cref="ConfigurationUnitInternal"/> class.
/// </summary>
/// <param name="unit">Configuration unit.</param>
/// <param name="origin">The origin of the unit.</param>
/// <param name="configurationFilePath">The configuration file path.</param>
/// <param name="directivesOverlay">Directives overlay.</param>
public ConfigurationUnitInternal(
ConfigurationUnit unit,
string origin,
string configurationFilePath,
IReadOnlyDictionary<string, object>? directivesOverlay = null)
{
this.Unit = unit;
this.origin = origin;
this.configurationFilePath = configurationFilePath;
this.DirectivesOverlay = directivesOverlay;
this.InitializeDirectives();

Expand Down Expand Up @@ -172,8 +173,8 @@ public ValueSet GetExpandedSettings()
{
if (value.Value is string)
{
// For now, we just expand origin.
valueSet.Add(value.Key, this.ExpandOrigin(value.Value as string, value.Key));
// For now, we just expand config root.
valueSet.Add(value.Key, this.ExpandConfigRoot(value.Value as string, value.Key));
}
else
{
Expand All @@ -184,21 +185,32 @@ public ValueSet GetExpandedSettings()
return valueSet;
}

private string? ExpandOrigin(string? value, string settingName)
private string? ExpandConfigRoot(string? value, string settingName)
{
if (!string.IsNullOrEmpty(value))
{
// TODO: since we only support one variable, this only finds and replace
// $WingetConfigRoot if found in the string when the work of expanding
// string is done it should take into account other operators like the subexpression operator $()
if (value.Contains(configRoot, StringComparison.OrdinalIgnoreCase))
if (value.Contains(configRootVar, StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrEmpty(this.origin))
if (string.IsNullOrEmpty(this.configurationFilePath))
{
throw new UnitSettingConfigRootException(this.Unit.UnitName, settingName);
msftrubengu marked this conversation as resolved.
Show resolved Hide resolved
}

return value.Replace(configRoot, this.origin, StringComparison.OrdinalIgnoreCase);
if (!File.Exists(this.configurationFilePath))
msftrubengu marked this conversation as resolved.
Show resolved Hide resolved
{
throw new FileNotFoundException(this.configurationFilePath);
}

var configRoot = Path.GetDirectoryName(this.configurationFilePath);
if (configRoot == null)
{
throw new ArgumentException();
}

return value.Replace(configRootVar, configRoot, StringComparison.OrdinalIgnoreCase);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public IConfigurationUnitProcessor CreateUnitProcessor(
{
try
{
var configurationUnitInternal = new ConfigurationUnitInternal(unit, this.configurationSet.Origin, directivesOverlay);
var configurationUnitInternal = new ConfigurationUnitInternal(unit, this.configurationSet.Path, directivesOverlay);
this.OnDiagnostics(DiagnosticLevel.Verbose, $"Creating unit processor for: {configurationUnitInternal.ToIdentifyingString()}...");

var dscResourceInfo = this.PrepareUnitForProcessing(configurationUnitInternal);
Expand Down Expand Up @@ -87,7 +87,7 @@ public IConfigurationUnitProcessor CreateUnitProcessor(
{
try
{
var unitInternal = new ConfigurationUnitInternal(unit, this.configurationSet.Origin);
var unitInternal = new ConfigurationUnitInternal(unit, this.configurationSet.Path);
this.OnDiagnostics(DiagnosticLevel.Verbose, $"Getting unit details [{detailLevel}] for: {unitInternal.ToIdentifyingString()}");
var dscResourceInfo = this.ProcessorEnvironment.GetDscResource(unitInternal);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ namespace Microsoft.Management.Configuration.UnitTests.Tests
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Management.Automation;
using Microsoft.Management.Configuration;
using Microsoft.Management.Configuration.Processor.Exceptions;
using Microsoft.Management.Configuration.Processor.Helpers;
using Microsoft.Management.Configuration.UnitTests.Fixtures;
using Microsoft.Management.Configuration.UnitTests.Helpers;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -112,11 +114,13 @@ public void GetVersion_BadVersion()
}

/// <summary>
/// Verifies expansion of origin.
/// Verifies expansion of ConfigRoot.
/// </summary>
[Fact]
public void GetExpandedSettings_Origin()
public void GetExpandedSettings_ConfigRoot()
{
using var tmpFile = new TempFile("fakeConfigFile.yml", content: "content");

var unit = new ConfigurationUnit();
unit.Settings.Add("var1", @"WinGetConfigRoot\this\is\a\path.txt");
unit.Settings.Add("var2", @"$WinGetConfigRoot\this\is\a\path.txt");
Expand All @@ -125,7 +129,8 @@ public void GetExpandedSettings_Origin()
unit.Settings.Add("var5", @"this\is\a\path\wingetconfigroot");
unit.Settings.Add("var6", @"this\is\a\path\$wingetconfigroot");

string configPath = @"one\root";
string configPath = tmpFile.FullFileName;
string? expectedPath = Path.GetDirectoryName(configPath);
var unitInternal = new ConfigurationUnitInternal(unit, configPath);

var expandedSettings = unitInternal.GetExpandedSettings();
Expand All @@ -134,26 +139,26 @@ public void GetExpandedSettings_Origin()
Assert.Equal(@"WinGetConfigRoot\this\is\a\path.txt", var1 as string);

var var2 = expandedSettings["var2"];
Assert.Equal(@"one\root\this\is\a\path.txt", var2 as string);
Assert.Equal($@"{expectedPath}\this\is\a\path.txt", var2 as string);

var var3 = expandedSettings["var3"];
Assert.Equal(@"this\is\a\WINGETCONFIGROOT\path.txt", var3 as string);

var var4 = expandedSettings["var4"];
Assert.Equal(@"this\is\a\one\root\path.txt", var4 as string);
Assert.Equal($@"this\is\a\{expectedPath}\path.txt", var4 as string);

var var5 = expandedSettings["var5"];
Assert.Equal(@"this\is\a\path\wingetconfigroot", var5 as string);

var var6 = expandedSettings["var6"];
Assert.Equal(@"this\is\a\path\one\root", var6 as string);
Assert.Equal($@"this\is\a\path\{expectedPath}", var6 as string);
}

/// <summary>
/// Verifies throws when origin is not set.
/// Verifies throws when config root is not set.
/// </summary>
[Fact]
public void GetExpandedSetting_Origin_Throw()
public void GetExpandedSetting_ConfigRoot_Throw()
{
var unit = new ConfigurationUnit();
unit.Settings.Add("var2", @"$WinGetConfigRoot\this\is\a\path.txt");
Expand Down