Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 18 additions & 1 deletion powershell/src/Public/Get-EnvFileVariable.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ function Get-EnvFileVariable {
$variables = Get-EnvFileContent $Path
try {
if ($variables.ContainsKey($variable)) {
return $variables.Get_Item($variable)
$rawVariable = $variables.Get_Item($variable)
if (IsLiteral -Value $rawVariable) {
#strip out the start/end single quotes if it's a literal value and un-escape.
return $rawVariable.Substring(1, $rawVariable.Length - 2).Replace("''", "'")
}
return $rawVariable
}
else {
throw "Unable to find value for $Variable in $Path"
Expand All @@ -48,4 +53,16 @@ function Get-EnvFileVariable {
catch {
throw "Unable to find value for $Variable in $Path"
}
}

function IsLiteral {
param(
[Parameter(Mandatory = $true)]
[string]
$Value
)
if(!$Value.StartsWith("'")){ return $false }
#Is it a literal value? Test for an odd number of starting 's to avoid escaped values and ending with '
$nonQuoteIndex = [regex]::Match($Value, "[^']")
return ($nonQuoteIndex.Success -and $nonQuoteIndex.Index % 2 -eq 1 -and $Value.EndsWith("'"))
}
19 changes: 15 additions & 4 deletions powershell/src/Public/Set-EnvFileVariable.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Set-StrictMode -Version Latest
Specifies the variable name.
.PARAMETER Value
Specifies the variable value.
.PARAMETER AsLiteral
Specifies whether the Value should be written as a literal (i.e wrapped in single quotes)
.PARAMETER Path
Specifies the Docker environment (.env) file path. Assumes .env file is in the current directory by default.
.EXAMPLE
Expand All @@ -18,6 +20,8 @@ Set-StrictMode -Version Latest
PS C:\> "value one" | Set-EnvFileVariable "VAR1"
.EXAMPLE
PS C:\> Set-EnvFileVariable -Variable VAR1 -Value "value one" -Path .\src\.env
.EXAMPLE
PS C:\> Set-EnvFileVariable -Variable VAR1 -Value "literal $tring" -AsLiteral
.INPUTS
System.String. You can pipe in the Value parameter.
.OUTPUTS
Expand All @@ -37,21 +41,28 @@ function Set-EnvFileVariable
[string]
$Value,

[switch]
$AsLiteral = $false,

[string]
$Path = ".\.env"
)

if (!(Test-Path $Path)) {
throw "The environment file $Path does not exist"
}

# Escape any '$' to prevent being used as a regex substitution
$Value = $Value.Replace('$', '$$')


if ($AsLiteral){
# Escape any ' to avoid terminating the value unexpectedly
$Value = "'$($Value.Replace("'", "''"))'"
}

$found = $false

$lines = @(Get-Content $Path -Encoding UTF8 | ForEach-Object {
if ($_ -imatch "^$Variable=.*") {
# Escape any '$' to prevent being used as a regex substitution
$Value = $Value.Replace('$', '$$')
$_ -ireplace "^$Variable=.*", "$Variable=$Value"
$found = $true
}
Expand Down
42 changes: 38 additions & 4 deletions powershell/test/Public/Get-EnvFileVariable.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
$content = @(
'VAR1=VAL1',
'VAR2=VAL2',
'VAR3=VAL3'
'VAR3=VAL3',
'VAR4=''VAL4$Literal''',
"VAR5=''VAL5''Escaped''",
"VAR6='VAL6''EscapedLiteral'",
"VAR7='VAL7"
"VAR8='''VAL8'"
)
Set-Content "$TestDrive\$envFile" -Value $content

Expand All @@ -37,22 +42,51 @@
{ Get-EnvFileVariable -Path $envFile -Variable 'VAR' } | Should -Throw
}

It 'reads variable correctly usiing default file path' {
It 'reads variable correctly using default file path' {
$value = 'VAL2'
$result = Get-EnvFileVariable -Variable 'VAR2'
$result | Should -Be $value
}

It 'reads variable correctly usiing relative file path' {
It 'reads variable correctly using relative file path' {
$value = 'VAL2'
$result = Get-EnvFileVariable -Path $envFile -Variable 'VAR2'
$result | Should -Be $value
}

It 'reads variable correctly usiing absolute file path' {
It 'reads variable correctly using absolute file path' {
$value = 'VAL2'
$result = Get-EnvFileVariable -Path "$TestDrive\$envFile" -Variable 'VAR2'
$result | Should -Be $value
}

It 'reads variable correctly using a literal value' {
$value = 'VAL4$Literal'
$result = Get-EnvFileVariable -Variable 'VAR4'
$result | Should -Be $value
}

It 'reads variable correctly using quotes in non-literal strings' {
$value = "''VAL5''Escaped''"
$result = Get-EnvFileVariable -Variable 'VAR5'
$result | Should -Be $value
}

It 'reads variable correctly using escaped quotes in literals' {
$value = "VAL6'EscapedLiteral"
$result = Get-EnvFileVariable -Variable 'VAR6'
$result | Should -Be $value
}

It 'reads variable correctly using non-literal strings starting with quote' {
$value = "'VAL7"
$result = Get-EnvFileVariable -Variable 'VAR7'
$result | Should -Be $value
}
It 'reads variable correctly using literal strings starting with quote' {
$value = "'VAL8"
$result = Get-EnvFileVariable -Variable 'VAR8'
$result | Should -Be $value
}
}
}
30 changes: 30 additions & 0 deletions powershell/test/Public/Set-EnvFileVariable.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,36 @@
$envFile | Should -FileContentMatchExactly '^VAR2=two$'
}

It 'sets variables with literal values when specified' {
Set-Content $envFile -Value @(
'VAR1=VAL1',
'VAR2=VAL2',
'VAR3=VAL3'
)
Set-EnvFileVariable -Path $envFile -Variable 'VAR2' -Value 'literal$tring' -AsLiteral
$envFile | Should -FileContentMatchExactly ([regex]::Escape('VAR2=''literal$tring'''))
}

It 'adds variable with literal values when specified' {
Set-Content $envFile -Value @(
'VAR1=VAL1',
'VAR2=VAL2',
'VAR3=VAL3'
)
Set-EnvFileVariable -Path $envFile -Variable 'VAR4' -Value 'literal$tring' -AsLiteral
$envFile | Should -FileContentMatchExactly ([regex]::Escape('VAR4=''literal$tring'''))
}

It 'adds variable with literal values when specified' {
Set-Content $envFile -Value @(
'VAR1=VAL1',
'VAR2=VAL2',
'VAR3=VAL3'
)
Set-EnvFileVariable -Path $envFile -Variable 'VAR2' -Value "VAL2'Escaped" -AsLiteral
$envFile | Should -FileContentMatchExactly "VAR2='VAL2''Escaped'"
}

It 'uses .\.env as default $Path' {
Set-Content $envFile -Value "foo=bar"

Expand Down