JSON - Merge Files

Octopus.Script exported 2019-01-31 by jonasjanusauskas belongs to ‘JSON’ category.

Merge JSON files

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Source file

jmf_SourceFile = Required

Path to the source file

Transform file

jmf_TransformFile = Required

Path to the file with the changes

Fail if transform file missing

jmf_FailIfTransformFileMissing = False

Should the script fail if the transformation file is missing?

Output file

jmf_OutputFile = Required

Path to the output file

Script body

Steps based on this template will execute the following PowerShell script.

function Get-RequiredParam($Name) {
    $result = $null

    if ($OctopusParameters -ne $null) {
        $result = $OctopusParameters[$Name]
    }

    if ($result -eq $null) {
        $variable = Get-Variable $Name -EA SilentlyContinue    
        if ($variable -ne $null) {
            $result = $variable.Value
        }
    }

    if ($result -eq $null) {
		throw "Missing parameter value $Name"
    }

    return $result
}

function Merge-Objects($file1, $file2) {
    $propertyNames = $($file2 | Get-Member -MemberType *Property).Name
    foreach ($propertyName in $propertyNames) {
		# Check if property already exists
        if ($file1.PSObject.Properties.Match($propertyName).Count) {
            if ($file1.$propertyName.GetType().Name -eq 'PSCustomObject') {
				# Recursively merge subproperties
                $file1.$propertyName = Merge-Objects $file1.$propertyName $file2.$propertyName
            } else {
				# Overwrite Property
                $file1.$propertyName = $file2.$propertyName
            }
        } else {
			# Add property
            $file1 | Add-Member -MemberType NoteProperty -Name $propertyName -Value $file2.$propertyName
        }
    }
    return $file1
}

function Merge-Json($sourcePath, $transformPath, $failIfTransformMissing, $outputPath) {
	if(!(Test-Path $sourcePath)) {
		Write-Host "Source file $sourcePath does not exist!"
		Exit 1
	}
	
	$sourceObject = (Get-Content -Path $sourcePath -Encoding UTF8) -join "`n" | ConvertFrom-Json
	$mergedObject = $sourceObject
	
	if (!(Test-Path $transformPath)) {
		Write-Host "Transform file $transformPath does not exist!"
		if ([System.Convert]::ToBoolean($failIfTransformMissing)) {
			Exit 1
		}
		Write-Host 'Source file will be written to output without changes'
	} else {
		Write-Host 'Applying transformations'
		$transformObject = (Get-Content -Path $transformPath -Encoding UTF8) -join "`n" | ConvertFrom-Json
		$mergedObject = Merge-Objects $sourceObject $transformObject
	}
	
	Write-Host "Writing merged JSON to $outputPath..."
	$mergedJson = $mergedObject | ConvertTo-Json -Depth 200
	[System.IO.File]::WriteAllLines($outputPath, $mergedJson)
}

$ErrorActionPreference = 'Stop'

if($OctopusParameters -eq $null) {
    Write-Host 'OctopusParameters is null...exiting with 1'
    Exit 1    
}

$sourceFilePath = Get-RequiredParam 'jmf_SourceFile'
$transformFilePath = Get-RequiredParam 'jmf_TransformFile'
$failIfTransformFileMissing = Get-RequiredParam 'jmf_FailIfTransformFileMissing'
$outputFilePath = Get-RequiredParam 'jmf_OutputFile'

