microsoft / json-document-transforms Goto Github PK
View Code? Open in Web Editor NEWJDT - Transform JSON files using a JSON transformation file
License: Other
JDT - Transform JSON files using a JSON transformation file
License: Other
Currently, the root-level element cannot be an array, the transformation will fail. First off, I think we need to add better error handling to improve the user experience. Then, look into supporting this without breaking transformations.
Copied from: microsoft/slow-cheetah#107
Trying to replace whole file which contains date with zero'es as milliseconds results in transformed file losing those zero'es
Transformation file:
{ "value": "2017-12-20T20:10:00.0000000" }
Transformed file:
{ "value": "2017-12-20T20:10:00" }
Expected transformed file:
{ "value": "2017-12-20T20:10:00.0000000" }
Hello all. First, my issue could very well be solved if I could find the correct and complete documentation for slow cheetah usage, specifically in PowerShell.
I'm trying to add the ability to transform json config files via powershell for use in certain cases (but not ALL environments/situations, so adding this to source/project files is not an option).
I'm able to do this exact same thing using XDT for web.config files in other builds, so I know its possible with the correct usage.
So far, I'm able to get all the way to the point where the transform should occur, but then get an error that is completely silent other than 'false'.
I was able to find someones example on stack exchange (https://stackoverflow.com/questions/62944828/can-you-run-microsoft-visualstudio-slowcheetah-from-powershell), which has been modified/simplified to eliminate issues. I'm left with this:
function GetNuget(){
process{
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
'Downloading nuget.exe' | Write-Verbose
$webclient = New-Object System.Net.WebClient
$webclient.DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', "$env:LOCALAPPDATA\NuGet\BuildTools\nuget.exe")
return "$env:LOCALAPPDATA\NuGet\BuildTools\nuget.exe"
}
}
function GetNugetPackage(){
if(!(Test-Path "$env:LOCALAPPDATA\NuGet\BuildTools\")){
New-Item -Path "$env:LOCALAPPDATA\NuGet\BuildTools\" -ItemType Directory | Out-Null
}
$cmdArgs = @(
'install',
'Microsoft.VisualStudio.SlowCheetah',
'-OutputDirectory',
(Resolve-Path "$env:LOCALAPPDATA\NuGet\BuildTools\").ToString()
)
&(GetNuget `
-toolsDir "$env:LOCALAPPDATA\NuGet\BuildTools\" `
-nugetDownloadUrl 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe') `
$cmdArgs | Out-Null
$toolPath = (
Get-ChildItem `
-Path "$env:LOCALAPPDATA\NuGet\BuildTools\" `
-Include 'Microsoft.VisualStudio.SlowCheetah.dll' `
-Recurse
) | Select-Object -First 1
return $toolPath
}
function TransformConfig{
[cmdletbinding()]
param(
[Parameter(
Mandatory=$true,
Position=0)]
$sourceFile,
[Parameter(
Mandatory=$true,
Position=1)]
$transformFile,
[Parameter(
Mandatory=$true,
Position=2)]
$destFile,
$toolsDir = "$env:LOCALAPPDATA\NuGet\BuildTools\"
)
process{
$sourcePath = (Resolve-Path $sourceFile).ToString()
$transformPath = (Resolve-Path $transformFile).ToString()
$cheetahPath = GetNugetPackage `
-packageName 'Microsoft.VisualStudio.SlowCheetah' `
-toolFileName 'Microsoft.VisualStudio.SlowCheetah.dll' `
-toolsDir "$env:LOCALAPPDATA\NuGet\BuildTools\"
[Reflection.Assembly]::LoadFrom($cheetahPath.FullName) | Out-Null
Add-Type -TypeDefinition $loggingStubSource -Language CSharp -ReferencedAssemblies $cheetahPath.FullName
$logStub = New-Object Microsoft.VisualStudio.SlowCheetah.LoggingStub
$transformer = [Microsoft.VisualStudio.SlowCheetah.TransformerFactory]::GetTransformer($sourcePath, $logStub);
$transformer.Transform($sourcePath, $transformPath, $destFile);
}
}
$loggingStubSource = @"
using System;
namespace Microsoft.VisualStudio.SlowCheetah
{
public class LoggingStub : ITransformationLogger
{
public void LogError(string message, params object[] messageArgs) { }
public void LogError(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) { }
public void LogErrorFromException(Exception ex) { }
public void LogErrorFromException(Exception ex, string file, int lineNumber, int linePosition) { }
public void LogMessage(LogMessageImportance importance, string message, params object[] messageArgs) { }
public void LogWarning(string message, params object[] messageArgs) { }
public void LogWarning(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) { }
}
}
"@
TransformConfig -sourceFile $sourceFile -transformFile $transformFile -destFile $destFile
I would appreciate, above all else, links to docs explaining proper usage. Understanding and being able to implement this more properly is ideal, but any help is welcome.
There are important files that Microsoft projects should all have that are not present in this repository. A pull request has been opened to add the missing file(s). When the pr is merged this issue will be closed automatically.
Microsoft teams can learn more about this effort and share feedback within the open source guidance available internally.
JsonTransformation.Apply
should detect the encoding of the input (either stream or file) and return a stream with the same encoding.
Note that StreamReader.CurrentEncoding
does not seem to work properly (see this). I have confirmed this problem through some testing.
When using slow cheetah to transform json files we discovered that the transforms would fail intermittently. This was particularly frequent when building a project targeting multiple frameworks (net461 and netcore2.1 in this instance). The parallel build behaviour of msbuild meant it would regularly attempt to perform the same transforms at the same time (once for each target framework).
This would result in msbuild output similar to:
[17:52:50] [Step 6/12] 2>UpdateLocalAppSettings:
[17:52:50] [Step 6/12] Beginning transformation.
[17:52:50] [Step 6/12] 15>UpdateLocalAppSettings:
[17:52:50] [Step 6/12] Beginning transformation.
[17:52:50] [Step 6/12] Transformation failed.
This seems to be caused by the source file being opened with exclusive access for the duration of the transform. The files need to be opened with a FileShare mode of Read to allow concurrent transformations.
Under the "Default Transformation" section there is an array listed as "SupportedVersions" that says the default transformation for arrays is append but when going to the "Replace" section, it does not show how to replace an array.
Let's assume I have 2 appsettings.json files that need merged so that the SupportedVersions array is replaced when listed under the Settings section.
First file
{
"Settings": {
"SupportedVersions" : [1, 2]
}
}
Second file
{
"Settings": {
"SupportedVersions" : [3, 4]
}
}
Expected output
{
"Settings": {
"SupportedVersions" : [3, 4]
}
}
I can get this to work by using the following but is there an easier way that I can't find in the documentation?
This works but is long
{
"Settings": {
"@jdt.replace" : {
"@jdt.path" : "$.SupportedVersions",
"@jdt.value" : [3, 4]
}
}
}
I'm transforming to intermediary values, not the final values;
I'm unable to transform this:
"ClientStoreExpiration": 300,
into this:
"ClientStoreExpiration": $IdentityServerClientStoreExpiration,
Is this possible?
When it's a string there is no problem because it sits inside quotes, ex:
"UserStoreUrl": "http:\\localhost"
into "UserStoreUrl": "$UserStoreUrl"
Hi.
If the source or transform files are read-only, an UnauthorizedAccessException is thrown:
System.UnauthorizedAccessException: Access to the path 'C:\MyApp\MyProject\MyFile.json' is denied.
I expected a transformation to succeed even if the source or transform files are read-only.
Here's a related issue: microsoft/slow-cheetah#86
Thank you.
Add the ability to replace a node with a code-generated value during the transformation.
Considering this example, I have a json that looks like this
{
"root": {
"second-level":{
"third-level":[1,2,3,4]
}
}
}
If I want to move the value of "third-level" up to the second level, like this
{
"root": {
"second-level":[1,2,3,4]
}
}
How should I write the transform string, or is it supported?
Hello,
Could you please create new nuget release which would include fix for issue #16?
Thank you
When I was trying to use the JDT by following the https://github.com/Microsoft/json-document-transforms/wiki.
Everytime when i use the @jdt.path in the transformation file, i continuously get the below Exception message
"@jdt.Path" is not a valid attribute for this transformation.
Below is the C# code, I have used by referring the wiki https://github.com/microsoft/json-document-transforms/wiki/Rename-Transformation
`
var engine = new JsonTransformation($"./{specName}");
var json = engine.Apply($"./{inputName}");
json.Position = 0;
using (StreamReader reader = new StreamReader(json, Encoding.UTF8))
{
var anotherVaue = reader.ReadToEnd();
Console.WriteLine(anotherVaue);
}`
Source file is
{ "A" : { "RenameThis" : true }, "B" : { "RenameThis" : false }, "C" : [ { "Name" : "C01", "Value" : 1 }, { "Name" : "C02", "Value" : 2 } ] }
Transform file
{ "@jdt.rename" : { "@jdt.Path " : "$[?(@.Rename == true)]", "@jdt.Value" : "Astar" }, "C" : { "@jdt.rename" : { "@jdt.path" : "@[*].Name", "@jdt.value" : "Nstar" } } }
When i try to do it i continuously received the below error.
"@jdt.Path" is not a valid attribute for this transformation.
After all the Trial and error by assuming something wrong with the source or transformation file. I downloaded the source code to find out the reason.
It seems, In JdtRename file. https://github.com/microsoft/json-document-transforms/blob/a9bf106829b3c9d8b73fdf67d37891f95d3f6ee8/src/Microsoft.VisualStudio.Jdt/Processors/Attributes/JdtAttributeValidator.cs Line Number 67. It tries to validate the property name and AttributeNames are equal.
Currently in our case, The property name would be @jdt.path and AttributeNames contains the EnumValues of [Path,Value].
Since it always fail and return the "@jdt.Path" is not a valid attribute for this transformation.
When i try modifying it in a below way. it started working fine.
I changed. from
internal static JdtAttributes GetByName(this IEnumerable<JdtAttributes> collection, string name) { // The default value for the enum is 0, which is None return collection.SingleOrDefault(a => a.FullName().Equals(name)); }
To This
internal static JdtAttributes GetByName(this IEnumerable<JdtAttributes> collection, string name) { // The default value for the enum is 0, which is None return collection.SingleOrDefault(a => a.FullName().ToLower().Contains(name.ToLower())); }
Is it a bug?
I have a JSON file with an object with one property called "Groups", which is an array of objects. In my base JSON, i have 2 objects in the array. for my PROD environment, i want to replace everything in the base JSON file with everything in the PROD transform file, which only has one object in the array. Unless i am missing something, i do not see a way to do that.
I'm trying to transform
{ "outputs": [
{ "type": "Sample" },
{
"type": "Sample1",
"indexNamePrefix": "Sample2",
"serviceUri": "Sample3",
"eventDocumentTypeName": "Sample4"
}
]
}
into something like this
{ "outputs": [
{ "type": "Sample" },
{
"type": "Sample1",
"indexNamePrefix": "Sample2",
"serviceUri": "NewValue",
"eventDocumentTypeName": "Sample4"
}
]
}
I have tried the couple of transforms based on your examples
Try 1:
I just tried to replace the serviceUri which was the only change, following the transform
{
"outputs": {
"@jdt.replace": {
"@jdt.path": "@[?(@.serviceUri == Sample3)]",
"@jdt.value": {
"serviceUri": "NewValue"
}
}
}
}
Result was something like below , which is similar to the transform and doesn't seem like transformation happened
{
"outputs": {
"@jdt.replace": {
"@jdt.path": "@[?(@.serviceUri == Sample3)]",
"@jdt.value": {
"serviceUri": "NewValue"
}
}
}
Try 2:
I tried to replace the entire outputs node
{
"outputs": {
// Double brackets are needed to specify
// the array as the transformation value
"@jdt.replace": [
[
{
"type": "Sample"
},
{
"type": "Sample1",
"indexNamePrefix": "Sample2",
"serviceUri": "NewValue",
"eventDocumentTypeName": "Sample4"
}
]
]
}
}
Result was the same as the transform here too , am I missing something ? because the basic remove and rename transforms are working fine.
Thanks in Advance
Example explained in Replace section of the wiki does not work - https://github.com/Microsoft/json-document-transforms/wiki/Replace-Transformation#path-attribute
Please fix the documentation.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.