Skip to content

Commit 212e38e

Browse files
committed
Add logic for configuration paths on Linux/MacOS
1 parent 66af84a commit 212e38e

3 files changed

Lines changed: 97 additions & 16 deletions

File tree

Build.ps1

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function init {
5555
}
5656

5757
# We expect the source for the module in a subdirectory called one of three things:
58-
$Script:SourcePath = "src", "source", ${ModuleName} | ForEach { Join-Path $Path $_ -Resolve -ErrorAction Ignore } | Select -First 1
58+
$Script:SourcePath = "src", "source", ${ModuleName} | ForEach-Object { Join-Path $Path $_ -Resolve -ErrorAction Ignore } | Select-Object -First 1
5959
if(!$SourcePath) {
6060
Write-Warning "This Build script expects a 'Source' or '$ModuleName' folder to be alongside it."
6161
throw "Can't find module source folder."
@@ -66,7 +66,7 @@ function init {
6666
Write-Warning "This Build script expects a '${ModuleName}.psd1' in the '$SourcePath' folder."
6767
throw "Can't find module source files"
6868
}
69-
$Script:TestPath = "Tests", "Specs" | ForEach { Join-Path $Path $_ -Resolve -ErrorAction Ignore } | Select -First 1
69+
$Script:TestPath = "Tests", "Specs" | ForEach-Object { Join-Path $Path $_ -Resolve -ErrorAction Ignore } | Select-Object -First 1
7070
if(!$TestPath) {
7171
Write-Warning "This Build script expects a 'Tests' or 'Specs' folder to contain tests."
7272
}
@@ -145,9 +145,9 @@ function update {
145145
Trace-Message "UPDATE $ModuleName in $Path"
146146

147147
if(Test-Path (Join-Path $Path packages.config)) {
148-
if(!($Name = Get-PackageSource | ? Location -eq 'https://www.nuget.org/api/v2' | % Name)) {
148+
if(!($Name = Get-PackageSource | Where-Object Location -eq 'https://www.nuget.org/api/v2' | ForEach-Object Name)) {
149149
Write-Warning "Adding NuGet package source"
150-
$Name = Register-PackageSource NuGet -Location 'https://www.nuget.org/api/v2' -ForceBootstrap -ProviderName NuGet | % Name
150+
$Name = Register-PackageSource NuGet -Location 'https://www.nuget.org/api/v2' -ForceBootstrap -ProviderName NuGet | Where-Object Name
151151
}
152152

153153
if($Force -and (Test-Path $Path\packages)) {
@@ -162,9 +162,9 @@ function update {
162162
}
163163

164164
# Remember, as of now, only nuget actually supports the -Destination flag
165-
foreach($Package in ([xml](gc .\packages.config)).packages.package) {
165+
foreach($Package in ([xml](Get-Content .\packages.config)).packages.package) {
166166
Trace-Message "Installing $($Package.id) v$($Package.version) from $($Package.Source)"
167-
$install = Install-Package -Name $Package.id -RequiredVersion $Package.version -Source $Package.Source -Destination $Path\packages -Force:$Force -ErrorVariable failure
167+
$null = Install-Package -Name $Package.id -RequiredVersion $Package.version -Source $Package.Source -Destination $Path\packages -Force:$Force -ErrorVariable failure
168168
if($failure) {
169169
throw "Failed to install $($package.id), see errors above."
170170
}
@@ -196,7 +196,7 @@ function build {
196196
$targets = ($TargetFramework -replace '^','lib\') + 'lib' | ForEach-Object { Join-Path $folder $_ }
197197
}
198198

199-
$PackageSource = Get-Item $targets -ErrorAction SilentlyContinue | Select -First 1 -Expand FullName
199+
$PackageSource = Get-Item $targets -ErrorAction SilentlyContinue | Select-Object -First 1 -Expand FullName
200200
if(!$PackageSource) {
201201
throw "Could not find a lib folder for $($Package.id) from package. You may need to run Setup.ps1"
202202
}
@@ -231,7 +231,7 @@ function build {
231231
$ReleaseModule = Join-Path $ReleasePath ${RootModule}
232232
Trace-Message " Setting content for $ReleaseModule"
233233

234-
$FunctionsToExport = Join-Path $SourcePath Public\*.ps1 -Resolve | % { [System.IO.Path]::GetFileNameWithoutExtension($_) }
234+
$FunctionsToExport = Join-Path $SourcePath Public\*.ps1 -Resolve | ForEach-Object { [System.IO.Path]::GetFileNameWithoutExtension($_) }
235235
Set-Content $ReleaseModule ((
236236
(Get-Content (Join-Path $SourcePath Private\*.ps1) -Raw) +
237237
(Get-Content (Join-Path $SourcePath Public\*.ps1) -Raw)) -join "`r`n`r`n`r`n") -Encoding UTF8
@@ -243,7 +243,7 @@ function build {
243243

244244
# Finally, we need to copy any files in the Source directory
245245
Get-ChildItem $SourcePath -File |
246-
Where Name -ne $RootModule |
246+
Where-Object Name -ne $RootModule |
247247
Copy-Item -Destination $ReleasePath
248248

249249
Update-Manifest $ReleaseManifest -Property FunctionsToExport -Value $FunctionsToExport

Source/Configuration.psd1

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,23 @@ AliasesToExport = '*'
4242
FileList = @('.\Configuration.psd1','.\Configuration.psm1','.\Metadata.psm1','.\en-US\about_Configuration.help.txt')
4343

4444
PrivateData = @{
45+
# Allows overriding the default paths where Configuration stores it's configuration
46+
# Within those folders, the module assumes a "powershell" folder and creates per-module configuration folders
47+
PathOverride = @{
48+
# Where the user's personal configuration settings go.
49+
# Highest presedence, overrides all other settings.
50+
# Defaults to $Env:LocalAppData on Windows
51+
# Defaults to $Env:XDG_CONFIG_HOME elsewhere ($HOME/.config/)
52+
UserData = ""
53+
# On some systems there are "roaming" user configuration stored in the user's profile. Overrides machine configuration
54+
# Defaults to $Env:AppData on Windows
55+
# Defaults to $Env:XDG_CONFIG_DIRS elsewhere (or $HOME/.local/share/)
56+
EnterpriseData = ""
57+
# Machine specific configuration. Overrides defaults, but is overriden by both user roaming and user local settings
58+
# Defaults to $Env:ProgramData on Windows
59+
# Defaults to /etc/xdg elsewhere
60+
MachineData = ""
61+
}
4562
# PSData is module packaging and gallery metadata embedded in PrivateData
4663
# It's for the PoshCode and PowerShellGet modules
4764
# We had to do this because it's the only place we're allowed to extend the manifest

Source/Configuration.psm1

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,84 @@
11
# Allows you to override the Scope storage paths (e.g. for testing)
22
param(
33
$Converters = @{},
4-
$EnterpriseData = $Env:AppData,
5-
$UserData = $Env:LocalAppData,
6-
$MachineData = $Env:ProgramData
4+
$EnterpriseData,
5+
$UserData,
6+
$MachineData
77
)
88

9-
$EnterpriseData = Join-Path $EnterpriseData WindowsPowerShell
10-
$UserData = Join-Path $UserData WindowsPowerShell
11-
$MachineData = Join-Path $MachineData WindowsPowerShell
12-
139
$ConfigurationRoot = Get-Variable PSScriptRoot* -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq "PSScriptRoot" } | ForEach-Object { $_.Value }
1410
if(!$ConfigurationRoot) {
1511
$ConfigurationRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
1612
}
1713

14+
function InitializeStoragePaths {
15+
[CmdletBinding()]
16+
param(
17+
$EnterpriseData,
18+
$UserData,
19+
$MachineData
20+
)
21+
22+
# Where the user's personal configuration settings go.
23+
# Highest presedence, overrides all other settings.
24+
if([string]::IsNullOrWhiteSpace($UserData)) {
25+
if(!($UserData = $MyInvocation.MyCommand.Module.PrivateData.PathOverride.UserData)) {
26+
if($IsLinux -or $IsMacOs) {
27+
# Defaults to $Env:XDG_CONFIG_HOME on Linux or MacOS ($HOME/.config/)
28+
if(!($UserData = $Env:XDG_CONFIG_HOME)) {
29+
$UserData = "$HOME/.config/"
30+
}
31+
} else {
32+
# Defaults to $Env:LocalAppData on Windows
33+
if(!($UserData = $Env:LocalAppData)) {
34+
$UserData = [Environment]::GetFolderPath("LocalApplicationData")
35+
}
36+
}
37+
}
38+
}
39+
40+
# On some systems there are "roaming" user configuration stored in the user's profile. Overrides machine configuration
41+
if([string]::IsNullOrWhiteSpace($EnterpriseData)) {
42+
if(!($EnterpriseData = $MyInvocation.MyCommand.Module.PrivateData.PathOverride.EnterpriseData)) {
43+
if($IsLinux -or $IsMacOs) {
44+
# Defaults to the first value in $Env:XDG_CONFIG_DIRS on Linux or MacOS (or $HOME/.local/share/)
45+
if(!($EnterpriseData = @($Env:XDG_CONFIG_DIRS -split ([IO.Path]::PathSeparator))[0] )) {
46+
$EnterpriseData = "$HOME/.local/share/"
47+
}
48+
} else {
49+
# Defaults to $Env:AppData on Windows
50+
if(!($EnterpriseData = $Env:AppData)) {
51+
$EnterpriseData = [Environment]::GetFolderPath("ApplicationData")
52+
}
53+
}
54+
}
55+
}
56+
57+
# Machine specific configuration. Overrides defaults, but is overriden by both user roaming and user local settings
58+
if([string]::IsNullOrWhiteSpace($MachineData)) {
59+
if(!($MachineData = $MyInvocation.MyCommand.Module.PrivateData.PathOverride.MachineData)) {
60+
if($IsLinux -or $IsMacOs) {
61+
# Defaults to /etc/xdg elsewhere
62+
$XdgConfigDirs = $Env:XDG_CONFIG_DIRS -split ([IO.Path]::PathSeparator) | Where-Object { Test-Path $_ }
63+
if(!($MachineData = if($XdgConfigDirs.Count -gt 1) { $XdgConfigDirs[1]})) {
64+
$MachineData = "/etc/xdg/"
65+
}
66+
} else {
67+
# Defaults to $Env:ProgramData on Windows
68+
if(!($MachineData = $Env:ProgramAppData)) {
69+
$MachineData = [Environment]::GetFolderPath("CommonApplicationData")
70+
}
71+
}
72+
}
73+
}
74+
75+
Join-Path $EnterpriseData powershell
76+
Join-Path $UserData powershell
77+
Join-Path $MachineData powershell
78+
}
79+
80+
$EnterpriseData, $UserData, $MachineData = InitializeStoragePaths $EnterpriseData $UserData $MachineData
81+
1882
Import-Module "${ConfigurationRoot}\Metadata.psm1" -Force -Args @($Converters)
1983

2084
function ParameterBinder {

0 commit comments

Comments
 (0)