Merge-Json $sourceFilePath $transformFilePath $failIfTransformFileMissing $outputFilePath

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "6bb1fb50-de38-4380-a5ef-7f21ac3a3e6f",
  "Name": "JSON - Merge Files",
  "Description": "Merge JSON files",
  "Version": 2,
  "ExportedAt": "2019-01-31T13:01:36.386Z",
  "ActionType": "Octopus.Script",
  "Author": "jonasjanusauskas",
  "Parameters": [
    {
      "Id": "ff6ebb11-b388-460b-835e-5cf98ae394ed",
      "Name": "jmf_SourceFile",
      "Label": "Source file",
      "HelpText": "Path to the source file",
      "DefaultValue": "Required",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      },
      "Links": {}
    },
    {
      "Id": "f4695bf4-817a-4029-92b8-3e0c9f7da324",
      "Name": "jmf_TransformFile",
      "Label": "Transform file",
      "HelpText": "Path to the file with the changes",
      "DefaultValue": "Required",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      },
      "Links": {}
    },
    {
      "Id": "8b5e7f58-a167-46c9-9260-6c49f4945943",
      "Name": "jmf_FailIfTransformFileMissing",
      "Label": "Fail if transform file missing",
      "HelpText": "Should the script fail if the transformation file is missing?",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      },
      "Links": {}
    },
    {
      "Id": "16e43e45-5bc7-4e13-a0d1-4c699cadd259",
      "Name": "jmf_OutputFile",
      "Label": "Output file",
      "HelpText": "Path to the output file",
      "DefaultValue": "Required",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      },
      "Links": {}
    }
  ],
  "Properties": {
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.RunOnServer": "false",
    "Octopus.Action.Script.ScriptBody": "function Get-RequiredParam($Name) {\n    $result = $null\n\n    if ($OctopusParameters -ne $null) {\n        $result = $OctopusParameters[$Name]\n    }\n\n    if ($result -eq $null) {\n        $variable = Get-Variable $Name -EA SilentlyContinue    \n        if ($variable -ne $null) {\n            $result = $variable.Value\n        }\n    }\n\n    if ($result -eq $null) {\n\t\tthrow \"Missing parameter value $Name\"\n    }\n\n    return $result\n}\n\nfunction Merge-Objects($file1, $file2) {\n    $propertyNames = $($file2 | Get-Member -MemberType *Property).Name\n    foreach ($propertyName in $propertyNames) {\n\t\t# Check if property already exists\n        if ($file1.PSObject.Properties.Match($propertyName).Count) {\n            if ($file1.$propertyName.GetType().Name -eq 'PSCustomObject') {\n\t\t\t\t# Recursively merge subproperties\n                $file1.$propertyName = Merge-Objects $file1.$propertyName $file2.$propertyName\n            } else {\n\t\t\t\t# Overwrite Property\n                $file1.$propertyName = $file2.$propertyName\n            }\n        } else {\n\t\t\t# Add property\n            $file1 | Add-Member -MemberType NoteProperty -Name $propertyName -Value $file2.$propertyName\n        }\n    }\n    return $file1\n}\n\nfunction Merge-Json($sourcePath, $transformPath, $failIfTransformMissing, $outputPath) {\n\tif(!(Test-Path $sourcePath)) {\n\t\tWrite-Host \"Source file $sourcePath does not exist!\"\n\t\tExit 1\n\t}\n\t\n\t$sourceObject = (Get-Content -Path $sourcePath -Encoding UTF8) -join \"`n\" | ConvertFrom-Json\n\t$mergedObject = $sourceObject\n\t\n\tif (!(Test-Path $transformPath)) {\n\t\tWrite-Host \"Transform file $transformPath does not exist!\"\n\t\tif ([System.Convert]::ToBoolean($failIfTransformMissing)) {\n\t\t\tExit 1\n\t\t}\n\t\tWrite-Host 'Source file will be written to output without changes'\n\t} else {\n\t\tWrite-Host 'Applying transformations'\n\t\t$transformObject = (Get-Content -Path $transformPath -Encoding UTF8) -join \"`n\" | ConvertFrom-Json\n\t\t$mergedObject = Merge-Objects $sourceObject $transformObject\n\t}\n\t\n\tWrite-Host \"Writing merged JSON to $outputPath...\"\n\t$mergedJson = $mergedObject | ConvertTo-Json -Depth 200\n\t[System.IO.File]::WriteAllLines($outputPath, $mergedJson)\n}\n\n$ErrorActionPreference = 'Stop'\n\nif($OctopusParameters -eq $null) {\n    Write-Host 'OctopusParameters is null...exiting with 1'\n    Exit 1    \n}\n\n$sourceFilePath = Get-RequiredParam 'jmf_SourceFile'\n$transformFilePath = Get-RequiredParam 'jmf_TransformFile'\n$failIfTransformFileMissing = Get-RequiredParam 'jmf_FailIfTransformFileMissing'\n$outputFilePath = Get-RequiredParam 'jmf_OutputFile'\n\nMerge-Json $sourceFilePath $transformFilePath $failIfTransformFileMissing $outputFilePath"
  },
  "Category": "JSON",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/json-merge.json",
  "Website": "/step-templates/6bb1fb50-de38-4380-a5ef-7f21ac3a3e6f",
  "Logo": "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",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Thursday, January 31, 2019