@ -29,11 +29,11 @@ $path= Get-Attr $params "path" $FALSE;
$regexp = Get-Attr $params " regexp " $FALSE ;
$state = Get-Attr $params " state " " present " ;
$line = Get-Attr $params " line " $FALSE ;
$backrefs = Get-Attr $params " backrefs " " no " ;
$backrefs = Get-Attr -obj $params -name " backrefs " -default " no " -type " bool "
$insertafter = Get-Attr $params " insertafter " $FALSE ;
$insertbefore = Get-Attr $params " insertbefore " $FALSE ;
$create = Get-Attr $params " create " " no " ;
$backup = Get-Attr $params " backup " " no " ;
$create = Get-Attr $params -name " create " -default " no " -type " bool " ;
$backup = Get-Attr $params -name " backup " -default " no " -type " bool " ;
$validate = Get-Attr $params " validate " $FALSE ;
$encoding = Get-Attr $params " encoding " " auto " ;
$newline = Get-Attr $params " newline " " windows " ;
@ -63,30 +63,35 @@ If (Test-Path $path -pathType container) {
}
# Write lines to a file using the specified line separator and encoding,
# Write lines to a file using the specified line separator and encoding,
# performing validation if a validation command was specified.
function WriteLines($outlines , $path , $linesep , $encodingobj , $validate ) {
$temppath = [ System.IO.Path ] :: GetTempFileName ( ) ;
Try {
$temppath = [ System.IO.Path ] :: GetTempFileName ( ) ;
}
Catch {
Fail-Json ( " Cannot create temporary file! ( " + $_ . Exception . Message + " ) " )
}
$joined = $outlines -join $linesep ;
[ System.IO.File ] :: WriteAllText ( $temppath , $joined , $encodingobj ) ;
If ( $validate -ne $FALSE ) {
If ( ! ( $validate -like " *%s* " ) ) {
Fail-Json ( New-Object psobject ) " validate must contain %s: $validate " ;
}
$validate = $validate . Replace ( " %s " , $temppath ) ;
$validate = $validate . Replace ( " %s " , $temppath ) ;
$parts = [ System.Collections.ArrayList ] $validate . Split ( " " ) ;
$cmdname = $parts [ 0 ] ;
$cmdargs = $validate . Substring ( $cmdname . Length + 1 ) ;
$process = [ Diagnostics.Process ] :: Start ( $cmdname , $cmdargs ) ;
$process . WaitForExit ( ) ;
If ( $process . ExitCode -ne 0 ) {
[ string ] $output = $process . StandardOutput . ReadToEnd ( ) ;
[ string ] $error = $process . StandardError . ReadToEnd ( ) ;
@ -95,11 +100,23 @@ function WriteLines($outlines, $path, $linesep, $encodingobj, $validate) {
}
}
# Commit changes to the path
$cleanpath = $path . Replace ( " / " , " \ " ) ;
Copy-Item $temppath $cleanpath -force ;
Remove-Item $temppath -force ;
Try {
Copy-Item $temppath $cleanpath -force -ErrorAction Stop ;
}
Catch {
Fail-Json ( " Cannot write to: $cleanpath ( " + $_ . Exception . Message + " ) " )
}
Try {
Remove-Item $temppath -force -ErrorAction Stop ;
}
Catch {
Fail-Json ( " Cannot remove temporary file: $temppath ( " + $_ . Exception . Message + " ) " )
}
}
@ -117,14 +134,14 @@ function BackupFile($path) {
function Present($path , $regexp , $line , $insertafter , $insertbefore , $create , $backup , $backrefs , $validate , $encodingobj , $linesep ) {
# Note that we have to clean up the path because ansible wants to treat / and \ as
# Note that we have to clean up the path because ansible wants to treat / and \ as
# interchangeable in windows pathnames, but .NET framework internals do not support that.
$cleanpath = $path . Replace ( " / " , " \ " ) ;
# Check if path exists. If it does not exist, either create it if create == "yes"
# was specified or fail with a reasonable error message.
If ( ! ( Test-Path $path ) ) {
If ( $create -eq " no " ) {
If ( -not $create ) {
Fail-Json ( New-Object psobject ) " Path $path does not exist ! " ;
}
# Create new empty file, using the specified encoding to write correct BOM
@ -139,16 +156,16 @@ function Present($path, $regexp, $line, $insertafter, $insertbefore, $create, $b
Else {
$lines = [ System.Collections.ArrayList ] $content ;
}
# Compile the regex specified, if provided
$mre = $FALSE ;
If ( $regexp -ne $FALSE ) {
$mre = New-Object Regex $regexp , 'Compiled' ;
}
# Compile the regex for insertafter or insertbefore, if provided
$insre = $FALSE ;
If ( $insertafter -ne $FALSE -and $insertafter -ne " BOF " -and $insertafter -ne " EOF " ) {
$insre = New-Object Regex $insertafter , 'Compiled' ;
}
@ -160,7 +177,7 @@ function Present($path, $regexp, $line, $insertafter, $insertbefore, $create, $b
# index[1] is the line num where insertafter/inserbefore has been found
$index = -1 , -1 ;
$lineno = 0 ;
# The latest match object and matched line
$matched_line = " " ;
$m = $FALSE ;
@ -186,16 +203,16 @@ function Present($path, $regexp, $line, $insertafter, $insertbefore, $create, $b
}
If ( $insertbefore -ne $FALSE ) {
$index [ 1 ] = $lineno ;
}
}
}
$lineno = $lineno + 1 ;
}
$changed = $FALSE ;
$msg = " " ;
If ( $index [ 0 ] -ne -1 ) {
If ( $backrefs -ne " no " ) {
If ( $backrefs ) {
$new_line = [ regex ] :: Replace ( $matched_line , $regexp , $line ) ;
}
Else {
@ -207,7 +224,7 @@ function Present($path, $regexp, $line, $insertafter, $insertbefore, $create, $b
$changed = $TRUE ;
}
}
ElseIf ( $backrefs -ne " no " ) {
ElseIf ( $backrefs ) {
# No matches - no-op
}
ElseIf ( $insertbefore -eq " BOF " -or $insertafter -eq " BOF " ) {
@ -229,10 +246,10 @@ function Present($path, $regexp, $line, $insertafter, $insertbefore, $create, $b
# Write backup file if backup == "yes"
$backuppath = " " ;
If ( $changed -eq $TRUE -and $backup -eq " yes " ) {
If ( $changed -eq $TRUE -and $backup -eq $TRUE ) {
$backuppath = BackupFile $path ;
}
# Write changes to the path if changes were made
If ( $changed ) {
WriteLines $lines $path $linesep $encodingobj $validate ;
@ -247,7 +264,7 @@ function Present($path, $regexp, $line, $insertafter, $insertbefore, $create, $b
backup = $backuppath
encoding = $encodingstr
}
Exit-Json $result ;
}
@ -262,9 +279,9 @@ function Absent($path, $regexp, $line, $backup, $validate, $encodingobj, $linese
}
# Read the dest file lines using the indicated encoding into a mutable ArrayList. Note
# that we have to clean up the path because ansible wants to treat / and \ as
# that we have to clean up the path because ansible wants to treat / and \ as
# interchangeable in windows pathnames, but .NET framework internals do not support that.
$cleanpath = $path . Replace ( " / " , " \ " ) ;
$content = [ System.IO.File ] :: ReadAllLines ( $cleanpath , $encodingobj ) ;
If ( $content -eq $null ) {
@ -273,7 +290,7 @@ function Absent($path, $regexp, $line, $backup, $validate, $encodingobj, $linese
Else {
$lines = [ System.Collections.ArrayList ] $content ;
}
# Initialize message to be returned on success
$msg = " " ;
@ -307,10 +324,10 @@ function Absent($path, $regexp, $line, $backup, $validate, $encodingobj, $linese
# Write backup file if backup == "yes"
$backuppath = " " ;
If ( $changed -eq $TRUE -and $backup -eq " yes " ) {
If ( $changed -eq $TRUE -and $backup -eq $TRUE ) {
$backuppath = BackupFile $path ;
}
# Write changes to the path if changes were made
If ( $changed ) {
WriteLines $left $path $linesep $encodingobj $validate ;
@ -328,7 +345,7 @@ function Absent($path, $regexp, $line, $backup, $validate, $encodingobj, $linese
found = $fcount
encoding = $encodingstr
}
Exit-Json $result ;
}
@ -362,7 +379,7 @@ If ($encoding -ne "auto") {
}
# Otherwise see if we can determine the current encoding of the target file.
# If the file doesn't exist yet (create == 'yes') we use the default or
# If the file doesn't exist yet (create == 'yes') we use the default or
# explicitly specified encoding set above.
Elseif ( Test-Path $path ) {
@ -382,11 +399,11 @@ Elseif (Test-Path $path) {
}
# Get the first N bytes from the file, where N is the max preamble length we saw
[ Byte[] ] $bom = Get-Content -Encoding Byte -ReadCount $max_preamble_len -TotalCount $max_preamble_len -Path $path ;
# Iterate through the sorted encodings, looking for a full match.
$found = $FALSE ;
Foreach ( $encoding in $sortedlist . GetValueList ( ) ) {
$preamble = $encoding . GetPreamble ( ) ;
@ -411,19 +428,19 @@ Elseif (Test-Path $path) {
}
# Main dispatch - based on the value of 'state', perform argument validation and
# Main dispatch - based on the value of 'state', perform argument validation and
# call the appropriate handler function.
If ( $state -eq " present " ) {
If ( $backrefs - ne " no " - and $regexp -eq $FALSE ) {
If ( $backrefs - and $regexp -eq $FALSE ) {
Fail-Json ( New-Object psobject ) " regexp= is required with backrefs=true " ;
}
If ( $line -eq $FALSE ) {
Fail-Json ( New-Object psobject ) " line= is required with state=present " ;
}
If ( $insertbefore -eq $FALSE -and $insertafter -eq $FALSE ) {
$insertafter = " EOF " ;
}
@ -436,6 +453,6 @@ Else {
If ( $regexp -eq $FALSE -and $line -eq $FALSE ) {
Fail-Json ( New-Object psobject ) " one of line= or regexp= is required with state=absent " ;
}
Absent $path $regexp $line $backup $validate $encodingobj $linesep ;
}