├── .azuredevops
└── dependabot.yml
├── .config
└── dotnet-tools.json
├── .devcontainer
├── Dockerfile
└── devcontainer.json
├── .editorconfig
├── .gitattributes
├── .github
├── .editorconfig
├── actions
│ └── publish-artifacts
│ │ └── action.yaml
├── renovate.json
└── workflows
│ ├── build.yml
│ ├── docs.yml
│ ├── docs_validate.yml
│ └── libtemplate-update.yml
├── .gitignore
├── .vscode
├── extensions.json
├── launch.json
├── settings.json
└── tasks.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Directory.Build.props
├── Directory.Build.rsp
├── Directory.Build.targets
├── Directory.Packages.props
├── LICENSE
├── README.md
├── SECURITY.md
├── SUPPORT.md
├── azure-pipelines.yml
├── azure-pipelines
├── Archive-SourceCode.ps1
├── BuildStageVariables.yml
├── Get-InsertionPRId.ps1
├── GlobalVariables.yml
├── Install-NuGetPackage.ps1
├── Merge-CodeCoverage.ps1
├── NuGetSbom.targets
├── OptProf.yml
├── OptProf_part2.yml
├── PoliCheckExclusions.xml
├── PostPRMessage.ps1
├── TSAOptions.json
├── WIFtoPATauth.yml
├── apiscan.yml
├── archive-sourcecode.yml
├── build.yml
├── dotnet.yml
├── falsepositives.gdnsuppress
├── install-dependencies.yml
├── libtemplate-update.yml
├── microbuild.after.yml
├── microbuild.before.yml
├── no_authenticode.txt
├── no_strongname.txt
├── official.yml
├── prepare-insertion-stages.yml
├── publish-codecoverage.yml
├── publish-symbols.yml
├── publish_artifacts.ps1
├── release-deployment-prep.yml
├── release.yml
├── schedule-only-steps.yml
├── unofficial.yml
├── vs-insertion.yml
└── vs-validation.yml
├── docfx
├── .gitignore
├── docfx.json
├── docs
│ ├── features.md
│ ├── getting-started.md
│ └── toc.yml
├── index.md
└── toc.yml
├── global.json
├── init.cmd
├── init.ps1
├── nuget.config
├── src
├── .editorconfig
├── AssemblyInfo.cs
├── AssemblyInfo.vb
├── Directory.Build.props
├── Directory.Build.targets
├── Microsoft.VisualStudio.Jdt
│ ├── IJsonTransformationLogger.cs
│ ├── JdtException.cs
│ ├── JdtExtensions.cs
│ ├── JdtUtilities.cs
│ ├── JsonTransformation.cs
│ ├── JsonTransformationContextLogger.cs
│ ├── Microsoft.VisualStudio.Jdt.csproj
│ ├── Processors
│ │ ├── Attributes
│ │ │ ├── JdtAttributeExtensions.cs
│ │ │ └── JdtAttributeValidator.cs
│ │ ├── JdtArrayProcessor.cs
│ │ ├── JdtDefault.cs
│ │ ├── JdtMerge.cs
│ │ ├── JdtProcessor.ProcessorChain.cs
│ │ ├── JdtProcessor.cs
│ │ ├── JdtRecurse.cs
│ │ ├── JdtRemove.cs
│ │ ├── JdtRename.cs
│ │ ├── JdtReplace.cs
│ │ └── JdtValidator.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── OptProf.targets
├── VSInsertionMetadata
│ ├── Library.VSInsertionMetadata.proj
│ ├── ProfilingInputs.props
│ └── VSInsertionMetadata.targets
├── jdt.sln
├── stylecop.json
└── version.json
├── test
├── .editorconfig
├── Directory.Build.props
├── Directory.Build.targets
└── Microsoft.VisualStudio.Jdt.Tests
│ ├── App.config
│ ├── Inputs
│ ├── Default
│ │ ├── Array.Merge.Expected.json
│ │ ├── Array.Merge.Transform.json
│ │ ├── Array.Replace.Expected.json
│ │ ├── Array.Replace.Transform.json
│ │ ├── Array.Source.json
│ │ ├── Object.Merge.Expected.json
│ │ ├── Object.Merge.Transform.json
│ │ ├── Object.Replace.Expected.json
│ │ ├── Object.Replace.Transform.json
│ │ ├── Object.Source.json
│ │ ├── Primitive.AddArray.Expected.json
│ │ ├── Primitive.AddArray.Transform.json
│ │ ├── Primitive.AddObject.Expected.json
│ │ ├── Primitive.AddObject.Transform.json
│ │ ├── Primitive.AddPrimitive.Expected.json
│ │ ├── Primitive.AddPrimitive.Transform.json
│ │ ├── Primitive.Replace.Expected.json
│ │ ├── Primitive.Replace.Transform.json
│ │ └── Primitive.Source.json
│ ├── Merge
│ │ ├── Object.MergeObjects.Expected.json
│ │ ├── Object.MergeObjects.Transform.json
│ │ ├── Object.Source.json
│ │ ├── Object.UsingDirectPath.Expected.json
│ │ ├── Object.UsingDirectPath.Transform.json
│ │ ├── Primitive.MergeObjects.Expected.json
│ │ ├── Primitive.MergeObjects.Transform.json
│ │ ├── Primitive.MergePrimitives.Expected.json
│ │ ├── Primitive.MergePrimitives.Transform.json
│ │ ├── Primitive.Source.json
│ │ ├── Primitive.UsingSimplePath.Expected.json
│ │ └── Primitive.UsingSimplePath.Transform.json
│ ├── Remove
│ │ ├── Array.DirectPath.Expected.json
│ │ ├── Array.DirectPath.Transform.json
│ │ ├── Array.ScriptPath.Expected.json
│ │ ├── Array.ScriptPath.Transform.json
│ │ ├── Array.Source.json
│ │ ├── Object.DirectPath.Expected.json
│ │ ├── Object.DirectPath.Transform.json
│ │ ├── Object.InObject.Expected.json
│ │ ├── Object.InObject.Transform.json
│ │ ├── Object.PathToItself.Expected.json
│ │ ├── Object.PathToItself.Transform.json
│ │ ├── Object.Source.json
│ │ ├── Object.WithBool.Expected.json
│ │ ├── Object.WithBool.Transform.json
│ │ ├── Primitive.FromRoot.Expected.json
│ │ ├── Primitive.FromRoot.Transform.json
│ │ ├── Primitive.Source.json
│ │ ├── Primitive.UsingPathArray.Expected.json
│ │ ├── Primitive.UsingPathArray.Transform.json
│ │ ├── Primitive.UsingSimpleArray.Expected.json
│ │ ├── Primitive.UsingSimpleArray.Transform.json
│ │ ├── Primitive.UsingSimplePath.Expected.json
│ │ ├── Primitive.UsingSimplePath.Transform.json
│ │ └── Skipped
│ │ │ ├── Object.ScriptPath.Expected.json
│ │ │ └── Object.ScriptPath.Transform.json
│ ├── Rename
│ │ ├── Array.DirectPath.Expected.json
│ │ ├── Array.DirectPath.Transform.json
│ │ ├── Array.ScriptPath.Expected.json
│ │ ├── Array.ScriptPath.Transform .json
│ │ ├── Array.Source.json
│ │ ├── Object.InObject.Expected.json
│ │ ├── Object.InObject.Transform.json
│ │ ├── Object.Source.json
│ │ ├── Object.UsingSimplePath.Expected.json
│ │ ├── Object.UsingSimplePath.Transform.json
│ │ ├── Object.WithChangingNames.Expected.json
│ │ ├── Object.WithChangingNames.Transform.json
│ │ ├── Primitive.FromRoot.Expected.json
│ │ ├── Primitive.FromRoot.Transform.json
│ │ ├── Primitive.Source.json
│ │ ├── Primitive.UsingSimpleArray.Expected.json
│ │ ├── Primitive.UsingSimpleArray.Transform.json
│ │ ├── Primitive.UsingSimplePath.Expected.json
│ │ └── Primitive.UsingSimplePath.Transform.json
│ └── Replace
│ │ ├── Array.DirectPath.Expected.json
│ │ ├── Array.DirectPath.Transform.json
│ │ ├── Array.ScriptPath.Expected.json
│ │ ├── Array.ScriptPath.Transform.json
│ │ ├── Array.Source.json
│ │ ├── Object.Source.json
│ │ ├── Object.WithArray.Expected.json
│ │ ├── Object.WithArray.Transform.json
│ │ ├── Object.WithObject.Expected.json
│ │ ├── Object.WithObject.Transform.json
│ │ ├── Object.WithPrimitive.Expected.json
│ │ └── Object.WithPrimitive.Transform.json
│ ├── JdtUtilitiesTest.cs
│ ├── JsonTransformationTest.cs
│ ├── JsonTransformationTestLogger.cs
│ ├── Microsoft.VisualStudio.Jdt.Tests.csproj
│ ├── ReadOnlyTempFile.cs
│ ├── TransformTest.cs
│ └── xunit.runner.json
└── tools
├── Check-DotNetRuntime.ps1
├── Check-DotNetSdk.ps1
├── Convert-PDB.ps1
├── Get-ArtifactsStagingDirectory.ps1
├── Get-CodeCovTool.ps1
├── Get-LibTemplateBasis.ps1
├── Get-NuGetTool.ps1
├── Get-ProcDump.ps1
├── Get-SymbolFiles.ps1
├── Get-TempToolsPath.ps1
├── Install-DotNetSdk.ps1
├── Install-NuGetCredProvider.ps1
├── MergeFrom-Template.ps1
├── Prepare-Legacy-Symbols.ps1
├── Set-EnvVars.ps1
├── artifacts
├── APIScanInputs.ps1
├── LocBin.ps1
├── VSInsertion.ps1
├── Variables.ps1
├── _all.ps1
├── _stage_all.ps1
├── build_logs.ps1
├── coverageResults.ps1
├── deployables.ps1
├── projectAssetsJson.ps1
├── symbols.ps1
├── testResults.ps1
└── test_symbols.ps1
├── dotnet-test-cloud.ps1
├── publish-CodeCov.ps1
├── test.runsettings
└── variables
├── BusinessGroupName.ps1
├── DotNetSdkVersion.ps1
├── InsertJsonValues.ps1
├── InsertPropsValues.ps1
├── InsertTargetBranch.ps1
├── InsertVersionsValues.ps1
├── LocLanguages.ps1
├── ProfilingInputsDropName.ps1
├── SymbolsFeatureName.ps1
├── VstsDropNames.ps1
├── _all.ps1
└── _define.ps1
/.azuredevops/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Please see the documentation for all configuration options:
2 | # https://eng.ms/docs/products/dependabot/configuration/version_updates
3 |
4 | version: 2
5 | updates:
6 | - package-ecosystem: nuget
7 | directory: /
8 | schedule:
9 | interval: monthly
10 |
--------------------------------------------------------------------------------
/.config/dotnet-tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "isRoot": true,
4 | "tools": {
5 | "powershell": {
6 | "version": "7.5.0",
7 | "commands": [
8 | "pwsh"
9 | ],
10 | "rollForward": false
11 | },
12 | "dotnet-coverage": {
13 | "version": "17.14.2",
14 | "commands": [
15 | "dotnet-coverage"
16 | ],
17 | "rollForward": false
18 | },
19 | "nbgv": {
20 | "version": "3.7.115",
21 | "commands": [
22 | "nbgv"
23 | ],
24 | "rollForward": false
25 | },
26 | "docfx": {
27 | "version": "2.78.3",
28 | "commands": [
29 | "docfx"
30 | ],
31 | "rollForward": false
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/.devcontainer/Dockerfile:
--------------------------------------------------------------------------------
1 | # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions
2 | FROM mcr.microsoft.com/dotnet/sdk:9.0.202-noble@sha256:332e0362dd210a10348d436a5fb7f87aeec28c2c53ac2c3c2659e57c22294d0e
3 |
4 | # Installing mono makes `dotnet test` work without errors even for net472.
5 | # But installing it takes a long time, so it's excluded by default.
6 | #RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
7 | #RUN echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | tee /etc/apt/sources.list.d/mono-official-stable.list
8 | #RUN apt-get update
9 | #RUN DEBIAN_FRONTEND=noninteractive apt-get install -y mono-devel
10 |
11 | # Clear the NUGET_XMLDOC_MODE env var so xml api doc files get unpacked, allowing a rich experience in Intellisense.
12 | # See https://github.com/dotnet/dotnet-docker/issues/2790 for a discussion on this, where the prioritized use case
13 | # was *not* devcontainers, sadly.
14 | ENV NUGET_XMLDOC_MODE=
15 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Dev space",
3 | "dockerFile": "Dockerfile",
4 | "customizations": {
5 | "vscode": {
6 | "settings": {
7 | "terminal.integrated.shell.linux": "/usr/bin/pwsh"
8 | },
9 | "extensions": [
10 | "ms-azure-devops.azure-pipelines",
11 | "ms-dotnettools.csharp",
12 | "k--kato.docomment",
13 | "editorconfig.editorconfig",
14 | "esbenp.prettier-vscode",
15 | "pflannery.vscode-versionlens",
16 | "davidanson.vscode-markdownlint",
17 | "dotjoshjohnson.xml",
18 | "ms-vscode-remote.remote-containers",
19 | "ms-azuretools.vscode-docker",
20 | "tintoy.msbuild-project-tools"
21 | ]
22 | }
23 | },
24 | "postCreateCommand": "./init.ps1 -InstallLocality machine"
25 | }
26 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | # Ensure shell scripts use LF line endings (linux only accepts LF)
7 | *.sh eol=lf
8 | *.ps1 eol=lf
9 |
10 | # The macOS codesign tool is extremely picky, and requires LF line endings.
11 | *.plist eol=lf
12 |
13 | ###############################################################################
14 | # Set default behavior for command prompt diff.
15 | #
16 | # This is need for earlier builds of msysgit that does not have it on by
17 | # default for csharp files.
18 | # Note: This is only used by command line
19 | ###############################################################################
20 | #*.cs diff=csharp
21 |
22 | ###############################################################################
23 | # Set the merge driver for project and solution files
24 | #
25 | # Merging from the command prompt will add diff markers to the files if there
26 | # are conflicts (Merging from VS is not affected by the settings below, in VS
27 | # the diff markers are never inserted). Diff markers may cause the following
28 | # file extensions to fail to load in VS. An alternative would be to treat
29 | # these files as binary and thus will always conflict and require user
30 | # intervention with every merge. To do so, just uncomment the entries below
31 | ###############################################################################
32 | #*.sln merge=binary
33 | #*.csproj merge=binary
34 | #*.vbproj merge=binary
35 | #*.vcxproj merge=binary
36 | #*.vcproj merge=binary
37 | #*.dbproj merge=binary
38 | #*.fsproj merge=binary
39 | #*.lsproj merge=binary
40 | #*.wixproj merge=binary
41 | #*.modelproj merge=binary
42 | #*.sqlproj merge=binary
43 | #*.wwaproj merge=binary
44 |
45 | ###############################################################################
46 | # behavior for image files
47 | #
48 | # image files are treated as binary by default.
49 | ###############################################################################
50 | #*.jpg binary
51 | #*.png binary
52 | #*.gif binary
53 |
54 | ###############################################################################
55 | # diff behavior for common document formats
56 | #
57 | # Convert binary document formats to text before diffing them. This feature
58 | # is only available from the command line. Turn it on by uncommenting the
59 | # entries below.
60 | ###############################################################################
61 | #*.doc diff=astextplain
62 | #*.DOC diff=astextplain
63 | #*.docx diff=astextplain
64 | #*.DOCX diff=astextplain
65 | #*.dot diff=astextplain
66 | #*.DOT diff=astextplain
67 | #*.pdf diff=astextplain
68 | #*.PDF diff=astextplain
69 | #*.rtf diff=astextplain
70 | #*.RTF diff=astextplain
71 |
--------------------------------------------------------------------------------
/.github/.editorconfig:
--------------------------------------------------------------------------------
1 | [renovate.json*]
2 | indent_style = tab
3 |
--------------------------------------------------------------------------------
/.github/actions/publish-artifacts/action.yaml:
--------------------------------------------------------------------------------
1 | name: Publish artifacts
2 | description: Publish artifacts
3 |
4 | runs:
5 | using: composite
6 | steps:
7 | - name: 📥 Collect artifacts
8 | run: tools/artifacts/_stage_all.ps1
9 | shell: pwsh
10 | if: always()
11 |
12 | # TODO: replace this hard-coded list with a loop that utilizes the NPM package at
13 | # https://github.com/actions/toolkit/tree/main/packages/artifact (or similar) to push the artifacts.
14 |
15 | - name: 📢 Upload project.assets.json files
16 | if: always()
17 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
18 | with:
19 | name: projectAssetsJson-${{ runner.os }}
20 | path: ${{ runner.temp }}/_artifacts/projectAssetsJson
21 | continue-on-error: true
22 | - name: 📢 Upload variables
23 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
24 | with:
25 | name: variables-${{ runner.os }}
26 | path: ${{ runner.temp }}/_artifacts/Variables
27 | continue-on-error: true
28 | - name: 📢 Upload build_logs
29 | if: always()
30 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
31 | with:
32 | name: build_logs-${{ runner.os }}
33 | path: ${{ runner.temp }}/_artifacts/build_logs
34 | continue-on-error: true
35 | - name: 📢 Upload testResults
36 | if: always()
37 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
38 | with:
39 | name: testResults-${{ runner.os }}
40 | path: ${{ runner.temp }}/_artifacts/testResults
41 | continue-on-error: true
42 | - name: 📢 Upload coverageResults
43 | if: always()
44 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
45 | with:
46 | name: coverageResults-${{ runner.os }}
47 | path: ${{ runner.temp }}/_artifacts/coverageResults
48 | continue-on-error: true
49 | - name: 📢 Upload symbols
50 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
51 | with:
52 | name: symbols-${{ runner.os }}
53 | path: ${{ runner.temp }}/_artifacts/symbols
54 | continue-on-error: true
55 | - name: 📢 Upload deployables
56 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
57 | with:
58 | name: deployables-${{ runner.os }}
59 | path: ${{ runner.temp }}/_artifacts/deployables
60 | if: always()
61 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "github>microsoft/vs-renovate-presets:microbuild",
5 | "github>microsoft/vs-renovate-presets:vs_main_dependencies"
6 | ],
7 | "packageRules": []
8 | }
9 |
--------------------------------------------------------------------------------
/.github/workflows/docs.yml:
--------------------------------------------------------------------------------
1 | name: 📚 Docs
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
9 | permissions:
10 | actions: read
11 | pages: write
12 | id-token: write
13 | contents: read
14 |
15 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
16 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
17 | concurrency:
18 | group: pages
19 | cancel-in-progress: false
20 |
21 | jobs:
22 | publish-docs:
23 | environment:
24 | name: github-pages
25 | url: ${{ steps.deployment.outputs.page_url }}
26 | runs-on: ubuntu-latest
27 | steps:
28 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
29 | with:
30 | fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
31 | - name: ⚙ Install prerequisites
32 | run: ./init.ps1 -UpgradePrerequisites
33 |
34 | - run: dotnet docfx docfx/docfx.json
35 | name: 📚 Generate documentation
36 |
37 | - name: Upload artifact
38 | uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
39 | with:
40 | path: docfx/_site
41 |
42 | - name: Deploy to GitHub Pages
43 | id: deployment
44 | uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
45 |
--------------------------------------------------------------------------------
/.github/workflows/docs_validate.yml:
--------------------------------------------------------------------------------
1 | name: 📃 Docfx Validate
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - main
8 | - microbuild
9 |
10 | jobs:
11 | build:
12 | name: 📚 Doc validation
13 | runs-on: ubuntu-24.04
14 | steps:
15 | - uses: actions/checkout@v4
16 | with:
17 | fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
18 | - name: 🔗 Markup Link Checker (mlc)
19 | uses: becheran/mlc@v0.21.0
20 | with:
21 | args: --do-not-warn-for-redirect-to https://learn.microsoft.com*,https://dotnet.microsoft.com/*,https://dev.azure.com/*,https://app.codecov.io/* -p docfx -i https://aka.ms/onboardsupport,https://aka.ms/spot,https://msrc.microsoft.com/*,https://www.microsoft.com/msrc*,https://microsoft.com/msrc*
22 | - name: ⚙ Install prerequisites
23 | run: |
24 | ./init.ps1 -UpgradePrerequisites
25 | dotnet --info
26 | shell: pwsh
27 | - name: 📚 Verify docfx build
28 | run: dotnet docfx docfx/docfx.json --warningsAsErrors --disableGitFeatures
29 | if: runner.os == 'Linux'
30 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
4 | // List of extensions which should be recommended for users of this workspace.
5 | "recommendations": [
6 | "ms-azure-devops.azure-pipelines",
7 | "ms-dotnettools.csharp",
8 | "k--kato.docomment",
9 | "editorconfig.editorconfig",
10 | "esbenp.prettier-vscode",
11 | "pflannery.vscode-versionlens",
12 | "davidanson.vscode-markdownlint",
13 | "dotjoshjohnson.xml",
14 | "ms-vscode-remote.remote-containers",
15 | "ms-azuretools.vscode-docker",
16 | "tintoy.msbuild-project-tools"
17 | ],
18 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
19 | "unwantedRecommendations": []
20 | }
21 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to find out which attributes exist for C# debugging
3 | // Use hover for the description of the existing attributes
4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": ".NET Core Attach",
9 | "type": "coreclr",
10 | "request": "attach",
11 | "processId": "${command:pickProcess}"
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.trimTrailingWhitespace": true,
3 | "files.insertFinalNewline": true,
4 | "files.trimFinalNewlines": true,
5 | "azure-pipelines.1ESPipelineTemplatesSchemaFile": true,
6 | "omnisharp.enableEditorConfigSupport": true,
7 | "omnisharp.enableRoslynAnalyzers": true,
8 | "dotnet.completion.showCompletionItemsFromUnimportedNamespaces": true,
9 | "editor.formatOnSave": true,
10 | "[xml]": {
11 | "editor.wordWrap": "off"
12 | },
13 | // Treat these files as Azure Pipelines files
14 | "files.associations": {
15 | "**/azure-pipelines/**/*.yml": "azure-pipelines",
16 | "azure-pipelines.yml": "azure-pipelines"
17 | },
18 | // Use Prettier as the default formatter for Azure Pipelines files.
19 | // Needs to be explicitly configured: https://github.com/Microsoft/azure-pipelines-vscode#document-formatting
20 | "[azure-pipelines]": {
21 | "editor.defaultFormatter": "esbenp.prettier-vscode",
22 | "editor.formatOnSave": false // enable this when they conform
23 | },
24 | }
25 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "build",
6 | "command": "dotnet",
7 | "type": "process",
8 | "args": [
9 | "build",
10 | "${workspaceFolder}",
11 | "/property:GenerateFullPaths=true",
12 | "/consoleloggerparameters:NoSummary"
13 | ],
14 | "problemMatcher": "$msCompile"
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | $(MSBuildThisFileDirectory)
6 | $(RepoRootPath)obj\$([MSBuild]::MakeRelative($(RepoRootPath), $(MSBuildProjectDirectory)))\
7 | $(RepoRootPath)bin\$(MSBuildProjectName)\
8 | $(RepoRootPath)bin\Packages\$(Configuration)\NuGet\
9 | $(RepoRootPath)bin\Packages\$(Configuration)\Vsix\$(Platform)\
10 | enable
11 | enable
12 | latest
13 | true
14 | true
15 | true
16 |
17 |
18 | true
19 |
20 |
21 |
22 | false
23 |
24 |
25 | $(MSBuildThisFileDirectory)
26 |
27 |
28 | embedded
29 |
30 | https://github.com/microsoft/json-document-transforms
31 | Microsoft
32 | Microsoft
33 | © Microsoft Corporation. All rights reserved.
34 | MIT
35 | true
36 | true
37 | true
38 | snupkg
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | $(RepositoryUrl)/releases/tag/v$(Version)
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Directory.Build.rsp:
--------------------------------------------------------------------------------
1 | #------------------------------------------------------------------------------
2 | # This file contains command-line options that MSBuild will process as part of
3 | # every build, unless the "/noautoresponse" switch is specified.
4 | #
5 | # MSBuild processes the options in this file first, before processing the
6 | # options on the command line. As a result, options on the command line can
7 | # override the options in this file. However, depending on the options being
8 | # set, the overriding can also result in conflicts.
9 | #
10 | # NOTE: The "/noautoresponse" switch cannot be specified in this file, nor in
11 | # any response file that is referenced by this file.
12 | #------------------------------------------------------------------------------
13 | /nr:false
14 | /m
15 | /verbosity:minimal
16 | /clp:Summary;ForceNoAlign
17 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 13
5 | 16.9
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Directory.Packages.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | true
7 | 2.0.171
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | JSON Document Transforms
2 |
3 | MIT License
4 |
5 | Copyright (c) Microsoft Corporation. All rights reserved.
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | JSON Document Transfoms
2 | ============
3 | [](https://nuget.org/packages/Microsoft.VisualStudio.Jdt)
4 | [](https://ci.appveyor.com/project/jviau/json-document-transforms/branch/master)
5 |
6 | JSON Document Transforms (JDT) library. Perform transformations on JSON files using another JSON as the specification. This is the C# implementation.
7 |
8 | For more information on how JDT works, see the [JDT Wiki](https://github.com/Microsoft/json-document-transforms/wiki)
9 |
10 | This project has adopted the [Microsoft Open Source Code of
11 | Conduct](https://opensource.microsoft.com/codeofconduct/).
12 | For more information see the [Code of Conduct
13 | FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
14 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com)
15 | with any additional questions or comments.
16 |
17 | ## Trademarks
18 |
19 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.
20 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/msrc/pgp-key-msrc).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/msrc/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/SUPPORT.md:
--------------------------------------------------------------------------------
1 | # Support
2 |
3 | ## How to file issues and get help
4 |
5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing
6 | issues before filing new issues to avoid duplicates. For new issues, file your bug or
7 | feature request as a new Issue.
8 |
9 | For help and questions about using this project, please create an issue.
10 |
11 | ## Microsoft Support Policy
12 |
13 | Support for this **json-document-transforms** is limited to the resources listed above.
14 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | batch: true
3 | branches:
4 | include:
5 | - main
6 | - 'v*.*'
7 | - microbuild
8 | - 'validate/*'
9 | paths:
10 | exclude:
11 | - doc/
12 | - '*.md'
13 | - .vscode/
14 | - .github/
15 | - azure-pipelines/release.yml
16 |
17 | parameters:
18 | - name: EnableMacOSBuild
19 | displayName: Build on macOS
20 | type: boolean
21 | default: false # macOS is often bogged down in Azure Pipelines
22 | - name: RunTests
23 | displayName: Run tests
24 | type: boolean
25 | default: true
26 |
27 | variables:
28 | - template: /azure-pipelines/BuildStageVariables.yml@self
29 |
30 | jobs:
31 | - template: azure-pipelines/build.yml
32 | parameters:
33 | Is1ESPT: false
34 | EnableMacOSBuild: ${{ parameters.EnableMacOSBuild }}
35 | RunTests: ${{ parameters.RunTests }}
36 |
--------------------------------------------------------------------------------
/azure-pipelines/BuildStageVariables.yml:
--------------------------------------------------------------------------------
1 | variables:
2 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
3 | BuildConfiguration: Release
4 | NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages/
5 | # codecov_token: 4dc9e7e2-6b01-4932-a180-847b52b43d35 # Get a new one from https://codecov.io/
6 |
--------------------------------------------------------------------------------
/azure-pipelines/Get-InsertionPRId.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Look up the pull request URL of the insertion PR.
4 | #>
5 | $stagingFolder = $env:BUILD_STAGINGDIRECTORY
6 | if (!$stagingFolder) {
7 | $stagingFolder = $env:SYSTEM_DEFAULTWORKINGDIRECTORY
8 | if (!$stagingFolder) {
9 | Write-Error "This script must be run in an Azure Pipeline."
10 | exit 1
11 | }
12 | }
13 | $markdownFolder = Join-Path $stagingFolder (Join-Path 'MicroBuild' 'Output')
14 | $markdownFile = Join-Path $markdownFolder 'PullRequestUrl.md'
15 | if (!(Test-Path $markdownFile)) {
16 | Write-Error "This script should be run after the MicroBuildInsertVsPayload task."
17 | exit 2
18 | }
19 |
20 | $insertionPRUrl = Get-Content $markdownFile
21 | if (!($insertionPRUrl -match 'https:.+?/pullrequest/(\d+)')) {
22 | Write-Error "Failed to parse pull request URL: $insertionPRUrl"
23 | exit 3
24 | }
25 |
26 | $Matches[1]
27 |
--------------------------------------------------------------------------------
/azure-pipelines/GlobalVariables.yml:
--------------------------------------------------------------------------------
1 | variables:
2 | # These variables are required for MicroBuild tasks
3 | TeamName: VS IDE
4 | TeamEmail: vsidemicrobuild@microsoft.com
5 | # These variables influence insertion pipelines
6 | ContainsVsix: false # This should be true when the repo builds a VSIX that should be inserted to VS.
7 |
--------------------------------------------------------------------------------
/azure-pipelines/Install-NuGetPackage.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Installs a NuGet package.
4 | .PARAMETER PackageID
5 | The Package ID to install.
6 | .PARAMETER Version
7 | The version of the package to install. If unspecified, the latest stable release is installed.
8 | .PARAMETER Source
9 | The package source feed to find the package to install from.
10 | .PARAMETER PackagesDir
11 | The directory to install the package to. By default, it uses the Packages folder at the root of the repo.
12 | .PARAMETER ConfigFile
13 | The nuget.config file to use. By default, it uses :/nuget.config.
14 | .OUTPUTS
15 | System.String. The path to the installed package.
16 | #>
17 | [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Low')]
18 | Param(
19 | [Parameter(Position=1,Mandatory=$true)]
20 | [string]$PackageId,
21 | [Parameter()]
22 | [string]$Version,
23 | [Parameter()]
24 | [string]$Source,
25 | [Parameter()]
26 | [switch]$Prerelease,
27 | [Parameter()]
28 | [string]$PackagesDir="$PSScriptRoot\..\packages",
29 | [Parameter()]
30 | [string]$ConfigFile="$PSScriptRoot\..\nuget.config",
31 | [Parameter()]
32 | [ValidateSet('Quiet','Normal','Detailed')]
33 | [string]$Verbosity='normal'
34 | )
35 |
36 | $nugetPath = & "$PSScriptRoot\..\tools\Get-NuGetTool.ps1"
37 |
38 | try {
39 | Write-Verbose "Installing $PackageId..."
40 | $nugetArgs = "Install",$PackageId,"-OutputDirectory",$PackagesDir,'-ConfigFile',$ConfigFile
41 | if ($Version) { $nugetArgs += "-Version",$Version }
42 | if ($Source) { $nugetArgs += "-FallbackSource",$Source }
43 | if ($Prerelease) { $nugetArgs += "-Prerelease" }
44 | $nugetArgs += '-Verbosity',$Verbosity
45 |
46 | if ($PSCmdlet.ShouldProcess($PackageId, 'nuget install')) {
47 | $p = Start-Process $nugetPath $nugetArgs -NoNewWindow -Wait -PassThru
48 | if ($null -ne $p.ExitCode -and $p.ExitCode -ne 0) { throw }
49 | }
50 |
51 | # Provide the path to the installed package directory to our caller.
52 | Write-Output (Get-ChildItem "$PackagesDir\$PackageId.*")[0].FullName
53 | } finally {
54 | Pop-Location
55 | }
56 |
--------------------------------------------------------------------------------
/azure-pipelines/Merge-CodeCoverage.ps1:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pwsh
2 |
3 | <#
4 | .SYNOPSIS
5 | Merges code coverage reports.
6 | .PARAMETER Path
7 | The path(s) to search for Cobertura code coverage reports.
8 | .PARAMETER Format
9 | The format for the merged result. The default is Cobertura
10 | .PARAMETER OutputDir
11 | The directory the merged result will be written to. The default is `coveragereport` in the root of this repo.
12 | #>
13 | [CmdletBinding()]
14 | Param(
15 | [Parameter(Mandatory=$true)]
16 | [string[]]$Path,
17 | [ValidateSet('Badges', 'Clover', 'Cobertura', 'CsvSummary', 'Html', 'Html_Dark', 'Html_Light', 'HtmlChart', 'HtmlInline', 'HtmlInline_AzurePipelines', 'HtmlInline_AzurePipelines_Dark', 'HtmlInline_AzurePipelines_Light', 'HtmlSummary', 'JsonSummary', 'Latex', 'LatexSummary', 'lcov', 'MarkdownSummary', 'MHtml', 'PngChart', 'SonarQube', 'TeamCitySummary', 'TextSummary', 'Xml', 'XmlSummary')]
18 | [string]$Format='Cobertura',
19 | [string]$OutputFile=("$PSScriptRoot/../coveragereport/merged.cobertura.xml")
20 | )
21 |
22 | $RepoRoot = [string](Resolve-Path $PSScriptRoot/..)
23 | Push-Location $RepoRoot
24 | try {
25 | Write-Verbose "Searching $Path for *.cobertura.xml files"
26 | $reports = Get-ChildItem -Recurse $Path -Filter *.cobertura.xml
27 |
28 | if ($reports) {
29 | $reports |% { $_.FullName } |% {
30 | # In addition to replacing {reporoot}, we also normalize on one kind of slash so that the report aggregates data for a file whether data was collected on Windows or not.
31 | $xml = [xml](Get-Content -LiteralPath $_)
32 | $xml.coverage.packages.package.classes.class |? { $_.filename} |% {
33 | $_.filename = $_.filename.Replace('{reporoot}', $RepoRoot).Replace([IO.Path]::AltDirectorySeparatorChar, [IO.Path]::DirectorySeparatorChar)
34 | }
35 |
36 | $xml.Save($_)
37 | }
38 |
39 | $Inputs = $reports |% { Resolve-Path -relative $_.FullName }
40 |
41 | if ((Split-Path $OutputFile) -and -not (Test-Path (Split-Path $OutputFile))) {
42 | New-Item -Type Directory -Path (Split-Path $OutputFile) | Out-Null
43 | }
44 |
45 | & dotnet dotnet-coverage merge $Inputs -o $OutputFile -f cobertura
46 | } else {
47 | Write-Error "No reports found to merge."
48 | }
49 | } finally {
50 | Pop-Location
51 | }
52 |
--------------------------------------------------------------------------------
/azure-pipelines/NuGetSbom.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | $(TargetsForTfmSpecificBuildOutput);IncludeSbomInNupkg
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/azure-pipelines/PoliCheckExclusions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | NODE_MODULES|.STORE
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/azure-pipelines/PostPRMessage.ps1:
--------------------------------------------------------------------------------
1 | [CmdletBinding(SupportsShouldProcess = $true)]
2 | param(
3 | [Parameter(Mandatory=$true)]
4 | $AccessToken,
5 | [Parameter(Mandatory=$true)]
6 | $Markdown,
7 | [ValidateSet('Active','ByDesign','Closed','Fixed','Pending','Unknown','WontFix')]
8 | $CommentState='Active'
9 | )
10 |
11 | # See https://docs.microsoft.com/en-us/dotnet/api/microsoft.teamfoundation.sourcecontrol.webapi.commentthreadstatus?view=azure-devops-dotnet
12 | if ($CommentState -eq 'Active') {
13 | $StatusCode = 1
14 | } elseif ($CommentState -eq 'ByDesign') {
15 | $StatusCode = 5
16 | } elseif ($CommentState -eq 'Closed') {
17 | $StatusCode = 4
18 | } elseif ($CommentState -eq 'Fixed') {
19 | $StatusCode = 2
20 | } elseif ($CommentState -eq 'Pending') {
21 | $StatusCode = 6
22 | } elseif ($CommentState -eq 'Unknown') {
23 | $StatusCode = 0
24 | } elseif ($CommentState -eq 'WontFix') {
25 | $StatusCode = 3
26 | }
27 |
28 | # Build the JSON body up
29 | $body = ConvertTo-Json @{
30 | comments = @(@{
31 | parentCommentId = 0
32 | content = $Markdown
33 | commentType = 1
34 | })
35 | status = $StatusCode
36 | }
37 |
38 | Write-Verbose "Posting JSON payload: `n$Body"
39 |
40 | # Post the message to the Pull Request
41 | # https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pull%20request%20threads?view=azure-devops-rest-5.1
42 | $url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/git/repositories/$($env:BUILD_REPOSITORY_NAME)/pullRequests/$($env:SYSTEM_PULLREQUEST_PULLREQUESTID)/threads?api-version=5.1"
43 | if ($PSCmdlet.ShouldProcess($url, 'Post comment via REST call')) {
44 | try {
45 | if (!$env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI) {
46 | Write-Error "Posting to the pull request requires that the script is running in an Azure Pipelines context."
47 | exit 1
48 | }
49 | Write-Host "Posting PR comment to: $url"
50 | Invoke-RestMethod -Uri $url -Method POST -Headers @{Authorization = "Bearer $AccessToken"} -Body $Body -ContentType application/json
51 | }
52 | catch {
53 | Write-Error $_
54 | Write-Error $_.Exception.Message
55 | exit 2
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/azure-pipelines/TSAOptions.json:
--------------------------------------------------------------------------------
1 | {
2 | "tsaVersion": "TsaV2",
3 | "codebase": "NewOrUpdate",
4 | "codebaseName": "json-document-transforms",
5 | "tsaStamp": "DevDiv",
6 | "tsaEnvironment": "PROD",
7 | "notificationAliases": [
8 | "vsslnx@microsoft.com"
9 | ],
10 | "instanceUrl": "https://devdiv.visualstudio.com",
11 | "projectName": "DevDiv",
12 | "areaPath": "DevDiv\\VS Core\\Project\\SlowCheetah",
13 | "iterationPath": "DevDiv",
14 | "tools": [
15 | "APIScan",
16 | "CodeQL"
17 | ],
18 | "repositoryName": "json-document-transforms"
19 | }
20 |
--------------------------------------------------------------------------------
/azure-pipelines/WIFtoPATauth.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: deadPATServiceConnectionId # The GUID of the PAT-based service connection whose access token must be replaced.
3 | type: string
4 | - name: wifServiceConnectionName # The name of the WIF service connection to use to get the access token.
5 | type: string
6 | - name: resource # The scope for which the access token is requested.
7 | type: string
8 | default: 499b84ac-1321-427f-aa17-267ca6975798 # Azure Artifact feeds (any of them)
9 |
10 | steps:
11 | - task: AzureCLI@2
12 | displayName: 🔏 Authenticate with WIF service connection
13 | inputs:
14 | azureSubscription: ${{ parameters.wifServiceConnectionName }}
15 | scriptType: pscore
16 | scriptLocation: inlineScript
17 | inlineScript: |
18 | $accessToken = az account get-access-token --query accessToken --resource '${{ parameters.resource }}' -o tsv
19 | # Set the access token as a secret, so it doesn't get leaked in the logs
20 | Write-Host "##vso[task.setsecret]$accessToken"
21 | # Override the apitoken of the nuget service connection, for the duration of this stage
22 | Write-Host "##vso[task.setendpoint id=${{ parameters.deadPATServiceConnectionId }};field=authParameter;key=apitoken]$accessToken"
23 |
--------------------------------------------------------------------------------
/azure-pipelines/apiscan.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: windowsPool
3 | type: object
4 | - name: RealSign
5 | type: boolean
6 |
7 | jobs:
8 | - job: apiscan
9 | displayName: APIScan
10 | dependsOn: Windows
11 | pool: ${{ parameters.windowsPool }}
12 | timeoutInMinutes: 120
13 | templateContext:
14 | ${{ if not(parameters.RealSign) }}:
15 | mb:
16 | signing: # if the build is test-signed, install the signing plugin so that CSVTestSignPolicy.xml is available
17 | enabled: true
18 | zipSources: false
19 | signType: test
20 | outputs:
21 | - output: pipelineArtifact
22 | displayName: 📢 collect apiscan artifact
23 | targetPath: $(Pipeline.Workspace)/.gdn/.r/apiscan/001/Logs
24 | artifactName: apiscan-logs
25 | condition: succeededOrFailed()
26 | variables:
27 | - name: SymbolsFeatureName
28 | value: $[ dependencies.Windows.outputs['SetPipelineVariables.SymbolsFeatureName'] ]
29 | - name: NBGV_MajorMinorVersion
30 | value: $[ dependencies.Windows.outputs['nbgv.NBGV_MajorMinorVersion'] ]
31 | - ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
32 | # https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/25351/APIScan-step-by-step-guide-to-setting-up-a-Pipeline
33 | - group: VSEng sponsored APIScan # Expected to provide ApiScanClientId
34 | steps:
35 | # We need TSAOptions.json
36 | - checkout: self
37 | fetchDepth: 1
38 |
39 | - download: current
40 | artifact: APIScanInputs
41 | displayName: 🔻 Download APIScanInputs artifact
42 |
43 | - task: APIScan@2
44 | displayName: 🔍 Run APIScan
45 | inputs:
46 | softwareFolder: $(Pipeline.Workspace)/APIScanInputs
47 | softwareName: $(SymbolsFeatureName)
48 | softwareVersionNum: $(NBGV_MajorMinorVersion)
49 | isLargeApp: false
50 | toolVersion: Latest
51 | preserveLogsFolder: true
52 | env:
53 | AzureServicesAuthConnectionString: runAs=App;AppId=$(ApiScanClientId)
54 |
55 | # File bugs when APIScan finds issues
56 | - task: TSAUpload@2
57 | displayName: 🪳 TSA upload
58 | inputs:
59 | GdnPublishTsaOnboard: True
60 | GdnPublishTsaConfigFile: $(Build.SourcesDirectory)\azure-pipelines\TSAOptions.json
61 | condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
62 |
--------------------------------------------------------------------------------
/azure-pipelines/archive-sourcecode.yml:
--------------------------------------------------------------------------------
1 | trigger: none # We only want to trigger manually or based on resources
2 | pr: none
3 |
4 | # Source archival requirements come from a compliance tenet. Review a sample task here: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1550985
5 | # Source code should be archived within 30 days of the release date, and at least every quarter if your product is releasing more than once every 6 months.
6 | # If your sources on GitHub are public open source project, then using GitHub Public Archive is sufficient.
7 | schedules:
8 | - cron: "13 13 13 */3 *" # Every three months
9 | displayName: Periodic source archival
10 | branches:
11 | include:
12 | - main
13 |
14 | resources:
15 | repositories:
16 | - repository: MicroBuildTemplate
17 | type: git
18 | name: 1ESPipelineTemplates/MicroBuildTemplate
19 | ref: refs/tags/release
20 |
21 | parameters:
22 | - name: notes
23 | displayName: Notes to include in the SCA request
24 | type: string
25 | default: ' ' # optional parameters require a non-empty default.
26 | - name: whatif
27 | displayName: Only simulate the request
28 | type: boolean
29 | default: false
30 |
31 | variables:
32 | - group: VS Core team # Expected to provide ManagerAlias, SourceCodeArchivalUri
33 | - template: GlobalVariables.yml
34 |
35 | extends:
36 | template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate
37 | parameters:
38 | sdl:
39 | sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES
40 |
41 | stages:
42 | - stage: archive
43 | jobs:
44 | - job: archive
45 | pool:
46 | name: AzurePipelines-EO
47 | demands:
48 | - ImageOverride -equals 1ESPT-Ubuntu22.04
49 | os: Linux
50 |
51 | steps:
52 | - checkout: self
53 | clean: true
54 | fetchDepth: 0
55 | - powershell: tools/Install-DotNetSdk.ps1
56 | displayName: ⚙ Install .NET SDK
57 | - task: NuGetAuthenticate@1
58 | displayName: 🔏 Authenticate NuGet feeds
59 | inputs:
60 | forceReinstallCredentialProvider: true
61 | - script: dotnet tool restore
62 | displayName: ⚙️ Restore CLI tools
63 | - powershell: tools/variables/_define.ps1
64 | failOnStderr: true
65 | displayName: ⚙ Set pipeline variables based on source
66 | - task: AzureCLI@2
67 | displayName: 🔏 Authenticate with WIF service connection
68 | inputs:
69 | azureSubscription: VS Core Source Code Archival
70 | scriptType: pscore
71 | scriptLocation: inlineScript
72 | inlineScript: |
73 | $accessToken = az account get-access-token --query accessToken --resource api://177cf50a-4bf5-4481-8b7e-f32900dfc8e6 -o tsv
74 | Write-Host "##vso[task.setvariable variable=scaToken;issecret=true]$accessToken"
75 | - pwsh: >
76 | $TeamAlias = '$(TeamEmail)'.Substring(0, '$(TeamEmail)'.IndexOf('@'))
77 |
78 | azure-pipelines/Archive-SourceCode.ps1
79 | -ManagerAlias '$(ManagerAlias)'
80 | -TeamAlias $TeamAlias
81 | -BusinessGroupName '$(BusinessGroupName)'
82 | -ProductName '$(SymbolsFeatureName)'
83 | -ProductLanguage English
84 | -Notes '${{ parameters.notes }}'
85 | -AccessToken '$(scaToken)'
86 | -Verbose
87 | -WhatIf:$${{ parameters.whatif }}
88 | displayName: 🗃️ Submit archival request
89 |
--------------------------------------------------------------------------------
/azure-pipelines/dotnet.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: RunTests
3 | - name: IsOptProf
4 | type: boolean
5 | default: false
6 | - name: Is1ESPT
7 | type: boolean
8 |
9 | steps:
10 |
11 | - script: dotnet build src -t:build,pack --no-restore -c $(BuildConfiguration) /bl:"$(Build.ArtifactStagingDirectory)/build_logs/build.binlog"
12 | displayName: 🛠 dotnet build
13 |
14 | - ${{ if not(parameters.IsOptProf) }}:
15 | - powershell: tools/dotnet-test-cloud.ps1 -Configuration $(BuildConfiguration) -Agent $(Agent.JobName) -PublishResults
16 | displayName: 🧪 dotnet test
17 | condition: and(succeeded(), ${{ parameters.RunTests }})
18 |
19 | - ${{ if parameters.IsOptProf }}:
20 | - script: dotnet pack src\VSInsertionMetadata -c $(BuildConfiguration) -warnaserror /bl:"$(Build.ArtifactStagingDirectory)/build_logs/VSInsertion-Pack.binlog"
21 | displayName: 🔧 dotnet pack VSInsertionMetadata
22 |
23 | - powershell: tools/variables/_define.ps1
24 | failOnStderr: true
25 | displayName: ⚙ Update pipeline variables based on build outputs
26 | condition: succeededOrFailed()
27 |
28 | - ${{ if parameters.Is1ESPT }}:
29 | - powershell: azure-pipelines/publish_artifacts.ps1 -StageOnly -AvoidSymbolicLinks -ArtifactNameSuffix "-$(Agent.JobName)" -Verbose
30 | failOnStderr: true
31 | displayName: 📢 Stage artifacts
32 | condition: succeededOrFailed()
33 | - ${{ else }}:
34 | - powershell: azure-pipelines/publish_artifacts.ps1 -ArtifactNameSuffix "-$(Agent.JobName)" -Verbose
35 | failOnStderr: true
36 | displayName: 📢 Publish artifacts
37 | condition: succeededOrFailed()
38 |
39 | - ${{ if and(ne(variables['codecov_token'], ''), parameters.RunTests) }}:
40 | - powershell: |
41 | $ArtifactStagingFolder = & "tools/Get-ArtifactsStagingDirectory.ps1"
42 | $CoverageResultsFolder = Join-Path $ArtifactStagingFolder "coverageResults-$(Agent.JobName)"
43 | tools/publish-CodeCov.ps1 -CodeCovToken "$(codecov_token)" -PathToCodeCoverage "$CoverageResultsFolder" -Name "$(Agent.JobName) Coverage Results" -Flags "$(Agent.JobName)"
44 | displayName: 📢 Publish code coverage results to codecov.io
45 | timeoutInMinutes: 3
46 | continueOnError: true
47 |
--------------------------------------------------------------------------------
/azure-pipelines/falsepositives.gdnsuppress:
--------------------------------------------------------------------------------
1 | {
2 | "version": "latest",
3 | "suppressionSets": {
4 | "falsepositives": {
5 | "name": "falsepositives",
6 | "createdDate": "2021-12-03 00:23:08Z",
7 | "lastUpdatedDate": "2021-12-03 00:23:08Z"
8 | }
9 | },
10 | "results": {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/azure-pipelines/install-dependencies.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: initArgs
3 | type: string
4 | default: ''
5 | - name: needsAzurePublicFeeds
6 | type: boolean
7 | default: true # If nuget.config pulls from the azure-public account, we need to authenticate when building on the devdiv account.
8 |
9 | steps:
10 | - ${{ if and(parameters.needsAzurePublicFeeds, eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9')) }}:
11 | - template: WIFtoPATauth.yml
12 | parameters:
13 | wifServiceConnectionName: azure-public/vside package pull
14 | deadPATServiceConnectionId: 0ae39abc-4d06-4436-a7b5-865833df49db # azure-public/msft_consumption
15 |
16 | - task: NuGetAuthenticate@1
17 | displayName: 🔏 Authenticate NuGet feeds
18 | inputs:
19 | ${{ if and(parameters.needsAzurePublicFeeds, eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9')) }}:
20 | nuGetServiceConnections: azure-public/msft_consumption
21 |
22 | - powershell: |
23 | $AccessToken = '$(System.AccessToken)' # Avoid specifying the access token directly on the init.ps1 command line to avoid it showing up in errors
24 | .\init.ps1 -AccessToken $AccessToken ${{ parameters['initArgs'] }} -UpgradePrerequisites -NoNuGetCredProvider
25 | dotnet --info
26 |
27 | # Print mono version if it is present.
28 | if (Get-Command mono -ErrorAction SilentlyContinue) {
29 | mono --version
30 | }
31 | displayName: ⚙ Install prerequisites
32 |
33 | - powershell: tools/variables/_define.ps1
34 | failOnStderr: true
35 | displayName: ⚙ Set pipeline variables based on source
36 | name: SetPipelineVariables
37 |
--------------------------------------------------------------------------------
/azure-pipelines/microbuild.after.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: EnableOptProf
3 | type: boolean
4 | default: false
5 | - name: IsOptProf
6 | type: boolean
7 | default: false
8 | - name: SkipCodesignVerify
9 | type: boolean
10 |
11 | steps:
12 | - ${{ if not(parameters.SkipCodesignVerify) }}: # skip CodesignVerify on validation builds because we don't even test-sign nupkg's.
13 | - task: MicroBuildCodesignVerify@3
14 | displayName: 🔍 Verify Signed Files
15 | inputs:
16 | ApprovalListPathForSigs: $(Build.SourcesDirectory)\azure-pipelines\no_strongname.txt
17 | ApprovalListPathForCerts: $(Build.SourcesDirectory)\azure-pipelines\no_authenticode.txt
18 | TargetFolders: |
19 | $(Build.SourcesDirectory)/bin/Packages/$(BuildConfiguration)
20 | condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
21 |
22 | - ${{ if parameters.IsOptProf }}:
23 | - task: ms-vscs-artifact.build-tasks.artifactDropTask-1.artifactDropTask@0
24 | inputs:
25 | dropServiceURI: https://devdiv.artifacts.visualstudio.com
26 | buildNumber: $(ProfilingInputsDropName)
27 | sourcePath: $(Build.ArtifactStagingDirectory)\OptProf\ProfilingInputs
28 | toLowerCase: false
29 | usePat: true
30 | displayName: 📢 Publish to Artifact Services - ProfilingInputs
31 | condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
32 |
33 | - task: PublishBuildArtifacts@1
34 | inputs:
35 | PathtoPublish: $(Build.ArtifactStagingDirectory)/InsertionOutputs
36 | ArtifactName: InsertionOutputs
37 | ArtifactType: Container
38 | displayName: 📢 Publish InsertionOutputs as Azure DevOps artifacts
39 |
--------------------------------------------------------------------------------
/azure-pipelines/microbuild.before.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: EnableLocalization
3 | type: boolean
4 | default: false
5 | - name: EnableOptProf
6 | type: boolean
7 | default: false
8 | - name: IsOptProf
9 | type: boolean
10 | default: false
11 | - name: ShouldSkipOptimize
12 | type: boolean
13 | default: false
14 | - name: RealSign
15 | type: boolean
16 |
17 | steps:
18 | - ${{ if and(not(parameters.IsOptProf), ne(variables['Build.Reason'], 'PullRequest')) }}:
19 | # notice@0 requires CG detection to run first, and non-default branches don't inject it automatically.
20 | - task: ComponentGovernanceComponentDetection@0
21 | displayName: 🔍 Component Detection
22 |
23 | - task: notice@0
24 | displayName: 🛠️ Generate NOTICE file
25 | inputs:
26 | outputfile: $(System.DefaultWorkingDirectory)/obj/NOTICE
27 | outputformat: text
28 | retryCountOnTaskFailure: 3 # fails when the cloud service is overloaded
29 | continueOnError: ${{ not(parameters.RealSign) }} # Tolerate failures when we're not building something that may ship.
30 |
31 | - ${{ if parameters.IsOptProf }}:
32 | # We have to install these plugins ourselves for Optprof runs because those pipelines haven't migrated to 1ES PT yet.
33 | - task: MicroBuildOptProfPlugin@6
34 | inputs:
35 | ProfilingInputsDropName: $(ProfilingInputsDropName)
36 | OptimizationInputsLookupMethod: DropPrefix
37 | DropNamePrefix: OptimizationInputs/$(System.TeamProject)/$(Build.Repository.Name)
38 | ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }}
39 | AccessToken: $(System.AccessToken)
40 | displayName: 🔧 Install OptProf Plugin
41 |
42 | - task: MicroBuildSigningPlugin@4
43 | inputs:
44 | signType: Real
45 | zipSources: false
46 | displayName: 🔧 Install MicroBuild Signing Plugin
47 |
48 | - ${{ if parameters.EnableLocalization }}:
49 | - task: MicroBuildLocalizationPlugin@4
50 | inputs:
51 | languages: $(LocLanguages)
52 | displayName: 🔧 Install MicroBuild Localization Plugin
53 |
--------------------------------------------------------------------------------
/azure-pipelines/no_authenticode.txt:
--------------------------------------------------------------------------------
1 | bin\packages\release\vsix\_manifest\manifest.cat,sbom signed
2 | bin\packages\release\vsix\_manifest\spdx_2.2\manifest.cat,sbom signed
3 |
--------------------------------------------------------------------------------
/azure-pipelines/no_strongname.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/json-document-transforms/6b1170757c9c032fce38e46b0deaf9817dfa96b9/azure-pipelines/no_strongname.txt
--------------------------------------------------------------------------------
/azure-pipelines/official.yml:
--------------------------------------------------------------------------------
1 | trigger: none # We only want to trigger manually or based on a schedule
2 | pr: none
3 | #schedules:
4 | #- cron: "0 3 * * *" # Daily @ 8 PM PST
5 | # displayName: Daily vs-insertion
6 | # branches:
7 | # include:
8 | # - microbuild
9 |
10 | parameters:
11 | # As an entrypoint pipeline yml file, all parameters here show up in the Queue Run dialog.
12 | # If any paramaters should NOT be queue-time options, they should be removed from here
13 | # and references to them in this file replaced with hard-coded values.
14 | # - name: ShouldSkipOptimize # Uncomment this and references to it below when setting EnableOptProf to true in build.yml.
15 | # displayName: Skip OptProf optimization
16 | # type: boolean
17 | # default: false
18 | - name: EnableMacOSBuild
19 | displayName: Build on macOS
20 | type: boolean
21 | default: false # macOS is often bogged down in Azure Pipelines
22 | - name: RunTests
23 | displayName: Run tests
24 | type: boolean
25 | default: true
26 | - name: EnableAPIScan
27 | displayName: Include APIScan with compliance tools
28 | type: boolean
29 | default: false # enable in individual repos only AFTER updating TSAOptions.json with your own values
30 | - name: PublishCodeCoverage
31 | displayName: Publish code coverage
32 | type: boolean
33 | default: true
34 |
35 | resources:
36 | repositories:
37 | - repository: MicroBuildTemplate
38 | type: git
39 | name: 1ESPipelineTemplates/MicroBuildTemplate
40 | ref: refs/tags/release
41 |
42 | variables:
43 | - template: GlobalVariables.yml
44 |
45 | extends:
46 | template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate
47 | parameters:
48 | sdl:
49 | sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES
50 | codeSignValidation:
51 | enabled: true
52 | break: true
53 | additionalTargetsGlobPattern: -|Variables-*\*.ps1;-|LocBin-*\**;-|APIScanInputs-*\**;-|test_symbols-*\**;-|MicroBuild\**
54 | policheck:
55 | enabled: true
56 | exclusionsFile: $(System.DefaultWorkingDirectory)\azure-pipelines\PoliCheckExclusions.xml
57 | suppression:
58 | suppressionFile: $(System.DefaultWorkingDirectory)\azure-pipelines\falsepositives.gdnsuppress
59 | sbom:
60 | enabled: false # Skip 1ES SBOM because microbuild has our own sbom system
61 | stages:
62 | - stage: Build
63 | variables:
64 | - template: /azure-pipelines/BuildStageVariables.yml@self
65 | jobs:
66 | - template: /azure-pipelines/build.yml@self
67 | parameters:
68 | Is1ESPT: true
69 | RealSign: true
70 | # ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }}
71 | EnableAPIScan: ${{ parameters.EnableAPIScan }}
72 | windowsPool: VSEngSS-MicroBuild2022-1ES
73 | linuxPool:
74 | name: AzurePipelines-EO
75 | demands:
76 | - ImageOverride -equals 1ESPT-Ubuntu22.04
77 | os: Linux
78 | macOSPool:
79 | name: Azure Pipelines
80 | vmImage: macOS-14
81 | os: macOS
82 | EnableMacOSBuild: ${{ parameters.EnableMacOSBuild }}
83 | RunTests: ${{ parameters.RunTests }}
84 | PublishCodeCoverage: ${{ parameters.PublishCodeCoverage }}
85 | - template: /azure-pipelines/prepare-insertion-stages.yml@self
86 | parameters:
87 | RealSign: true
88 |
--------------------------------------------------------------------------------
/azure-pipelines/prepare-insertion-stages.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: ArchiveSymbols
3 | type: boolean
4 | default: true
5 | - name: RealSign
6 | displayName: Real sign?
7 | type: boolean
8 | - name: PackagePush
9 | type: boolean
10 | default: false # Switch to true to enable the push job below
11 |
12 | stages:
13 | - ${{ if or(parameters.ArchiveSymbols, parameters.PackagePush) }}:
14 | - stage: release
15 | displayName: Publish
16 | jobs:
17 | - ${{ if parameters.ArchiveSymbols }}:
18 | - job: symbol_archive
19 | displayName: Archive symbols
20 | pool: VSEngSS-MicroBuild2022-1ES
21 | steps:
22 | - checkout: none
23 | - download: current
24 | artifact: Variables-Windows
25 | displayName: 🔻 Download Variables-Windows artifact
26 | - powershell: $(Pipeline.Workspace)/Variables-Windows/_define.ps1
27 | displayName: ⚙️ Set pipeline variables based on artifacts
28 | - download: current
29 | artifact: symbols-legacy
30 | displayName: 🔻 Download symbols-legacy artifact
31 | - task: MicroBuildArchiveSymbols@5
32 | displayName: 🔣 Archive symbols to Symweb
33 | inputs:
34 | SymbolsFeatureName: $(SymbolsFeatureName)
35 | SymbolsProject: VS
36 | SymbolsAgentPath: $(Pipeline.Workspace)/symbols-legacy
37 |
38 | - ${{ if parameters.PackagePush }}:
39 | - job: push
40 | ${{ if parameters.RealSign }}:
41 | displayName: azure-public/vs-impl feed
42 | ${{ else }}:
43 | displayName: devdiv/vs-impl feed # Leave this as-is, since non-signed builds must not be pushed to public feeds.
44 | ${{ if parameters.ArchiveSymbols }}:
45 | dependsOn: symbol_archive
46 | pool:
47 | name: AzurePipelines-EO
48 | demands:
49 | - ImageOverride -equals 1ESPT-Ubuntu22.04
50 | os: Linux
51 | templateContext:
52 | outputs:
53 | - output: nuget
54 | displayName: 📦 Push nuget packages
55 | packagesToPush: '$(Pipeline.Workspace)/deployables-Windows/NuGet/*.nupkg'
56 | packageParentPath: $(Pipeline.Workspace)/deployables-Windows/NuGet
57 | allowPackageConflicts: true
58 | ${{ if parameters.RealSign }}:
59 | nuGetFeedType: external
60 | publishFeedCredentials: azure-public/vs-impl
61 | ${{ else }}:
62 | nuGetFeedType: internal
63 | publishVstsFeed: vs-impl # Leave this as-is, since non-signed builds must not be pushed to public feeds.
64 | steps:
65 | - checkout: none
66 | - download: current
67 | artifact: Variables-Windows
68 | displayName: 🔻 Download Variables-Windows artifact
69 | - powershell: $(Pipeline.Workspace)/Variables-Windows/_define.ps1
70 | displayName: ⚙️ Set pipeline variables based on artifacts
71 | - download: current
72 | artifact: deployables-Windows
73 | displayName: 🔻 Download deployables-Windows artifact
74 | - ${{ if parameters.RealSign }}:
75 | - template: WIFtoPATauth.yml
76 | parameters:
77 | wifServiceConnectionName: azure-public/vside package push
78 | deadPATServiceConnectionId: 207efd62-fd0f-43e7-aeae-17c4febcc660 # azure-public/vs-impl
79 |
--------------------------------------------------------------------------------
/azure-pipelines/publish-codecoverage.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: EnableMacOSBuild
3 | type: boolean
4 | - name: EnableLinuxBuild
5 | type: boolean
6 |
7 | steps:
8 | - download: current
9 | artifact: coverageResults-Windows
10 | displayName: 🔻 Download Windows code coverage results
11 | continueOnError: true
12 | - ${{ if parameters.EnableLinuxBuild }}:
13 | - download: current
14 | artifact: coverageResults-Linux
15 | displayName: 🔻 Download Linux code coverage results
16 | continueOnError: true
17 | - ${{ if parameters.EnableMacOSBuild }}:
18 | - download: current
19 | artifact: coverageResults-macOS
20 | displayName: 🔻 Download macOS code coverage results
21 | continueOnError: true
22 | - powershell: azure-pipelines/Merge-CodeCoverage.ps1 -Path '$(Pipeline.Workspace)' -OutputFile coveragereport/merged.cobertura.xml -Format Cobertura -Verbose
23 | displayName: ⚙ Merge coverage
24 | - task: PublishCodeCoverageResults@2
25 | displayName: 📢 Publish code coverage results to Azure DevOps
26 | inputs:
27 | summaryFileLocation: coveragereport/merged.cobertura.xml
28 | failIfCoverageEmpty: true
29 |
--------------------------------------------------------------------------------
/azure-pipelines/publish-symbols.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: EnableMacOSBuild
3 | type: boolean
4 | - name: EnableLinuxBuild
5 | type: boolean
6 |
7 | steps:
8 | - task: DownloadPipelineArtifact@2
9 | inputs:
10 | artifact: symbols-Windows
11 | path: $(Pipeline.Workspace)/symbols/Windows
12 | displayName: 🔻 Download Windows symbols
13 | continueOnError: true
14 | - ${{ if parameters.EnableLinuxBuild }}:
15 | - task: DownloadPipelineArtifact@2
16 | inputs:
17 | artifact: symbols-Linux
18 | path: $(Pipeline.Workspace)/symbols/Linux
19 | displayName: 🔻 Download Linux symbols
20 | continueOnError: true
21 | - ${{ if parameters.EnableMacOSBuild }}:
22 | - task: DownloadPipelineArtifact@2
23 | inputs:
24 | artifact: symbols-macOS
25 | path: $(Pipeline.Workspace)/symbols/macOS
26 | displayName: 🔻 Download macOS symbols
27 | continueOnError: true
28 |
29 | - task: DownloadPipelineArtifact@2
30 | inputs:
31 | artifact: test_symbols-Windows
32 | path: $(Pipeline.Workspace)/test_symbols/Windows
33 | displayName: 🔻 Download Windows test symbols
34 | continueOnError: true
35 | - ${{ if parameters.EnableLinuxBuild }}:
36 | - task: DownloadPipelineArtifact@2
37 | inputs:
38 | artifact: test_symbols-Linux
39 | path: $(Pipeline.Workspace)/test_symbols/Linux
40 | displayName: 🔻 Download Linux test symbols
41 | continueOnError: true
42 | - ${{ if parameters.EnableMacOSBuild }}:
43 | - task: DownloadPipelineArtifact@2
44 | inputs:
45 | artifact: test_symbols-macOS
46 | path: $(Pipeline.Workspace)/test_symbols/macOS
47 | displayName: 🔻 Download macOS test symbols
48 | continueOnError: true
49 |
50 | - task: PublishSymbols@2
51 | inputs:
52 | SymbolsFolder: $(Pipeline.Workspace)/symbols
53 | SearchPattern: '**/*.pdb'
54 | IndexSources: false
55 | SymbolServerType: TeamServices
56 | displayName: 📢 Publish symbols
57 |
58 | - task: PublishSymbols@2
59 | inputs:
60 | SymbolsFolder: $(Pipeline.Workspace)/test_symbols
61 | SearchPattern: '**/*.pdb'
62 | IndexSources: false
63 | SymbolServerType: TeamServices
64 | displayName: 📢 Publish test symbols
65 |
66 | - powershell: tools/Prepare-Legacy-Symbols.ps1 -Path $(Pipeline.Workspace)/symbols/Windows
67 | displayName: ⚙ Prepare symbols for symbol archival
68 |
--------------------------------------------------------------------------------
/azure-pipelines/publish_artifacts.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | This script translates all the artifacts described by _all.ps1
4 | into commands that instruct Azure Pipelines to actually collect those artifacts.
5 | #>
6 |
7 | [CmdletBinding()]
8 | param (
9 | [string]$ArtifactNameSuffix,
10 | [switch]$StageOnly,
11 | [switch]$AvoidSymbolicLinks
12 | )
13 |
14 | Function Set-PipelineVariable($name, $value) {
15 | if ((Test-Path "Env:\$name") -and (Get-Item "Env:\$name").Value -eq $value) {
16 | return # already set
17 | }
18 |
19 | #New-Item -LiteralPath "Env:\$name".ToUpper() -Value $value -Force | Out-Null
20 | Write-Host "##vso[task.setvariable variable=$name]$value"
21 | }
22 |
23 | Function Test-ArtifactUploaded($artifactName) {
24 | $varName = "ARTIFACTUPLOADED_$($artifactName.ToUpper())"
25 | Test-Path "env:$varName"
26 | }
27 |
28 | & "$PSScriptRoot/../tools/artifacts/_stage_all.ps1" -ArtifactNameSuffix $ArtifactNameSuffix -AvoidSymbolicLinks:$AvoidSymbolicLinks |% {
29 | # Set a variable which will out-live this script so that a subsequent attempt to collect and upload artifacts
30 | # will skip this one from a check in the _all.ps1 script.
31 | Set-PipelineVariable "ARTIFACTSTAGED_$($_.Name.ToUpper())" 'true'
32 | Write-Host "Staged artifact $($_.Name) to $($_.Path)"
33 |
34 | if (!$StageOnly) {
35 | if (Test-ArtifactUploaded $_.Name) {
36 | Write-Host "Skipping $($_.Name) because it has already been uploaded." -ForegroundColor DarkGray
37 | } else {
38 | Write-Host "##vso[artifact.upload containerfolder=$($_.Name);artifactname=$($_.Name);]$($_.Path)"
39 |
40 | # Set a variable which will out-live this script so that a subsequent attempt to collect and upload artifacts
41 | # will skip this one from a check in the _all.ps1 script.
42 | Set-PipelineVariable "ARTIFACTUPLOADED_$($_.Name.ToUpper())" 'true'
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/azure-pipelines/release-deployment-prep.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - download: CI
3 | artifact: Variables-Windows
4 | displayName: 🔻 Download Variables-Windows artifact
5 | - powershell: $(Pipeline.Workspace)/CI/Variables-Windows/_define.ps1
6 | displayName: ⚙️ Set pipeline variables based on artifacts
7 |
--------------------------------------------------------------------------------
/azure-pipelines/release.yml:
--------------------------------------------------------------------------------
1 | trigger: none # We only want to trigger manually or based on resources
2 | pr: none
3 |
4 | resources:
5 | repositories:
6 | - repository: MicroBuildTemplate
7 | type: git
8 | name: 1ESPipelineTemplates/MicroBuildTemplate
9 | ref: refs/tags/release
10 | pipelines:
11 | - pipeline: CI
12 | source: json-document-transforms-ci # TODO: This should match the name of your CI pipeline
13 | trigger:
14 | tags:
15 | - auto-release
16 |
17 | variables:
18 | - template: GlobalVariables.yml
19 |
20 | extends:
21 | template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate
22 | parameters:
23 | sdl:
24 | sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES
25 |
26 | stages:
27 | - stage: release
28 | jobs:
29 | - job: release
30 | pool:
31 | name: AzurePipelines-EO
32 | demands:
33 | - ImageOverride -equals 1ESPT-Ubuntu22.04
34 | os: Linux
35 | templateContext:
36 | outputs:
37 | - output: nuget
38 | displayName: 📦 Push packages to nuget.org
39 | packagesToPush: '$(Pipeline.Workspace)/CI/deployables-Windows/NuGet/*.nupkg'
40 | packageParentPath: $(Pipeline.Workspace)/CI/deployables-Windows/NuGet
41 | allowPackageConflicts: true
42 | nuGetFeedType: external
43 | publishFeedCredentials: VisualStudioExtensibility (nuget.org)
44 | steps:
45 | - checkout: none
46 | - powershell: |
47 | Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)"
48 | if ('$(resources.pipeline.CI.runName)'.Contains('-')) {
49 | Write-Host "##vso[task.setvariable variable=IsPrerelease]true"
50 | } else {
51 | Write-Host "##vso[task.setvariable variable=IsPrerelease]false"
52 | }
53 | displayName: ⚙ Set up pipeline
54 | - download: CI
55 | artifact: deployables-Windows
56 | displayName: 🔻 Download deployables-Windows artifact
57 | patterns: 'NuGet/*'
58 | - task: GitHubRelease@1
59 | displayName: 📢 GitHub release (create)
60 | inputs:
61 | gitHubConnection: ttstanley # TODO: fill in service connection here
62 | repositoryName: $(Build.Repository.Name)
63 | target: $(resources.pipeline.CI.sourceCommit)
64 | tagSource: userSpecifiedTag
65 | tag: v$(resources.pipeline.CI.runName)
66 | title: v$(resources.pipeline.CI.runName)
67 | isDraft: true # After running this step, visit the new draft release, edit, and publish.
68 | isPreRelease: $(IsPrerelease)
69 | assets: $(Pipeline.Workspace)/CI/deployables-Windows/NuGet/*.nupkg
70 | changeLogCompareToRelease: lastNonDraftRelease
71 | changeLogType: issueBased
72 | changeLogLabels: |
73 | [
74 | { "label" : "breaking change", "displayName" : "Breaking changes", "state" : "closed" },
75 | { "label" : "bug", "displayName" : "Fixes", "state" : "closed" },
76 | { "label" : "enhancement", "displayName": "Enhancements", "state" : "closed" }
77 | ]
78 |
--------------------------------------------------------------------------------
/azure-pipelines/schedule-only-steps.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - powershell: echo "##vso[build.addbuildtag]auto-insertion"
3 | displayName: Tag for auto-insertion
4 |
--------------------------------------------------------------------------------
/azure-pipelines/unofficial.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | batch: true
3 | branches:
4 | include:
5 | - main
6 | - microbuild
7 | - 'validate/*'
8 | paths:
9 | exclude:
10 | - doc/
11 | - '*.md'
12 | - .vscode/
13 | - azure-pipelines/release.yml
14 | - azure-pipelines/vs-insertion.yml
15 |
16 | parameters:
17 | # As an entrypoint pipeline yml file, all parameters here show up in the Queue Run dialog.
18 | # If any paramaters should NOT be queue-time options, they should be removed from here
19 | # and references to them in this file replaced with hard-coded values.
20 | # - name: ShouldSkipOptimize # Uncomment this and references to it below when setting EnableOptProf to true in build.yml.
21 | # displayName: Skip OptProf optimization
22 | # type: boolean
23 | # default: false
24 | - name: EnableMacOSBuild
25 | displayName: Build on macOS
26 | type: boolean
27 | default: false # macOS is often bogged down in Azure Pipelines
28 | - name: RunTests
29 | displayName: Run tests
30 | type: boolean
31 | default: true
32 | - name: EnableAPIScan
33 | displayName: Include APIScan with compliance tools
34 | type: boolean
35 | default: false
36 | - name: EnableProductionSDL
37 | displayName: Enable Production SDL
38 | type: boolean
39 | default: false
40 | - name: PublishCodeCoverage
41 | displayName: Publish code coverage
42 | type: boolean
43 | default: true
44 |
45 | resources:
46 | repositories:
47 | - repository: MicroBuildTemplate
48 | type: git
49 | name: 1ESPipelineTemplates/MicroBuildTemplate
50 | ref: refs/tags/release
51 |
52 | variables:
53 | - template: GlobalVariables.yml
54 |
55 | extends:
56 | template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate
57 | parameters:
58 | sdl:
59 | sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES
60 | suppression:
61 | suppressionFile: $(System.DefaultWorkingDirectory)\azure-pipelines\falsepositives.gdnsuppress
62 | enableProductionSDL: ${{ parameters.EnableProductionSDL }}
63 | codeSignValidation:
64 | enabled: ${{ parameters.EnableProductionSDL }}
65 | break: true
66 | additionalTargetsGlobPattern: -|Variables-*\*.ps1;-|APIScanInputs-*\**;-|test_symbols-*\**;-|MicroBuild\**
67 | policyFile: $(MBSIGN_APPFOLDER)\CSVTestSignPolicy.xml
68 | policheck:
69 | enabled: ${{ parameters.EnableProductionSDL }}
70 | exclusionsFile: $(System.DefaultWorkingDirectory)\azure-pipelines\PoliCheckExclusions.xml
71 | sbom:
72 | enabled: false # Skip 1ES SBOM because microbuild has our own sbom system
73 | stages:
74 | - stage: Build
75 | variables:
76 | - template: /azure-pipelines/BuildStageVariables.yml@self
77 | jobs:
78 | - template: /azure-pipelines/build.yml@self
79 | parameters:
80 | Is1ESPT: true
81 | RealSign: false
82 | # ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }}
83 | EnableAPIScan: ${{ parameters.EnableAPIScan }}
84 | windowsPool: VSEngSS-MicroBuild2022-1ES
85 | linuxPool:
86 | name: AzurePipelines-EO
87 | demands:
88 | - ImageOverride -equals 1ESPT-Ubuntu22.04
89 | os: Linux
90 | macOSPool:
91 | name: Azure Pipelines
92 | vmImage: macOS-14
93 | os: macOS
94 | EnableMacOSBuild: ${{ parameters.EnableMacOSBuild }}
95 | RunTests: ${{ parameters.RunTests }}
96 | PublishCodeCoverage: ${{ parameters.PublishCodeCoverage }}
97 |
--------------------------------------------------------------------------------
/azure-pipelines/vs-insertion.yml:
--------------------------------------------------------------------------------
1 | trigger: none # We only want to trigger manually or based on resources
2 | pr: none
3 |
4 | resources:
5 | repositories:
6 | - repository: MicroBuildTemplate
7 | type: git
8 | name: 1ESPipelineTemplates/MicroBuildTemplate
9 | ref: refs/tags/release
10 | pipelines:
11 | - pipeline: CI
12 | source: Library # TODO: This should match the name of your CI pipeline
13 | tags:
14 | - Real signed
15 | trigger:
16 | tags:
17 | - Real signed
18 | - auto-insertion
19 |
20 | variables:
21 | - template: GlobalVariables.yml
22 |
23 | extends:
24 | template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate
25 | parameters:
26 | sdl:
27 | sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES
28 |
29 | stages:
30 | - stage: insertion
31 | jobs:
32 | - job: insertion
33 | displayName: VS insertion
34 | pool: VSEngSS-MicroBuild2022-1ES
35 | templateContext:
36 | outputParentDirectory: $(Pipeline.Workspace)/CI
37 | steps:
38 | - checkout: none
39 | - powershell: Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)"
40 | displayName: ⚙️ Set pipeline name
41 | - template: azure-pipelines/release-deployment-prep.yml@self
42 | - download: CI
43 | artifact: VSInsertion-Windows
44 | displayName: 🔻 Download VSInsertion-Windows artifact
45 | - ${{ if eq(variables['ContainsVsix'], 'true') }}:
46 | - task: 1ES.MicroBuildVstsDrop@1
47 | displayName: 🔺 Upload VSTS Drop
48 | inputs:
49 | dropFolder: $(Pipeline.Workspace)/CI/VSInsertion-windows/Vsix
50 | dropName: $(VstsDropNames)
51 | accessToken: $(System.AccessToken)
52 | - task: 1ES.PublishNuget@1
53 | displayName: 📦 Push VS-repo packages to VS feed
54 | inputs:
55 | packagesToPush: '$(Pipeline.Workspace)/CI/VSInsertion-Windows/*.nupkg'
56 | packageParentPath: $(Pipeline.Workspace)/CI/VSInsertion-Windows
57 | allowPackageConflicts: true
58 | publishVstsFeed: VS
59 | - task: MicroBuildInsertVsPayload@5
60 | displayName: 🏭 Insert VS Payload
61 | inputs:
62 | TeamName: $(TeamName)
63 | TeamEmail: $(TeamEmail)
64 | InsertionPayloadName: $(Build.Repository.Name) $(Build.BuildNumber)
65 | InsertionBuildPolicies: Request Perf DDRITs
66 | InsertionReviewers: $(Build.RequestedFor) # Append `,Your team name` (without quotes)
67 | AutoCompletePR: true
68 | AutoCompleteMergeStrategy: Squash
69 | ShallowClone: true
70 | - powershell: |
71 | $contentType = 'application/json';
72 | $headers = @{ Authorization = 'Bearer $(System.AccessToken)' };
73 | $rawRequest = @{ daysValid = 365 * 2; definitionId = $(resources.pipeline.CI.pipelineID); ownerId = 'User:$(Build.RequestedForId)'; protectPipeline = $false; runId = $(resources.pipeline.CI.runId) };
74 | $request = ConvertTo-Json @($rawRequest);
75 | Write-Host $request
76 | $uri = "$(System.CollectionUri)$(System.TeamProject)/_apis/build/retention/leases?api-version=6.0-preview.1";
77 | Invoke-RestMethod -uri $uri -method POST -Headers $headers -ContentType $contentType -Body $request;
78 | displayName: 🗻 Retain inserted builds
79 |
--------------------------------------------------------------------------------
/docfx/.gitignore:
--------------------------------------------------------------------------------
1 | _site/
2 | api/
3 |
--------------------------------------------------------------------------------
/docfx/docfx.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": [
3 | {
4 | "src": [
5 | {
6 | "src": "../src",
7 | "files": [
8 | "**/*.csproj"
9 | ]
10 | }
11 | ],
12 | "dest": "api"
13 | }
14 | ],
15 | "build": {
16 | "content": [
17 | {
18 | "files": [
19 | "**/*.{md,yml}"
20 | ],
21 | "exclude": [
22 | "_site/**"
23 | ]
24 | }
25 | ],
26 | "resource": [
27 | {
28 | "files": [
29 | "images/**"
30 | ]
31 | }
32 | ],
33 | "xref": [
34 | "https://learn.microsoft.com/en-us/dotnet/.xrefmap.json"
35 | ],
36 | "output": "_site",
37 | "template": [
38 | "default",
39 | "modern"
40 | ],
41 | "globalMetadata": {
42 | "_appName": "Library",
43 | "_appTitle": "Library",
44 | "_enableSearch": true,
45 | "pdf": false
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/docfx/docs/features.md:
--------------------------------------------------------------------------------
1 | # Features
2 |
3 | TODO
4 |
--------------------------------------------------------------------------------
/docfx/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | ## Installation
4 |
5 | Consume this library via its NuGet Package.
6 | Click on the badge to find its latest version and the instructions for consuming it that best apply to your project.
7 |
8 | [](https://nuget.org/packages/Library)
9 |
10 | ## Usage
11 |
12 | TODO
13 |
--------------------------------------------------------------------------------
/docfx/docs/toc.yml:
--------------------------------------------------------------------------------
1 | items:
2 | - name: Features
3 | href: features.md
4 | - name: Getting Started
5 | href: getting-started.md
6 |
--------------------------------------------------------------------------------
/docfx/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | _layout: landing
3 | ---
4 |
5 | # Overview
6 |
7 | This is your docfx landing page.
8 |
9 | Click "Docs" across the top to get started.
10 |
--------------------------------------------------------------------------------
/docfx/toc.yml:
--------------------------------------------------------------------------------
1 | items:
2 | - name: Docs
3 | href: docs/
4 | - name: API
5 | href: api/
6 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "9.0.202",
4 | "rollForward": "patch",
5 | "allowPrerelease": false
6 | },
7 | "msbuild-sdks": {
8 | "Microsoft.Build.NoTargets": "3.7.56"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/init.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | SETLOCAL
3 | set PS1UnderCmd=1
4 |
5 | :: Get the datetime in a format that can go in a filename.
6 | set _my_datetime=%date%_%time%
7 | set _my_datetime=%_my_datetime: =_%
8 | set _my_datetime=%_my_datetime::=%
9 | set _my_datetime=%_my_datetime:/=_%
10 | set _my_datetime=%_my_datetime:.=_%
11 | set CmdEnvScriptPath=%temp%\envvarscript_%_my_datetime%.cmd
12 |
13 | powershell.exe -NoProfile -NoLogo -ExecutionPolicy bypass -Command "try { & '%~dpn0.ps1' %*; exit $LASTEXITCODE } catch { write-host $_; exit 1 }"
14 |
15 | :: Set environment variables in the parent cmd.exe process.
16 | IF EXIST "%CmdEnvScriptPath%" (
17 | ENDLOCAL
18 | CALL "%CmdEnvScriptPath%"
19 | DEL "%CmdEnvScriptPath%"
20 | )
21 |
--------------------------------------------------------------------------------
/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/.editorconfig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/json-document-transforms/6b1170757c9c032fce38e46b0deaf9817dfa96b9/src/.editorconfig
--------------------------------------------------------------------------------
/src/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Runtime.InteropServices;
5 |
6 | [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]
7 |
--------------------------------------------------------------------------------
/src/AssemblyInfo.vb:
--------------------------------------------------------------------------------
1 | ' Copyright (c) Microsoft Corporation. All rights reserved.
2 | ' Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | Imports System.Runtime.InteropServices
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | README.md
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/JdtException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt
5 | {
6 | using System;
7 | using Newtonsoft.Json;
8 |
9 | ///
10 | /// The file that caused the exception.
11 | ///
12 | public enum ErrorLocation
13 | {
14 | ///
15 | /// Represents no location set.
16 | ///
17 | None,
18 |
19 | ///
20 | /// Represents the source file.
21 | ///
22 | Source,
23 |
24 | ///
25 | /// Represents the transform file.
26 | ///
27 | Transform,
28 | }
29 |
30 | ///
31 | /// Exception thrown on JDT error.
32 | ///
33 | [Serializable]
34 | public class JdtException : Exception
35 | {
36 | ///
37 | /// Initializes a new instance of the class.
38 | ///
39 | /// The exception message.
40 | public JdtException(string message)
41 | : base(message)
42 | {
43 | }
44 |
45 | ///
46 | /// Initializes a new instance of the class.
47 | ///
48 | /// The exception message.
49 | /// The file that generated the exception.
50 | public JdtException(string message, ErrorLocation location)
51 | : this(message)
52 | {
53 | this.Location = location;
54 | }
55 |
56 | ///
57 | /// Initializes a new instance of the class.
58 | ///
59 | /// The exception message.
60 | /// The file that generated the exception.
61 | /// The line that caused the error.
62 | /// The position in the lite that caused the error.
63 | public JdtException(string message, ErrorLocation location, int lineNumber, int linePosition)
64 | : this(message, location)
65 | {
66 | this.LineNumber = lineNumber;
67 | this.LinePosition = linePosition;
68 | }
69 |
70 | ///
71 | /// Gets the line number of the exception.
72 | ///
73 | public int LineNumber { get; }
74 |
75 | ///
76 | /// Gets the line position of the exception.
77 | ///
78 | public int LinePosition { get; }
79 |
80 | ///
81 | /// Gets the name of the file that generated the exception.
82 | ///
83 | public ErrorLocation Location { get; } = ErrorLocation.None;
84 |
85 | ///
86 | /// Returns a with line info.
87 | ///
88 | /// The exception message.
89 | /// The file that generated the exception.
90 | /// The line info of the object that caused the error.
91 | /// A new instance of .
92 | internal static JdtException FromLineInfo(string message, ErrorLocation location, IJsonLineInfo lineInfo)
93 | {
94 | return new JdtException(message, location, lineInfo?.LineNumber ?? 0, lineInfo?.LinePosition ?? 0);
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/JdtExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt
5 | {
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using Newtonsoft.Json.Linq;
10 |
11 | ///
12 | /// Defines extension methods used in JDT.
13 | ///
14 | internal static class JdtExtensions
15 | {
16 | ///
17 | /// Gets all the properties within the object that correspond to JDT syntax.
18 | ///
19 | /// The object to search.
20 | /// An enumerable of properties that start with the JDT prefix.
21 | internal static IEnumerable GetJdtProperties(this JObject objectToSearch)
22 | {
23 | if (objectToSearch == null)
24 | {
25 | throw new ArgumentNullException(nameof(objectToSearch));
26 | }
27 |
28 | return objectToSearch.Properties().Where(p => JdtUtilities.IsJdtSyntax(p.Name));
29 | }
30 |
31 | ///
32 | /// Checks if an exception is critical.
33 | ///
34 | /// The exception to check.
35 | /// True if the exception is critical and should not be caught.
36 | internal static bool IsCriticalException(this Exception ex)
37 | {
38 | return ex is NullReferenceException
39 | || ex is OutOfMemoryException
40 | || ex is IndexOutOfRangeException
41 | #if NET45
42 | || ex is StackOverflowException
43 | || ex is AccessViolationException
44 | || ex is System.Threading.ThreadAbortException
45 | #endif
46 | ;
47 | }
48 |
49 | ///
50 | /// Clones a preserving the line information.
51 | ///
52 | /// The object to clone.
53 | /// A clone of the object with its line info.
54 | internal static JObject CloneWithLineInfo(this JObject objectToClone)
55 | {
56 | var loadSettings = new JsonLoadSettings()
57 | {
58 | LineInfoHandling = JdtUtilities.GetLineInfoHandling(),
59 | };
60 |
61 | using (Newtonsoft.Json.JsonReader objectReader = objectToClone.CreateReader())
62 | {
63 | return JObject.Load(objectReader, loadSettings);
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/Microsoft.VisualStudio.Jdt.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | library
5 | netstandard2.0;net472
6 |
7 |
8 |
9 | Microsoft
10 | Microsoft, VisualStudioExtensibility
11 | Transform json files using a json transformation schema
12 | © Microsoft Corporation. All rights reserved.
13 | json transformation transforms file-transform jdt
14 | https://aka.ms/VsExtensibilityIcon
15 | true
16 | https://github.com/Microsoft/json-document-transforms
17 | https://github.com/Microsoft/json-document-transforms
18 | True
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | True
39 | True
40 | Resources.resx
41 |
42 |
43 |
44 |
45 |
46 | ResXFileCodeGenerator
47 | Resources.Designer.cs
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/Processors/Attributes/JdtAttributeExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt
5 | {
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 |
10 | ///
11 | /// Implements extensions for .
12 | ///
13 | internal static class JdtAttributeExtensions
14 | {
15 | ///
16 | /// Get the full name of an attribute, with the JDT prefix.
17 | ///
18 | /// The attribute.
19 | /// A string with the full name of the requested attribute.
20 | internal static string FullName(this JdtAttributes attribute)
21 | {
22 | if (attribute == JdtAttributes.None)
23 | {
24 | return JdtUtilities.JdtSyntaxPrefix;
25 | }
26 |
27 | return JdtUtilities.JdtSyntaxPrefix + Enum.GetName(typeof(JdtAttributes), attribute).ToLower();
28 | }
29 |
30 | ///
31 | /// Gets a from an enumerable based on name.
32 | ///
33 | /// The enumerable to search.
34 | /// The name of the attribute.
35 | /// The attribute with that name of if no attribute was found.
36 | internal static JdtAttributes GetByName(this IEnumerable collection, string name)
37 | {
38 | // The default value for the enum is 0, which is None
39 | return collection.SingleOrDefault(a => a.FullName().Equals(name));
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/Processors/JdtArrayProcessor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt
5 | {
6 | using System;
7 | using Newtonsoft.Json.Linq;
8 |
9 | ///
10 | /// Base for a processor that handles array values.
11 | ///
12 | internal abstract class JdtArrayProcessor : JdtProcessor
13 | {
14 | ///
15 | internal override void Process(JObject source, JObject transform, JsonTransformationContextLogger logger)
16 | {
17 | if (source == null)
18 | {
19 | throw new ArgumentNullException(nameof(source));
20 | }
21 |
22 | if (transform == null)
23 | {
24 | throw new ArgumentNullException(nameof(transform));
25 | }
26 |
27 | JToken transformValue;
28 | if (transform.TryGetValue(this.FullVerb, out transformValue))
29 | {
30 | if (!this.Transform(source, transformValue, logger))
31 | {
32 | // If the transformation returns false,
33 | // it performed an operation that halts transforms
34 | return;
35 | }
36 | }
37 |
38 | this.Successor.Process(source, transform, logger);
39 | }
40 |
41 | ///
42 | /// The core transformation logic. Arrays are treated as the transform values.
43 | ///
44 | /// Object to be transformed.
45 | /// Value of the transform.
46 | /// The transformation context logger.
47 | /// True if transforms should continue.
48 | protected abstract bool ProcessCore(JObject source, JToken transformValue, JsonTransformationContextLogger logger);
49 |
50 | ///
51 | /// Performs the initial logic of processing arrays.
52 | /// Arrays cause the transform to be applied to each value in them.
53 | ///
54 | /// Object to be transformed.
55 | /// Value of the transform.
56 | /// The transformation context logger.
57 | /// True if transforms should continue.
58 | private bool Transform(JObject source, JToken transformValue, JsonTransformationContextLogger logger)
59 | {
60 | if (transformValue.Type == JTokenType.Array)
61 | {
62 | // If the value is an array, perform the transformation for each object in the array
63 | // From here, arrays are handled as the transformation value
64 | foreach (JToken arrayValue in (JArray)transformValue)
65 | {
66 | if (!this.ProcessCore(source, arrayValue, logger))
67 | {
68 | // If the core transformation indicates a halt, we halt
69 | return true;
70 | }
71 | }
72 |
73 | // If we are not told to stop, we continue with transformations
74 | return true;
75 | }
76 | else
77 | {
78 | // If it is not an array, perform the transformation as normal
79 | return this.ProcessCore(source, transformValue, logger);
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/Processors/JdtDefault.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt
5 | {
6 | using System;
7 | using System.Linq;
8 | using Newtonsoft.Json.Linq;
9 |
10 | ///
11 | /// Represents the default JDT transformation.
12 | ///
13 | internal class JdtDefault : JdtProcessor
14 | {
15 | ///
16 | public override string Verb { get; } = null;
17 |
18 | ///
19 | internal override void Process(JObject source, JObject transform, JsonTransformationContextLogger logger)
20 | {
21 | if (source == null)
22 | {
23 | throw new ArgumentNullException(nameof(source));
24 | }
25 |
26 | if (transform == null)
27 | {
28 | throw new ArgumentNullException(nameof(transform));
29 | }
30 |
31 | // JDT Verbs are not handled here
32 | foreach (JProperty transformNode in transform.Properties()
33 | .Where(p => !JdtUtilities.IsJdtSyntax(p.Name)))
34 | {
35 | JToken nodeToTransform;
36 | if (source.TryGetValue(transformNode.Name, out nodeToTransform))
37 | {
38 | // If the node is present in both transform and source, analyze the types
39 | // If both are objects, that is a recursive transformation, not handled here
40 | if (nodeToTransform.Type == JTokenType.Array && transformNode.Value.Type == JTokenType.Array)
41 | {
42 | // If the original and transform are arrays, merge the contents together
43 | ((JArray)nodeToTransform).Merge(transformNode.Value.DeepClone());
44 | }
45 | else if (nodeToTransform.Type != JTokenType.Object || transformNode.Value.Type != JTokenType.Object)
46 | {
47 | // TO DO: Verify if object has JDT verbs. They shouldn't be allowed here because they won't be processed
48 | // If the contents are different, execute the replace
49 | source[transformNode.Name] = transformNode.Value.DeepClone();
50 | }
51 | }
52 | else
53 | {
54 | // If the node is not present in the original, add it
55 | source.Add(transformNode.DeepClone());
56 | }
57 | }
58 |
59 | this.Successor.Process(source, transform, logger);
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/Processors/JdtProcessor.ProcessorChain.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt
5 | {
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using Newtonsoft.Json.Linq;
10 |
11 | ///
12 | /// The JdtProcessor chain.
13 | ///
14 | internal abstract partial class JdtProcessor
15 | {
16 | private class JdtProcessorChain
17 | {
18 | // This is a a list of supported transformations
19 | // It is in order of execution
20 | private readonly List processors = new List()
21 | {
22 | // Supported transformations
23 | new JdtRecurse(),
24 | new JdtRemove(),
25 | new JdtReplace(),
26 | new JdtRename(),
27 | new JdtMerge(),
28 | new JdtDefault(),
29 | };
30 |
31 | public JdtProcessorChain()
32 | {
33 | var validator = new JdtValidator();
34 |
35 | // The first step of a transformation is validating the verbs
36 | this.processors.Insert(0, validator);
37 |
38 | // The successor of each transform processor should be the next one on the list
39 | // The last processor defaults to the end of chain processor
40 | List.Enumerator processorsEnumerator = this.processors.GetEnumerator();
41 | processorsEnumerator.MoveNext();
42 | foreach (JdtProcessor? successor in this.processors.Skip(1))
43 | {
44 | if (!string.IsNullOrEmpty(successor.Verb))
45 | {
46 | // If the transformation has a corresponding verb,
47 | // add it to the list of verbs to be validated
48 | validator.ValidVerbs.Add(successor.Verb);
49 | }
50 |
51 | processorsEnumerator.Current.Successor = successor;
52 | processorsEnumerator.MoveNext();
53 | }
54 | }
55 |
56 | public void Start(JObject source, JObject transform, JsonTransformationContextLogger logger)
57 | {
58 | if (source == null)
59 | {
60 | throw new ArgumentNullException(nameof(source));
61 | }
62 |
63 | if (transform == null)
64 | {
65 | throw new ArgumentNullException(nameof(transform));
66 | }
67 |
68 | this.processors.First().Process(source, transform, logger);
69 | }
70 | }
71 |
72 | ///
73 | /// Represents the end of the transformation chain.
74 | ///
75 | private class JdtEndOfChain : JdtProcessor
76 | {
77 | private JdtEndOfChain()
78 | {
79 | }
80 |
81 | public static JdtEndOfChain Instance { get; } = new JdtEndOfChain();
82 |
83 | public override string Verb { get; } = null;
84 |
85 | internal override void Process(JObject source, JObject transform, JsonTransformationContextLogger logger)
86 | {
87 | // Do nothing, the chain is done
88 | }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/Processors/JdtProcessor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt
5 | {
6 | using System;
7 | using Newtonsoft.Json.Linq;
8 |
9 | ///
10 | /// Represents a transformation.
11 | ///
12 | internal abstract partial class JdtProcessor
13 | {
14 | private static readonly JdtProcessorChain ProcessorChain = new JdtProcessorChain();
15 |
16 | private JdtProcessor successor;
17 |
18 | ///
19 | /// Gets the JDT verb corresponding to this transformation.
20 | /// Can be null or empty.
21 | /// Does not include the preffix (@jdt.)
22 | ///
23 | public abstract string Verb { get; }
24 |
25 | ///
26 | /// Gets the full verb corresponding the to the transformation.
27 | ///
28 | protected string FullVerb
29 | {
30 | get
31 | {
32 | return this.Verb == null ? null : JdtUtilities.JdtSyntaxPrefix + this.Verb;
33 | }
34 | }
35 |
36 | ///
37 | /// Gets the successor of the current transformation.
38 | ///
39 | protected JdtProcessor Successor
40 | {
41 | get
42 | {
43 | // Defaults to the end of chain processor
44 | return this.successor ?? JdtEndOfChain.Instance;
45 | }
46 |
47 | private set
48 | {
49 | this.successor = value;
50 | }
51 | }
52 |
53 | ///
54 | /// Executes the entire transformation with the given objects
55 | /// Mutates the source object.
56 | ///
57 | /// Object to be transformed.
58 | /// Object that specifies the transformation.
59 | /// The logger for the transformation.
60 | internal static void ProcessTransform(JObject source, JObject transform, JsonTransformationContextLogger logger)
61 | {
62 | if (source == null)
63 | {
64 | throw new ArgumentNullException(nameof(source));
65 | }
66 |
67 | if (transform == null)
68 | {
69 | throw new ArgumentNullException(nameof(transform));
70 | }
71 |
72 | // Passes in a clone of the transform object because it can be altered during the transformation process
73 | ProcessorChain.Start(source, (JObject)transform.CloneWithLineInfo(), logger);
74 | }
75 |
76 | ///
77 | /// Executes the transformation.
78 | ///
79 | /// Object to be transformed.
80 | /// Object specifying the transformation.
81 | /// The logger for the transformation.
82 | internal abstract void Process(JObject source, JObject transform, JsonTransformationContextLogger logger);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/Processors/JdtRecurse.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt
5 | {
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using Newtonsoft.Json.Linq;
10 |
11 | ///
12 | /// Represents a recursive JDT transformation.
13 | ///
14 | internal class JdtRecurse : JdtProcessor
15 | {
16 | ///
17 | public override string Verb { get; } = null;
18 |
19 | ///
20 | internal override void Process(JObject source, JObject transform, JsonTransformationContextLogger logger)
21 | {
22 | if (source == null)
23 | {
24 | throw new ArgumentNullException(nameof(source));
25 | }
26 |
27 | if (transform == null)
28 | {
29 | throw new ArgumentNullException(nameof(transform));
30 | }
31 |
32 | // Nodes that should be removed from the transform after they are handled
33 | var nodesToRemove = new List();
34 |
35 | foreach (JProperty transformNode in transform.Properties()
36 | .Where(p => p.Value.Type == JTokenType.Object && !JdtUtilities.IsJdtSyntax(p.Name)))
37 | {
38 | // We recurse into objects that do not correspond to JDT verbs and that exist in both source and transform
39 | JToken sourceChild;
40 | if (source.TryGetValue(transformNode.Name, out sourceChild) && sourceChild.Type == JTokenType.Object)
41 | {
42 | ProcessTransform((JObject)sourceChild, (JObject)transformNode.Value, logger);
43 |
44 | // If we have already recursed into that node, it should be removed from the transform
45 | nodesToRemove.Add(transformNode.Name);
46 | }
47 | }
48 |
49 | // Remove all of the previously handled nodes
50 | // This is necessary so that a rename does not cause a node to be hadled twice
51 | nodesToRemove.ForEach(node => transform.Remove(node));
52 |
53 | // Continue to next transformation
54 | this.Successor.Process(source, transform, logger);
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Microsoft.VisualStudio.Jdt/Processors/JdtValidator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt
5 | {
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using Newtonsoft.Json.Linq;
10 |
11 | ///
12 | /// Validates the JDT verbs in the transformation.
13 | ///
14 | internal class JdtValidator : JdtProcessor
15 | {
16 | ///
17 | /// Gets set of the valid verbs for the transformation.
18 | ///
19 | public HashSet ValidVerbs { get; } = new HashSet();
20 |
21 | ///
22 | public override string Verb { get; } = null;
23 |
24 | ///
25 | internal override void Process(JObject source, JObject transform, JsonTransformationContextLogger logger)
26 | {
27 | if (source == null)
28 | {
29 | throw new ArgumentNullException(nameof(source));
30 | }
31 |
32 | if (transform == null)
33 | {
34 | throw new ArgumentNullException(nameof(transform));
35 | }
36 |
37 | foreach (JProperty transformNode in transform.Properties()
38 | .Where(p => JdtUtilities.IsJdtSyntax(p.Name)))
39 | {
40 | string verb = JdtUtilities.GetJdtSyntax(transformNode.Name);
41 | if (verb != null)
42 | {
43 | if (!this.ValidVerbs.Contains(verb))
44 | {
45 | throw JdtException.FromLineInfo(string.Format(Resources.ErrorMessage_InvalidVerb, verb), ErrorLocation.Transform, transformNode);
46 | }
47 | }
48 | }
49 |
50 | this.Successor.Process(source, transform, logger);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/OptProf.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | IBC
5 | Common7\IDE\PrivateAssemblies\$(TargetFileName)
6 | /ExeConfig:"%VisualStudio.InstallationUnderTest.Path%\Common7\IDE\vsn.exe"
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/VSInsertionMetadata/Library.VSInsertionMetadata.proj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 | true
5 | $(RepoRootPath)bin\Packages\$(Configuration)\VSRepo\
6 | false
7 | false
8 | Contains metadata for insertion into VS.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/VSInsertionMetadata/ProfilingInputs.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/VSInsertionMetadata/VSInsertionMetadata.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | $(TargetsForTfmSpecificContentInPackage);
27 | SubstituteProfilingInputsMacro;
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
43 |
44 |
47 |
49 |
50 |
51 |
52 |
53 |
54 |
57 |
64 |
65 | $(PackageVersion).$(Build_BuildId)
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/jdt.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.13.35505.181
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.VisualStudio.Jdt", "Microsoft.VisualStudio.Jdt\Microsoft.VisualStudio.Jdt.csproj", "{E4517B62-6E49-47A9-93A3-889B2E0A92B5}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{386BAD62-57B8-4AEB-AEE5-D122A8330656}"
9 | ProjectSection(SolutionItems) = preProject
10 | Directory.Build.props = Directory.Build.props
11 | Directory.Build.targets = Directory.Build.targets
12 | ..\Directory.Packages.props = ..\Directory.Packages.props
13 | stylecop.json = stylecop.json
14 | version.json = version.json
15 | EndProjectSection
16 | EndProject
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.VisualStudio.Jdt.Tests", "..\test\Microsoft.VisualStudio.Jdt.Tests\Microsoft.VisualStudio.Jdt.Tests.csproj", "{DC4029BB-86FD-AC0B-8024-03ECD0301F86}"
18 | EndProject
19 | Global
20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 | Debug|Any CPU = Debug|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {E4517B62-6E49-47A9-93A3-889B2E0A92B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {E4517B62-6E49-47A9-93A3-889B2E0A92B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {E4517B62-6E49-47A9-93A3-889B2E0A92B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {E4517B62-6E49-47A9-93A3-889B2E0A92B5}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {DC4029BB-86FD-AC0B-8024-03ECD0301F86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {DC4029BB-86FD-AC0B-8024-03ECD0301F86}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {DC4029BB-86FD-AC0B-8024-03ECD0301F86}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {DC4029BB-86FD-AC0B-8024-03ECD0301F86}.Release|Any CPU.Build.0 = Release|Any CPU
33 | EndGlobalSection
34 | GlobalSection(SolutionProperties) = preSolution
35 | HideSolutionNode = FALSE
36 | EndGlobalSection
37 | GlobalSection(ExtensibilityGlobals) = postSolution
38 | SolutionGuid = {F194D4D1-A28A-4C19-941E-BF828EA6DD8C}
39 | EndGlobalSection
40 | EndGlobal
41 |
--------------------------------------------------------------------------------
/src/stylecop.json:
--------------------------------------------------------------------------------
1 | {
2 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
3 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
4 | "settings": {
5 | "documentationRules": {
6 | "companyName": "Microsoft Corporation",
7 | "copyrightText": "Copyright (c) {companyName}. All rights reserved.\nLicensed under the {licenseName} license. See {licenseFile} file in the project root for full license information.",
8 | "variables": {
9 | "licenseName": "MIT",
10 | "licenseFile": "LICENSE"
11 | },
12 | "xmlHeader": false
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3 | "version": "0.9",
4 | "publicReleaseRefSpec": [
5 | "^refs/heads/main$" // we release out of main
6 | ],
7 | "cloudBuild": {
8 | "buildNumber": {
9 | "enabled": true
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 |
3 | # SA1600: Elements should be documented
4 | dotnet_diagnostic.SA1600.severity = silent
5 |
6 | # SA1601: Partial elements should be documented
7 | dotnet_diagnostic.SA1601.severity = silent
8 |
9 | # SA1602: Enumeration items should be documented
10 | dotnet_diagnostic.SA1602.severity = silent
11 |
12 | # SA1615: Element return value should be documented
13 | dotnet_diagnostic.SA1615.severity = silent
14 |
15 | # VSTHRD103: Call async methods when in an async method
16 | dotnet_diagnostic.VSTHRD103.severity = silent
17 |
18 | # VSTHRD111: Use .ConfigureAwait(bool)
19 | dotnet_diagnostic.VSTHRD111.severity = none
20 |
21 | # VSTHRD200: Use Async suffix for async methods
22 | dotnet_diagnostic.VSTHRD200.severity = silent
23 |
24 | # CA1014: Mark assemblies with CLSCompliant
25 | dotnet_diagnostic.CA1014.severity = none
26 |
27 | # CA1050: Declare types in namespaces
28 | dotnet_diagnostic.CA1050.severity = none
29 |
30 | # CA1303: Do not pass literals as localized parameters
31 | dotnet_diagnostic.CA1303.severity = none
32 |
33 | # CS1591: Missing XML comment for publicly visible type or member
34 | dotnet_diagnostic.CS1591.severity = silent
35 |
36 | # CA1707: Identifiers should not contain underscores
37 | dotnet_diagnostic.CA1707.severity = silent
38 |
39 | # CA1062: Validate arguments of public methods
40 | dotnet_diagnostic.CA1062.severity = suggestion
41 |
42 | # CA1063: Implement IDisposable Correctly
43 | dotnet_diagnostic.CA1063.severity = silent
44 |
45 | # CA1816: Dispose methods should call SuppressFinalize
46 | dotnet_diagnostic.CA1816.severity = silent
47 |
48 | # CA2007: Consider calling ConfigureAwait on the awaited task
49 | dotnet_diagnostic.CA2007.severity = none
50 |
51 | # SA1401: Fields should be private
52 | dotnet_diagnostic.SA1401.severity = silent
53 |
54 | # SA1133: Do not combine attributes
55 | dotnet_diagnostic.SA1133.severity = silent
56 |
--------------------------------------------------------------------------------
/test/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/test/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Array.Merge.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Added": true }
4 | ],
5 | "B": [
6 | {
7 | "Name": "B1",
8 | "Value": 1
9 | },
10 | {
11 | "Name": "B2",
12 | "Value": 2
13 | },
14 | {
15 | "Name": "B2",
16 | "Value": 3
17 | }
18 | ],
19 | "C": [
20 | {},
21 | { "Empty": false },
22 | { "Array": [ { "Inception": true } ] },
23 | { "Empty": false }
24 | ],
25 | "D": {
26 | "D1": [
27 | { "Value": 1 },
28 | { "Value": 0 }
29 | ]
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Array.Merge.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Added": true }
4 | ],
5 | "B": [
6 | {
7 | "Name": "B2",
8 | "Value": 2
9 | },
10 | {
11 | "Name": "B2",
12 | "Value": 3
13 | }
14 | ],
15 | "C": [
16 | { "Empty": false }
17 | ],
18 | "D": {
19 | "D1": [ { "Value": 0 } ]
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Array.Replace.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "Replaced": true
4 | },
5 | "B": [
6 | {
7 | "Name": "B1",
8 | "Value": 1
9 | }
10 | ],
11 | "C": "Replaced",
12 | "D": {
13 | "D1": null
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Array.Replace.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "Replaced": true
4 | },
5 | "C": "Replaced",
6 | "D": {
7 | "D1": null
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Array.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [],
3 | "B": [
4 | {
5 | "Name": "B1",
6 | "Value": 1
7 | }
8 | ],
9 | "C": [
10 | {},
11 | { "Empty": false },
12 | { "Array": [ { "Inception": true } ] }
13 | ],
14 | "D": {
15 | "D1": [ { "Value": 1 } ]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Object.Merge.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "A1": "New"
4 | },
5 | "B": {
6 | "B1": 10,
7 | "B2": 2,
8 | "B3": 30
9 | },
10 | "C": {
11 | "C1": {
12 | "C11": true,
13 | "C12": false,
14 | "C13": [
15 | { "Name": "C131" },
16 | { "Name": "C132" }
17 | ]
18 | },
19 | "C2": 2,
20 | "C3": {
21 | "Added": true
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Object.Merge.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "A1": "New"
4 | },
5 | "B": {
6 | "B1": 10,
7 | "B3": 30
8 | },
9 | "C": {
10 | "C1": {
11 | "C12": false,
12 | "C13": [
13 | { "Name": "C131" },
14 | { "Name": "C132" }
15 | ]
16 | },
17 | "C3": {
18 | "Added": true
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Object.Replace.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": null,
3 | "B": "Replaced",
4 | "C": {
5 | "C1": [ { "C11": true } ],
6 | "C2": 2
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Object.Replace.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": null,
3 | "B": "Replaced",
4 | "C": {
5 | "C1": [ {"C11": true} ]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Object.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | },
4 | "B": {
5 | "B1": 1,
6 | "B2": 2
7 | },
8 | "C": {
9 | "C1": {
10 | "C11": true
11 | },
12 | "C2": 2
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Primitive.AddArray.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": true,
4 | "C": null,
5 | "D": "4",
6 | "E": [
7 | {
8 | "String": "string",
9 | "Primitive": null
10 | },
11 | { "Object": { "Value": 10 } },
12 | { "Array": [ { "Inception": true } ] },
13 | {}
14 | ],
15 | "F": [
16 | { "Repeat": true },
17 | { "Repeat": true }
18 | ],
19 | "G": []
20 | }
21 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Primitive.AddArray.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "E": [
3 | {
4 | "String": "string",
5 | "Primitive": null
6 | },
7 | { "Object": { "Value": 10 } },
8 | { "Array": [ {"Inception": true} ] },
9 | {}
10 | ],
11 | "F": [
12 | { "Repeat": true },
13 | { "Repeat": true }
14 | ],
15 | "G": []
16 | }
17 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Primitive.AddObject.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": true,
4 | "C": null,
5 | "D": "4",
6 | "E": {
7 | },
8 | "F": {
9 | "F1": 1,
10 | "F2": true,
11 | "F3": "F3"
12 | },
13 | "G": {
14 | "G1": {
15 | },
16 | "G2": null,
17 | "G3": {
18 | "G31": 10,
19 | "G32": null
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Primitive.AddObject.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "E": {
3 | },
4 | "F": {
5 | "F1": 1,
6 | "F2": true,
7 | "F3": "F3"
8 | },
9 | "G": {
10 | "G1": {
11 | },
12 | "G2": null,
13 | "G3": {
14 | "G31": 10,
15 | "G32": null
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Primitive.AddPrimitive.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": true,
4 | "C": null,
5 | "D": "4",
6 | "E": true,
7 | "F": 6,
8 | "G": null,
9 | "H": "8"
10 | }
11 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Primitive.AddPrimitive.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "E": true,
3 | "F": 6,
4 | "G": null,
5 | "H": "8"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Primitive.Replace.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 10,
3 | "B": null,
4 | "C": "Replaced",
5 | "D": "4"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Primitive.Replace.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 10,
3 | "B": null,
4 | "C": "Replaced"
5 | }
6 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Default/Primitive.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": true,
4 | "C": null,
5 | "D": "4"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Object.MergeObjects.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": {
4 | "B1": 1,
5 | "B2": 20,
6 | "B3": 3
7 | },
8 | "C": {
9 | "C1": {
10 | "C11": 1,
11 | "C12": 2
12 | },
13 | "C2": null
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Object.MergeObjects.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "@jdt.merge": 1
4 | },
5 | "B": {
6 | "@jdt.merge": {
7 | "B2": 20,
8 | "B3": 3
9 | }
10 | },
11 | "C": {
12 | "@jdt.merge": {
13 | "C1": {
14 | "C12": 2,
15 | "C11": 1
16 | },
17 | "C2": null
18 | },
19 | "C1": {
20 | "@jdt.merge": {
21 | "C12": false
22 | },
23 | "C11": true
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Object.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {},
3 | "B": {
4 | "B1": 1,
5 | "B2": 2
6 | },
7 | "C": {
8 | "C1": {
9 | "C11": true
10 | },
11 | "C2": 2
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Object.UsingDirectPath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {},
3 | "B": {
4 | "B1": 1,
5 | "B2": {
6 | "B21": 1,
7 | "B22": 2
8 | }
9 | },
10 | "C": {
11 | "C1": {
12 | "C11": 1,
13 | "C12": 2
14 | },
15 | "C2": 2
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Object.UsingDirectPath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.merge": {
3 | "@jdt.path": "$.B.B2",
4 | "@jdt.value": {
5 | "B21": 1,
6 | "B22": 2
7 | }
8 | },
9 | "C": {
10 | "@jdt.merge": {
11 | "@jdt.path": "$.C1",
12 | "@jdt.value": {
13 | "C11": 1,
14 | "C12": 2
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Primitive.MergeObjects.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "A1": 1
4 | },
5 | "B": true,
6 | "C": {},
7 | "D": "4",
8 | "E": {
9 | "Added": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Primitive.MergeObjects.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.merge": {
3 | "A": {
4 | "A1": 1
5 | },
6 | "C": {},
7 | "E": {
8 | "Added": true
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Primitive.MergePrimitives.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": false,
4 | "C": null,
5 | "D": "4",
6 | "E": "new",
7 | "F": 10
8 | }
9 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Primitive.MergePrimitives.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.merge": {
3 | "B": false,
4 | "E": "new",
5 | "F": 10
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Primitive.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": true,
4 | "C": null,
5 | "D": "4"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Primitive.UsingSimplePath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": "One",
3 | "B": true,
4 | "C": null,
5 | "D": "4"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Merge/Primitive.UsingSimplePath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.merge": {
3 | "@jdt.path": "$.A",
4 | "@jdt.value": "One"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Array.DirectPath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Index": 1 },
4 | { "Index": 3 }
5 | ],
6 | "B": [
7 | { "Remove": true },
8 | { "Remove": false },
9 | { "Remove": "WrongValue" },
10 | { "HasRemove": false },
11 | { "Remove": true }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Array.DirectPath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.remove": {
3 | "@jdt.path": "$.A[1]"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Array.ScriptPath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Index": 1 },
4 | { "Index": 2 },
5 | { "Index": 3 }
6 | ],
7 | "B": [
8 | { "Remove": false },
9 | { "Remove": "WrongValue" },
10 | { "HasRemove": false }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Array.ScriptPath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.remove": {
3 | "@jdt.path": "$.B[?(@.Remove == true)]"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Array.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Index": 1 },
4 | { "Index": 2 },
5 | { "Index": 3 }
6 | ],
7 | "B": [
8 | { "Remove": true },
9 | { "Remove": false },
10 | { "Remove": "WrongValue" },
11 | { "HasRemove": false },
12 | { "Remove": true }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Object.DirectPath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | },
4 | "B": {
5 | "B1": 1
6 | },
7 | "C": {
8 | "C2": 2
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Object.DirectPath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.remove": {
3 | "@jdt.path": "$.B.B2"
4 | },
5 | "C": {
6 | "@jdt.remove": {
7 | "@jdt.path": "$.C1"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Object.InObject.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "B": {
3 | "B2": 2
4 | },
5 | "C": {
6 | "C2": 2
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Object.InObject.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.remove": "A",
3 | "B": {
4 | "@jdt.remove": "B1"
5 | },
6 | "C": {
7 | "@jdt.remove": "C1",
8 | "C1": {
9 | "@jdt.remove": "C11"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Object.PathToItself.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": null,
3 | "B": {
4 | "B1": 1,
5 | "B2": 2
6 | },
7 | "C": {
8 | "C1": {
9 | "C11": true
10 | },
11 | "C2": 2
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Object.PathToItself.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "@jdt.remove": {
4 | "@jdt.path": "$"
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Object.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | },
4 | "B": {
5 | "B1": 1,
6 | "B2": 2
7 | },
8 | "C": {
9 | "C1": {
10 | "C11": true
11 | },
12 | "C2": 2
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Object.WithBool.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": null,
3 | "B": {
4 | "B1": 1,
5 | "B2": 2
6 | },
7 | "C": {
8 | "C1": null,
9 | "C2": 2
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Object.WithBool.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "@jdt.remove": true
4 | },
5 | "B": {
6 | "@jdt.remove": false
7 | },
8 | "C": {
9 | "C1": {
10 | "@jdt.remove": true,
11 | "C12": 3
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Primitive.FromRoot.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "B": true,
3 | "C": null,
4 | "D": "4"
5 | }
6 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Primitive.FromRoot.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.remove": "A"
3 | }
4 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Primitive.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": true,
4 | "C": null,
5 | "D": "4"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Primitive.UsingPathArray.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "C": null
4 | }
5 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Primitive.UsingPathArray.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.remove": [
3 | {
4 | "@jdt.path": "$.D"
5 | },
6 | {
7 | "@jdt.path": "B"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Primitive.UsingSimpleArray.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "C": null,
3 | "D": "4"
4 | }
5 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Primitive.UsingSimpleArray.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.remove": ["A", "B"]
3 | }
4 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Primitive.UsingSimplePath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": true,
4 | "D": "4"
5 | }
6 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Primitive.UsingSimplePath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.remove": {
3 | "@jdt.path": "C"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Skipped/Object.ScriptPath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | },
4 | "C": {
5 | "C1": {
6 | "C11": true
7 | },
8 | "C2": 2
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Remove/Skipped/Object.ScriptPath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.remove": {
3 | "@jdt.path": "$[?(@.B1)]"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Array.DirectPath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Ind": 1 },
4 | { "Index": 2 },
5 | { "Ind": 3 }
6 | ],
7 | "B": [
8 | { "Rename": true, "ToChange": 1 },
9 | { "Rename": false, "ToChange": 1 },
10 | { "Rename": "WrongValue", "ToChange": 1 },
11 | { "HasRename": false, "ToChange": 1 },
12 | { "Rename": true, "ToChange": 1 }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Array.DirectPath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.rename": {
3 | "@jdt.path": "$.A[0,2].Index",
4 | "@jdt.value": "Ind"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Array.ScriptPath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Index": 1 },
4 | { "Index": 2 },
5 | { "Index": 3 }
6 | ],
7 | "B": [
8 | { "Rename": true, "Changed": 1 },
9 | { "Rename": false, "ToChange": 2 },
10 | { "Rename": "WrongValue", "ToChange": 3 },
11 | { "HasRename": false, "ToChange": 4 },
12 | { "Rename": true, "Changed": 5 }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Array.ScriptPath.Transform .json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.rename": {
3 | "@jdt.path": "$.B[?(@.Rename == true)].ToChange",
4 | "@jdt.value": "Changed"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Array.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Index": 1 },
4 | { "Index": 2 },
5 | { "Index": 3 }
6 | ],
7 | "B": [
8 | { "Rename": true, "ToChange": 1 },
9 | { "Rename": false, "ToChange": 1 },
10 | { "Rename": "WrongValue", "ToChange": 1 },
11 | { "HasRename": false, "ToChange": 1 },
12 | { "Rename": true, "ToChange": 1 }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Object.InObject.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | },
4 | "Bee": {
5 | "B1": 1,
6 | "B2": 2
7 | },
8 | "Cstar": {
9 | "C01": {
10 | "C11": true
11 | },
12 | "C02": 2
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Object.InObject.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.rename": {
3 | "C": "Cstar",
4 | "B": "Bee"
5 | },
6 |
7 | "C": {
8 | "@jdt.rename": {
9 | "C1": "C01",
10 | "C2": "C02"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Object.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | },
4 | "B": {
5 | "B1": 1,
6 | "B2": 2
7 | },
8 | "C": {
9 | "C1": {
10 | "C11": true
11 | },
12 | "C2": 2
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Object.UsingSimplePath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | },
4 | "B": {
5 | "B1": 1,
6 | "B2": 2
7 | },
8 | "C": {
9 | "C01": {
10 | "C11": true
11 | },
12 | "C2": 2
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Object.UsingSimplePath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.rename": {
3 | "@jdt.path": "$.C.C1",
4 | "@jdt.value": "C01"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Object.WithChangingNames.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | },
4 | "B": {
5 | "B1": 1,
6 | "B2": 2
7 | },
8 | "C": {
9 | "C01": {
10 | "Cee11": true
11 | },
12 | "C2": 2
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Object.WithChangingNames.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.rename": {
3 | "@jdt.path": "$.C.C1",
4 | "@jdt.value": "C01"
5 | },
6 | "C": {
7 | "@jdt.rename": {
8 | "@jdt.path": "$.C1.C11",
9 | "@jdt.value": "Cee11"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Primitive.FromRoot.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "Astar": 1,
3 | "B": true,
4 | "NewC": null,
5 | "D": "4"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Primitive.FromRoot.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.rename": {
3 | "A": "Astar",
4 | "C": "NewC"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Primitive.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": true,
4 | "C": null,
5 | "D": "4"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Primitive.UsingSimpleArray.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "Astar": 1,
3 | "B": true,
4 | "C": null,
5 | "Dee": "4"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Primitive.UsingSimpleArray.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.rename": [
3 | {
4 | "A": "Astar"
5 | },
6 | {
7 | "D" : "Dee"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Primitive.UsingSimplePath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "Eh": 1,
3 | "B": true,
4 | "C": null,
5 | "D": "4"
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Rename/Primitive.UsingSimplePath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.rename": {
3 | "@jdt.path": "$.A",
4 | "@jdt.value": "Eh"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Array.DirectPath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | 1,
4 | { "Index": 2 },
5 | { "StringIndex": "03", "Replaced" : true }
6 | ],
7 | "B": [
8 | { "Replace": true },
9 | { "Replace": false },
10 | { "Replace": "WrongValue" },
11 | { "HasReplace": true },
12 | { "Replace": true }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Array.DirectPath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.replace": [
3 | {
4 | "@jdt.path": "$.A[0]",
5 | "@jdt.value": 1
6 | },
7 | {
8 | "@jdt.path": "$.A[2]",
9 | "@jdt.value": {
10 | "StringIndex": "03",
11 | "Replaced" : true
12 | }
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Array.ScriptPath.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Index": 1 },
4 | { "Index": 2 },
5 | { "Index": 3 }
6 | ],
7 | "B": [
8 | { "Replaced": "Yes" },
9 | { "Replace": false },
10 | { "Replace": "WrongValue" },
11 | { "HasReplace": true },
12 | { "Replaced": "Yes" }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Array.ScriptPath.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "@jdt.replace": {
3 | "@jdt.path": "$.B[?(@.Replace == true)]",
4 | "@jdt.value": {"Replaced": "Yes"}
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Array.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": [
3 | { "Index": 1 },
4 | { "Index": 2 },
5 | { "Index": 3 }
6 | ],
7 | "B": [
8 | { "Replace": true },
9 | { "Replace": false },
10 | { "Replace": "WrongValue" },
11 | { "HasReplace": true },
12 | { "Replace": true }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Object.Source.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | },
4 | "B": {
5 | "B1": 1,
6 | "B2": 2
7 | },
8 | "C": {
9 | "C1": {
10 | "C11": true
11 | },
12 | "C2": 2
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Object.WithArray.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": 1,
3 | "B": {
4 | "B1": 1,
5 | "B2": 2
6 | },
7 | "C": [
8 | { "C1": { "C11": 1 } },
9 | { "C2": 2 }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Object.WithArray.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "@jdt.replace": [
4 | 1,
5 | "Skipped"
6 | ]
7 | },
8 | "C": {
9 | "@jdt.replace": [
10 | [
11 | { "C1": { "C11": 1 } },
12 | { "C2": 2 }
13 | ]
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Object.WithObject.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "A1": 1,
4 | "A2": 2
5 | },
6 | "B": {
7 | "1B": 10,
8 | "2B": 22
9 | },
10 | "C": {
11 | "C1": {
12 | "Value": 1
13 | },
14 | "C2": 2
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Object.WithObject.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "@jdt.replace": {
4 | "A1": 1,
5 | "A2": 2
6 | }
7 | },
8 | "B": {
9 | "@jdt.replace": {
10 | "1B": 10,
11 | "2B": 22
12 | }
13 | },
14 | "C": {
15 | "C1": {
16 | "@jdt.replace": {
17 | "Value": 1
18 | }
19 | },
20 | "C2": 2
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Object.WithPrimitive.Expected.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": true,
3 | "B": 20,
4 | "C": {
5 | "C1": 1,
6 | "C2": 2
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Inputs/Replace/Object.WithPrimitive.Transform.json:
--------------------------------------------------------------------------------
1 | {
2 | "A": {
3 | "@jdt.replace": true
4 | },
5 | "B": {
6 | "@jdt.replace": 20
7 | },
8 | "C": {
9 | "C1": {
10 | "@jdt.replace": 1,
11 | "C11": "Skipped"
12 | },
13 | "C2": 2
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/JdtUtilitiesTest.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt.Tests
5 | {
6 | using Microsoft.VisualStudio.Jdt;
7 | using Xunit;
8 |
9 | ///
10 | /// Test class for .
11 | ///
12 | public class JdtUtilitiesTest
13 | {
14 | ///
15 | /// Tests with invalid JSON syntax.
16 | ///
17 | /// Key to test.
18 | [Theory]
19 | [InlineData(null)]
20 | [InlineData("")]
21 | [InlineData("string")]
22 | [InlineData("jdt.Verb")]
23 | [InlineData("@jdtverb")]
24 | [InlineData("@jdt")]
25 | [InlineData("@JDT.WrongCase")]
26 | public void IsJdtSyntaxInvalid(string key)
27 | {
28 | Assert.False(JdtUtilities.IsJdtSyntax(key));
29 | }
30 |
31 | ///
32 | /// Tests with valid JSON syntax.
33 | ///
34 | /// Key to test.
35 | [Theory]
36 | [InlineData("@jdt.NotAVerb")]
37 | [InlineData("@jdt.Remove")]
38 | [InlineData("@jdt.merge")]
39 | [InlineData("@jdt.")]
40 | [InlineData("@jdt. ")]
41 | public void IsJdtSyntaxValid(string key)
42 | {
43 | Assert.True(JdtUtilities.IsJdtSyntax(key));
44 | }
45 |
46 | ///
47 | /// Tests with invalid JSON syntax.
48 | ///
49 | /// Key to test.
50 | [Theory]
51 | [InlineData(null)]
52 | [InlineData("")]
53 | [InlineData("string")]
54 | [InlineData("jdt.Verb")]
55 | [InlineData("@jdtverb")]
56 | [InlineData("@jdt")]
57 | [InlineData("@JDT.WrongCase")]
58 | public void GetInvalidJdtSyntax(string key)
59 | {
60 | Assert.Null(JdtUtilities.GetJdtSyntax(key));
61 | }
62 |
63 | ///
64 | /// Tests with valid JSON syntax.
65 | ///
66 | [Fact]
67 | public void GetValidJdtSyntax()
68 | {
69 | Assert.Equal(JdtUtilities.GetJdtSyntax("@jdt."), string.Empty);
70 | Assert.Equal(" ", JdtUtilities.GetJdtSyntax("@jdt. "));
71 | Assert.Equal("verb", JdtUtilities.GetJdtSyntax("@jdt.verb"));
72 | Assert.Equal("NotAVerb", JdtUtilities.GetJdtSyntax("@jdt.NotAVerb"));
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/Microsoft.VisualStudio.Jdt.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net472;net5.0
5 | false
6 | $(NoWarn);CS1591
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | all
20 | runtime; build; native; contentfiles; analyzers; buildtransitive
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/ReadOnlyTempFile.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.VisualStudio.Jdt.Tests
5 | {
6 | using System;
7 | using System.IO;
8 |
9 | ///
10 | /// Read-Only Temp File.
11 | ///
12 | ///
13 | internal class ReadOnlyTempFile : IDisposable
14 | {
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | /// The contents.
19 | public ReadOnlyTempFile(string contents)
20 | {
21 | // create temp file
22 | this.FilePath = Path.GetTempFileName();
23 |
24 | // write contents
25 | File.WriteAllText(this.FilePath, contents);
26 |
27 | // set the file as read-only
28 | File.SetAttributes(this.FilePath, FileAttributes.ReadOnly);
29 | }
30 |
31 | ///
32 | /// Gets the file path.
33 | ///
34 | /// The file path.
35 | public string FilePath { get; private set; }
36 |
37 | ///
38 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
39 | ///
40 | public void Dispose()
41 | {
42 | // delete file
43 | if ((this.FilePath == null) || !File.Exists(this.FilePath))
44 | {
45 | // nothing to delete
46 | return;
47 | }
48 |
49 | // remove read-only attribute if it exists
50 | FileAttributes attributes = File.GetAttributes(this.FilePath);
51 | if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
52 | {
53 | // read-only attribute exists
54 | // remove read-only attribute
55 | File.SetAttributes(this.FilePath, attributes ^ FileAttributes.ReadOnly);
56 | }
57 |
58 | // delete the file
59 | File.Delete(this.FilePath);
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/test/Microsoft.VisualStudio.Jdt.Tests/xunit.runner.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
3 | "shadowCopy": false
4 | }
5 |
--------------------------------------------------------------------------------
/tools/Check-DotNetRuntime.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Checks whether a given .NET Core runtime is installed.
4 | #>
5 | [CmdletBinding()]
6 | Param (
7 | [Parameter()]
8 | [ValidateSet('Microsoft.AspNetCore.App','Microsoft.NETCore.App')]
9 | [string]$Runtime='Microsoft.NETCore.App',
10 | [Parameter(Mandatory=$true)]
11 | [Version]$Version
12 | )
13 |
14 | $dotnet = Get-Command dotnet -ErrorAction SilentlyContinue
15 | if (!$dotnet) {
16 | # Nothing is installed.
17 | Write-Output $false
18 | exit 1
19 | }
20 |
21 | Function IsVersionMatch {
22 | Param(
23 | [Parameter()]
24 | $actualVersion
25 | )
26 | return $actualVersion -and
27 | $Version.Major -eq $actualVersion.Major -and
28 | $Version.Minor -eq $actualVersion.Minor -and
29 | (($Version.Build -eq -1) -or ($Version.Build -eq $actualVersion.Build)) -and
30 | (($Version.Revision -eq -1) -or ($Version.Revision -eq $actualVersion.Revision))
31 | }
32 |
33 | $installedRuntimes = dotnet --list-runtimes |? { $_.Split()[0] -ieq $Runtime } |% { $v = $null; [Version]::tryparse($_.Split()[1], [ref] $v); $v }
34 | $matchingRuntimes = $installedRuntimes |? { IsVersionMatch -actualVersion $_ }
35 | if (!$matchingRuntimes) {
36 | Write-Output $false
37 | exit 1
38 | }
39 |
40 | Write-Output $true
41 | exit 0
42 |
--------------------------------------------------------------------------------
/tools/Check-DotNetSdk.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Checks whether the .NET Core SDK required by this repo is installed.
4 | #>
5 | [CmdletBinding()]
6 | Param (
7 | )
8 |
9 | $dotnet = Get-Command dotnet -ErrorAction SilentlyContinue
10 | if (!$dotnet) {
11 | # Nothing is installed.
12 | Write-Output $false
13 | exit 1
14 | }
15 |
16 | # We need to set the current directory so dotnet considers the SDK required by our global.json file.
17 | Push-Location "$PSScriptRoot\.."
18 | try {
19 | dotnet -h 2>&1 | Out-Null
20 | if (($LASTEXITCODE -eq 129) -or # On Linux
21 | ($LASTEXITCODE -eq -2147450751) # On Windows
22 | ) {
23 | # These exit codes indicate no matching SDK exists.
24 | Write-Output $false
25 | exit 2
26 | }
27 |
28 | # The required SDK is already installed!
29 | Write-Output $true
30 | exit 0
31 | } catch {
32 | # I don't know why, but on some build agents (e.g. MicroBuild), an exception is thrown from the `dotnet` invocation when a match is not found.
33 | Write-Output $false
34 | exit 3
35 | } finally {
36 | Pop-Location
37 | }
38 |
--------------------------------------------------------------------------------
/tools/Convert-PDB.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Converts between Windows PDB and Portable PDB formats.
4 | .PARAMETER DllPath
5 | The path to the DLL whose PDB is to be converted.
6 | .PARAMETER PdbPath
7 | The path to the PDB to convert. May be omitted if the DLL was compiled on this machine and the PDB is still at its original path.
8 | .PARAMETER OutputPath
9 | The path of the output PDB to write.
10 | #>
11 | [CmdletBinding()]
12 | Param(
13 | [Parameter(Mandatory=$true,Position=0)]
14 | [string]$DllPath,
15 | [Parameter()]
16 | [string]$PdbPath,
17 | [Parameter(Mandatory=$true,Position=1)]
18 | [string]$OutputPath
19 | )
20 |
21 | if ($IsMacOS -or $IsLinux) {
22 | Write-Error "This script only works on Windows"
23 | return
24 | }
25 |
26 | $version = '1.1.0-beta2-21101-01'
27 | $baseDir = "$PSScriptRoot/../obj/tools"
28 | $pdb2pdbpath = "$baseDir/Microsoft.DiaSymReader.Pdb2Pdb.$version/tools/Pdb2Pdb.exe"
29 | if (-not (Test-Path $pdb2pdbpath)) {
30 | if (-not (Test-Path $baseDir)) { New-Item -Type Directory -Path $baseDir | Out-Null }
31 | $baseDir = (Resolve-Path $baseDir).Path # Normalize it
32 | Write-Verbose "& (& $PSScriptRoot/Get-NuGetTool.ps1) install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json | Out-Null"
33 | & (& $PSScriptRoot/Get-NuGetTool.ps1) install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json | Out-Null
34 | }
35 |
36 | $args = $DllPath,'/out',$OutputPath,'/nowarn','0021'
37 | if ($PdbPath) {
38 | $args += '/pdb',$PdbPath
39 | }
40 |
41 | Write-Verbose "$pdb2pdbpath $args"
42 | & $pdb2pdbpath $args
43 |
--------------------------------------------------------------------------------
/tools/Get-ArtifactsStagingDirectory.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [switch]$CleanIfLocal
3 | )
4 | if ($env:BUILD_ARTIFACTSTAGINGDIRECTORY) {
5 | $ArtifactStagingFolder = $env:BUILD_ARTIFACTSTAGINGDIRECTORY
6 | } elseif ($env:RUNNER_TEMP) {
7 | $ArtifactStagingFolder = Join-Path $env:RUNNER_TEMP _artifacts
8 | } else {
9 | $ArtifactStagingFolder = [System.IO.Path]::GetFullPath("$PSScriptRoot/../obj/_artifacts")
10 | if ($CleanIfLocal -and (Test-Path $ArtifactStagingFolder)) {
11 | Remove-Item $ArtifactStagingFolder -Recurse -Force
12 | }
13 | }
14 |
15 | $ArtifactStagingFolder
16 |
--------------------------------------------------------------------------------
/tools/Get-CodeCovTool.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Downloads the CodeCov.io uploader tool and returns the path to it.
4 | .PARAMETER AllowSkipVerify
5 | Allows skipping signature verification of the downloaded tool if gpg is not installed.
6 | #>
7 | [CmdletBinding()]
8 | Param(
9 | [switch]$AllowSkipVerify
10 | )
11 |
12 | if ($IsMacOS) {
13 | $codeCovUrl = "https://uploader.codecov.io/latest/macos/codecov"
14 | $toolName = 'codecov'
15 | }
16 | elseif ($IsLinux) {
17 | $codeCovUrl = "https://uploader.codecov.io/latest/linux/codecov"
18 | $toolName = 'codecov'
19 | }
20 | else {
21 | $codeCovUrl = "https://uploader.codecov.io/latest/windows/codecov.exe"
22 | $toolName = 'codecov.exe'
23 | }
24 |
25 | $shaSuffix = ".SHA256SUM"
26 | $sigSuffix = $shaSuffix + ".sig"
27 |
28 | Function Get-FileFromWeb([Uri]$Uri, $OutDir) {
29 | $OutFile = Join-Path $OutDir $Uri.Segments[-1]
30 | if (!(Test-Path $OutFile)) {
31 | Write-Verbose "Downloading $Uri..."
32 | if (!(Test-Path $OutDir)) { New-Item -ItemType Directory -Path $OutDir | Out-Null }
33 | try {
34 | (New-Object System.Net.WebClient).DownloadFile($Uri, $OutFile)
35 | } finally {
36 | # This try/finally causes the script to abort
37 | }
38 | }
39 |
40 | $OutFile
41 | }
42 |
43 | $toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1"
44 | $binaryToolsPath = Join-Path $toolsPath codecov
45 | $testingPath = Join-Path $binaryToolsPath unverified
46 | $finalToolPath = Join-Path $binaryToolsPath $toolName
47 |
48 | if (!(Test-Path $finalToolPath)) {
49 | if (Test-Path $testingPath) {
50 | Remove-Item -Recurse -Force $testingPath # ensure we download all matching files
51 | }
52 | $tool = Get-FileFromWeb $codeCovUrl $testingPath
53 | $sha = Get-FileFromWeb "$codeCovUrl$shaSuffix" $testingPath
54 | $sig = Get-FileFromWeb "$codeCovUrl$sigSuffix" $testingPath
55 | $key = Get-FileFromWeb https://keybase.io/codecovsecurity/pgp_keys.asc $testingPath
56 |
57 | if ((Get-Command gpg -ErrorAction SilentlyContinue)) {
58 | Write-Host "Importing codecov key" -ForegroundColor Yellow
59 | gpg --import $key
60 | Write-Host "Verifying signature on codecov hash" -ForegroundColor Yellow
61 | gpg --verify $sig $sha
62 | } else {
63 | if ($AllowSkipVerify) {
64 | Write-Warning "gpg not found. Unable to verify hash signature."
65 | } else {
66 | throw "gpg not found. Unable to verify hash signature. Install gpg or add -AllowSkipVerify to override."
67 | }
68 | }
69 |
70 | Write-Host "Verifying hash on downloaded tool" -ForegroundColor Yellow
71 | $actualHash = (Get-FileHash -LiteralPath $tool -Algorithm SHA256).Hash
72 | $expectedHash = (Get-Content $sha).Split()[0]
73 | if ($actualHash -ne $expectedHash) {
74 | # Validation failed. Delete the tool so we can't execute it.
75 | #Remove-Item $codeCovPath
76 | throw "codecov uploader tool failed signature validation."
77 | }
78 |
79 | Copy-Item $tool $finalToolPath
80 |
81 | if ($IsMacOS -or $IsLinux) {
82 | chmod u+x $finalToolPath
83 | }
84 | }
85 |
86 | return $finalToolPath
87 |
--------------------------------------------------------------------------------
/tools/Get-LibTemplateBasis.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Returns the name of the well-known branch in the Library.Template repository upon which HEAD is based.
4 | #>
5 | [CmdletBinding(SupportsShouldProcess = $true)]
6 | Param(
7 | [switch]$ErrorIfNotRelated
8 | )
9 |
10 | # This list should be sorted in order of decreasing specificity.
11 | $branchMarkers = @(
12 | @{ commit = 'fd0a7b25ccf030bbd16880cca6efe009d5b1fffc'; branch = 'microbuild' };
13 | @{ commit = '05f49ce799c1f9cc696d53eea89699d80f59f833'; branch = 'main' };
14 | )
15 |
16 | foreach ($entry in $branchMarkers) {
17 | if (git rev-list HEAD | Select-String -Pattern $entry.commit) {
18 | return $entry.branch
19 | }
20 | }
21 |
22 | if ($ErrorIfNotRelated) {
23 | Write-Error "Library.Template has not been previously merged with this repo. Please review https://github.com/AArnott/Library.Template/tree/main?tab=readme-ov-file#readme for instructions."
24 | exit 1
25 | }
26 |
--------------------------------------------------------------------------------
/tools/Get-NuGetTool.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Downloads the NuGet.exe tool and returns the path to it.
4 | .PARAMETER NuGetVersion
5 | The version of the NuGet tool to acquire.
6 | #>
7 | Param(
8 | [Parameter()]
9 | [string]$NuGetVersion='6.12.2'
10 | )
11 |
12 | $toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1"
13 | $binaryToolsPath = Join-Path $toolsPath $NuGetVersion
14 | if (!(Test-Path $binaryToolsPath)) { $null = mkdir $binaryToolsPath }
15 | $nugetPath = Join-Path $binaryToolsPath nuget.exe
16 |
17 | if (!(Test-Path $nugetPath)) {
18 | Write-Host "Downloading nuget.exe $NuGetVersion..." -ForegroundColor Yellow
19 | (New-Object System.Net.WebClient).DownloadFile("https://dist.nuget.org/win-x86-commandline/v$NuGetVersion/NuGet.exe", $nugetPath)
20 | }
21 |
22 | return (Resolve-Path $nugetPath).Path
23 |
--------------------------------------------------------------------------------
/tools/Get-ProcDump.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Downloads 32-bit and 64-bit procdump executables and returns the path to where they were installed.
4 | #>
5 | $version = '0.0.1'
6 | $baseDir = "$PSScriptRoot\..\obj\tools"
7 | $procDumpToolPath = "$baseDir\procdump.$version\bin"
8 | if (-not (Test-Path $procDumpToolPath)) {
9 | if (-not (Test-Path $baseDir)) { New-Item -Type Directory -Path $baseDir | Out-Null }
10 | $baseDir = (Resolve-Path $baseDir).Path # Normalize it
11 | & (& $PSScriptRoot\Get-NuGetTool.ps1) install procdump -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://api.nuget.org/v3/index.json | Out-Null
12 | }
13 |
14 | (Resolve-Path $procDumpToolPath).Path
15 |
--------------------------------------------------------------------------------
/tools/Get-SymbolFiles.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Collect the list of PDBs built in this repo.
4 | .PARAMETER Path
5 | The directory to recursively search for PDBs.
6 | .PARAMETER Tests
7 | A switch indicating to find PDBs only for test binaries instead of only for shipping shipping binaries.
8 | #>
9 | [CmdletBinding()]
10 | param (
11 | [parameter(Mandatory=$true)]
12 | [string]$Path,
13 | [switch]$Tests
14 | )
15 |
16 | $ActivityName = "Collecting symbols from $Path"
17 | Write-Progress -Activity $ActivityName -CurrentOperation "Discovery PDB files"
18 | $PDBs = Get-ChildItem -rec "$Path/*.pdb"
19 |
20 | # Filter PDBs to product OR test related.
21 | $testregex = "unittest|tests|\.test\."
22 |
23 | Write-Progress -Activity $ActivityName -CurrentOperation "De-duplicating symbols"
24 | $PDBsByHash = @{}
25 | $i = 0
26 | $PDBs |% {
27 | Write-Progress -Activity $ActivityName -CurrentOperation "De-duplicating symbols" -PercentComplete (100 * $i / $PDBs.Length)
28 | $hash = Get-FileHash $_
29 | $i++
30 | Add-Member -InputObject $_ -MemberType NoteProperty -Name Hash -Value $hash.Hash
31 | Write-Output $_
32 | } | Sort-Object CreationTime |% {
33 | # De-dupe based on hash. Prefer the first match so we take the first built copy.
34 | if (-not $PDBsByHash.ContainsKey($_.Hash)) {
35 | $PDBsByHash.Add($_.Hash, $_.FullName)
36 | Write-Output $_
37 | }
38 | } |? {
39 | if ($Tests) {
40 | $_.FullName -match $testregex
41 | } else {
42 | $_.FullName -notmatch $testregex
43 | }
44 | } |% {
45 | # Collect the DLLs/EXEs as well.
46 | $rootName = "$($_.Directory)/$($_.BaseName)"
47 | if ($rootName.EndsWith('.ni')) {
48 | $rootName = $rootName.Substring(0, $rootName.Length - 3)
49 | }
50 |
51 | $dllPath = "$rootName.dll"
52 | $exePath = "$rootName.exe"
53 | if (Test-Path $dllPath) {
54 | $BinaryImagePath = $dllPath
55 | } elseif (Test-Path $exePath) {
56 | $BinaryImagePath = $exePath
57 | } else {
58 | Write-Warning "`"$_`" found with no matching binary file."
59 | $BinaryImagePath = $null
60 | }
61 |
62 | if ($BinaryImagePath) {
63 | Write-Output $BinaryImagePath
64 | Write-Output $_.FullName
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/tools/Get-TempToolsPath.ps1:
--------------------------------------------------------------------------------
1 | if ($env:AGENT_TEMPDIRECTORY) {
2 | $path = "$env:AGENT_TEMPDIRECTORY\$env:BUILD_BUILDID"
3 | } elseif ($env:localappdata) {
4 | $path = "$env:localappdata\gitrepos\tools"
5 | } else {
6 | $path = "$PSScriptRoot\..\obj\tools"
7 | }
8 |
9 | if (!(Test-Path $path)) {
10 | New-Item -ItemType Directory -Path $Path | Out-Null
11 | }
12 |
13 | (Resolve-Path $path).Path
14 |
--------------------------------------------------------------------------------
/tools/Install-NuGetCredProvider.ps1:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pwsh
2 |
3 | <#
4 | .SYNOPSIS
5 | Downloads and installs the Microsoft Artifacts Credential Provider
6 | from https://github.com/microsoft/artifacts-credprovider
7 | to assist in authenticating to Azure Artifact feeds in interactive development
8 | or unattended build agents.
9 | .PARAMETER Force
10 | Forces install of the CredProvider plugin even if one already exists. This is useful to upgrade an older version.
11 | .PARAMETER AccessToken
12 | An optional access token for authenticating to Azure Artifacts authenticated feeds.
13 | #>
14 | [CmdletBinding()]
15 | Param (
16 | [Parameter()]
17 | [switch]$Force,
18 | [Parameter()]
19 | [string]$AccessToken
20 | )
21 |
22 | $envVars = @{}
23 |
24 | $toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1"
25 |
26 | if ($IsMacOS -or $IsLinux) {
27 | $installerScript = "installcredprovider.sh"
28 | $sourceUrl = "https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh"
29 | } else {
30 | $installerScript = "installcredprovider.ps1"
31 | $sourceUrl = "https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1"
32 | }
33 |
34 | $installerScript = Join-Path $toolsPath $installerScript
35 |
36 | if (!(Test-Path $installerScript) -or $Force) {
37 | Invoke-WebRequest $sourceUrl -OutFile $installerScript
38 | }
39 |
40 | $installerScript = (Resolve-Path $installerScript).Path
41 |
42 | if ($IsMacOS -or $IsLinux) {
43 | chmod u+x $installerScript
44 | }
45 |
46 | & $installerScript -Force:$Force -AddNetfx -InstallNet8
47 |
48 | if ($AccessToken) {
49 | $endpoints = @()
50 |
51 | $endpointURIs = @()
52 | Get-ChildItem "$PSScriptRoot\..\nuget.config" -Recurse |% {
53 | $nugetConfig = [xml](Get-Content -LiteralPath $_)
54 |
55 | $nugetConfig.configuration.packageSources.add |? { ($_.value -match '^https://pkgs\.dev\.azure\.com/') -or ($_.value -match '^https://[\w\-]+\.pkgs\.visualstudio\.com/') } |% {
56 | if ($endpointURIs -notcontains $_.Value) {
57 | $endpointURIs += $_.Value
58 | $endpoint = New-Object -TypeName PSObject
59 | Add-Member -InputObject $endpoint -MemberType NoteProperty -Name endpoint -Value $_.value
60 | Add-Member -InputObject $endpoint -MemberType NoteProperty -Name username -Value ado
61 | Add-Member -InputObject $endpoint -MemberType NoteProperty -Name password -Value $AccessToken
62 | $endpoints += $endpoint
63 | }
64 | }
65 | }
66 |
67 | $auth = New-Object -TypeName PSObject
68 | Add-Member -InputObject $auth -MemberType NoteProperty -Name endpointCredentials -Value $endpoints
69 |
70 | $authJson = ConvertTo-Json -InputObject $auth
71 | $envVars += @{
72 | 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS'=$authJson;
73 | }
74 | }
75 |
76 | & "$PSScriptRoot/Set-EnvVars.ps1" -Variables $envVars | Out-Null
77 |
--------------------------------------------------------------------------------
/tools/MergeFrom-Template.ps1:
--------------------------------------------------------------------------------
1 |
2 | <#
3 | .SYNOPSIS
4 | Merges the latest changes from Library.Template into HEAD of this repo.
5 | .PARAMETER LocalBranch
6 | The name of the local branch to create at HEAD and use to merge into from Library.Template.
7 | #>
8 | [CmdletBinding(SupportsShouldProcess = $true)]
9 | Param(
10 | [string]$LocalBranch = "dev/$($env:USERNAME)/libtemplateUpdate"
11 | )
12 |
13 | Function Spawn-Tool($command, $commandArgs, $workingDirectory, $allowFailures) {
14 | if ($workingDirectory) {
15 | Push-Location $workingDirectory
16 | }
17 | try {
18 | if ($env:TF_BUILD) {
19 | Write-Host "$pwd >"
20 | Write-Host "##[command]$command $commandArgs"
21 | }
22 | else {
23 | Write-Host "$command $commandArgs" -ForegroundColor Yellow
24 | }
25 | if ($commandArgs) {
26 | & $command @commandArgs
27 | } else {
28 | Invoke-Expression $command
29 | }
30 | if ((!$allowFailures) -and ($LASTEXITCODE -ne 0)) { exit $LASTEXITCODE }
31 | }
32 | finally {
33 | if ($workingDirectory) {
34 | Pop-Location
35 | }
36 | }
37 | }
38 |
39 | $remoteBranch = & $PSScriptRoot\Get-LibTemplateBasis.ps1 -ErrorIfNotRelated
40 | if ($LASTEXITCODE -ne 0) {
41 | exit $LASTEXITCODE
42 | }
43 |
44 | $LibTemplateUrl = 'https://github.com/aarnott/Library.Template'
45 | Spawn-Tool 'git' ('fetch', $LibTemplateUrl, $remoteBranch)
46 | $SourceCommit = Spawn-Tool 'git' ('rev-parse', 'FETCH_HEAD')
47 | $BaseBranch = Spawn-Tool 'git' ('branch', '--show-current')
48 | $SourceCommitUrl = "$LibTemplateUrl/commit/$SourceCommit"
49 |
50 | # To reduce the odds of merge conflicts at this stage, we always move HEAD to the last successful merge.
51 | $basis = Spawn-Tool 'git' ('rev-parse', 'HEAD') # TODO: consider improving this later
52 |
53 | Write-Host "Merging the $remoteBranch branch of Library.Template ($SourceCommit) into local repo $basis" -ForegroundColor Green
54 |
55 | Spawn-Tool 'git' ('checkout', '-b', $LocalBranch, $basis) $null $true
56 | if ($LASTEXITCODE -eq 128) {
57 | Spawn-Tool 'git' ('checkout', $LocalBranch)
58 | Spawn-Tool 'git' ('merge', $basis)
59 | }
60 |
61 | Spawn-Tool 'git' ('merge', 'FETCH_HEAD', '--no-ff', '-m', "Merge the $remoteBranch branch from $LibTemplateUrl`n`nSpecifically, this merges [$SourceCommit from that repo]($SourceCommitUrl).")
62 | if ($LASTEXITCODE -eq 1) {
63 | Write-Error "Merge conflict detected. Manual resolution required."
64 | exit 1
65 | }
66 | elseif ($LASTEXITCODE -ne 0) {
67 | Write-Error "Merge failed with exit code $LASTEXITCODE."
68 | exit $LASTEXITCODE
69 | }
70 |
71 | $result = New-Object PSObject -Property @{
72 | BaseBranch = $BaseBranch # The original branch that was checked out when the script ran.
73 | LocalBranch = $LocalBranch # The name of the local branch that was created before the merge.
74 | SourceCommit = $SourceCommit # The commit from Library.Template that was merged in.
75 | SourceBranch = $remoteBranch # The branch from Library.Template that was merged in.
76 | }
77 |
78 | Write-Host $result
79 | Write-Output $result
80 |
--------------------------------------------------------------------------------
/tools/Prepare-Legacy-Symbols.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]$Path
3 | )
4 |
5 | $ArtifactStagingFolder = & "$PSScriptRoot/Get-ArtifactsStagingDirectory.ps1"
6 | $ArtifactStagingFolder += '/symbols-legacy'
7 | robocopy $Path $ArtifactStagingFolder /mir /njh /njs /ndl /nfl
8 | $WindowsPdbSubDirName = 'symstore'
9 |
10 | Get-ChildItem "$ArtifactStagingFolder\*.pdb" -Recurse |% {
11 | $dllPath = "$($_.Directory)/$($_.BaseName).dll"
12 | $exePath = "$($_.Directory)/$($_.BaseName).exe"
13 | if (Test-Path $dllPath) {
14 | $BinaryImagePath = $dllPath
15 | } elseif (Test-Path $exePath) {
16 | $BinaryImagePath = $exePath
17 | } else {
18 | Write-Warning "`"$_`" found with no matching binary file."
19 | $BinaryImagePath = $null
20 | }
21 |
22 | if ($BinaryImagePath) {
23 | # Convert the PDB to legacy Windows PDBs
24 | Write-Host "Converting PDB for $_" -ForegroundColor DarkGray
25 | $WindowsPdbDir = "$($_.Directory.FullName)\$WindowsPdbSubDirName"
26 | if (!(Test-Path $WindowsPdbDir)) { mkdir $WindowsPdbDir | Out-Null }
27 | $legacyPdbPath = "$WindowsPdbDir\$($_.BaseName).pdb"
28 | & "$PSScriptRoot\Convert-PDB.ps1" -DllPath $BinaryImagePath -PdbPath $_ -OutputPath $legacyPdbPath
29 | if ($LASTEXITCODE -ne 0) {
30 | Write-Warning "PDB conversion of `"$_`" failed."
31 | }
32 |
33 | Move-Item $legacyPdbPath $_ -Force
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tools/Set-EnvVars.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Set environment variables in the environment.
4 | Azure Pipeline and CMD environments are considered.
5 | .PARAMETER Variables
6 | A hashtable of variables to be set.
7 | .PARAMETER PrependPath
8 | A set of paths to prepend to the PATH environment variable.
9 | .OUTPUTS
10 | A boolean indicating whether the environment variables can be expected to propagate to the caller's environment.
11 | .DESCRIPTION
12 | The CmdEnvScriptPath environment variable may be optionally set to a path to a cmd shell script to be created (or appended to if it already exists) that will set the environment variables in cmd.exe that are set within the PowerShell environment.
13 | This is used by init.cmd in order to reapply any new environment variables to the parent cmd.exe process that were set in the powershell child process.
14 | #>
15 | [CmdletBinding(SupportsShouldProcess=$true)]
16 | Param(
17 | [Parameter(Mandatory=$true, Position=1)]
18 | $Variables,
19 | [string[]]$PrependPath
20 | )
21 |
22 | if ($Variables.Count -eq 0) {
23 | return $true
24 | }
25 |
26 | $cmdInstructions = !$env:TF_BUILD -and !$env:GITHUB_ACTIONS -and !$env:CmdEnvScriptPath -and ($env:PS1UnderCmd -eq '1')
27 | if ($cmdInstructions) {
28 | Write-Warning "Environment variables have been set that will be lost because you're running under cmd.exe"
29 | Write-Host "Environment variables that must be set manually:" -ForegroundColor Blue
30 | } else {
31 | Write-Host "Environment variables set:" -ForegroundColor Blue
32 | Write-Host ($Variables | Out-String)
33 | if ($PrependPath) {
34 | Write-Host "Paths prepended to PATH: $PrependPath"
35 | }
36 | }
37 |
38 | if ($env:TF_BUILD) {
39 | Write-Host "Azure Pipelines detected. Logging commands will be used to propagate environment variables and prepend path."
40 | }
41 |
42 | if ($env:GITHUB_ACTIONS) {
43 | Write-Host "GitHub Actions detected. Logging commands will be used to propagate environment variables and prepend path."
44 | }
45 |
46 | $CmdEnvScript = ''
47 | $Variables.GetEnumerator() |% {
48 | Set-Item -LiteralPath env:$($_.Key) -Value $_.Value
49 |
50 | # If we're running in a cloud CI, set these environment variables so they propagate.
51 | if ($env:TF_BUILD) {
52 | Write-Host "##vso[task.setvariable variable=$($_.Key);]$($_.Value)"
53 | }
54 | if ($env:GITHUB_ACTIONS) {
55 | Add-Content -LiteralPath $env:GITHUB_ENV -Value "$($_.Key)=$($_.Value)"
56 | }
57 |
58 | if ($cmdInstructions) {
59 | Write-Host "SET $($_.Key)=$($_.Value)"
60 | }
61 |
62 | $CmdEnvScript += "SET $($_.Key)=$($_.Value)`r`n"
63 | }
64 |
65 | $pathDelimiter = ';'
66 | if ($IsMacOS -or $IsLinux) {
67 | $pathDelimiter = ':'
68 | }
69 |
70 | if ($PrependPath) {
71 | $PrependPath |% {
72 | $newPathValue = "$_$pathDelimiter$env:PATH"
73 | Set-Item -LiteralPath env:PATH -Value $newPathValue
74 | if ($cmdInstructions) {
75 | Write-Host "SET PATH=$newPathValue"
76 | }
77 |
78 | if ($env:TF_BUILD) {
79 | Write-Host "##vso[task.prependpath]$_"
80 | }
81 | if ($env:GITHUB_ACTIONS) {
82 | Add-Content -LiteralPath $env:GITHUB_PATH -Value $_
83 | }
84 |
85 | $CmdEnvScript += "SET PATH=$_$pathDelimiter%PATH%"
86 | }
87 | }
88 |
89 | if ($env:CmdEnvScriptPath) {
90 | if (Test-Path $env:CmdEnvScriptPath) {
91 | $CmdEnvScript = (Get-Content -LiteralPath $env:CmdEnvScriptPath) + $CmdEnvScript
92 | }
93 |
94 | Set-Content -LiteralPath $env:CmdEnvScriptPath -Value $CmdEnvScript
95 | }
96 |
97 | return !$cmdInstructions
98 |
--------------------------------------------------------------------------------
/tools/artifacts/APIScanInputs.ps1:
--------------------------------------------------------------------------------
1 | $inputs = & "$PSScriptRoot/symbols.ps1"
2 |
3 | if (!$inputs) { return }
4 |
5 | # Filter out specific files that target OS's that are not subject to APIScan.
6 | # Files that are subject but are not supported must be scanned and an SEL exception filed.
7 | $outputs = @{}
8 | $forbiddenSubPaths = @(
9 | , 'linux-*'
10 | , 'osx*'
11 | )
12 |
13 | $inputs.GetEnumerator() | % {
14 | $list = $_.Value | ? {
15 | $path = $_.Replace('\', '/')
16 | return !($forbiddenSubPaths | ? { $path -like "*/$_/*" })
17 | }
18 | $outputs[$_.Key] = $list
19 | }
20 |
21 |
22 | $outputs
23 |
--------------------------------------------------------------------------------
/tools/artifacts/LocBin.ps1:
--------------------------------------------------------------------------------
1 | # Identify LCE files and the binary files they describe
2 | $BinRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..\bin")
3 | if (!(Test-Path $BinRoot)) { return }
4 |
5 | $FilesToCopy = @()
6 | $FilesToCopy += Get-ChildItem -Recurse -File -Path $BinRoot |? { $_.FullName -match '\\Localize\\' }
7 |
8 | Get-ChildItem -rec "$BinRoot\*.lce" -File | % {
9 | $FilesToCopy += $_
10 | $FilesToCopy += $_.FullName.SubString(0, $_.FullName.Length - 4)
11 | }
12 |
13 | $FilesToCopy += Get-ChildItem -rec "$BinRoot\*.lcg" -File | % { [xml](Get-Content $_) } | % { $_.lcx.name }
14 |
15 | @{
16 | "$BinRoot" = $FilesToCopy;
17 | }
18 |
--------------------------------------------------------------------------------
/tools/artifacts/VSInsertion.ps1:
--------------------------------------------------------------------------------
1 | # This artifact captures everything needed to insert into VS (NuGet packages, insertion metadata, etc.)
2 |
3 | [CmdletBinding()]
4 | Param (
5 | )
6 |
7 | if ($IsMacOS -or $IsLinux) {
8 | # We only package up for insertions on Windows agents since they are where optprof can happen.
9 | Write-Verbose "Skipping VSInsertion artifact since we're not on Windows."
10 | return @{}
11 | }
12 |
13 | $RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..")
14 | $BuildConfiguration = $env:BUILDCONFIGURATION
15 | if (!$BuildConfiguration) {
16 | $BuildConfiguration = 'Debug'
17 | }
18 |
19 | $PackagesRoot = "$RepoRoot/bin/Packages/$BuildConfiguration"
20 | $NuGetPackages = "$PackagesRoot/NuGet"
21 | $VsixPackages = "$PackagesRoot/Vsix"
22 |
23 | if (!(Test-Path $NuGetPackages)) {
24 | Write-Warning "Skipping because NuGet packages haven't been built yet."
25 | return @{}
26 | }
27 |
28 | $result = @{
29 | "$NuGetPackages" = (Get-ChildItem $NuGetPackages -Recurse)
30 | }
31 |
32 | if (Test-Path $VsixPackages) {
33 | $result["$PackagesRoot"] += Get-ChildItem $VsixPackages -Recurse
34 | }
35 |
36 | if ($env:IsOptProf) {
37 | $VSRepoPackages = "$PackagesRoot/VSRepo"
38 | $result["$VSRepoPackages"] = (Get-ChildItem "$VSRepoPackages\*.VSInsertionMetadata.*.nupkg");
39 | }
40 |
41 | $result
42 |
--------------------------------------------------------------------------------
/tools/artifacts/Variables.ps1:
--------------------------------------------------------------------------------
1 | # This artifact captures all variables defined in the ..\variables folder.
2 | # It "snaps" the values of these variables where we can compute them during the build,
3 | # and otherwise captures the scripts to run later during an Azure Pipelines environment release.
4 |
5 | $RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot/../..")
6 | $ArtifactBasePath = "$RepoRoot/obj/_artifacts"
7 | $VariablesArtifactPath = Join-Path $ArtifactBasePath variables
8 | if (-not (Test-Path $VariablesArtifactPath)) { New-Item -ItemType Directory -Path $VariablesArtifactPath | Out-Null }
9 |
10 | # Copy variables, either by value if the value is calculable now, or by script
11 | Get-ChildItem "$PSScriptRoot/../variables" |% {
12 | $value = $null
13 | if (-not $_.BaseName.StartsWith('_')) { # Skip trying to interpret special scripts
14 | # First check the environment variables in case the variable was set in a queued build
15 | # Always use all caps for env var access because Azure Pipelines converts variables to upper-case for env vars,
16 | # and on non-Windows env vars are case sensitive.
17 | $envVarName = $_.BaseName.ToUpper()
18 | if (Test-Path env:$envVarName) {
19 | $value = Get-Content "env:$envVarName"
20 | }
21 |
22 | # If that didn't give us anything, try executing the script right now from its original position
23 | if (-not $value) {
24 | $value = & $_.FullName
25 | }
26 |
27 | if ($value) {
28 | # We got something, so wrap it with quotes so it's treated like a literal value.
29 | $value = "'$value'"
30 | }
31 | }
32 |
33 | # If that didn't get us anything, just copy the script itself
34 | if (-not $value) {
35 | $value = Get-Content -LiteralPath $_.FullName
36 | }
37 |
38 | Set-Content -LiteralPath "$VariablesArtifactPath/$($_.Name)" -Value $value
39 | }
40 |
41 | @{
42 | "$VariablesArtifactPath" = (Get-ChildItem $VariablesArtifactPath -Recurse);
43 | }
44 |
--------------------------------------------------------------------------------
/tools/artifacts/_all.ps1:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pwsh
2 |
3 | <#
4 | .SYNOPSIS
5 | This script returns all the artifacts that should be collected after a build.
6 | Each powershell artifact is expressed as an object with these properties:
7 | Source - the full path to the source file
8 | ArtifactName - the name of the artifact to upload to
9 | ContainerFolder - the relative path within the artifact in which the file should appear
10 | Each artifact aggregating .ps1 script should return a hashtable:
11 | Key = path to the directory from which relative paths within the artifact should be calculated
12 | Value = an array of paths (absolute or relative to the BaseDirectory) to files to include in the artifact.
13 | FileInfo objects are also allowed.
14 | .PARAMETER Force
15 | Executes artifact scripts even if they have already been staged.
16 | #>
17 |
18 | [CmdletBinding(SupportsShouldProcess = $true)]
19 | param (
20 | [string]$ArtifactNameSuffix,
21 | [switch]$Force
22 | )
23 |
24 | Function EnsureTrailingSlash($path) {
25 | if ($path.length -gt 0 -and !$path.EndsWith('\') -and !$path.EndsWith('/')) {
26 | $path = $path + [IO.Path]::DirectorySeparatorChar
27 | }
28 |
29 | $path.Replace('\', [IO.Path]::DirectorySeparatorChar)
30 | }
31 |
32 | Function Test-ArtifactStaged($artifactName) {
33 | $varName = "ARTIFACTSTAGED_$($artifactName.ToUpper())"
34 | Test-Path "env:$varName"
35 | }
36 |
37 | Get-ChildItem "$PSScriptRoot\*.ps1" -Exclude "_*" -Recurse | % {
38 | $ArtifactName = $_.BaseName
39 | if ($Force -or !(Test-ArtifactStaged($ArtifactName + $ArtifactNameSuffix))) {
40 | $totalFileCount = 0
41 | Write-Verbose "Collecting file list for artifact $($_.BaseName)"
42 | $fileGroups = & $_
43 | if ($fileGroups) {
44 | $fileGroups.GetEnumerator() | % {
45 | $BaseDirectory = New-Object Uri ((EnsureTrailingSlash $_.Key.ToString()), [UriKind]::Absolute)
46 | $_.Value | ? { $_ } | % {
47 | if ($_.GetType() -eq [IO.FileInfo] -or $_.GetType() -eq [IO.DirectoryInfo]) {
48 | $_ = $_.FullName
49 | }
50 |
51 | $artifact = New-Object -TypeName PSObject
52 | Add-Member -InputObject $artifact -MemberType NoteProperty -Name ArtifactName -Value $ArtifactName
53 |
54 | $SourceFullPath = New-Object Uri ($BaseDirectory, $_)
55 | Add-Member -InputObject $artifact -MemberType NoteProperty -Name Source -Value $SourceFullPath.LocalPath
56 |
57 | $RelativePath = [Uri]::UnescapeDataString($BaseDirectory.MakeRelative($SourceFullPath))
58 | Add-Member -InputObject $artifact -MemberType NoteProperty -Name ContainerFolder -Value (Split-Path $RelativePath)
59 |
60 | Write-Output $artifact
61 | $totalFileCount += 1
62 | }
63 | }
64 | }
65 |
66 | if ($totalFileCount -eq 0) {
67 | Write-Warning "No files found for the `"$ArtifactName`" artifact."
68 | }
69 | } else {
70 | Write-Host "Skipping $ArtifactName because it has already been staged." -ForegroundColor DarkGray
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/tools/artifacts/_stage_all.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | This script links all the artifacts described by _all.ps1
4 | into a staging directory, reading for uploading to a cloud build artifact store.
5 | It returns a sequence of objects with Name and Path properties.
6 | #>
7 |
8 | [CmdletBinding()]
9 | param (
10 | [string]$ArtifactNameSuffix,
11 | [switch]$AvoidSymbolicLinks
12 | )
13 |
14 | $ArtifactStagingFolder = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1" -CleanIfLocal
15 |
16 | function Create-SymbolicLink {
17 | param (
18 | $Link,
19 | $Target
20 | )
21 |
22 | if ($Link -eq $Target) {
23 | return
24 | }
25 |
26 | if (Test-Path $Link) { Remove-Item $Link }
27 | $LinkContainer = Split-Path $Link -Parent
28 | if (!(Test-Path $LinkContainer)) { mkdir $LinkContainer }
29 | if ($IsMacOS -or $IsLinux) {
30 | ln $Target $Link | Out-Null
31 | } else {
32 | cmd /c "mklink `"$Link`" `"$Target`"" | Out-Null
33 | }
34 |
35 | if ($LASTEXITCODE -ne 0) {
36 | # Windows requires admin privileges to create symbolic links
37 | # unless Developer Mode has been enabled.
38 | throw "Failed to create symbolic link at $Link that points to $Target"
39 | }
40 | }
41 |
42 | # Stage all artifacts
43 | $Artifacts = & "$PSScriptRoot\_all.ps1" -ArtifactNameSuffix $ArtifactNameSuffix
44 | $Artifacts |% {
45 | $DestinationFolder = [System.IO.Path]::GetFullPath("$ArtifactStagingFolder/$($_.ArtifactName)$ArtifactNameSuffix/$($_.ContainerFolder)").TrimEnd('\')
46 | $Name = "$(Split-Path $_.Source -Leaf)"
47 |
48 | #Write-Host "$($_.Source) -> $($_.ArtifactName)\$($_.ContainerFolder)" -ForegroundColor Yellow
49 |
50 | if (-not (Test-Path $DestinationFolder)) { New-Item -ItemType Directory -Path $DestinationFolder | Out-Null }
51 | if (Test-Path -PathType Leaf $_.Source) { # skip folders
52 | $TargetPath = Join-Path $DestinationFolder $Name
53 | if ($AvoidSymbolicLinks) {
54 | Copy-Item -LiteralPath $_.Source -Destination $TargetPath
55 | } else {
56 | Create-SymbolicLink -Link $TargetPath -Target $_.Source
57 | }
58 | }
59 | }
60 |
61 | $ArtifactNames = $Artifacts |% { "$($_.ArtifactName)$ArtifactNameSuffix" }
62 | $ArtifactNames += Get-ChildItem env:ARTIFACTSTAGED_* |% {
63 | # Return from ALLCAPS to the actual capitalization used for the artifact.
64 | $artifactNameAllCaps = "$($_.Name.Substring('ARTIFACTSTAGED_'.Length))"
65 | (Get-ChildItem $ArtifactStagingFolder\$artifactNameAllCaps* -Filter $artifactNameAllCaps).Name
66 | }
67 | $ArtifactNames | Get-Unique |% {
68 | $artifact = New-Object -TypeName PSObject
69 | Add-Member -InputObject $artifact -MemberType NoteProperty -Name Name -Value $_
70 | Add-Member -InputObject $artifact -MemberType NoteProperty -Name Path -Value (Join-Path $ArtifactStagingFolder $_)
71 | Write-Output $artifact
72 | }
73 |
--------------------------------------------------------------------------------
/tools/artifacts/build_logs.ps1:
--------------------------------------------------------------------------------
1 | $ArtifactStagingFolder = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1"
2 |
3 | if (!(Test-Path $ArtifactStagingFolder/build_logs)) { return }
4 |
5 | @{
6 | "$ArtifactStagingFolder/build_logs" = (Get-ChildItem -Recurse "$ArtifactStagingFolder/build_logs")
7 | }
8 |
--------------------------------------------------------------------------------
/tools/artifacts/coverageResults.ps1:
--------------------------------------------------------------------------------
1 | $RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..")
2 |
3 | $coverageFiles = @(Get-ChildItem "$RepoRoot/test/*.cobertura.xml" -Recurse | Where {$_.FullName -notlike "*/In/*" -and $_.FullName -notlike "*\In\*" })
4 |
5 | # Prepare code coverage reports for merging on another machine
6 | $repoRoot = $env:SYSTEM_DEFAULTWORKINGDIRECTORY
7 | if (!$repoRoot) { $repoRoot = $env:GITHUB_WORKSPACE }
8 | if ($repoRoot) {
9 | Write-Host "Substituting $repoRoot with `"{reporoot}`""
10 | $coverageFiles |% {
11 | $content = Get-Content -LiteralPath $_ |% { $_ -Replace [regex]::Escape($repoRoot), "{reporoot}" }
12 | Set-Content -LiteralPath $_ -Value $content -Encoding UTF8
13 | }
14 | } else {
15 | Write-Warning "coverageResults: Cloud build not detected. Machine-neutral token replacement skipped."
16 | }
17 |
18 | if (!((Test-Path $RepoRoot\bin) -and (Test-Path $RepoRoot\obj))) { return }
19 |
20 | @{
21 | $RepoRoot = (
22 | $coverageFiles +
23 | (Get-ChildItem "$RepoRoot\obj\*.cs" -Recurse)
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/tools/artifacts/deployables.ps1:
--------------------------------------------------------------------------------
1 | $RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..")
2 | $BuildConfiguration = $env:BUILDCONFIGURATION
3 | if (!$BuildConfiguration) {
4 | $BuildConfiguration = 'Debug'
5 | }
6 |
7 | $PackagesRoot = "$RepoRoot/bin/Packages/$BuildConfiguration"
8 |
9 | if (!(Test-Path $PackagesRoot)) { return }
10 |
11 | @{
12 | "$PackagesRoot" = (Get-ChildItem $PackagesRoot -Recurse)
13 | }
14 |
--------------------------------------------------------------------------------
/tools/artifacts/projectAssetsJson.ps1:
--------------------------------------------------------------------------------
1 | $ObjRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..\obj")
2 |
3 | if (!(Test-Path $ObjRoot)) { return }
4 |
5 | @{
6 | "$ObjRoot" = (
7 | (Get-ChildItem "$ObjRoot\project.assets.json" -Recurse)
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/tools/artifacts/symbols.ps1:
--------------------------------------------------------------------------------
1 | $BinPath = [System.IO.Path]::GetFullPath("$PSScriptRoot/../../bin")
2 | if (!(Test-Path $BinPath)) { return }
3 | $symbolfiles = & "$PSScriptRoot/../Get-SymbolFiles.ps1" -Path $BinPath | Get-Unique
4 |
5 | @{
6 | "$BinPath" = $SymbolFiles;
7 | }
8 |
--------------------------------------------------------------------------------
/tools/artifacts/testResults.ps1:
--------------------------------------------------------------------------------
1 | [CmdletBinding()]
2 | Param(
3 | )
4 |
5 | $result = @{}
6 |
7 | $testRoot = Resolve-Path "$PSScriptRoot\..\..\test"
8 | $result[$testRoot] = (Get-ChildItem "$testRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File)
9 |
10 | $artifactStaging = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1"
11 | $testlogsPath = Join-Path $artifactStaging "test_logs"
12 | if (Test-Path $testlogsPath) {
13 | $result[$testlogsPath] = Get-ChildItem $testlogsPath -Recurse;
14 | }
15 |
16 | $result
17 |
--------------------------------------------------------------------------------
/tools/artifacts/test_symbols.ps1:
--------------------------------------------------------------------------------
1 | $BinPath = [System.IO.Path]::GetFullPath("$PSScriptRoot/../../bin")
2 | if (!(Test-Path $BinPath)) { return }
3 | $symbolfiles = & "$PSScriptRoot/../Get-SymbolFiles.ps1" -Path $BinPath -Tests | Get-Unique
4 |
5 | @{
6 | "$BinPath" = $SymbolFiles;
7 | }
8 |
--------------------------------------------------------------------------------
/tools/dotnet-test-cloud.ps1:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pwsh
2 |
3 | <#
4 | .SYNOPSIS
5 | Runs tests as they are run in cloud test runs.
6 | .PARAMETER Configuration
7 | The configuration within which to run tests
8 | .PARAMETER Agent
9 | The name of the agent. This is used in preparing test run titles.
10 | .PARAMETER PublishResults
11 | A switch to publish results to Azure Pipelines.
12 | .PARAMETER x86
13 | A switch to run the tests in an x86 process.
14 | .PARAMETER dotnet32
15 | The path to a 32-bit dotnet executable to use.
16 | #>
17 | [CmdletBinding()]
18 | Param(
19 | [string]$Configuration = 'Debug',
20 | [string]$Agent = 'Local',
21 | [switch]$PublishResults,
22 | [switch]$x86,
23 | [string]$dotnet32
24 | )
25 |
26 | $RepoRoot = (Resolve-Path "$PSScriptRoot/..").Path
27 | $ArtifactStagingFolder = & "$PSScriptRoot/Get-ArtifactsStagingDirectory.ps1"
28 |
29 | $dotnet = 'dotnet'
30 | if ($x86) {
31 | $x86RunTitleSuffix = ", x86"
32 | if ($dotnet32) {
33 | $dotnet = $dotnet32
34 | }
35 | else {
36 | $dotnet32Possibilities = "$PSScriptRoot\../obj/tools/x86/.dotnet/dotnet.exe", "$env:AGENT_TOOLSDIRECTORY/x86/dotnet/dotnet.exe", "${env:ProgramFiles(x86)}\dotnet\dotnet.exe"
37 | $dotnet32Matches = $dotnet32Possibilities | ? { Test-Path $_ }
38 | if ($dotnet32Matches) {
39 | $dotnet = Resolve-Path @($dotnet32Matches)[0]
40 | Write-Host "Running tests using `"$dotnet`"" -ForegroundColor DarkGray
41 | }
42 | else {
43 | Write-Error "Unable to find 32-bit dotnet.exe"
44 | return 1
45 | }
46 | }
47 | }
48 |
49 | $testBinLog = Join-Path $ArtifactStagingFolder (Join-Path build_logs test.binlog)
50 | $testDiagLog = Join-Path $ArtifactStagingFolder (Join-Path test_logs diag.log)
51 |
52 | & $dotnet test "$RepoRoot\test\Microsoft.VisualStudio.Jdt.Tests"`
53 | --no-build `
54 | -c $Configuration `
55 | --filter "TestCategory!=FailsInCloudTest" `
56 | --collect "Code Coverage;Format=cobertura" `
57 | --settings "$PSScriptRoot/test.runsettings" `
58 | --blame-hang-timeout 60s `
59 | --blame-crash `
60 | -bl:"$testBinLog" `
61 | --diag "$testDiagLog;TraceLevel=info" `
62 | --logger trx `
63 |
64 | $unknownCounter = 0
65 | Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx | % {
66 | Copy-Item $_ -Destination $ArtifactStagingFolder/test_logs/
67 |
68 | if ($PublishResults) {
69 | $x = [xml](Get-Content -LiteralPath $_)
70 | $runTitle = $null
71 | if ($x.TestRun.TestDefinitions -and $x.TestRun.TestDefinitions.GetElementsByTagName('UnitTest')) {
72 | $storage = $x.TestRun.TestDefinitions.GetElementsByTagName('UnitTest')[0].storage -replace '\\', '/'
73 | if ($storage -match '/(?net[^/]+)/(?:(?[^/]+)/)?(?[^/]+)\.(dll|exe)$') {
74 | if ($matches.rid) {
75 | $runTitle = "$($matches.lib) ($($matches.tfm), $($matches.rid), $Agent)"
76 | }
77 | else {
78 | $runTitle = "$($matches.lib) ($($matches.tfm)$x86RunTitleSuffix, $Agent)"
79 | }
80 | }
81 | }
82 | if (!$runTitle) {
83 | $unknownCounter += 1;
84 | $runTitle = "unknown$unknownCounter ($Agent$x86RunTitleSuffix)";
85 | }
86 |
87 | Write-Host "##vso[results.publish type=VSTest;runTitle=$runTitle;publishRunAttachments=true;resultFiles=$_;failTaskOnFailedTests=true;testRunSystem=VSTS - PTR;]"
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/tools/publish-CodeCov.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Uploads code coverage to codecov.io
4 | .PARAMETER CodeCovToken
5 | Code coverage token to use
6 | .PARAMETER PathToCodeCoverage
7 | Path to root of code coverage files
8 | .PARAMETER Name
9 | Name to upload with codecoverge
10 | .PARAMETER Flags
11 | Flags to upload with codecoverge
12 | #>
13 | [CmdletBinding()]
14 | Param (
15 | [Parameter(Mandatory=$true)]
16 | [string]$CodeCovToken,
17 | [Parameter(Mandatory=$true)]
18 | [string]$PathToCodeCoverage,
19 | [string]$Name,
20 | [string]$Flags
21 | )
22 |
23 | $RepoRoot = (Resolve-Path "$PSScriptRoot/..").Path
24 |
25 | Get-ChildItem -Recurse -LiteralPath $PathToCodeCoverage -Filter "*.cobertura.xml" | % {
26 | $relativeFilePath = Resolve-Path -relative $_.FullName
27 |
28 | Write-Host "Uploading: $relativeFilePath" -ForegroundColor Yellow
29 | & (& "$PSScriptRoot/Get-CodeCovTool.ps1") -t $CodeCovToken -f $relativeFilePath -R $RepoRoot -F $Flags -n $Name
30 | }
31 |
--------------------------------------------------------------------------------
/tools/test.runsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | \.dll$
10 | \.exe$
11 |
12 |
13 | xunit\..*
14 |
15 |
16 |
17 |
18 | ^System\.Diagnostics\.DebuggerHiddenAttribute$
19 | ^System\.Diagnostics\.DebuggerNonUserCodeAttribute$
20 | ^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$
21 | ^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$
22 |
23 |
24 |
25 |
26 | True
27 |
28 | True
29 |
30 | True
31 |
32 | False
33 |
34 | False
35 |
36 | False
37 |
38 | True
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/tools/variables/BusinessGroupName.ps1:
--------------------------------------------------------------------------------
1 | 'Visual Studio - VS Core'
2 |
--------------------------------------------------------------------------------
/tools/variables/DotNetSdkVersion.ps1:
--------------------------------------------------------------------------------
1 | $globalJson = Get-Content -LiteralPath "$PSScriptRoot\..\..\global.json" | ConvertFrom-Json
2 | $globalJson.sdk.version
3 |
--------------------------------------------------------------------------------
/tools/variables/InsertJsonValues.ps1:
--------------------------------------------------------------------------------
1 | $vstsDropNames = & "$PSScriptRoot\VstsDropNames.ps1"
2 | $BuildConfiguration = $env:BUILDCONFIGURATION
3 | if (!$BuildConfiguration) {
4 | $BuildConfiguration = 'Debug'
5 | }
6 |
7 | $BasePath = "$PSScriptRoot\..\..\bin\Packages\$BuildConfiguration\Vsix"
8 |
9 | if (Test-Path $BasePath) {
10 | $vsmanFiles = @()
11 | Get-ChildItem $BasePath *.vsman -Recurse -File |% {
12 | $version = (Get-Content $_.FullName | ConvertFrom-Json).info.buildVersion
13 | $fn = $_.Name
14 | $vsmanFiles += "$fn{$version}=https://vsdrop.corp.microsoft.com/file/v1/$vstsDropNames;$fn"
15 | }
16 |
17 | [string]::join(',',$vsmanFiles)
18 | }
19 |
--------------------------------------------------------------------------------
/tools/variables/InsertPropsValues.ps1:
--------------------------------------------------------------------------------
1 | $InsertedPkgs = (& "$PSScriptRoot\..\artifacts\VSInsertion.ps1")
2 |
3 | $icv=@()
4 | foreach ($kvp in $InsertedPkgs.GetEnumerator()) {
5 | $kvp.Value |% {
6 | if ($_.Name -match "^(.*?)\.(\d+\.\d+\.\d+(?:\.\d+)?(?:-.*?)?)(?:\.symbols)?\.nupkg$") {
7 | $id = $Matches[1]
8 | $version = $Matches[2]
9 | $icv += "$id=$version"
10 | }
11 | }
12 | }
13 |
14 | Write-Output ([string]::join(',',$icv))
15 |
--------------------------------------------------------------------------------
/tools/variables/InsertTargetBranch.ps1:
--------------------------------------------------------------------------------
1 | # This is the default branch of the VS repo that we will use to insert into VS.
2 | 'main'
3 |
--------------------------------------------------------------------------------
/tools/variables/InsertVersionsValues.ps1:
--------------------------------------------------------------------------------
1 | # When you need binding redirects in the VS repo updated to match
2 | # assemblies that you build here, remove the "return" statement
3 | # and update the hashtable below with the T4 macro you'll use for
4 | # your libraries as defined in the src\ProductData\AssemblyVersions.tt file.
5 | return
6 |
7 | $MacroName = 'LibraryNoDotsVersion'
8 | $SampleProject = "$PSScriptRoot\..\..\src\LibraryName"
9 | [string]::join(',',(@{
10 | ($MacroName) = & { (dotnet nbgv get-version --project $SampleProject --format json | ConvertFrom-Json).AssemblyVersion };
11 | }.GetEnumerator() |% { "$($_.key)=$($_.value)" }))
12 |
--------------------------------------------------------------------------------
/tools/variables/LocLanguages.ps1:
--------------------------------------------------------------------------------
1 | ## For faster PR/CI builds localize only for 2 languages, ENU and JPN provide good enough coverage
2 | if ($env:BUILD_REASON -eq 'PullRequest') {
3 | 'ENU,JPN'
4 | } else {
5 | 'VS'
6 | }
7 |
--------------------------------------------------------------------------------
/tools/variables/ProfilingInputsDropName.ps1:
--------------------------------------------------------------------------------
1 | if ($env:SYSTEM_TEAMPROJECT) {
2 | "ProfilingInputs/$env:SYSTEM_TEAMPROJECT/$env:BUILD_REPOSITORY_NAME/$env:BUILD_SOURCEBRANCHNAME/$env:BUILD_BUILDID"
3 | } else {
4 | Write-Warning "No Azure Pipelines build detected. No Azure Pipelines drop name will be computed."
5 | }
6 |
--------------------------------------------------------------------------------
/tools/variables/SymbolsFeatureName.ps1:
--------------------------------------------------------------------------------
1 | 'json-document-transforms'
2 |
--------------------------------------------------------------------------------
/tools/variables/VstsDropNames.ps1:
--------------------------------------------------------------------------------
1 | "Products/$env:SYSTEM_TEAMPROJECT/$env:BUILD_REPOSITORY_NAME/$env:BUILD_SOURCEBRANCHNAME/$env:BUILD_BUILDID"
2 |
--------------------------------------------------------------------------------
/tools/variables/_all.ps1:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pwsh
2 |
3 | <#
4 | .SYNOPSIS
5 | This script returns a hashtable of build variables that should be set
6 | at the start of a build or release definition's execution.
7 | #>
8 |
9 | [CmdletBinding(SupportsShouldProcess = $true)]
10 | param (
11 | )
12 |
13 | $vars = @{}
14 |
15 | Get-ChildItem "$PSScriptRoot\*.ps1" -Exclude "_*" |% {
16 | Write-Host "Computing $($_.BaseName) variable"
17 | $vars[$_.BaseName] = & $_
18 | }
19 |
20 | $vars
21 |
--------------------------------------------------------------------------------
/tools/variables/_define.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | This script translates the variables returned by the _all.ps1 script
4 | into commands that instruct Azure Pipelines to actually set those variables for other pipeline tasks to consume.
5 |
6 | The build or release definition may have set these variables to override
7 | what the build would do. So only set them if they have not already been set.
8 | #>
9 |
10 | [CmdletBinding()]
11 | param (
12 | )
13 |
14 | (& "$PSScriptRoot\_all.ps1").GetEnumerator() |% {
15 | # Always use ALL CAPS for env var names since Azure Pipelines converts variable names to all caps and on non-Windows OS, env vars are case sensitive.
16 | $keyCaps = $_.Key.ToUpper()
17 | if ((Test-Path "env:$keyCaps") -and (Get-Content "env:$keyCaps")) {
18 | Write-Host "Skipping setting $keyCaps because variable is already set to '$(Get-Content env:$keyCaps)'." -ForegroundColor Cyan
19 | } else {
20 | Write-Host "$keyCaps=$($_.Value)" -ForegroundColor Yellow
21 | if ($env:TF_BUILD) {
22 | # Create two variables: the first that can be used by its simple name and accessible only within this job.
23 | Write-Host "##vso[task.setvariable variable=$keyCaps]$($_.Value)"
24 | # and the second that works across jobs and stages but must be fully qualified when referenced.
25 | Write-Host "##vso[task.setvariable variable=$keyCaps;isOutput=true]$($_.Value)"
26 | } elseif ($env:GITHUB_ACTIONS) {
27 | Add-Content -LiteralPath $env:GITHUB_ENV -Value "$keyCaps=$($_.Value)"
28 | }
29 | Set-Item -LiteralPath "env:$keyCaps" -Value $_.Value
30 | }
31 | }
32 |
--------------------------------------------------------------------------------