Skip to content

Commit 0fc522e

Browse files
committed
Migrate private functions out of Invoke-Plaster
1 parent c810135 commit 0fc522e

40 files changed

Lines changed: 1418 additions & 1234 deletions

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// -------- Search configuration --------
99
// Exclude the Output folder from search results.
1010
"search.exclude": {
11-
"Output": true,
11+
"Output/**": true
1212
},
1313
//-------- PowerShell Configuration --------
1414
// Use a custom PowerShell Script Analyzer settings file for this workspace.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function ConvertTo-DestinationRelativePath {
2+
param(
3+
[ValidateNotNullOrEmpty()]
4+
[string]$Path
5+
)
6+
$fullDestPath = $DestinationPath
7+
if (![System.IO.Path]::IsPathRooted($fullDestPath)) {
8+
$fullDestPath = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($DestinationPath)
9+
}
10+
11+
$fullPath = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($Path)
12+
if (!$fullPath.StartsWith($fullDestPath, 'OrdinalIgnoreCase')) {
13+
throw ($LocalizedData.ErrorPathMustBeUnderDestPath_F2 -f $fullPath, $fullDestPath)
14+
}
15+
16+
$fullPath.Substring($fullDestPath.Length).TrimStart('\', '/')
17+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Plaster zen for file handling. All file related operations should use this method
2+
# to actually write/overwrite/modify files in the DestinationPath. This method
3+
# handles detecting conflicts, gives the user a chance to determine how to handle
4+
# conflicts. The user can choose to use the Force parameter to force the overwriting
5+
# of existing files at the destination path.
6+
# File processing (expanding substitution variable, modifying file contents) should always
7+
# be done to a temp file (be sure to always remove temp file when done). That temp file
8+
# is what gets passed to this function as the $SrcPath. This allows Plaster to alert the
9+
# user when the repeated application of a template will modify any existing file.
10+
# NOTE: Plaster keeps track of which files it has "created" (as opposed to overwritten)
11+
# so that any later change to that file doesn't trigger conflict handling.
12+
function Copy-FileWithConflictDetection {
13+
[CmdletBinding(SupportsShouldProcess = $true)]
14+
param(
15+
[string]$SrcPath,
16+
[string]$DstPath
17+
)
18+
# Just double-checking that DstPath parameter is an absolute path otherwise
19+
# it could fail the check that the DstPath is under the overall DestinationPath.
20+
if (![System.IO.Path]::IsPathRooted($DstPath)) {
21+
$DstPath = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($DstPath)
22+
}
23+
24+
# Check if DstPath file conflicts with an existing SrcPath file.
25+
$operation = $LocalizedData.OpCreate
26+
$opmessage = (ConvertTo-DestinationRelativePath $DstPath)
27+
if (Test-Path -LiteralPath $DstPath) {
28+
if (Test-FilesIdentical $SrcPath $DstPath) {
29+
$operation = $LocalizedData.OpIdentical
30+
} elseif ($script:templateCreatedFiles.ContainsKey($DstPath)) {
31+
# Plaster created this file previously during template invocation
32+
# therefore, there is no conflict. We're simply updating the file.
33+
$operation = $LocalizedData.OpUpdate
34+
} elseif ($Force) {
35+
$operation = $LocalizedData.OpForce
36+
} else {
37+
$operation = $LocalizedData.OpConflict
38+
}
39+
}
40+
41+
# Copy the file to the destination
42+
if ($PSCmdlet.ShouldProcess($DstPath, $operation)) {
43+
Write-OperationStatus $operation $opmessage
44+
45+
if ($operation -eq $LocalizedData.OpIdentical) {
46+
# If the files are identical, no need to do anything
47+
return
48+
}
49+
50+
if (($operation -eq $LocalizedData.OpCreate) -or ($operation -eq $LocalizedData.OpUpdate)) {
51+
Copy-Item -LiteralPath $SrcPath -Destination $DstPath
52+
if ($PassThru) {
53+
$InvokePlasterInfo.CreatedFiles += $DstPath
54+
}
55+
$script:templateCreatedFiles[$DstPath] = $null
56+
} elseif ($Force -or $PSCmdlet.ShouldContinue(($LocalizedData.OverwriteFile_F1 -f $DstPath),
57+
$LocalizedData.FileConflict,
58+
[ref]$script:fileConflictConfirmYesToAll,
59+
[ref]$script:fileConflictConfirmNoToAll)) {
60+
$backupFilename = New-BackupFilename $DstPath
61+
Copy-Item -LiteralPath $DstPath -Destination $backupFilename
62+
Copy-Item -LiteralPath $SrcPath -Destination $DstPath
63+
if ($PassThru) {
64+
$InvokePlasterInfo.UpdatedFiles += $DstPath
65+
}
66+
$script:templateCreatedFiles[$DstPath] = $null
67+
}
68+
}
69+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
function Expand-FileSourceSpec([string]$srcRelPath, [string]$dstRelPath) {
2+
$srcPath = Join-Path $templateAbsolutePath $srcRelPath
3+
$dstPath = Join-Path $destinationAbsolutePath $dstRelPath
4+
5+
if ($srcRelPath.IndexOfAny([char[]]('*', '?')) -lt 0) {
6+
# No wildcard spec in srcRelPath so return info on single file.
7+
# Also, if dstRelPath is empty, then use source rel path.
8+
if (!$dstRelPath) {
9+
$dstPath = Join-Path $destinationAbsolutePath $srcRelPath
10+
}
11+
12+
return New-FileSystemCopyInfo $srcPath $dstPath
13+
}
14+
15+
# Prepare parameter values for call to Get-ChildItem to get list of files based on wildcard spec.
16+
$gciParams = @{}
17+
$parent = Split-Path $srcPath -Parent
18+
$leaf = Split-Path $srcPath -Leaf
19+
$gciParams['LiteralPath'] = $parent
20+
$gciParams['File'] = $true
21+
22+
if ($leaf -eq '**') {
23+
$gciParams['Recurse'] = $true
24+
} else {
25+
if ($leaf.IndexOfAny([char[]]('*', '?')) -ge 0) {
26+
$gciParams['Filter'] = $leaf
27+
}
28+
29+
$leaf = Split-Path $parent -Leaf
30+
if ($leaf -eq '**') {
31+
$parent = Split-Path $parent -Parent
32+
$gciParams['LiteralPath'] = $parent
33+
$gciParams['Recurse'] = $true
34+
}
35+
}
36+
37+
$srcRelRootPathLength = $gciParams['LiteralPath'].Length
38+
39+
# Generate a FileCopyInfo object for every file expanded by the wildcard spec.
40+
$files = @(Microsoft.PowerShell.Management\Get-ChildItem @gciParams)
41+
foreach ($file in $files) {
42+
$fileSrcPath = $file.FullName
43+
$relPath = $fileSrcPath.Substring($srcRelRootPathLength)
44+
$fileDstPath = Join-Path $dstPath $relPath
45+
New-FileSystemCopyInfo $fileSrcPath $fileDstPath
46+
}
47+
48+
# Copy over empty directories - if any.
49+
$gciParams.Remove('File')
50+
$gciParams['Directory'] = $true
51+
$dirs = @(Microsoft.PowerShell.Management\Get-ChildItem @gciParams |
52+
Where-Object { $_.GetFileSystemInfos().Length -eq 0 })
53+
foreach ($dir in $dirs) {
54+
$dirSrcPath = $dir.FullName
55+
$relPath = $dirSrcPath.Substring($srcRelRootPathLength)
56+
$dirDstPath = Join-Path $dstPath $relPath
57+
New-FileSystemCopyInfo $dirSrcPath $dirDstPath
58+
}
59+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function Get-ColorForOperation {
2+
param(
3+
$operation
4+
)
5+
switch ($operation) {
6+
$LocalizedData.OpConflict { 'Red' }
7+
$LocalizedData.OpCreate { 'Green' }
8+
$LocalizedData.OpForce { 'Yellow' }
9+
$LocalizedData.OpIdentical { 'Cyan' }
10+
$LocalizedData.OpModify { 'Magenta' }
11+
$LocalizedData.OpUpdate { 'Green' }
12+
$LocalizedData.OpMissing { 'Red' }
13+
$LocalizedData.OpVerify { 'Green' }
14+
default { $Host.UI.RawUI.ForegroundColor }
15+
}
16+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function Get-ErrorLocationFileAttrVal {
2+
param(
3+
[string]$ElementName,
4+
[string]$AttributeName
5+
)
6+
$LocalizedData.ExpressionErrorLocationFile_F2 -f $ElementName, $AttributeName
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function Get-ErrorLocationModifyAttrVal {
2+
param(
3+
[string]$AttributeName
4+
)
5+
$LocalizedData.ExpressionErrorLocationModify_F1 -f $AttributeName
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function Get-ErrorLocationNewModManifestAttrVal {
2+
param(
3+
[string]$AttributeName
4+
)
5+
$LocalizedData.ExpressionErrorLocationNewModManifest_F1 -f $AttributeName
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function Get-ErrorLocationParameterAttrVal {
2+
param(
3+
[string]$ParameterName,
4+
[string]$AttributeName
5+
)
6+
$LocalizedData.ExpressionErrorLocationParameter_F2 -f $ParameterName, $AttributeName
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function Get-ErrorLocationRequireModuleAttrVal {
2+
param(
3+
[string]$ModuleName,
4+
[string]$AttributeName
5+
)
6+
$LocalizedData.ExpressionErrorLocationRequireModule_F2 -f $ModuleName, $AttributeName
7+
}

0 commit comments

Comments
 (0)