diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml index 8ac3ac6f5..0acbdf4a0 100644 --- a/.azure/pipelines/ci.yml +++ b/.azure/pipelines/ci.yml @@ -2,7 +2,7 @@ trigger: branches: include: - - master + - main - release/* # Trigger builds for PRs to any branch @@ -11,16 +11,41 @@ pr: include: - '*' +schedules: +- cron: 0 9 * * 1 + displayName: "Run CodeQL3000 weekly, Monday at 2:00 AM PDT" + branches: + include: + - release/2.1 + - main + always: true + +parameters: +# Parameters below are ignored in public builds. +# +# Choose whether to run the CodeQL3000 tasks. +# Manual builds align w/ official builds unless this parameter is true. +- name: runCodeQL3000 + default: false + displayName: Run CodeQL3000 tasks + type: boolean + +variables: + BuildConfiguration: Release + jobs: -- template: ../templates/project-ci.yml +- template: jobs/project-ci.yml parameters: # Ensures the alignment of branch name and deployment params buildArgs: '/warnaserror:BUILD1001' - afterBuild: - - task: PublishBuildArtifacts@1 - displayName: Upload KoreBuild artifact - condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'), eq(variables['AgentOsName'], 'Windows'), eq(variables['system.pullrequest.isfork'], false)) - inputs: - pathtoPublish: artifacts/korebuild/ - artifactName: korebuild - artifactType: Container + ${{ if and(eq(variables['System.TeamProject'], 'internal'), or(eq(variables['Build.Reason'], 'Schedule'), and(eq(variables['Build.Reason'], 'Manual'), eq(parameters.runCodeQL3000, 'true')))) }}: + runCodeQL3000: true + ${{ else }}: + afterBuild: + - task: PublishBuildArtifacts@1 + displayName: Upload KoreBuild artifact + condition: and(succeeded(), eq(variables['BuildConfiguration'], 'Release'), eq(variables['AgentOsName'], 'Windows'), eq(variables['system.pullrequest.isfork'], false)) + inputs: + pathtoPublish: artifacts/korebuild/ + artifactName: korebuild + artifactType: Container diff --git a/.azure/templates/jobs/default-build.yml b/.azure/pipelines/jobs/default-build.yml similarity index 87% rename from .azure/templates/jobs/default-build.yml rename to .azure/pipelines/jobs/default-build.yml index 0e5b478f8..058be9661 100644 --- a/.azure/templates/jobs/default-build.yml +++ b/.azure/pipelines/jobs/default-build.yml @@ -48,6 +48,7 @@ parameters: afterBuild: [] codeSign: false variables: {} + runCodeQL3000: false dependsOn: '' # buildSteps: [] - don't define an empty object default because there is no way in template expression yet to check "if isEmpty(parameters.buildSteps)" # jobName: '' - use agentOs by default. @@ -68,31 +69,44 @@ jobs: maxParallel: 8 matrix: ${{ parameters.matrix }} # Map friendly OS names to the right queue - # See https://github.com/dotnet/arcade/blob/master/Documentation/ChoosingAMachinePool.md and + # See https://github.com/dotnet/arcade/blob/main/Documentation/ChoosingAMachinePool.md and # https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml#use-a-microsoft-hosted-agent pool: ${{ if ne(parameters.poolName, '') }}: name: ${{ parameters.poolName }} ${{ if and(eq(parameters.poolName, ''), eq(parameters.agentOs, 'macOS')) }}: - vmImage: macOS-10.13 + vmImage: macOS-10.15 ${{ if and(eq(parameters.poolName, ''), eq(parameters.agentOs, 'Linux')) }}: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 ${{ if and(eq(parameters.poolName, ''), eq(parameters.agentOs, 'Windows')) }}: - vmImage: vs2017-win2016 + vmImage: windows-2019 ${{ if ne(variables['System.TeamProject'], 'public') }}: - name: NetCoreInternal-Pool - queue: BuildPool.Windows.10.Amd64.VS2017 + name: NetCore1ESPool-Svc-Internal + demands: ImageOverride -equals windows.vs2019.amd64 variables: AgentOsName: ${{ parameters.agentOs }} ASPNETCORE_TEST_LOG_MAXPATH: "200" # Keep test log file name length low enough for artifact zipping DOTNET_HOME: $(Agent.BuildDirectory)/.dotnet BuildScriptArgs: ${{ parameters.buildArgs }} BuildConfiguration: ${{ parameters.configuration }} + LC_ALL: 'en_US.UTF-8' + LANG: 'en_US.UTF-8' + LANGUAGE: 'en_US.UTF-8' TeamName: AspNetCore ${{ if and(eq(parameters.codeSign, 'true'), eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}: _SignType: real ${{ if or(ne(parameters.codeSign, 'true'), ne(variables['System.TeamProject'], 'internal'), eq(variables['Build.Reason'], 'PullRequest')) }}: _SignType: '' + ${{ if eq(parameters.runCodeQL3000, 'true') }}: + # Do not let CodeQL3000 Extension gate scan frequency. + Codeql.Cadence: 0 + # Enable CodeQL3000 unconditionally so it may be run on any branch. + Codeql.Enabled: true + Codeql.SourceRoot: src + # CodeQL3000 needs this plumbed along as a variable to enable TSA. + Codeql.TSAEnabled: ${{ eq(variables['Build.Reason'], 'Schedule') }} + # Default expects tsaoptions.json under SourceRoot. + Codeql.TSAOptionsPath: '$(Build.SourcesDirectory)/.config/tsaoptions.json' ${{ insert }}: ${{ parameters.variables }} steps: - checkout: self diff --git a/.azure/pipelines/jobs/project-ci.yml b/.azure/pipelines/jobs/project-ci.yml new file mode 100644 index 000000000..3b738c4c9 --- /dev/null +++ b/.azure/pipelines/jobs/project-ci.yml @@ -0,0 +1,71 @@ +# Description: Runs build.cmd/sh on macOS, Linux, and Windows +# Parameters: +# buildArgs: string +# Additional arguments to pass to the build.sh/cmd script. +# Note: -ci is always passed +# beforeBuild: [steps] +# Additional steps to run before build.sh/cmd +# afterBuild: [steps] +# Additional steps to run after build.sh/cmd +# variables: {} +# Azure DevOps build and environment variables +# matrix: {} +# The matrix of configurations to run. By default, it runs a Debug and Release build on all platforms +# codeSign: boolean +# This build definition is enabled for code signing. (Only applies to Windows) +# runCodeQL3000: boolean +# This build should run CodeQL3000 instead of the regular build + +parameters: + buildArgs: '' + beforeBuild: [] + afterBuild: [] + codeSign: false + variables: {} + runCodeQL3000: false + +jobs: +- ${{ if and(ne(variables['System.TeamProject'], 'public'), eq(parameters.runCodeQL3000, 'true')) }}: + - template: default-build.yml + parameters: + agentOs: Windows + matrix: ${{ parameters.matrix }} + buildArgs: ${{ parameters.buildArgs }} + beforeBuild: + - task: CodeQL3000Init@0 + displayName: CodeQL Initialize + - script: "echo ##vso[build.addbuildtag]CodeQL3000" + displayName: 'Set CI CodeQL3000 tag' + condition: ne(variables.CODEQL_DIST,'') + afterBuild: + - task: CodeQL3000Finalize@0 + displayName: CodeQL Finalize + codeSign: false + variables: ${{ parameters.variables }} + runCodeQL3000: true +- ${{ else }}: # regular build + - template: default-build.yml + parameters: + agentOs: Windows + matrix: ${{ parameters.matrix }} + buildArgs: ${{ parameters.buildArgs }} + beforeBuild: ${{ parameters.beforeBuild }} + afterBuild: ${{ parameters.afterBuild }} + codeSign: ${{ parameters.codeSign }} + variables: ${{ parameters.variables }} + - template: default-build.yml + parameters: + agentOs: macOS + matrix: ${{ parameters.matrix }} + buildArgs: ${{ parameters.buildArgs }} + beforeBuild: ${{ parameters.beforeBuild }} + afterBuild: ${{ parameters.afterBuild }} + variables: ${{ parameters.variables }} + - template: default-build.yml + parameters: + agentOs: Linux + matrix: ${{ parameters.matrix }} + buildArgs: ${{ parameters.buildArgs }} + beforeBuild: ${{ parameters.beforeBuild }} + afterBuild: ${{ parameters.afterBuild }} + variables: ${{ parameters.variables }} diff --git a/.azure/templates/project-ci.yml b/.azure/templates/project-ci.yml deleted file mode 100644 index 8902e7046..000000000 --- a/.azure/templates/project-ci.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Description: Runs build.cmd/sh on macOS, Linux, and Windows -# Parameters: -# buildArgs: string -# Additional arguments to pass to the build.sh/cmd script. -# Note: -ci is always passed -# beforeBuild: [steps] -# Additional steps to run before build.sh/cmd -# afterBuild: [steps] -# Additional steps to run after build.sh/cmd -# variables: {} -# Azure DevOps build and environment variables -# matrix: {} -# The matrix of configurations to run. By default, it runs a Debug and Release build on all platforms -# codeSign: boolean -# This build definition is enabled for code signing. (Only applies to Windows) - -parameters: - buildArgs: '' - beforeBuild: [] - afterBuild: [] - codeSign: false - variables: {} - matrix: - Release: - BuildConfiguration: Release - Debug: - BuildConfiguration: Debug - -jobs: -- template: jobs/default-build.yml - parameters: - agentOs: Windows - matrix: ${{ parameters.matrix }} - buildArgs: ${{ parameters.buildArgs }} - beforeBuild: ${{ parameters.beforeBuild }} - afterBuild: ${{ parameters.afterBuild }} - codeSign: ${{ parameters.codeSign }} - variables: ${{ parameters.variables }} -- template: jobs/default-build.yml - parameters: - agentOs: macOS - matrix: ${{ parameters.matrix }} - buildArgs: ${{ parameters.buildArgs }} - beforeBuild: ${{ parameters.beforeBuild }} - afterBuild: ${{ parameters.afterBuild }} - variables: ${{ parameters.variables }} -- template: jobs/default-build.yml - parameters: - agentOs: Linux - matrix: ${{ parameters.matrix }} - buildArgs: ${{ parameters.buildArgs }} - beforeBuild: ${{ parameters.beforeBuild }} - afterBuild: ${{ parameters.afterBuild }} - variables: ${{ parameters.variables }} diff --git a/.config/tsaoptions.json b/.config/tsaoptions.json new file mode 100644 index 000000000..0128aa272 --- /dev/null +++ b/.config/tsaoptions.json @@ -0,0 +1,12 @@ +{ + "areaPath": "DevDiv\\ASP.NET Core", + "codebaseName": "Buildtools", + "instanceUrl": "https://devdiv.visualstudio.com/", + "iterationPath": "DevDiv", + "notificationAliases": [ + "aspnetcore-build@microsoft.com" + ], + "projectName": "DEVDIV", + "repositoryName": "Buildtools", + "template": "TFSDEVDIV" +} \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..0578a0e1f --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @aspnet/build diff --git a/.gitignore b/.gitignore index 523876b6f..a03f501b2 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ node_modules .nuget/NuGet.exe project.lock.json .build +.idea/ .vs/ .vscode/ global.json diff --git a/BuildTools.sln b/BuildTools.sln index 5b92dcc49..7ef78b100 100644 --- a/BuildTools.sln +++ b/BuildTools.sln @@ -1,16 +1,15 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27121.1 -MinimumVisualStudioVersion = 15.0.26730.03 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.0.0 +MinimumVisualStudioVersion = 16.0.0.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A4F4353B-C3D2-40B0-909A-5B48A748EA76}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "files", "files", "{BF3E9C90-F129-4CE6-8F3B-F96831E4429B}" ProjectSection(SolutionItems) = preProject - .appveyor.yml = .appveyor.yml .editorconfig = .editorconfig .gitattributes = .gitattributes .gitignore = .gitignore - .travis.yml = .travis.yml build.cmd = build.cmd build.ps1 = build.ps1 build.sh = build.sh @@ -39,30 +38,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{60A938B2-D EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGetPackageVerifier.Console", "modules\NuGetPackageVerifier\console\NuGetPackageVerifier.Console.csproj", "{657AFF5E-164E-493D-8501-8026B7C20808}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiCheckBaseline.V1", "test\ApiCheckBaseline.V1\ApiCheckBaseline.V1.csproj", "{1B1731E0-4ADB-4A04-9418-FCD7F5CFB79E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiCheckBaseline.V2", "test\ApiCheckBaseline.V2\ApiCheckBaseline.V2.csproj", "{ECA89839-3332-43F3-B1B1-9C2D91B7285E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiCheck.Test", "test\ApiCheck.Test\ApiCheck.Test.csproj", "{D61A892B-D214-44AB-9652-334C4338377B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiCheck.Console", "src\ApiCheck.Console\ApiCheck.Console.csproj", "{AEFC7985-27C8-468E-8EF8-E1D589C9053F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGetPackageVerifier.Task", "modules\NuGetPackageVerifier\msbuild\NuGetPackageVerifier.Task.csproj", "{EF38C1CA-8A2E-4C8E-B478-7072C0140514}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Internal.AspNetCore.Sdk", "src\Internal.AspNetCore.Sdk\Internal.AspNetCore.Sdk.csproj", "{F0E4CF2B-29B9-432B-BF27-195996CA24FD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildTools.Tasks", "modules\BuildTools.Tasks\BuildTools.Tasks.csproj", "{6A631446-BBDD-4743-B576-7F9793B6BE45}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildTools.Tasks.Tests", "test\BuildTools.Tasks.Tests\BuildTools.Tasks.Tests.csproj", "{211858CA-6E82-4EFD-9960-8D023EEB789F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiCheck.Task", "src\ApiCheck.Task\ApiCheck.Task.csproj", "{9BE633D2-025A-4B29-A8A9-FC8F79C331AB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Internal.AspNetCore.BuildTasks", "src\Internal.AspNetCore.BuildTasks\Internal.AspNetCore.BuildTasks.csproj", "{F0E4CF2B-29B9-432B-BF27-195996CA24FD}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KoreBuild.FunctionalTests", "test\KoreBuild.FunctionalTests\KoreBuild.FunctionalTests.csproj", "{D5D1BD88-1781-4448-89DD-3E62C95D3A77}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{76ABA507-B453-43BA-BA98-FA3FDDC6DD39}" ProjectSection(SolutionItems) = preProject build\dependencies.props = build\dependencies.props - build\repo.beforecommon.props = build\repo.beforecommon.props build\repo.props = build\repo.props build\repo.targets = build\repo.targets EndProjectSection @@ -82,13 +66,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGetPackageVerifier", "NuG EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KoreBuild.Tasks.Tests", "test\KoreBuild.Tasks.Tests\KoreBuild.Tasks.Tests.csproj", "{A3A81E93-0157-406F-A43C-C163F7F781A9}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{B16B5072-3A0B-4527-8AB5-1C73A51684F7}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KoreBuild.Console", "tools\KoreBuild.Console\KoreBuild.Console.csproj", "{02F548A6-B0E9-4F09-BC03-812FC3C8F0D2}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiCheckForwardDestination", "test\ApiCheckForwardDestination\ApiCheckForwardDestination.csproj", "{605F0478-A9D2-4A8A-BB38-9D5DC132FBB5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGetPackageVerifier.Tests", "test\NuGetPackageVerifier.Tests\NuGetPackageVerifier.Tests.csproj", "{439CC7A3-F6E6-46B8-B6A0-05E22E558FC2}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Internal.AspNetCore.SiteExtension.Sdk", "src\Internal.AspNetCore.SiteExtension.Sdk\Internal.AspNetCore.SiteExtension.Sdk.csproj", "{418F99A5-5EC4-4895-B8EB-7F8BBA241DB2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildTasks.Tests", "test\BuildTasks.Tests\BuildTasks.Tests.csproj", "{917C539F-4A6A-4CA0-B6E5-D50F383718A6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -100,22 +80,6 @@ Global {657AFF5E-164E-493D-8501-8026B7C20808}.Debug|Any CPU.Build.0 = Debug|Any CPU {657AFF5E-164E-493D-8501-8026B7C20808}.Release|Any CPU.ActiveCfg = Release|Any CPU {657AFF5E-164E-493D-8501-8026B7C20808}.Release|Any CPU.Build.0 = Release|Any CPU - {1B1731E0-4ADB-4A04-9418-FCD7F5CFB79E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1B1731E0-4ADB-4A04-9418-FCD7F5CFB79E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1B1731E0-4ADB-4A04-9418-FCD7F5CFB79E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1B1731E0-4ADB-4A04-9418-FCD7F5CFB79E}.Release|Any CPU.Build.0 = Release|Any CPU - {ECA89839-3332-43F3-B1B1-9C2D91B7285E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ECA89839-3332-43F3-B1B1-9C2D91B7285E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ECA89839-3332-43F3-B1B1-9C2D91B7285E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ECA89839-3332-43F3-B1B1-9C2D91B7285E}.Release|Any CPU.Build.0 = Release|Any CPU - {D61A892B-D214-44AB-9652-334C4338377B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D61A892B-D214-44AB-9652-334C4338377B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D61A892B-D214-44AB-9652-334C4338377B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D61A892B-D214-44AB-9652-334C4338377B}.Release|Any CPU.Build.0 = Release|Any CPU - {AEFC7985-27C8-468E-8EF8-E1D589C9053F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AEFC7985-27C8-468E-8EF8-E1D589C9053F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AEFC7985-27C8-468E-8EF8-E1D589C9053F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AEFC7985-27C8-468E-8EF8-E1D589C9053F}.Release|Any CPU.Build.0 = Release|Any CPU {EF38C1CA-8A2E-4C8E-B478-7072C0140514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EF38C1CA-8A2E-4C8E-B478-7072C0140514}.Debug|Any CPU.Build.0 = Debug|Any CPU {EF38C1CA-8A2E-4C8E-B478-7072C0140514}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -124,18 +88,6 @@ Global {F0E4CF2B-29B9-432B-BF27-195996CA24FD}.Debug|Any CPU.Build.0 = Debug|Any CPU {F0E4CF2B-29B9-432B-BF27-195996CA24FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {F0E4CF2B-29B9-432B-BF27-195996CA24FD}.Release|Any CPU.Build.0 = Release|Any CPU - {6A631446-BBDD-4743-B576-7F9793B6BE45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6A631446-BBDD-4743-B576-7F9793B6BE45}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6A631446-BBDD-4743-B576-7F9793B6BE45}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6A631446-BBDD-4743-B576-7F9793B6BE45}.Release|Any CPU.Build.0 = Release|Any CPU - {211858CA-6E82-4EFD-9960-8D023EEB789F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {211858CA-6E82-4EFD-9960-8D023EEB789F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {211858CA-6E82-4EFD-9960-8D023EEB789F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {211858CA-6E82-4EFD-9960-8D023EEB789F}.Release|Any CPU.Build.0 = Release|Any CPU - {9BE633D2-025A-4B29-A8A9-FC8F79C331AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9BE633D2-025A-4B29-A8A9-FC8F79C331AB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9BE633D2-025A-4B29-A8A9-FC8F79C331AB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9BE633D2-025A-4B29-A8A9-FC8F79C331AB}.Release|Any CPU.Build.0 = Release|Any CPU {D5D1BD88-1781-4448-89DD-3E62C95D3A77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D5D1BD88-1781-4448-89DD-3E62C95D3A77}.Debug|Any CPU.Build.0 = Debug|Any CPU {D5D1BD88-1781-4448-89DD-3E62C95D3A77}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -148,40 +100,28 @@ Global {A3A81E93-0157-406F-A43C-C163F7F781A9}.Debug|Any CPU.Build.0 = Debug|Any CPU {A3A81E93-0157-406F-A43C-C163F7F781A9}.Release|Any CPU.ActiveCfg = Release|Any CPU {A3A81E93-0157-406F-A43C-C163F7F781A9}.Release|Any CPU.Build.0 = Release|Any CPU - {02F548A6-B0E9-4F09-BC03-812FC3C8F0D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {02F548A6-B0E9-4F09-BC03-812FC3C8F0D2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {02F548A6-B0E9-4F09-BC03-812FC3C8F0D2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {02F548A6-B0E9-4F09-BC03-812FC3C8F0D2}.Release|Any CPU.Build.0 = Release|Any CPU - {605F0478-A9D2-4A8A-BB38-9D5DC132FBB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {605F0478-A9D2-4A8A-BB38-9D5DC132FBB5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {605F0478-A9D2-4A8A-BB38-9D5DC132FBB5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {605F0478-A9D2-4A8A-BB38-9D5DC132FBB5}.Release|Any CPU.Build.0 = Release|Any CPU - {418F99A5-5EC4-4895-B8EB-7F8BBA241DB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {418F99A5-5EC4-4895-B8EB-7F8BBA241DB2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {418F99A5-5EC4-4895-B8EB-7F8BBA241DB2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {418F99A5-5EC4-4895-B8EB-7F8BBA241DB2}.Release|Any CPU.Build.0 = Release|Any CPU + {439CC7A3-F6E6-46B8-B6A0-05E22E558FC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {439CC7A3-F6E6-46B8-B6A0-05E22E558FC2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {439CC7A3-F6E6-46B8-B6A0-05E22E558FC2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {439CC7A3-F6E6-46B8-B6A0-05E22E558FC2}.Release|Any CPU.Build.0 = Release|Any CPU + {917C539F-4A6A-4CA0-B6E5-D50F383718A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {917C539F-4A6A-4CA0-B6E5-D50F383718A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {917C539F-4A6A-4CA0-B6E5-D50F383718A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {917C539F-4A6A-4CA0-B6E5-D50F383718A6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {657AFF5E-164E-493D-8501-8026B7C20808} = {C0E43505-F8EB-4B7F-B84D-5961F9763945} - {1B1731E0-4ADB-4A04-9418-FCD7F5CFB79E} = {60A938B2-D95A-403C-AA7A-3683AD64DFA0} - {ECA89839-3332-43F3-B1B1-9C2D91B7285E} = {60A938B2-D95A-403C-AA7A-3683AD64DFA0} - {D61A892B-D214-44AB-9652-334C4338377B} = {60A938B2-D95A-403C-AA7A-3683AD64DFA0} - {AEFC7985-27C8-468E-8EF8-E1D589C9053F} = {A4F4353B-C3D2-40B0-909A-5B48A748EA76} {EF38C1CA-8A2E-4C8E-B478-7072C0140514} = {C0E43505-F8EB-4B7F-B84D-5961F9763945} {F0E4CF2B-29B9-432B-BF27-195996CA24FD} = {A4F4353B-C3D2-40B0-909A-5B48A748EA76} - {6A631446-BBDD-4743-B576-7F9793B6BE45} = {BD3545FB-5520-43DF-B4F9-83BEA3A38ECA} - {211858CA-6E82-4EFD-9960-8D023EEB789F} = {60A938B2-D95A-403C-AA7A-3683AD64DFA0} - {9BE633D2-025A-4B29-A8A9-FC8F79C331AB} = {A4F4353B-C3D2-40B0-909A-5B48A748EA76} {D5D1BD88-1781-4448-89DD-3E62C95D3A77} = {60A938B2-D95A-403C-AA7A-3683AD64DFA0} {020ED083-4076-4711-A52B-2F89EA884F9B} = {BD3545FB-5520-43DF-B4F9-83BEA3A38ECA} {C0E43505-F8EB-4B7F-B84D-5961F9763945} = {BD3545FB-5520-43DF-B4F9-83BEA3A38ECA} {A3A81E93-0157-406F-A43C-C163F7F781A9} = {60A938B2-D95A-403C-AA7A-3683AD64DFA0} - {02F548A6-B0E9-4F09-BC03-812FC3C8F0D2} = {B16B5072-3A0B-4527-8AB5-1C73A51684F7} - {605F0478-A9D2-4A8A-BB38-9D5DC132FBB5} = {60A938B2-D95A-403C-AA7A-3683AD64DFA0} - {418F99A5-5EC4-4895-B8EB-7F8BBA241DB2} = {A4F4353B-C3D2-40B0-909A-5B48A748EA76} + {439CC7A3-F6E6-46B8-B6A0-05E22E558FC2} = {60A938B2-D95A-403C-AA7A-3683AD64DFA0} + {917C539F-4A6A-4CA0-B6E5-D50F383718A6} = {60A938B2-D95A-403C-AA7A-3683AD64DFA0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1B8809C8-A6C3-4761-BC91-B12841F49AE1} diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md new file mode 100644 index 000000000..775f221c9 --- /dev/null +++ b/CODE-OF-CONDUCT.md @@ -0,0 +1,6 @@ +# Code of Conduct + +This project has adopted the code of conduct defined by the Contributor Covenant +to clarify expected behavior in our community. + +For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac2d28d2f..3924182cb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ Contributing ====== -Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/AspNetCore/blob/master/CONTRIBUTING.md) in the AspNetCore repo. +Information on contributing to this repo is in the [Contributing Guide](https://github.com/dotnet/aspnetcore/blob/main/CONTRIBUTING.md) in the AspNetCore repo. diff --git a/Directory.Build.props b/Directory.Build.props index 5773b98f0..92e5bbed9 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,30 +4,21 @@ - - <_AspNetToolsSdkPath>$(MSBuildThisFileDirectory)src\Internal.AspNetCore.Sdk - $(_AspNetToolsSdkPath)\build\Internal.AspNetCore.Sdk.targets - $(_AspNetToolsSdkPath)\buildMultiTargeting\Internal.AspNetCore.Sdk.targets - false - false - false - false $(NoWarn);NU5105 false true true - - https://github.com/aspnet/BuildTools git - $(MSBuildThisFileDirectory) + $(MSBuildThisFileDirectory) + diff --git a/README.md b/README.md index e13cd1d29..9b6dfd484 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ -Build Tools -=========== +Build Tools [Obsolete] +====================== + +:warning: **The tools in this repo are obsolete.** You should convert to using Arcade tools. +See . + Utilities used in the build system for projects that are used with ASP.NET Core and Entity Framework Core. @@ -13,11 +17,13 @@ See [docs/README.md](./docs/README.md). Channel | Latest Build ---------------|:--------------- -master | ![badge][master-badge] +main | ![badge][main-badge] +release/2.2 | ![badge][rel-2.2-badge] release/2.1 | ![badge][rel-2.1-badge] release/2.0 | ![badge][rel-2.0-badge] -[master-badge]: https://aspnetcore.blob.core.windows.net/buildtools/korebuild/channels/master/badge.svg +[main-badge]: https://aspnetcore.blob.core.windows.net/buildtools/korebuild/channels/main/badge.svg +[rel-2.2-badge]: https://aspnetcore.blob.core.windows.net/buildtools/korebuild/channels/release/2.2/badge.svg [rel-2.1-badge]: https://aspnetcore.blob.core.windows.net/buildtools/korebuild/channels/release/2.1/badge.svg [rel-2.0-badge]: https://aspnetcore.blob.core.windows.net/buildtools/korebuild/channels/release/2.0/badge.svg diff --git a/build/dependencies.props b/build/dependencies.props index b0683ba4d..c4c3b56d4 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -3,34 +3,35 @@ 1.5.1 0.3.0 2.0.0 - 1.0.0-beta.19119.1 - 1.0.0-beta.19119.1 + 1.0.0-beta.19167.10 + 1.0.0-beta.19167.10 1.0.0-preview.1 15.9.0 0.10.0-beta6 4.7.99 - 10.0.1 - 4.3.0 - 4.3.0 + 13.0.1 + 6.0.6 + 6.0.5 + 4.3.4 2.2.7 - 2.3.1 - 2.3.1 + 2.4.1 + 2.4.1 - 15.8.166 + 16.0.0-preview.383 $(MicrosoftBuildPackageVersion) $(MicrosoftBuildPackageVersion) $(MicrosoftBuildPackageVersion) 9.0.1 - 4.7.0-netcore.2.1.preview2.5133 + 5.0.0-preview1.5663 diff --git a/build/repo.props b/build/repo.props index 603d5ec41..c428e476d 100644 --- a/build/repo.props +++ b/build/repo.props @@ -3,13 +3,8 @@ true - - - - - diff --git a/build/repo.targets b/build/repo.targets index 4c552b0b7..929eb1653 100644 --- a/build/repo.targets +++ b/build/repo.targets @@ -1,6 +1,7 @@ + <_NuGetExeDownloadPath>$(IntermediateDir)nuget.exe <_KoreBuildIntermediateDir>$(IntermediateDir)korebuild\ <_KoreBuildIntermediateDir>$([MSBuild]::NormalizeDirectory($(_KoreBuildIntermediateDir))) <_KoreBuildOutDir>$(ArtifactsDir)korebuild\artifacts\$(Version)\ @@ -10,7 +11,7 @@ $(_ChannelOutDir)badge.svg $(_ChannelOutDir)latest.txt $(ArtifactsDir)korebuild\channel.txt - $(PrepareDependsOn);SetTeamCityBuildNumberToVersion + $(PrepareDependsOn);DownloadNuGetExe @@ -31,58 +32,36 @@ - - - - - - - - - $(BuildProperties);RepositoryCommit=$(RepositoryCommit) - $(BuildProperties);RepositoryBranch=$(RepositoryBranch) - + + - + - - - - - <_ToolsProjects Include="$(RepositoryRoot)tools\KoreBuild.Console\KoreBuild.Console.csproj"> - PublishDir=$(_KoreBuildIntermediateDir)\tools\%(Identity)\ - - - - - - - + - + + + - <_ModuleProjects Include="$(RepositoryRoot)modules\%(KoreBuildModule.Identity)\%(Identity).*proj"> + <_ModuleProjects Include="$(RepoRoot)modules\%(KoreBuildModule.Identity)\%(Identity).*proj"> Version=$(Version);PublishDir=$(_KoreBuildIntermediateDir)modules\%(Identity)\ @@ -96,7 +75,7 @@ - + diff --git a/build/sdk.props b/build/sdk.props new file mode 100644 index 000000000..c98a76a23 --- /dev/null +++ b/build/sdk.props @@ -0,0 +1,3 @@ + + + diff --git a/build/sdk.targets b/build/sdk.targets new file mode 100644 index 000000000..3695d4330 --- /dev/null +++ b/build/sdk.targets @@ -0,0 +1,3 @@ + + + diff --git a/build/sources.props b/build/sources.props index c648b2764..34b3e2f43 100644 --- a/build/sources.props +++ b/build/sources.props @@ -6,7 +6,8 @@ $(RestoreSources); https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json; - https://api.nuget.org/v3/index.json; + https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json; + https://dnceng.pkgs.visualstudio.com/public/_packaging/nuget-build/nuget/v3/index.json; diff --git a/modules/BuildTools.Tasks/GenerateSvgBadge.cs b/build/tasks/GenerateSvgBadge.cs similarity index 92% rename from modules/BuildTools.Tasks/GenerateSvgBadge.cs rename to build/tasks/GenerateSvgBadge.cs index 14a45afbd..a755ed756 100644 --- a/modules/BuildTools.Tasks/GenerateSvgBadge.cs +++ b/build/tasks/GenerateSvgBadge.cs @@ -12,15 +12,8 @@ namespace Microsoft.AspNetCore.BuildTools /// /// Generates an SVG file badge that can be embedded into a markdown page /// -#if SDK - public class Sdk_GenerateSvgBadge : Microsoft.Build.Utilities.Task - { -#elif BuildTools public class GenerateSvgBadge : Microsoft.Build.Utilities.Task { -#else -#error This must be built either for an SDK or for BuildTools -#endif private static readonly string Template = @" @@ -76,11 +69,8 @@ public override bool Execute() Log.LogError("Color cannot be an empty string"); return false; } -#if SDK - var generator = new Sdk_GenerateFileFromTemplate() -#else + var generator = new GenerateFileFromTemplate() -#endif { BuildEngine = BuildEngine, OutputPath = OutputPath, diff --git a/build/tasks/RepoTasks.csproj b/build/tasks/RepoTasks.csproj index f64666705..d6c2750ea 100644 --- a/build/tasks/RepoTasks.csproj +++ b/build/tasks/RepoTasks.csproj @@ -1,25 +1,19 @@ - + - netcoreapp2.1 + netcoreapp3.1 net46 $(DefineConstants);BuildTools $(NoWarn);NU1603 + RepoTasks - - - - - - - - - + + + - - + diff --git a/modules/BuildTools.Tasks/ZipArchive.cs b/build/tasks/ZipArchive.cs similarity index 96% rename from modules/BuildTools.Tasks/ZipArchive.cs rename to build/tasks/ZipArchive.cs index cb25d5c8d..54102f60c 100644 --- a/modules/BuildTools.Tasks/ZipArchive.cs +++ b/build/tasks/ZipArchive.cs @@ -12,13 +12,7 @@ namespace Microsoft.AspNetCore.BuildTools { -#if SDK - public class Sdk_ZipArchive : Task -#elif BuildTools public class ZipArchive : Task -#else -#error This must be built either for an SDK or for BuildTools -#endif { /// /// The path where the zip file should be created. @@ -89,7 +83,7 @@ public override bool Execute() var entry = zip.CreateEntryFromFile(file.ItemSpec, entryName); #if NET46 -#elif NETCOREAPP2_1 || NETSTANDARD2_0 +#elif NETCOREAPP3_1 || NETSTANDARD2_0 if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // This isn't required when creating a zip on Windows. unzip will check which diff --git a/docs/KoreBuild.md b/docs/KoreBuild.md index 9d31e94b0..cf7568ab5 100644 --- a/docs/KoreBuild.md +++ b/docs/KoreBuild.md @@ -13,12 +13,8 @@ Previously repositories were runable in only one way, by doing `.\build.cmd`. Bu Command | Purpose | Example ----------------------|------------------------------------------------------------------|---------- install-tools | Installs dotnet, CLI and Shared runtimes. | .\run.ps1 install-tools -docker-build | Runs the build inside docker. | .\run.ps1 docker-build {jessie\|winservercore} /t:SomeTarget /p:Parameters default-build | Runs install-tools followed by msbuild (like build.cmd used to). | .\run.ps1 default-build /t:SomeTarget /p:Parameters msbuild | Runs the build normally. | .\run.ps1 msbuild /t:SomeTarget /p:Parameters -upgrade deps | Upgrade the dependencies.props of this project. | .\run.ps1 upgrade deps -generate deps | Generate a dependencies.props for this project. | .\run.ps1 generate deps -generate api-baseline | Re-generate baselines for all projects. | .\run.ps1 generate api-baseline ### KoreBuild properties @@ -26,10 +22,7 @@ Below is a list of some of the properties that KoreBuild recognizes which you mi Property | Purpose ------------------|-------- -GenerateBaselines | Toggles the (re-)generation of baselines for all projects (defaults to true). -ReplaceBaselines | If 'true' baseline.\*.json and breakingchanges.\*.json files are deleted, and baseline.\*.json files are recreated from the current state. VSTestBlame | Turns on the '--blame' option of vstest, useful for diagnosing test host failures. -EnableApiCheck | If 'false' no targets related to ApiCheck are run. ### KoreBuild config @@ -41,10 +34,10 @@ Example: { // add this for editor auto-completion :) - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/main/tools/korebuild.schema.json", // specifies the channel used to update KoreBuild to new versions when you attempt to upgrade KoreBuild - "channel": "dev", + "channel": "main", "toolsets": { // All toolsets listed in this section are treated as required toolsets diff --git a/docs/Logging.md b/docs/Logging.md index 580ad35b6..c81d55e14 100644 --- a/docs/Logging.md +++ b/docs/Logging.md @@ -1,20 +1,10 @@ Logging ------- -KoreBuild produces log files to $(RepositoryRoot)/artifacts/logs. The following log formats can be used: +KoreBuild produces log files to $(RepoRoot)/artifacts/logs. The following log formats can be used: ## Binary Logger Using `build.cmd -Verbose` will produce a binary log file to artifacts/logs/msbuild.binlog. See for details. - -## TeamCity Logger - -KoreBuild can produce log messages for TeamCity by using . - -To configure this, - -1. Download the logger from JetBrains. https://github.com/JetBrains/TeamCity.MSBuild.Logger#download -2. Install this on CI agents. -3. Set the environment variable `KOREBUILD_TEAMCITY_LOGGER` to the file path of TeamCity.MSBuild.Logger.dll on CI agents. diff --git a/docs/PackageReferenceManagement.md b/docs/PackageReferenceManagement.md deleted file mode 100644 index 2c5203df7..000000000 --- a/docs/PackageReferenceManagement.md +++ /dev/null @@ -1,87 +0,0 @@ -PackageReference management ---------------------------- - -## Usage - -KoreBuild includes tools to help you automatically update your `dependencies.props` files. - -#### Generating a dependencies.props file - -On an existing project, you can execute the following command: -``` -run.ps1 generate deps -``` - -This will update csproj files and overwrite your build/dependencies.props file with variables. - -#### Updating dependencies.props - -KoreBuild can help you automatically update the `build/dependencies.props` file in your repo by using a lineup package. - -On command line, you can then execute -``` -run.ps1 upgrade deps -``` - -This command requires you set a few properties so the command can download a remote package and use that as the source -of version information. Most aspnetcore repos will set this in `build/repo.props` - -```xml - - Internal.AspNetCore.Universe.Lineup - - 2.1.0-* - https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json - -``` - -The lineup package itself contains a file that lists all version, and is itself also packaged under `build/dependencies.props`. The `upgrade deps` command will update any matching variables from the lineup package in the local copy of build/dependencies.props. - -## Restrictions on PackageReference usage - -To manage the complexity of keeping PackageReference versions consistent within a repo and between multiple repos, KoreBuild will enforce the following patterns for using PackageReference. - -#### 1. build/dependencies.props - -Each repository should have this file, and it should look like this. - -```xml - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - 10.0.1 - 15.3.0 - 4.7.49 - 2.3.0 - - - - 10.0.1 - - -``` - -The `` section is for variables which should be automatically updated. - -The `` section is for variables which upgrade automation should not touch. - -### 2. PackageReference's should use variables to set versions - -All .csproj files should set the version of a package reference like this: - -```xml - - - -``` - -#### Opt-out of restrictions - -To opt-out of these restrictions, projects should add this to the `build/repo.props` file in their repository. -```xml - - true - -``` diff --git a/docs/Signing.md b/docs/Signing.md index f5e14c4d6..68c9ccfdd 100644 --- a/docs/Signing.md +++ b/docs/Signing.md @@ -137,4 +137,4 @@ For example, content/*.js;Microsoft.DotNet.Web.Spa.ProjectTemplates.*.nupkg; Exclude JavaScript files from codesigning in project templates ``` -See https://github.com/dotnet/arcade/tree/master/src/SignCheck for more details on SignCheck. +See https://github.com/dotnet/arcade/tree/main/src/SignCheck for more details on SignCheck. diff --git a/files/KoreBuild/KoreBuild.Common.props b/files/KoreBuild/KoreBuild.Common.props index 10729698c..7c3efef4e 100644 --- a/files/KoreBuild/KoreBuild.Common.props +++ b/files/KoreBuild/KoreBuild.Common.props @@ -33,17 +33,19 @@ Default layout and configuration. Release Debug $(BuildProperties);Configuration=$(Configuration) - $(MSBuildStartupDirectory) - $([MSBuild]::NormalizeDirectory('$(RepositoryRoot)')) - $([MSBuild]::NormalizeDirectory('$(RepositoryRoot)'))artifacts\ + $(MSBuildStartupDirectory) + $([MSBuild]::NormalizeDirectory('$(RepoRoot)')) + + $(RepoRoot) + $([MSBuild]::NormalizeDirectory('$(RepoRoot)'))artifacts\ $(ArtifactsDir)build\ - $(ArtifactsDir)logs\ - $([MSBuild]::NormalizeDirectory('$(RepositoryRoot)'))obj\ + $(ArtifactsDir)logs\ + $([MSBuild]::NormalizeDirectory('$(RepoRoot)'))obj\ $(NUGET_PACKAGES) $(USERPROFILE)\.nuget\packages\ $(HOME)\.nuget\packages\ - $(RepositoryRoot)\.nuget\packages\ + $(RepoRoot)\.nuget\packages\ $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)')) @@ -69,10 +71,6 @@ Default layout and configuration. This environment variable is automatically set by VSTS. --> $(BUILD_BUILDNUMBER) - $(BUILD_SOURCEBRANCH) - $(RepositoryBranch.Substring(11)) - $(RepositoryBranch.Substring(10)) - $(BUILD_SOURCEVERSION) @@ -93,8 +91,6 @@ Default layout and configuration. $(BuildProperties);BuildNumber=$(BuildNumber) - $(BuildProperties);RepositoryCommit=$(RepositoryCommit) - $(BuildProperties);RepositoryBranch=$(RepositoryBranch) $(BuildProperties);GenerateFullPaths=true diff --git a/files/KoreBuild/KoreBuild.Common.targets b/files/KoreBuild/KoreBuild.Common.targets index 27255d0fe..56ec37890 100644 --- a/files/KoreBuild/KoreBuild.Common.targets +++ b/files/KoreBuild/KoreBuild.Common.targets @@ -19,7 +19,7 @@ after all other property imports. $(Version) $(BuildProperties);RepoVersion=$(Version);RepoPackageVersion=$(PackageVersion) - $(BuildProperties);VerifyVersion=false + $(BuildProperties);VerifyVersion=false - + - - - + + + - + diff --git a/files/KoreBuild/KoreBuild.sh b/files/KoreBuild/KoreBuild.sh index ceaefa0c0..b3fbfc8f4 100755 --- a/files/KoreBuild/KoreBuild.sh +++ b/files/KoreBuild/KoreBuild.sh @@ -72,15 +72,8 @@ invoke_korebuild_command(){ elif [ "$command" = "install-tools" ]; then __install_tools "$tools_source" "$dot_net_home" else - __ensure_dotnet - - kore_build_console_dll="$__korebuild_dir/tools/KoreBuild.Console.dll" - - __exec dotnet "$kore_build_console_dll" "$command" \ - --tools-source "$tools_source" \ - --dotnet-home "$dot_net_home" \ - --repo-path "$repo_path" \ - "$@" + __error "Unrecognized command '$command'" + exit 1 fi } @@ -129,24 +122,37 @@ __install_tools() { # Set environment variables export PATH="$install_dir:$PATH" - - # This is a workaround for https://github.com/Microsoft/msbuild/issues/2914. - # Currently, the only way to configure the NuGetSdkResolver is with NuGet.config, which is not generally used in aspnet org projects. - # This project is restored so that it pre-populates the NuGet cache with SDK packages. - local restorerfile="$__korebuild_dir/modules/BundledPackages/BundledPackageRestorer.csproj" - local restorerfilelock="$NUGET_PACKAGES/internal.aspnetcore.sdk/$(__get_korebuild_version)/korebuild.sentinel" - if [[ -e "$restorerfile" ]] && [[ ! -e "$restorerfilelock" ]]; then - mkdir -p "$(dirname $restorerfilelock)" - touch "$restorerfilelock" - __exec dotnet msbuild -t:restore -v:q "$restorerfile" - fi - # end workaround } __show_version_info() { MAGENTA="\033[0;95m" + YELLOW="\033[0;33m" RESET="\033[0m" + if [ -z "${TF_BUILD:-}" ]; then + echo "##vso[task.logissue type=warning] KoreBuild has been deprecated. You should use Arcade instead now. https://github.com/dotnet/arcade" + fi + + echo -e "" + echo -e "" + echo -e "" + echo -e "${YELLOW}*****************************************${RESET}" + echo -e "${YELLOW}*****************************************${RESET}" + echo -e "${YELLOW}** **${RESET}" + echo -e "${YELLOW}** WARNING! **${RESET}" + echo -e "${YELLOW}** **${RESET}" + echo -e "${YELLOW}** KoreBuild has been deprecated. **${RESET}" + echo -e "${YELLOW}** You should use Arcade instead now. **${RESET}" + echo -e "${YELLOW}** https://github.com/dotnet/arcade **${RESET}" + echo -e "${YELLOW}** **${RESET}" + echo -e "${YELLOW}** WARNING! **${RESET}" + echo -e "${YELLOW}** **${RESET}" + echo -e "${YELLOW}*****************************************${RESET}" + echo -e "${YELLOW}*****************************************${RESET}" + echo -e "" + echo -e "" + echo -e "" + __korebuild_version="$(__get_korebuild_version)" if [[ "$__korebuild_version" != '' ]]; then echo -e "${MAGENTA}Using KoreBuild ${__korebuild_version}${RESET}" diff --git a/files/KoreBuild/Project.Inspection.targets b/files/KoreBuild/Project.Inspection.targets index 2945b5294..b88c67084 100644 --- a/files/KoreBuild/Project.Inspection.targets +++ b/files/KoreBuild/Project.Inspection.targets @@ -11,11 +11,15 @@ $(PackageOutputPath)$(PackageId).$(NormalizedPackageVersion).nupkg $(PackageOutputPath)$(PackageId).$(NormalizedPackageVersion).symbols.nupkg + + <_ReferencesInternalAspNetCoreSdk Condition="'$(_ReferencesInternalAspNetCoreSdk)' == ''">@(PackageReference->AnyHaveMetadataValue('Identity', 'Internal.AspNetCore.Sdk')) + + <_ReferencesInternalAspNetCoreSdk Condition="'$(_ReferencesInternalAspNetCoreSdk)' == ''">false + - <_ReferencesInternalAspNetCoreSdk Condition="'$(_ReferencesInternalAspNetCoreSdk)' == ''">@(PackageReference->AnyHaveMetadataValue('Identity', 'Internal.AspNetCore.Sdk')) true true @@ -37,6 +41,7 @@ $([MSBuild]::Escape($(TargetFrameworks))) $(PackageType) $(RepositoryRoot) + $(RepoRoot) $(RepositoryUrl) $(PackageArtifactCategory) $(PackageSigningCertName) @@ -54,14 +59,18 @@ $(IncludeSource) $(PackageType) $(RepositoryRoot) + $(RepoRoot) $(RepositoryUrl) $(PackageArtifactCategory) $(PackageSigningCertName) - true + true false true + + + true $(FullPackageOutputPath) @@ -72,7 +81,7 @@ $(FullPackageOutputPath) - + true $(SymbolsPackageOutputPath) diff --git a/files/KoreBuild/config/sdk.version b/files/KoreBuild/config/sdk.version index 63673c7e7..6a0741321 100644 --- a/files/KoreBuild/config/sdk.version +++ b/files/KoreBuild/config/sdk.version @@ -1 +1 @@ -2.1.506 +3.1.416 diff --git a/files/KoreBuild/modules/benchmarks/module.targets b/files/KoreBuild/modules/benchmarks/module.targets index 45abe7616..e38a57a2e 100644 --- a/files/KoreBuild/modules/benchmarks/module.targets +++ b/files/KoreBuild/modules/benchmarks/module.targets @@ -30,10 +30,10 @@ Runs a quick validation on all benchmark projects. Importance="High" Condition="'@(BenchmarkAssembly)' != ''" /> - - + + diff --git a/files/KoreBuild/modules/projectbuild/module.targets b/files/KoreBuild/modules/projectbuild/module.targets index c57ac2331..15c23d7e3 100644 --- a/files/KoreBuild/modules/projectbuild/module.targets +++ b/files/KoreBuild/modules/projectbuild/module.targets @@ -11,7 +11,7 @@ FYI: targets, properties, and items that begin with an underscore are meant to b - + @@ -56,7 +56,7 @@ Executes /t:{Target} on all projects - + @@ -75,6 +75,18 @@ Executes /t:{Target} on all projects ItemName="_ProjectToRestoreWithNuGet" /> + + + + <_ProjectToRestoreWithNuGetList>@(_ProjectToRestoreWithNuGet->'%(FullPath)') @@ -93,6 +105,15 @@ Executes /t:{Target} on all projects Properties="$(BuildProperties);__BuildTarget=Restore" RemoveProperties="$(_BuildPropertiesToRemove);Platform" BuildInParallel="%(_ProjectToRestoreDirectly.RestoreInParallel)" /> + + + + diff --git a/files/KoreBuild/modules/sharedsources/module.props b/files/KoreBuild/modules/sharedsources/module.props index a31ab89b3..207c020f7 100644 --- a/files/KoreBuild/modules/sharedsources/module.props +++ b/files/KoreBuild/modules/sharedsources/module.props @@ -1,6 +1,6 @@ - $(RepositoryRoot)shared/ + $(RepoRoot)shared/ diff --git a/files/KoreBuild/modules/sharedsources/module.targets b/files/KoreBuild/modules/sharedsources/module.targets index a7a679719..61203e8c6 100644 --- a/files/KoreBuild/modules/sharedsources/module.targets +++ b/files/KoreBuild/modules/sharedsources/module.targets @@ -3,7 +3,7 @@ Target: PackSharedSources Creates a content files package for all each directory in -that matches "$(RepositoryRoot)/shared/*.Sources". +that matches "$(RepoRoot)/shared/*.Sources". ################################################################### --> @@ -40,6 +40,7 @@ that matches "$(RepositoryRoot)/shared/*.Sources". <_SharedSourcesPackageProperties> RepositoryRoot=$(RepositoryRoot); + RepoRoot=$(RepoRoot); ImportDirectoryBuildProps=false; <_SharedSourcesPackageProperties Condition=" '$(OverridePackageOutputPath)' != 'false' "> diff --git a/files/KoreBuild/modules/sharedsources/sharedsources.csproj b/files/KoreBuild/modules/sharedsources/sharedsources.csproj index 04fb6f381..cca4e3e35 100644 --- a/files/KoreBuild/modules/sharedsources/sharedsources.csproj +++ b/files/KoreBuild/modules/sharedsources/sharedsources.csproj @@ -13,28 +13,29 @@ - + - + - + true true - $(RepositoryRoot)artifacts\build + $(RepoRoot)artifacts\build netstandard1.0 false $(ProjectDirName) $(PackageId) false + false contentFiles true $(DefaultExcludeItems);$(BaseOutputPath);$(BaseIntermediateOutputPath); @@ -77,6 +78,7 @@ $(NormalizedPackageVersion) $(TargetFramework) $(RepositoryRoot) + $(RepoRoot) $(RepositoryUrl) $(PackageArtifactCategory) true diff --git a/files/KoreBuild/modules/solutionbuild/module.targets b/files/KoreBuild/modules/solutionbuild/module.targets index 1f08e1f3b..1a14e38d5 100644 --- a/files/KoreBuild/modules/solutionbuild/module.targets +++ b/files/KoreBuild/modules/solutionbuild/module.targets @@ -9,14 +9,14 @@ FYI: targets, properties, and items that begin with an underscore are meant to b - - + + - <_FunctionalTests Include="$(RepositoryRoot)test\*\*FunctionalTest*.csproj" Exclude="@(ExcludeFromTest)" /> - + <_FunctionalTests Include="$(RepoRoot)test\*\*FunctionalTest*.csproj" Exclude="@(ExcludeFromTest)" /> + - + @@ -59,7 +59,7 @@ Executes /t:{Target} on all solutions - + diff --git a/files/KoreBuild/modules/vstest/module.targets b/files/KoreBuild/modules/vstest/module.targets index 9d76bb0a6..847475372 100644 --- a/files/KoreBuild/modules/vstest/module.targets +++ b/files/KoreBuild/modules/vstest/module.targets @@ -75,10 +75,10 @@ Runs the VSTest on all projects in the ProjectToBuild itemgroup. - <_TestGroups Include="@(_ProjectToTestDirectly)"> + <_TestGroups Include="%(_ProjectToTestDirectly.Identity)"> Test true - $(BuildProperties) + %(_ProjectToTestDirectly.AdditionalProperties);$(BuildProperties) @@ -92,9 +92,14 @@ Runs the VSTest on all projects in the ProjectToBuild itemgroup. - $(LogOutputDir)$(TestGroupName)-$(TargetFramework)-$(BuildNumber).trx + $(LogOutputDir)$(TestGroupName)-$(TargetFramework)-$(BuildNumber) + $(TrxFileWithoutExtension).trx + $(TrxFileWithoutExtension).flaky.trx + $(TrxFileWithoutExtension)*.trx trx;LogFileName=$(TrxFile) - $(LogOutputDir)$(TestGroupName)-$(TargetFramework)-$(BuildNumber).diag + $(LogOutputDir)$(TestGroupName)-$(TargetFramework)-$(BuildNumber) + $(VSTestDiagFileBase).diag + $(VSTestDiagFileBase).flaky.diag @@ -109,6 +114,18 @@ Runs the VSTest on all projects in the ProjectToBuild itemgroup. %(TestAssemblies.RootDir)%(TestAssemblies.Directory) + + <_DefaultNonFlakyTestFilterExpression>Flaky:All!=true + <_DefaultNonFlakyTestFilterExpression Condition="'$(AGENT_OS)' != ''">$(_DefaultNonFlakyTestFilterExpression)&Flaky:AzP:All!=true&Flaky:AzP:OS:$(AGENT_OS)!=true + <_DefaultFlakyTestFilterExpression>Flaky:All=true + <_DefaultFlakyTestFilterExpression Condition="'$(AGENT_OS)' != ''">$(_DefaultFlakyTestFilterExpression)|Flaky:AzP:All=true|Flaky:AzP:OS:$(AGENT_OS)=true + + $(_DefaultFlakyTestFilterExpression) + $(_DefaultNonFlakyTestFilterExpression) + + + $(NonFlakyTestFilterExpression) + $(FlakyTestFilterExpression) @@ -119,20 +136,25 @@ Runs the VSTest on all projects in the ProjectToBuild itemgroup. - + + - + - + + + + <_TrxFiles Include="$(TrxFileWildcard)" /> + - + Condition="'$(TEAMCITY_VERSION)' != '' AND Exists('%(_TrxFiles.FullPath)')" /> diff --git a/files/KoreBuild/msbuild/KoreBuild.RepoTasks.Sdk/Sdk/Sdk.props b/files/KoreBuild/msbuild/KoreBuild.RepoTasks.Sdk/Sdk/Sdk.props index 6f6db6d81..933bc4bff 100644 --- a/files/KoreBuild/msbuild/KoreBuild.RepoTasks.Sdk/Sdk/Sdk.props +++ b/files/KoreBuild/msbuild/KoreBuild.RepoTasks.Sdk/Sdk/Sdk.props @@ -5,7 +5,7 @@ true true - + library - - - Resx - - - - - - diff --git a/modules/BuildTools.Tasks/Properties/InternalsVisibleTo.cs b/modules/BuildTools.Tasks/Properties/InternalsVisibleTo.cs deleted file mode 100644 index b11b4fa2c..000000000 --- a/modules/BuildTools.Tasks/Properties/InternalsVisibleTo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("BuildTools.Tasks.Tests")] diff --git a/modules/BuildTools.Tasks/Publish.targets b/modules/BuildTools.Tasks/Publish.targets deleted file mode 100644 index cd76193e6..000000000 --- a/modules/BuildTools.Tasks/Publish.targets +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - <_TargetFramework Remove="@(_TargetFramework)" /> - <_TargetFramework Include="$(TargetFrameworks)" /> - - - - - - - diff --git a/modules/BuildTools.Tasks/Run.cs b/modules/BuildTools.Tasks/Run.cs deleted file mode 100644 index 1b6b3da75..000000000 --- a/modules/BuildTools.Tasks/Run.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.BuildTools -{ - /// - /// A task that runs a process without piping output into the logger. - /// See for more arguments. - /// -#if SDK - public class Sdk_Run -#elif BuildTools - public class Run -#else -#error This must be built either for an SDK or for BuildTools -#endif - : RunBase - { - /// - /// The executable to run. Can be a file path or a command for an executable on the system PATH. - /// - [Required] - public string FileName { get; set; } - - protected override string ToolName => FileName; - - protected override string GenerateFullPathToTool() - { - return FileName; - } - } -} diff --git a/modules/BuildTools.Tasks/RunBase.cs b/modules/BuildTools.Tasks/RunBase.cs deleted file mode 100644 index ab6baeee6..000000000 --- a/modules/BuildTools.Tasks/RunBase.cs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Linq; -using Microsoft.Build.Utilities; -using Microsoft.Build.Framework; -using Microsoft.Extensions.CommandLineUtils; - -namespace Microsoft.AspNetCore.BuildTools -{ - /// - /// A task that runs a process without piping output into the logger. - /// - public abstract class RunBase : ToolTask - { - protected RunBase() - { - // only use exit code to determine error by default. - LogStandardErrorAsError = false; - } - - private static readonly char[] EqualsArray = new[] { '=' }; - - private const int OK = 0; - - /// - /// A list of arguments to be passed to the executable. The task will escape them for spaces and quotes. - /// Cannot be used with - /// - public ITaskItem[] Arguments { get; set; } - - /// - /// The command to pass to the executable as string. - /// Cannot be used with - /// - public string Command { get; set; } - - // Additional options - /// - /// The current working directory - /// - public string WorkingDirectory { get; set; } - - /// - /// Don't fail the task if the command exits with a non-zero code - /// - public bool IgnoreExitCode { get; set; } - - /// - /// Repeat the command up to this many times if the exit code is non-zero. Defaults to 0. - /// - public int MaxRetries { get; set; } - - /// - /// Ignore standard error and warning formatting - /// - public bool IgnoreStandardErrorWarningFormat { get; set; } - - // increase the default output importance from Low to High - /// - protected override MessageImportance StandardErrorLoggingImportance => MessageImportance.High; - - /// - protected override MessageImportance StandardOutputLoggingImportance => MessageImportance.High; - - protected override bool HandleTaskExecutionErrors() - { - return IgnoreExitCode || base.HandleTaskExecutionErrors(); - } - - protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) - { - if (IgnoreStandardErrorWarningFormat) - { - Log.LogMessage(messageImportance, singleLine); - } - else - { - base.LogEventsFromTextOutput(singleLine, messageImportance); - } - } - - protected override string GetWorkingDirectory() => WorkingDirectory; - - protected override bool ValidateParameters() - { - var exe = GenerateFullPathToTool(); - - if (string.IsNullOrEmpty(exe)) - { - Log.LogError("FileName must be specified."); - return false; - } - - if (MaxRetries < 0) - { - Log.LogError("MaxRetries must be a non-negative number."); - return false; - } - - if (!string.IsNullOrEmpty(WorkingDirectory) && !Directory.Exists(WorkingDirectory)) - { - Log.LogError("WorkingDirectory does not exist: '{0}'", WorkingDirectory); - return false; - } - - // if path is not rooted, it may be a command on the system PATH - if (Path.IsPathRooted(exe) && !File.Exists(exe)) - { - Log.LogError("FileName does not exist: '{0}'", WorkingDirectory); - return false; - } - - return base.ValidateParameters(); - } - - public override bool Execute() - { - var retries = Math.Max(1, MaxRetries); - for (int i = 0; i < retries; i++) - { - if (base.Execute()) - { - return true; - } - } - - return false; - } - - protected override string GenerateCommandLineCommands() - { - var cmd = 0; - var arguments = string.Empty; - - if (Arguments != null) - { - arguments = ArgumentEscaper.EscapeAndConcatenate(Arguments.Select(i => i.ItemSpec)); - cmd++; - } - - if (!string.IsNullOrEmpty(Command)) - { - arguments = Command; - cmd++; - } - - if (cmd > 1) - { - Log.LogError("Arguments and Command cannot both be used."); - return null; - } - - return arguments; - } - } -} diff --git a/modules/BuildTools.Tasks/RunDotNet.cs b/modules/BuildTools.Tasks/RunDotNet.cs deleted file mode 100644 index 7c939e2f5..000000000 --- a/modules/BuildTools.Tasks/RunDotNet.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.Extensions.CommandLineUtils; - -namespace Microsoft.AspNetCore.BuildTools -{ - /// - /// A task that runs a dotnet command without piping output into the logger. - /// See for more arguments. - /// -#if SDK - public class Sdk_RunDotNet -#elif BuildTools - public class RunDotNet -#else -#error This must be built either for an SDK or for BuildTools -#endif - : RunBase - { - protected override string ToolName => "dotnet"; - - protected override string GenerateFullPathToTool() -#if NET46 - => "dotnet"; -#else - => DotNetMuxer.MuxerPathOrDefault(); -#endif - } -} diff --git a/modules/BuildTools.Tasks/SetEnvironmentVariable.cs b/modules/BuildTools.Tasks/SetEnvironmentVariable.cs deleted file mode 100644 index 62ca1cc79..000000000 --- a/modules/BuildTools.Tasks/SetEnvironmentVariable.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.BuildTools -{ -#if SDK - public class Sdk_SetEnvironmentVariable : Task -#elif BuildTools - public class SetEnvironmentVariable : Task -#else -#error This must be built either for an SDK or for BuildTools -#endif - { - [Required] - public string Variable { get; set; } - - [Required] - public string Value { get; set; } - - public override bool Execute() - { - if (string.IsNullOrEmpty(Variable)) - { - Log.LogError($"{nameof(Variable)} cannot be null or an empty string"); - return false; - } - - var expandedValue = Environment.ExpandEnvironmentVariables(Value); - - Log.LogMessage("Setting environment variable '{0}' to '{1}'", Variable, expandedValue); - - Environment.SetEnvironmentVariable(Variable, expandedValue); - - return true; - } - } -} diff --git a/modules/BuildTools.Tasks/UnzipArchive.cs b/modules/BuildTools.Tasks/UnzipArchive.cs deleted file mode 100644 index 5a4f37861..000000000 --- a/modules/BuildTools.Tasks/UnzipArchive.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using System.IO.Compression; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using ZipArchiveStream = System.IO.Compression.ZipArchive; -using IOFile = System.IO.File; - -namespace Microsoft.AspNetCore.BuildTools -{ - /// - /// Unzips an archive file. - /// -#if SDK - public class Sdk_UnzipArchive : Task -#elif BuildTools - public class UnzipArchive : Task -#else -#error This must be built either for an SDK or for BuildTools -#endif - { - /// - /// The file to unzip. - /// - [Required] - public string File { get; set; } - - /// - /// The directory where files will be unzipped. - /// - /// - [Required] - public string Destination { get; set; } - - /// - /// Overwrite if it exists. Defaults to false. - /// - public bool Overwrite { get; set; } = false; - - /// - /// Disables normalizing zip entry paths while extracting. - /// - public bool DisablePathNormalization { get; set; } = false; - - /// - /// The files that were unzipped. - /// - [Output] - public ITaskItem[] OutputFiles { get; set; } - - public override bool Execute() - { - if (!IOFile.Exists(File)) - { - Log.LogError("'{0}' does not exist", File); - return false; - } - - Directory.CreateDirectory(Destination); - - var output = new List(); - using (var stream = IOFile.OpenRead(File)) - using (var zip = new ZipArchiveStream(stream, ZipArchiveMode.Read)) - { - foreach (var entry in zip.Entries) - { - var entryPath = entry.FullName; - if (!DisablePathNormalization) - { - if (entry.FullName.IndexOf('\\') >= 0) - { - Log.LogMessage(null, null, null, File, 0, 0, 0, 0, MessageImportance.Low, - message: $"Zip entry '{entry.FullName}' has been normalized because it contains a backslash. Set DisablePathNormalization=true to disable this."); - entryPath = entry.FullName.Replace('\\', '/'); - } - } - - var fileDest = Path.Combine(Destination, entryPath); - var dirName = Path.GetDirectoryName(fileDest); - Directory.CreateDirectory(dirName); - - // Do not try to extract directories - if (Path.GetFileName(fileDest) != string.Empty) - { - entry.ExtractToFile(fileDest, Overwrite); - Log.LogMessage(MessageImportance.Low, "Extracted '{0}'", fileDest); - output.Add(new TaskItem(fileDest)); - } - } - } - - Log.LogMessage(MessageImportance.High, "Extracted {0} file(s) to '{1}'", output.Count, Destination); - OutputFiles = output.ToArray(); - - return true; - } - } -} diff --git a/modules/BuildTools.Tasks/UpdatePackageSource.cs b/modules/BuildTools.Tasks/UpdatePackageSource.cs deleted file mode 100644 index 07321a095..000000000 --- a/modules/BuildTools.Tasks/UpdatePackageSource.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Linq; -using System.Xml.Linq; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.BuildTools -{ - /// - /// Update or adds a NuGet feed to a NuGet.config file. It reads - /// and replaces or adds the feed named with . - /// -#if SDK - public class Sdk_UpdatePackageSource : Task -#elif BuildTools - public class UpdatePackageSource : Task -#else -#error This must be built either for an SDK or for BuildTools -#endif - { - [Required] - public string NuGetConfigPath { get; set; } - - [Required] - public string SourceName { get; set; } - - [Required] - public string SourceUri { get; set; } - - public override bool Execute() - { - if (string.IsNullOrEmpty(SourceName)) - { - Log.LogError("FeedName must not be empty"); - return false; - } - - if (string.IsNullOrEmpty(SourceUri)) - { - Log.LogError("PackageSource must not be empty"); - return false; - } - - var nugetConfig = XDocument.Load(NuGetConfigPath); - var packageSources = nugetConfig.Element("configuration")?.Element("packageSources"); - var addElements = packageSources?.Elements("add").ToList(); - - var valueToUpdate = addElements.FirstOrDefault(f => string.Equals(f.Attribute("key")?.Value, SourceName, StringComparison.OrdinalIgnoreCase)); - if (valueToUpdate == null) - { - Log.LogMessage("Adding feed '{0}' to '{1}'", SourceName, SourceUri); - packageSources.Add(new XElement("add", - new XAttribute("key", SourceName), - new XAttribute("value", SourceUri))); - } - else - { - Log.LogMessage("Updating feed '{0}' to '{1}'", SourceName, SourceUri); - valueToUpdate.SetAttributeValue("value", SourceUri); - } - - using (var file = new FileStream(NuGetConfigPath, FileMode.Create)) - { - nugetConfig.Save(file); - } - - Log.LogMessage("Saved changes to '{0}'", NuGetConfigPath); - - return true; - } - } -} diff --git a/modules/BuildTools.Tasks/Utilities/GitRepoInfo.cs b/modules/BuildTools.Tasks/Utilities/GitRepoInfo.cs deleted file mode 100644 index 77d1edf35..000000000 --- a/modules/BuildTools.Tasks/Utilities/GitRepoInfo.cs +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Linq; - -namespace Microsoft.AspNetCore.BuildTools.Utilities -{ - internal class GitRepoInfo - { - private const string HeadContentStart = "ref: refs/heads/"; - private const string GitDirRefContentStart = "gitdir:"; - - private const int CommitShaLength = 40; - - /// - /// The name of the branch HEAD is pointed to. Can be null or empty - /// for repositories in detached HEAD mode. - /// - public string Branch { get; set; } - - /// - /// The full commit SHA of the current commit referenced by HEAD. - /// - public string CommitHash { get; private set; } - - /// - /// The root folder of the working directory. Not the .git folder itself. - /// - public string RepositoryRootPath { get; private set; } - - /// - /// The folder containing the .git folder - /// - public string GitDir { get; private set; } - - /// - /// The repo is in detached head mode. - /// - public bool DetachedHeadMode { get; private set; } - - /// - /// Full path to the HEAD file. - /// - public string HeadFile { get; set; } - - /// - /// Find give info for a folder inside the git project. Does not need to be the top folder. - /// This task will search upwards for the .git folder. - /// - public static GitRepoInfo Load(string workingDirectory) - { - var repoRoot = GetRepositoryRoot(workingDirectory); - if (repoRoot == null) - { - throw new DirectoryNotFoundException($"Could not find the git directory for '{workingDirectory}'"); - } - - var info = new GitRepoInfo - { - RepositoryRootPath = FileHelpers.EnsureTrailingSlash(repoRoot.FullName) - }; - - switch (repoRoot.GetFileSystemInfos(".git").FirstOrDefault()) - { - case DirectoryInfo d: - // regular git working directories - info.GitDir = d.FullName; - info.HeadFile = Path.Combine(info.GitDir, "HEAD"); - break; - case FileInfo f: - // submodules and worktrees - var contents = File.ReadAllText(f.FullName); - if (contents.StartsWith(GitDirRefContentStart, StringComparison.OrdinalIgnoreCase)) - { - var gitdirRef = contents.Substring(GitDirRefContentStart.Length).Trim(); - var gitDirRoot = Path.IsPathRooted(gitdirRef) - ? new DirectoryInfo(gitdirRef) - : new DirectoryInfo(Path.Combine(f.Directory.FullName, gitdirRef)); - - info.HeadFile = Path.Combine(gitDirRoot.FullName, "HEAD"); - - var commonDir = gitDirRoot.GetFiles("commondir").FirstOrDefault(); - if (commonDir != null) - { - // happens in worktrees - var commonDirRef = File.ReadAllText(commonDir.FullName).Trim(); - info.GitDir = Path.IsPathRooted(commonDirRef) - ? commonDirRef - : Path.Combine(gitDirRoot.FullName, commonDirRef); - } - else - { - // happens with submodules - info.GitDir = gitDirRoot.FullName; - } - } - else - { - throw new DirectoryNotFoundException($"Unable to determine the location of the .git directory. Unrecognized file format: {f.FullName}"); - } - break; - case null: - default: - throw new ArgumentOutOfRangeException("Unrecognized implementation of FileSystemInfo"); - } - - if (!File.Exists(info.HeadFile)) - { - throw new FileNotFoundException("Unable to determine the status of the git repo. No HEAD file found."); - } - - var content = File.ReadAllText(info.HeadFile).Trim(); - if (content.StartsWith(HeadContentStart, StringComparison.OrdinalIgnoreCase)) - { - info.Branch = content.Substring(HeadContentStart.Length); - info.CommitHash = ResolveHashFromBranch(info.GitDir, info.Branch); - } - else if (content.Length == CommitShaLength) - { - info.DetachedHeadMode = true; - info.CommitHash = content; - } - else - { - throw new InvalidOperationException($"Unable to determine the status of the git repo. THe HEAD file has an unexpected format: '{content}'"); - } - - return info; - } - - private static string ResolveHashFromBranch(string gitDir, string branch) - { - if (string.IsNullOrEmpty(branch)) - { - throw new InvalidOperationException("Current branch appears to be empty. Failed to retrieve current branch."); - } - - var branchFile = Path.Combine(gitDir, "refs", "heads", branch); - if (File.Exists(branchFile)) - { - return File.ReadAllText(branchFile).Trim(); - } - - var packedRefs = Path.Combine(gitDir, "packed-refs"); - if (File.Exists(packedRefs)) - { - var lines = File.ReadAllLines(packedRefs); - foreach (var line in lines) - { - if (line.Length == 0) - { - continue; - } - - if (line[0] == '#' || line[0] == '^') - { - continue; - } - - var split = line.Split(new[] { ' ' }, 2); - if (split.Length < 2) - { - continue; - } - - if (string.Equals("refs/heads/" + branch, split[1], StringComparison.Ordinal)) - { - return split[0]; - } - } - } - - throw new FileNotFoundException("Unable to determine current git commit hash"); - } - - private static DirectoryInfo GetRepositoryRoot(string start) - { - var dir = new DirectoryInfo(start); - while (dir != null) - { - var dotGit = dir.GetFileSystemInfos(".git").FirstOrDefault(); - if (dotGit != null) - { - return dir; - } - dir = dir.Parent; - } - return null; - } - } -} diff --git a/modules/BuildTools.Tasks/Utilities/IndentedTextWriter.cs b/modules/BuildTools.Tasks/Utilities/IndentedTextWriter.cs deleted file mode 100644 index 064152069..000000000 --- a/modules/BuildTools.Tasks/Utilities/IndentedTextWriter.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Text; - -namespace Microsoft.AspNetCore.BuildTools.Utilities -{ - internal class IndentedTextWriter : TextWriter - { - private readonly TextWriter _wrapped; - private readonly string _spaces; - - public IndentedTextWriter(TextWriter wrapped, int indentSpaces) - { - _wrapped = wrapped; - _spaces = new String(' ', indentSpaces); - } - - public override Encoding Encoding => _wrapped.Encoding; - - public override void Write(char value) - => _wrapped.Write(value); - - public override void WriteLine(string line) - { - _wrapped.Write(_spaces); - _wrapped.WriteLine(line); - } - - protected override void Dispose(bool disposing) - { - } - } -} diff --git a/modules/BuildTools.Tasks/Utilities/TextWriterExtensions.cs b/modules/BuildTools.Tasks/Utilities/TextWriterExtensions.cs deleted file mode 100644 index ba195085e..000000000 --- a/modules/BuildTools.Tasks/Utilities/TextWriterExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNetCore.BuildTools.Utilities; - -namespace System.IO -{ - internal static class TextWriterExtensions - { - public static IndentedTextWriter Indent(this TextWriter writer, int spaces = 4) - => new IndentedTextWriter(writer, spaces); - } -} diff --git a/modules/BuildTools.Tasks/WaitForDebugger.cs b/modules/BuildTools.Tasks/WaitForDebugger.cs deleted file mode 100644 index 43478090a..000000000 --- a/modules/BuildTools.Tasks/WaitForDebugger.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Diagnostics; -using System.Threading; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.BuildTools -{ -#if SDK - public class Sdk_WaitForDebugger : Task, ICancelableTask -#elif BuildTools - public class WaitForDebugger : Task -#else -#error This must be built either for an SDK or for BuildTools -#endif - { - private bool _canceled; - - public void Cancel() - { - _canceled = true; - } - - public override bool Execute() - { - Log.LogMessage(MessageImportance.High, $"Waiting for debugger. Process ID: {Process.GetCurrentProcess().Id}"); - - // 30 seconds - var maxTimeout = 30 * 1000; - var step = 150; - - while (!Debugger.IsAttached && maxTimeout > 0 && !_canceled) - { - Thread.Sleep(step); - maxTimeout -= step; - } - - if (!Debugger.IsAttached && !_canceled) - { - Log.LogMessage(MessageImportance.High, "Waiting for debugger timed out. Continuing execution."); - } - - return true; - } - } -} diff --git a/modules/BuildTools.Tasks/_._ b/modules/BuildTools.Tasks/_._ deleted file mode 100644 index e69de29bb..000000000 diff --git a/modules/BuildTools.Tasks/module.props b/modules/BuildTools.Tasks/module.props deleted file mode 100644 index 0f1724a8a..000000000 --- a/modules/BuildTools.Tasks/module.props +++ /dev/null @@ -1,11 +0,0 @@ - - - - <_BuildToolsAssembly Condition="'$(MSBuildRuntimeType)' == 'core' ">$(MSBuildThisFileDirectory)netcoreapp2.1\Internal.AspNetCore.BuildTools.Tasks.dll - <_BuildToolsAssembly Condition="'$(MSBuildRuntimeType)' != 'core' ">$(MSBuildThisFileDirectory)net46\Internal.AspNetCore.BuildTools.Tasks.dll - <_BuildTasksPrefix> - - - - - diff --git a/modules/BuildTools.Tasks/module.targets b/modules/BuildTools.Tasks/module.targets deleted file mode 100644 index b22749fea..000000000 --- a/modules/BuildTools.Tasks/module.targets +++ /dev/null @@ -1,84 +0,0 @@ - - - - $(PrepareDependsOn);_UseVolatileFeed;ResolveCommitHash - - - - - - - - - - - - $(APPVEYOR_REPO_COMMIT) - $(TRAVIS_COMMIT) - $(CommitHash) - - - - - - - - - $(RepositoryCommit) - $(BuildProperties);CommitHash=$(RepositoryCommit) - $(BuildProperties);RepositoryCommit=$(RepositoryCommit) - - - - - - - - - <_ResxTargets>$(MSBuildThisFileDirectory)Project.CSharp.Resx.targets - <_ResxSlnProps>$(BuildProperties) - - <_ResxSlnProps>$(_ResxSlnProps);CustomAfterMicrosoftCommonTargets=$(_ResxTargets) - <_ResxSlnProps>$(_ResxSlnProps);CustomAfterMicrosoftCommonCrossTargetingTargets=$(_ResxTargets) - - - - - - - - <_UpdateFeeds Include="ARTIFACTS" Value="$(NUGET_VOLATILE_FEED_ARTIFACTS)" Condition="'$(NUGET_VOLATILE_FEED_ARTIFACTS)' != ''" /> - <_UpdateFeeds Include="AspNetCore" Value="$(NUGET_VOLATILE_FEED_AspNetCore)" Condition="'$(NUGET_VOLATILE_FEED_AspNetCore)' != ''" /> - - - - - - - diff --git a/modules/BundledPackages/BundledPackages.proj b/modules/BundledPackages/BundledPackages.proj deleted file mode 100644 index 04da269d2..000000000 --- a/modules/BundledPackages/BundledPackages.proj +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - -<Project> - <PropertyGroup> - <ImportDirectoryBuildProps>false</ImportDirectoryBuildProps> - <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets> - </PropertyGroup> - - <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" /> - - <PropertyGroup> - <TargetFramework>netcoreapp2.1</TargetFramework> - <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="MicroBuild.Core" Version="$(MicroBuildCorePackageVersion)" /> - <PackageReference Include="Internal.AspNetCore.Sdk" Version="$(Version)" /> - </ItemGroup> - - <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" /> - -</Project> - - - - - - - - - - diff --git a/modules/BundledPackages/NuGet.config b/modules/BundledPackages/NuGet.config deleted file mode 100644 index b34426546..000000000 --- a/modules/BundledPackages/NuGet.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/modules/KoreBuild.Tasks/CheckPackageReferences.cs b/modules/KoreBuild.Tasks/CheckPackageReferences.cs deleted file mode 100644 index c99d5dd26..000000000 --- a/modules/KoreBuild.Tasks/CheckPackageReferences.cs +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using KoreBuild.Tasks.ProjectModel; -using KoreBuild.Tasks.Utilities; -using Microsoft.AspNetCore.BuildTools; -using Microsoft.Build.Construction; -using Microsoft.Build.Exceptions; -using Microsoft.Build.Framework; -using NuGet.Versioning; - -namespace KoreBuild.Tasks -{ - /// - /// Ensures MSBuild files use PackageReference responsibly. - /// - public class CheckPackageReferences : Microsoft.Build.Utilities.Task - { - /// - /// The solutions of csproj files to check. - /// - [Required] - public ITaskItem[] Projects { get; set; } - - /// - /// The file that contains the PropertyGroup of versions - /// - [Required] - public string DependenciesFile { get; set; } - - public string[] Properties { get; set; } - - public override bool Execute() - { - if (Projects == null || Projects.Length == 0) - { - Log.LogMessage(MessageImportance.Low, "No projects or solutions were found. Skipping PackageReference validation."); - return true; - } - - if (!File.Exists(DependenciesFile)) - { - Log.LogKoreBuildError(KoreBuildErrors.DependenciesFileDoesNotExist, $"Expected the dependencies file to exist at {DependenciesFile}"); - return false; - } - - if (!DependencyVersionsFile.TryLoad(DependenciesFile, out var depsFile)) - { - Log.LogError($"Could not load the dependencies file from {DependenciesFile}"); - return false; - } - - if (!depsFile.HasVersionsPropertyGroup) - { - Log.LogKoreBuildWarning(KoreBuildErrors.PackageRefPropertyGroupNotFound, $"No PropertyGroup with Label=\"{DependencyVersionsFile.PackageVersionsLabel}\" or Label=\"{DependencyVersionsFile.AutoPackageVersionsLabel}\" could be found in {DependenciesFile}"); - } - - foreach (var proj in Projects) - { - var ext = Path.GetExtension(proj.ItemSpec); - if (ext == ".sln") - { - var solutionProps = MSBuildListSplitter.GetNamedProperties(Properties); - var projectFiles = Projects.SelectMany(p => SolutionInfoFactory.GetProjects(p, solutionProps)).Distinct(); - foreach (var project in projectFiles) - { - VerifyPackageReferences(project, depsFile.VersionVariables); - } - } - else - { - VerifyPackageReferences(proj.ItemSpec, depsFile.VersionVariables); - } - } - - return !Log.HasLoggedErrors; - } - - private void VerifyPackageReferences(string filePath, IReadOnlyDictionary versionVariables) - { - ProjectRootElement doc; - try - { - doc = ProjectRootElement.Open(filePath); - } - catch (InvalidProjectFileException ex) - { - Log.LogError(null, null, null, filePath, 0, 0, 0, 0, message: "Invalid project file: " + ex.Message); - return; - } - - var packageReferences = doc.Items.Where(i => i.ItemType == "PackageReference"); - foreach (var pkgRef in packageReferences) - { - var id = pkgRef.Include; - - if (string.IsNullOrEmpty(id)) - { - // this node is an Update or Remove node - continue; - } - - var versionMetadata = pkgRef.Metadata.LastOrDefault(m => m.Name == "Version"); - var versionRaw = versionMetadata?.Value; - if (versionMetadata == null || string.IsNullOrEmpty(versionRaw)) - { - Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.PackageReferenceDoesNotHaveVersion, $"PackageReference to {id} does not define a Version"); - continue; - } - - var versionIsVariable = - versionRaw != null - && versionRaw.Length > 3 - && versionRaw[0] == '$' - && versionRaw[1] == '(' - && versionRaw[versionRaw.Length - 1] == ')' - && versionRaw.IndexOf(')') == versionRaw.Length - 1; - - if (!versionIsVariable) - { - Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.PackageRefHasLiteralVersion, "PackageReference must use an MSBuild variable to set the version."); - continue; - } - - var versionVarName = versionRaw.Substring(2, versionRaw.Length - 3); - - if (!versionVariables.TryGetValue(versionVarName, out var variable)) - { - Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.VariableNotFoundInDependenciesPropsFile, $"The variable {versionRaw} could not be found in {DependenciesFile}"); - continue; - } - - var versionValue = variable.Version; - if (!VersionRange.TryParse(versionValue, out var nugetVersion)) - { - Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.InvalidPackageVersion, $"PackageReference to {id} has an invalid version identifier: '{versionValue}'"); - continue; - } - - if (nugetVersion.IsFloating) - { - Log.LogKoreBuildError(pkgRef.Location.File, pkgRef.Location.Line, KoreBuildErrors.PackageRefHasFloatingVersion, $"PackageReference to {id} uses a floating version: '{versionValue}'"); - } - } - } - } -} diff --git a/modules/KoreBuild.Tasks/CodeSign.props b/modules/KoreBuild.Tasks/CodeSign.props new file mode 100644 index 000000000..382a7aee1 --- /dev/null +++ b/modules/KoreBuild.Tasks/CodeSign.props @@ -0,0 +1,29 @@ + + + + + true + + + $(RepoRoot)build\signcheck.exclusions.txt + + $(ArtifactsDir) + + + $(RepoRoot) + + + true + false + + + false + true + + + + + + + + diff --git a/modules/KoreBuild.Tasks/CodeSign.targets b/modules/KoreBuild.Tasks/CodeSign.targets index 28edbbc5c..2ea2a8399 100644 --- a/modules/KoreBuild.Tasks/CodeSign.targets +++ b/modules/KoreBuild.Tasks/CodeSign.targets @@ -1,26 +1,4 @@ - - - - true - - - $(RepositoryRoot)build\signcheck.exclusions.txt - - $(ArtifactsDir) - - - $(RepositoryRoot) - - - true - false - - - false - true - - @@ -52,7 +30,9 @@ DryRun="$(SignToolDryRun)" TestSign="$(SignToolTestSign)" ItemsToSign="@(_ItemsToSign)" - FileSignInfo="@(_FileSignInfo)" + FileSignInfo="@(_FileSignInfo);@(FileNamesToSign)" + StrongNameSignInfo="@(AssemblyToSign)" + FileExtensionSignInfo="@(FileExtensionsToSign)" TempDir="$(IntermediateDir)" LogDir="$(LogOutputDir)" MSBuildPath="$(MSBuildx86Path)" @@ -69,18 +49,18 @@ + - - + - + diff --git a/modules/KoreBuild.Tasks/ComputeChecksum.cs b/modules/KoreBuild.Tasks/ComputeChecksum.cs deleted file mode 100644 index 45f37f4bb..000000000 --- a/modules/KoreBuild.Tasks/ComputeChecksum.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.Build.Framework; - -namespace KoreBuild.Tasks -{ - /// - /// Computes the checksum for a single file. - /// - public class ComputeChecksum : Microsoft.Build.Utilities.Task - { - /// - /// The file path. - /// - [Required] - public string File { get; set; } - - /// - /// The algorithm. Allowed values: SHA256, SHA384, SHA512. - /// - public string Algorithm { get; set; } = "SHA256"; - - /// - /// The hash. - /// - [Output] - public string Hash { get; set; } - - public override bool Execute() - { - Hash = HashHelper.GetFileHash(Algorithm, File); - - return true; - } - } -} diff --git a/modules/KoreBuild.Tasks/DisableSkipStrongName.cs b/modules/KoreBuild.Tasks/DisableSkipStrongName.cs deleted file mode 100644 index acb0d2345..000000000 --- a/modules/KoreBuild.Tasks/DisableSkipStrongName.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using KoreBuild.Tasks.SkipStrongNames; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Microsoft.Win32; - -namespace KoreBuild.Tasks -{ - public class DisableSkipStrongName : Task - { - [Required] - public string XmlFile { get; set; } - - public override bool Execute() - { - var configuration = new StrongNameConfiguration(AssembliesFile.Read(XmlFile)); - - return SkipDisable(configuration); - } - - private bool SkipDisable(StrongNameConfiguration configuration) - { - bool printedHeader = false; - - foreach (RegistrySection section in WindowsRegistry.Sections) - { - using (RegistryKey registryKey = WindowsRegistry.CreateWritableVerificationRegistryKey(section)) - { - if (registryKey == null) - { - Log.LogError($"Unable to open writable verification registry key for {section}."); - return false; - } - - foreach (var assembly in configuration.FilteredAssemblySpecifications[section]) - { - RegistryKey subKey = registryKey.OpenSubKey(assembly); - - if (subKey != null) - { - if (!printedHeader) - { - printedHeader = true; - Log.LogMessage("Deleting registry entries:"); - } - - Log.LogMessage($" {registryKey}\\{assembly}"); - subKey.Dispose(); - registryKey.DeleteSubKeyTree(assembly); - } - } - } - } - - if (!printedHeader) - { - Log.LogMessage("Skip Strong Names is already disabled."); - } - else - { - Log.LogMessage(""); - Log.LogMessage("Skip Strong Names was successfully disabled."); - } - - return true; - } - } -} diff --git a/modules/KoreBuild.Tasks/DownloadFile.cs b/modules/KoreBuild.Tasks/DownloadFile.cs deleted file mode 100644 index cf0be8e50..000000000 --- a/modules/KoreBuild.Tasks/DownloadFile.cs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Build.Framework; - -namespace KoreBuild.Tasks -{ - /// - /// Downloads a file. - /// - public class DownloadFile : Microsoft.Build.Utilities.Task, ICancelableTask - { - private readonly CancellationTokenSource _cts = new CancellationTokenSource(); - - /// - /// The file to download. Can be prefixed with file:// for local file paths. - /// - [Required] - public string Uri { get; set; } - - /// - /// Destination for the downloaded file. If the file already exists, it is not re-downloaded unless is true. - /// - [Required] - public string DestinationPath { get; set; } - - /// - /// Should be overwritten. When true, the file is always re-downloaded. - /// - public bool Overwrite { get; set; } - - /// - /// The maximum amount of time to allow for downloading the file. Defaults to 15 minutes. - /// - public int TimeoutSeconds { get; set; } = 60 * 15; - - public void Cancel() => _cts.Cancel(); - - public override bool Execute() => ExecuteAsync().Result; - - public async Task ExecuteAsync() - { - if (File.Exists(DestinationPath) && !Overwrite) - { - return true; - } - - const string FileUriProtocol = "file://"; - - if (Uri.StartsWith(FileUriProtocol, StringComparison.OrdinalIgnoreCase)) - { - var filePath = Uri.Substring(FileUriProtocol.Length); - Log.LogMessage($"Copying '{filePath}' to '{DestinationPath}'"); - File.Copy(filePath, DestinationPath); - } - else - { - Log.LogMessage($"Downloading '{Uri}' to '{DestinationPath}'"); - - using (var httpClient = new HttpClient - { - // Timeout if no response starts in 2 minutes - Timeout = TimeSpan.FromMinutes(2), - }) - { - try - { - var response = await httpClient.GetAsync(Uri, _cts.Token); - response.EnsureSuccessStatusCode(); - _cts.Token.ThrowIfCancellationRequested(); - - Directory.CreateDirectory(Path.GetDirectoryName(DestinationPath)); - - using (var outStream = File.Create(DestinationPath)) - { - var responseStream = response.Content.ReadAsStreamAsync(); - var finished = await Task.WhenAny(responseStream, Task.Delay(TimeSpan.FromSeconds(TimeoutSeconds))); - - if (!ReferenceEquals(responseStream, finished)) - { - throw new TimeoutException($"Download failed to complete in {TimeoutSeconds} seconds."); - } - - responseStream.Result.CopyTo(outStream); - } - } - catch (Exception ex) - { - Log.LogError($"Downloading '{Uri}' failed."); - Log.LogErrorFromException(ex, showStackTrace: true); - - File.Delete(DestinationPath); - return false; - } - } - } - - return !Log.HasLoggedErrors; - } - } -} diff --git a/modules/KoreBuild.Tasks/DownloadNuGetPackages.cs b/modules/KoreBuild.Tasks/DownloadNuGetPackages.cs deleted file mode 100644 index e69cb71f1..000000000 --- a/modules/KoreBuild.Tasks/DownloadNuGetPackages.cs +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using KoreBuild.Tasks.Utilities; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using NuGet.Build; -using NuGet.Packaging.Core; -using NuGet.Versioning; - -namespace KoreBuild.Tasks -{ - /// - /// Downloads NuGet packages in parallel. - /// - public class DownloadNuGetPackages : Microsoft.Build.Utilities.Task, ICancelableTask - { - private readonly CancellationTokenSource _cts = new CancellationTokenSource(); - - /// - /// The NuGet packages to download. Expected form: - /// - /// ItemSpec = PackageID - /// - /// Metadata: - /// Version = the exact package version to download - /// Source = the NuGet feed (remote or folder) - /// - [Required] - public ITaskItem[] Packages { get; set; } - - /// - /// The directory for download NuGet files. The task will write files to $(DestinationFolder)/$(PackageId.ToLower()).$(Version).nupkg - /// - [Required] - public string DestinationFolder { get; set; } - - /// - /// The package files that were downloaded. - /// - [Output] - public ITaskItem[] Files { get; set; } - - /// - /// The maximum amount of time to allow for downloading packages. - /// - public int TimeoutSeconds { get; set; } = 60 * 5; - - public void Cancel() => _cts.Cancel(); - - public override bool Execute() - { - return ExecuteAsync().Result; - } - - public async Task ExecuteAsync() - { - DestinationFolder = DestinationFolder.Replace('\\', '/'); - - var requests = new List(); - var files = new List(); - var downloadCount = 0; - foreach (var item in Packages) - { - var id = item.ItemSpec; - var rawVersion = item.GetMetadata("Version"); - if (!NuGetVersion.TryParse(rawVersion, out var version)) - { - Log.LogError($"Package '{id}' has an invalid 'Version' metadata value: '{rawVersion}'."); - return false; - } - - var source = item.GetMetadata("Source"); - if (string.IsNullOrEmpty(source)) - { - Log.LogError($"Package '{id}' is missing the 'Source' metadata value."); - return false; - } - - var outputPath = Path.Combine(DestinationFolder, $"{id.ToLowerInvariant()}.{version.ToNormalizedString()}.nupkg"); - - files.Add(new TaskItem(outputPath)); - if (File.Exists(outputPath)) - { - Log.LogMessage($"Skipping {id} {version}. Already exists in '{outputPath}'"); - continue; - } - else - { - downloadCount++; - - var request = new PackageDownloadRequest - { - Identity = new PackageIdentity(id, version), - OutputPath = outputPath, - Sources = source.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries), - }; - - requests.Add(request); - } - } - - Files = files.ToArray(); - - if (downloadCount == 0) - { - Log.LogMessage("All packages are downloaded."); - return true; - } - - Directory.CreateDirectory(DestinationFolder); - var logger = new MSBuildLogger(Log); - var timeout = TimeSpan.FromSeconds(TimeoutSeconds); - var downloader = new PackageDownloader(logger); - var timer = Stopwatch.StartNew(); - - var result = await downloader.DownloadPackagesAsync(requests, timeout, _cts.Token); - - timer.Stop(); - logger.LogMinimal($"Finished downloading {requests.Count} package(s) in {timer.ElapsedMilliseconds}ms"); - return result; - } - } -} diff --git a/modules/KoreBuild.Tasks/EnableSkipStrongName.cs b/modules/KoreBuild.Tasks/EnableSkipStrongName.cs deleted file mode 100644 index 53ffd31ce..000000000 --- a/modules/KoreBuild.Tasks/EnableSkipStrongName.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Runtime.InteropServices; -using KoreBuild.Tasks.SkipStrongNames; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Microsoft.Win32; - -namespace KoreBuild.Tasks -{ - public class EnableSkipStrongName : Task - { - [Required] - public string XmlFile { get; set; } - - public override bool Execute() - { - var configuration = new StrongNameConfiguration(AssembliesFile.Read(XmlFile)); - - return SkipEnable(configuration); - } - - private bool SkipEnable(StrongNameConfiguration configuration) - { - if (!File.Exists(XmlFile)) - { - Log.LogError("The XmlFile given must exist."); - return false; - } - - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Log.LogError("Strongname tasks should only be run on Windows."); - return false; - } - - bool printedHeader = false; - - foreach (RegistrySection section in WindowsRegistry.Sections) - { - using (RegistryKey registryKey = WindowsRegistry.CreateWritableVerificationRegistryKey(section)) - { - if (registryKey == null) - { - Log.LogError($"Unable to open writable verification registry key for {section}."); - return false; - } - - foreach (var assembly in configuration.FilteredAssemblySpecifications[section]) - { - using (RegistryKey subKey = registryKey.OpenSubKey(assembly)) - { - if (subKey == null) - { - if (!printedHeader) - { - printedHeader = true; - Log.LogMessage("Adding registry entries:"); - } - - Log.LogMessage($" {registryKey}\\{assembly}"); - registryKey.CreateSubKey(assembly); - } - } - } - } - } - - if (!printedHeader) - { - Log.LogMessage("Skip Strong Names is already enabled."); - } - else - { - Log.LogMessage(""); - Log.LogMessage("Skip Strong Names was successfully enabled."); - } - - return true; - } - } -} diff --git a/modules/KoreBuild.Tasks/GenerateDependenciesPropsFile.cs b/modules/KoreBuild.Tasks/GenerateDependenciesPropsFile.cs deleted file mode 100644 index 149fc5b8d..000000000 --- a/modules/KoreBuild.Tasks/GenerateDependenciesPropsFile.cs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using KoreBuild.Tasks.ProjectModel; -using KoreBuild.Tasks.Utilities; -using Microsoft.Build.Construction; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace KoreBuild.Tasks -{ - /// - /// Generates the build/dependencies.props file base on your current project, - /// and updates all PackageReferences in and to use MSBuild variables. - /// - public class GenerateDependenciesPropsFile : Microsoft.Build.Utilities.Task, ICancelableTask - { - private readonly CancellationTokenSource _cts = new CancellationTokenSource(); - - /// - /// The projects to update - /// - [Required] - public ITaskItem[] Projects { get; set; } - - /// - /// other files to update that may have PackageReferences in them - /// - public ITaskItem[] OtherImports { get; set; } - - /// - /// Location of the dependenices.props file - /// - [Required] - public string DependenciesFile { get; set; } - - /// - /// Additional properties to use when evaluating the projects - /// - public string[] Properties { get; set; } - - public void Cancel() - { - _cts.Cancel(); - } - - public override bool Execute() - { - var unifiedPackageList = new Dictionary(StringComparer.OrdinalIgnoreCase); - - var projects = new ProjectInfoFactory(Log).CreateMany(Projects, Properties, false, _cts.Token); - var packageRefs = projects.SelectMany(p => p.Frameworks).SelectMany(f => f.Dependencies); - - foreach (var packageRef in packageRefs) - { - if (packageRef.Value.IsImplicitlyDefined) - { - // skip PackageReferences added by the SDK - continue; - } - - if (packageRef.Value.NoWarn.Contains(KoreBuildErrors.Prefix + KoreBuildErrors.ConflictingPackageReferenceVersions)) - { - // Make it possible to suppress version conflicts while generating this file. - continue; - } - - if (unifiedPackageList.TryGetValue(packageRef.Value.Id, out var other)) - { - if (other.Version != packageRef.Value.Version) - { - Log.LogKoreBuildError(KoreBuildErrors.ConflictingPackageReferenceVersions, $"Conflicting dependency versions for {packageRef.Value.Id}: {other.Project.FileName} references '{other.Version}' but {packageRef.Value.Project.FileName} references '{packageRef.Value.Version}'"); - } - } - else - { - unifiedPackageList.Add(packageRef.Value.Id, packageRef.Value); - Log.LogMessage(MessageImportance.Low, $"Found {packageRef.Value.Id} = {packageRef.Value.Version}"); - } - } - - if (Log.HasLoggedErrors) - { - return false; - } - - var items = unifiedPackageList.Values.Select(p => new TaskItem(p.Id, new Hashtable { ["Version"] = p.Version })).ToArray(); - - var task = new GeneratePackageVersionPropsFile - { - AddOverrideImport = true, - SuppressVariableLabels = true, - Packages = items, - BuildEngine = BuildEngine, - HostObject = HostObject, - OutputPath = DependenciesFile, - }; - - if (!task.Execute()) - { - return false; - } - - var otherImports = OtherImports != null - ? OtherImports.Select(p => p.ItemSpec) - : Array.Empty(); - - foreach (var proj in projects.Select(p => p.FullPath).Concat(otherImports)) - { - var project = ProjectRootElement.Open(proj, ProjectCollection.GlobalProjectCollection, preserveFormatting: true); - var changed = false; - foreach (var item in project.Items.Where(i => i.ItemType == "PackageReference")) - { - var noWarn = item.Metadata.FirstOrDefault(m => m.Name == "NoWarn"); - if (noWarn != null && noWarn.Value.Contains(KoreBuildErrors.Prefix + KoreBuildErrors.ConflictingPackageReferenceVersions)) - { - continue; - } - - var versionMetadata = item.Metadata.LastOrDefault(p => p.Name == "Version"); - if (versionMetadata != null && versionMetadata.Value.StartsWith("$(")) - { - continue; - } - changed = true; - - var varName = $"$({DependencyVersionsFile.GetVariableName(item.Include)})"; - if (versionMetadata == null) - { - item.AddMetadata("Version", varName, expressAsAttribute: true); - } - else - { - versionMetadata.Value = varName; - } - } - - if (changed) - { - Log.LogMessage(MessageImportance.High, $"Updated {proj}"); - project.Save(proj); - } - else - { - Log.LogMessage(MessageImportance.Normal, $"Skipping {proj}. Already up to date."); - } - } - - return !Log.HasLoggedErrors; - } - } -} diff --git a/modules/KoreBuild.Tasks/GeneratePackageVersionPropsFile.cs b/modules/KoreBuild.Tasks/GeneratePackageVersionPropsFile.cs deleted file mode 100644 index 38c34cf15..000000000 --- a/modules/KoreBuild.Tasks/GeneratePackageVersionPropsFile.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using KoreBuild.Tasks.Utilities; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace KoreBuild.Tasks -{ - public class GeneratePackageVersionPropsFile : Task - { - [Required] - public ITaskItem[] Packages { get; set; } - - [Required] - public string OutputPath { get; set; } - - public bool AddOverrideImport { get; set; } - - public string[] AdditionalImports { get; set; } - - public bool SuppressVariableLabels { get; set; } - - public override bool Execute() - { - OutputPath = OutputPath.Replace('\\', '/'); - Directory.CreateDirectory(Path.GetDirectoryName(OutputPath)); - - DependencyVersionsFile depsFile; - if (File.Exists(OutputPath)) - { - if (!DependencyVersionsFile.TryLoad(OutputPath, out depsFile)) - { - depsFile = DependencyVersionsFile.Create(AddOverrideImport, AdditionalImports); - Log.LogWarning($"Could not load the existing deps file from {OutputPath}. This file will be overwritten."); - } - } - else - { - depsFile = DependencyVersionsFile.Create(AddOverrideImport, AdditionalImports); - } - - var varNames = new HashSet(); - foreach (var pkg in Packages) - { - var packageVersion = pkg.GetMetadata("Version"); - - if (string.IsNullOrEmpty(packageVersion)) - { - Log.LogError("Package {0} is missing the Version metadata", pkg.ItemSpec); - continue; - } - - string packageVarName; - if (!string.IsNullOrEmpty(pkg.GetMetadata("VariableName"))) - { - packageVarName = pkg.GetMetadata("VariableName"); - if (!packageVarName.EndsWith("Version", StringComparison.Ordinal)) - { - Log.LogError("VariableName for {0} must end in 'Version'", pkg.ItemSpec); - continue; - } - } - else - { - packageVarName = DependencyVersionsFile.GetVariableName(pkg.ItemSpec); - } - - if (varNames.Contains(packageVarName)) - { - Log.LogError("Multiple packages would produce {0} in the generated dependencies.props file. Set VariableName to differentiate the packages manually", packageVarName); - continue; - } - - var item = depsFile.Update(packageVarName, packageVersion); - if (!SuppressVariableLabels) - { - item.SetLabel(pkg.ItemSpec); - } - } - - depsFile.Save(OutputPath); - Log.LogMessage(MessageImportance.Normal, $"Generated {OutputPath}"); - return !Log.HasLoggedErrors; - } - } -} diff --git a/modules/KoreBuild.Tasks/GetToolsets.cs b/modules/KoreBuild.Tasks/GetToolsets.cs index 2f4edec2c..f2de1a253 100644 --- a/modules/KoreBuild.Tasks/GetToolsets.cs +++ b/modules/KoreBuild.Tasks/GetToolsets.cs @@ -98,7 +98,8 @@ private void GetVisualStudio(KoreBuildSettings.VisualStudioToolset vsToolset) if (vsToolset.Required != KoreBuildSettings.RequiredPlatforms.None) { Log.LogError($"Could not find an installation of Visual Studio that satisifies the specified requirements in '{ConfigFile}'. " + - "Execute `./run.ps1 install vs` to update or install the current VS installation."); + "Execute `./run.ps1 install vs` to update or install the current VS installation. " + + "See https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-community for more details on workloads."); } return; } diff --git a/modules/KoreBuild.Tasks/InstallDotNet.cs b/modules/KoreBuild.Tasks/InstallDotNet.cs index 4f82a83f3..3c055c5ac 100644 --- a/modules/KoreBuild.Tasks/InstallDotNet.cs +++ b/modules/KoreBuild.Tasks/InstallDotNet.cs @@ -19,6 +19,7 @@ namespace KoreBuild.Tasks /// public class InstallDotNet : Microsoft.Build.Utilities.Task, ICancelableTask { + private const string DefaultArch = "x64"; public readonly CancellationTokenSource _cts = new CancellationTokenSource(); /// @@ -86,7 +87,7 @@ private async Task ExecuteAsync() arguments.AddRange(defaultArgs); var arch = string.IsNullOrEmpty(request.Arch) - ? "x64" + ? DefaultArch : request.Arch; arguments.Add("-Architecture"); arguments.Add(arch); @@ -233,19 +234,25 @@ private async Task ExecuteAsync() private string GetInstallDir(string arch) { - if (string.IsNullOrEmpty(DotNetHome)) - { - var dotnetPath = Path.GetDirectoryName(DotNetMuxer.MuxerPath); - return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? Path.Combine(Path.GetDirectoryName(dotnetPath), arch) - : dotnetPath; - } - else - { - return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? Path.Combine(DotNetHome, arch) - : DotNetHome; - } + var shouldInstallToSubfolder = IsDotNetArchEnabled(arch); + var muxerDir = Path.GetDirectoryName(DotNetMuxer.MuxerPath); + var dotnetRootPath = !string.IsNullOrEmpty(DotNetHome) + ? DotNetHome + : shouldInstallToSubfolder + ? Path.GetDirectoryName(muxerDir) + : muxerDir; + + return shouldInstallToSubfolder + ? Path.Combine(dotnetRootPath, arch) + : dotnetRootPath; + } + + private bool IsDotNetArchEnabled(string arch) + { + // Only install to $DOTNET_HOME/x64/ on Windows + // if KOREBUILD_DISABLE_DOTNET_ARCH is undefined or arch != x64 + return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + && (Environment.GetEnvironmentVariable("KOREBUILD_DISABLE_DOTNET_ARCH") == null || !string.Equals(DefaultArch, arch, StringComparison.OrdinalIgnoreCase)); } private IEnumerable CreateAssetRequests() diff --git a/modules/KoreBuild.Tasks/Internal/HashHelper.cs b/modules/KoreBuild.Tasks/Internal/HashHelper.cs deleted file mode 100644 index 0973cf812..000000000 --- a/modules/KoreBuild.Tasks/Internal/HashHelper.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Security.Cryptography; -using System.Text; - -namespace KoreBuild.Tasks -{ - internal class HashHelper - { - public static string GetFileHash(string algorithmName, string filePath) - { - byte[] hash; - using (var stream = File.OpenRead(filePath)) - { - HashAlgorithm algorithm; - switch (algorithmName.ToUpperInvariant()) - { - case "SHA256": - algorithm = new SHA256Managed(); - break; - case "SHA384": - algorithm = new SHA384Managed(); - break; - case "SHA512": - algorithm = new SHA512Managed(); - break; - default: - throw new ArgumentOutOfRangeException($"Unsupported hash algoritm {algorithmName}", nameof(algorithm)); - } - hash = algorithm.ComputeHash(stream); - } - - var sb = new StringBuilder(); - foreach (var b in hash) - { - sb.AppendFormat("{0:X2}", b); - } - - return sb.ToString(); - } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/MSBuildLogger.cs b/modules/KoreBuild.Tasks/Internal/MSBuildLogger.cs deleted file mode 100644 index 458bd698d..000000000 --- a/modules/KoreBuild.Tasks/Internal/MSBuildLogger.cs +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using NuGet.Common; - -namespace NuGet.Build -{ - /// - /// TaskLoggingHelper -> ILogger - /// - internal class MSBuildLogger : LoggerBase, Common.ILogger - { - private readonly TaskLoggingHelper _taskLogging; - - private delegate void LogMessageWithDetails(string subcategory, - string code, - string helpKeyword, - string file, - int lineNumber, - int columnNumber, - int endLineNumber, - int endColumnNumber, - MessageImportance importance, - string message, - params object[] messageArgs); - - private delegate void LogErrorWithDetails(string subcategory, - string code, - string helpKeyword, - string file, - int lineNumber, - int columnNumber, - int endLineNumber, - int endColumnNumber, - string message, - params object[] messageArgs); - - private delegate void LogMessageAsString(MessageImportance importance, - string message, - params object[] messageArgs); - - private delegate void LogErrorAsString(string message, - params object[] messageArgs); - - public MSBuildLogger(TaskLoggingHelper taskLogging) - { - _taskLogging = taskLogging ?? throw new ArgumentNullException(nameof(taskLogging)); - } - - public override void Log(ILogMessage message) - { - if (DisplayMessage(message.Level)) - { - if (RuntimeEnvironmentHelper.IsMono) - { - LogForMono(message); - return; - } - else - { - var logMessage = message as IRestoreLogMessage; - - if (logMessage == null) - { - logMessage = new RestoreLogMessage(message.Level, message.Message) - { - Code = message.Code, - FilePath = message.ProjectPath - }; - } - LogForNonMono(logMessage); - } - } - } - - /// - /// Log using with metadata for non mono platforms. - /// - private void LogForNonMono(IRestoreLogMessage message) - { - switch (message.Level) - { - case LogLevel.Error: - LogError(message, _taskLogging.LogError, _taskLogging.LogError); - break; - - case LogLevel.Warning: - LogError(message, _taskLogging.LogWarning, _taskLogging.LogWarning); - break; - - case LogLevel.Minimal: - LogMessage(message, MessageImportance.High, _taskLogging.LogMessage, _taskLogging.LogMessage); - break; - - case LogLevel.Information: - LogMessage(message, MessageImportance.Normal, _taskLogging.LogMessage, _taskLogging.LogMessage); - break; - - case LogLevel.Debug: - case LogLevel.Verbose: - default: - // Default to LogLevel.Debug and low importance - LogMessage(message, MessageImportance.Low, _taskLogging.LogMessage, _taskLogging.LogMessage); - break; - } - } - - /// - /// Log using basic methods to avoid missing methods on mono. - /// - private void LogForMono(ILogMessage message) - { - switch (message.Level) - { - case LogLevel.Error: - _taskLogging.LogError(message.Message); - break; - - case LogLevel.Warning: - _taskLogging.LogWarning(message.Message); - break; - - case LogLevel.Minimal: - _taskLogging.LogMessage(MessageImportance.High, message.Message); - break; - - case LogLevel.Information: - _taskLogging.LogMessage(MessageImportance.Normal, message.Message); - break; - - case LogLevel.Debug: - case LogLevel.Verbose: - default: - // Default to LogLevel.Debug and low importance - _taskLogging.LogMessage(MessageImportance.Low, message.Message); - break; - } - - return; - } - - private void LogMessage(IRestoreLogMessage logMessage, - MessageImportance importance, - LogMessageWithDetails logWithDetails, - LogMessageAsString logAsString) - { - if (logMessage.Code > NuGetLogCode.Undefined) - { - // NuGet does not currently have a subcategory while throwing logs, hence string.Empty - logWithDetails(string.Empty, - Enum.GetName(typeof(NuGetLogCode), logMessage.Code), - Enum.GetName(typeof(NuGetLogCode), logMessage.Code), - logMessage.FilePath, - logMessage.StartLineNumber, - logMessage.StartColumnNumber, - logMessage.EndLineNumber, - logMessage.EndColumnNumber, - importance, - logMessage.Message); - } - else - { - logAsString(importance, logMessage.Message); - } - } - - private void LogError(IRestoreLogMessage logMessage, - LogErrorWithDetails logWithDetails, - LogErrorAsString logAsString) - { - if (logMessage.Code > NuGetLogCode.Undefined) - { - // NuGet does not currently have a subcategory while throwing logs, hence string.Empty - logWithDetails(string.Empty, - Enum.GetName(typeof(NuGetLogCode), logMessage.Code), - Enum.GetName(typeof(NuGetLogCode), logMessage.Code), - logMessage.FilePath, - logMessage.StartLineNumber, - logMessage.StartColumnNumber, - logMessage.EndLineNumber, - logMessage.EndColumnNumber, - logMessage.Message); - } - else - { - logAsString(logMessage.Message); - } - } - - public override System.Threading.Tasks.Task LogAsync(ILogMessage message) - { - Log(message); - - return System.Threading.Tasks.Task.FromResult(0); - } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/PackageInfo.cs b/modules/KoreBuild.Tasks/Internal/PackageInfo.cs deleted file mode 100644 index b976aabfa..000000000 --- a/modules/KoreBuild.Tasks/Internal/PackageInfo.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using NuGet.Packaging.Core; - -namespace KoreBuild.Tasks.Internal -{ - public class PackageInfo - { - public PackageIdentity Identity { get; set; } - - public string PackagePath { get; set; } - - public override string ToString() - { - return Identity.ToString(); - } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/ProjectModel/DotNetCliReferenceInfo.cs b/modules/KoreBuild.Tasks/Internal/ProjectModel/DotNetCliReferenceInfo.cs deleted file mode 100644 index d4a9712fd..000000000 --- a/modules/KoreBuild.Tasks/Internal/ProjectModel/DotNetCliReferenceInfo.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace KoreBuild.Tasks.ProjectModel -{ - internal class DotNetCliReferenceInfo - { - public DotNetCliReferenceInfo(string id, string version) - { - if (string.IsNullOrEmpty(id)) - { - throw new ArgumentException(nameof(id)); - } - - Id = id; - Version = version; - } - - public string Id { get; } - public string Version { get; } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/ProjectModel/PackageReferenceInfo.cs b/modules/KoreBuild.Tasks/Internal/ProjectModel/PackageReferenceInfo.cs deleted file mode 100644 index 63a9edde8..000000000 --- a/modules/KoreBuild.Tasks/Internal/ProjectModel/PackageReferenceInfo.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; - -namespace KoreBuild.Tasks.ProjectModel -{ - internal class PackageReferenceInfo - { - public PackageReferenceInfo(string id, string version, bool isImplicitlyDefined, IReadOnlyList noWarn) - { - if (string.IsNullOrEmpty(id)) - { - throw new ArgumentException(nameof(id)); - } - - Id = id; - Version = version; - IsImplicitlyDefined = isImplicitlyDefined; - NoWarn = noWarn; - } - - public string Id { get; } - public string Version { get; } - public bool IsImplicitlyDefined { get; } - public IReadOnlyList NoWarn { get; } - public ProjectInfo Project { get; internal set; } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/ProjectModel/ProjectFrameworkInfo.cs b/modules/KoreBuild.Tasks/Internal/ProjectModel/ProjectFrameworkInfo.cs deleted file mode 100644 index ee0f9d3db..000000000 --- a/modules/KoreBuild.Tasks/Internal/ProjectModel/ProjectFrameworkInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using NuGet.Frameworks; - -namespace KoreBuild.Tasks.ProjectModel -{ - internal class ProjectFrameworkInfo - { - public ProjectFrameworkInfo(NuGetFramework targetFramework, IReadOnlyDictionary dependencies) - { - TargetFramework = targetFramework ?? throw new ArgumentNullException(nameof(targetFramework)); - Dependencies = dependencies ?? throw new ArgumentNullException(nameof(dependencies)); - } - - public NuGetFramework TargetFramework { get; } - public IReadOnlyDictionary Dependencies { get; } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/ProjectModel/ProjectInfo.cs b/modules/KoreBuild.Tasks/Internal/ProjectModel/ProjectInfo.cs deleted file mode 100644 index 95dc0780f..000000000 --- a/modules/KoreBuild.Tasks/Internal/ProjectModel/ProjectInfo.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace KoreBuild.Tasks.ProjectModel -{ - internal class ProjectInfo - { - public ProjectInfo(string fullPath, - string projectExtensionsPath, - IReadOnlyList frameworks, - IReadOnlyList tools) - { - if (!Path.IsPathRooted(fullPath)) - { - throw new ArgumentException("Path must be absolute", nameof(fullPath)); - } - - Frameworks = frameworks ?? throw new ArgumentNullException(nameof(frameworks)); - Tools = tools ?? throw new ArgumentNullException(nameof(tools)); - - FullPath = fullPath; - FileName = Path.GetFileName(fullPath); - Directory = Path.GetDirectoryName(FullPath); - ProjectExtensionsPath = projectExtensionsPath ?? Path.Combine(Directory, "obj"); - - foreach (var dep in frameworks.SelectMany(f => f.Dependencies)) - { - dep.Value.Project = this; - } - } - - public string FullPath { get; } - public string FileName { get; } - public string ProjectExtensionsPath { get; } - public string Directory { get; } - - public IReadOnlyList Frameworks { get; } - public IReadOnlyList Tools { get; } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/ProjectModel/ProjectInfoFactory.cs b/modules/KoreBuild.Tasks/Internal/ProjectModel/ProjectInfoFactory.cs deleted file mode 100644 index 65e5879dc..000000000 --- a/modules/KoreBuild.Tasks/Internal/ProjectModel/ProjectInfoFactory.cs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.BuildTools; -using Microsoft.Build.Construction; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Execution; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using NuGet.Frameworks; - -namespace KoreBuild.Tasks.ProjectModel -{ - internal class ProjectInfoFactory - { - private readonly TaskLoggingHelper _logger; - - public ProjectInfoFactory(TaskLoggingHelper logger) - { - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - } - - public IReadOnlyList CreateMany(ITaskItem[] projectItems, string[] properties, bool policyDesignBuild, CancellationToken token) - { - if (projectItems == null) - { - return Array.Empty(); - } - - var cts = new CancellationTokenSource(); - token.Register(() => cts.Cancel()); - var solutionProps = MSBuildListSplitter.GetNamedProperties(properties); - var projectFiles = projectItems.SelectMany(p => SolutionInfoFactory.GetProjects(p, solutionProps)).Distinct(); - var projects = new ConcurrentBag(); - var stop = Stopwatch.StartNew(); - - Parallel.ForEach(projectFiles, projectFile => - { - if (cts.Token.IsCancellationRequested) - { - return; - } - - try - { - projects.Add(Create(projectFile, policyDesignBuild)); - } - catch (Exception ex) - { - _logger.LogErrorFromException(ex); - cts.Cancel(); - } - }); - - stop.Stop(); - _logger.LogMessage(MessageImportance.Low, $"Finished design-time build in {stop.ElapsedMilliseconds}ms"); - return projects.ToArray(); - } - - public ProjectInfo Create(string path, bool policyDesignBuild) - { - var project = GetProject(path, ProjectCollection.GlobalProjectCollection, policyDesignBuild); - var instance = project.CreateProjectInstance(ProjectInstanceSettings.ImmutableWithFastItemLookup); - var projExtPath = instance.GetPropertyValue("MSBuildProjectExtensionsPath"); - - var targetFrameworks = instance.GetPropertyValue("TargetFrameworks"); - var targetFramework = instance.GetPropertyValue("TargetFramework"); - - var frameworks = new List(); - if (!string.IsNullOrEmpty(targetFrameworks) && string.IsNullOrEmpty(targetFramework)) - { - // multi targeting - foreach (var tfm in targetFrameworks.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) - { - project.SetGlobalProperty("TargetFramework", tfm); - var innerBuild = project.CreateProjectInstance(ProjectInstanceSettings.ImmutableWithFastItemLookup); - - var tfmInfo = new ProjectFrameworkInfo(NuGetFramework.Parse(tfm), GetDependencies(innerBuild)); - - frameworks.Add(tfmInfo); - } - - project.RemoveGlobalProperty("TargetFramework"); - } - else if (!string.IsNullOrEmpty(targetFramework)) - { - var tfmInfo = new ProjectFrameworkInfo(NuGetFramework.Parse(targetFramework), GetDependencies(instance)); - - frameworks.Add(tfmInfo); - } - - var projectDir = Path.GetDirectoryName(path); - - var tools = GetTools(instance).ToArray(); - - return new ProjectInfo(path, projExtPath, frameworks, tools); - } - - private static Project GetProject(string path, ProjectCollection projectCollection, bool policyDesignBuild) - { - var projects = projectCollection.GetLoadedProjects(path); - foreach (var proj in projects) - { - if (proj.GetPropertyValue("DesignTimeBuild") == "true") - { - return proj; - } - } - var xml = ProjectRootElement.Open(path, projectCollection); - var globalProps = new Dictionary() - { - ["DesignTimeBuild"] = "true", - }; - if (policyDesignBuild) - { - globalProps["PolicyDesignTimeBuild"] = "true"; - } - var project = new Project(xml, - globalProps, - toolsVersion: "15.0", - projectCollection: projectCollection) - { - IsBuildEnabled = false - }; - return project; - } - - private IReadOnlyDictionary GetDependencies(ProjectInstance project) - { - var references = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var item in project.GetItems("PackageReference")) - { - bool.TryParse(item.GetMetadataValue("IsImplicitlyDefined"), out var isImplicit); - var noWarn = item.GetMetadataValue("NoWarn"); - IReadOnlyList noWarnItems = string.IsNullOrEmpty(noWarn) - ? Array.Empty() - : noWarn.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); - - var info = new PackageReferenceInfo(item.EvaluatedInclude, item.GetMetadataValue("Version"), isImplicit, noWarnItems); - - if (references.ContainsKey(info.Id)) - { - _logger.LogKoreBuildWarning(project.ProjectFileLocation.File, KoreBuildErrors.DuplicatePackageReference, $"Found a duplicate PackageReference for {info.Id}. Restore results may be unpredictable."); - } - - references[info.Id] = info; - } - - return references; - } - - private static IEnumerable GetTools(ProjectInstance project) - { - return project.GetItems("DotNetCliToolReference").Select(item => - new DotNetCliReferenceInfo(item.EvaluatedInclude, item.GetMetadataValue("Version"))); - } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/ProjectModel/SolutionInfo.cs b/modules/KoreBuild.Tasks/Internal/ProjectModel/SolutionInfo.cs deleted file mode 100644 index d968438cb..000000000 --- a/modules/KoreBuild.Tasks/Internal/ProjectModel/SolutionInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; - -namespace KoreBuild.Tasks.ProjectModel -{ - internal class SolutionInfo - { - public SolutionInfo(string fullPath, IReadOnlyList projects) - { - if (string.IsNullOrEmpty(fullPath)) - { - throw new ArgumentException(nameof(fullPath)); - } - - FullPath = fullPath; - Projects = projects ?? throw new ArgumentNullException(nameof(projects)); - } - - public string FullPath { get; } - - public IReadOnlyList Projects { get; } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/ProjectModel/SolutionInfoFactory.cs b/modules/KoreBuild.Tasks/Internal/ProjectModel/SolutionInfoFactory.cs deleted file mode 100644 index 18d2a2550..000000000 --- a/modules/KoreBuild.Tasks/Internal/ProjectModel/SolutionInfoFactory.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.AspNetCore.BuildTools; -using Microsoft.Build.Construction; -using Microsoft.Build.Framework; - -namespace KoreBuild.Tasks.ProjectModel -{ - internal class SolutionInfoFactory - { - public static SolutionInfo Create(string filePath, string configName) - { - var sln = SolutionFile.Parse(filePath); - - if (string.IsNullOrEmpty(configName)) - { - configName = sln.GetDefaultConfigurationName(); - } - - var projects = new List(); - - var config = sln.SolutionConfigurations.FirstOrDefault(c => c.ConfigurationName == configName); - if (config == null) - { - throw new InvalidOperationException($"A solution configuration by the name of '{configName}' was not found in '{filePath}'"); - } - - foreach (var project in sln.ProjectsInOrder - .Where(p => - p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat // skips solution folders - && p.ProjectConfigurations.TryGetValue(config.FullName, out var projectConfig) - && projectConfig.IncludeInBuild)) - { - projects.Add(project.AbsolutePath.Replace('\\', '/')); - } - - return new SolutionInfo(filePath, projects.ToArray()); - } - - public static IEnumerable GetProjects(ITaskItem projectOrSolution, IDictionary solutionProperties) - { - var projectFilePath = projectOrSolution.ItemSpec.Replace('\\', '/'); - - if (Path.GetExtension(projectFilePath).Equals(".sln", StringComparison.OrdinalIgnoreCase)) - { - // prefer the AdditionalProperties metadata as this is what the MSBuild task will use when building solutions - var props = MSBuildListSplitter.GetNamedProperties(projectOrSolution.GetMetadata("AdditionalProperties")); - props.TryGetValue("Configuration", out var config); - - if (config == null) - { - solutionProperties.TryGetValue("Configuration", out config); - } - - var sln = Create(projectFilePath, config); - - foreach (var project in sln.Projects) - { - yield return project; - } - } - else - { - yield return Path.GetFullPath(projectFilePath); - } - } - } -} diff --git a/modules/KoreBuild.Tasks/Internal/SimplePackageInstaller.cs b/modules/KoreBuild.Tasks/Internal/SimplePackageInstaller.cs deleted file mode 100644 index c9011c606..000000000 --- a/modules/KoreBuild.Tasks/Internal/SimplePackageInstaller.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using NuGet.Commands; -using NuGet.Common; -using NuGet.DependencyResolver; -using NuGet.LibraryModel; -using NuGet.Packaging; -using NuGet.Packaging.Core; -using NuGet.Packaging.Signing; -using NuGet.Protocol.Core.Types; - -namespace KoreBuild.Tasks.Utilities -{ - internal class SimplePackageInstaller - { - private readonly string _packagesDirectory; - private readonly ILogger _logger; - private readonly SourceCacheContext _cacheContext; - private readonly int _maxDegreeOfConcurrency; - - public SimplePackageInstaller(string packageDir, SourceCacheContext cacheContext, bool disableParallel, ILogger logger) - { - _packagesDirectory = packageDir; - _cacheContext = cacheContext; - _logger = logger; - _maxDegreeOfConcurrency = disableParallel ? 1 : 16; - } - - public async Task InstallPackagesAsync(IEnumerable graphs, - HashSet allInstalledPackages, - CancellationToken token) - { - var packagesToInstall = graphs.SelectMany(g => g.Install.Where(match => allInstalledPackages.Add(match.Library))); - if (_maxDegreeOfConcurrency <= 1) - { - foreach (var match in packagesToInstall) - { - await InstallPackageAsync(match, token); - } - } - else - { - var bag = new ConcurrentBag(packagesToInstall); - var tasks = Enumerable.Range(0, _maxDegreeOfConcurrency) - .Select(async _ => - { - while (bag.TryTake(out RemoteMatch match)) - { - await InstallPackageAsync(match, token); - } - }); - await Task.WhenAll(tasks); - } - } - - private async Task InstallPackageAsync(RemoteMatch installItem, CancellationToken token) - { - var packageIdentity = new PackageIdentity(installItem.Library.Name, installItem.Library.Version); - - var verificationProviders = SignatureVerificationProviderFactory.GetSignatureVerificationProviders(); - var signedPackageVerifier = new PackageSignatureVerifier(verificationProviders, SignedPackageVerifierSettings.VerifyCommandDefaultPolicy); - - var versionFolderPathResolver = new VersionFolderPathResolver(_packagesDirectory); - var packageExtractionContext = new PackageExtractionContext( - PackageSaveMode.Defaultv3, - XmlDocFileSaveMode.None, - _logger, - signedPackageVerifier); - - using (var packageDependency = await installItem.Provider.GetPackageDownloaderAsync( - packageIdentity, - _cacheContext, - _logger, - token)) - { - await PackageExtractor.InstallFromSourceAsync( - packageIdentity, - packageDependency, - versionFolderPathResolver, - packageExtractionContext, - token); - } - } - } -} diff --git a/modules/KoreBuild.Tasks/KoreBuild.Tasks.csproj b/modules/KoreBuild.Tasks/KoreBuild.Tasks.csproj index 6147092aa..d1346531e 100644 --- a/modules/KoreBuild.Tasks/KoreBuild.Tasks.csproj +++ b/modules/KoreBuild.Tasks/KoreBuild.Tasks.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -9,22 +9,19 @@ - - + + - - + - - diff --git a/tools/KoreBuildSettings.cs b/modules/KoreBuild.Tasks/KoreBuildSettings.cs similarity index 100% rename from tools/KoreBuildSettings.cs rename to modules/KoreBuild.Tasks/KoreBuildSettings.cs diff --git a/modules/KoreBuild.Tasks/PackNuSpec.cs b/modules/KoreBuild.Tasks/PackNuSpec.cs deleted file mode 100644 index f711a4fbb..000000000 --- a/modules/KoreBuild.Tasks/PackNuSpec.cs +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Linq; -using Microsoft.AspNetCore.BuildTools; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using NuGet.Frameworks; -using NuGet.Packaging; -using NuGet.Packaging.Core; -using NuGet.Versioning; - -namespace KoreBuild.Tasks -{ - /// - /// Generates a nupkg from a nuspec file - /// - public class PackNuSpec : Microsoft.Build.Utilities.Task - { - /// - /// The path the nuspec file. - /// - [Required] - public string NuspecPath { get; set; } - - /// - /// Output nupkg is placed in folder + '$(id).$(version).nupkg'. - /// Either this or must be specified. - /// - public string DestinationFolder { get; set; } - - /// - /// The output path for the nupkg. - /// Either this or must be specified. - /// - public string OutputPath { get; set; } - - /// - /// The base path to use for any relative paths in the <files%gt; section of nuspec. - /// Defaults to the nuspec folder. - /// - public string BasePath { get; set; } - - /// - /// Dependencies to add to the metadata>dependencies section of the spec. - /// Metadata 'TargetFramework' can be specified to further put dependencies into >group[targetFramework] - /// - public ITaskItem[] Dependencies { get; set; } - - /// - /// Files to add to the package. Must specify the PackagePath metadata. - /// - public ITaskItem[] PackageFiles { get; set; } - - /// - /// Subsitution in the nuspec via $key$. - /// - public string[] Properties { get; set; } - - /// - /// Pack empty directories. - /// - public bool IncludeEmptyDirectories { get; set; } = false; - - /// - /// Overwrite the destination file if it exists. - /// - public bool Overwrite { get; set; } = false; - - /// - /// The nupkg files created - /// - [Output] - public ITaskItem[] Packages { get; set; } - - public override bool Execute() - { - if (!File.Exists(NuspecPath)) - { - Log.LogError("Nuspec does not exist: " + NuspecPath); - return false; - } - - var packageBasePath = string.IsNullOrEmpty(BasePath) - ? Path.GetDirectoryName(NuspecPath) - : BasePath; - - if (!Directory.Exists(packageBasePath)) - { - Log.LogError("Base path does not exist: " + packageBasePath); - return false; - } - - if (!(string.IsNullOrEmpty(DestinationFolder) ^ string.IsNullOrEmpty(OutputPath))) - { - Log.LogError("Either DestinationFolder and OutputPath must be specified, but only not both."); - return false; - } - - var properties = MSBuildListSplitter.GetNamedProperties(Properties); - - string PropertyProvider(string name) - { - if (properties.TryGetValue(name, out var value)) - { - return value; - } - Log.LogError("Undefined property: " + name); - return null; - } - - PackageBuilder packageBuilder; - try - { - Log.LogMessage($"Loading nuspec {NuspecPath}"); - - using (var file = File.OpenRead(NuspecPath)) - { - var manifest = Manifest.ReadFrom(file, PropertyProvider, validateSchema: false); - if (!manifest.HasFilesNode) - { - // Warn about this overly permissive default in nuspec. - Log.LogKoreBuildWarning(KoreBuildErrors.NuspecMissingFilesNode, - "The nuspec file is missing the nodes. This causes all files in NuspecBase to be included in the package. " + - @"Add an empty `` node to prevent this behavior. Add ` ` to the nuspec to suppress this warning."); - } - } - - packageBuilder = new PackageBuilder(NuspecPath, packageBasePath, PropertyProvider, IncludeEmptyDirectories); - } - catch (InvalidDataException ex) - { - Log.LogKoreBuildError(NuspecPath, KoreBuildErrors.InvalidNuspecFile, ex.Message); - return false; - } - - if (Dependencies != null) - { - AddDependencies(packageBuilder); - } - - if (PackageFiles != null) - { - AddFiles(packageBuilder); - } - - if (Log.HasLoggedErrors) - { - return false; - } - - var dest = !string.IsNullOrEmpty(OutputPath) - ? OutputPath - : Path.Combine(DestinationFolder, $"{packageBuilder.Id}.{packageBuilder.Version}.nupkg"); - - // normalize path - dest = Path.GetFullPath(dest); - - Directory.CreateDirectory(Path.GetDirectoryName(dest)); - - if (!Overwrite && File.Exists(dest)) - { - Log.LogError($"File path '{dest}' already exists. Set Overwrite=true to overwrite the destination nupkg file."); - return false; - } - - if (packageBuilder.Files != null) - { - foreach (var file in packageBuilder.Files) - { - if (file is PhysicalPackageFile p) - { - Log.LogMessage($"Packing {p.SourcePath} => {p.Path}"); - } - else - { - Log.LogMessage($"Packing {file.Path}"); - } - } - } - - using (var stream = File.Create(dest)) - { - packageBuilder.Save(stream); - } - - Log.LogMessage(MessageImportance.High, $"Created package {dest}"); - Packages = new[] { new TaskItem(dest) }; - - return true; - } - - private void AddFiles(PackageBuilder builder) - { - foreach (var file in PackageFiles) - { - var packagePath = file.GetMetadata("PackagePath"); - var fileName = Path.GetFileName(packagePath); - if (string.IsNullOrEmpty(fileName)) - { - Log.LogKoreBuildError(KoreBuildErrors.InvalidPackagePathMetadata, - "The PackagePath metadata value on {0} is invalid. PackagePath must be set to the exact file path within the nuget package."); - continue; - } - - builder.Files.Add(new PhysicalPackageFile - { - SourcePath = file.ItemSpec, - TargetPath = packagePath, - }); - } - } - - private void AddDependencies(PackageBuilder builder) - { - var packageRequest = Dependencies.Select(d => - { - NuGetFramework tfm = NuGetFramework.AnyFramework; - if (!string.IsNullOrEmpty(d.GetMetadata("TargetFramework"))) - { - tfm = NuGetFramework.Parse(d.GetMetadata("TargetFramework")); - } - - if (string.IsNullOrEmpty(d.GetMetadata("Version"))) - { - Log.LogError($"Dependency {d.ItemSpec} is missing expected metdata: Version"); - } - - return new - { - tfm, - dependency = new PackageDependency(d.ItemSpec, - VersionRange.Parse(d.GetMetadata("Version")), - d.GetMetadata("IncludeAssets").Split(';').Select(s => s.Trim()).ToArray(), - d.GetMetadata("ExcludeAssets").Split(';').Select(s => s.Trim()).ToArray()) - }; - }); - - foreach (var group in packageRequest.GroupBy(g => g.tfm)) - { - var existingPackages = builder.DependencyGroups.FirstOrDefault(g => g.TargetFramework == group.Key)?.Packages - ?? Enumerable.Empty(); - - var depGroup = new PackageDependencyGroup(group.Key, existingPackages.Concat(group.Select(d => d.dependency))); - builder.DependencyGroups.Add(depGroup); - } - } - } -} diff --git a/modules/KoreBuild.Tasks/PushNuGetPackages.cs b/modules/KoreBuild.Tasks/PushNuGetPackages.cs deleted file mode 100644 index ae564dc98..000000000 --- a/modules/KoreBuild.Tasks/PushNuGetPackages.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Concurrent; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Build.Framework; -using NuGet.Common; -using NuGet.Packaging; -using NuGet.Protocol; -using NuGet.Protocol.Core.Types; -using KoreBuild.Tasks.Internal; - -namespace KoreBuild.Tasks -{ - public class PushNuGetPackages : Microsoft.Build.Utilities.Task, ICancelableTask - { - private const int _maxRetryCount = 5; - private const int _maxParallelPackagePushes = 4; - - private ConcurrentBag _packages; - private readonly CancellationTokenSource _packagePushCancellationTokenSource = new CancellationTokenSource(); - - [Required] - public ITaskItem[] Packages { get; set; } - - [Required] - public string Feed { get; set; } - - // not be required if pushing to the filesystem - public string ApiKey { get; set; } - - public int TimeoutSeconds { get; set; } = 300; - - public void Cancel() - { - _packagePushCancellationTokenSource.Cancel(); - } - - public override bool Execute() - { - if (Packages.Length == 0) - { - Log.LogWarning("No package files were found to be published."); - return true; - } - - if (string.IsNullOrEmpty(Feed)) - { - Log.LogError("Feed must not be null or empty."); - return false; - } - - var packages = Packages - .Select(fileInfo => - { - using (var fileStream = File.OpenRead(fileInfo.ItemSpec)) - using (var reader = new PackageArchiveReader(fileStream)) - { - return new PackageInfo - { - Identity = reader.GetIdentity(), - PackagePath = fileInfo.ItemSpec - }; - } - }); - - _packages = new ConcurrentBag(packages); - - Log.LogMessage(MessageImportance.High, "Attempting to push {0} package(s) to {1}", Packages.Length, Feed); - try - { - PublishToFeedAsync().GetAwaiter().GetResult(); - Log.LogMessage(MessageImportance.High, "Successfully pushed {0} package(s) to {1}", Packages.Length, Feed); - return true; - } - catch (Exception ex) - { - Log.LogErrorFromException(ex, showStackTrace: true); - return false; - } - } - - private async Task PublishToFeedAsync() - { - Log.LogMessage("Publishing packages to feed: {0}", Feed); - - var sourceRepository = Repository.Factory.GetCoreV3(Feed, FeedType.HttpV3); - var packageUpdateResource = await sourceRepository.GetResourceAsync(); - - var tasks = new Task[_maxParallelPackagePushes]; - for (var i = 0; i < tasks.Length; i++) - { - tasks[i] = PushPackagesAsync(packageUpdateResource); - } - - await Task.WhenAll(tasks); - } - - private async Task PushPackagesAsync(PackageUpdateResource packageUpdateResource) - { - while (_packages.TryTake(out var package)) - { - await PushPackageAsync(packageUpdateResource, package); - } - } - - private async Task PushPackageAsync(PackageUpdateResource packageUpdateResource, PackageInfo package) - { - for (var attempt = 1; attempt <= _maxRetryCount; attempt++) - { - // Fail fast if a parallel push operation has already failed - _packagePushCancellationTokenSource.Token.ThrowIfCancellationRequested(); - - Log.LogMessage($"Attempting to publish package {package.Identity} (Attempt: {attempt})"); - - try - { - await packageUpdateResource.Push( - package.PackagePath, - symbolSource: null, - timeoutInSecond: TimeoutSeconds, - disableBuffering: false, - getApiKey: _ => ApiKey, - getSymbolApiKey: _ => null, - noServiceEndpoint: false, - log: NullLogger.Instance); - - Log.LogMessage(MessageImportance.High, $"Published package {package.Identity}"); - - return; - } - catch (Exception ex) when (attempt < _maxRetryCount) // allow exception to be thrown at the last attempt - { - Log.LogMessage( - MessageImportance.High, - $"Attempt {attempt} failed to publish package {package.Identity}." + - Environment.NewLine + - ex + - Environment.NewLine + - "Retrying..."); - } - catch - { - _packagePushCancellationTokenSource.Cancel(); - throw; - } - } - } - } -} diff --git a/modules/KoreBuild.Tasks/SkipStrongName/AssembliesFile.cs b/modules/KoreBuild.Tasks/SkipStrongName/AssembliesFile.cs deleted file mode 100644 index 9fb2343be..000000000 --- a/modules/KoreBuild.Tasks/SkipStrongName/AssembliesFile.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Xml.Linq; - -namespace KoreBuild.Tasks.SkipStrongNames -{ - internal static class AssembliesFile - { - public static AssemblySpecification[] Read(string path) - { - XElement assembliesElement = XElement.Load(path); - - if (assembliesElement.Name != "assemblies") - { - throw new InvalidOperationException("The name of the root element must be assemblies."); - } - - XAttribute defaultPublicKeyTokenAttribute = assembliesElement.Attribute("defaultPublicKeyToken"); - - string defaultPublicKeyToken; - - if (defaultPublicKeyTokenAttribute != null) - { - defaultPublicKeyToken = defaultPublicKeyTokenAttribute.Value; - } - else - { - defaultPublicKeyToken = null; - } - - List specifications = new List(); - - foreach (XElement assembly in assembliesElement.Elements("assembly")) - { - XAttribute nameAttribute = assembly.Attribute("name"); - - if (nameAttribute == null) - { - throw new InvalidOperationException("An assembly element must have a name attribute."); - } - - XAttribute publicKeyTokenAttribute = assembly.Attribute("publicKeyToken"); - string publicKeyToken; - - if (publicKeyTokenAttribute != null) - { - publicKeyToken = publicKeyTokenAttribute.Value; - } - else - { - publicKeyToken = defaultPublicKeyToken; - } - - if (publicKeyToken == null) - { - throw new InvalidOperationException("An assembly element must have a publicKeyToken attribute, " + - "or the assemblies element must have a defaultPublicKeyToken attribute."); - } - - specifications.Add(new AssemblySpecification - { - Name = nameAttribute.Value, - PublicKeyToken = publicKeyToken - }); - } - - if (specifications.Count == 0) - { - throw new InvalidOperationException( - "The assemblies element must contain at least one assembly element."); - } - - return specifications.ToArray(); - } - } -} diff --git a/modules/KoreBuild.Tasks/SkipStrongName/AssemblySpecification.cs b/modules/KoreBuild.Tasks/SkipStrongName/AssemblySpecification.cs deleted file mode 100644 index 5f6798254..000000000 --- a/modules/KoreBuild.Tasks/SkipStrongName/AssemblySpecification.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace KoreBuild.Tasks.SkipStrongNames -{ - internal class AssemblySpecification - { - public string Name { get; set; } - - public string PublicKeyToken { get; set; } - - public override string ToString() - { - return Name + "," + PublicKeyToken; - } - } -} diff --git a/modules/KoreBuild.Tasks/SkipStrongName/RegistrySection.cs b/modules/KoreBuild.Tasks/SkipStrongName/RegistrySection.cs deleted file mode 100644 index 2999ae1d0..000000000 --- a/modules/KoreBuild.Tasks/SkipStrongName/RegistrySection.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace KoreBuild.Tasks.SkipStrongNames -{ - public enum RegistrySection - { - Native, - Windows32OnWindows64 - } -} diff --git a/modules/KoreBuild.Tasks/SkipStrongName/Status.cs b/modules/KoreBuild.Tasks/SkipStrongName/Status.cs deleted file mode 100644 index 2f37811fe..000000000 --- a/modules/KoreBuild.Tasks/SkipStrongName/Status.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace KoreBuild.Tasks.SkipStrongNames -{ - public enum Status - { - Disabled, - Enabled, - PartiallyEnabled, - } -} diff --git a/modules/KoreBuild.Tasks/SkipStrongName/StrongNameConfiguration.cs b/modules/KoreBuild.Tasks/SkipStrongName/StrongNameConfiguration.cs deleted file mode 100644 index 80dedffc5..000000000 --- a/modules/KoreBuild.Tasks/SkipStrongName/StrongNameConfiguration.cs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace KoreBuild.Tasks.SkipStrongNames -{ - internal class StrongNameConfiguration - { - private readonly Dictionary> _strongNameExclusions; - private readonly AssemblySpecification[] _assemblies; - - public StrongNameConfiguration(AssemblySpecification[] specifications) - { - if (specifications != null) - { - _assemblies = specifications.OrderBy(s => s.Name).ToArray(); - } - else - { - _assemblies = null; - } - - FilteredAssemblySpecifications = new Dictionary(); - _strongNameExclusions = new Dictionary>(); - - foreach (RegistrySection section in WindowsRegistry.Sections) - { - HashSet sectionExclusions = WindowsRegistry.LoadStrongNameExclusions(section); - string[] sectionFilteredAssemblies = FilterAssemblySpecifications(_assemblies, sectionExclusions); - - FilteredAssemblySpecifications.Add(section, sectionFilteredAssemblies); - _strongNameExclusions.Add(section, sectionExclusions); - } - } - - public Dictionary FilteredAssemblySpecifications { get; private set; } - - public Status Status - { - get - { - bool allFound = true; - bool anyFound = false; - - foreach (RegistrySection section in WindowsRegistry.Sections) - { - string[] sectionFilteredAssemblies = FilteredAssemblySpecifications[section]; - HashSet sectionExclusions = _strongNameExclusions[section]; - - foreach (string assemblySpecification in sectionFilteredAssemblies) - { - bool found = sectionExclusions.Contains(assemblySpecification); - allFound = allFound && found; - anyFound = anyFound || found; - - if (!allFound && anyFound) - { - break; - } - } - } - - if (allFound) - { - return Status.Enabled; - } - else if (anyFound) - { - return Status.PartiallyEnabled; - } - else - { - return Status.Disabled; - } - } - } - - private string[] FilterAssemblySpecifications(AssemblySpecification[] assemblies, HashSet exclusions) - { - if (assemblies == null || assemblies.Length == 0) - { - return new string[0]; - } - - // Determine whether strong name verification is disabled globally (with a "*,*" entry). - if (exclusions.Contains("*,*")) - { - return new string[0]; - } - - // Get a list of the public key tokens that are globally excluded (with a "*,PublicKeyToken" entry) - HashSet globallyExcludedPublicKeyTokens = new HashSet(StringComparer.InvariantCultureIgnoreCase); - - foreach (var publicKeyToken in assemblies.Select(a => a.PublicKeyToken.ToUpperInvariant()).Distinct()) - { - if (exclusions.Contains("*," + publicKeyToken)) - { - globallyExcludedPublicKeyTokens.Add(publicKeyToken); - } - } - - // Create specifications for the list of the assemblies not covered by a global exclusion - return (from element in assemblies - where !globallyExcludedPublicKeyTokens.Contains(element.PublicKeyToken) - select element.ToString()).ToArray(); - } - } -} diff --git a/modules/KoreBuild.Tasks/SkipStrongName/WindowsRegistry.cs b/modules/KoreBuild.Tasks/SkipStrongName/WindowsRegistry.cs deleted file mode 100644 index 6e7a5aae8..000000000 --- a/modules/KoreBuild.Tasks/SkipStrongName/WindowsRegistry.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using Microsoft.Win32; - -namespace KoreBuild.Tasks.SkipStrongNames -{ - internal static class WindowsRegistry - { - private const string SoftwareNativeKeyName = "SOFTWARE"; - private const string SoftwareWowKeyName = @"SOFTWARE\Wow6432Node"; - private const string VerificationSubKeyName = @"Microsoft\StrongName\Verification"; - - private static readonly Lazy softwareWowExists = new Lazy(() => CheckRegistryKeyExists(SoftwareWowKeyName)); - - public static IEnumerable Sections - { - get - { - yield return RegistrySection.Native; - - if (softwareWowExists.Value) - { - yield return RegistrySection.Windows32OnWindows64; - } - } - } - - public static RegistryKey CreateWritableVerificationRegistryKey(RegistrySection section) - { - return CreateWriteableRegistryKey(GetBaseKeyName(section), VerificationSubKeyName); - } - - public static HashSet LoadStrongNameExclusions(RegistrySection section) - { - HashSet results = new HashSet(StringComparer.OrdinalIgnoreCase); - - using (RegistryKey key = OpenReadOnlyVerificationRegistryKey(section)) - { - if (key != null) - { - foreach (var subKey in key.GetSubKeyNames()) - { - results.Add(subKey); - } - } - } - - return results; - } - - private static bool CheckRegistryKeyExists(string name) - { - using (RegistryKey key = OpenReadOnlyRegistryKey(name)) - { - return key != null; - } - } - - private static RegistryKey CreateWriteableRegistryKey(string baseKeyName, string subKeyName) - { - List keysToDispose = new List(); - - try - { - RegistryKey currentKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(baseKeyName, writable: true); - - if (currentKey == null) - { - return null; - } - - string[] subKeyParts = subKeyName.Split('\\'); - - foreach (string subKeyPart in subKeyParts) - { - keysToDispose.Add(currentKey); - currentKey = currentKey.CreateSubKey(subKeyPart); - } - - return currentKey; - } - finally - { - foreach (RegistryKey key in keysToDispose) - { - key.Dispose(); - } - } - } - - private static string GetBaseKeyName(RegistrySection section) - { - switch (section) - { - case RegistrySection.Windows32OnWindows64: - return SoftwareWowKeyName; - case RegistrySection.Native: - default: - return SoftwareNativeKeyName; - } - } - - private static RegistryKey OpenReadOnlyRegistryKey(string name) - { - return Microsoft.Win32.Registry.LocalMachine.OpenSubKey(name); - } - - private static RegistryKey OpenReadOnlyVerificationRegistryKey(RegistrySection section) - { - string keyName = GetBaseKeyName(section) + '\\' + VerificationSubKeyName; - return OpenReadOnlyRegistryKey(keyName); - } - } -} diff --git a/modules/KoreBuild.Tasks/SkipStrongNames.xml b/modules/KoreBuild.Tasks/SkipStrongNames.xml deleted file mode 100644 index 3457d438e..000000000 --- a/modules/KoreBuild.Tasks/SkipStrongNames.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/modules/KoreBuild.Tasks/UpgradeDependencies.cs b/modules/KoreBuild.Tasks/UpgradeDependencies.cs deleted file mode 100644 index 4e5ca9006..000000000 --- a/modules/KoreBuild.Tasks/UpgradeDependencies.cs +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using System.Xml; -using KoreBuild.Tasks.Utilities; -using Microsoft.Build.Construction; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Framework; -using NuGet.Build; -using NuGet.Configuration; -using NuGet.Packaging; -using NuGet.Packaging.Core; -using NuGet.Protocol; -using NuGet.Protocol.Core.Types; -using NuGet.Versioning; - -namespace KoreBuild.Tasks -{ - /// - /// Uses a remote package to update the version variables in the local dependencies.props file - /// - public class UpgradeDependencies : Microsoft.Build.Utilities.Task, ICancelableTask - { - private CancellationTokenSource _cts = new CancellationTokenSource(); - - /// - /// The lineup package ID of the nupkg that contains the master dependencies.props files that will be used to upgrade versions - /// - [Required] - public string LineupPackageId { get; set; } - - /// - /// The version of the lineup package. If empty, this will attempt to pull the latest - /// - public string LineupPackageVersion { get; set; } - - /// - /// The dependencies.props file to use versions from - /// - public string LineupDependenciesFile { get; set; } - - /// - /// The NuGet feed containing the lineup package - /// - [Required] - public string LineupPackageRestoreSource { get; set; } - - /// - /// The dependencies.props file to update - /// - [Required] - public string DependenciesFile { get; set; } - - public void Cancel() - { - _cts.Cancel(); - } - - public override bool Execute() - { - return ExecuteAsync().GetAwaiter().GetResult(); - } - - public async Task ExecuteAsync() - { - if (!DependencyVersionsFile.TryLoad(DependenciesFile, out var localVersionsFile)) - { - Log.LogError($"Could not load file from {DependenciesFile}"); - return false; - } - - if (!localVersionsFile.HasVersionsPropertyGroup) - { - Log.LogKoreBuildWarning(KoreBuildErrors.PackageRefPropertyGroupNotFound, $"No PropertyGroup with Label=\"{DependencyVersionsFile.PackageVersionsLabel}\" could be found in {DependenciesFile}"); - } - - if (localVersionsFile.VersionVariables.Count == 0) - { - Log.LogMessage(MessageImportance.High, $"No version variables could be found in {DependenciesFile}"); - return true; - } - - - var tmpNupkgPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - var logger = new MSBuildLogger(Log); - - try - { - var remoteDepsVersionFile = await TryDownloadLineupDepsFile() ?? await TryDownloadLineupPackage(logger, tmpNupkgPath); - - if (remoteDepsVersionFile == null) - { - return false; - } - - var updateCount = UpdateDependencies(localVersionsFile, remoteDepsVersionFile); - - if (updateCount > 0) - { - Log.LogMessage($"Finished updating {updateCount} version variables in {DependenciesFile}"); - localVersionsFile.Save(DependenciesFile); - } - else - { - Log.LogMessage($"Versions in {DependenciesFile} are already up to date"); - } - - return !Log.HasLoggedErrors; - } - finally - { - if (File.Exists(tmpNupkgPath)) - { - File.Delete(tmpNupkgPath); - } - } - } - - private async Task TryDownloadLineupDepsFile() - { - if (string.IsNullOrEmpty(LineupDependenciesFile)) - { - return null; - } - - var path = LineupDependenciesFile; - string text; - if (path.StartsWith("http")) - { - using (var client = new HttpClient()) - { - text = await client.GetStringAsync(path); - } - } - else - { - text = File.ReadAllText(path); - } - - - using (var stringReader = new StringReader(text)) - using (var reader = new XmlTextReader(stringReader)) - { - var project = new Project(ProjectRootElement.Create(reader)); - return DependencyVersionsFile.LoadFromProject(project); - } - } - - private async Task TryDownloadLineupPackage(MSBuildLogger logger, string tmpNupkgPath) - { - VersionRange versionRange; - - if (string.IsNullOrEmpty(LineupPackageVersion)) - { - versionRange = VersionRange.AllFloating; - } - else if (!VersionRange.TryParse(LineupPackageVersion, out versionRange)) - { - Log.LogError($"{LineupPackageVersion} is not a valid NuGet package version"); - return null; - } - - var packageVersion = await GetPackageVersion(versionRange); - if (packageVersion == null) - { - Log.LogError($"Could not find a version of {LineupPackageId} in the version range {versionRange}."); - return null; - } - - var packageId = new PackageIdentity(LineupPackageId, packageVersion); - - var request = new PackageDownloadRequest - { - Identity = packageId, - OutputPath = tmpNupkgPath, - Sources = new[] { LineupPackageRestoreSource }, - }; - - var result = await new PackageDownloader(logger).DownloadPackagesAsync(new[] { request }, TimeSpan.FromSeconds(60), _cts.Token); - - if (!result) - { - Log.LogError("Could not download the lineup package"); - return null; - } - - using (var nupkgReader = new PackageArchiveReader(tmpNupkgPath)) - using (var stream = nupkgReader.GetStream("build/dependencies.props")) - using (var reader = new XmlTextReader(stream)) - { - var projectRoot = ProjectRootElement.Create(reader); - return DependencyVersionsFile.Load(projectRoot); - } - } - - private int UpdateDependencies(DependencyVersionsFile localVersionsFile, DependencyVersionsFile remoteDepsVersionFile) - { - var updateCount = 0; - foreach (var localVariable in localVersionsFile.VersionVariables.Values.Where(v => !v.IsReadOnly)) - { - string remoteVariableVersion; - // special case any package bundled in KoreBuild - if (!string.IsNullOrEmpty(KoreBuildVersion.Current) && localVariable.Name == "InternalAspNetCoreSdkPackageVersion") - { - remoteVariableVersion = KoreBuildVersion.Current; - Log.LogMessage(MessageImportance.Low, "Setting InternalAspNetCoreSdkPackageVersion to the current version of KoreBuild"); - } - else - { - if (remoteDepsVersionFile.VersionVariables.TryGetValue(localVariable.Name, out var remoteVariable)) - { - remoteVariableVersion = remoteVariable.Version; - } - else - { - Log.LogKoreBuildWarning( - DependenciesFile, KoreBuildErrors.PackageVersionNotFoundInLineup, - $"A new version variable for {localVariable.Name} could not be found in {LineupPackageId}. This might be an unsupported external dependency."); - continue; - } - } - - - if (remoteVariableVersion != localVariable.Version) - { - updateCount++; - localVersionsFile.Update(localVariable.Name, remoteVariableVersion); - } - } - - return updateCount; - } - - private async Task GetPackageVersion(VersionRange range) - { - if (!range.IsFloating) - { - return range.MinVersion; - } - - using (var cacheContext = new SourceCacheContext()) - { - var log = new MSBuildLogger(Log); - var defaultSettings = Settings.LoadDefaultSettings(root: null, configFileName: null, machineWideSettings: null); - var sourceProvider = new CachingSourceProvider(new PackageSourceProvider(defaultSettings)); - - var repo = sourceProvider.CreateRepository(new PackageSource(LineupPackageRestoreSource)); - - var metadata = await repo.GetResourceAsync(); - if (!await metadata.Exists(LineupPackageId, cacheContext, log, _cts.Token)) - { - Log.LogError($"Package {LineupPackageId} is not available on '{repo}'"); - return null; - } - - try - { - var versions = await metadata.GetVersions(LineupPackageId, includePrerelease: true, includeUnlisted: false, sourceCacheContext: cacheContext, log: log, token: _cts.Token); - - return range.FindBestMatch(versions); - } - catch (Exception ex) - { - Log.LogError($"Unexpected error while fetching versions from {repo.PackageSource.Source}: " + ex.Message); - return null; - } - } - } - } -} diff --git a/modules/KoreBuild.Tasks/Utilities/DependencyVersionsFile.cs b/modules/KoreBuild.Tasks/Utilities/DependencyVersionsFile.cs deleted file mode 100644 index 2b50a02b1..000000000 --- a/modules/KoreBuild.Tasks/Utilities/DependencyVersionsFile.cs +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.Build.Construction; -using Microsoft.Build.Evaluation; - -namespace KoreBuild.Tasks.Utilities -{ - public class DependencyVersionsFile - { - public const string PackageVersionsLabel = "Package Versions"; - - public const string AutoPackageVersionsLabel = "Package Versions: Auto"; - public const string PinnedPackageVersionsLabel = "Package Versions: Pinned"; - - private readonly Dictionary _versionVariables - = new Dictionary(StringComparer.OrdinalIgnoreCase); - - //private readonly SortedDictionary _versionElements - // = new SortedDictionary(StringComparer.OrdinalIgnoreCase); - - private readonly ProjectRootElement _document; - private ProjectPropertyGroupElement _autoPackageVersions; - private ProjectPropertyGroupElement _pinnedPackageVersions; - - private DependencyVersionsFile(ProjectRootElement xDocument) - { - _document = xDocument; - } - - public static string GetVariableName(string packageId) - { - var sb = new StringBuilder(); - var first = true; - foreach (var ch in packageId) - { - if (!char.IsLetterOrDigit(ch)) - { - first = true; - continue; - } - - if (first) - { - first = false; - sb.Append(char.ToUpperInvariant(ch)); - } - else - { - sb.Append(ch); - } - } - sb.Append("PackageVersion"); - return sb.ToString(); - } - - - public static DependencyVersionsFile Create(bool addOverrideImport, string[] additionalImports = null) - { - var projectRoot = ProjectRootElement.Create(NewProjectFileOptions.None); - - projectRoot.AddPropertyGroup().AddProperty("MSBuildAllProjects", "$(MSBuildAllProjects);$(MSBuildThisFileFullPath)"); - - var autoPackageVersions = projectRoot.AddPropertyGroup(); - autoPackageVersions.Label = AutoPackageVersionsLabel; - - if (additionalImports != null) - { - foreach (var item in additionalImports) - { - var import = projectRoot.AddImport(item); - import.Condition = $"Exists('{item}')"; - } - } - - if (addOverrideImport) - { - var import = projectRoot.AddImport("$(DotNetPackageVersionPropsPath)"); - import.Condition = " '$(DotNetPackageVersionPropsPath)' != '' "; - } - - var pinnedPackageVersions = projectRoot.AddPropertyGroup(); - pinnedPackageVersions.Label = PinnedPackageVersionsLabel; - - return new DependencyVersionsFile(projectRoot) - { - _autoPackageVersions = autoPackageVersions, - _pinnedPackageVersions = pinnedPackageVersions, - }; - } - - public static bool TryLoad(string sourceFile, out DependencyVersionsFile file) - { - try - { - file = Load(sourceFile); - return true; - } - catch - { - file = null; - return false; - } - } - - public static DependencyVersionsFile Load(string sourceFile) - { - var project = ProjectRootElement.Open(sourceFile, ProjectCollection.GlobalProjectCollection, preserveFormatting: true); - return Load(project); - } - - public static DependencyVersionsFile Load(ProjectRootElement document) - { - var file = new DependencyVersionsFile(document); - - var propGroups = file._document.PropertyGroups; - - var listPropertyGroups = new List(); - - foreach (var propGroup in propGroups) - { - var attr = propGroup.Label; - if (attr != null && attr.StartsWith(PackageVersionsLabel, StringComparison.OrdinalIgnoreCase)) - { - file.HasVersionsPropertyGroup = true; - listPropertyGroups.Add(propGroup); - } - } - - foreach (var group in listPropertyGroups) - { - var isReadOnly = string.Equals(group.Label, PinnedPackageVersionsLabel, StringComparison.OrdinalIgnoreCase); - if (isReadOnly) - { - file._pinnedPackageVersions = group; - } - else - { - file._autoPackageVersions = group; - } - - foreach (var child in group.Properties) - { - var variable = new PackageVersionVariable(child, isReadOnly); - file._versionVariables[variable.Name] = variable; - } - } - - file.EnsureGroupsCreated(); - return file; - } - - private void EnsureGroupsCreated() - { - if (_autoPackageVersions == null) - { - _autoPackageVersions = _document.AddPropertyGroup(); - _autoPackageVersions.Label = AutoPackageVersionsLabel; - } - - if (_pinnedPackageVersions == null) - { - _pinnedPackageVersions = _document.AddPropertyGroup(); - _pinnedPackageVersions.Label = PinnedPackageVersionsLabel; - } - } - - public static DependencyVersionsFile LoadFromProject(Project project) - { - var file = new DependencyVersionsFile(ProjectRootElement.Create(NewProjectFileOptions.None)); - - foreach (var property in project.AllEvaluatedProperties.Where(p => p.Xml != null)) - { - var group = (ProjectPropertyGroupElement)property.Xml.Parent; - var isReadOnly = string.Equals(group.Label, PinnedPackageVersionsLabel, StringComparison.OrdinalIgnoreCase); - - var variable = new PackageVersionVariable(property.Xml, property.EvaluatedValue?.Trim(), isReadOnly); - file._versionVariables[property.Name] = variable; - } - - file.EnsureGroupsCreated(); - - return file; - } - - public bool HasVersionsPropertyGroup { get; private set; } - - // copying is required so calling .Set while iterating on this doesn't raise an InvalidOperationException - public IReadOnlyDictionary VersionVariables - => new Dictionary(_versionVariables, StringComparer.OrdinalIgnoreCase); - - public PackageVersionVariable Update(string variableName, string version) - { - if (!_versionVariables.TryGetValue(variableName, out var variable)) - { - var element = _document.CreatePropertyElement(variableName); - variable = new PackageVersionVariable(element, version, isReadOnly: false); - _versionVariables[variableName] = variable; - variable.AddToGroup(_autoPackageVersions); - } - - variable.UpdateVersion(version); - return variable; - } - - public PackageVersionVariable AddPinnedVariable(string variableName, string version) - { - if (_versionVariables.ContainsKey(variableName)) - { - throw new InvalidOperationException("Key already exists: " + variableName); - } - - var element = _document.CreatePropertyElement(variableName); - var variable = new PackageVersionVariable(element, version, isReadOnly: true); - _versionVariables.Add(variableName, variable); - variable.AddToGroup(_pinnedPackageVersions); - return variable; - } - - public void Save(string filePath) - { - _autoPackageVersions.RemoveAllChildren(); - foreach (var item in _versionVariables.Values.Where(v => !v.IsReadOnly).OrderBy(v => v.Name)) - { - item.AddToGroup(_autoPackageVersions); - } - - _document.Save(filePath, Encoding.UTF8); - } - } -} diff --git a/modules/KoreBuild.Tasks/Utilities/DownloadFileHelper.cs b/modules/KoreBuild.Tasks/Utilities/DownloadFileHelper.cs new file mode 100644 index 000000000..3d1bebae5 --- /dev/null +++ b/modules/KoreBuild.Tasks/Utilities/DownloadFileHelper.cs @@ -0,0 +1,76 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Build.Utilities; +using Task = System.Threading.Tasks.Task; + +namespace KoreBuild.Tasks.Utilities +{ + public class DownloadFileHelper + { + public static async Task DownloadFileAsync(string uri, string destinationPath, bool overwrite, CancellationToken cancellationToken, int timeoutSeconds, TaskLoggingHelper log) + { + if (File.Exists(destinationPath) && !overwrite) + { + return true; + } + + const string FileuriProtocol = "file://"; + + if (uri.StartsWith(FileuriProtocol, StringComparison.OrdinalIgnoreCase)) + { + var filePath = uri.Substring(FileuriProtocol.Length); + log.LogMessage($"Copying '{filePath}' to '{destinationPath}'"); + File.Copy(filePath, destinationPath); + } + else + { + log.LogMessage($"Downloading '{uri}' to '{destinationPath}'"); + + using (var httpClient = new HttpClient + { + // Timeout if no response starts in 2 minutes + Timeout = TimeSpan.FromMinutes(2), + }) + { + try + { + var response = await httpClient.GetAsync(uri, cancellationToken); + response.EnsureSuccessStatusCode(); + cancellationToken.ThrowIfCancellationRequested(); + + Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); + + using (var outStream = File.Create(destinationPath)) + { + var responseStream = response.Content.ReadAsStreamAsync(); + var finished = await Task.WhenAny(responseStream, Task.Delay(TimeSpan.FromSeconds(timeoutSeconds))); + + if (!ReferenceEquals(responseStream, finished)) + { + throw new TimeoutException($"Download failed to complete in {timeoutSeconds} seconds."); + } + + responseStream.Result.CopyTo(outStream); + } + } + catch (Exception ex) + { + log.LogError($"Downloading '{uri}' failed."); + log.LogErrorFromException(ex, showStackTrace: true); + + File.Delete(destinationPath); + return false; + } + } + } + + return !log.HasLoggedErrors; + } + } +} diff --git a/modules/KoreBuild.Tasks/Utilities/PackageDownloadRequest.cs b/modules/KoreBuild.Tasks/Utilities/PackageDownloadRequest.cs deleted file mode 100644 index 40aeef381..000000000 --- a/modules/KoreBuild.Tasks/Utilities/PackageDownloadRequest.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using NuGet.Packaging.Core; - -namespace KoreBuild.Tasks.Utilities -{ - public class PackageDownloadRequest - { - public PackageIdentity Identity { get; set; } - public string OutputPath { get; set; } - public IReadOnlyList Sources { get; set; } - } -} diff --git a/modules/KoreBuild.Tasks/Utilities/PackageDownloader.cs b/modules/KoreBuild.Tasks/Utilities/PackageDownloader.cs deleted file mode 100644 index 9d5a9ac32..000000000 --- a/modules/KoreBuild.Tasks/Utilities/PackageDownloader.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using NuGet.Commands; -using NuGet.Configuration; -using NuGet.Packaging.Core; -using NuGet.Protocol; -using NuGet.Protocol.Core.Types; - -namespace KoreBuild.Tasks.Utilities -{ - public class PackageDownloader - { - private static readonly Task FalseTask = Task.FromResult(false); - private readonly NuGet.Common.ILogger logger; - - public PackageDownloader(NuGet.Common.ILogger logger) - { - this.logger = logger; - } - - public async Task DownloadPackagesAsync(ICollection requests, TimeSpan timeout, CancellationToken cancellationToken) - { - logger.LogMinimal($"Downloading {requests.Count} package(s)"); - - var cts = new CancellationTokenSource(timeout); - cancellationToken.Register(() => cts.Cancel()); - - using (var cacheContext = new SourceCacheContext()) - using (var throttle = new SemaphoreSlim(8)) - { - var defaultSettings = Settings.LoadDefaultSettings(root: null, configFileName: null, machineWideSettings: null); - var sourceProvider = new CachingSourceProvider(new PackageSourceProvider(defaultSettings)); - var tasks = new List>(); - - foreach (var request in requests) - { - var feeds = request.Sources - .Select(s => s?.Trim()) - .Where(s => !string.IsNullOrEmpty(s)) - .Distinct() - .Select(sourceProvider.CreateRepository); - tasks.Add(DownloadPackageAsync(request, feeds, cacheContext, throttle, logger, cts.Token)); - } - - var all = Task.WhenAll(tasks); - var delay = Task.Delay(timeout); - - var finished = await Task.WhenAny(all, delay); - if (ReferenceEquals(delay, finished)) - { - logger.LogError($"Timed out after {timeout.TotalSeconds}s"); - cts.Cancel(); - return false; - } - - if (!tasks.All(a => a.Result)) - { - logger.LogError("Failed to download all packages"); - return false; - } - - return true; - } - } - - private async Task DownloadPackageAsync( - PackageDownloadRequest request, - IEnumerable repositories, - SourceCacheContext cacheContext, - SemaphoreSlim throttle, - NuGet.Common.ILogger logger, - CancellationToken cancellationToken) - { - foreach (var repo in repositories) - { - var findPackageByIdResource = await repo.GetResourceAsync(cancellationToken); - - if (findPackageByIdResource == null) - { - logger.LogError($"{nameof(FindPackageByIdResource)} for '{repo}' could not be loaded."); - return false; - } - - using (var downloader = await findPackageByIdResource.GetPackageDownloaderAsync(request.Identity, cacheContext, logger, cancellationToken)) - { - if (downloader == null) - { - logger.LogInformation($"Package {request.Identity.Id} {request.Identity.Version} is not available on '{repo}'"); - // Skip to the next source if a package cannot be found in a given source. - continue; - } - - downloader.SetThrottle(throttle); - if (!await downloader.CopyNupkgFileToAsync(request.OutputPath, cancellationToken)) - { - logger.LogError($"Could not download {request.Identity.Id} {request.Identity.Version} from {repo}."); - return false; - } - } - - return true; - } - - logger.LogError($"{request.Identity.Id} {request.Identity.Version} is not available.'"); - return false; - } - } -} diff --git a/modules/KoreBuild.Tasks/Utilities/PackageVersionVariable.cs b/modules/KoreBuild.Tasks/Utilities/PackageVersionVariable.cs deleted file mode 100644 index 4131e2113..000000000 --- a/modules/KoreBuild.Tasks/Utilities/PackageVersionVariable.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.Build.Construction; - -namespace KoreBuild.Tasks.Utilities -{ - public class PackageVersionVariable - { - private readonly ProjectPropertyElement _element; - - public PackageVersionVariable(ProjectPropertyElement element, bool isReadOnly) - : this(element, element.Value?.Trim(), isReadOnly) - { - } - - public PackageVersionVariable(ProjectPropertyElement element, string version, bool isReadOnly) - { - _element = element ?? throw new ArgumentNullException(nameof(element)); - IsReadOnly = isReadOnly; - Name = element.Name.ToString(); - Version = version ?? string.Empty; - } - - public string Name { get; } - - public string Version - { - get => _element.Value; - private set => _element.Value = value; - } - - public bool IsReadOnly { get; private set; } - - public void UpdateVersion(string version) - { - if (IsReadOnly) - { - throw new InvalidOperationException("You cannot updated a pinned package version variable automatically"); - } - - Version = version; - } - - public void AddToGroup(ProjectPropertyGroupElement group) - { - group.AppendChild(_element); - } - - public void SetLabel(string label) - { - _element.Label = label; - } - } -} diff --git a/modules/KoreBuild.Tasks/Utilities/VsInstallerHelper.cs b/modules/KoreBuild.Tasks/Utilities/VsInstallerHelper.cs new file mode 100644 index 000000000..bdb1b6ef4 --- /dev/null +++ b/modules/KoreBuild.Tasks/Utilities/VsInstallerHelper.cs @@ -0,0 +1,71 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Build.Utilities; +using Newtonsoft.Json; + +namespace KoreBuild.Tasks.Utilities +{ + internal class VsInstallerHelper + { + public static async Task DownloadVsExe(TaskLoggingHelper log, string vsProductType) + { + var exeName = $"vs_{vsProductType}.exe"; + var tempPath = Path.Combine(Path.GetTempPath(), exeName); + + await DownloadFileHelper.DownloadFileAsync(uri: $"https://aka.ms/vs/15/release/{exeName}", + destinationPath: tempPath, + overwrite: true, + cancellationToken: new CancellationToken(), + timeoutSeconds: 60 * 15, + log); + + log.LogMessage($"Downloaded visual studio exe to {tempPath}."); + + return tempPath; + } + + private class VsJsonFile + { + [JsonProperty(PropertyName = "channelUri")] + public string ChannelUri { get; set; } + [JsonProperty(PropertyName = "channelId")] + public string ChannelId { get; set; } + [JsonProperty(PropertyName = "productId")] + public string ProductId { get; set; } + [JsonProperty(PropertyName = "includeRecommended")] + public bool IncludeRecommended { get; set; } + [JsonProperty(PropertyName = "addProductLang")] + public List AddProductLang { get; set; } + [JsonProperty(PropertyName = "add")] + public List Add { get; set; } + } + + public static string CreateVsFileFromRequiredToolset(KoreBuildSettings.VisualStudioToolset vsToolset, TaskLoggingHelper log, string vsProductType) + { + var vsFile = new VsJsonFile + { + ChannelUri = "https://aka.ms/vs/15/release/channel", + ChannelId = "VisualStudio.15.Release", + ProductId = $"Microsoft.VisualStudio.Product.{vsProductType}", + IncludeRecommended = false, + AddProductLang = new List + { + "en-US" + }, + Add = new List(vsToolset.RequiredWorkloads) + }; + + var tempFile = Path.Combine(Path.GetTempPath(), $"vs_{vsProductType}.json"); + + var json = JsonConvert.SerializeObject(vsFile); + File.WriteAllText(tempFile, json); + + return tempFile; + } + } +} diff --git a/modules/KoreBuild.Tasks/VerifyChecksum.cs b/modules/KoreBuild.Tasks/VerifyChecksum.cs deleted file mode 100644 index 3cb7d48c7..000000000 --- a/modules/KoreBuild.Tasks/VerifyChecksum.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.Build.Framework; - -namespace KoreBuild.Tasks -{ - /// - /// Verify the checksum for a single file. - /// - public class VerifyChecksum : Microsoft.Build.Utilities.Task - { - /// - /// The file path. - /// - [Required] - public string File { get; set; } - - /// - /// The algorithm. Allowed values: SHA256, SHA384, SHA512. - /// - public string Algorithm { get; set; } = "SHA256"; - - /// - /// The hash. - /// - [Required] - public string Hash { get; set; } - - public override bool Execute() - { - var actualHash = HashHelper.GetFileHash(Algorithm, File); - - if (!actualHash.Equals(Hash, StringComparison.OrdinalIgnoreCase)) - { - Log.LogError($"Checksum mismatch. Expected {File} to have {Algorithm} checksum of {Hash}, but it was {actualHash}"); - return false; - } - - return true; - } - } -} diff --git a/modules/KoreBuild.Tasks/module.props b/modules/KoreBuild.Tasks/module.props index cfa690448..58949fc17 100644 --- a/modules/KoreBuild.Tasks/module.props +++ b/modules/KoreBuild.Tasks/module.props @@ -1,5 +1,6 @@ + $(MSBuildThisFileDirectory)Internal.AspNetCore.KoreBuild.Tasks.dll @@ -10,22 +11,10 @@ - - - - - - - - - - - - $(KOREBUILD_DOTNET_ARCH) @@ -72,7 +61,7 @@ Specifies a required .NET Core SDK. Examples: - + --> $(DefaultDotNetAssetArch) diff --git a/modules/KoreBuild.Tasks/module.targets b/modules/KoreBuild.Tasks/module.targets index 9989d3471..01c047af4 100644 --- a/modules/KoreBuild.Tasks/module.targets +++ b/modules/KoreBuild.Tasks/module.targets @@ -3,11 +3,10 @@ GetToolsets;$(PrepareDependsOn) - InstallDotNet;CheckPackageReferences;$(RestoreDependsOn) + InstallDotNet;$(RestoreDependsOn) - false - $(RepositoryRoot)korebuild.json - $(RepositoryRoot)build\dependencies.props + $(RepoRoot)korebuild.json + $(RepoRoot)build\dependencies.props - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(RepositoryRoot)NuGetPackageVerifier.json + $(RepoRoot)NuGetPackageVerifier.json diff --git a/scripts/UpdateDependencyVersions.ps1 b/scripts/UpdateSdkVersion.ps1 old mode 100755 new mode 100644 similarity index 74% rename from scripts/UpdateDependencyVersions.ps1 rename to scripts/UpdateSdkVersion.ps1 index 57c1d906d..40253fb00 --- a/scripts/UpdateDependencyVersions.ps1 +++ b/scripts/UpdateSdkVersion.ps1 @@ -9,9 +9,7 @@ to know the internal details of how config files are layed out in this repo. [cmdletbinding(SupportsShouldProcess = $true, PositionalBinding = $false)] param( [Parameter()] - [Alias("sdk")] - [string]$DotNetSdkVersion = $null, - [string]$DotNetRuntimeVersion = $null, + [string]$Version = $null, [string[]]$GitCommitArgs = @(), [switch]$Force ) @@ -27,13 +25,13 @@ if (!$git) { $updates = @() -if ($DotNetSdkVersion -and $PSCmdlet.ShouldProcess("Update dotnet SDK to $DotNetSdkVersion")) { +if ($Version -and $PSCmdlet.ShouldProcess("Update dotnet SDK to $Version")) { $path = "$PSScriptRoot/../files/KoreBuild/config/sdk.version" $currentVersion = (Get-Content -path $path -Encoding Ascii).Trim() - if ($currentVersion -ne $DotNetSdkVersion) { - $DotNetSdkVersion | Set-Content -path $path -Encoding Ascii + if ($currentVersion -ne $Version) { + $Version | Set-Content -path $path -Encoding Ascii if ($git) { & git add $path } - $updates += "SDK to $DotNetSdkVersion" + $updates += "SDK to $Version" } } diff --git a/scripts/bootstrapper/run.ps1 b/scripts/bootstrapper/run.ps1 index 2f892843e..b0ca082f1 100755 --- a/scripts/bootstrapper/run.ps1 +++ b/scripts/bootstrapper/run.ps1 @@ -52,8 +52,8 @@ in the file are overridden by command line parameters. Example config file: ```json { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", - "channel": "master", + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/main/tools/korebuild.schema.json", + "channel": "main", "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" } ``` @@ -193,7 +193,7 @@ if (!$DotNetHome) { else { Join-Path $PSScriptRoot '.dotnet'} } -if (!$Channel) { $Channel = 'master' } +if (!$Channel) { $Channel = 'main' } if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' } # Execute diff --git a/scripts/bootstrapper/run.sh b/scripts/bootstrapper/run.sh index 129b0b957..89a6442d6 100755 --- a/scripts/bootstrapper/run.sh +++ b/scripts/bootstrapper/run.sh @@ -251,7 +251,7 @@ if [ -f "$config_file" ]; then fi [ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" -[ -z "$channel" ] && channel='master' +[ -z "$channel" ] && channel='main' [ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' get_korebuild diff --git a/shared/Microsoft.Extensions.CommandLineUtils.Sources/Utilities/DotNetMuxer.cs b/shared/Microsoft.Extensions.CommandLineUtils.Sources/Utilities/DotNetMuxer.cs index 75a6042b4..34da57ef6 100644 --- a/shared/Microsoft.Extensions.CommandLineUtils.Sources/Utilities/DotNetMuxer.cs +++ b/shared/Microsoft.Extensions.CommandLineUtils.Sources/Utilities/DotNetMuxer.cs @@ -39,7 +39,7 @@ private static string TryFindMuxerPath() var fileName = MuxerName; #if NET46 fileName += ".exe"; -#elif NETCOREAPP2_1 || NETSTANDARD2_0 +#elif NETCOREAPP3_1 || NETCOREAPP3_0 || NETCOREAPP2_2 || NETCOREAPP2_1 || NETSTANDARD2_0 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { fileName += ".exe"; diff --git a/src/ApiCheck.Console/ApiCheck.Console.csproj b/src/ApiCheck.Console/ApiCheck.Console.csproj deleted file mode 100644 index 614dd088c..000000000 --- a/src/ApiCheck.Console/ApiCheck.Console.csproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - netcoreapp2.1;net46 - Microsoft.AspNetCore.BuildTools.ApiCheck - ApiCheck - Microsoft.AspNetCore.BuildTools.ApiCheck - exe - false - false - - - - - $(MSBuildThisFileDirectory)Microsoft.AspNetCore.BuildTools.ApiCheck.nuspec - $(MSBuildThisFileDirectory)bin\$(Configuration)\publish\ - $(IntermediatePackDir)$(TargetFramework)\ - - - - - - - - - - - - - <_TargetFramework Include="$(TargetFrameworks)" /> - - - - - - - $(NuspecProperties);id=$(PackageId) - $(NuspecProperties);publishDir=$(IntermediatePackDir) - $(NuspecProperties);taskBuildDir=$(MSBuildThisFileDirectory)..\ApiCheck.Task\bin\$(Configuration) - $(NuspecProperties);version=$(PackageVersion) - - - - - diff --git a/src/ApiCheck.Console/ApiListing/ApiElement.cs b/src/ApiCheck.Console/ApiListing/ApiElement.cs deleted file mode 100644 index 849a29104..000000000 --- a/src/ApiCheck.Console/ApiListing/ApiElement.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Diagnostics; - -namespace ApiCheck.Description -{ - [DebuggerDisplay("{" + nameof(Id) + ",nq}")] - public class ApiElement - { - public virtual string Id { get; } - } -} diff --git a/src/ApiCheck.Console/ApiListing/ApiElementVisibility.cs b/src/ApiCheck.Console/ApiListing/ApiElementVisibility.cs deleted file mode 100644 index f3a04e7e0..000000000 --- a/src/ApiCheck.Console/ApiListing/ApiElementVisibility.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace ApiCheck.Description -{ - [JsonConverter(typeof(StringEnumConverter))] - public enum ApiElementVisibility - { - Public, - Protected - } -} diff --git a/src/ApiCheck.Console/ApiListing/ApiListing.cs b/src/ApiCheck.Console/ApiListing/ApiListing.cs deleted file mode 100644 index e23db4f91..000000000 --- a/src/ApiCheck.Console/ApiListing/ApiListing.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Newtonsoft.Json; - -namespace ApiCheck.Description -{ - public class ApiListing - { - public string AssemblyIdentity { get; set; } - - public IList Types { get; } = new List(); - - [JsonIgnore] - public IEnumerable> SourceFilters { get; set; } - - public TypeDescriptor FindType(string name) - { - foreach (var type in Types) - { - if (string.Equals(name, type.Name, StringComparison.Ordinal)) - { - return type; - } - } - - return null; - } - - public ApiElement FindElement(string typeId, string memberId) - { - var type = Types.FirstOrDefault(t => t.Id == typeId); - if (type == null) - { - return null; - } - - if (memberId == null) - { - return type; - } - - return type.FindMember(memberId); - } - } -} diff --git a/src/ApiCheck.Console/ApiListing/ApiListingFilters.cs b/src/ApiCheck.Console/ApiListing/ApiListingFilters.cs deleted file mode 100644 index 38d4989e2..000000000 --- a/src/ApiCheck.Console/ApiListing/ApiListingFilters.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Linq; -using System.Reflection; -using ApiCheck.Description; - -namespace ApiCheck -{ - public static class ApiListingFilters - { - public static bool IsInInternalNamespace(MemberInfo e) - { - var type = e as TypeInfo; - if (type == null) - { - return false; - } - - var segments = type.Namespace.Split('.'); - return segments.Any(s => s == "Internal"); - } - - public static bool IsInInternalNamespace(ApiElement e) - { - var type = e as TypeDescriptor; - if (type == null) - { - return false; - } - - var segments = type.Name.Split('.'); - // Skip the last segment as is the type name. - return segments.Take(segments.Length - 1).Any(s => s.Equals("Internal")); - } - } -} diff --git a/src/ApiCheck.Console/ApiListing/GenericParameterDescriptor.cs b/src/ApiCheck.Console/ApiListing/GenericParameterDescriptor.cs deleted file mode 100644 index 3b174b0b0..000000000 --- a/src/ApiCheck.Console/ApiListing/GenericParameterDescriptor.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Reflection; -using Newtonsoft.Json; - -namespace ApiCheck.Description -{ - public class GenericParameterDescriptor : ApiElement - { - [JsonIgnore] - public override string Id => HasConstraints() ? $"T{ParameterPosition}" + " : " + GetConstraints() : ParameterName; - - [JsonIgnore] - public TypeInfo Source { get; set; } - - public string ParameterName { get; set; } - - public int ParameterPosition { get; set; } - - private string GetConstraints() - { - var constraints = new List(); - foreach (var type in BaseTypeOrInterfaces) - { - constraints.Add(type); - } - if (Class) - { - constraints.Add("class"); - } - - if (Struct) - { - constraints.Add("struct"); - } - - if (!Struct && New) - { - constraints.Add("new()"); - } - - return string.Join(", ", constraints); - } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool New { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Class { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Struct { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public IList BaseTypeOrInterfaces { get; } = new List(); - - public bool HasConstraints() => New || Class || Struct || BaseTypeOrInterfaces.Count > 0; - } -} diff --git a/src/ApiCheck.Console/ApiListing/MemberDescriptor.cs b/src/ApiCheck.Console/ApiListing/MemberDescriptor.cs deleted file mode 100644 index 35ef300c6..000000000 --- a/src/ApiCheck.Console/ApiListing/MemberDescriptor.cs +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using Newtonsoft.Json; - -namespace ApiCheck.Description -{ - public class MemberDescriptor : ApiElement - { - [JsonIgnore] - public override string Id => string.Join(" ", GetComponents()); - - [JsonIgnore] - public MemberInfo Source { get; set; } - - public MemberKind Kind { get; set; } - - public string Name { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public IList Parameters { get; set; } = new List(); - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public string ReturnType { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Sealed { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Static { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Virtual { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Override { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Abstract { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool New { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Extension { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool ReadOnly { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public string ExplicitInterface { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public string ImplementedInterface { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public ApiElementVisibility? Visibility { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public IList GenericParameter { get; } = new List(); - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Constant { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public string Literal { get; set; } - - private IEnumerable GetComponents() - { - if (ExplicitInterface == null && Visibility != null) - { - switch (Visibility) - { - case ApiElementVisibility.Public: - yield return "public"; - break; - case ApiElementVisibility.Protected: - yield return "protected"; - break; - } - } - - if (Constant) - { - yield return "const"; - } - else - { - if (Static) - { - yield return "static"; - } - - if (ReadOnly) - { - yield return "readonly"; - } - } - - if (Abstract) - { - yield return "abstract"; - } - - if (Sealed && ImplementedInterface == null) - { - yield return "sealed"; - } - - if (!Sealed && Virtual && !Abstract && !Override && ImplementedInterface == null) - { - yield return "virtual"; - } - - if (Override) - { - yield return "override"; - } - - if (New) - { - yield return "new"; - } - - if (ReturnType != null) - { - yield return ReturnType; - } - - if (Kind != MemberKind.Field) - { - var name = ExplicitInterface != null ? $"{ExplicitInterface}.{Name}" : Name; - yield return GetParametersComponent(name); - - foreach (var constraint in GenericParameter.Where(p => p.HasConstraints())) - { - yield return "where"; - yield return constraint.Id; - } - } - else - { - yield return Name; - - if (Literal != null) - { - yield return "="; - yield return Literal; - } - } - } - - private string GetParametersComponent(string name) - { - var builder = new StringBuilder(); - - builder.Append(name); - builder.Append("("); - for (var i = 0; i < Parameters.Count; i++) - { - var parameter = Parameters[i]; - if (Extension && i == 0) - { - builder.Append("this "); - } - builder.Append(parameter.Id); - if (i < Parameters.Count - 1) - { - builder.Append(", "); - } - } - - builder.Append(")"); - return builder.ToString(); - } - - public static string GetMemberNameFor(MethodBase member, bool includeGenericParameters = true) - { - if (!member.IsGenericMethod || !includeGenericParameters) - { - return member.Name; - } - - var genericParameters = string.Join(", ", member.GetGenericArguments().Select(ga => TypeDescriptor.GetTypeNameFor(ga.GetTypeInfo()))); - - return $"{member.Name}<{genericParameters}>"; - } - } -} diff --git a/src/ApiCheck.Console/ApiListing/MemberKind.cs b/src/ApiCheck.Console/ApiListing/MemberKind.cs deleted file mode 100644 index d3a64f3e0..000000000 --- a/src/ApiCheck.Console/ApiListing/MemberKind.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace ApiCheck.Description -{ - [JsonConverter(typeof(StringEnumConverter))] - public enum MemberKind - { - Constructor, - // This includes property and events accessors. - Method, - Field - } -} diff --git a/src/ApiCheck.Console/ApiListing/ParameterDescriptor.cs b/src/ApiCheck.Console/ApiListing/ParameterDescriptor.cs deleted file mode 100644 index 6d72ac88b..000000000 --- a/src/ApiCheck.Console/ApiListing/ParameterDescriptor.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Reflection; -using Newtonsoft.Json; - -namespace ApiCheck.Description -{ - public class ParameterDescriptor : ApiElement - { - [JsonIgnore] - public override string Id => string.Join(" ", GetComponents()); - - [JsonIgnore] - public ParameterInfo Source { get; set; } - - public string Name { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public string Type { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public ParameterDirection Direction { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public string DefaultValue { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool IsParams { get; set; } - - private IEnumerable GetComponents() - { - switch (Direction) - { - case ParameterDirection.In: - break; - case ParameterDirection.Out: - yield return "out"; - break; - case ParameterDirection.Ref: - yield return "ref"; - break; - } - - if (IsParams) - { - yield return "params"; - } - - yield return Type; - yield return Name; - - if (DefaultValue != null) - { - yield return "="; - yield return DefaultValue; - } - } - } -} diff --git a/src/ApiCheck.Console/ApiListing/ParameterDirection.cs b/src/ApiCheck.Console/ApiListing/ParameterDirection.cs deleted file mode 100644 index 452ecfca2..000000000 --- a/src/ApiCheck.Console/ApiListing/ParameterDirection.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace ApiCheck.Description -{ - [JsonConverter(typeof(StringEnumConverter))] - public enum ParameterDirection - { - In, - Out, - Ref - } -} diff --git a/src/ApiCheck.Console/ApiListing/TypeDescriptor.cs b/src/ApiCheck.Console/ApiListing/TypeDescriptor.cs deleted file mode 100644 index 9b2298fb4..000000000 --- a/src/ApiCheck.Console/ApiListing/TypeDescriptor.cs +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Newtonsoft.Json; - -namespace ApiCheck.Description -{ - public class TypeDescriptor : ApiElement - { - [JsonIgnore] - public override string Id => string.Join(" ", GetSignatureComponents()); - - [JsonIgnore] - public TypeInfo Source { get; set; } - - public string Name { get; set; } - - public ApiElementVisibility Visibility { get; set; } - - public TypeKind Kind { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Abstract { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Static { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public bool Sealed { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public string BaseType { get; set; } - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public IList ImplementedInterfaces { get; } = new List(); - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public IList Members { get; } = new List(); - - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - public IList GenericParameters { get; } = new List(); - - private IEnumerable GetSignatureComponents() - { - switch (Visibility) - { - case ApiElementVisibility.Public: - yield return "public"; - break; - case ApiElementVisibility.Protected: - yield return "protected"; - break; - } - - if (Static) - { - yield return "static"; - } - else if (Kind == TypeKind.Class) - { - if (Abstract) - { - yield return "abstract"; - } - - if (Sealed) - { - yield return "sealed"; - } - } - - switch (Kind) - { - case TypeKind.Struct: - yield return "struct"; - break; - case TypeKind.Interface: - yield return "interface"; - break; - case TypeKind.Class: - yield return "class"; - break; - case TypeKind.Enumeration: - yield return "enum"; - break; - case TypeKind.Unknown: - Console.WriteLine($"Undefined kind for: {Name}"); - break; - default: - throw new InvalidOperationException("Invalid kind"); - } - - yield return Name; - - if (BaseType != null || ImplementedInterfaces.Count > 0) - { - yield return ":"; - yield return string.Join(", ", GetBaseTypeAndImplementedInterfaces()); - } - - foreach (var constraint in GenericParameters.Where(p => p.HasConstraints())) - { - yield return "where"; - yield return constraint.Id; - } - } - - public MemberDescriptor FindMember(string id) - { - foreach (var member in Members) - { - if (string.Equals(id, member.Id, StringComparison.Ordinal)) - { - return member; - } - } - - return null; - } - - private IEnumerable GetBaseTypeAndImplementedInterfaces() - { - if (BaseType != null) - { - yield return BaseType; - } - - foreach (var @interface in ImplementedInterfaces) - { - if (@interface != null) - { - yield return @interface; - } - } - } - - public static string GetTypeNameFor(TypeInfo type) - { - var typeName = type.FullName ?? type.Name; - - if (type.IsGenericParameter) - { - typeName = $"T{type.GenericParameterPosition}"; - } - - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) - { - var underlyingTypeName = GetTypeNameFor(type.GetGenericArguments().Single().GetTypeInfo()); - typeName = underlyingTypeName + "?"; - } - - if (type.IsGenericType) - { - if (type.DeclaringType == null || Equals(type.DeclaringType.GetTypeInfo(), type)) - { - var name = type.GetGenericTypeDefinition().FullName; - typeName = name.Substring(0, name.IndexOf('`')); - typeName = $"{typeName}<{string.Join(", ", type.GetGenericArguments().Select(ga => GetTypeNameFor(ga.GetTypeInfo())))}>"; - } - else - { - var container = type.DeclaringType.GetTypeInfo(); - var prefix = GetTypeNameFor(container); - var name = type.GetGenericTypeDefinition().FullName; - var currentTypeGenericArguments = type.GetGenericTypeDefinition().GetGenericArguments() - .Where(p => container.GetGenericArguments().All(cp => cp.Name != p.Name)) - .Select(p => type.GetGenericArguments()[p.GenericParameterPosition]) - .ToArray(); - - if (currentTypeGenericArguments.Length == 0) - { - var nestedClassSeparatorIndex = name.LastIndexOf("+"); - name = name.Substring(nestedClassSeparatorIndex + 1, name.Length - nestedClassSeparatorIndex - 1); - } - else - { - var lastGenericArityIndex = name.LastIndexOf('`'); - var nestedClassSeparatorIndex = name.LastIndexOf("+"); - name = name.Substring(nestedClassSeparatorIndex + 1, lastGenericArityIndex - nestedClassSeparatorIndex - 1); - name = $"{name}<{string.Join(", ", currentTypeGenericArguments.Select(ga => GetTypeNameFor(ga.GetTypeInfo())))}>"; - } - - typeName = $"{prefix}+{name}"; - } - } - - if (type.IsArray) - { - var name = GetTypeNameFor(type.GetElementType().GetTypeInfo()); - typeName = $"{name}[]"; - } - - if (type.IsByRef) - { - typeName = GetTypeNameFor(type.GetElementType().GetTypeInfo()); - } - - // Parameters passed by reference through out or ref modifiers have an & at the end of their - // name to indicate they are pointers to a given type. - typeName = typeName.TrimEnd('&'); - - return typeName; - } - - public static IEnumerable GetImplementedInterfacesFor(TypeInfo type) - { - if (type.IsGenericParameter) - { - var interfaces = type.ImplementedInterfaces.ToArray(); - foreach (var t in interfaces) - { - var implementedInterface = t.GetTypeInfo(); - var implementedOnBaseType = type.BaseType != null && - InterfaceIsImplementedOnBaseType(type.BaseType.GetTypeInfo(), - implementedInterface); - - if (!implementedOnBaseType && !InterfaceIsTransitivelyImplemented(type, implementedInterface)) - { - yield return implementedInterface; - } - } - } - else if (!type.IsInterface) - { - var interfaces = type.ImplementedInterfaces.ToArray(); - foreach (var t in interfaces) - { - var implementedInterface = t.GetTypeInfo(); - if ((!InterfaceIsImplementedOnBaseType(type.BaseType.GetTypeInfo(), implementedInterface) && - !InterfaceIsTransitivelyImplemented(type, implementedInterface)) || - InterfaceIsReimplementedOnCurrentType(type, implementedInterface)) - { - yield return implementedInterface; - } - } - } - else - { - var interfaces = type.ImplementedInterfaces.ToArray(); - foreach (var t in interfaces) - { - var implementedInterface = t.GetTypeInfo(); - if (!InterfaceIsTransitivelyImplemented(type, implementedInterface)) - { - yield return implementedInterface; - } - } - } - } - - private static bool InterfaceIsReimplementedOnCurrentType(TypeInfo type, TypeInfo implementedInterface) - { - var mapping = type.GetRuntimeInterfaceMap(implementedInterface.AsType()); - return InterfaceIsImplementedOnBaseType(type.BaseType.GetTypeInfo(), implementedInterface) && - mapping.TargetMethods.Any(tm => tm.DeclaringType.GetTypeInfo().Equals(type) && - (tm.IsPrivate || tm.Equals(tm.GetBaseDefinition()))); - } - - private static bool InterfaceIsTransitivelyImplemented(TypeInfo type, TypeInfo implementedInterface) - { - return type.ImplementedInterfaces - .SelectMany(ii => ii.GetTypeInfo().ImplementedInterfaces) - .Any(bii => bii.GetTypeInfo().Equals(implementedInterface)); - } - - private static bool InterfaceIsImplementedOnBaseType(TypeInfo typeInfo, TypeInfo implementedInterface) - { - return typeInfo.ImplementedInterfaces.Any(ii => ii.GetTypeInfo().Equals(implementedInterface)); - } - } -} diff --git a/src/ApiCheck.Console/ApiListing/TypeKind.cs b/src/ApiCheck.Console/ApiListing/TypeKind.cs deleted file mode 100644 index eac324545..000000000 --- a/src/ApiCheck.Console/ApiListing/TypeKind.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace ApiCheck.Description -{ - [JsonConverter(typeof(StringEnumConverter))] - public enum TypeKind - { - Unknown, - Struct, - Interface, - // Includes delegates as they are extend multicast delegate. - Class, - Enumeration - } -} diff --git a/src/ApiCheck.Console/ApiListingComparer.cs b/src/ApiCheck.Console/ApiListingComparer.cs deleted file mode 100644 index 813404de3..000000000 --- a/src/ApiCheck.Console/ApiListingComparer.cs +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using ApiCheck.Description; - -namespace ApiCheck -{ - public class ApiListingComparer - { - private readonly ApiListing _newApiListing; - private readonly ApiListing _oldApiListing; - - public ApiListingComparer( - ApiListing oldApiListing, - ApiListing newApiListing) - { - _oldApiListing = oldApiListing; - _newApiListing = newApiListing; - } - - public IList GetDifferences() - { - var breakingChanges = new List(); - var newTypes = _newApiListing.Types; - - foreach (var type in _oldApiListing.Types) - { - var newType = _newApiListing.FindType(type.Name); - if (newType == null) - { - breakingChanges.Add(new BreakingChange(type.Id, memberId: null, kind: ChangeKind.Removal)); - } - else - { - newTypes.Remove(newType); - - if (!string.Equals(type.Id, newType.Id, StringComparison.Ordinal) - && !IsAcceptableTypeChange(type, newType)) - { - breakingChanges.Add(new BreakingChange(type.Id, memberId: null, kind: ChangeKind.Removal)); - continue; - } - - CompareMembers(type, newType, breakingChanges); - } - } - - return breakingChanges; - } - - private void CompareMembers(TypeDescriptor type, TypeDescriptor newType, List breakingChanges) - { - var newMembers = newType.Members.ToList(); - - foreach (var member in type.Members) - { - if (IsAcceptableMemberChange(newType, member, out var newMember)) - { - newMembers.Remove(newMember); - } - else - { - breakingChanges.Add(new BreakingChange(type.Id, member.Id, ChangeKind.Removal)); - } - } - - if (newMembers.Count > 0) - { - if (type.Kind == TypeKind.Interface) - { - breakingChanges.AddRange(newMembers.Select(member => new BreakingChange(newType.Id, member.Id, ChangeKind.Addition))); - } - else - { - var disallowedNewMembers = newMembers.Where(member => member.Abstract).ToArray(); - if (disallowedNewMembers.Length > 0) - { - breakingChanges.AddRange(disallowedNewMembers.Select(member => new BreakingChange(newType.Id, member.Id, ChangeKind.Addition))); - } - } - } - } - - private bool IsAcceptableMemberChange(TypeDescriptor newType, MemberDescriptor member, out MemberDescriptor newMember) - { - var acceptable = false; - newMember = null; - var candidate = newType; - while (candidate != null && !acceptable) - { - var matchingMembers = candidate.Members.Where(m => m.Id == member.Id).ToList(); - - if (matchingMembers.Count == 1) - { - newMember = matchingMembers.Single(); - acceptable = true; - } - else if (member.Kind == MemberKind.Method) - { - var matchingMember = newType.Members.FirstOrDefault(m => SameSignature(member, m)); - if (matchingMember != null) - { - acceptable = (member.Sealed || !matchingMember.Sealed) - && (!member.Virtual || matchingMember.Virtual || matchingMember.Override) - && member.Static == matchingMember.Static - && (member.Abstract || !matchingMember.Abstract); - - if (acceptable) - { - newMember = matchingMember; - } - } - } - - candidate = candidate.BaseType == null ? null : FindOrGenerateDescriptorForBaseType(candidate); - } - - return acceptable; - } - - private TypeDescriptor FindOrGenerateDescriptorForBaseType(TypeDescriptor candidate) - { - return _newApiListing.FindType(candidate.BaseType) ?? - ApiListingGenerator.GenerateTypeDescriptor(candidate.Source.BaseType.GetTypeInfo(), _newApiListing.SourceFilters); - } - - private bool SameSignature(MemberDescriptor original, MemberDescriptor candidate) - { - return original.ReturnType == candidate.ReturnType && - original.Name == candidate.Name && - SameGenericParameters(original.GenericParameter, candidate.GenericParameter) && - SameParameters(original.Parameters, candidate.Parameters); - } - - private bool SameParameters( - IList original, - IList candidate) - { - if (original.Count != candidate.Count) - { - return false; - } - - for (var i = 0; i < original.Count; i++) - { - var originalParameter = original[i]; - var candidatePrameter = candidate[i]; - if (originalParameter.Type != candidatePrameter.Type || - originalParameter.Name != candidatePrameter.Name || - originalParameter.Direction != candidatePrameter.Direction || - originalParameter.DefaultValue != candidatePrameter.DefaultValue || - originalParameter.IsParams != candidatePrameter.IsParams) - { - return false; - } - } - - return true; - } - - private bool SameGenericParameters(IList original, IList candidate) - { - if (original.Count != candidate.Count) - { - return false; - } - - for (var i = 0; i < original.Count; i++) - { - var originalParameter = original[i]; - var candidatePrameter = candidate[i]; - if (originalParameter.ParameterPosition != candidatePrameter.ParameterPosition || - !originalParameter.BaseTypeOrInterfaces.OrderBy(id => id).SequenceEqual(candidatePrameter.BaseTypeOrInterfaces.OrderBy(id => id)) || - originalParameter.New != candidatePrameter.New || - originalParameter.Class != candidatePrameter.Class || - originalParameter.Struct != candidatePrameter.Struct) - { - return false; - } - } - - return true; - } - - private bool IsAcceptableTypeChange(TypeDescriptor oldType, TypeDescriptor newType) - { - var typeChanged = oldType.Kind != newType.Kind; - if (typeChanged) - { - return false; - } - - if (!HasCompatibleVisibility(oldType, newType)) - { - return false; - } - - if (oldType.GenericParameters.Count > 0 && - !HasCompatibleSetOfGenericParameters(oldType.GenericParameters, newType.GenericParameters)) - { - return false; - } - - switch (oldType.Kind) - { - case TypeKind.Struct: - return ImplementsAllInterfaces(oldType, newType); - case TypeKind.Class: - return ImplementsAllInterfaces(oldType, newType) && - (!newType.Sealed || oldType.Sealed == newType.Sealed) && - (!newType.Abstract || oldType.Abstract == newType.Abstract) && - newType.Static == oldType.Static && - (oldType.BaseType == null || newType.BaseType == oldType.BaseType); - case TypeKind.Interface: - return HasCompatibleSetOfInterfaces(oldType, newType); - case TypeKind.Enumeration: - return oldType.BaseType == newType.BaseType; - case TypeKind.Unknown: - break; - } - - return false; - } - - private bool HasCompatibleSetOfGenericParameters( - IList oldGenericParameters, - IList newGenericParameters) - { - if (oldGenericParameters.Count != newGenericParameters.Count) - { - return false; - } - - var oldSet = oldGenericParameters.OrderBy(ogp => ogp.ParameterPosition).ToArray(); - var newSet = newGenericParameters.OrderBy(ogp => ogp.ParameterPosition).ToArray(); - for (var i = 0; i < oldSet.Length; i++) - { - var oldParameter = oldSet[i]; - var newParameter = newSet[i]; - var areCompatible = AreCompatible(oldParameter, newParameter); - if (!areCompatible) - { - return false; - } - } - - return true; - } - - private bool AreCompatible(GenericParameterDescriptor oldParameter, GenericParameterDescriptor newParameter) - { - return ((newParameter.New && oldParameter.New) || !newParameter.New) && - ((newParameter.Class && oldParameter.Class) || !newParameter.Class) && - ((newParameter.Struct && oldParameter.Struct) || !newParameter.Struct) && - newParameter.BaseTypeOrInterfaces.Count == oldParameter.BaseTypeOrInterfaces.Count && - newParameter.BaseTypeOrInterfaces.All(btoi => oldParameter.BaseTypeOrInterfaces.Contains(btoi)); - } - - private bool HasCompatibleSetOfInterfaces(TypeDescriptor oldType, TypeDescriptor newType) - { - // An interface can't require new implemented interfaces unless they are marker interfaces (they don't have any member) - var newInterfaces = newType.Source.ImplementedInterfaces - .Where(i => !oldType.ImplementedInterfaces.Contains(TypeDescriptor.GetTypeNameFor(i.GetTypeInfo()))); - - return newInterfaces.All(ni => ni.GetTypeInfo().GetMembers().Length == 0); - } - - private bool ImplementsAllInterfaces(TypeDescriptor oldType, TypeDescriptor newType) - { - var oldInterfaces = oldType.ImplementedInterfaces; - var newInterfaces = newType.Source.ImplementedInterfaces.Select(i => TypeDescriptor.GetTypeNameFor(i.GetTypeInfo())); - - return oldInterfaces.All(oi => newInterfaces.Contains(oi)); - } - - private bool HasCompatibleVisibility(TypeDescriptor oldType, TypeDescriptor newType) - { - switch (oldType.Visibility) - { - case ApiElementVisibility.Public: - return newType.Visibility == ApiElementVisibility.Public; - case ApiElementVisibility.Protected: - // Is going from protected to public a breaking change ? - return true; - default: - throw new InvalidOperationException("Unrecognized visibility"); - } - } - } -} diff --git a/src/ApiCheck.Console/ApiListingGenerator.cs b/src/ApiCheck.Console/ApiListingGenerator.cs deleted file mode 100644 index 04d76225e..000000000 --- a/src/ApiCheck.Console/ApiListingGenerator.cs +++ /dev/null @@ -1,469 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; -using ApiCheck.Description; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace ApiCheck -{ - public class ApiListingGenerator - { - private const BindingFlags SearchFlags = BindingFlags.Public | - BindingFlags.NonPublic | - BindingFlags.Instance | - BindingFlags.Static | - BindingFlags.DeclaredOnly; - - private readonly Assembly _assembly; - private readonly IEnumerable> _filters; - - public ApiListingGenerator(Assembly assembly, IEnumerable> filters) - { - _assembly = assembly; - _filters = filters; - } - - public static JObject GenerateApiListingReport(Assembly assembly, IEnumerable> filters = null) - { - var generator = new ApiListingGenerator(assembly, filters ?? Enumerable.Empty>()); - var apiListingDocument = generator.GenerateApiListing(); - return JObject.FromObject(apiListingDocument); - } - - public ApiListing GenerateApiListing() - { - var types = _assembly.DefinedTypes -#if NETCOREAPP2_1 // Reflection does not provide a hook to enumerate forwarded types in .NET Framework. - .Concat(_assembly - .GetForwardedTypes() - .Select(type => type.GetTypeInfo())) -#endif - .Where(t => t.IsPublic || t.IsNestedPublic || t.IsNestedFamily || t.IsNestedFamORAssem); - - var document = new ApiListing - { - AssemblyIdentity = _assembly.GetName().ToString(), - SourceFilters = _filters - }; - foreach (var type in types.Where(t => !_filters.Any(filter => filter(t)))) - { - var apiListingType = GenerateTypeDescriptor(type); - document.Types.Add(apiListingType); - } - - return document; - } - - public static TypeDescriptor GenerateTypeDescriptor(TypeInfo type, IEnumerable> filters = null) - { - filters = filters ?? Enumerable.Empty>(); - var generator = new ApiListingGenerator(type.Assembly, filters); - return generator.GenerateTypeDescriptor(type); - } - - private TypeDescriptor GenerateTypeDescriptor(TypeInfo type) - { - var typeDescriptor = new TypeDescriptor - { - Source = type, - Name = TypeDescriptor.GetTypeNameFor(type), - Kind = GetTypeKind(type), - }; - if (typeDescriptor.Kind == TypeKind.Unknown) - { - throw new InvalidOperationException($"Can't determine type for {type.FullName}"); - } - - // At this point we've filtered away any non public or protected member, - // so we only need to check if something is public - typeDescriptor.Visibility = type.IsPublic || type.IsNestedPublic ? ApiElementVisibility.Public : ApiElementVisibility.Protected; - - typeDescriptor.Static = typeDescriptor.Kind == TypeKind.Class && type.IsSealed && type.IsAbstract; - - typeDescriptor.Abstract = type.IsAbstract; - - typeDescriptor.Sealed = type.IsSealed; - - if (type.BaseType != null && - type.BaseType != typeof(object) && - type.BaseType != typeof(ValueType) && - !(type.IsEnum && type.GetEnumUnderlyingType() == typeof(int))) - { - typeDescriptor.BaseType = !type.IsEnum ? - TypeDescriptor.GetTypeNameFor(type.BaseType.GetTypeInfo()) : - TypeDescriptor.GetTypeNameFor(type.GetEnumUnderlyingType().GetTypeInfo()); - } - - if (type.ImplementedInterfaces.Any()) - { - var interfaces = TypeDescriptor.GetImplementedInterfacesFor(type).ToList(); - foreach (var @interface in interfaces.Select(TypeDescriptor.GetTypeNameFor)) - { - typeDescriptor.ImplementedInterfaces.Add(@interface); - } - } - - if (type.IsGenericType) - { - var constraints = GetGenericConstraintsFor(type.GetGenericArguments().Select(t => t.GetTypeInfo()).ToArray()); - foreach (var constraint in constraints) - { - typeDescriptor.GenericParameters.Add(constraint); - } - } - - var members = type.GetMembers(SearchFlags); - - foreach (var member in members) - { - if (_filters.Any(f => f(member))) - { - continue; - } - - var memberApiListing = GenerateMemberApiListing(type, member); - if (memberApiListing != null) - { - memberApiListing.Source = member; - typeDescriptor.Members.Add(memberApiListing); - } - } - - return typeDescriptor; - } - - private static TypeKind GetTypeKind(TypeInfo type) - { - if (type.IsInterface) - { - return TypeKind.Interface; - } - - if (type.IsEnum) - { - return TypeKind.Enumeration; - } - - if (type.IsValueType) - { - return TypeKind.Struct; - } - - if (type.IsClass) - { - return TypeKind.Class; - } - - return TypeKind.Unknown; - } - - private static IEnumerable GetGenericConstraintsFor(TypeInfo[] genericArguments) - { - foreach (var typeArgument in genericArguments) - { - var constraintDescriptor = new GenericParameterDescriptor - { - Source = typeArgument - }; - if (typeArgument.IsGenericParameter) - { - if (typeArgument.BaseType != null && - typeArgument.BaseType != typeof(object) - && typeArgument.BaseType != typeof(ValueType)) - { - constraintDescriptor.BaseTypeOrInterfaces.Add(TypeDescriptor.GetTypeNameFor(typeArgument.BaseType.GetTypeInfo())); - } - - foreach (var interfaceType in TypeDescriptor.GetImplementedInterfacesFor(typeArgument)) - { - constraintDescriptor.BaseTypeOrInterfaces.Add(TypeDescriptor.GetTypeNameFor(interfaceType)); - } - - constraintDescriptor.ParameterName = typeArgument.Name; - constraintDescriptor.ParameterPosition = typeArgument.GenericParameterPosition; - constraintDescriptor.New = (typeArgument.GenericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint; - constraintDescriptor.Class = (typeArgument.GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint; - constraintDescriptor.Struct = (typeArgument.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint; - } - else - { - constraintDescriptor.ParameterName = TypeDescriptor.GetTypeNameFor(typeArgument); - } - - yield return constraintDescriptor; - } - } - - public static MemberDescriptor GenerateMemberApiListing(TypeInfo type, MemberInfo member) - { - switch (member.MemberType) - { - case MemberTypes.Constructor: - var ctor = (ConstructorInfo)member; - if (!ctor.IsPublic && !ctor.IsFamily && !ctor.IsFamilyOrAssembly) - { - return null; - } - - var constructorDescriptor = new MemberDescriptor - { - Kind = MemberKind.Constructor, - Visibility = ctor.IsPublic ? ApiElementVisibility.Public : ApiElementVisibility.Protected, - - Name = MemberDescriptor.GetMemberNameFor(ctor) - }; - foreach (var parameter in ctor.GetParameters()) - { - var parameterDescriptor = GenerateParameterDescriptor(parameter); - constructorDescriptor.Parameters.Add(parameterDescriptor); - } - - return constructorDescriptor; - - case MemberTypes.Method: - var method = (MethodInfo)member; - if (!method.IsPublic && !method.IsFamily && !method.IsFamilyOrAssembly) - { - return null; - } - - var methodDescriptor = new MemberDescriptor - { - Kind = MemberKind.Method, - - Visibility = method.IsPublic ? ApiElementVisibility.Public : ApiElementVisibility.Protected - }; - if (!type.IsInterface) - { - methodDescriptor.ExplicitInterface = GetInterfaceImplementation(method, explicitImplementation: true); - methodDescriptor.ImplementedInterface = methodDescriptor.ExplicitInterface ?? GetInterfaceImplementation(method, explicitImplementation: false); - } - else - { - methodDescriptor.Visibility = null; - } - - methodDescriptor.Name = MemberDescriptor.GetMemberNameFor(method); - - if (method.IsGenericMethod) - { - var constraints = GetGenericConstraintsFor(method.GetGenericArguments().Select(t => t.GetTypeInfo()).ToArray()); - foreach (var constraint in constraints) - { - methodDescriptor.GenericParameter.Add(constraint); - } - } - - methodDescriptor.Static = method.IsStatic; - methodDescriptor.Sealed = method.IsFinal; - methodDescriptor.Virtual = !type.IsInterface && method.IsVirtual; - methodDescriptor.Override = !type.IsInterface && method.IsVirtual && !Equals(method.GetBaseDefinition(), method); - methodDescriptor.Abstract = !type.IsInterface && method.IsAbstract; - methodDescriptor.New = !method.IsAbstract && !method.IsVirtual && method.IsHideBySig && method - .DeclaringType.GetMember(method.Name) - .OfType() - .Count(m => SameSignature(m, method)) > 1; - methodDescriptor.Extension = method.IsDefined(typeof(ExtensionAttribute), false); - - foreach (var parameter in method.GetParameters()) - { - var parameterDescriptor = GenerateParameterDescriptor(parameter); - methodDescriptor.Parameters.Add(parameterDescriptor); - } - - methodDescriptor.ReturnType = TypeDescriptor.GetTypeNameFor(method.ReturnType.GetTypeInfo()); - - return methodDescriptor; - - case MemberTypes.Field: - var field = (FieldInfo)member; - if (!field.IsPublic && !field.IsFamily && !field.IsFamilyOrAssembly) - { - return null; - } - - if (type.IsEnum && !field.IsLiteral) - { - // Skip storage for enumerations. - return null; - } - - var fieldDescriptor = new MemberDescriptor - { - Visibility = field.IsPublic ? ApiElementVisibility.Public : ApiElementVisibility.Protected, - - Kind = MemberKind.Field, - Name = field.Name - }; - if (type.IsEnum || field.IsLiteral) - { - fieldDescriptor.Literal = FormatLiteralValue(field.GetRawConstantValue(), field.FieldType); - } - - if (type.IsEnum) - { - fieldDescriptor.Visibility = null; - } - else - { - fieldDescriptor.Constant = field.IsLiteral; - fieldDescriptor.Static = field.IsStatic; - fieldDescriptor.ReadOnly = field.IsInitOnly; - fieldDescriptor.ReturnType = TypeDescriptor.GetTypeNameFor(field.FieldType.GetTypeInfo()); - } - - return fieldDescriptor; - case MemberTypes.Event: - case MemberTypes.Property: - case MemberTypes.NestedType: - // All these cases are covered by the methods they implicitly define on the class - // (Properties and Events) and when we enumerate all the types in an assembly (Nested types). - return null; - - case MemberTypes.TypeInfo: - // There should not be any member passed into this method that is not a top level type. - case MemberTypes.Custom: - // We don't know about custom member types, so better throw if we find something we don't understand. - case MemberTypes.All: - throw new InvalidOperationException($"'{type.MemberType}' [{member}] is not supported."); - - default: - return null; - } - } - - public static ApiListing LoadFrom(string json, IEnumerable> oldApiListingFilters = null) - { - oldApiListingFilters = oldApiListingFilters ?? Enumerable.Empty>(); - var oldApiListing = JsonConvert.DeserializeObject(json); - foreach (var type in oldApiListing.Types.ToArray()) - { - if (oldApiListingFilters.Any(filter => filter(type))) - { - oldApiListing.Types.Remove(type); - } - - foreach (var member in type.Members.ToArray()) - { - if (oldApiListingFilters.Any(filter => filter(member))) - { - type.Members.Remove(member); - } - } - } - return oldApiListing; - } - - private static string GetInterfaceImplementation(MethodInfo method, bool explicitImplementation) - { - var typeInfo = method.DeclaringType.GetTypeInfo(); - foreach (var interfaceImplementation in method.DeclaringType.GetInterfaces()) - { - var map = typeInfo.GetRuntimeInterfaceMap(interfaceImplementation); - if (map.TargetMethods.Any(m => m.Equals(method))) - { - return !explicitImplementation || (method.IsPrivate && method.IsFinal) ? - TypeDescriptor.GetTypeNameFor(interfaceImplementation.GetTypeInfo()) : - null; - } - } - - return null; - } - - private static bool SameSignature(MethodInfo candidate, MethodInfo method) - { - if (candidate.ReturnType != method.ReturnType) - { - return false; - } - - var candidateParameters = candidate.GetParameters(); - var methodParameters = method.GetParameters(); - - if (candidateParameters.Length != methodParameters.Length) - { - return false; - } - - for (var i = 0; i < candidateParameters.Length; i++) - { - var candidateParameter = candidateParameters[i]; - var methodParameter = methodParameters[i]; - if (candidateParameter.ParameterType != methodParameter.ParameterType || - candidateParameter.HasDefaultValue != methodParameter.HasDefaultValue || - candidateParameter.IsIn != methodParameter.IsIn || - candidateParameter.IsOut != methodParameter.IsOut || - candidateParameter.IsOptional != methodParameter.IsOptional) - { - return false; - } - } - - return true; - } - - private static ParameterDescriptor GenerateParameterDescriptor(ParameterInfo parameter) - { - return new ParameterDescriptor - { - Source = parameter, - Name = parameter.Name, - Type = TypeDescriptor.GetTypeNameFor(parameter.ParameterType.GetTypeInfo()), - Direction = parameter.ParameterType.IsByRef && parameter.IsOut ? ParameterDirection.Out : - parameter.ParameterType.IsByRef && !parameter.IsOut ? ParameterDirection.Ref : - ParameterDirection.In, - DefaultValue = parameter.HasDefaultValue ? FormatLiteralValue(parameter) : null, - IsParams = parameter.GetCustomAttribute() != null - }; - } - - private static string FormatLiteralValue(ParameterInfo parameter) - { - return FormatLiteralValue(parameter.RawDefaultValue, parameter.ParameterType); - } - - private static string FormatLiteralValue(object rawDefaultValue, Type elementType) - { - if (rawDefaultValue == null) - { - var elementTypeInfo = elementType.GetTypeInfo(); - return elementTypeInfo.IsValueType ? $"default({TypeDescriptor.GetTypeNameFor(elementTypeInfo)})" : "null"; - } - - if (elementType == typeof(string)) - { - return $"\"{rawDefaultValue}\""; - } - - if (elementType == typeof(char)) - { - return $"'{rawDefaultValue}'"; - } - - if (rawDefaultValue is bool || - rawDefaultValue is byte || - rawDefaultValue is sbyte || - rawDefaultValue is short || - rawDefaultValue is ushort || - rawDefaultValue is int || - rawDefaultValue is uint || - rawDefaultValue is long || - rawDefaultValue is ulong || - rawDefaultValue is double || - rawDefaultValue is float || - rawDefaultValue is decimal) - { - return rawDefaultValue.ToString(); - } - - throw new InvalidOperationException("Unsupported default value type"); - } - } -} diff --git a/src/ApiCheck.Console/BreakingChange.cs b/src/ApiCheck.Console/BreakingChange.cs deleted file mode 100644 index dff0d9fbb..000000000 --- a/src/ApiCheck.Console/BreakingChange.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.DotNet.PlatformAbstractions; - -namespace ApiCheck -{ - public class BreakingChange - { - public BreakingChange(string typeId, string memberId, ChangeKind kind) - { - TypeId = typeId; - MemberId = memberId; - Kind = kind; - } - - public string TypeId { get; } - public string MemberId { get; } - public ChangeKind Kind { get; } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - return obj.GetType() == GetType() && Equals((BreakingChange)obj); - } - - private bool Equals(BreakingChange other) - { - return string.Equals(TypeId, other.TypeId) && string.Equals(MemberId, other.MemberId) && Kind == other.Kind; - } - - public override int GetHashCode() - { - var hashCodeCombiner = HashCodeCombiner.Start(); - hashCodeCombiner.Add(TypeId); - hashCodeCombiner.Add(MemberId); - hashCodeCombiner.Add(Kind); - - return hashCodeCombiner.CombinedHash; - } - } -} diff --git a/src/ApiCheck.Console/ChangeKind.cs b/src/ApiCheck.Console/ChangeKind.cs deleted file mode 100644 index 9423d0be0..000000000 --- a/src/ApiCheck.Console/ChangeKind.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace ApiCheck -{ - [JsonConverter(typeof(StringEnumConverter))] - public enum ChangeKind - { - Removal, - Addition, - } -} diff --git a/src/ApiCheck.Console/Loader/AssemblyLoader.cs b/src/ApiCheck.Console/Loader/AssemblyLoader.cs deleted file mode 100644 index 90b3ab8f9..000000000 --- a/src/ApiCheck.Console/Loader/AssemblyLoader.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#if NET46 -using System.IO; -#endif -using System.Reflection; -#if NETCOREAPP2_1 -using NuGet.ProjectModel; -using ApiCheck.NuGet; -#endif - -namespace ApiCheck -{ - public abstract class AssemblyLoader - { - public static Assembly LoadAssembly( - string assemblyPath, - string assetsJson, - string framework) - { -#if NETCOREAPP2_1 - var lockFile = new LockFileFormat().Read(assetsJson); - var graph = PackageGraph.Create(lockFile, framework); - var loader = new CoreClrAssemblyLoader(graph, assemblyPath); -#else - var assemblyDirectory = Path.GetDirectoryName(assemblyPath); - var loader = new FullFrameworkAssemblyLoader(assemblyDirectory); -#endif - - return loader.Load(assemblyPath); - } - } -} diff --git a/src/ApiCheck.Console/Loader/AssemblyNameComparer.cs b/src/ApiCheck.Console/Loader/AssemblyNameComparer.cs deleted file mode 100644 index 49b9563c7..000000000 --- a/src/ApiCheck.Console/Loader/AssemblyNameComparer.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace ApiCheck -{ - internal class AssemblyNameComparer : IEqualityComparer - { - public static readonly IEqualityComparer OrdinalIgnoreCase = new AssemblyNameComparer(); - - public bool Equals(AssemblyName x, AssemblyName y) - { - // Ignore case because that's what Assembly.Load does. - return string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase) && - string.Equals(x.CultureName ?? string.Empty, y.CultureName ?? string.Empty, StringComparison.Ordinal); - } - - public int GetHashCode(AssemblyName obj) - { - var hashCode = 0; - if (obj.Name != null) - { - hashCode ^= obj.Name.GetHashCode(); - } - - hashCode ^= (obj.CultureName ?? string.Empty).GetHashCode(); - return hashCode; - } - } -} diff --git a/src/ApiCheck.Console/Loader/CoreClrAssemblyLoader.cs b/src/ApiCheck.Console/Loader/CoreClrAssemblyLoader.cs deleted file mode 100644 index 87aed447f..000000000 --- a/src/ApiCheck.Console/Loader/CoreClrAssemblyLoader.cs +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#if NETCOREAPP2_1 - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Runtime.Loader; -using NuGet.Frameworks; -using ApiCheck.NuGet; - -namespace ApiCheck -{ - public class CoreClrAssemblyLoader - { - private readonly IDictionary _assemblyPaths; - private readonly PackageGraph _graph; - private readonly ApiCheckLoadContext _loadContext; - - public CoreClrAssemblyLoader(PackageGraph graph, string assemblyPath) - { - _graph = graph; - _assemblyPaths = new Dictionary(new AssemblyNameComparer()); - var directory = new DirectoryInfo(Path.GetDirectoryName(assemblyPath)); - if (directory.Exists) - { - foreach (var assembly in directory.EnumerateFiles("*.dll")) - { - if (TryGetAssemblyName(assembly.FullName, out var name)) - { - _assemblyPaths.Add(name, assembly.FullName); - } - } - } - - foreach (var path in graph.GetAssembliesFullPath()) - { - if (TryGetAssemblyName(path, out var name) && !_assemblyPaths.ContainsKey(name)) - { - _assemblyPaths.Add(name, path); - } - } - - _loadContext = new ApiCheckLoadContext(FindAssemblyPath); - } - - public Assembly Load(string assemblyPath) - { - return _loadContext.LoadFromAssemblyPath(assemblyPath); - } - - private bool TryGetAssemblyName(string path, out AssemblyName assemblyName) - { - assemblyName = null; - if (!File.Exists(path)) - { - // Path might be bin\placeholder\** if assembly came from a project-to-project reference. Since those - // assemblies are found in the current output directory, just ignore non-existent paths. If this path - // came from somewhere else and assembly is used, loading will fail soon enough. - return false; - } - - // From http://msdn.microsoft.com/en-us/library/ms173100.aspx and AssemblyHelper.IsAssemblyManaged(). - try - { - assemblyName = AssemblyLoadContext.GetAssemblyName(path); - return true; - } - catch (FileNotFoundException) - { - // The file cannot be found (should be redundant). - } - catch (BadImageFormatException) - { - // The file is not an assembly. - } - catch (FileLoadException) - { - // The assembly has already been loaded. - } - - return false; - } - - private string FindAssemblyPath(AssemblyName name) - { - if (_assemblyPaths.TryGetValue(name, out var path)) - { - return path; - } - - return null; - } - - private class ApiCheckLoadContext : AssemblyLoadContext - { - private readonly Func _finder; - - public ApiCheckLoadContext(Func finder) - { - _finder = finder; - } - - protected override Assembly Load(AssemblyName assemblyName) - { - try - { - var assembly = Default.LoadFromAssemblyName(assemblyName); - if (assembly != null) - { - return assembly; - } - } - catch (FileNotFoundException) - { - } - - string path = _finder(assemblyName); - if (path != null) - { - return LoadFromAssemblyPath(path); - } - - return null; - } - } - } -} -#endif diff --git a/src/ApiCheck.Console/Loader/FullFrameworkAssemblyLoader.cs b/src/ApiCheck.Console/Loader/FullFrameworkAssemblyLoader.cs deleted file mode 100644 index f540ea567..000000000 --- a/src/ApiCheck.Console/Loader/FullFrameworkAssemblyLoader.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#if !NETCOREAPP2_1 - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -namespace ApiCheck -{ - public class FullFrameworkAssemblyLoader - { - private readonly Dictionary _resolvedDlls; - - public FullFrameworkAssemblyLoader(string probingPath) - { - var directory = new DirectoryInfo(probingPath); - _resolvedDlls = directory.EnumerateFiles("*.dll") - .ToDictionary(f => GetAssemblyName(f.FullName), f => f.FullName, new AssemblyNameComparer()); - - AppDomain.CurrentDomain.AssemblyResolve += Resolver; - } - - private AssemblyName GetAssemblyName(string assemblyPath) => AssemblyName.GetAssemblyName(assemblyPath); - - private Assembly Resolver(object sender, ResolveEventArgs args) - { - var name = new AssemblyName(args.Name); - var path = FindAssemblyPath(name); - - return path != null ? Assembly.LoadFile(path) : null; - } - - private string FindAssemblyPath(AssemblyName name) => _resolvedDlls.TryGetValue(name, out var path) ? path : null; - - public Assembly Load(string assemblyPath) => Assembly.LoadFile(assemblyPath); - } -} - -#endif \ No newline at end of file diff --git a/src/ApiCheck.Console/Microsoft.AspNetCore.BuildTools.ApiCheck.nuspec b/src/ApiCheck.Console/Microsoft.AspNetCore.BuildTools.ApiCheck.nuspec deleted file mode 100644 index 9d49b2da3..000000000 --- a/src/ApiCheck.Console/Microsoft.AspNetCore.BuildTools.ApiCheck.nuspec +++ /dev/null @@ -1,18 +0,0 @@ - - - - $id$ - $version$ - Microsoft - Generates API baselines and detects breaking changes in APIs. - - - - - - - - - - - diff --git a/src/ApiCheck.Console/NuGet/Package.cs b/src/ApiCheck.Console/NuGet/Package.cs deleted file mode 100644 index fa4501f78..000000000 --- a/src/ApiCheck.Console/NuGet/Package.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using NuGet.LibraryModel; -using NuGet.Versioning; - -namespace ApiCheck.NuGet -{ - public class Package : IEquatable - { - public Package( - string name, - string version, - string path, - string signaturePath, - IEnumerable dependencies, - IEnumerable runtimeAssemblies) - { - Name = name; - Version = version; - Path = path; - PackageHash = signaturePath; - Dependencies = dependencies; - Assemblies = runtimeAssemblies.Select(ra => new PackageAssembly(ra, GetAssemblyPath(ra))); - } - - public Package(Package package) - { - Name = package.Name; - Version = package.Version; - Path = package.Path; - PackageHash = package.PackageHash; - Dependencies = package.Dependencies; - Assemblies = package.Assemblies; - } - - public LibraryIdentity Identity => new LibraryIdentity(Name, NuGetVersion.Parse(Version), LibraryType.Package); - public string Name { get; set; } - public string Version { get; set; } - public IEnumerable Dependencies { get; set; } - public string Path { get; set; } - public string PackageHash { get; set; } - public IEnumerable Assemblies { get; set; } - - public bool Equals(Package other) => - Name.Equals(other?.Name, StringComparison.OrdinalIgnoreCase) && - Version.Equals(other?.Version, StringComparison.OrdinalIgnoreCase); - - public override bool Equals(object obj) => Equals(obj as Package); - - public override int GetHashCode() => Name.GetHashCode() ^ Version.GetHashCode(); - - public override string ToString() => $"{Name} {Version}"; - - public string GetAssemblyPath(string relativeAssemblyPath) => - System.IO.Path.Combine(Path, relativeAssemblyPath); - } -} diff --git a/src/ApiCheck.Console/NuGet/PackageAssembly.cs b/src/ApiCheck.Console/NuGet/PackageAssembly.cs deleted file mode 100644 index 317a3bdd9..000000000 --- a/src/ApiCheck.Console/NuGet/PackageAssembly.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; - -namespace ApiCheck.NuGet -{ - public class PackageAssembly - { - public PackageAssembly(string relativePath, string resolvedPath) - { - RelativePath = relativePath; - ResolvedPath = resolvedPath; - } - - public string FileName => Path.GetFileName(ResolvedPath); - public string RelativePath { get; set; } - public string ResolvedPath { get; set; } - } -} diff --git a/src/ApiCheck.Console/NuGet/PackageGraph.cs b/src/ApiCheck.Console/NuGet/PackageGraph.cs deleted file mode 100644 index a06bf71e0..000000000 --- a/src/ApiCheck.Console/NuGet/PackageGraph.cs +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using NuGet.Frameworks; -using NuGet.Packaging.Core; -using NuGet.ProjectModel; - -namespace ApiCheck.NuGet -{ - public class PackageGraph - { - private PackageGraph( - IEnumerable packageFolders, - IDictionary allPackages, - IEnumerable packages, - string targetFrameworkName) - { - PackageSources = packageFolders; - AllPackages = allPackages; - Dependencies = packages; - Framework = targetFrameworkName; - } - - public PackageGraph GetClosure(string packageId) - { - if (!AllPackages.TryGetValue(packageId, out var package)) - { - return null; - } - - var allPackages = new Dictionary(); - CollectPackages(package, allPackages); - return new PackageGraph(PackageSources, allPackages, new[] { package }, Framework); - } - - private void CollectPackages(Package package, IDictionary allPackages) - { - var remainingPackages = new Stack(); - remainingPackages.Push(package); - while (remainingPackages.Count > 0) - { - var current = remainingPackages.Pop(); - if (!allPackages.ContainsKey(current.Name)) - { - allPackages.Add(current.Name, current); - foreach (var dependency in current.Dependencies) - { - if (!allPackages.ContainsKey(dependency.Name)) - { - remainingPackages.Push(dependency); - } - } - } - } - } - - public PackageGraph WithoutPackage(string packageId) - { - var packages = new Dictionary(AllPackages, StringComparer.OrdinalIgnoreCase); - var package = packages.FirstOrDefault(p => p.Key.Equals(packageId, StringComparison.OrdinalIgnoreCase)); - if (package.Value != null) - { - var packagesToExclude = GetPackagesToExclude(package); - foreach (var exclusion in packagesToExclude) - { - packages.Remove(exclusion.Key); - } - - var newDependencies = Dependencies.ToList(); - foreach (var dependency in Dependencies) - { - if (packagesToExclude.ContainsKey(dependency.Name)) - { - newDependencies.Remove(dependency); - } - } - - foreach (var dependency in newDependencies.ToArray()) - { - var newDependency = RemovePackagesFromTransitiveDependencies(dependency, packagesToExclude); - if (!Equals(newDependency, dependency)) - { - newDependencies.Remove(dependency); - newDependencies.Add(newDependency); - } - } - - return new PackageGraph(PackageSources, packages, newDependencies, Framework); - } - - return this; - } - - private Package RemovePackagesFromTransitiveDependencies( - Package dependency, - Dictionary packagesToExclude) - { - var dependenciesModified = false; - var newDependencies = new List(); - foreach (var package in dependency.Dependencies) - { - if (!packagesToExclude.ContainsKey(package.Name)) - { - var newDependency = RemovePackagesFromTransitiveDependencies(package, packagesToExclude); - if (!Equals(newDependency, package) || dependenciesModified) - { - dependenciesModified = true; - } - newDependencies.Add(newDependency); - } - else - { - dependenciesModified = true; - } - } - - if (dependenciesModified) - { - var newPackage = new Package(dependency) - { - Dependencies = newDependencies - }; - return newPackage; - } - return dependency; - } - - private static Dictionary GetPackagesToExclude(KeyValuePair package) - { - var packagesToExclude = new Dictionary(StringComparer.OrdinalIgnoreCase); - var pendingDependencies = new Stack(); - pendingDependencies.Push(package.Value); - while (pendingDependencies.Count > 0) - { - var current = pendingDependencies.Pop(); - if (!packagesToExclude.ContainsKey(current.Name)) - { - packagesToExclude.Add(current.Name, current); - foreach (var dependency in current.Dependencies) - { - pendingDependencies.Push(dependency); - } - } - } - - return packagesToExclude; - } - - public IEnumerable Dependencies { get; set; } - - public IDictionary AllPackages { get; set; } - - public IEnumerable PackageSources { get; set; } - - public string Framework { get; set; } - - public static PackageGraph Create(LockFile lockFile, string targetFrameworkName) - { - var runtimeIdentifier = RuntimeGraph.GetCurrentRuntimeId(); - var fallbacks = RuntimeGraph.GetCompatibleRuntimes(runtimeIdentifier); - - var parsedFramework = NuGetFramework.Parse(targetFrameworkName); - var dependencyGroup = FindCompatibleDependencyGroup(lockFile, parsedFramework); - if (dependencyGroup == null) - { - return null; - } - - var chosenFramework = NuGetFramework.Parse(dependencyGroup.FrameworkName); - var potentialFrameworks = lockFile.Targets - .Where(t => t.TargetFramework.Equals(chosenFramework)); - var targetFramework = potentialFrameworks - .FirstOrDefault(t => runtimeIdentifier.Equals(t.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase)); - - targetFramework = targetFramework ?? potentialFrameworks - .FirstOrDefault(t => RuntimeIsCompatible(t.RuntimeIdentifier, fallbacks)); - - targetFramework = targetFramework ?? potentialFrameworks - .FirstOrDefault(t => t.RuntimeIdentifier == null); - - var directDependencies = targetFramework - .Libraries - .Where(l => dependencyGroup.Dependencies.Any(d => d.StartsWith(l.Name, StringComparison.OrdinalIgnoreCase))) - .ToArray(); - - var allPackages = new Dictionary(StringComparer.OrdinalIgnoreCase); - - var sources = lockFile.PackageFolders.Select(p => p.Path).ToArray(); - - var packages = directDependencies - .Select(dd => CreatePackage(dd, targetFramework, lockFile.Libraries, allPackages, sources, fallbacks)) - .ToArray(); - - return new PackageGraph(sources, allPackages, packages, chosenFramework.GetShortFolderName()); - } - - private static ProjectFileDependencyGroup FindCompatibleDependencyGroup(LockFile lockFile, NuGetFramework parsedFramework) - { - return lockFile.ProjectFileDependencyGroups.FirstOrDefault(g => NuGetFramework.Parse(g.FrameworkName).Equals(parsedFramework)) ?? - lockFile.ProjectFileDependencyGroups.FirstOrDefault(g => IsCompatible(parsedFramework, NuGetFramework.Parse(g.FrameworkName))); - } - - private static bool IsCompatible(NuGetFramework reference, NuGetFramework target) - { - return DefaultCompatibilityProvider.Instance.IsCompatible(reference, target); - } - - private static bool RuntimeIsCompatible(string runtime, IEnumerable compatibleRuntimes) - { - // Technically, a null runtime is compatible. But, Create() gives preference to targets with an exact - // match and then a compatible match (this method) over targets with a null Runtime. - return compatibleRuntimes.Any(r => r.Equals(runtime, StringComparison.OrdinalIgnoreCase)); - } - - public IEnumerable GetAssembliesFullPath() => - AllPackages.SelectMany(p => p.Value.Assemblies.Select(a => a.ResolvedPath)); - - private static Package CreatePackage( - LockFileTargetLibrary dependency, - LockFileTarget targetFramework, - IList libraries, - IDictionary packageDictionary, - IEnumerable sources, - IEnumerable compatibleRuntimes) - { - var library = libraries - .First(l => string.Equals(l.Name, dependency.Name, StringComparison.OrdinalIgnoreCase) && - l.Version.Equals(dependency.Version)); - if (packageDictionary.TryGetValue(library.Name, out var package)) - { - return package; - } - - var packagePath = ResolvePackagePath(library.Name, library.Version.ToString(), sources); - var signaturePath = library.Files - .SingleOrDefault(f => f.EndsWith(".sha512", StringComparison.OrdinalIgnoreCase)); - - var dependencies = new List(); - if (dependency.Dependencies?.Count > 0) - { - foreach (var d in dependency.Dependencies) - { - if (!packageDictionary.TryGetValue(d.Id, out var dependentPackage)) - { - dependentPackage = CreatePackage( - FindLibrary(targetFramework, d), - targetFramework, - libraries, - packageDictionary, - sources, - compatibleRuntimes); - } - - dependencies.Add(dependentPackage); - } - } - - var assemblies = dependency - .RuntimeAssemblies - .Where(assembly => !assembly.Path.EndsWith("_._", StringComparison.Ordinal)) - .ToArray(); - if (assemblies.Length == 0) - { - var targetAssemblyPaths = dependency - .RuntimeTargets - .Where(target => RuntimeIsCompatible(target.Runtime, compatibleRuntimes) && - !target.Path.EndsWith("_._", StringComparison.Ordinal)); - assemblies = targetAssemblyPaths.ToArray(); - } - - var assemblyPaths = assemblies.Select(assembly => assembly.Path); - package = new Package( - library.Name, - library.Version.ToString(), - packagePath, - signaturePath, - dependencies, - assemblyPaths); - - packageDictionary.Add(package.Name, package); - - return package; - } - - private static string ResolvePath(string path, string libraryName, string version, IEnumerable sources) - { - foreach (var source in sources) - { - var fullPath = Path.Combine(source, libraryName, version, path); - if (File.Exists(fullPath)) - { - return fullPath; - } - } - - return path; - } - - private static string ResolvePackagePath(string libraryName, string version, IEnumerable sources) - { - foreach (var source in sources) - { - var fullPath = Path.Combine(source, libraryName, version); - if (Directory.Exists(fullPath)) - { - return fullPath; - } - } - - return string.Empty; - } - - private static LockFileTargetLibrary FindLibrary(LockFileTarget targetFramework, PackageDependency d) - { - return targetFramework.Libraries.First(l => d.Id.Equals(l.Name)); - } - } -} diff --git a/src/ApiCheck.Console/NuGet/RuntimeDefinition.cs b/src/ApiCheck.Console/NuGet/RuntimeDefinition.cs deleted file mode 100644 index 19882c634..000000000 --- a/src/ApiCheck.Console/NuGet/RuntimeDefinition.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; - -namespace ApiCheck.NuGet -{ - public class RuntimeDefinition - { - public string Name { get; set; } - public IEnumerable Fallbacks { get; set; } - - public override string ToString() - { - return Name; - } - } -} diff --git a/src/ApiCheck.Console/NuGet/RuntimeGraph.Compatibility.cs b/src/ApiCheck.Console/NuGet/RuntimeGraph.Compatibility.cs deleted file mode 100644 index ae61c8822..000000000 --- a/src/ApiCheck.Console/NuGet/RuntimeGraph.Compatibility.cs +++ /dev/null @@ -1,814 +0,0 @@ -namespace ApiCheck.NuGet -{ - public partial class RuntimeGraph - { - private const string RuntimeCompatibility = @" -{ - ""runtimes"": { - ""base"": { - }, - ""any"": { - ""#import"": [ ""base"" ] - }, - ""win"": { - ""#import"": [ ""any"" ] - }, - ""win-x86"": { - ""#import"": [ ""win"" ] - }, - ""win-x64"": { - ""#import"": [ ""win"" ] - }, - ""win7"": { - ""#import"": [ ""win"" ] - }, - ""win7-x86"": { - ""#import"": [ ""win7"", ""win-x86"" ] - }, - ""win7-x64"": { - ""#import"": [ ""win7"", ""win-x64"" ] - }, - ""win8"": { - ""#import"": [ ""win7"" ] - }, - ""win8-x86"": { - ""#import"": [ ""win8"", ""win7-x86"" ] - }, - ""win8-x64"": { - ""#import"": [ ""win8"", ""win7-x64"" ] - }, - ""win8-arm"": { - ""#import"": [ ""win8"" ] - }, - ""win81"": { - ""#import"": [ ""win8"" ] - }, - ""win81-x86"": { - ""#import"": [ ""win81"", ""win8-x86"" ] - }, - ""win81-x64"": { - ""#import"": [ ""win81"", ""win8-x64"" ] - }, - ""win81-arm"": { - ""#import"": [ ""win81"", ""win8-arm"" ] - }, - ""win10"": { - ""#import"": [ ""win81"" ] - }, - ""win10-x86"": { - ""#import"": [ ""win10"", ""win81-x86"" ] - }, - ""win10-x64"": { - ""#import"": [ ""win10"", ""win81-x64"" ] - }, - ""win10-arm"": { - ""#import"": [ ""win10"", ""win81-arm"" ] - }, - ""win10-arm64"": { - ""#import"": [ ""win10"" ] - }, - ""aot"": { - ""#import"": [ ""any"" ] - }, - ""win-aot"": { - ""#import"": [ ""win"", ""aot"" ] - }, - ""win-x86-aot"": { - ""#import"": [ ""win-aot"", ""win-x86"" ] - }, - ""win-x64-aot"": { - ""#import"": [ ""win-aot"", ""win-x64"" ] - }, - ""win7-aot"": { - ""#import"": [ ""win-aot"", ""win7"" ] - }, - ""win7-x86-aot"": { - ""#import"": [ ""win7-aot"", ""win7-x86"" ] - }, - ""win7-x64-aot"": { - ""#import"": [ ""win7-aot"", ""win7-x64"" ] - }, - ""win8-aot"": { - ""#import"": [ ""win8"", ""win7-aot"" ] - }, - ""win8-x86-aot"": { - ""#import"": [ ""win8-aot"", ""win8-x86"", ""win7-x86-aot"" ] - }, - ""win8-x64-aot"": { - ""#import"": [ ""win8-aot"", ""win8-x64"", ""win7-x64-aot"" ] - }, - ""win8-arm-aot"": { - ""#import"": [ ""win8-aot"", ""win8-arm"" ] - }, - ""win81-aot"": { - ""#import"": [ ""win81"", ""win8-aot"" ] - }, - ""win81-x86-aot"": { - ""#import"": [ ""win81-aot"", ""win81-x86"", ""win8-x86-aot"" ] - }, - ""win81-x64-aot"": { - ""#import"": [ ""win81-aot"", ""win81-x64"", ""win8-x64-aot"" ] - }, - ""win81-arm-aot"": { - ""#import"": [ ""win81-aot"", ""win81-arm"", ""win8-arm-aot"" ] - }, - ""win10-aot"": { - ""#import"": [ ""win10"", ""win81-aot"" ] - }, - ""win10-x86-aot"": { - ""#import"": [ ""win10-aot"", ""win10-x86"", ""win81-x86-aot"" ] - }, - ""win10-x64-aot"": { - ""#import"": [ ""win10-aot"", ""win10-x64"", ""win81-x64-aot"" ] - }, - ""win10-arm-aot"": { - ""#import"": [ ""win10-aot"", ""win10-arm"", ""win81-arm-aot"" ] - }, - ""win10-arm64-aot"": { - ""#import"": [ ""win10-aot"", ""win10-arm64"" ] - }, - ""unix"": { - ""#import"": [ ""any"" ] - }, - ""unix-x64"": { - ""#import"": [ ""unix"" ] - }, - ""unix-x86"": { - ""#import"": [ ""unix"" ] - }, - ""unix-arm"": { - ""#import"": [ ""unix"" ] - }, - ""unix-armel"": { - ""#import"": [ ""unix"" ] - }, - ""unix-arm64"": { - ""#import"": [ ""unix"" ] - }, - ""osx"": { - ""#import"": [ ""unix"" ] - }, - ""osx-x64"": { - ""#import"": [ ""osx"", ""unix-x64"" ] - }, - ""osx.10.10"": { - ""#import"": [ ""osx"" ] - }, - ""osx.10.10-x64"": { - ""#import"": [ ""osx.10.10"", ""osx-x64"" ] - }, - ""osx.10.11"": { - ""#import"": [ ""osx.10.10"" ] - }, - ""osx.10.11-x64"": { - ""#import"": [ ""osx.10.11"", ""osx.10.10-x64"" ] - }, - ""osx.10.12"": { - ""#import"": [ ""osx.10.11"" ] - }, - ""osx.10.12-x64"": { - ""#import"": [ ""osx.10.12"", ""osx.10.11-x64"" ] - }, - ""linux"": { - ""#import"": [ ""unix"" ] - }, - ""linux-x64"": { - ""#import"": [ ""linux"", ""unix-x64"" ] - }, - ""linux-x86"": { - ""#import"": [ ""linux"", ""unix-x86"" ] - }, - ""linux-arm"": { - ""#import"": [ ""linux"", ""unix-arm"" ] - }, - ""linux-armel"": { - ""#import"": [ ""linux"", ""unix-armel"" ] - }, - ""linux-arm64"": { - ""#import"": [ ""linux"", ""unix-arm64"" ] - }, - ""rhel"": { - ""#import"": [ ""linux"" ] - }, - ""rhel-x64"": { - ""#import"": [ ""rhel"", ""linux-x64"" ] - }, - ""rhel.7"": { - ""#import"": [ ""rhel"" ] - }, - ""rhel.7-x64"": { - ""#import"": [ ""rhel.7"", ""rhel-x64"" ] - }, - ""rhel.7.0"": { - ""#import"": [ ""rhel.7"" ] - }, - ""rhel.7.0-x64"": { - ""#import"": [ ""rhel.7.0"", ""rhel.7-x64"" ] - }, - ""rhel.7.1"": { - ""#import"": [ ""rhel.7.0"" ] - }, - ""rhel.7.1-x64"": { - ""#import"": [ ""rhel.7.1"", ""rhel.7.0-x64"" ] - }, - ""rhel.7.2"": { - ""#import"": [ ""rhel.7.1"" ] - }, - ""rhel.7.2-x64"": { - ""#import"": [ ""rhel.7.2"", ""rhel.7.1-x64"" ] - }, - ""rhel.7.3"": { - ""#import"": [ ""rhel.7.2"" ] - }, - ""rhel.7.3-x64"": { - ""#import"": [ ""rhel.7.3"", ""rhel.7.2-x64"" ] - }, - ""rhel.7.4"": { - ""#import"": [ ""rhel.7.3"" ] - }, - ""rhel.7.4-x64"": { - ""#import"": [ ""rhel.7.4"", ""rhel.7.3-x64"" ] - }, - ""ol"": { - ""#import"": [ ""rhel"" ] - }, - ""ol-x64"": { - ""#import"": [ ""ol"", ""rhel-x64"" ] - }, - ""ol.7"": { - ""#import"": [ ""ol"", ""rhel.7"" ] - }, - ""ol.7-x64"": { - ""#import"": [ ""ol.7"", ""ol-x64"", ""rhel.7-x64"" ] - }, - ""ol.7.0"": { - ""#import"": [ ""ol.7"", ""rhel.7.0"" ] - }, - ""ol.7.0-x64"": { - ""#import"": [ ""ol.7.0"", ""ol.7-x64"", ""rhel.7.0-x64"" ] - }, - ""ol.7.1"": { - ""#import"": [ ""ol.7.0"", ""rhel.7.1"" ] - }, - ""ol.7.1-x64"": { - ""#import"": [ ""ol.7.1"", ""ol.7.0-x64"", ""rhel.7.1-x64"" ] - }, - ""ol.7.2"": { - ""#import"": [ ""ol.7.1"", ""rhel.7.2"" ] - }, - ""ol.7.2-x64"": { - ""#import"": [ ""ol.7.2"", ""ol.7.1-x64"", ""rhel.7.2-x64"" ] - }, - ""centos"": { - ""#import"": [ ""rhel"" ] - }, - ""centos-x64"": { - ""#import"": [ ""centos"", ""rhel-x64"" ] - }, - ""centos.7"": { - ""#import"": [ ""centos"", ""rhel.7"" ] - }, - ""centos.7-x64"": { - ""#import"": [ ""centos.7"", ""centos-x64"", ""rhel.7-x64"" ] - }, - ""debian"": { - ""#import"": [ ""linux"" ] - }, - ""debian-x64"": { - ""#import"": [ ""debian"", ""linux-x64"" ] - }, - ""debian-x86"": { - ""#import"": [ ""debian"", ""linux-x86"" ] - }, - ""debian-arm"": { - ""#import"": [ ""debian"", ""linux-arm"" ] - }, - ""debian-armel"": { - ""#import"": [ ""debian"", ""linux-armel"" ] - }, - ""debian-arm64"": { - ""#import"": [ ""debian"", ""linux-arm64"" ] - }, - ""debian.8"": { - ""#import"": [ ""debian"" ] - }, - ""debian.8-x64"": { - ""#import"": [ ""debian.8"", ""debian-x64"" ] - }, - ""debian.8-x86"": { - ""#import"": [ ""debian.8"", ""debian-x86"" ] - }, - ""debian.8-arm"": { - ""#import"": [ ""debian.8"", ""debian-arm"" ] - }, - ""debian.8-armel"": { - ""#import"": [ ""debian.8"", ""debian-armel"" ] - }, - ""debian.8-arm64"": { - ""#import"": [ ""debian.8"", ""debian-arm64"" ] - }, - ""tizen"": { - ""#import"": [ ""linux"" ] - }, - ""tizen-armel"": { - ""#import"": [ ""tizen"", ""linux-armel"" ] - }, - ""tizen.4.0.0-armel"": { - ""#import"": [ ""tizen.4.0.0"", ""tizen-armel"" ] - }, - ""ubuntu"": { - ""#import"": [ ""debian"" ] - }, - ""ubuntu-x64"": { - ""#import"": [ ""ubuntu"", ""debian-x64"" ] - }, - ""ubuntu-x86"": { - ""#import"": [ ""ubuntu"", ""debian-x86"" ] - }, - ""ubuntu-arm"": { - ""#import"": [ ""ubuntu"", ""debian-arm"" ] - }, - ""ubuntu.14.04"": { - ""#import"": [ ""ubuntu"" ] - }, - ""ubuntu.14.04-x64"": { - ""#import"": [ ""ubuntu.14.04"", ""ubuntu-x64"" ] - }, - ""ubuntu.14.04-x86"": { - ""#import"": [ ""ubuntu.14.04"", ""ubuntu-x86"" ] - }, - ""ubuntu.14.04-arm"": { - ""#import"": [ ""ubuntu.14.04"", ""ubuntu-arm"" ] - }, - ""ubuntu.14.10"": { - ""#import"": [ ""ubuntu"" ] - }, - ""ubuntu.14.10-x64"": { - ""#import"": [ ""ubuntu.14.10"", ""ubuntu-x64"" ] - }, - ""ubuntu.14.10-x86"": { - ""#import"": [ ""ubuntu.14.10"", ""ubuntu-x86"" ] - }, - ""ubuntu.14.10-arm"": { - ""#import"": [ ""ubuntu.14.10"", ""ubuntu-arm"" ] - }, - ""ubuntu.15.04"": { - ""#import"": [ ""ubuntu"" ] - }, - ""ubuntu.15.04-x64"": { - ""#import"": [ ""ubuntu.15.04"", ""ubuntu-x64"" ] - }, - ""ubuntu.15.04-x86"": { - ""#import"": [ ""ubuntu.15.04"", ""ubuntu-x86"" ] - }, - ""ubuntu.15.04-arm"": { - ""#import"": [ ""ubuntu.15.04"", ""ubuntu-arm"" ] - }, - ""ubuntu.15.10"": { - ""#import"": [ ""ubuntu"" ] - }, - ""ubuntu.15.10-x64"": { - ""#import"": [ ""ubuntu.15.10"", ""ubuntu-x64"" ] - }, - ""ubuntu.15.10-x86"": { - ""#import"": [ ""ubuntu.15.10"", ""ubuntu-x86"" ] - }, - ""ubuntu.15.10-arm"": { - ""#import"": [ ""ubuntu.15.10"", ""ubuntu-arm"" ] - }, - ""ubuntu.16.04"": { - ""#import"": [ ""ubuntu"" ] - }, - ""ubuntu.16.04-x64"": { - ""#import"": [ ""ubuntu.16.04"", ""ubuntu-x64"" ] - }, - ""ubuntu.16.04-x86"": { - ""#import"": [ ""ubuntu.16.04"", ""ubuntu-x86"" ] - }, - ""ubuntu.16.04-arm"": { - ""#import"": [ ""ubuntu.16.04"", ""ubuntu-arm"" ] - }, - ""ubuntu.16.10"": { - ""#import"": [ ""ubuntu"" ] - }, - ""ubuntu.16.10-x64"": { - ""#import"": [ ""ubuntu.16.10"", ""ubuntu-x64"" ] - }, - ""ubuntu.16.10-x86"": { - ""#import"": [ ""ubuntu.16.10"", ""ubuntu-x86"" ] - }, - ""ubuntu.16.10-arm"": { - ""#import"": [ ""ubuntu.16.10"", ""ubuntu-arm"" ] - }, - ""linuxmint.17"": { - ""#import"": [ ""ubuntu.14.04"" ] - }, - ""linuxmint.17-x64"": { - ""#import"": [ ""linuxmint.17"", ""ubuntu.14.04-x64"" ] - }, - ""linuxmint.17.1"": { - ""#import"": [ ""linuxmint.17"" ] - }, - ""linuxmint.17.1-x64"": { - ""#import"": [ ""linuxmint.17.1"", ""linuxmint.17-x64"" ] - }, - ""linuxmint.17.2"": { - ""#import"": [ ""linuxmint.17.1"" ] - }, - ""linuxmint.17.2-x64"": { - ""#import"": [ ""linuxmint.17.2"", ""linuxmint.17.1-x64"" ] - }, - ""linuxmint.17.3"": { - ""#import"": [ ""linuxmint.17.2"" ] - }, - ""linuxmint.17.3-x64"": { - ""#import"": [ ""linuxmint.17.3"", ""linuxmint.17.2-x64"" ] - }, - ""linuxmint.18"": { - ""#import"": [ ""ubuntu.16.04"" ] - }, - ""linuxmint.18-x64"": { - ""#import"": [ ""linuxmint.18"", ""ubuntu.16.04-x64"" ] - }, - ""fedora"": { - ""#import"": [ ""linux"" ] - }, - ""fedora-x64"": { - ""#import"": [ ""fedora"", ""linux-x64"" ] - }, - ""fedora.23"": { - ""#import"": [ ""fedora"" ] - }, - ""fedora.23-x64"": { - ""#import"": [ ""fedora.23"", ""fedora-x64"" ] - }, - ""fedora.24"": { - ""#import"": [ ""fedora"" ] - }, - ""fedora.24-x64"": { - ""#import"": [ ""fedora.24"", ""fedora-x64"" ] - }, - ""opensuse"": { - ""#import"": [ ""linux"" ] - }, - ""opensuse-x64"": { - ""#import"": [ ""opensuse"", ""linux-x64"" ] - }, - ""opensuse.13.2"": { - ""#import"": [ ""opensuse"" ] - }, - ""opensuse.13.2-x64"": { - ""#import"": [ ""opensuse.13.2"", ""opensuse-x64"" ] - }, - ""opensuse.42.1"": { - ""#import"": [ ""opensuse"" ] - }, - ""opensuse.42.1-x64"": { - ""#import"": [ ""opensuse.42.1"", ""opensuse-x64"" ] - }, - ""alpine"": { - ""#import"": [ ""linux"" ] - }, - ""alpine-x64"": { - ""#import"": [ ""alpine"", ""linux-x64"" ] - }, - ""alpine.3"": { - ""#import"": [ ""alpine"" ] - }, - ""alpine.3-x64"": { - ""#import"": [ ""alpine.3"", ""alpine-x64"" ] - }, - ""alpine.3.4.3"": { - ""#import"": [ ""alpine.3"" ] - }, - ""alpine.3.4.3-x64"": { - ""#import"": [ ""alpine.3.4.3"", ""alpine.3-x64"" ] - }, - ""corert"": { - ""#import"": [ ""any"" ] - }, - ""win-corert"": { - ""#import"": [ ""corert"", ""win"" ] - }, - ""win-x86-corert"": { - ""#import"": [ ""win-corert"", ""win-x86"" ] - }, - ""win-x64-corert"": { - ""#import"": [ ""win-corert"", ""win-x64"" ] - }, - ""win7-corert"": { - ""#import"": [ ""win-corert"", ""win7"" ] - }, - ""win7-x86-corert"": { - ""#import"": [ ""win7-corert"", ""win7-x86"" ] - }, - ""win7-x64-corert"": { - ""#import"": [ ""win7-corert"", ""win7-x64"" ] - }, - ""win8-corert"": { - ""#import"": [ ""win7-corert"", ""win8"" ] - }, - ""win8-x86-corert"": { - ""#import"": [ ""win8-corert"", ""win7-x86-corert"", ""win8-x86"" ] - }, - ""win8-x64-corert"": { - ""#import"": [ ""win8-corert"", ""win7-x64-corert"", ""win8-x64"" ] - }, - ""win8-arm-corert"": { - ""#import"": [ ""win8-corert"", ""win8-arm"" ] - }, - ""win81-corert"": { - ""#import"": [ ""win8-corert"", ""win81"" ] - }, - ""win81-x86-corert"": { - ""#import"": [ ""win81-corert"", ""win8-x86-corert"", ""win81-x86"" ] - }, - ""win81-x64-corert"": { - ""#import"": [ ""win81-corert"", ""win8-x64-corert"", ""win81-x64"" ] - }, - ""win81-arm-corert"": { - ""#import"": [ ""win81-corert"", ""win8-arm-corert"", ""win81-arm"" ] - }, - ""win10-corert"": { - ""#import"": [ ""win81-corert"", ""win10"" ] - }, - ""win10-x86-corert"": { - ""#import"": [ ""win10-corert"", ""win81-x86-corert"", ""win10-x86"" ] - }, - ""win10-x64-corert"": { - ""#import"": [ ""win10-corert"", ""win81-x64-corert"", ""win10-x64"" ] - }, - ""win10-arm-corert"": { - ""#import"": [ ""win10-corert"", ""win81-arm-corert"", ""win10-arm"" ] - }, - ""win10-arm64-corert"": { - ""#import"": [ ""win10-corert"", ""win10-arm64"" ] - }, - ""unix-corert"": { - ""#import"": [ ""corert"", ""unix"" ] - }, - ""unix-x64-corert"": { - ""#import"": [ ""unix-corert"", ""unix-x64"" ] - }, - ""unix-arm-corert"": { - ""#import"": [ ""unix-corert"", ""unix-arm"" ] - }, - ""unix-arm64-corert"": { - ""#import"": [ ""unix-corert"", ""unix-arm64"" ] - }, - ""osx-corert"": { - ""#import"": [ ""unix-corert"", ""osx"" ] - }, - ""osx-x64-corert"": { - ""#import"": [ ""osx-corert"", ""unix-x64-corert"", ""osx-x64"" ] - }, - ""osx.10.10-corert"": { - ""#import"": [ ""osx-corert"", ""osx.10.10"" ] - }, - ""osx.10.10-x64-corert"": { - ""#import"": [ ""osx.10.10-corert"", ""osx-x64-corert"", ""osx.10.10-x64"" ] - }, - ""osx.10.11-corert"": { - ""#import"": [ ""osx.10.10-corert"", ""osx.10.11"" ] - }, - ""osx.10.11-x64-corert"": { - ""#import"": [ ""osx.10.11-corert"", ""osx.10.10-x64-corert"", ""osx.10.11-x64"" ] - }, - ""osx.10.12-corert"": { - ""#import"": [ ""osx.10.11-corert"", ""osx.10.12"" ] - }, - ""osx.10.12-x64-corert"": { - ""#import"": [ ""osx.10.12-corert"", ""osx.10.11-x64-corert"", ""osx.10.12-x64"" ] - }, - ""linux-corert"": { - ""#import"": [ ""corert"", ""linux"", ""unix-corert"" ] - }, - ""linux-x64-corert"": { - ""#import"": [ ""linux-corert"", ""linux-x64"" ] - }, - ""linux-arm-corert"": { - ""#import"": [ ""linux-corert"", ""linux-arm"" ] - }, - ""linux-arm64-corert"": { - ""#import"": [ ""linux-corert"", ""linux-arm64"" ] - }, - ""rhel-corert"": { - ""#import"": [ ""corert"", ""rhel"" ] - }, - ""rhel-x64-corert"": { - ""#import"": [ ""rhel-corert"", ""linux-x64-corert"", ""rhel-x64"" ] - }, - ""rhel.7-corert"": { - ""#import"": [ ""rhel-corert"", ""rhel.7"" ] - }, - ""rhel.7-x64-corert"": { - ""#import"": [ ""rhel.7-corert"", ""rhel-x64-corert"", ""rhel.7-x64"" ] - }, - ""rhel.7.0-corert"": { - ""#import"": [ ""rhel.7-corert"", ""rhel.7.0"" ] - }, - ""rhel.7.0-x64-corert"": { - ""#import"": [ ""rhel.7.0-corert"", ""rhel.7-x64-corert"", ""rhel.7.0-x64"" ] - }, - ""rhel.7.1-corert"": { - ""#import"": [ ""rhel.7.0-corert"", ""rhel.7.1"" ] - }, - ""rhel.7.1-x64-corert"": { - ""#import"": [ ""rhel.7.1-corert"", ""rhel.7.0-x64-corert"", ""rhel.7.1-x64"" ] - }, - ""rhel.7.2-corert"": { - ""#import"": [ ""rhel.7.1-corert"", ""rhel.7.2"" ] - }, - ""rhel.7.2-x64-corert"": { - ""#import"": [ ""rhel.7.2-corert"", ""rhel.7.1-x64-corert"", ""rhel.7.2-x64"" ] - }, - ""ol-corert"": { - ""#import"": [ ""rhel-corert"", ""ol"" ] - }, - ""ol-x64-corert"": { - ""#import"": [ ""ol-corert"", ""rhel-x64-corert"", ""ol-x64"" ] - }, - ""ol.7-corert"": { - ""#import"": [ ""ol-corert"", ""ol.7"" ] - }, - ""ol.7-x64-corert"": { - ""#import"": [ ""ol.7-corert"", ""rhel.7-x64-corert"", ""ol.7-x64"" ] - }, - ""ol.7.0-corert"": { - ""#import"": [ ""ol.7-corert"", ""ol.7.0"" ] - }, - ""ol.7.0-x64-corert"": { - ""#import"": [ ""ol.7.0-corert"", ""rhel.7.0-corert"", ""ol.7.0-x64"" ] - }, - ""ol.7.1-corert"": { - ""#import"": [ ""ol.7.0-corert"", ""ol.7.1"" ] - }, - ""ol.7.1-x64-corert"": { - ""#import"": [ ""ol.7.1-corert"", ""rhel.7.1-x64-corert"", ""ol.7.1-x64"" ] - }, - ""centos-corert"": { - ""#import"": [ ""rel-corert"", ""centos"" ] - }, - ""centos-x64-corert"": { - ""#import"": [ ""centos-corert"", ""rhel-x64-corert"", ""centos-x64"" ] - }, - ""centos.7-corert"": { - ""#import"": [ ""centos-corert"", ""centos.7"" ] - }, - ""centos.7-x64-corert"": { - ""#import"": [ ""centos.7-corert"", ""centos-x64-corert"", ""centos.7-x64"" ] - }, - ""debian-corert"": { - ""#import"": [ ""linux-corert"", ""debian"" ] - }, - ""debian-x64-corert"": { - ""#import"": [ ""debian-corert"", ""linux-x64-corert"", ""debian-x64"" ] - }, - ""debian-arm-corert"": { - ""#import"": [ ""debian-corert"", ""debian-arm"" ] - }, - ""debian-arm64-corert"": { - ""#import"": [ ""debian-corert"", ""debian-arm64"" ] - }, - ""debian.8-corert"": { - ""#import"": [ ""debian-corert"", ""debian.8"" ] - }, - ""debian.8-x64-corert"": { - ""#import"": [ ""debian.8-corert"", ""debian-x64-corert"", ""debian.8-x64"" ] - }, - ""debian.8-arm-corert"": { - ""#import"": [ ""debian.8-corert"", ""debian-arm-corert"", ""debian.8-arm"" ] - }, - ""debian.8-arm64-corert"": { - ""#import"": [ ""debian.8-corert"", ""debian-arm64-corert"", ""debian.8-arm64"" ] - }, - ""ubuntu-corert"": { - ""#import"": [ ""debian-corert"", ""ubuntu"" ] - }, - ""ubuntu-x64-corert"": { - ""#import"": [ ""ubuntu-corert"", ""debian-x64-corert"", ""ubuntu-x64"" ] - }, - ""ubuntu.14.04-corert"": { - ""#import"": [ ""ubuntu-corert"", ""ubuntu.14.06"" ] - }, - ""ubuntu.14.04-x64-corert"": { - ""#import"": [ ""ubuntu.14.04-corert"", ""ubuntu-x64-corert"", ""ubuntu-14.04-x64"" ] - }, - ""ubuntu.14.10-corert"": { - ""#import"": [ ""ubuntu.14.04-corert"", ""ubuntu-14.10"" ] - }, - ""ubuntu.14.10-x64-corert"": { - ""#import"": [ ""ubuntu.14.10-corert"", ""ubuntu.14.04-x64-corert"", ""ubuntu.14.10-x64"" ] - }, - ""ubuntu.15.04-corert"": { - ""#import"": [ ""ubuntu.14.10-corert"", ""ubuntu-15.04"" ] - }, - ""ubuntu.15.04-x64-corert"": { - ""#import"": [ ""ubuntu.15.04-corert"", ""ubuntu.14.10-x64-corert"", ""ubuntu.15.04-x64"" ] - }, - ""ubuntu.15.10-corert"": { - ""#import"": [ ""ubuntu.15.04-corert"", ""ubuntu-15.10"" ] - }, - ""ubuntu.15.10-x64-corert"": { - ""#import"": [ ""ubuntu.15.10-corert"", ""ubuntu.15.04-x64-corert"", ""ubuntu.15.10-x64"" ] - }, - ""ubuntu.16.04-corert"": { - ""#import"": [ ""ubuntu.15.10-corert"", ""ubuntu-16.04"" ] - }, - ""ubuntu.16.04-x64-corert"": { - ""#import"": [ ""ubuntu.16.04-corert"", ""ubuntu.15.10-x64-corert"", ""ubuntu.16.04-x64"" ] - }, - ""ubuntu.16.10-corert"": { - ""#import"": [ ""ubuntu.16.04-corert"", ""ubuntu.16.10"" ] - }, - ""ubuntu.16.10-x64-corert"": { - ""#import"": [ ""ubuntu.16.10-corert"", ""ubuntu.16.04-x64-corert"", ""ubuntu.16.10-x64"" ] - }, - ""linuxmint.17-corert"": { - ""#import"": [ ""ubuntu.14.04-corert"", ""linuxmint.17"" ] - }, - ""linuxmint.17-x64-corert"": { - ""#import"": [ ""linuxmint.17-corert"", ""ubuntu.14.04-x64-corert"", ""linuxmint.17-x64"" ] - }, - ""linuxmint.17.1-corert"": { - ""#import"": [ ""linuxmint.17-corert"", ""linuxmint.17.1"" ] - }, - ""linuxmint.17.1-x64-corert"": { - ""#import"": [ ""linuxmint.17.1-corert"", ""linuxmint.17-x64-corert"", ""linuxmint.17.1-x64"" ] - }, - ""linuxmint.17.2-corert"": { - ""#import"": [ ""linuxmint.17.1-corert"", ""linuxmint.17.2"" ] - }, - ""linuxmint.17.2-x64-corert"": { - ""#import"": [ ""linuxmint.17.2-corert"", ""linuxmint.17.1-x64-corert"", ""linuxmint.17.2-x64"" ] - }, - ""linuxmint.17.3-corert"": { - ""#import"": [ ""linuxmint.17.2-corert"", ""linuxmint.17.3"" ] - }, - ""linuxmint.17.3-x64-corert"": { - ""#import"": [ ""linuxmint.17.3-corert"", ""linuxmint.17.2-x64-corert"", ""linuxmint.17.3-x64"" ] - }, - ""linuxmint.18-corert"": { - ""#import"": [ ""ubuntu.16.04-corert"", ""linuxmint.18"" ] - }, - ""linuxmint.18-x64-corert"": { - ""#import"": [ ""linuxmint.18-corert"", ""ubuntu.16.04-x64-corert"", ""linuxmint.18-x64"" ] - }, - ""fedora-corert"": { - ""#import"": [ ""linux-corert"", ""fedora"" ] - }, - ""fedora-x64-corert"": { - ""#import"": [ ""fedora-corert"", ""linux-x64-corert"", ""fedora-x64"" ] - }, - ""fedora.23-corert"": { - ""#import"": [ ""fedora-corert"", ""fedora.23"" ] - }, - ""fedora.23-x64-corert"": { - ""#import"": [ ""fedora.23-corert"", ""fedora-x64-corert"", ""fedora.23-x64"" ] - }, - ""fedora.24-corert"": { - ""#import"": [ ""fedora.23-corert"", ""fedora.24"" ] - }, - ""fedora.24-x64-corert"": { - ""#import"": [ ""fedora.24-corert"", ""fedora.23-x64-corert"", ""fedora.24-x64"" ] - }, - ""opensuse-corert"": { - ""#import"": [ ""linux-corert"", ""opensuse"" ] - }, - ""opensuse-x64-corert"": { - ""#import"": [ ""opensuse-corert"", ""linux-x64-corert"", ""opensuste-x64"" ] - }, - ""opensuse.13.2-corert"": { - ""#import"": [ ""opensuse-corert"", ""opensuse.13.2"" ] - }, - ""opensuse.13.2-x64-corert"": { - ""#import"": [ ""opensuse.13.2-corert"", ""opensuse-x64-corert"", ""opensuse.13.2-x64"" ] - }, - ""opensuse.42.1-corert"": { - ""#import"": [ ""opensuse.13.2-corert"", ""opensuse.42.1"" ] - }, - ""opensuse.42.1-x64-corert"": { - ""#import"": [ ""opensuse.42.1-corert"", ""opensuse.13.2-x64-corert"", ""opensuse.42.1-x64"" ] - }, - ""alpine-corert"": { - ""#import"": [ ""linux-corert"", ""alpine"" ] - }, - ""alpine-x64-corert"": { - ""#import"": [ ""alpine-corert"", ""linux-x64-corert"", ""alpine-x64"" ] - }, - ""alpine.3-corert"": { - ""#import"": [ ""alpine-corert"", ""alpine.3"" ] - }, - ""alpine.3-x64-corert"": { - ""#import"": [ ""alpine.3-corert"", ""alpine-x64-corert"", ""alpine.3-x64"" ] - }, - ""alpine.3.4.3-corert"": { - ""#import"": [ ""alpine.3-corert"", ""alpine.3.4.3"" ] - }, - ""alpine.3.4.3-x64-corert"": { - ""#import"": [ ""alpine.3.4.3-corert"", ""alpine.3-x64-corert"", ""alpine.3.4.3-x64"" ] - } - } -}"; - } -} diff --git a/src/ApiCheck.Console/NuGet/RuntimeGraph.cs b/src/ApiCheck.Console/NuGet/RuntimeGraph.cs deleted file mode 100644 index ba6faef5c..000000000 --- a/src/ApiCheck.Console/NuGet/RuntimeGraph.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.DotNet.PlatformAbstractions; -using Newtonsoft.Json.Linq; - -namespace ApiCheck.NuGet -{ - public partial class RuntimeGraph - { - private static readonly RuntimeGraph Instance; - - static RuntimeGraph() - { - var graph = JObject.Parse(RuntimeCompatibility); - var runtimes = (IDictionary)graph["runtimes"]; - var runtimesList = runtimes.Select(kvp => new RuntimeDefinition - { - Name = kvp.Key, - Fallbacks = CreateRuntimeDefinitions((IDictionary)kvp.Value, runtimes).ToArray() - }).ToArray(); - - Instance = new RuntimeGraph(runtimesList); - } - - private static IEnumerable CreateRuntimeDefinitions( - IDictionary definition, - IDictionary runtimes) - { - if (!definition.ContainsKey("#import")) - { - return Enumerable.Empty(); - } - var fallbacks = (JArray)definition["#import"]; - return fallbacks - .Select(fr => (string)fr) - .Select(fr => - { - if (runtimes.FirstOrDefault(r => r.Key.Equals(fr)).Key == null) - { - return new RuntimeDefinition - { - Name = fr, - Fallbacks = Enumerable.Empty() - }; - } - return new RuntimeDefinition - { - Name = runtimes.First(r => r.Key.Equals(fr)).Key, - Fallbacks = CreateRuntimeDefinitions( - (IDictionary)runtimes.First(r => r.Key.Equals(fr)).Value, - runtimes).ToArray() - }; - }); - } - - private RuntimeGraph(IEnumerable runtimes) - { - Runtimes = runtimes; - } - - public IEnumerable Runtimes { get; set; } - - public static IEnumerable GetCompatibleRuntimes(string runtimeId) - { - var runtimes = new HashSet(); - var runtime = Instance.Runtimes.FirstOrDefault(r => r.Name.Equals(runtimeId)); - if (runtime != null) - { - var pendingRuntimes = new Stack(); - pendingRuntimes.Push(runtime); - while (pendingRuntimes.Count > 0) - { - var currentRuntime = pendingRuntimes.Pop(); - runtimes.Add(currentRuntime.Name); - foreach (var fallback in currentRuntime.Fallbacks) - { - pendingRuntimes.Push(fallback); - } - } - } - - return runtimes; - } - - public static string GetCurrentRuntimeId() - { - if (RuntimeEnvironment.OperatingSystemPlatform != Platform.Windows) - { - return RuntimeEnvironment.GetRuntimeIdentifier(); - } - var arch = RuntimeEnvironment.RuntimeArchitecture.ToLowerInvariant(); - if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("6.1", StringComparison.Ordinal)) - { - return "win7-" + arch; - } - if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("6.2", StringComparison.Ordinal)) - { - return "win8-" + arch; - } - if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("6.3", StringComparison.Ordinal)) - { - return "win81-" + arch; - } - if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("10.0", StringComparison.Ordinal)) - { - return "win10-" + arch; - } - - throw new InvalidOperationException("Runtime not supported"); - } - } -} diff --git a/src/ApiCheck.Console/Program.cs b/src/ApiCheck.Console/Program.cs deleted file mode 100644 index 4185a52fd..000000000 --- a/src/ApiCheck.Console/Program.cs +++ /dev/null @@ -1,337 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using ApiCheck.Description; -using Microsoft.Extensions.CommandLineUtils; -using Newtonsoft.Json; - -namespace ApiCheck -{ - public class Program - { - private const int Ok = 0; - private const int Error = 1; - - public static int Main(string[] args) - { - try - { - var app = new CommandLineApplication - { - Name = "ApiCheck" - }; - - app.Command("generate", c => - { - var assemblyPathOption = c.Option("-a|--assembly", - "Path to the assembly to generate the ApiListing for", CommandOptionType.SingleValue); - var assetsJson = c.Option("-p|--project", "Path to the project.assets.json file", - CommandOptionType.SingleValue); - var framework = c.Option("-f|--framework", - "The moniker for the framework the assembly to analize was compiled against.", - CommandOptionType.SingleValue); - var noPublicInternal = c.Option("-epi|--exclude-public-internal", - "Exclude types on the .Internal namespace from the generated report", - CommandOptionType.NoValue); - var outputPath = c.Option("-o|--out", "Output path for the generated ApiListing file", - CommandOptionType.SingleValue); - - c.HelpOption("-h|--help"); - - c.OnExecute(() => OnGenerate(c, assemblyPathOption, assetsJson, framework, noPublicInternal, - outputPath)); - }); - - app.Command("compare", c => - { - var apiListingPathOption = c.Option("-b|--api-listing", - "Path to the API listing file to use as reference.", CommandOptionType.SingleValue); - var exclusionsPathOption = c.Option("-e|--exclusions", - "Path to the exclusions file for the ApiListing", CommandOptionType.SingleValue); - var assemblyPathOption = c.Option("-a|--assembly", - "Path to the assembly to generate the ApiListing for", CommandOptionType.SingleValue); - var assetsJson = c.Option("-p|--project", "Path to the project.assets.json file", - CommandOptionType.SingleValue); - var framework = c.Option("-f|--framework", - "The moniker for the framework the assembly to analize was compiled against.", - CommandOptionType.SingleValue); - var noPublicInternal = c.Option("-epi|--exclude-public-internal", - "Exclude types on the .Internal namespace from the generated report", - CommandOptionType.NoValue); - - c.HelpOption("-h|--help"); - - c.OnExecute(() => OnCompare(c, apiListingPathOption, exclusionsPathOption, assemblyPathOption, - assetsJson, framework, noPublicInternal)); - }); - - app.HelpOption("-h|--help"); - - app.OnExecute(() => - { - app.ShowHelp(); - return Ok; - }); - - return app.Execute(args); - } - catch (FileNotFoundException e) - { - Console.WriteLine(e.ToString()); - } - catch (ReflectionTypeLoadException e) - { - // ReflectionTypeLoadException does not override ToString() to include LoaderExceptions. - Console.WriteLine($"{e.GetType().FullName}: {e.Message}"); - - var hadLoaderExceptions = false; - foreach (var loaderException in e.LoaderExceptions) - { - hadLoaderExceptions = true; - Console.WriteLine($" {loaderException.GetType().FullName}: {loaderException.Message}"); - - var innerException = loaderException.InnerException; - while (innerException != null) - { - Console.WriteLine($" {innerException.GetType().FullName}: {innerException.Message}"); - innerException = innerException.InnerException; - } - - if (loaderException.InnerException != null) - { - Console.WriteLine(" --- End of inner exceptions ---"); - } - } - - if (hadLoaderExceptions) - { - Console.WriteLine(" --- End of loader exceptions ---"); - } - - var inner = e.InnerException; - while (inner != null) - { - Console.WriteLine($" {inner.GetType().FullName}: {inner.Message}"); - inner = inner.InnerException; - } - - if (e.InnerException != null) - { - Console.WriteLine(" --- End of inner exceptions ---"); - } - - Console.WriteLine(e.StackTrace); - } - - return Error; - } - - private static int OnGenerate( - CommandLineApplication command, - CommandOption assemblyPath, - CommandOption assetsJson, - CommandOption framework, - CommandOption excludeInternalNamespace, - CommandOption output) - { - if (!assemblyPath.HasValue() || - !output.HasValue() || - !assetsJson.HasValue() || - !framework.HasValue()) - { - Console.Error.WriteLine("Missing required option."); - command.ShowHelp(); - return Error; - } - - var assembly = AssemblyLoader.LoadAssembly( - assemblyPath.Value(), - assetsJson.Value(), - framework.Value()); - - var filters = new List>(); - if (excludeInternalNamespace.HasValue()) - { - filters.Add(ApiListingFilters.IsInInternalNamespace); - } - - var report = ApiListingGenerator.GenerateApiListingReport(assembly, filters); - using (var writer = new JsonTextWriter(File.CreateText(output.Value()))) - { - writer.Formatting = Formatting.Indented; - writer.Indentation = 2; - writer.IndentChar = ' '; - - report.WriteTo(writer); - } - - return Ok; - } - - private static int OnCompare( - CommandLineApplication command, - CommandOption apiListingPathOption, - CommandOption breakingChangesPathOption, - CommandOption assemblyPath, - CommandOption assetsJson, - CommandOption framework, - CommandOption excludeInternalNamespace) - { - if (!apiListingPathOption.HasValue() || - !assemblyPath.HasValue() || - !assetsJson.HasValue() || - !framework.HasValue()) - { - command.ShowHelp(); - return Error; - } - - var assembly = AssemblyLoader.LoadAssembly( - assemblyPath.Value(), - assetsJson.Value(), - framework.Value()); - - var newApiListingFilters = new List>(); - var oldApiListingFilters = new List>(); - - if (excludeInternalNamespace.HasValue()) - { - newApiListingFilters.Add(ApiListingFilters.IsInInternalNamespace); - oldApiListingFilters.Add(ApiListingFilters.IsInInternalNamespace); - } - - var oldApiListing = ApiListingGenerator.LoadFrom(File.ReadAllText(apiListingPathOption.Value()), - oldApiListingFilters); - - var generator = new ApiListingGenerator(assembly, newApiListingFilters); - var newApiListing = generator.GenerateApiListing(); - var knownBreakingChanges = (breakingChangesPathOption.HasValue() - ? JsonConvert.DeserializeObject>( - File.ReadAllText(breakingChangesPathOption.Value())) - : null) ?? new List(); - - var comparer = new ApiListingComparer(oldApiListing, newApiListing); - - var breakingChanges = comparer.GetDifferences(); - var newBreakingChanges = breakingChanges.Except(knownBreakingChanges).ToList(); - var incorrectBreakingChanges = knownBreakingChanges.Except(breakingChanges).ToList(); - - const string indent = " "; - - var breakingChangesToPrint = new List(); - - if (newBreakingChanges.Count > 0) - { - Console.WriteLine( - $"ERROR: Verifying breaking changes for framework {framework.Value()} failed."); - } - - var removedTypes = newBreakingChanges.Where(b => b.MemberId == null).OrderBy(b => b.TypeId).ToList(); - if (removedTypes.Count > 0) - { - Console.WriteLine(); - Console.WriteLine("The following types have been removed."); - Console.WriteLine(); - Console.WriteLine(string.Join(Environment.NewLine, removedTypes.Select(b => indent + b.TypeId))); - Console.WriteLine(); - } - - breakingChangesToPrint.AddRange(removedTypes); - - var removedMembers = newBreakingChanges - .Where(b => b.MemberId != null && b.Kind == ChangeKind.Removal) - .OrderBy(b => b.MemberId) - .GroupBy(b => b.TypeId) - .ToList(); - if (removedMembers.Count > 0) - { - Console.WriteLine(); - Console.WriteLine(); - Console.WriteLine("The following types have one or more members removed from them."); - Console.WriteLine(); - - foreach (var memberGrouping in removedMembers) - { - Console.WriteLine(indent + memberGrouping.Key); - Console.WriteLine(string.Join(Environment.NewLine, - memberGrouping.Select(b => indent + indent + b.MemberId).ToList())); - Console.WriteLine(); - } - } - - breakingChangesToPrint.AddRange(removedMembers.SelectMany(t => t.ToList())); - - var newMembersOnInterfaces = newBreakingChanges - .Where(b => b.MemberId != null && b.Kind == ChangeKind.Addition) - .OrderBy(b => b.MemberId) - .GroupBy(b => b.TypeId) - .ToList(); - if (newMembersOnInterfaces.Count > 0) - { - Console.WriteLine(); - Console.WriteLine(); - Console.WriteLine("The following interfaces have one or more members added to them."); - - foreach (var memberGrouping in newMembersOnInterfaces) - { - Console.WriteLine(indent + memberGrouping.Key); - Console.WriteLine(string.Join(Environment.NewLine, - memberGrouping.Select(b => indent + indent + b.MemberId).ToList())); - Console.WriteLine(); - } - } - - breakingChangesToPrint.AddRange(newMembersOnInterfaces.SelectMany(t => t.ToList())); - - foreach (var exclusion in incorrectBreakingChanges) - { - if (breakingChangesPathOption.HasValue()) - { - Console.Error.WriteLine( - $"ERROR: The following exclusion is in the exclusion file '{breakingChangesPathOption.Value()}', but is no longer necessary:"); - } - else - { - Console.Error.WriteLine( - "ERROR: The following exclusion is in the exclusion file, but is no longer necessary:"); - } - Console.WriteLine(JsonConvert.SerializeObject(exclusion, Formatting.Indented)); - Console.WriteLine(); - } - - if (breakingChangesToPrint.Any()) - { - Console.WriteLine(); - Console.WriteLine(); - Console.WriteLine("Following is the list of exclusions that either need to be added to the list of breaking changes, or the breaking changes themselves need to be reverted:"); - Console.WriteLine( - JsonConvert.SerializeObject( - breakingChangesToPrint, - Formatting.Indented, - new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - })); - Console.WriteLine(); - } - - if (newBreakingChanges.Count > 0 || incorrectBreakingChanges.Count > 0) - { - Console.WriteLine( - "The process for breaking changes is described in: https://github.com/aspnet/AspNetCore/wiki/Engineering-guidelines#breaking-changes"); - Console.WriteLine( - "The process to add an exclusion to this tool is described in: https://github.com/aspnet/BuildTools/wiki/Api-Check#apicheck-exceptions"); - Console.WriteLine(); - - return Error; - } - - return Ok; - } - } -} diff --git a/src/ApiCheck.Console/README.md b/src/ApiCheck.Console/README.md deleted file mode 100644 index 6e9559e61..000000000 --- a/src/ApiCheck.Console/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Api Check -=========== -The documentation for this project can be found [here](https://github.com/aspnet/BuildTools/wiki/Api-Check). \ No newline at end of file diff --git a/src/ApiCheck.Console/build/Microsoft.AspNetCore.BuildTools.ApiCheck.props b/src/ApiCheck.Console/build/Microsoft.AspNetCore.BuildTools.ApiCheck.props deleted file mode 100644 index 705b19be6..000000000 --- a/src/ApiCheck.Console/build/Microsoft.AspNetCore.BuildTools.ApiCheck.props +++ /dev/null @@ -1,16 +0,0 @@ - - - - <_ApiCheckTaskAssembly>$(MSBuildThisFileDirectory)..\tools\netstandard2.0\Microsoft.AspNetCore.BuildTools.ApiCheck.Task.dll - - - - - diff --git a/src/ApiCheck.Task/ApiCheckGenerateTask.cs b/src/ApiCheck.Task/ApiCheckGenerateTask.cs deleted file mode 100644 index 38eebd79b..000000000 --- a/src/ApiCheck.Task/ApiCheckGenerateTask.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - - -using System; -using System.IO; -using Microsoft.Build.Framework; -using System.Reflection; - -namespace Microsoft.AspNetCore.BuildTools.ApiCheck.Task -{ - /// - /// An MSBuild task that acts as a shim to Microsoft.AspNetCore.BuildTools.ApiCheck.exe generate ... or - /// dotnet Microsoft.AspNetCore.BuildTools.ApiCheck.dll generate .... - /// - public class ApiCheckGenerateTask : ApiCheckTasksBase - { - protected override bool ValidateParameters() - { - if (string.IsNullOrEmpty(ApiListingPath)) - { - Log.LogError($"API listing file '{ApiListingPath}' not specified."); - return false; - } - - return base.ValidateParameters(); - } - - protected override string GenerateCommandLineCommands() - { - return GenerateCommandLineCommands("generate"); - } - } -} diff --git a/src/ApiCheck.Task/ApiCheckTask.cs b/src/ApiCheck.Task/ApiCheckTask.cs deleted file mode 100644 index db72c97f2..000000000 --- a/src/ApiCheck.Task/ApiCheckTask.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Reflection; -using Microsoft.Build.Framework; - -namespace Microsoft.AspNetCore.BuildTools.ApiCheck.Task -{ - /// - /// An MSBuild task that acts as a shim to Microsoft.AspNetCore.BuildTools.ApiCheck.exe compare ... or - /// dotnet Microsoft.AspNetCore.BuildTools.ApiCheck.dll compare .... - /// - public class ApiCheckTask : ApiCheckTasksBase - { - /// - /// Path to the exclusions file that narrows , ignoring listed breaking changes. - /// - public string ExclusionsPath { get; set; } - - /// - protected override bool ValidateParameters() - { - if (string.IsNullOrEmpty(ApiListingPath) || !File.Exists(ApiListingPath)) - { - Log.LogError($"API listing file '{ApiListingPath}' not specified or does not exist."); - return false; - } - - if (!string.IsNullOrEmpty(ExclusionsPath) && !File.Exists(ExclusionsPath)) - { - Log.LogError($"Exclusions file '{ExclusionsPath}' does not exist."); - return false; - } - - return base.ValidateParameters(); - } - - /// - protected override string GenerateCommandLineCommands() - { - var arguments = GenerateCommandLineCommands("compare"); - - if (!string.IsNullOrEmpty(ExclusionsPath)) - { - arguments += $@" --exclusions ""{ExclusionsPath}"""; - } - - return arguments; - } - } -} diff --git a/src/ApiCheck.Task/ApiCheckTasksBase.cs b/src/ApiCheck.Task/ApiCheckTasksBase.cs deleted file mode 100644 index a80e95e87..000000000 --- a/src/ApiCheck.Task/ApiCheckTasksBase.cs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Microsoft.Extensions.CommandLineUtils; - -namespace Microsoft.AspNetCore.BuildTools.ApiCheck.Task -{ - public abstract class ApiCheckTasksBase : ToolTask - { - protected const string ApiCheckToolName = "ApiCheck"; - - public ApiCheckTasksBase() - { - // Tool does not use stderr for anything. Treat everything that appears there as an error. - LogStandardErrorAsError = true; - } - - /// - /// Path to the project.assets.json file created when building . - /// - [Required] - public string ProjectAssetsPath { get; set; } - - /// - /// Path for the API listing file. - /// - [Required] - public string ApiListingPath { get; set; } - - /// - /// Path to the assembly to consider. - /// - [Required] - public string AssemblyPath { get; set; } - - /// - /// Exclude types defined in .Internal namespaces from the comparison, ignoring breaking changes in such types. - /// - public bool ExcludePublicInternalTypes { get; set; } - - /// - /// The framework moniker for . - /// - [Required] - public string Framework { get; set; } - - /// - protected override MessageImportance StandardErrorLoggingImportance => MessageImportance.High; - - /// - protected override MessageImportance StandardOutputLoggingImportance => MessageImportance.High; - - /// - protected override string ToolName - { - get - { - if (Framework.StartsWith("net4", StringComparison.OrdinalIgnoreCase)) - { - return ApiCheckToolName + ".exe"; - } - - var exeExtension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty; - return "dotnet" + exeExtension; - } - } - - protected override bool ValidateParameters() - { - if (string.IsNullOrEmpty(AssemblyPath) || !File.Exists(AssemblyPath)) - { - Log.LogError($"Assembly '{AssemblyPath}' not specified or does not exist."); - return false; - } - - if (string.IsNullOrEmpty(Framework)) - { - Log.LogError("Framework moniker must be specified."); - return false; - } - - if (string.IsNullOrEmpty(ProjectAssetsPath) || !File.Exists(ProjectAssetsPath)) - { - Log.LogError($"Project assets file '{ProjectAssetsPath}' not specified or does not exist."); - return false; - } - - return base.ValidateParameters(); - } - - /// - protected override string GenerateFullPathToTool() - { - // ToolExe equals ToolName by default. Assume (as base class does) any user override is in the same directory. - if (Framework.StartsWith("net4", StringComparison.OrdinalIgnoreCase)) - { - var taskAssemblyFolder = Path.GetDirectoryName(GetType().GetTypeInfo().Assembly.Location); - return Path.GetFullPath(Path.Combine(taskAssemblyFolder, "..", "net46", ToolExe)); - } - - // If muxer does not find dotnet, fall back to system PATH and hope for the best. - return DotNetMuxer.MuxerPath ?? ToolExe; - } - - /// - protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) - { - // Since tool prints out formatted list of breaking changes, - // anything that starts with Error considered an error; the rest is user information. - if (singleLine.StartsWith("Error", StringComparison.OrdinalIgnoreCase)) - { - Log.LogError(singleLine, Array.Empty()); - } - else - { - base.LogEventsFromTextOutput(singleLine, messageImportance); - } - } - - protected string GenerateCommandLineCommands(string command) - { - var arguments = string.Empty; - if (!Framework.StartsWith("net4", StringComparison.OrdinalIgnoreCase)) - { - var taskAssemblyFolder = Path.GetDirectoryName(GetType().GetTypeInfo().Assembly.Location); - var toolPath = Path.Combine(taskAssemblyFolder, "..", "netcoreapp2.1", ApiCheckToolName + ".dll"); - arguments = $@"""{Path.GetFullPath(toolPath)}"" "; - } - - arguments += command; - - if (ExcludePublicInternalTypes) - { - arguments += " --exclude-public-internal"; - } - - arguments += $@" --assembly ""{AssemblyPath}"" --framework {Framework}"; - arguments += $@" --project ""{ProjectAssetsPath}"""; - if (command == "compare") - { - arguments += $@" --api-listing ""{ApiListingPath}"""; - } - - if (command == "generate") - { - arguments += $@" --out {ApiListingPath}"; - } - - return arguments; - } - } -} diff --git a/modules/BuildTools.Tasks/Utilities/FileHelpers.cs b/src/Internal.AspNetCore.BuildTasks/FileHelpers.cs similarity index 74% rename from modules/BuildTools.Tasks/Utilities/FileHelpers.cs rename to src/Internal.AspNetCore.BuildTasks/FileHelpers.cs index fba111114..a61f8c1fc 100644 --- a/modules/BuildTools.Tasks/Utilities/FileHelpers.cs +++ b/src/Internal.AspNetCore.BuildTasks/FileHelpers.cs @@ -1,6 +1,7 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.IO; namespace Microsoft.AspNetCore.BuildTools.Utilities @@ -15,5 +16,10 @@ public static string EnsureTrailingSlash(string path) public static bool HasTrailingSlash(string path) => !string.IsNullOrEmpty(path) && (path[path.Length - 1] == Path.DirectorySeparatorChar || path[path.Length - 1] == Path.AltDirectorySeparatorChar); + + public static string NormalizePath(string path) + => string.IsNullOrEmpty(path) + ? path + : path.Replace('\\', '/'); } } diff --git a/modules/BuildTools.Tasks/GenerateFileFromTemplate.cs b/src/Internal.AspNetCore.BuildTasks/GenerateFileFromTemplate.cs similarity index 95% rename from modules/BuildTools.Tasks/GenerateFileFromTemplate.cs rename to src/Internal.AspNetCore.BuildTasks/GenerateFileFromTemplate.cs index 63f061391..059aa1426 100644 --- a/modules/BuildTools.Tasks/GenerateFileFromTemplate.cs +++ b/src/Internal.AspNetCore.BuildTasks/GenerateFileFromTemplate.cs @@ -27,13 +27,7 @@ namespace Microsoft.AspNetCore.BuildTools /// /// /// -#if SDK - public class Sdk_GenerateFileFromTemplate : Task -#elif BuildTools public class GenerateFileFromTemplate : Task -#else -#error This must be built either for an SDK or for BuildTools -#endif { /// /// The template file. @@ -76,7 +70,7 @@ public override bool Execute() return true; } - internal string Replace(string template, IDictionary values) + public string Replace(string template, IDictionary values) { var sb = new StringBuilder(); var varNameSb = new StringBuilder(); diff --git a/src/ApiCheck.Task/ApiCheck.Task.csproj b/src/Internal.AspNetCore.BuildTasks/Internal.AspNetCore.BuildTasks.csproj similarity index 50% rename from src/ApiCheck.Task/ApiCheck.Task.csproj rename to src/Internal.AspNetCore.BuildTasks/Internal.AspNetCore.BuildTasks.csproj index d05c4b8a6..4279ac44c 100644 --- a/src/ApiCheck.Task/ApiCheck.Task.csproj +++ b/src/Internal.AspNetCore.BuildTasks/Internal.AspNetCore.BuildTasks.csproj @@ -2,17 +2,21 @@ netstandard2.0 - false - Microsoft.AspNetCore.BuildTools.ApiCheck.Task - Microsoft.AspNetCore.BuildTools.ApiCheck.Task + Build tasks. This package is intended for Microsoft use only. + false + false + tools\ + true + true - + + diff --git a/shared/Utilities/MSBuildListSplitter.cs b/src/Internal.AspNetCore.BuildTasks/MSBuildListSplitter.cs similarity index 100% rename from shared/Utilities/MSBuildListSplitter.cs rename to src/Internal.AspNetCore.BuildTasks/MSBuildListSplitter.cs diff --git a/src/Internal.AspNetCore.BuildTasks/build/Internal.AspNetCore.BuildTasks.props b/src/Internal.AspNetCore.BuildTasks/build/Internal.AspNetCore.BuildTasks.props new file mode 100644 index 000000000..9c99f1b5e --- /dev/null +++ b/src/Internal.AspNetCore.BuildTasks/build/Internal.AspNetCore.BuildTasks.props @@ -0,0 +1,9 @@ + + + + <_BuildTasksAssembly>$(MSBuildThisFileDirectory)..\tools\netstandard2.0\Internal.AspNetCore.BuildTasks.dll + + + + + diff --git a/src/Internal.AspNetCore.Sdk/Internal.AspNetCore.Sdk.csproj b/src/Internal.AspNetCore.Sdk/Internal.AspNetCore.Sdk.csproj deleted file mode 100644 index ccbd52d58..000000000 --- a/src/Internal.AspNetCore.Sdk/Internal.AspNetCore.Sdk.csproj +++ /dev/null @@ -1,49 +0,0 @@ - - - - Internal.AspNetCore.Sdk - netcoreapp2.1;net46 - $(DefineConstants);SDK - false - Build targets and extensions to Microsoft.NET.Sdk. This package is intended for Microsoft use only. - Microsoft.AspNetCore.BuildTools - ..\..\modules\BuildTools.Tasks\ - $(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - $(NuspecProperties);id=$(PackageId) - $(NuspecProperties);apicheckVersion=$(ApiCheckPackageVersion) - $(NuspecProperties);config=$(Configuration) - $(NuspecProperties);version=$(PackageVersion) - $(NuspecProperties);description=$(Description) - $(NuspecProperties);copyright=$(Copyright) - - - - diff --git a/src/Internal.AspNetCore.Sdk/Internal.AspNetCore.Sdk.nuspec b/src/Internal.AspNetCore.Sdk/Internal.AspNetCore.Sdk.nuspec deleted file mode 100644 index 159d409ac..000000000 --- a/src/Internal.AspNetCore.Sdk/Internal.AspNetCore.Sdk.nuspec +++ /dev/null @@ -1,22 +0,0 @@ - - - - $id$ - $version$ - Microsoft - false - $description$ - $copyright$ - - - - - - - - - - - - - diff --git a/src/Internal.AspNetCore.Sdk/_._ b/src/Internal.AspNetCore.Sdk/_._ deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/Internal.AspNetCore.Sdk/build/ApiCheck.props b/src/Internal.AspNetCore.Sdk/build/ApiCheck.props deleted file mode 100644 index 8be250a64..000000000 --- a/src/Internal.AspNetCore.Sdk/build/ApiCheck.props +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - <_ApiCheckIsSupported Condition=" '$(OS)' != 'Windows_NT' ">false - - - <_ApiCheckIsSupported Condition=" '$(MSBuildRuntimeType)' != 'Core' ">false - - - true - - true - - - $(GenerateNuspecDependsOn);Generate-ApiCheck-Baselines - $(GenerateNuspecDependsOn);Replace-ApiCheck-Baselines - $(GenerateNuspecDependsOn);ApiCheck - - diff --git a/src/Internal.AspNetCore.Sdk/build/ApiCheck.targets b/src/Internal.AspNetCore.Sdk/build/ApiCheck.targets deleted file mode 100644 index d27f30a1d..000000000 --- a/src/Internal.AspNetCore.Sdk/build/ApiCheck.targets +++ /dev/null @@ -1,64 +0,0 @@ - - - - - <_ApiListingFileSuffix Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ">netframework.json - <_ApiListingFileSuffix Condition=" '$(_ApiListingFileSuffix)' == '' ">netcore.json - <_ApiListingFilePath>$(MSBuildProjectDirectory)\baseline.$(_ApiListingFileSuffix) - <_ApiListingOutputFile>$(OutputPath)\baseline.$(_ApiListingFileSuffix) - <_ApiExclusionsFilePath>$(MSBuildProjectDirectory)\breakingchanges.$(_ApiListingFileSuffix) - - - - - - - - - - <_ApiExclusionsFile Condition=" Exists('$(_ApiExclusionsFilePath)') ">$(_ApiExclusionsFilePath) - - - - - - - - <_ApiListingFile Condition=" Exists('$(_ApiListingFilePath)') ">$(_ApiListingFilePath) - <_ApiExclusionsFile Condition=" Exists('$(_ApiExclusionsFilePath)') ">$(_ApiExclusionsFilePath) - - - - - - - - diff --git a/src/Internal.AspNetCore.Sdk/build/Common.props b/src/Internal.AspNetCore.Sdk/build/Common.props deleted file mode 100644 index fe971de28..000000000 --- a/src/Internal.AspNetCore.Sdk/build/Common.props +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - Microsoft - Microsoft Corporation. - © Microsoft Corporation. All rights reserved. - true - en-US - https://raw.githubusercontent.com/aspnet/AspNetCore/2.0.0/LICENSE.txt - https://go.microsoft.com/fwlink/?LinkID=288859 - https://asp.net - true - true - true - 7.2 - - SHA256 - - true - - - - - Microsoft400 - 3PartySHA2 - Microsoft400 - NuGet - VsixSHA2 - MicrosoftJAR - - - - - - true - - $(WarningsNotAsErrors);xUnit1004 - <_TwoDigitYear>$([MSBuild]::Subtract($([System.DateTime]::UtcNow.Year), 2000)) - <_ThreeDigitDayOfYear>$([System.DateTime]::UtcNow.DayOfYear.ToString().PadLeft(3, '0')) - $(_TwoDigitYear)$(_ThreeDigitDayOfYear) - - - - - <_Parameter1>BuildNumber - <_Parameter2>$(BuildNumber) - - - - - - true - <_BuildTasksPrefix>Sdk_ - <_BuildToolsAssemblyTfm Condition="'$(MSBuildRuntimeType)' == 'Core'">netcoreapp2.1 - <_BuildToolsAssemblyTfm Condition="'$(MSBuildRuntimeType)' != 'Core'">net46 - <_BuildToolsAssembly>$(MSBuildThisFileDirectory)..\tools\$(_BuildToolsAssemblyTfm)\Internal.AspNetCore.Sdk.dll - - - - - diff --git a/src/Internal.AspNetCore.Sdk/build/Common.targets b/src/Internal.AspNetCore.Sdk/build/Common.targets deleted file mode 100644 index afb5caf4c..000000000 --- a/src/Internal.AspNetCore.Sdk/build/Common.targets +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - $(NoWarn);NU5105 - - - - $(GenerateNuspecDependsOn);_EnsureDebugTypeIsPortable - $(TargetsForTfmSpecificBuildOutput);_EnsureDebugTypeIsPortable - - - - - - - - - - - - - - - - - - - - - <_ResxFiles Update="@(_ResxFiles)" Condition="'%(_ResxFiles.GeneratedFileName)' == ''"> - Properties\%(FileName).Designer.cs - - - - - - - - - - - diff --git a/src/Internal.AspNetCore.Sdk/build/DotNetTool.targets b/src/Internal.AspNetCore.Sdk/build/DotNetTool.targets deleted file mode 100644 index d4bbb768c..000000000 --- a/src/Internal.AspNetCore.Sdk/build/DotNetTool.targets +++ /dev/null @@ -1,21 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - $(GetSignedPackageFilesDependsOn);_GetSignedPackageFilesForGeneratedShims - $(OutDir) - - - - - <_ShimRids Include="$(PackAsToolShimRuntimeIdentifiers)" /> - - tools/$(TargetFramework)/any/shims/%(_ShimRids.Identity)/ - - - tools/$(TargetFramework)/any/$(TargetFileName) - - - - - diff --git a/src/Internal.AspNetCore.Sdk/build/GenerateAssemblyInfo.targets b/src/Internal.AspNetCore.Sdk/build/GenerateAssemblyInfo.targets deleted file mode 100644 index e6a37337a..000000000 --- a/src/Internal.AspNetCore.Sdk/build/GenerateAssemblyInfo.targets +++ /dev/null @@ -1,52 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - $(IntermediateOutputPath)Internal.AspNetCore.Sdk.AssemblyInfo$(DefaultLanguageSourceExtension) - true - - - - - - - - - - - - - - - - <_InternalAspNetCoreAttributes Remove="@(_InternalAspNetCoreAttributes)" /> - <_InternalAspNetCoreAttributes Include="System.Reflection.AssemblyMetadata" Condition="'$(Serviceable)'!='false'"> - <_Parameter1>Serviceable - <_Parameter2>True - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Internal.AspNetCore.Sdk/build/Git.targets b/src/Internal.AspNetCore.Sdk/build/Git.targets deleted file mode 100644 index 23ac18ebf..000000000 --- a/src/Internal.AspNetCore.Sdk/build/Git.targets +++ /dev/null @@ -1,131 +0,0 @@ - - - - $(RepositoryCommit) - true - $(IntermediateOutputPath)$(AssemblyName).CommitHash$(DefaultLanguageSourceExtension) - $(IntermediateOutputPath)sourcelink.json - true - - /_/ - - $(DeterministicSourceRoot) - $([MSBuild]::NormalizeDirectory($(RepositoryRoot))) - - $([MSBuild]::NormalizeDirectory($(RepositoryRoot)))=$(DeterministicSourceRoot) - - - - - - - - - - - - - $(APPVEYOR_REPO_COMMIT) - $(TRAVIS_COMMIT) - $(CommitHash) - - - - - - - - - $(RepositoryCommit) - - - - - - - - - - - - - - - - - - - - - - - - - $(IntermediateOutputPath)$(RepositoryCommit.Substring(0, 10)).commit - - - - <_OldCommitFiles Include="$(IntermediateOutputPath)*.commit" Exclude="$(IntermediateCommitHash)" /> - - - - - - - - - - <_CustomAttributes Remove="@(_CustomAttributes)" /> - <_CustomAttributes Include="System.Reflection.AssemblyMetadataAttribute"> - <_Parameter1>CommitHash - <_Parameter2>$(RepositoryCommit) - - - - - - - - - - - - diff --git a/src/Internal.AspNetCore.Sdk/build/Internal.AspNetCore.Sdk.props b/src/Internal.AspNetCore.Sdk/build/Internal.AspNetCore.Sdk.props deleted file mode 100644 index fe0303c43..000000000 --- a/src/Internal.AspNetCore.Sdk/build/Internal.AspNetCore.Sdk.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/Internal.AspNetCore.Sdk/build/Internal.AspNetCore.Sdk.targets b/src/Internal.AspNetCore.Sdk/build/Internal.AspNetCore.Sdk.targets deleted file mode 100644 index ab26b21b2..000000000 --- a/src/Internal.AspNetCore.Sdk/build/Internal.AspNetCore.Sdk.targets +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/Internal.AspNetCore.Sdk/buildMultiTargeting/ApiCheck.targets b/src/Internal.AspNetCore.Sdk/buildMultiTargeting/ApiCheck.targets deleted file mode 100644 index 52ff78833..000000000 --- a/src/Internal.AspNetCore.Sdk/buildMultiTargeting/ApiCheck.targets +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - <_TargetFrameworks Remove="@(_TargetFrameworks)" /> - <_TargetFrameworks Include="$(TargetFrameworks)" /> - - - - - - - - <_TargetFrameworks Remove="@(_TargetFrameworks)" /> - <_TargetFrameworks Include="$(TargetFrameworks)" /> - - - - - - - - <_TargetFrameworks Remove="@(_TargetFrameworks)" /> - <_TargetFrameworks Include="$(TargetFrameworks)" /> - - - - - diff --git a/src/Internal.AspNetCore.Sdk/buildMultiTargeting/Internal.AspNetCore.Sdk.props b/src/Internal.AspNetCore.Sdk/buildMultiTargeting/Internal.AspNetCore.Sdk.props deleted file mode 100644 index 17b7dea67..000000000 --- a/src/Internal.AspNetCore.Sdk/buildMultiTargeting/Internal.AspNetCore.Sdk.props +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - false - - - false - - - - - - diff --git a/src/Internal.AspNetCore.Sdk/buildMultiTargeting/Internal.AspNetCore.Sdk.targets b/src/Internal.AspNetCore.Sdk/buildMultiTargeting/Internal.AspNetCore.Sdk.targets deleted file mode 100644 index 4d8a26ed0..000000000 --- a/src/Internal.AspNetCore.Sdk/buildMultiTargeting/Internal.AspNetCore.Sdk.targets +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - <_TargetFrameworks Remove="@(_TargetFrameworks)" /> - <_TargetFrameworks Include="$(TargetFrameworks)" /> - - - - - - - - - diff --git a/src/Internal.AspNetCore.SiteExtension.Sdk/Internal.AspNetCore.SiteExtension.Sdk.csproj b/src/Internal.AspNetCore.SiteExtension.Sdk/Internal.AspNetCore.SiteExtension.Sdk.csproj deleted file mode 100644 index 03164d8c1..000000000 --- a/src/Internal.AspNetCore.SiteExtension.Sdk/Internal.AspNetCore.SiteExtension.Sdk.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - Internal.AspNetCore.SiteExtension.Sdk - netcoreapp2.1;net46 - false - Build targets and extensions to Microsoft.NET.Sdk. This package is intended for Microsoft use only. - $(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec - false - false - - - - - - - - - - - - - $(NuspecProperties);id=$(PackageId) - $(NuspecProperties);config=$(Configuration) - $(NuspecProperties);version=$(PackageVersion) - $(NuspecProperties);description=$(Description) - $(NuspecProperties);copyright=$(Copyright) - - - - diff --git a/src/Internal.AspNetCore.SiteExtension.Sdk/Internal.AspNetCore.SiteExtension.Sdk.nuspec b/src/Internal.AspNetCore.SiteExtension.Sdk/Internal.AspNetCore.SiteExtension.Sdk.nuspec deleted file mode 100644 index a6552123b..000000000 --- a/src/Internal.AspNetCore.SiteExtension.Sdk/Internal.AspNetCore.SiteExtension.Sdk.nuspec +++ /dev/null @@ -1,18 +0,0 @@ - - - - $id$ - $version$ - Microsoft - false - $description$ - $copyright$ - - - - - - - - - diff --git a/src/Internal.AspNetCore.SiteExtension.Sdk/TrimDeps.cs b/src/Internal.AspNetCore.SiteExtension.Sdk/TrimDeps.cs deleted file mode 100644 index f19f610bd..000000000 --- a/src/Internal.AspNetCore.SiteExtension.Sdk/TrimDeps.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Linq; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace RepoTasks -{ - public class TrimDeps : Task - { - [Required] - public ITaskItem[] DepsFiles { get; set; } - - public override bool Execute() - { - foreach (var depsFile in DepsFiles) - { - ChangeEntryPointLibraryName(depsFile.ItemSpec); - } - - // Parse input - return true; - } - - - private void ChangeEntryPointLibraryName(string depsFile) - { - JToken deps; - using (var file = File.OpenText(depsFile)) - using (JsonTextReader reader = new JsonTextReader(file)) - { - deps = JObject.ReadFrom(reader); - } - - foreach (JProperty target in deps["targets"]) - { - var targetLibrary = target.Value.Children().FirstOrDefault(); - if (targetLibrary == null) - { - continue; - } - - targetLibrary.Remove(); - } - - var library = deps["libraries"].Children().First(); - library.Remove(); - - using (var file = File.CreateText(depsFile)) - using (var writer = new JsonTextWriter(file) { Formatting = Formatting.Indented }) - { - deps.WriteTo(writer); - } - } - } -} diff --git a/src/Internal.AspNetCore.SiteExtension.Sdk/_._ b/src/Internal.AspNetCore.SiteExtension.Sdk/_._ deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/Internal.AspNetCore.SiteExtension.Sdk/build/Internal.AspNetCore.SiteExtension.Sdk.props b/src/Internal.AspNetCore.SiteExtension.Sdk/build/Internal.AspNetCore.SiteExtension.Sdk.props deleted file mode 100644 index d1c6e62fe..000000000 --- a/src/Internal.AspNetCore.SiteExtension.Sdk/build/Internal.AspNetCore.SiteExtension.Sdk.props +++ /dev/null @@ -1,13 +0,0 @@ - - - - netcoreapp2.1 - net46 - $(MSBuildThisFileDirectory)..\tools\$(TaskFolder)\Internal.AspNetCore.SiteExtension.Sdk.dll - - - - diff --git a/src/Internal.AspNetCore.SiteExtension.Sdk/build/Internal.AspNetCore.SiteExtension.Sdk.targets b/src/Internal.AspNetCore.SiteExtension.Sdk/build/Internal.AspNetCore.SiteExtension.Sdk.targets deleted file mode 100644 index 087de5d39..000000000 --- a/src/Internal.AspNetCore.SiteExtension.Sdk/build/Internal.AspNetCore.SiteExtension.Sdk.targets +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - <_TemplatesDirectory>$(MSBuildThisFileDirectory)..\content\ - <_DepsOutputDirectory>$(MSBuildProjectDirectory)\$(BaseIntermediateOutputPath) - <_WorkingDirectory>$(_DepsOutputDirectory)\depswork - <_BasePackagePath>content\additionaldeps\ - <_RuntimeStoreManifestFile>$(_DepsOutputDirectory)\rs.csproj - <_RuntimeStoreOutput>$(_DepsOutputDirectory)\rs\ - - - - - - - - - <_TemplateFiles Include="$(MSBuildThisFileDirectory)..\content\HostingStartup\**\*" /> - <_HostingStartupPackageReference - Include="%(HostingStartupPackageReference.Identity)" - Source="%(HostingStartupPackageReference.Source)" - Version="%(HostingStartupPackageReference.Version)" - WorkingDirectory="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)" - Project="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)\HostingStartup.csproj" - DepsFile="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)\p\HostingStartup.deps.json" - TrimmedDepsFile="$(_DepsOutputDirectory)%(HostingStartupPackageReference.Identity)\%(HostingStartupPackageReference.Identity).deps.json" - PackagePath="$(_BasePackagePath)%(HostingStartupPackageReference.Identity)\shared\Microsoft.AspNetCore.App\$(MicrosoftAspNetCoreAppPackageVersion)\" - /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Internal.AspNetCore.SiteExtension.Sdk/content/HostingStartup/HostingStartup.csproj b/src/Internal.AspNetCore.SiteExtension.Sdk/content/HostingStartup/HostingStartup.csproj deleted file mode 100644 index 3b06dd7e5..000000000 --- a/src/Internal.AspNetCore.SiteExtension.Sdk/content/HostingStartup/HostingStartup.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - netcoreapp2.1 - Exe - - - - - - - diff --git a/src/Internal.AspNetCore.SiteExtension.Sdk/content/HostingStartup/Program.cs b/src/Internal.AspNetCore.SiteExtension.Sdk/content/HostingStartup/Program.cs deleted file mode 100644 index 8cd3c0026..000000000 --- a/src/Internal.AspNetCore.SiteExtension.Sdk/content/HostingStartup/Program.cs +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -public class Program -{ - public static void Main() { } -} \ No newline at end of file diff --git a/test.ps1 b/test.ps1 index 11da65256..ddde0d73a 100755 --- a/test.ps1 +++ b/test.ps1 @@ -7,6 +7,7 @@ param( [string]$RepoPath, [switch]$NoBuild = $false, [switch]$CI = $false, + [switch]$NoReinstall = $false, [Parameter(ValueFromRemainingArguments = $true)] [string[]]$Arguments ) @@ -37,8 +38,7 @@ $Arguments += , "/p:DotNetRestoreSources=$packageDir" foreach ($pkg in @( "Internal.AspNetCore.Sdk", - "Internal.AspNetCore.SiteExtension.Sdk", - "Microsoft.AspNetCore.BuildTools.ApiCheck")) { + "Internal.AspNetCore.SiteExtension.Sdk")) { $pkgRoot = "${env:USERPROFILE}/.nuget/packages/$pkg/$toolsVersion/" if (Test-Path $pkgRoot) { @@ -46,5 +46,6 @@ foreach ($pkg in @( } } +$Reinstall = -not $NoReinstall -& .\scripts\bootstrapper\run.ps1 -Update -Reinstall -Command $Command -Path $RepoPath -ToolsSource $toolsSource -Ci:$CI @Arguments +& .\scripts\bootstrapper\run.ps1 -Update -Reinstall:$Reinstall -Command $Command -Path $RepoPath -ToolsSource $toolsSource -Ci:$CI @Arguments diff --git a/test/ApiCheck.Test/ApiCheck.Test.csproj b/test/ApiCheck.Test/ApiCheck.Test.csproj deleted file mode 100644 index 2dbad76da..000000000 --- a/test/ApiCheck.Test/ApiCheck.Test.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - netcoreapp2.1;net461 - netcoreapp2.1 - - - - - - - - - - - - - - - diff --git a/test/ApiCheck.Test/ApiListingComparerTests.cs b/test/ApiCheck.Test/ApiListingComparerTests.cs deleted file mode 100644 index 663448a9e..000000000 --- a/test/ApiCheck.Test/ApiListingComparerTests.cs +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using ApiCheck.Description; -using ApiCheckApiListing.V2; -using Scenarios; -using Xunit; - -namespace ApiCheck.Test -{ - public class ApiListingComparerTests - { - public Assembly V1Assembly => typeof(ApiCheckApiListingV1).GetTypeInfo().Assembly; - public Assembly V2Assembly => typeof(ApiCheckApiListingV2).GetTypeInfo().Assembly; - - public IEnumerable> TestFilters => new Func [] - { - ti => (ti as TypeInfo)?.Namespace?.StartsWith("ComparisonScenarios") == false - }; - -#if NETCOREAPP2_1 // Reflection does not provide a hook to enumerate forwarded types in .NET Framework. - [Fact] - public void Compare_AllowsTypeToBeForwarded() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - var typeToCheck = "public class ComparisonScenarios.TypeToBeForwarded"; - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - Assert.DoesNotContain(breakingChanges, bc => bc.TypeId == typeToCheck); - } - - [Fact] - public void Compare_DetectsChangesInForwardedType() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - var typeToCheck = "public class ComparisonScenarios.TypeToBeForwardedAndChanged"; - var getterRemoval = new BreakingChange( - typeToCheck, - "public System.String get_PropertyToBeRemoved()", - ChangeKind.Removal); - var setterRemoval = new BreakingChange( - typeToCheck, - "public System.Void set_PropertyToBeRemoved(System.String value)", - ChangeKind.Removal); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - Assert.Equal(2, breakingChanges.Count(bc => bc.TypeId == typeToCheck)); - Assert.Contains(getterRemoval, breakingChanges); - Assert.Contains(setterRemoval, breakingChanges); - } -#endif - - [Fact] - public void Compare_Detects_ChangesInTypeVisibility_as_removal() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var expected = new BreakingChange( - "public class ComparisonScenarios.PublicToInternalClass", - memberId: null, - kind: ChangeKind.Removal); - Assert.Contains(expected, breakingChanges); - } - - [Fact] - public void Compare_Detects_TypeRenames_as_removal() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var expected = new BreakingChange( - "public interface ComparisonScenarios.TypeToRename", - memberId: null, - kind: ChangeKind.Removal); - Assert.Contains(expected, breakingChanges); - } - - [Fact] - public void Compare_Detects_TypeGenericAritybreakingChanges_as_removal() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var expected = new BreakingChange( - "public struct ComparisonScenarios.StructToMakeGeneric", - memberId: null, - kind: ChangeKind.Removal); - Assert.Contains(expected, breakingChanges); - } - - [Theory] - [InlineData("public class ComparisonScenarios.ClassToRemoveFieldsFrom")] - [InlineData("public struct ComparisonScenarios.StructToRemoveFieldsFrom")] - public void Compare_DetectsAllFieldRemovals(string typeToCheck) - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Oops. The NewInternalProperty addition is a breaking change; makes it impossible to subclass type in - // another assembly. - var expected = new List - { - // Changing a const's value doesn't cause a binary incompatibility but often causes problems. - new BreakingChange( - typeToCheck, - "public const System.Int32 ConstToChangeValue = 1", - ChangeKind.Removal), - // Removing a const doesn't cause a binary incompatibilty but often causes problems. - new BreakingChange( - typeToCheck, - "public const System.Int32 ConstToMakeField = 2", - ChangeKind.Removal), - // Oops. Making a field writable is not technically a breaking change. - new BreakingChange( - typeToCheck, - "public readonly System.Int32 FieldToMakeWritable", - ChangeKind.Removal), - new BreakingChange( - typeToCheck, - "public static readonly System.Int32 StaticFieldToMakeConst", - ChangeKind.Removal), - // Oops. Making a field writable is not technically a breaking change. - new BreakingChange( - typeToCheck, - "public static readonly System.Int32 StaticFieldToMakeWritable", - ChangeKind.Removal), - new BreakingChange( - typeToCheck, - "public static System.Int32 StaticFieldToMakeReadonly", - ChangeKind.Removal), - new BreakingChange( - typeToCheck, - "public System.Int32 FieldToMakeReadonly", - ChangeKind.Removal), - new BreakingChange( - typeToCheck, - "public System.Int32 FieldToRemove", - ChangeKind.Removal), - }; - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var breakingChanginesInType = breakingChanges - .Where(change => string.Equals(change.TypeId, typeToCheck, StringComparison.Ordinal)) - .OrderBy(change => change.MemberId); - Assert.Equal(expected, breakingChanginesInType); - } - - [Fact] - public void Compare_Detects_NamespacebreakingChanges_as_removal() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var expected = new BreakingChange( - "public class ComparisonScenarios.ClassToChangeNamespaces", - memberId: null, - kind: ChangeKind.Removal); - Assert.Contains(expected, breakingChanges); - } - - [Fact] - public void Compare_Detects_ClassBeingNested_as_removal() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var expected = new BreakingChange( - "public class ComparisonScenarios.ClassToNest", - memberId: null, - kind: ChangeKind.Removal); - Assert.Contains(expected, breakingChanges); - } - - [Fact] - public void Compare_Detects_ClassBeingUnnested_as_removal() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var expected = new BreakingChange( - "public class ComparisonScenarios.ClassToUnnestContainer+ClassToUnnest", - memberId: null, - kind: ChangeKind.Removal); - Assert.Contains(expected, breakingChanges); - } - - [Fact] - public void Compare_Detects_GenericTypeConstraintsBeingAdded_as_removal() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var expected = new BreakingChange( - "public class ComparisonScenarios.GenericTypeWithConstraintsToBeAdded", - memberId: null, - kind: ChangeKind.Removal); - Assert.Contains(expected, breakingChanges); - } - - [Fact] - public void Compare_Detects_MethodParametersBeingAdded_as_removal() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var expected = new BreakingChange( - "public class ComparisonScenarios.ClassWithMethods", - "public System.Void MethodToAddParameters()", - kind: ChangeKind.Removal); - Assert.Contains(expected, breakingChanges); - } - - [Fact] - public void Compare_DoesNotFailForTypeAddingAnInterface() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - Assert.Null(breakingChanges.FirstOrDefault( - bc => bc.TypeId == "public ComparisonScenarios.TypeWithExtraInterface")); - } - - [Fact] - public void Compare_DetectsAbstractMethodAdditions() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - var typeToCheck = "public abstract class ComparisonScenarios.AbstractClassToAddMethodsTo"; - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var breakingChangesInType = breakingChanges - .Where(change => string.Equals(change.TypeId, typeToCheck, StringComparison.Ordinal)); - var breakingChange = Assert.Single(breakingChangesInType); - Assert.Equal(ChangeKind.Addition, breakingChange.Kind); - Assert.Equal("public abstract System.Void NewAbstractMethod()", breakingChange.MemberId); - } - - [Fact] - public void Compare_DetectsAbstractPropertyAdditions() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - var typeToCheck = "public abstract class ComparisonScenarios.AbstractClassToAddPropertiesTo"; - var expected = new List - { - new BreakingChange( - typeToCheck, - "public abstract System.Int32 get_NewAbstractProperty()", - ChangeKind.Addition), - new BreakingChange( - typeToCheck, - "public abstract System.Void set_PropertyToAddSetterTo(System.Int32 value)", - ChangeKind.Addition), - }; - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var breakingChangesInType = breakingChanges - .Where(change => string.Equals(change.TypeId, typeToCheck, StringComparison.Ordinal)) - .OrderBy(change => change.MemberId); - Assert.Equal(expected, breakingChangesInType); - } - - [Fact] - public void Compare_DetectsNewMembersBeingAddedToAnInterface_as_addition() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var interfaceBreakingChanges = breakingChanges - .Where( b => b.TypeId == "public interface ComparisonScenarios.IInterfaceToAddMembersTo") - .ToList(); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Int32 get_NewMember()" && b.Kind == ChangeKind.Addition); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void set_NewMember(System.Int32 value)" && b.Kind == ChangeKind.Addition); - } - - [Fact] - public void Compare_AllowsExclusionsOnNewInterfaceMembers() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - var knownBreakingChanges = new List - { - new BreakingChange( - "public interface ComparisonScenarios.IInterfaceToAddMembersTo", - "System.Int32 get_NewMember()", - ChangeKind.Addition), - new BreakingChange( - "public interface ComparisonScenarios.IInterfaceToAddMembersTo", - "System.Void set_NewMember(System.Int32 value)", - ChangeKind.Addition) - }; - - // Act - var breakingChanges = comparer.GetDifferences().Except(knownBreakingChanges); - - // Assert - Assert.DoesNotContain( - breakingChanges, - bc => bc.TypeId == "public interface ComparisonScenarios.IInterfaceToAddMembersTo"); - } - - [Fact] - public void Compare_DetectsNewMembersInThePresenceOfRenamedAndRemovedMembers() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var interfaceBreakingChanges = breakingChanges - .Where( b => b.TypeId == "public interface ComparisonScenarios.IInterfaceWithMembersThatWillGetRenamedRemovedAndAdded") - .ToList(); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void MemberToBeRenamed()" && b.Kind == ChangeKind.Removal); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void MemberToBeRemoved()" && b.Kind == ChangeKind.Removal); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void RenamedMember()" && b.Kind == ChangeKind.Addition); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void AddedMember()" && b.Kind == ChangeKind.Addition); - } - - [Fact] - public void Compare_DetectsNewMembersInThePresenceOfTheSameNumberOfRemovedAndAddedMembers() - { - // Arrange - var v1ApiListing = CreateApiListingDocument(V1Assembly); - var v2ApiListing = CreateApiListingDocument(V2Assembly); - var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); - - // Act - var breakingChanges = comparer.GetDifferences(); - - // Assert - var interfaceBreakingChanges = breakingChanges - .Where(b => b.TypeId == "public interface ComparisonScenarios.IInterfaceWithSameNumberOfRemovedAndAddedMembers") - .ToList(); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void FirstMemberToRemove()" && b.Kind == ChangeKind.Removal); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void SecondMemberToRemove()" && b.Kind == ChangeKind.Removal); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void ThirdMemberToRemove()" && b.Kind == ChangeKind.Removal); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void FirstAddedMember()" && b.Kind == ChangeKind.Addition); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void SecondAddedMember()" && b.Kind == ChangeKind.Addition); - Assert.Single(interfaceBreakingChanges, - b => b.MemberId == "System.Void ThirdAddedMember()" && b.Kind == ChangeKind.Addition); - } - - private ApiListing CreateApiListingDocument(Assembly assembly) - { - var generator = new ApiListingGenerator(assembly, TestFilters); - - return generator.GenerateApiListing(); - } - } -} diff --git a/test/ApiCheck.Test/ApiListingGenerationTests.cs b/test/ApiCheck.Test/ApiListingGenerationTests.cs deleted file mode 100644 index c9deeefe6..000000000 --- a/test/ApiCheck.Test/ApiListingGenerationTests.cs +++ /dev/null @@ -1,1258 +0,0 @@ -using System; -using System.Linq; -using System.Reflection; -using ApiCheck.Description; -using ApiCheckApiListing.V2; -using Scenarios; -using Xunit; - -namespace ApiCheck.Test -{ - public class ApiListingGenerationTests - { - public Assembly V1Assembly => typeof(ApiCheckApiListingV1).GetTypeInfo().Assembly; - public Assembly V2Assembly => typeof(ApiCheckApiListingV2).GetTypeInfo().Assembly; - - [Fact] - public void DetectsClasses() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Single(report.Types, t => t.Id == "public class Scenarios.BasicClass"); - } - - [Fact] - public void DetectsStructs() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Single(report.Types, t => t.Id == "public struct Scenarios.BasicStruct"); - } - - [Fact] - public void DetectsDerivedClasses() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Single(report.Types, t => t.Id == "public class Scenarios.DerivedClass : Scenarios.BasicClass"); - } - - [Fact] - public void DetectsBasicInterface() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Single(report.Types, t => t.Id == "public interface Scenarios.IBasicInterface"); - } - - [Fact] - public void DetectsComplexInterface() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Single(report.Types, t => t.Id == "public interface Scenarios.IComplexInterface : Scenarios.IBasicInterface"); - } - - [Fact] - public void DetectsInterfacesThatImplicitlyImplementOtherInterfaces() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Single(report.Types, t => t.Id == "public interface Scenarios.IMultipleLevelInterface : Scenarios.IComplexInterface"); - } - - [Fact] - public void DetectsClassImplementingInterface() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassImplementingInterface : Scenarios.IBasicInterfaceForClass"); - } - - [Fact] - public void DetectsClassDerivingClassImplementingInterface() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassDerivingClassImplementingInterface : Scenarios.ClassImplementingInterface"); - } - - [Fact] - public void ParameterlessVoidReturningMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var method = Assert.Single(type.Members, m => m.Id == "public System.Void ParameterlessVoidReturningMethod()"); - } - - [Fact] - public void DetectsProtectedIntReturningMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var method = Assert.Single(type.Members, m => m.Id == "protected System.Int32 ProtectedIntReturningMethod()"); - } - - [Fact] - public void ProtectedInternalStringReturningMethodWithStringParameter() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - Assert.DoesNotContain(type.Members, m => m.Id == "protected internal System.String ProtectedInternalStringReturningMethodWithStringParameter(System.String stringParameter)"); - } - - [Fact] - public void PublicClassReturningMethodWithOptionalStringParameter() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var method = Assert.Single(type.Members, m => m.Id == "public Scenarios.MethodTypesClass PublicClassReturningMethodWithOptionalStringParameter(System.String defaultParameter = \"hello\")"); - } - - [Fact] - public void PrivateBoolReturningMethodWithOptionalCharParameter() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - Assert.DoesNotContain(type.Members, m => m.Id == "private System.Boolean PrivateBoolReturningMethodWithOptionalCharParameter(System.Char charParameter = 'c')"); - } - - [Fact] - public void PublicDecimalReturningMethodWithAllDefaultParameterTypes() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - var parameters = string.Join(", ", - "Scenarios.MethodTypesClass methodTypes = null", - "System.String nullString = null", - @"System.String nonNullString = ""string""", - "System.Char charDefault = 'c'", - "System.Boolean boolDefault = False", - "System.Byte byteDefault = 3", - "System.SByte sbyteDefault = 5", - "System.Int16 shortDefault = 7", - "System.UInt16 ushortDefault = 9", - "System.Int32 intDefault = 11", - "System.UInt32 uintDefault = 13", - "System.Int64 longDefault = 15", - "System.UInt64 ulongDefault = 17", - "System.Double doubleDefault = 19", - "System.Single floatDefault = 21", - "System.Decimal decimalDefault = 23.0", - "System.Threading.CancellationToken cancellation = default(System.Threading.CancellationToken)"); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var method = Assert.Single(type.Members, m => m.Id == $"public System.Decimal PublicDecimalReturningMethodWithAllDefaultParameterTypes({parameters})"); - } - - [Fact] - public void DetectsVoidReturningMethodWithParamsArgument() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var method = Assert.Single(type.Members, m => m.Id == "public System.Void VoidReturningMethodWithParamsArgument(params System.String[] stringParams)"); - } - - [Fact] - public void DetectsStaticVoidReturningMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var method = Assert.Single(type.Members, m => m.Id == "public static System.Void StaticVoidReturningMethod()"); - } - - [Fact] - public void DetectsPublicNestedClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.NestedTypesClass+PublicNestedClass"); - } - - [Fact] - public void DetectsProtectedNestedClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "protected class Scenarios.NestedTypesClass+ProtectedNestedClass"); - } - - [Fact] - public void DetectsProtectedInternalNestedClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Single(report.Types, t => t.Id == "protected class Scenarios.NestedTypesClass+ProtectedInternalNestedClass"); - } - - [Fact] - public void DetectsInternalNestedClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.DoesNotContain(report.Types, t => t.Id == "internal class Scenarios.NestedTypesClass+InternalNestedClass"); - } - - [Fact] - public void DetectsPrivateNestedClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.DoesNotContain(report.Types, t => t.Id == "private class Scenarios.NestedTypesClass+PrivateNestedClass"); - } - - [Fact] - public void DetectsPublicNestedInterface() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public interface Scenarios.NestedTypesClass+PublicNestedInterface"); - } - - [Fact] - public void DetectsMultipleLevelsNestedClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.NestedTypesClass+IntermediateNestedClass+MultiLevelNestedClass"); - } - - [Fact] - public void DetectsAbstractClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public abstract class Scenarios.HierarchyAbstractClass"); - } - - [Fact] - public void DetectsGenericInterfaceNestedWithinGenericClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public interface Scenarios.GenericsAndNestedTypes+IntermediateNonGenericNestedClass+AnotherNestedGenericClass+ILeafGenericInterface"); - } - - [Fact] - public void DetectsInstantiatedNestedGenericsCorrectly() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public interface Scenarios.GenericsAndNestedTypes+IntermediateNonGenericNestedClass+AnotherNestedGenericClass+ILeafGenericInterface"); - var method = Assert.Single(type.Members, m => m.Id == "Scenarios.GenericsAndNestedTypes+IntermediateNonGenericNestedClass+AnotherNestedGenericClass+ILeafGenericInterface MultipleLevelGenericReturnType(Scenarios.GenericsAndNestedTypes+IntermediateNonGenericNestedClass intermediate, Scenarios.GenericsAndNestedTypes+IntermediateNonGenericNestedClass+AnotherNestedGenericClass another)"); - } - - [Fact] - public void DetectsAbstractVoidMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public abstract class Scenarios.HierarchyAbstractClass"); - var method = Assert.Single(type.Members, m => m.Id == "public abstract System.Void AbstractVoidMethod()"); - } - - [Fact] - public void DetectsVirtualVoidMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public abstract class Scenarios.HierarchyAbstractClass"); - var method = Assert.Single(type.Members, m => m.Id == "public virtual System.Void VirtualVoidMethod()"); - } - - [Fact] - public void DetectsAbstractImplementationMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.HierarchyDerivedClass : Scenarios.HierarchyAbstractClass"); - var method = Assert.Single(type.Members, m => m.Id == "public override System.Void AbstractVoidMethod()"); - } - - [Fact] - public void DetectsVirtualOverrideMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.HierarchyDerivedClass : Scenarios.HierarchyAbstractClass"); - var method = Assert.Single(type.Members, m => m.Id == "public override System.Void VirtualVoidMethod()"); - } - - [Fact] - public void DetectsNewMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.HierarchyDerivedClass : Scenarios.HierarchyAbstractClass"); - var method = Assert.Single(type.Members, m => m.Id == "public new System.Void NonVirtualNonAbstractMethod()"); - } - - [Fact] - public void DetectsSealedClasses() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public sealed class Scenarios.SealedDerivedClass : Scenarios.HierarchyAbstractClass"); - } - - [Fact] - public void DetectsSealedAbstractImplementationMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public sealed class Scenarios.SealedDerivedClass : Scenarios.HierarchyAbstractClass"); - var method = Assert.Single(type.Members, m => m.Id == "public sealed override System.Void AbstractVoidMethod()"); - } - - [Fact] - public void DetectsSealedVirtualOverrideMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public sealed class Scenarios.SealedDerivedClass : Scenarios.HierarchyAbstractClass"); - var method = Assert.Single(type.Members, m => m.Id == "public sealed override System.Void VirtualVoidMethod()"); - } - - [Fact] - public void DetectsStaticClasses() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public static class Scenarios.StaticClass"); - } - - [Fact] - public void DetectsExtensionMethods() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public static class Scenarios.ExtensionMethodsClass"); - var method = Assert.Single(type.Members, m => m.Id == "public static System.String ExtensionMethod(this System.String self)"); - } - - [Fact] - public void DetectsImmediatelyImplementedInterfaces() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.AuthorizeFilter : Scenarios.IFilterFactory"); - } - - [Fact] - public void DoesNotIncludeInterfacesWhenNotExplicitlyReimplemented() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassOverridingVirtualMethodFromBaseClass : Scenarios.IntermediateSubclassNotPartiallyOverridingImplementation"); - } - - [Fact] - public void DoesNotIncludeInterfacesWhenExtendingAnotherMoreSpecificInterfaceAndNotReimplementingAnyMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ConsumesAttribute : System.Attribute, Scenarios.IConsumesActionConstraint"); - } - - [Fact] - public void DetectsExplicitlyImplementedInterfaces() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ExplicitImplementationClass : Scenarios.IInterfaceForExplicitImplementation"); - Assert.DoesNotContain(type.Members, m => m.Id == "System.Void Scenarios.IInterfaceForExplicitImplementation.ExplicitImplementationMethod()"); - } - - [Fact] - public void DetectsReimplementedInterfaceExplicitly() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassDerivingClassReimplementingInterface : Scenarios.OriginalClassImplementingInterface, Scenarios.IBasicInterfaceForInterfaceReimplementation"); - Assert.DoesNotContain(type.Members, m => m.Id == "System.Void Scenarios.IBasicInterfaceForInterfaceReimplementation.A()"); - } - - [Fact] - public void DetectsReimplementedInterfaceImplicitly() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassReimplementingInterfaceFromBaseClassWithExplicitImplementedInterface : Scenarios.ExplicitlyImplementedInterfaceBaseClass, Scenarios.IBasicInterfaceForInterfaceReimplementation"); - var method = Assert.Single(type.Members, m => m.Id == "public System.Void A()"); - } - - [Fact] - public void DetectsGenericTypes() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.GenericType"); - } - - [Fact] - public void DetectsClosedGenericTypes() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClosedGenericType : Scenarios.GenericType"); - } - - [Fact] - public void DetectsMultipleGenericTypes() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public interface Scenarios.IMultipleGenericTypes"); - } - - [Fact] - public void DetectsSemiClosedGenericTypes() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.SemiClosedGenericClass : Scenarios.IMultipleGenericTypes"); - } - - [Fact] - public void DetectsClassNewGenericTypeConstraints() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public interface Scenarios.IGenericInterfaceWithConstraints where T0 : class, new()"); - } - - [Fact] - public void DetectsStructGenericTypeConstraints() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - var type = Assert.Single(report.Types, t => t.Id == "public interface Scenarios.IGenericInterfaceWithStructConstraint where T0 : struct"); - } - - [Fact] - public void DetectsGenericInterfaceWithMultipleInterfaceConstraints() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public interface Scenarios.IGenericWithMultipleTypesAndConstraints where T0 : Scenarios.BaseClassForConstraint where T1 : Scenarios.BaseClassForConstraint, Scenarios.IInterfaceForConstraint, new() where T2 : System.Collections.Generic.IDictionary, new()"); - } - - [Fact] - public void DetectsGenericClassImplementingGenericInterfaceWithMultipleInterfaceConstraints() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassImplementingGenericWithMultipleTypesAndConstraints : Scenarios.IGenericWithMultipleTypesAndConstraints where T0 : Scenarios.BaseClassForConstraint where T1 : Scenarios.BaseClassForConstraint, Scenarios.IInterfaceForConstraint, new() where T2 : System.Collections.Generic.IDictionary, new()"); - } - - [Fact] - public void DetectsGenericMethod() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var method = Assert.Single(type.Members, m => m.Id == "public T0 GenericMethod(T0 typeClassArgument)"); - } - - [Fact] - public void DetectsGenericMethodWithMultipleGenericArguments() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var method = Assert.Single(type.Members, m => m.Id == "public T0 GenericMethodWithMultipleGenericParameters(T0 typeClassArgument)"); - } - - [Fact] - public void DetectsMethodWithGenericArgumentsFromClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.GenericClassForGenericMethods"); - var method = Assert.Single(type.Members, m => m.Id == "public virtual System.Void MethodWithGenericArgumentsFromClass(T0 first, T1 second)"); - } - - [Fact] - public void DetectsMethodWithGenericArgumentsFromPartiallyClosedClass() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.PartiallyClosedClass : Scenarios.GenericClassForGenericMethods"); - var method = Assert.Single(type.Members, m => m.Id == "public override System.Void MethodWithGenericArgumentsFromClass(T0 first, System.String second)"); - } - - [Fact] - public void DetectsMethodWithGenericArgumentsAndConstraints() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.GenericMethodsWithConstraintsClass"); - var method = Assert.Single(type.Members, m => m.Id == "public System.Void GenericMethod(T0 argument) where T0 : class, new()"); - } - - [Fact] - public void DetectsMethodWithGenericArgumentsAndStructConstraint() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.GenericMethodsWithConstraintsClass"); - var method = Assert.Single(type.Members, m => m.Id == "public System.Void GenericMethodWithStructParameter(T0 argument) where T0 : struct"); - } - - [Fact] - public void DetectsMethodWithGenericArgumentsAndTypeAndImplementedInterfacesConstraints() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.GenericMethodsWithConstraintsClass"); - var method = Assert.Single(type.Members, m => m.Id == "public System.Void GenericMethodWithClassAndInterfacesConstraint(T0 argument) where T0 : System.Collections.ObjectModel.Collection, System.Collections.Generic.IDictionary"); - } - - [Fact] - public void DetectsPublicFields() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassWithFields"); - var member = Assert.Single(type.Members, m => m.Id == "public System.Int32 PublicField"); - } - - [Fact] - public void DetectsReadonlyFields() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassWithFields"); - var member = Assert.Single(type.Members, m => m.Id == "public readonly System.Boolean ReadonlyField"); - } - - [Fact] - public void DetectsConstantFields() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassWithFields"); - var member = Assert.Single(type.Members, m => m.Id == "public const System.Char ConstantField = 'c'"); - } - - [Fact] - public void DetectsStaticFields() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassWithFields"); - var member = Assert.Single(type.Members, m => m.Id == "public static System.String StaticField"); - } - - [Fact] - public void DetectsStaticReadonlyFields() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassWithFields"); - var member = Assert.Single(type.Members, m => m.Id == "public static readonly System.String StaticReadonlyField"); - } - - [Fact] - public void DetectsPropertiesAsMethods() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassWithPropertiesAndEvents"); - var getter = Assert.Single(type.Members, m => m.Id == "public System.String get_GetAndSetProperty()"); - var setter = Assert.Single(type.Members, m => m.Id == "public System.Void set_GetAndSetProperty(System.String value)"); - } - - [Fact] - public void DetectsEventsAsMethods() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassWithPropertiesAndEvents"); - var getter = Assert.Single(type.Members, m => m.Id == "public System.Void add_IntEvent(System.Action value)"); - var setter = Assert.Single(type.Members, m => m.Id == "public System.Void remove_IntEvent(System.Action value)"); - } - - [Fact] - public void DetectsEnumerations() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public enum Scenarios.CanonicalEnumeration"); - } - - [Fact] - public void DetectsEnumerationsValues() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public enum Scenarios.CanonicalEnumeration"); - var firstValue = Assert.Single(type.Members, m => m.Id == "FirstValue = 0"); - var secondValue = Assert.Single(type.Members, m => m.Id == "SecondValue = 1"); - } - - [Fact] - public void DetectsEnumerationsWithDifferentSizes() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public enum Scenarios.LongEnumeration : System.Int64"); - var firstValue = Assert.Single(type.Members, m => m.Id == "FirstValue = 0"); - var secondValue = Assert.Single(type.Members, m => m.Id == "ExplicitValue = 5"); - var thirdValue = Assert.Single(type.Members, m => m.Id == "ValueAfterExplicit = 6"); - } - - [Fact] - public void DetectsConstructors() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassWithConstructors"); - var firstValue = Assert.Single(type.Members, m => m.Id == "public .ctor()"); - var secondValue = Assert.Single(type.Members, m => m.Id == "public .ctor(System.Boolean parameter)"); - var thirdValue = Assert.Single(type.Members, m => m.Id == "public .ctor(System.String parameter = \"default\", params System.Int32[] values)"); - } - - [Fact] - public void DetectsExplicitConstructorWithParameters() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.ClassWithoutImplicitParameterlessConstructor"); - var secondValue = Assert.Single(type.Members, m => m.Id == "public .ctor(System.String parameter)"); - } - - [Fact] - public void DetectsMethodParameterDirections() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var secondValue = Assert.Single(type.Members, m => m.Id == "public System.Void MethodWithParametersInDifferentDirections(System.String inParameter, out System.Boolean outParameter, ref System.Int32 refParameter)"); - } - - [Fact] - public void DetectsArrayParameters() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var secondValue = Assert.Single(type.Members, m => m.Id == "public System.Void MethodWithArrayParameter(System.Linq.Expressions.Expression>[] arrayExpression)"); - } - - [Fact] - public void DetectsParametersWithGenericTypesCorrectly() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - - var type = Assert.Single(report.Types, t => t.Id == "public class Scenarios.MethodTypesClass"); - var secondValue = Assert.Single(type.Members, m => m.Id == "public static System.Boolean TryParseList(System.Collections.Generic.IList inputs, out System.Collections.Generic.IList parsedValues)"); - } - - [Fact] - public void FiltersNonPublicOrProtectedElements() - { - // Arrange - var generator = CreateGenerator(V1Assembly); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - foreach (var type in report.Types) - { - var typeVisibility = type.Visibility; - Assert.True(typeVisibility == ApiElementVisibility.Public || - typeVisibility == ApiElementVisibility.Protected); - Assert.NotNull(type.Members); - - foreach (var member in type.Members) - { - var memberVisibility = member.Visibility; - Assert.True(memberVisibility == null || - memberVisibility == ApiElementVisibility.Public || - memberVisibility == ApiElementVisibility.Protected); - } - } - } - - [Fact] - public void FiltersMembersOnTheInternalNamespace() - { - // Arrange - var generator = CreateGenerator(V1Assembly, ApiListingFilters.IsInInternalNamespace); - - // Act - var report = generator.GenerateApiListing(); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.DoesNotContain(report.Types, type => type.Name == "Scenarios.Internal.ExcludedType"); - } - - [Fact] - public void LoadFromFiltersMembersOnTheInternalNamespace() - { - // Arrange - var serialized = @"{ - ""AssemblyIdentity"": ""Test"", - ""Types"": [ - { - ""Name"": ""Scenarios.Internal.ExcludedType"" - } - ] -}"; - - // Act - var report = ApiListingGenerator.LoadFrom(serialized, new Func[] { ApiListingFilters.IsInInternalNamespace }); - - // Assert - Assert.NotNull(report); - Assert.NotNull(report.Types); - Assert.Empty(report.Types); - } - - private ApiListingGenerator CreateGenerator(Assembly assembly, params Func[] filters) - { - filters = filters ?? new Func[] { }; - return new ApiListingGenerator(assembly, filters); - } - } -} diff --git a/test/ApiCheckBaseline.V1/ApiCheckBaseline.V1.csproj b/test/ApiCheckBaseline.V1/ApiCheckBaseline.V1.csproj deleted file mode 100644 index 851737245..000000000 --- a/test/ApiCheckBaseline.V1/ApiCheckBaseline.V1.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - - netstandard1.6;net452;netcoreapp2.1 - false - - - diff --git a/test/ApiCheckBaseline.V1/ComparisonScenarios.cs b/test/ApiCheckBaseline.V1/ComparisonScenarios.cs deleted file mode 100644 index 47c51ca69..000000000 --- a/test/ApiCheckBaseline.V1/ComparisonScenarios.cs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -// V1 -namespace ComparisonScenarios -{ - public class TypeToBeForwarded - { - public string Name { get; set; } - } - - public class TypeToBeForwardedAndChanged - { - public string Name { get; set; } - - public string PropertyToBeRemoved { get; set; } - } - - public class PublicToInternalClass - { - } - - public interface TypeToRename - { - } - - public struct StructToMakeGeneric - { - } - - public struct StructToRemoveFieldsFrom - { - public StructToRemoveFieldsFrom(int fieldToIgnore) - { - FieldToIgnore = 0; - FieldToMakeReadonly = 3; - FieldToRemove = 4; - FieldToMakeWritable = 5; - } - - internal int FieldToIgnore; - - public const int ConstToChangeValue = 1; - - public const int ConstToMakeField = 2; - - public int FieldToMakeReadonly; - - public int FieldToRemove; - - public readonly int FieldToMakeWritable; - - public static int StaticFieldToMakeReadonly = 6; - - public static readonly int StaticFieldToMakeConst = 7; - - public static readonly int StaticFieldToMakeWritable = 8; - } - - public class ClassToRemoveFieldsFrom - { - internal int FieldToIgnore = 0; - - public const int ConstToChangeValue = 1; - - public const int ConstToMakeField = 2; - - public int FieldToMakeReadonly = 3; - - public int FieldToRemove = 4; - - public readonly int FieldToMakeWritable = 5; - - public static int StaticFieldToMakeReadonly = 6; - - public static readonly int StaticFieldToMakeConst = 7; - - public static readonly int StaticFieldToMakeWritable = 8; - } - - public class ClassToChangeNamespaces - { - } - - public class ClassToNestContainer - { - } - - public class ClassToNest - { - } - - public class ClassToUnnestContainer - { - public class ClassToUnnest - { - } - } - - public class GenericTypeWithConstraintsToBeAdded - { - } - - public class ClassWithMethods - { - public void MethodToAddParameters() { } - } - - public class TypeWithExtraInterface - { - } - - public abstract class AbstractClassToAddMethodsTo - { - } - - public abstract class AbstractClassToAddPropertiesTo - { - public abstract int PropertyToAddSetterTo { get; } - } - - public interface IInterfaceToAddMembersTo - { - bool ExistingMember { get; set; } - } - - public interface IInterfaceWithMembersThatWillGetRenamedRemovedAndAdded - { - void MemberToBeRenamed(); - void MemberToBeRemoved(); - } - - public interface IInterfaceWithSameNumberOfRemovedAndAddedMembers - { - void FirstMemberToRemove(); - void SecondMemberToRemove(); - void ThirdMemberToRemove(); - void FirstUnchangedMember(); - void SecondUnchangedMember(); - } -} diff --git a/test/ApiCheckBaseline.V1/Scenarios.cs b/test/ApiCheckBaseline.V1/Scenarios.cs deleted file mode 100644 index 395a2808a..000000000 --- a/test/ApiCheckBaseline.V1/Scenarios.cs +++ /dev/null @@ -1,483 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq.Expressions; -using System.Threading; - -namespace Scenarios -{ - public class ApiCheckApiListingV1 - { - } - public class BasicClass - { - } - - public class DerivedClass : BasicClass - { - } - - public struct BasicStruct - { - } - - public interface IBasicInterface - { - } - - public interface IComplexInterface : IBasicInterface - { - } - - public interface IMultipleLevelInterface : IComplexInterface - { - } - - public interface IBasicInterfaceForClass { } - - public class ClassImplementingInterface : IBasicInterfaceForClass - { - } - - public class ClassDerivingClassImplementingInterface : ClassImplementingInterface - { - } - - public class NestedTypesClass - { - public class PublicNestedClass - { - } - - protected class ProtectedNestedClass - { - } - - protected internal class ProtectedInternalNestedClass - { - } - - internal class InternalNestedClass - { - } - - private class PrivateNestedClass - { - } - - public interface PublicNestedInterface - { - } - - public class IntermediateNestedClass - { - public class MultiLevelNestedClass - { - } - } - } - - public abstract class HierarchyAbstractClass - { - public abstract void AbstractVoidMethod(); - - public virtual void VirtualVoidMethod() - { - } - - public void NonVirtualNonAbstractMethod() - { - } - } - - public class HierarchyDerivedClass : HierarchyAbstractClass - { - public override void AbstractVoidMethod() - { - } - - public override void VirtualVoidMethod() - { - } - - public new void NonVirtualNonAbstractMethod() - { - } - } - - public sealed class SealedDerivedClass : HierarchyAbstractClass - { - public sealed override void AbstractVoidMethod() - { - } - - public sealed override void VirtualVoidMethod() - { - } - } - - public static class StaticClass - { - } - - public static class ExtensionMethodsClass - { - public static string ExtensionMethod(this string self) - { - return null; - } - } - - public interface IInterfaceForExplicitImplementation - { - void ExplicitImplementationMethod(); - } - - public class ExplicitImplementationClass : IInterfaceForExplicitImplementation - { - void IInterfaceForExplicitImplementation.ExplicitImplementationMethod() - { - throw new NotImplementedException(); - } - } - - public interface IBasicInterfaceForInterfaceReimplementation - { - void A(); - } - - public class OriginalClassImplementingInterface : IBasicInterfaceForInterfaceReimplementation - { - public void A() - { - throw new NotImplementedException(); - } - } - - public class ClassDerivingClassReimplementingInterface : OriginalClassImplementingInterface, IBasicInterfaceForInterfaceReimplementation - { - void IBasicInterfaceForInterfaceReimplementation.A() - { - } - } - - public class ExplicitlyImplementedInterfaceBaseClass : IBasicInterfaceForInterfaceReimplementation - { - void IBasicInterfaceForInterfaceReimplementation.A() - { - throw new NotImplementedException(); - } - } - - public class ClassReimplementingInterfaceFromBaseClassWithExplicitImplementedInterface : ExplicitlyImplementedInterfaceBaseClass, IBasicInterfaceForInterfaceReimplementation - { - public void A() - { - } - } - - public class GenericType - { - } - - public class ClosedGenericType : GenericType - { - } - - public interface IMultipleGenericTypes - { - } - - public class SemiClosedGenericClass : IMultipleGenericTypes - { - } - - public interface IGenericInterfaceWithConstraints - where TClassNew : class, new() - { - } - - public interface IGenericInterfaceWithStructConstraint - where TStruct : struct - { - } - - public class BaseClassForConstraint - { - } - - public class DerivedClassForConstraint : BaseClassForConstraint - { - } - - public interface IInterfaceForConstraint - { - } - - public class ImplementedInterfaceForConstraint : BaseClassForConstraint, IInterfaceForConstraint - { - } - - public interface IGenericWithMultipleTypesAndConstraints - where TKey : BaseClassForConstraint - where TValue : BaseClassForConstraint, IInterfaceForConstraint, new() - where TDictionary : IDictionary, new() - { - } - - public class ClassImplementingGenericWithMultipleTypesAndConstraints : - IGenericWithMultipleTypesAndConstraints - where TKey : BaseClassForConstraint - where TValue : BaseClassForConstraint, IInterfaceForConstraint, new() - where TDictionary : IDictionary, new() - { - } - - public class MethodTypesClass - { - public void ParameterlessVoidReturningMethod() - { - } - - protected int ProtectedIntReturningMethod() - { - return 0; - } - - protected internal string ProtectedInternalStringReturningMethodWithStringParameter(string stringParameter) - { - return null; - } - - public MethodTypesClass PublicClassReturningMethodWithOptionalStringParameter(string defaultParameter = "hello") - { - return null; - } - - private bool PrivateBoolReturningMethodWithOptionalCharParameter(char charParameter = 'c') - { - return false; - } - - public decimal PublicDecimalReturningMethodWithAllDefaultParameterTypes( - MethodTypesClass methodTypes = null, - string nullString = null, - string nonNullString = "string", - char charDefault = 'c', - bool boolDefault = false, - byte byteDefault = 3, - sbyte sbyteDefault = 5, - short shortDefault = 7, - ushort ushortDefault = 9, - int intDefault = 11, - uint uintDefault = 13, - long longDefault = 15, - ulong ulongDefault = 17, - double doubleDefault = 19, - float floatDefault = 21.0f, - decimal decimalDefault = 23.0M, - CancellationToken cancellation = default(CancellationToken)) - { - return 1.0M; - } - - public void MethodWithParametersInDifferentDirections(string inParameter, out bool outParameter, ref int refParameter) - { - outParameter = false; - refParameter = 0; - } - - public void VoidReturningMethodWithParamsArgument(params string[] stringParams) - { - } - - public static void StaticVoidReturningMethod() - { - } - - public TClassType GenericMethod(TClassType typeClassArgument) - { - return default(TClassType); - } - - public TClassType GenericMethodWithMultipleGenericParameters(TClassType typeClassArgument) - { - return default(TClassType); - } - - public void MethodWithArrayParameter(Expression>[] arrayExpression) - { - } - - public static bool TryParseList(IList inputs, out IList parsedValues) - { - parsedValues = null; - return false; - } - } - - public class GenericClassForGenericMethods - { - public virtual void MethodWithGenericArgumentsFromClass(TFirst first, TSecond second) - { - } - } - - public class PartiallyClosedClass : GenericClassForGenericMethods - { - public override void MethodWithGenericArgumentsFromClass(TFirst first, string second) - { - } - } - - public class GenericMethodsWithConstraintsClass - { - public void GenericMethod(TClassNew argument) where TClassNew : class, new() - { - } - - public void GenericMethodWithStructParameter(TStruct argument) where TStruct : struct - { - } - - public void GenericMethodWithClassAndInterfacesConstraint(TExtend argument) where TExtend : Collection, IDictionary - { - } - } - - public class ClassWithFields - { - public int PublicField; - public readonly bool ReadonlyField; - public const char ConstantField = 'c'; - public static string StaticField = "Static"; - public static readonly string StaticReadonlyField = "StaticReadonly"; - } - - public class ClassWithPropertiesAndEvents - { - public string GetAndSetProperty { get; set; } - public event Action IntEvent - { - add { } - remove { } - } - } - - public enum CanonicalEnumeration - { - FirstValue, - SecondValue - } - - public enum LongEnumeration : long - { - FirstValue, - ExplicitValue = 5, - ValueAfterExplicit - } - - public class ClassWithConstructors - { - // Parameterless - public ClassWithConstructors() - { - } - - // Different visibility and a parameter - public ClassWithConstructors(bool parameter) - { - } - - public ClassWithConstructors(string parameter = "default", params int[] values) - { - } - } - - public class ClassWithoutImplicitParameterlessConstructor - { - public ClassWithoutImplicitParameterlessConstructor(string parameter) - { - } - } - - public class AuthorizeFilter : IFilterFactory - { - } - - public interface IFilterFactory : IFilterMetadata - { - } - - public interface IFilterMetadata - { - } - - public class ClassOverridingVirtualMethodFromBaseClass : IntermediateSubclassNotPartiallyOverridingImplementation - { - public override bool CanWrite(object value) => false; - } - - public class IntermediateSubclassNotPartiallyOverridingImplementation : BaseClassImplementingInterface - { - public sealed override void Write(bool value) - { - base.Write(value); - } - } - - public class BaseClassImplementingInterface : IBaseInterface - { - public virtual bool CanWrite(object value) => false; - public virtual void Write(bool value) - { - } - } - - public interface IBaseInterface - { - bool CanWrite(object value); - void Write(bool value); - } - - public class ConsumesAttribute : Attribute, IConsumesActionConstraint - { - public bool Accept() => true; - } - - public interface IConsumesActionConstraint : IActionConstraint - { - } - - public interface IActionConstraint : IFilterMetadata - { - bool Accept(); - } - - public class GenericsAndNestedTypes - { - public class IntermediateNonGenericNestedClass - { - public class AnotherNestedGenericClass - { - public interface ILeafGenericInterface - { - void GenericMethod(); - void NonGenericMethod(); - - ILeafGenericInterface MultipleLevelGenericReturnType(IntermediateNonGenericNestedClass intermediate, AnotherNestedGenericClass another); - } - } - } - } -} - -namespace Scenarios.Internal -{ - public class ExcludedType - { - } -} \ No newline at end of file diff --git a/test/ApiCheckBaseline.V2/ApiCheckBaseline.V2.csproj b/test/ApiCheckBaseline.V2/ApiCheckBaseline.V2.csproj deleted file mode 100644 index 4ecc7608d..000000000 --- a/test/ApiCheckBaseline.V2/ApiCheckBaseline.V2.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - netstandard1.6;net452;netcoreapp2.1 - false - - - - - - - diff --git a/test/ApiCheckBaseline.V2/ComparisonScenarios.cs b/test/ApiCheckBaseline.V2/ComparisonScenarios.cs deleted file mode 100644 index 6e8093cd1..000000000 --- a/test/ApiCheckBaseline.V2/ComparisonScenarios.cs +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -// V2 -[assembly: TypeForwardedTo(typeof(ComparisonScenarios.TypeToBeForwarded))] -[assembly: TypeForwardedTo(typeof(ComparisonScenarios.TypeToBeForwardedAndChanged))] - -namespace ComparisonScenarios -{ - internal class PublicToInternalClass - { - } - - public interface TypeToRenameRenamed - { - } - - public struct StructToMakeGeneric - { - } - - public struct StructToRemoveFieldsFrom - { - public StructToRemoveFieldsFrom(int fieldToIgnore) - { - FieldToMakeReadonly = 3; - FieldToMakeWritable = 5; - } - - public const int ConstToChangeValue = 0; - - public static readonly int ConstToMakeField = 2; - - public readonly int FieldToMakeReadonly; - - public int FieldToMakeWritable; - - public static readonly int StaticFieldToMakeReadonly = 6; - - public const int StaticFieldToMakeConst = 7; - - public static int StaticFieldToMakeWritable = 8; - } - - public class ClassToRemoveFieldsFrom - { - public const int ConstToChangeValue = 0; - - public static readonly int ConstToMakeField = 2; - - public readonly int FieldToMakeReadonly = 3; - - public int FieldToMakeWritable = 5; - - public static readonly int StaticFieldToMakeReadonly = 6; - - public const int StaticFieldToMakeConst = 7; - - public static int StaticFieldToMakeWritable = 8; - } - - public class ClassToNestContainer - { - public class ClassToNest - { - } - } - - public class ClassToUnnestContainer - { - } - - public class ClassToUnnest - { - } - - public class GenericTypeWithConstraintsToBeAdded where TToConstrain : IEnumerable, new() - { - } - - public class ClassWithMethods - { - public void MethodToAddParameters(int addedParameter) { } - } - - public class TypeWithExtraInterface : IExtraInterface - { - public int Property { get; set; } - } - - public interface IExtraInterface - { - int Property { get; set; } - } - - public abstract class AbstractClassToAddMethodsTo - { - public abstract void NewAbstractMethod(); - - public virtual void NewVirtualMethod() { } - - public void NewMethod() { } - - internal abstract void NewInternalMethod(); - } - - public abstract class AbstractClassToAddPropertiesTo - { - public abstract int NewAbstractProperty { get; } - - public abstract int PropertyToAddSetterTo { get; set; } - - public int NewProperty => 0; - - public virtual int NewVirtualProperty => 0; - - internal abstract int NewInternalProperty { get; } - } - - public interface IInterfaceToAddMembersTo - { - bool ExistingMember { get; set; } - int NewMember { get; set; } - } - - public interface IInterfaceWithMembersThatWillGetRenamedRemovedAndAdded - { - void RenamedMember(); - void AddedMember(); - } - - public interface IInterfaceWithSameNumberOfRemovedAndAddedMembers - { - void FirstUnchangedMember(); - void SecondUnchangedMember(); - void FirstAddedMember(); - void SecondAddedMember(); - void ThirdAddedMember(); - } -} - -namespace ComparisonScenarios.ChangedNamespace -{ - public class ClassToChangeNamespaces - { - } -} diff --git a/test/ApiCheckBaseline.V2/Scenarios.cs b/test/ApiCheckBaseline.V2/Scenarios.cs deleted file mode 100644 index 1ffc918ad..000000000 --- a/test/ApiCheckBaseline.V2/Scenarios.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace ApiCheckApiListing.V2 -{ - public class ApiCheckApiListingV2 - { - } -} diff --git a/test/ApiCheckForwardDestination/ApiCheckForwardDestination.csproj b/test/ApiCheckForwardDestination/ApiCheckForwardDestination.csproj deleted file mode 100644 index 7b685eeeb..000000000 --- a/test/ApiCheckForwardDestination/ApiCheckForwardDestination.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - - netstandard1.6;net452;netcoreapp2.1 - false - - - diff --git a/test/ApiCheckForwardDestination/ComparisonScenarios.cs b/test/ApiCheckForwardDestination/ComparisonScenarios.cs deleted file mode 100644 index 81f050d9c..000000000 --- a/test/ApiCheckForwardDestination/ComparisonScenarios.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ComparisonScenarios -{ - public class TypeToBeForwarded - { - public string Name { get; set; } - } - - public class TypeToBeForwardedAndChanged - { - public string Name { get; set; } - } -} diff --git a/test/BuildTools.Tasks.Tests/BuildTools.Tasks.Tests.csproj b/test/BuildTasks.Tests/BuildTasks.Tests.csproj similarity index 85% rename from test/BuildTools.Tasks.Tests/BuildTools.Tasks.Tests.csproj rename to test/BuildTasks.Tests/BuildTasks.Tests.csproj index a55fba799..a648451a2 100644 --- a/test/BuildTools.Tasks.Tests/BuildTools.Tasks.Tests.csproj +++ b/test/BuildTasks.Tests/BuildTasks.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp3.1 @@ -20,7 +20,7 @@ - + diff --git a/test/BuildTools.Tasks.Tests/GenerateFileFromTemplateTests.cs b/test/BuildTasks.Tests/GenerateFileFromTemplateTests.cs similarity index 100% rename from test/BuildTools.Tasks.Tests/GenerateFileFromTemplateTests.cs rename to test/BuildTasks.Tests/GenerateFileFromTemplateTests.cs diff --git a/test/BuildTools.Tasks.Tests/CreateSourceLinkTest.cs b/test/BuildTools.Tasks.Tests/CreateSourceLinkTest.cs deleted file mode 100644 index 10854c627..000000000 --- a/test/BuildTools.Tasks.Tests/CreateSourceLinkTest.cs +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using Microsoft.AspNetCore.BuildTools; -using Microsoft.DotNet.PlatformAbstractions; -using Xunit; - -namespace BuildTools.Tasks.Tests -{ - public class CreateSourceLinkTest - { - [Fact] - public void CreatesFile() - { - var destination = "sourcelink.json"; - - var repoName = "aspnet/BuildTools"; - - var originUrl = $"git@github.com:{repoName}.git"; - var commit = "5153bbdfa98dcc27a61d591ce09a0d632875e66f"; - var sourceLinkRoot = GetSourceLinkRoot(); - - var task = new CreateSourceLink - { - OriginUrl = originUrl, - Commit = commit, - DestinationFile = destination, - SourceLinkRoot = sourceLinkRoot - }; - - try - { - Assert.True(task.Execute(), "The task failed but should have passed."); - Assert.True(File.Exists(destination), "SourceLink file doesn't exist."); - - var expectedUrl = $"https://raw.githubusercontent.com/{repoName}/{commit}/*"; - var expected = $"{{\"documents\":{{\"{GetExpectedRootDirectory()}*\":\"{expectedUrl}\"}}}}"; - - var resultText = File.ReadAllText(destination); - - Assert.Equal(expected, resultText); - } - finally - { - File.Delete(destination); - } - } - - [Theory] - [InlineData("/_/")] - [InlineData("C:\\")] - [InlineData("/home/src/")] - public void DoesNotChangeBackslashes(string sourceLinkRoot) - { - var destination = "sourcelink.json"; - - var repoName = "aspnet/BuildTools"; - - var originUrl = $"git@github.com:{repoName}.git"; - var commit = "5153bbdfa98dcc27a61d591ce09a0d632875e66f"; - - var task = new CreateSourceLink - { - OriginUrl = originUrl, - Commit = commit, - DestinationFile = destination, - SourceLinkRoot = sourceLinkRoot - }; - - try - { - Assert.True(task.Execute(), "The task failed but should have passed."); - Assert.True(File.Exists(destination), "SourceLink file doesn't exist."); - var expectedSourceLinkRoot = sourceLinkRoot.Replace(@"\", @"\\"); - var expectedUrl = $"https://raw.githubusercontent.com/{repoName}/{commit}/*"; - var expected = $"{{\"documents\":{{\"{expectedSourceLinkRoot}*\":\"{expectedUrl}\"}}}}"; - - var resultText = File.ReadAllText(destination); - - Assert.Equal(expected, resultText); - } - finally - { - File.Delete(destination); - } - } - - [Fact] - public void HandlesHttps() - { - var destination = "sourcelink.json"; - - var repoName = "aspnet/BuildTools"; - - var originUrl = $"https://github.com/{repoName}.git"; - var commit = "5153bbdfa98dcc27a61d591ce09a0d632875e66f"; - var rootDir = GetSourceLinkRoot(); - - var task = new CreateSourceLink - { - OriginUrl = originUrl, - Commit = commit, - DestinationFile = destination, - SourceLinkRoot = rootDir - }; - - try - { - Assert.True(task.Execute(), "The task failed but should have passed."); - Assert.True(File.Exists(destination), "SourceLink file doesn't exist."); - - var expectedUrl = $"https://raw.githubusercontent.com/{repoName}/{commit}/*"; - var expected = $"{{\"documents\":{{\"{GetExpectedRootDirectory()}*\":\"{expectedUrl}\"}}}}"; - - Assert.Equal(expected, File.ReadAllText(destination)); - } - finally - { - File.Delete(destination); - } - } - - private static string GetExpectedRootDirectory() - { - switch (RuntimeEnvironment.OperatingSystemPlatform) - { - case Platform.Windows: - return "C:\\\\"; - case Platform.Linux: - case Platform.Darwin: - return "/home/"; - default: - throw new NotImplementedException($"SourceLink tests don't yet support {RuntimeEnvironment.OperatingSystemPlatform}."); - } - } - - private static string GetSourceLinkRoot() - { - switch (RuntimeEnvironment.OperatingSystemPlatform) - { - case Platform.Windows: - return @"C:\"; - case Platform.Linux: - case Platform.Darwin: - return "/home/"; - default: - throw new NotImplementedException($"SourceLink tests don't yet support {RuntimeEnvironment.OperatingSystemPlatform}."); - } - } - } -} diff --git a/test/BuildTools.Tasks.Tests/GenerateResxDesignerFilesTest.cs b/test/BuildTools.Tasks.Tests/GenerateResxDesignerFilesTest.cs deleted file mode 100644 index a2abad593..000000000 --- a/test/BuildTools.Tasks.Tests/GenerateResxDesignerFilesTest.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using Microsoft.AspNetCore.BuildTools; -using Microsoft.Build.Utilities; -using Xunit; - -namespace BuildTools.Tasks.Tests -{ - public class GenerateResxDesignerFilesTest - { - [Fact] - public void GeneratesResx() - { - var resx = Path.Combine(AppContext.BaseDirectory, "Resources", "Strings.resx"); - - var item = new TaskItem(resx); - item.SetMetadata("ManifestResourceName", "Microsoft.Extensions.Logging.Abstractions.Resource"); - item.SetMetadata("Type", "Resx"); - - var engine = new MockEngine(); - var task = new GenerateResxDesignerFiles - { - ResourceFiles = new[] { item }, - BuildEngine = engine, - }; - - var expectedFile = Path.Combine(AppContext.BaseDirectory, "Resources", "Strings.Designer.cs.txt"); - var actualFile = Path.Combine(AppContext.BaseDirectory, "Resources", "Strings.Designer.cs"); - if (File.Exists(actualFile)) - { - File.Delete(actualFile); - } - - Assert.True(task.Execute(), "Task failed"); - Assert.Empty(engine.Warnings); - - Assert.Equal(actualFile, Assert.Single(task.FileWrites).ItemSpec); - Assert.True(File.Exists(actualFile), "Actual file does not exist"); - Assert.Equal(File.ReadAllText(expectedFile), File.ReadAllText(actualFile), ignoreLineEndingDifferences: true); - } - } -} diff --git a/test/BuildTools.Tasks.Tests/GetAssemblyFileVersionTest.cs b/test/BuildTools.Tasks.Tests/GetAssemblyFileVersionTest.cs deleted file mode 100644 index c16d8aa0b..000000000 --- a/test/BuildTools.Tasks.Tests/GetAssemblyFileVersionTest.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit; - -namespace Microsoft.AspNetCore.BuildTools -{ - public class GetAssemblyFileVersionTest - { - [Fact] - public void Execute_SetsAssemblyFileVersionToAssemblyVersion_IfRevisionIsSet() - { - // Arrange - var getAssemblyFileVersion = new GetAssemblyFileVersion - { - AssemblyVersion = "1.2.3.4", - AssemblyRevision = 78, - }; - - // Act - var result = getAssemblyFileVersion.Execute(); - - // Assert - Assert.True(result); - Assert.Equal("1.2.3.4", getAssemblyFileVersion.AssemblyFileVersion); - } - - [Theory] - [InlineData("1.2.3")] - [InlineData("1.2.3.0")] - public void Execute_UsesAssemblyRevision_IfRevisionIsNotSet(string assemblyVersion) - { - // Arrange - var getAssemblyFileVersion = new GetAssemblyFileVersion - { - AssemblyVersion = assemblyVersion, - AssemblyRevision = 78, - }; - - // Act - var result = getAssemblyFileVersion.Execute(); - - // Assert - Assert.True(result); - Assert.Equal("1.2.3.78", getAssemblyFileVersion.AssemblyFileVersion); - } - } -} diff --git a/test/BuildTools.Tasks.Tests/GetGitCommitInfoTests.cs b/test/BuildTools.Tasks.Tests/GetGitCommitInfoTests.cs deleted file mode 100644 index a66ce9f20..000000000 --- a/test/BuildTools.Tasks.Tests/GetGitCommitInfoTests.cs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.IO.Compression; -using BuildTools.Tasks.Tests; -using Xunit; - -namespace Microsoft.AspNetCore.BuildTools.Tests -{ - public class GetGitCommitInfoTests : IDisposable - { - private readonly string _tempDir; - - public GetGitCommitInfoTests() - { - _tempDir = Path.Combine(AppContext.BaseDirectory, Path.GetRandomFileName()); - Directory.CreateDirectory(_tempDir); - } - - public void Dispose() - { - Directory.Delete(_tempDir, recursive: true); - } - - private string CreateTestRepro(string name) - { - ZipFile.ExtractToDirectory(Path.Combine(AppContext.BaseDirectory, "Resources", name), _tempDir, overwriteFiles: true); - return Path.Combine(_tempDir, Path.GetFileNameWithoutExtension(name)); - } - - [Fact] - public void ItFindsCommitHashFromSparseCheckout() - { - var engine = new MockEngine(); - var task = new GetGitCommitInfo - { - BuildEngine = engine, - WorkingDirectory = CreateTestRepro("SparseCheckout.zip"), - }; - Assert.True(task.Execute(), "Task should pass"); - - Assert.Equal("7896eb0373dac70940819ef6a6494fdeb4880391", task.CommitHash); - Assert.Equal("dev", task.Branch); - } - - [Fact] - public void ItFindsCommitHash() - { - var engine = new MockEngine(); - var task = new GetGitCommitInfo - { - BuildEngine = engine, - WorkingDirectory = CreateTestRepro("SimpleGitRepo.zip"), - }; - Assert.True(task.Execute(), "Task should pass"); - - Assert.Equal("9c03629e11679f5f3d9dbbd27286239588e0d296", task.CommitHash); - Assert.Equal("master", task.Branch); - } - - [Fact] - public void ItFindsCommitHashInWorktree() - { - var root = CreateTestRepro("WorktreeRepo.zip"); - - var engine = new MockEngine(); - var task = new GetGitCommitInfo - { - BuildEngine = engine, - WorkingDirectory = Path.Combine(root, "SourceRoot"), - }; - - Assert.True(task.Execute(), "Task should pass"); - Assert.Equal("27a9c92f96a117ff926c12beb9d4ea8d0f127e42", task.CommitHash); - Assert.Equal("master", task.Branch); - - engine = new MockEngine(); - task = new GetGitCommitInfo - { - BuildEngine = engine, - WorkingDirectory = Path.Combine(root, "Worktree1"), - }; - - Assert.True(task.Execute(), "Task should pass"); - Assert.Equal("51bd19b3825fbc3e96fbdabc9f2cfa9972999bfa", task.CommitHash); - Assert.Equal("worktree1", task.Branch); - } - - [Fact] - public void ItFindsCommitHashInSubmodule() - { - var root = CreateTestRepro("SubmoduleRepo.zip"); - - var engine = new MockEngine(); - var task = new GetGitCommitInfo - { - BuildEngine = engine, - WorkingDirectory = root, - }; - - Assert.True(task.Execute(), "Task should pass"); - Assert.Equal("91314ecce9e7d3cbd1d3f4d1f35664f52a301479", task.CommitHash); - Assert.Equal("master", task.Branch); - - engine = new MockEngine(); - task = new GetGitCommitInfo - { - BuildEngine = engine, - WorkingDirectory = Path.Combine(root, "modules", "submodule1"), - }; - - Assert.True(task.Execute(), "Task should pass"); - Assert.Equal("599e691c41f502ed9e062b1822ce13b673fc916e", task.CommitHash); - Assert.Equal("dev", task.Branch); - } - } -} diff --git a/test/BuildTools.Tasks.Tests/Resources/SimpleGitRepo.zip b/test/BuildTools.Tasks.Tests/Resources/SimpleGitRepo.zip deleted file mode 100644 index 1168f3e73..000000000 Binary files a/test/BuildTools.Tasks.Tests/Resources/SimpleGitRepo.zip and /dev/null differ diff --git a/test/BuildTools.Tasks.Tests/Resources/SparseCheckout.zip b/test/BuildTools.Tasks.Tests/Resources/SparseCheckout.zip deleted file mode 100644 index 933a12917..000000000 Binary files a/test/BuildTools.Tasks.Tests/Resources/SparseCheckout.zip and /dev/null differ diff --git a/test/BuildTools.Tasks.Tests/Resources/Strings.Designer.cs.txt b/test/BuildTools.Tasks.Tests/Resources/Strings.Designer.cs.txt deleted file mode 100644 index b7e25474d..000000000 --- a/test/BuildTools.Tasks.Tests/Resources/Strings.Designer.cs.txt +++ /dev/null @@ -1,44 +0,0 @@ -// -namespace Microsoft.Extensions.Logging.Abstractions -{ - using System.Globalization; - using System.Reflection; - using System.Resources; - - internal static class Resource - { - private static readonly ResourceManager _resourceManager - = new ResourceManager("Microsoft.Extensions.Logging.Abstractions.Resource", typeof(Resource).GetTypeInfo().Assembly); - - /// - /// The format string '{0}' does not have the expected number of named parameters. Expected {1} parameter(s) but found {2} parameter(s). - /// - internal static string UnexpectedNumberOfNamedParameters - { - get => GetString("UnexpectedNumberOfNamedParameters"); - } - - /// - /// The format string '{0}' does not have the expected number of named parameters. Expected {1} parameter(s) but found {2} parameter(s). - /// - internal static string FormatUnexpectedNumberOfNamedParameters(object p0, object p1, object p2) - => string.Format(CultureInfo.CurrentCulture, GetString("UnexpectedNumberOfNamedParameters"), p0, p1, p2); - - private static string GetString(string name, params string[] formatterNames) - { - var value = _resourceManager.GetString(name); - - System.Diagnostics.Debug.Assert(value != null); - - if (formatterNames != null) - { - for (var i = 0; i < formatterNames.Length; i++) - { - value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); - } - } - - return value; - } - } -} diff --git a/test/BuildTools.Tasks.Tests/Resources/Strings.resx b/test/BuildTools.Tasks.Tests/Resources/Strings.resx deleted file mode 100644 index 5112bed03..000000000 --- a/test/BuildTools.Tasks.Tests/Resources/Strings.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - The format string '{0}' does not have the expected number of named parameters. Expected {1} parameter(s) but found {2} parameter(s). - - \ No newline at end of file diff --git a/test/BuildTools.Tasks.Tests/Resources/SubmoduleRepo.zip b/test/BuildTools.Tasks.Tests/Resources/SubmoduleRepo.zip deleted file mode 100644 index 13cdf3cde..000000000 Binary files a/test/BuildTools.Tasks.Tests/Resources/SubmoduleRepo.zip and /dev/null differ diff --git a/test/BuildTools.Tasks.Tests/Resources/WorktreeRepo.zip b/test/BuildTools.Tasks.Tests/Resources/WorktreeRepo.zip deleted file mode 100644 index 4b1407329..000000000 Binary files a/test/BuildTools.Tasks.Tests/Resources/WorktreeRepo.zip and /dev/null differ diff --git a/test/BuildTools.Tasks.Tests/Resources/sampledata.json b/test/BuildTools.Tasks.Tests/Resources/sampledata.json deleted file mode 100644 index c8f0b8aa7..000000000 --- a/test/BuildTools.Tasks.Tests/Resources/sampledata.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "sdk": { "version": "1.2.3" }, - "runtimes": [ - { - "version": "1.0.0-beta" - }, - { - "version": "1.0.0-alpha" - } - ] -} diff --git a/test/BuildTools.Tasks.Tests/RunTaskTests.cs b/test/BuildTools.Tasks.Tests/RunTaskTests.cs deleted file mode 100644 index 6b4761192..000000000 --- a/test/BuildTools.Tasks.Tests/RunTaskTests.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using Microsoft.AspNetCore.BuildTools; -using Xunit; - -namespace BuildTools.Tasks.Tests -{ - public class RunTaskTests - { - [Fact] - public void ExitCodeIsNonZeroIfFailedToStart() - { - var engine = new MockEngine { ContinueOnError = true }; - var task = new Run - { - FileName = "sdfkjskldfsjdflkajsdas", - BuildEngine = engine, - }; - Assert.False(task.Execute()); - Assert.NotEqual(0, task.ExitCode); - } - } -} diff --git a/test/BuildTools.Tasks.Tests/UnzipArchiveTest.cs b/test/BuildTools.Tasks.Tests/UnzipArchiveTest.cs deleted file mode 100644 index fcbf0c9d9..000000000 --- a/test/BuildTools.Tasks.Tests/UnzipArchiveTest.cs +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using Microsoft.AspNetCore.BuildTools; -using Xunit; - -using ZipArchiveStream = System.IO.Compression.ZipArchive; -using System.IO.Compression; - -namespace BuildTools.Tasks.Tests -{ - public class UnzipArchiveTest : IDisposable - { - private readonly string _tempDir; - - public UnzipArchiveTest() - { - _tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - Directory.CreateDirectory(_tempDir); - } - - [Fact] - public void UnzipsFile() - { - var files = new[] - { - "a.txt", - "dir/b.txt", - }; - - var dest = CreateZip(files); - var outDir = Path.Combine(_tempDir, "out"); - - var task = new UnzipArchive - { - File = dest, - Destination = outDir, - BuildEngine = new MockEngine(), - }; - - Assert.True(task.Execute(), "The task failed but should have passed."); - Assert.True(Directory.Exists(outDir), outDir + " does not exist"); - Assert.Equal(files.Length, task.OutputFiles.Length); - - Assert.All(task.OutputFiles, - f => Assert.True(Path.IsPathRooted(f.ItemSpec), $"Entry {f} should be a fullpath rooted")); - - foreach (var file in files) - { - var outFile = Path.Combine(outDir, file); - Assert.True(File.Exists(outFile), outFile + " does not exist"); - } - } - - [Fact] - public void UnzipsSubdirectories() - { - var files = new[] - { - "a/b/c/d.dll", - "e/f/j/k/l.json", - "e/f/m/n/o.json" - }; - - var dest = CreateZip(files); - var outDir = Path.Combine(_tempDir, "out"); - - var task = new UnzipArchive - { - File = dest, - Destination = outDir, - BuildEngine = new MockEngine(), - }; - - Assert.True(task.Execute(), "The task failed but should have passed."); - Assert.True(Directory.Exists(outDir), outDir + " does not exist"); - Assert.Equal(files.Length, task.OutputFiles.Length); - - Assert.All(task.OutputFiles, - f => Assert.True(Path.IsPathRooted(f.ItemSpec), $"Entry {f} should be a fullpath rooted")); - - foreach (var file in files) - { - var outFile = Path.Combine(outDir, file); - Assert.True(File.Exists(outFile), outFile + " does not exist"); - } - } - - [Fact] - public void Overwrites() - { - var files = new[] - { - "a.txt", - "dir/b.txt" - }; - - var dest = CreateZip(files); - var outDir = Path.Combine(_tempDir, "out"); - - var task = new UnzipArchive - { - File = dest, - Destination = outDir, - BuildEngine = new MockEngine(), - Overwrite = true - }; - - Directory.CreateDirectory(outDir); - - // Create a.txt before trying to unzip - var path = Path.Combine(outDir, "a.txt"); - File.WriteAllText(path, "contents!"); - Assert.True(task.Execute(), "The task failed but should have passed."); - Assert.Empty(File.ReadAllText(path)); - } - - [Fact] - public void DoesNotOverwrite() - { - var files = new[] - { - "a.txt", - "dir/b.txt" - }; - - var dest = CreateZip(files); - var outDir = Path.Combine(_tempDir, "out"); - - var task = new UnzipArchive - { - File = dest, - Destination = outDir, - BuildEngine = new MockEngine(), - Overwrite = false - }; - - Directory.CreateDirectory(outDir); - - // Create a.txt before trying to unzip - var path = Path.Combine(outDir, "a.txt"); - var contents = "contents!"; - File.WriteAllText(path, contents); - - Assert.Throws(() => task.Execute()); - - Assert.Equal(contents, File.ReadAllText(path)); - } - - [Fact] - public void ItNormalizesBacklashesInPath() - { - var files = new[] - { - @"dir\b.txt" - }; - - var dest = CreateZip(files); - var outDir = Path.Combine(_tempDir, "out"); - - var engine = new MockEngine(); - var task = new UnzipArchive - { - File = dest, - Destination = outDir, - BuildEngine = engine, - Overwrite = false - }; - - Assert.True(task.Execute(), "The task failed but should have passed."); - Assert.True(File.Exists(Path.Combine(outDir, "dir", "b.txt")), "File should exist."); - } - - private string CreateZip(string[] files) - { - var dest = Path.Combine(_tempDir, "test.zip"); - - using (var fileStream = new FileStream(dest, FileMode.Create)) - using (var zipStream = new ZipArchiveStream(fileStream, ZipArchiveMode.Create)) - { - foreach (var file in files) - { - zipStream.CreateEntry(file); - } - } - - return dest; - } - - public void Dispose() - { - Directory.Delete(_tempDir, recursive: true); - } - } -} diff --git a/test/BuildTools.Tasks.Tests/ZipArchiveTest.cs b/test/BuildTools.Tasks.Tests/ZipArchiveTest.cs deleted file mode 100644 index c39ad48bd..000000000 --- a/test/BuildTools.Tasks.Tests/ZipArchiveTest.cs +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.AspNetCore.BuildTools; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Xunit; - -using ZipArchiveStream = System.IO.Compression.ZipArchive; - -namespace BuildTools.Tasks.Tests -{ - public class ZipArchiveTest : IDisposable - { - private readonly string _tempDir; - - public ZipArchiveTest() - { - _tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - Directory.CreateDirectory(_tempDir); - } - - [Fact] - public void ZipsLinkItems() - { - var inputFile = Path.Combine(_tempDir, "..", Guid.NewGuid().ToString()); - var dest = Path.Combine(_tempDir, "test.zip"); - var linkItem = new TaskItem(inputFile); - linkItem.SetMetadata("Link", "temp/temp/temp/file.txt"); - try - { - File.WriteAllText(inputFile, ""); - var task = new ZipArchive - { - SourceFiles = new[] { linkItem }, - WorkingDirectory = Path.Combine(_tempDir, "temp"), - File = dest, - BuildEngine = new MockEngine(), - }; - Assert.True(task.Execute()); - - using (var fileStream = new FileStream(dest, FileMode.Open)) - using (var zipStream = new ZipArchiveStream(fileStream)) - { - var entry = Assert.Single(zipStream.Entries); - Assert.Equal("temp/temp/temp/file.txt", entry.FullName); - } - } - finally - { - File.Delete(inputFile); - } - } - - [Fact] - public void CreatesZip() - { - var files = new[] - { - "a.txt", - "dir/b.txt", - @"dir\c.txt", - }; - - var dest = Path.Combine(_tempDir, "test.zip"); - Assert.False(File.Exists(dest)); - - var task = new ZipArchive - { - SourceFiles = CreateItems(files).ToArray(), - WorkingDirectory = _tempDir, - File = dest, - Overwrite = true, - BuildEngine = new MockEngine(), - }; - - Assert.True(task.Execute()); - Assert.True(File.Exists(dest)); - - using (var fileStream = new FileStream(dest, FileMode.Open)) - using (var zipStream = new ZipArchiveStream(fileStream)) - { - Assert.Equal(files.Length, zipStream.Entries.Count); - Assert.Collection(zipStream.Entries, - a => Assert.Equal("a.txt", a.FullName), - b => Assert.Equal("dir/b.txt", b.FullName), - c => Assert.Equal("dir/c.txt", c.FullName)); - } - } - - [Fact] - public void FailsIfFileExists() - { - var files = new[] - { - "test.txt", - }; - - var dest = Path.Combine(_tempDir, "test.zip"); - File.WriteAllText(dest, "Original"); - - var task = new ZipArchive - { - SourceFiles = CreateItems(files).ToArray(), - WorkingDirectory = _tempDir, - File = dest, - Overwrite = false, - BuildEngine = new MockEngine { ContinueOnError = true }, - }; - - Assert.False(task.Execute(), "Task should fail"); - Assert.Equal("Original", File.ReadAllText(dest)); - } - - [Fact] - public void OverwriteReplacesEntireZip() - { - var files1 = new[] - { - "a.txt", - "dir/b.txt", - @"dir\c.txt", - }; - - var files2 = new[] - { - "test.txt", - }; - - var dest = Path.Combine(_tempDir, "test.zip"); - Assert.False(File.Exists(dest)); - - var task = new ZipArchive - { - SourceFiles = CreateItems(files1).ToArray(), - WorkingDirectory = _tempDir, - File = dest, - BuildEngine = new MockEngine(), - }; - - Assert.True(task.Execute()); - Assert.True(File.Exists(dest)); - - task = new ZipArchive - { - SourceFiles = CreateItems(files2).ToArray(), - WorkingDirectory = _tempDir, - File = dest, - Overwrite = true, - BuildEngine = new MockEngine(), - }; - - Assert.True(task.Execute()); - Assert.True(File.Exists(dest)); - - using (var fileStream = File.OpenRead(dest)) - using (var zipStream = new ZipArchiveStream(fileStream)) - { - var entry = Assert.Single(zipStream.Entries); - Assert.Equal("test.txt", entry.FullName); - } - } - - [Fact] - public void FailsForEmptyFileName() - { - var inputFile = Path.Combine(_tempDir, "..", Guid.NewGuid().ToString()); - var dest = Path.Combine(_tempDir, "test.zip"); - var linkItem = new TaskItem(inputFile); - linkItem.SetMetadata("Link", "temp/"); - try - { - File.WriteAllText(inputFile, ""); - var mock = new MockEngine { ContinueOnError = true }; - var task = new ZipArchive - { - SourceFiles = new[] { linkItem }, - WorkingDirectory = Path.Combine(_tempDir, "temp"), - File = dest, - BuildEngine = mock, - }; - - Assert.False(task.Execute(), "Task should fail"); - Assert.NotEmpty(mock.Errors); - - using (var fileStream = new FileStream(dest, FileMode.Open)) - using (var zipStream = new ZipArchiveStream(fileStream)) - { - Assert.Empty(zipStream.Entries); - } - } - finally - { - File.Delete(inputFile); - } - } - - private IEnumerable CreateItems(string[] files) - { - foreach (var file in files) - { - var path = Path.Combine(_tempDir, file); - Directory.CreateDirectory(Path.GetDirectoryName(path)); - File.WriteAllText(path.Replace('\\', '/'), ""); - // intentionally allow item spec to contain \ and / - // this tests that MSBuild normalizes before we create zip entries - yield return new TaskItem(path); - } - } - - public void Dispose() - { - Directory.Delete(_tempDir, recursive: true); - } - } -} diff --git a/test/KoreBuild.FunctionalTests/KoreBuild.FunctionalTests.csproj b/test/KoreBuild.FunctionalTests/KoreBuild.FunctionalTests.csproj index bb1605c06..20c0d32dc 100644 --- a/test/KoreBuild.FunctionalTests/KoreBuild.FunctionalTests.csproj +++ b/test/KoreBuild.FunctionalTests/KoreBuild.FunctionalTests.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp3.1 diff --git a/test/KoreBuild.FunctionalTests/SimpleRepoTests.cs b/test/KoreBuild.FunctionalTests/SimpleRepoTests.cs index e6d4aadd9..4ddc095a1 100644 --- a/test/KoreBuild.FunctionalTests/SimpleRepoTests.cs +++ b/test/KoreBuild.FunctionalTests/SimpleRepoTests.cs @@ -33,7 +33,7 @@ public void FullBuildCompletes() { var app = _fixture.CreateTestApp("SimpleRepo"); - var build = app.ExecuteBuild(_output, "/p:BuildNumber=0001"); + var build = app.ExecuteBuild(_output, "/p:BuildNumber=0001", "/p:DisableCodeSigning=true"); Assert.Equal(0, build); @@ -52,64 +52,6 @@ public void FullBuildCompletes() { Assert.Empty(reader.GetFiles().Where(p => Path.GetExtension(p).Equals(".pdb", StringComparison.OrdinalIgnoreCase))); } - - // /t:TestNuGetPush - Assert.True(File.Exists(Path.Combine(app.WorkingDirectory, "obj", "tmp-nuget", "Simple.CliTool.1.0.0-beta-0001.nupkg")), "Build done a test push of all the packages"); - Assert.True(File.Exists(Path.Combine(app.WorkingDirectory, "obj", "tmp-nuget", "Simple.Lib.1.0.0-beta-0001.nupkg")), "Build done a test push of all the packages"); - Assert.True(File.Exists(Path.Combine(app.WorkingDirectory, "obj", "tmp-nuget", "Simple.Sources.1.0.0-beta-0001.nupkg")), "Build done a test push of all the packages"); - } - - [Fact] - public void BuildOfGlobalCliToolIncludesShims() - { - var app = _fixture.CreateTestApp("RepoWithGlobalTool"); - - var build = app.ExecuteBuild(_output, "/p:BuildNumber=0001"); - - Assert.Equal(0, build); - - var artifactsDir = Path.Combine(app.WorkingDirectory, "artifacts", "build"); - - var pkg = Path.Combine(artifactsDir, "GlobalConsoleTool.1.0.0.nupkg"); - using (var reader = new PackageArchiveReader(pkg)) - { - var files = reader.GetFiles(); - foreach (var file in files) - { - _output.WriteLine("pkg: " + file); - } - - var winx86 = Assert.Single(files, f => f.StartsWith("tools/netcoreapp2.1/any/shims/win-x86/")); - Assert.Equal("GlobalConsoleTool.exe", Path.GetFileName(winx86)); - - var winx64 = Assert.Single(files, f => f.StartsWith("tools/netcoreapp2.1/any/shims/win-x64/")); - Assert.Equal("GlobalConsoleTool.exe", Path.GetFileName(winx64)); - } - - var toolsDir = Path.Combine(app.WorkingDirectory, "artifacts", "tools"); - var installPsi = new ProcessStartInfo - { - FileName = DotNetMuxer.MuxerPathOrDefault(), - Arguments = ArgumentEscaper.EscapeAndConcatenate(new[] - { - "tool", - "install", - "--tool-path", toolsDir, - "GlobalConsoleTool", - "--add-source", artifactsDir - }), - }; - var install = app.Run(_output, installPsi); - Assert.Equal(0, install); - - var ext = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? ".exe" - : string.Empty; - var run = app.Run(_output, new ProcessStartInfo - { - FileName = Path.Combine(toolsDir, "GlobalConsoleTool" + ext), - }); - Assert.Equal(0, run); } [Fact] @@ -121,84 +63,5 @@ public void BuildShouldReturnNonZeroCode() Assert.NotEqual(0, build); } - - [DockerExistsFact(Skip = "winservercore currently fails on AppVeyor due to breaking changes in winservercore 1710")] - public void DockerSuccessful() - { - var app = _fixture.CreateTestApp("SimpleRepo"); - var platform = "jessie"; - - var dockerPlatform = GetDockerPlatform(); - if (dockerPlatform == OSPlatform.Windows) - { - platform = "winservercore"; - } - - var build = app.ExecuteRun(_output, new string[] { "docker-build", "-Path", app.WorkingDirectory }, platform, "/p:BuildNumber=0001"); - - Assert.Equal(0, build); - } - - private static OSPlatform GetDockerPlatform() - { - var startInfo = new ProcessStartInfo("docker", @"version -f ""{{ .Server.Os }}""") - { - RedirectStandardOutput = true, - UseShellExecute = false, - }; - - using (var process = Process.Start(startInfo)) - { - var output = process.StandardOutput.ReadToEnd().Trim(); - - OSPlatform result; - switch (output) - { - case "windows": - result = OSPlatform.Windows; - break; - case "linux": - result = OSPlatform.Linux; - break; - default: - throw new NotImplementedException($"No default for docker platform {output}"); - } - - return result; - } - } - } - - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - public class DockerExistsFactAttribute : FactAttribute - { - public DockerExistsFactAttribute() - { - if (!HasDocker()) - { - Skip = "Docker must be installed to run this test."; - } - } - - private static bool HasDocker() - { - try - { - var startInfo = new ProcessStartInfo("docker", "--version") - { - RedirectStandardOutput = true, - RedirectStandardError = true, - UseShellExecute = false, - }; - using (Process.Start(startInfo)) - { - return true; - } - } - catch (Win32Exception) - { - return false; - } - } } } diff --git a/test/KoreBuild.FunctionalTests/Utilities/RepoTestFixture.cs b/test/KoreBuild.FunctionalTests/Utilities/RepoTestFixture.cs index ea5edaff7..d9d3e5dd1 100644 --- a/test/KoreBuild.FunctionalTests/Utilities/RepoTestFixture.cs +++ b/test/KoreBuild.FunctionalTests/Utilities/RepoTestFixture.cs @@ -16,7 +16,6 @@ public class RepoTestFixture : IDisposable { "Internal.AspNetCore.Sdk", "Internal.AspNetCore.SiteExtension.Sdk", - "Microsoft.AspNetCore.BuildTools.ApiCheck", }; private static readonly string _solutionDir; diff --git a/test/KoreBuild.Tasks.Tests/CheckPackageReferenceTests.cs b/test/KoreBuild.Tasks.Tests/CheckPackageReferenceTests.cs deleted file mode 100644 index 6483b6214..000000000 --- a/test/KoreBuild.Tasks.Tests/CheckPackageReferenceTests.cs +++ /dev/null @@ -1,300 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using BuildTools.Tasks.Tests; -using Microsoft.Build.Utilities; -using Xunit; -using Xunit.Abstractions; - -namespace KoreBuild.Tasks.Tests -{ - [Collection(nameof(MSBuildTestCollection))] - public class CheckPackageReferenceTests : IDisposable - { - private readonly string _tempDir; - private readonly MockEngine _engine; - - public CheckPackageReferenceTests(ITestOutputHelper output, MSBuildTestCollectionFixture fixture) - { - _tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(_tempDir); - _engine = new MockEngine(output); - fixture.InitializeEnvironment(output); - } - - public void Dispose() - { - Directory.Delete(_tempDir, recursive: true); - } - - [Fact] - public void ItAllowsPinnedAndUnpinnedVersions() - { - var depsProps = Path.Combine(_tempDir, "dependencies.props"); - File.WriteAllText(depsProps, $@" - - - 1.0.0 - - - - - - 1.0.0 - - -".Replace('`', '"')); - - var csproj = Path.Combine(_tempDir, "Test.csproj"); - File.WriteAllText(csproj, $@" - - - - - $(BaseLinePackageVersion) - - - -".Replace('`', '"')); - - var task = new CheckPackageReferences - { - BuildEngine = _engine, - DependenciesFile = depsProps, - Projects = new[] { new TaskItem(csproj) } - }; - - Assert.True(task.Execute(), "Task is expected to pass"); - } - - [Fact] - public void PassesWhenAllRequirementsAreSatisifed() - { - var depsProps = Path.Combine(_tempDir, "dependencies.props"); - File.WriteAllText(depsProps, $@" - - - 1.0.0 - - -".Replace('`', '"')); - - var csproj = Path.Combine(_tempDir, "Test.csproj"); - File.WriteAllText(csproj, $@" - - - - - $(AspNetCorePackageVersion) - - - -".Replace('`', '"')); - - var task = new CheckPackageReferences - { - BuildEngine = _engine, - DependenciesFile = depsProps, - Projects = new[] { new TaskItem(csproj) } - }; - - Assert.True(task.Execute(), "Task is expected to pass"); - } - - [Fact] - public void IgnoresUpdateAndRemoveItems() - { - var depsProps = Path.Combine(_tempDir, "dependencies.props"); - File.WriteAllText(depsProps, $@" - - - -".Replace('`', '"')); - - var csproj = Path.Combine(_tempDir, "Test.csproj"); - File.WriteAllText(csproj, $@" - - - - - - -".Replace('`', '"')); - - _engine.ContinueOnError = true; - var task = new CheckPackageReferences - { - BuildEngine = _engine, - DependenciesFile = depsProps, - Projects = new[] { new TaskItem(csproj) } - }; - - Assert.True(task.Execute(), "Task is expected to pass"); - } - - [Fact] - public void FailsWhenDependenciesHasNoPropGroup() - { - var depsFile = Path.Combine(_tempDir, "deps.props"); - File.WriteAllText(depsFile, $@" - - - 1.0.0 - - -".Replace('`', '"')); - - _engine.ContinueOnError = true; - var task = new CheckPackageReferences - { - BuildEngine = _engine, - Projects = new[] { new TaskItem(depsFile) }, - DependenciesFile = depsFile, - }; - - Assert.True(task.Execute(), "Task is expected to pass"); - Assert.NotEmpty(_engine.Warnings); - Assert.Contains(_engine.Warnings, e => e.Code == KoreBuildErrors.Prefix + KoreBuildErrors.PackageRefPropertyGroupNotFound); - } - - [Fact] - public void FailsWhenVariableIsNotInDependenciesPropsFile() - { - var depsProps = Path.Combine(_tempDir, "dependencies.props"); - File.WriteAllText(depsProps, $@" - - - - -".Replace('`', '"')); - - var csproj = Path.Combine(_tempDir, "Test.csproj"); - File.WriteAllText(csproj, $@" - - - - - -".Replace('`', '"')); - - _engine.ContinueOnError = true; - var task = new CheckPackageReferences - { - BuildEngine = _engine, - Projects = new[] { new TaskItem(csproj) }, - DependenciesFile = depsProps, - }; - - Assert.False(task.Execute(), "Task is expected to fail"); - Assert.NotEmpty(_engine.Errors); - Assert.Contains(_engine.Errors, e => e.Code == KoreBuildErrors.Prefix + KoreBuildErrors.VariableNotFoundInDependenciesPropsFile); - } - - [Fact] - public void FailsWhenPackageVersionFloat() - { - var depsProps = Path.Combine(_tempDir, "dependencies.props"); - File.WriteAllText(depsProps, $@" - - - 1.0.0-* - - -".Replace('`', '"')); - - var csproj = Path.Combine(_tempDir, "Test.csproj"); - File.WriteAllText(csproj, $@" - - - - - -".Replace('`', '"')); - - _engine.ContinueOnError = true; - var task = new CheckPackageReferences - { - BuildEngine = _engine, - Projects = new[] { new TaskItem(csproj) }, - DependenciesFile = depsProps, - }; - - Assert.False(task.Execute(), "Task is expected to fail"); - Assert.NotEmpty(_engine.Errors); - Assert.Contains(_engine.Errors, e => e.Code == KoreBuildErrors.Prefix + KoreBuildErrors.PackageRefHasFloatingVersion); - } - - [Fact] - public void FailsWhenPackageVersionIsInvalid() - { - var depsProps = Path.Combine(_tempDir, "dependencies.props"); - File.WriteAllText(depsProps, $@" - - - 1 - - -".Replace('`', '"')); - - var csproj = Path.Combine(_tempDir, "Test.csproj"); - File.WriteAllText(csproj, $@" - - - - - -".Replace('`', '"')); - - _engine.ContinueOnError = true; - var task = new CheckPackageReferences - { - BuildEngine = _engine, - Projects = new[] { new TaskItem(csproj) }, - DependenciesFile = depsProps, - }; - - Assert.False(task.Execute(), "Task is expected to fail"); - Assert.NotEmpty(_engine.Errors); - Assert.Contains(_engine.Errors, e => e.Code == KoreBuildErrors.Prefix + KoreBuildErrors.InvalidPackageVersion); - } - - [Theory] - [InlineData("1.0.0")] - [InlineData("1.0.0-$(Suffix)")] - [InlineData("$(Prefix)-1.0.0-$(Suffix)")] - [InlineData("$(Prefix)-1.0.0")] - public void FailsWhenPackagesReferenceVersionDoesNotCompletelyUseVariables(string version) - { - var depsProps = Path.Combine(_tempDir, "dependencies.props"); - File.WriteAllText(depsProps, $@" - - - -".Replace('`', '"')); - - var csproj = Path.Combine(_tempDir, "Test.csproj"); - File.WriteAllText(csproj, $@" - - - - - -".Replace('`', '"')); - - _engine.ContinueOnError = true; - var task = new CheckPackageReferences - { - BuildEngine = _engine, - Projects = new[] { new TaskItem(csproj) }, - DependenciesFile = depsProps, - }; - - Assert.False(task.Execute(), "Task is expected to fail"); - Assert.NotEmpty(_engine.Errors); - var error = Assert.Single(_engine.Errors, e => e.Code == KoreBuildErrors.Prefix + KoreBuildErrors.PackageRefHasLiteralVersion); - Assert.Equal(4, error.LineNumber); - } - } -} diff --git a/test/KoreBuild.Tasks.Tests/ChecksumTests.cs b/test/KoreBuild.Tasks.Tests/ChecksumTests.cs deleted file mode 100644 index ddef3ff31..000000000 --- a/test/KoreBuild.Tasks.Tests/ChecksumTests.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using BuildTools.Tasks.Tests; -using Microsoft.Build.Utilities; -using Xunit; - -namespace KoreBuild.Tasks.Tests -{ - public class ChecksumTests - { - [Theory] - [InlineData("SHA256", "BCFAF334240356E1B97824A866F643B1ADA3C16AA0B5B2BFA8390D8BB54A244C")] - [InlineData("sha256", "BCFAF334240356E1B97824A866F643B1ADA3C16AA0B5B2BFA8390D8BB54A244C")] - [InlineData("SHA384", "5520B01FDE8A8A7EA38DCADFBF3CFAB2818FA0D5A8A16CB11A2FC7F5C9F1497F7B3C528FDB8CE10AA293A4E5FF32297F")] - [InlineData("SHA512", "7774962C97EAC52B45291E1410F06AC6EFF6AF9ED38A57E2CEB720650282E46CFE512FAAD68AD9C45B74ED1B7E460198E0B00D5C9EF0404FF76B12F8AD2D329F")] - public void ComputesFileChecksum(string algoritm, string hash) - { - var task = new ComputeChecksum - { - File = Path.Combine(AppContext.BaseDirectory, "TestResources", "lorem.bin"), - BuildEngine = new MockEngine(), - Algorithm = algoritm, - }; - Assert.True(task.Execute(), "Task should pass"); - Assert.Equal(hash, task.Hash); - } - - [Theory] - [InlineData("SHA256", "C442A45BB8D0938AFB2B5B0AA61C3ADA1B346F668A42879B1E653042433FAFCB")] - [InlineData("SHA384", "F79223FF5E4A392AA01EC8BDF825C3B7F7941F9C5F7CF2A11BC61A8A5D0AF8182BAFC3FBFDACD83AE7A8A8EDF10B0255")] - [InlineData("SHA512", "F923D2DA8F21B67FF4040FE9C5D00B0E891064E7B1DE47B54C9DA86DAAF215EFC64E282056027BEC2E75A83DE9FA6FFE6CA60F0141E19254B25CAE79C2694777")] - public void VerifyFileChecksum_Fails(string algoritm, string hash) - { - var task = new VerifyChecksum - { - File = Path.Combine(AppContext.BaseDirectory, "TestResources", "lorem.bin"), - BuildEngine = new MockEngine { ContinueOnError = true }, - Algorithm = algoritm, - Hash = hash, - }; - - Assert.False(task.Execute(), "Task should fail"); - } - - [Theory] - [InlineData("SHA256", "BCFAF334240356E1B97824A866F643B1ADA3C16AA0B5B2BFA8390D8BB54A244C")] - [InlineData("sha256", "bcfaf334240356e1b97824a866f643b1ada3c16aa0b5b2bfa8390d8bb54a244c")] - [InlineData("SHA384", "5520B01FDE8A8A7EA38DCADFBF3CFAB2818FA0D5A8A16CB11A2FC7F5C9F1497F7B3C528FDB8CE10AA293A4E5FF32297F")] - [InlineData("SHA512", "7774962C97EAC52B45291E1410F06AC6EFF6AF9ED38A57E2CEB720650282E46CFE512FAAD68AD9C45B74ED1B7E460198E0B00D5C9EF0404FF76B12F8AD2D329F")] - public void VerifyFileChecksum_Pass(string algoritm, string hash) - { - var task = new VerifyChecksum - { - File = Path.Combine(AppContext.BaseDirectory, "TestResources", "lorem.bin"), - BuildEngine = new MockEngine(), - Algorithm = algoritm, - Hash = hash, - }; - - Assert.True(task.Execute(), "Task should pass"); - } - } -} diff --git a/test/KoreBuild.Tasks.Tests/DependencyVersionsFileTests.cs b/test/KoreBuild.Tasks.Tests/DependencyVersionsFileTests.cs deleted file mode 100644 index 8b030706f..000000000 --- a/test/KoreBuild.Tasks.Tests/DependencyVersionsFileTests.cs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections; -using System.IO; -using System.Linq; -using BuildTools.Tasks.Tests; -using KoreBuild.Tasks.Utilities; -using Microsoft.Build.Construction; -using Microsoft.Build.Utilities; -using Xunit; -using Xunit.Abstractions; - -namespace KoreBuild.Tasks.Tests -{ - [Collection(nameof(MSBuildTestCollection))] - public class DependencyVersionsFileTests : IDisposable - { - private readonly string _tempFile; - private readonly ITestOutputHelper _output; - - public DependencyVersionsFileTests(ITestOutputHelper output, MSBuildTestCollectionFixture fixture) - { - _output = output; - fixture.InitializeEnvironment(output); - _tempFile = Path.Combine(AppContext.BaseDirectory, Path.GetRandomFileName()); - } - - public void Dispose() - { - if (File.Exists(_tempFile)) - { - File.Delete(_tempFile); - } - } - - [Fact] - public void ItSortsVariablesAlphabetically() - { - var depsFile = DependencyVersionsFile.Create(addOverrideImport: true); - depsFile.Update("XyzPackageVersion", "123"); - depsFile.Update("AbcPackageVersion", "456"); - depsFile.Save(_tempFile); - - var project = ProjectRootElement.Open(_tempFile); - _output.WriteLine(File.ReadAllText(_tempFile)); - - var versions = Assert.Single(project.PropertyGroups, p => p.Label == DependencyVersionsFile.AutoPackageVersionsLabel); - Assert.Collection(versions.Properties, - v => Assert.Equal("AbcPackageVersion", v.Name), - v => Assert.Equal("XyzPackageVersion", v.Name)); - } - - [Fact] - public void SetIsCaseInsensitive() - { - var depsFile = DependencyVersionsFile.Create(addOverrideImport: true); - depsFile.Update("XunitRunnerVisualStudioVersion", "2.3.0"); - depsFile.Update("XunitRunnerVisualstudioVersion", "2.4.0"); - depsFile.Save(_tempFile); - - var project = ProjectRootElement.Open(_tempFile); - _output.WriteLine(File.ReadAllText(_tempFile)); - - var versions = Assert.Single(project.PropertyGroups, p => p.Label == DependencyVersionsFile.AutoPackageVersionsLabel); - var prop = Assert.Single(versions.Properties); - Assert.Equal("XunitRunnerVisualStudioVersion", prop.Name); - Assert.Equal("2.4.0", prop.Value); - } - - [Theory] - [InlineData("Microsoft.Data.Sqlite", "MicrosoftDataSqlitePackageVersion")] - [InlineData("SQLitePCLRaw.bundle_green", "SQLitePCLRawBundleGreenPackageVersion")] - [InlineData("runtime.win-x64.Microsoft.NETCore", "RuntimeWinX64MicrosoftNETCorePackageVersion")] - public void GeneratesVariableName(string id, string varName) - { - Assert.Equal(varName, DependencyVersionsFile.GetVariableName(id)); - } - - [Fact] - public void AdditionalImportsAreAdded_WithOverrideImportFalse() - { - // Arrange - var path = "obj/test.props"; - var depsFile = DependencyVersionsFile.Create(addOverrideImport: false, additionalImports: new[] { path }); - depsFile.Save(_tempFile); - - // Act - var project = ProjectRootElement.Open(_tempFile); - _output.WriteLine(File.ReadAllText(_tempFile)); - - // Assert - var import = Assert.Single(project.Imports); - Assert.Equal(path, import.Project); - } - - [Fact] - public void AdditionalImportsAreAdded_WithOverrideImportTrue() - { - // Arrange - var path = "obj/external.props"; - var depsFile = DependencyVersionsFile.Create(addOverrideImport: true, additionalImports: new[] { path }); - depsFile.Save(_tempFile); - - // Act - var project = ProjectRootElement.Open(_tempFile); - _output.WriteLine(File.ReadAllText(_tempFile)); - - // Assert - Assert.Collection( - project.Imports, - import => Assert.Equal(path, import.Project), - import => Assert.Equal("$(DotNetPackageVersionPropsPath)", import.Project)); - } - } -} diff --git a/test/KoreBuild.Tasks.Tests/DownloadFileTests.cs b/test/KoreBuild.Tasks.Tests/DownloadFileTests.cs deleted file mode 100644 index ec741500a..000000000 --- a/test/KoreBuild.Tasks.Tests/DownloadFileTests.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using BuildTools.Tasks.Tests; -using Xunit; -using Xunit.Abstractions; -using Task = System.Threading.Tasks.Task; - -namespace KoreBuild.Tasks.Tests -{ - public class DownloadFileTests - { - private readonly ITestOutputHelper _output; - - public DownloadFileTests(ITestOutputHelper output) - { - _output = output; - } - - [Fact] - public async Task ItDownloadAFile() - { - var expectedPath = Path.Combine(AppContext.BaseDirectory, "microsoft.com.2.html"); - var task = new DownloadFile - { - Uri = "http://example.org/index.html", - DestinationPath = expectedPath, - BuildEngine = new MockEngine(_output), - }; - - if (File.Exists(expectedPath)) - { - File.Delete(expectedPath); - } - - Assert.True(await task.ExecuteAsync(), "Task should pass"); - Assert.True(File.Exists(expectedPath), "The file should exist"); - } - - [Fact] - public async Task ItDoesNotRedownloadDownloadAFileThatExists() - { - var expectedPath = Path.Combine(AppContext.BaseDirectory, "microsoft.com.1.html"); - var task = new DownloadFile - { - Uri = "http://example.org/index.html", - DestinationPath = expectedPath, - BuildEngine = new MockEngine(_output), - }; - - const string placeholder = "Dummy content"; - File.WriteAllText(expectedPath, placeholder); - - Assert.True(await task.ExecuteAsync(), "Task should pass"); - - Assert.Equal(placeholder, File.ReadAllText(expectedPath)); - - task.Overwrite = true; - - Assert.True(await task.ExecuteAsync(), "Task should pass"); - Assert.NotEqual(placeholder, File.ReadAllText(expectedPath)); - } - - [Fact] - public async Task ItFailsForFilesThatDoNotExist() - { - var engine = new MockEngine(_output) { ContinueOnError = true }; - var task = new DownloadFile - { - Uri = "http://localhost/this/file/does/not/exist", - DestinationPath = Path.Combine(AppContext.BaseDirectory, "dummy.txt"), - BuildEngine = engine, - }; - - Assert.False(await task.ExecuteAsync(), "Task should fail"); - Assert.NotEmpty(engine.Errors); - } - } -} diff --git a/test/KoreBuild.Tasks.Tests/DownloadNuGetPackagesTests.cs b/test/KoreBuild.Tasks.Tests/DownloadNuGetPackagesTests.cs deleted file mode 100644 index a1a72f3ef..000000000 --- a/test/KoreBuild.Tasks.Tests/DownloadNuGetPackagesTests.cs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections; -using System.IO; -using BuildTools.Tasks.Tests; -using Microsoft.Build.Utilities; -using Xunit; -using Xunit.Abstractions; -using Task = System.Threading.Tasks.Task; - -namespace KoreBuild.Tasks.Tests -{ - public class DownloadNuGetPackagesTest - { - private readonly ITestOutputHelper _output; - - public DownloadNuGetPackagesTest(ITestOutputHelper output) - { - _output = output; - } - - [Fact] - public async Task ItDownloadPackages() - { - var packages = new[] - { - new TaskItem("Newtonsoft.Json", new Hashtable - { - ["Version"] = "9.0.1", - ["Source"] = " https://api.nuget.org/v3/index.json ; ;https://api.nuget.org/v3/index.json; https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json " - }), - }; - - var task = new DownloadNuGetPackages - { - Packages = packages, - DestinationFolder = AppContext.BaseDirectory, - BuildEngine = new MockEngine(_output), - TimeoutSeconds = 120, - }; - var expectedPath = Path.Combine(AppContext.BaseDirectory, "newtonsoft.json.9.0.1.nupkg").Replace('\\', '/'); - if (File.Exists(expectedPath)) - { - File.Delete(expectedPath); - } - - Assert.False(File.Exists(expectedPath), "The file should not exist yet"); - Assert.True(await task.ExecuteAsync(), "Task should pass"); - var file = Assert.Single(task.Files); - Assert.Equal(expectedPath, file.ItemSpec.Replace('\\', '/')); - Assert.True(File.Exists(expectedPath), "The file should exist"); - } - - [Fact] - public async Task ItFailsForPackagesThatDoNotExist() - { - var packages = new[] - { - new TaskItem("SomePackage", new Hashtable { ["Version"] = "1.0.0", ["Source"] = AppContext.BaseDirectory }), - }; - - var engine = new MockEngine(_output) { ContinueOnError = true }; - var task = new DownloadNuGetPackages - { - Packages = packages, - DestinationFolder = AppContext.BaseDirectory, - BuildEngine = engine, - TimeoutSeconds = 120, - }; - - Assert.False(await task.ExecuteAsync(), "Task should fail"); - Assert.NotEmpty(engine.Errors); - Assert.Contains(engine.Errors, m => m.Message.Contains("SomePackage 1.0.0 is not available")); - } - - [Fact] - public async Task ItFindsPackageWhenMultipleFeedsAreSpecified() - { - var packages = new[] - { - new TaskItem("Newtonsoft.Json", new Hashtable { ["Version"] = "9.0.1", ["Source"] = $"{AppContext.BaseDirectory};https://api.nuget.org/v3/index.json"} ), - }; - - var task = new DownloadNuGetPackages - { - Packages = packages, - DestinationFolder = AppContext.BaseDirectory, - BuildEngine = new MockEngine(_output), - TimeoutSeconds = 120, - }; - var expectedPath = Path.Combine(AppContext.BaseDirectory, "newtonsoft.json.9.0.1.nupkg").Replace('\\', '/'); - if (File.Exists(expectedPath)) - { - File.Delete(expectedPath); - } - - Assert.False(File.Exists(expectedPath), "The file should not exist yet"); - Assert.True(await task.ExecuteAsync(), "Task should pass"); - var file = Assert.Single(task.Files); - Assert.Equal(expectedPath, file.ItemSpec.Replace('\\', '/')); - Assert.True(File.Exists(expectedPath), "The file should exist"); - } - } -} diff --git a/test/KoreBuild.Tasks.Tests/GenerateDependenciesPropsFileTests.cs b/test/KoreBuild.Tasks.Tests/GenerateDependenciesPropsFileTests.cs deleted file mode 100644 index 0748aec14..000000000 --- a/test/KoreBuild.Tasks.Tests/GenerateDependenciesPropsFileTests.cs +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections; -using System.IO; -using BuildTools.Tasks.Tests; -using KoreBuild.Tasks.Utilities; -using Microsoft.Build.Construction; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Xunit; -using Xunit.Abstractions; - -namespace KoreBuild.Tasks.Tests -{ - [Collection(nameof(MSBuildTestCollection))] - public class GenerateDependenciesPropsFileTests : IDisposable - { - private readonly ITestOutputHelper _output; - private readonly string _tempDir; - - public GenerateDependenciesPropsFileTests(ITestOutputHelper output, MSBuildTestCollectionFixture fixture) - { - _output = output; - _tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(_tempDir); - fixture.InitializeEnvironment(output); - } - - [Fact] - public void GeneratesVariableName() - { - var generatedFile = Path.Combine(_tempDir, "deps.props"); - var csproj = Path.Combine(_tempDir, "test.csproj"); - CreateProject(csproj, "1.2.3"); - - var task = new GenerateDependenciesPropsFile - { - BuildEngine = new MockEngine(_output), - DependenciesFile = generatedFile, - Projects = new[] { new TaskItem(csproj) }, - Properties = Array.Empty(), - }; - - Assert.True(task.Execute(), "Task is expected to pass"); - var depsFile = ProjectRootElement.Open(generatedFile); - _output.WriteLine(File.ReadAllText(generatedFile)); - var pg = Assert.Single(depsFile.PropertyGroups, p => p.Label == DependencyVersionsFile.AutoPackageVersionsLabel); - var prop = Assert.Single(pg.Properties, p => p.Name == "MyDependencyPackageVersion"); - Assert.Equal("1.2.3", prop.Value); - } - - [Fact] - public void IgnoresImplicitlyDefinedVariables() - { - var generatedFile = Path.Combine(_tempDir, "deps.props"); - var csproj = Path.Combine(_tempDir, "test.csproj"); - File.WriteAllText(csproj, $@" - - - netstandard2.0 - -".Replace('`', '"')); - - var task = new GenerateDependenciesPropsFile - { - BuildEngine = new MockEngine(_output), - DependenciesFile = generatedFile, - Projects = new[] { new TaskItem(csproj) }, - Properties = Array.Empty(), - }; - - Assert.True(task.Execute(), "Task is expected to pass"); - var depsFile = ProjectRootElement.Open(generatedFile); - _output.WriteLine(File.ReadAllText(generatedFile)); - var pg = Assert.Single(depsFile.PropertyGroups, p => p.Label == DependencyVersionsFile.AutoPackageVersionsLabel); - Assert.Empty(pg.Properties); - } - - [Fact] - public void FailsWhenConflictingVersions() - { - var generatedFile = Path.Combine(_tempDir, "deps.props"); - var csproj1 = Path.Combine(_tempDir, "test1.csproj"); - var csproj2 = Path.Combine(_tempDir, "test2.csproj"); - CreateProject(csproj1, "1.2.3"); - CreateProject(csproj2, "4.5.6"); - - var engine = new MockEngine(_output) { ContinueOnError = true }; - var task = new GenerateDependenciesPropsFile - { - BuildEngine = engine, - DependenciesFile = generatedFile, - Projects = new[] { new TaskItem(csproj1), new TaskItem(csproj2) }, - Properties = Array.Empty(), - }; - - Assert.False(task.Execute(), "Task is expected to fail"); - Assert.Single(engine.Errors, e => e.Code == KoreBuildErrors.Prefix + KoreBuildErrors.ConflictingPackageReferenceVersions); - } - - [Fact] - public void DoesNotFailWhenConflictingVersionsAreSuppressed() - { - var generatedFile = Path.Combine(_tempDir, "deps.props"); - var csproj1 = Path.Combine(_tempDir, "test1.csproj"); - var csproj2 = Path.Combine(_tempDir, "test2.csproj"); - CreateProject(csproj1, "1.2.3"); - - File.WriteAllText(csproj2, $@" - - - netstandard2.0 - - - - -".Replace('`', '"')); - - var task = new GenerateDependenciesPropsFile - { - BuildEngine = new MockEngine(_output), - DependenciesFile = generatedFile, - Projects = new[] { new TaskItem(csproj1), new TaskItem(csproj2) }, - Properties = Array.Empty(), - }; - - Assert.True(task.Execute(), "Task is expected to oass"); - } - - private static void CreateProject(string csprojFilePath, string version) - { - File.WriteAllText(csprojFilePath, $@" - - - netstandard2.0 - - - - -".Replace('`', '"')); - } - - - public void Dispose() - { - Directory.Delete(_tempDir, recursive: true); - } - } -} diff --git a/test/KoreBuild.Tasks.Tests/GeneratePackageVersionPropsFileTests.cs b/test/KoreBuild.Tasks.Tests/GeneratePackageVersionPropsFileTests.cs deleted file mode 100644 index 86c731b8c..000000000 --- a/test/KoreBuild.Tasks.Tests/GeneratePackageVersionPropsFileTests.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections; -using System.IO; -using BuildTools.Tasks.Tests; -using KoreBuild.Tasks.Utilities; -using Microsoft.Build.Construction; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Xunit; -using Xunit.Abstractions; - -namespace KoreBuild.Tasks.Tests -{ - [Collection(nameof(MSBuildTestCollection))] - public class GeneratePackageVersionPropsFileTests : IDisposable - { - private readonly ITestOutputHelper _output; - private readonly string _tempFile; - - public GeneratePackageVersionPropsFileTests(ITestOutputHelper output, MSBuildTestCollectionFixture fixture) - { - _output = output; - _tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - fixture.InitializeEnvironment(output); - } - - [Fact] - public void GeneratesFile() - { - var engine = new MockEngine(_output); - var task = new GeneratePackageVersionPropsFile - { - BuildEngine = engine, - Packages = new[] - { - // Order is important. These are intentionally reverse sorted to ensure the generated file sorts properties by prop name - new TaskItem("Newtonsoft.Json", new Hashtable{["Version"] = "10.0.3", ["VariableName"] = "JsonNetVersion"}), - new TaskItem("Microsoft.Azure", new Hashtable{["Version"] = "1.2.0"}), - new TaskItem("Another.Package", new Hashtable{["Version"] = "0.0.1", ["TargetFramework"] = "netstandard1.0"}), - }, - OutputPath = _tempFile, - }; - - Assert.True(task.Execute(), "Task is expected to pass"); - - var project = ProjectRootElement.Open(_tempFile); - _output.WriteLine(File.ReadAllText(_tempFile)); - - Assert.Empty(project.Imports); - Assert.Empty(project.ImportGroups); - - var defaultPropGroup = Assert.Single(project.PropertyGroups, pg => string.IsNullOrEmpty(pg.Label)); - var allProjectsProp = Assert.Single(defaultPropGroup.Properties); - Assert.Equal("MSBuildAllProjects", allProjectsProp.Name); - Assert.Empty(allProjectsProp.Condition); - Assert.Equal("$(MSBuildAllProjects);$(MSBuildThisFileFullPath)", allProjectsProp.Value); - - var versions = Assert.Single(project.PropertyGroups, pg => pg.Label == DependencyVersionsFile.AutoPackageVersionsLabel); - - // Order is important. These should be sorted. - Assert.Collection(versions.Properties, - p => - { - Assert.Equal("AnotherPackagePackageVersion", p.Name); - Assert.Equal("Another.Package", p.Label); - Assert.Equal("0.0.1", p.Value); - Assert.Empty(p.Condition); - }, - p => - { - Assert.Equal("JsonNetVersion", p.Name); - Assert.Equal("Newtonsoft.Json", p.Label); - Assert.Equal("10.0.3", p.Value); - Assert.Empty(p.Condition); - }, - p => - { - Assert.Equal("MicrosoftAzurePackageVersion", p.Name); - Assert.Equal("Microsoft.Azure", p.Label); - Assert.Equal("1.2.0", p.Value); - Assert.Empty(p.Condition); - }); - } - - [Fact] - public void GeneratesImport() - { - var task = new GeneratePackageVersionPropsFile - { - BuildEngine = new MockEngine(_output), - Packages = Array.Empty(), - AddOverrideImport = true, - OutputPath = _tempFile, - }; - - Assert.True(task.Execute(), "Task is expected to pass"); - var project = ProjectRootElement.Open(_tempFile); - _output.WriteLine(File.ReadAllText(_tempFile)); - - var import = Assert.Single(project.Imports); - Assert.Equal("$(DotNetPackageVersionPropsPath)", import.Project); - Assert.Equal(" '$(DotNetPackageVersionPropsPath)' != '' ", import.Condition); - } - - public void Dispose() - { - if (File.Exists(_tempFile)) - { - File.Delete(_tempFile); - } - } - } -} diff --git a/test/KoreBuild.Tasks.Tests/InstallDotNetTests.cs b/test/KoreBuild.Tasks.Tests/InstallDotNetTests.cs index 29f364631..646753257 100644 --- a/test/KoreBuild.Tasks.Tests/InstallDotNetTests.cs +++ b/test/KoreBuild.Tasks.Tests/InstallDotNetTests.cs @@ -30,7 +30,7 @@ public void InstallsDotnetCoreRuntime() Directory.Delete(path, recursive: true); } - var request = new TaskItem("1.0.5", new Hashtable + var request = new TaskItem("2.1.21", new Hashtable { ["Runtime"] = "dotnet", ["InstallDir"] = path @@ -47,7 +47,7 @@ public void InstallsDotnetCoreRuntime() InstallScript = script, }; - var expected = Path.Combine(path, "shared", "Microsoft.NETCore.App", "1.0.5", ".version"); + var expected = Path.Combine(path, "shared", "Microsoft.NETCore.App", "2.1.21", ".version"); Assert.False(File.Exists(expected), "Test folder should have been deleted"); Assert.True(task.Execute(), "Task should pass"); diff --git a/test/KoreBuild.Tasks.Tests/KoreBuild.Tasks.Tests.csproj b/test/KoreBuild.Tasks.Tests/KoreBuild.Tasks.Tests.csproj index 3a8903d13..31400d05e 100644 --- a/test/KoreBuild.Tasks.Tests/KoreBuild.Tasks.Tests.csproj +++ b/test/KoreBuild.Tasks.Tests/KoreBuild.Tasks.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp2.1 + netcoreapp3.1 @@ -27,10 +27,4 @@ - - - PreserveNewest - - - diff --git a/test/KoreBuild.Tasks.Tests/MockTaskItem.cs b/test/KoreBuild.Tasks.Tests/MockTaskItem.cs new file mode 100644 index 000000000..3b750d4be --- /dev/null +++ b/test/KoreBuild.Tasks.Tests/MockTaskItem.cs @@ -0,0 +1,65 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections; +using System.Collections.Generic; +using Microsoft.Build.Framework; + +namespace KoreBuild.Tasks.Tests +{ + internal class MockTaskItem : ITaskItem + { + private Dictionary _metadata = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public MockTaskItem(string itemSpec) + { + ItemSpec = itemSpec; + } + + public string this[string index] + { + get => GetMetadata(index); + set => SetMetadata(index, value); + } + + public string ItemSpec { get; set; } + + public ICollection MetadataNames => _metadata.Keys; + + public int MetadataCount => _metadata.Count; + + public IDictionary CloneCustomMetadata() + { + return new Dictionary(_metadata); + } + + public void CopyMetadataTo(ITaskItem destinationItem) + { + destinationItem.ItemSpec = ItemSpec; + foreach (var item in _metadata) + { + destinationItem.SetMetadata(item.Key, item.Value); + } + } + + public string GetMetadata(string metadataName) + { + _metadata.TryGetValue(metadataName, out var retVal); + return retVal; + } + + public void RemoveMetadata(string metadataName) + { + if (_metadata.ContainsKey(metadataName)) + { + _metadata.Remove(metadataName); + } + } + + public void SetMetadata(string metadataName, string metadataValue) + { + _metadata[metadataName] = metadataValue; + } + } +} diff --git a/test/KoreBuild.Tasks.Tests/PackNuSpecTests.cs b/test/KoreBuild.Tasks.Tests/PackNuSpecTests.cs deleted file mode 100644 index bdadd3e38..000000000 --- a/test/KoreBuild.Tasks.Tests/PackNuSpecTests.cs +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using BuildTools.Tasks.Tests; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using NuGet.Frameworks; -using NuGet.Packaging; -using NuGet.Versioning; -using Xunit; - -namespace KoreBuild.Tasks.Tests -{ - public class PackNuSpecTests : IDisposable - { - private readonly string _tempDir; - - public PackNuSpecTests() - { - _tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - Directory.CreateDirectory(_tempDir); - } - - [Fact] - public void CreatesPackage() - { - var outputPath = Path.Combine(_tempDir, $"TestPackage.1.0.0.nupkg"); - Directory.CreateDirectory(Path.Combine(_tempDir, "tools")); - Directory.CreateDirectory(Path.Combine(_tempDir, "lib", "netstandard2.0")); - File.WriteAllText(Path.Combine(_tempDir, "tools", "test.sh"), ""); - File.WriteAllText(Path.Combine(_tempDir, "lib", "netstandard2.0", "TestPackage.dll"), ""); - - var nuspec = CreateNuspec(@" - - - - TestPackage - 1.0.0 - Test - Test - - - - - - - "); - - var task = new PackNuSpec - { - NuspecPath = nuspec, - BasePath = _tempDir, - BuildEngine = new MockEngine(), - DestinationFolder = _tempDir, - }; - - Assert.True(task.Execute(), "The task should have passed"); - Assert.True(File.Exists(outputPath), "Should have produced a nupkg file in " + _tempDir); - var result = Assert.Single(task.Packages); - Assert.Equal(outputPath, result.ItemSpec); - using (var reader = new PackageArchiveReader(outputPath)) - { - var libItems = reader.GetLibItems().ToList(); - var libItem = Assert.Single(libItems); - Assert.Equal(FrameworkConstants.CommonFrameworks.NetStandard20, libItem.TargetFramework); - var assembly = Assert.Single(libItem.Items); - Assert.Equal("lib/netstandard2.0/TestPackage.dll", assembly); - - Assert.Contains(reader.GetFiles(), f => f == "tools/test.sh"); - } - } - - [Fact] - public void AppliesProperties() - { - var nuspec = CreateNuspec(@" - - - - HasProperties - $version$ - Microsoft - $description$ - $copyright$ - - - - - - - "); - - var version = "1.2.3"; - var description = "A test package\n\n\nwith newlines"; - var outputPath = Path.Combine(_tempDir, $"HasProperties.{version}.nupkg"); - var task = new PackNuSpec - { - NuspecPath = nuspec, - BasePath = _tempDir, - BuildEngine = new MockEngine(), - DestinationFolder = _tempDir, - Properties = new[] { $"version={version}", "", "", $" description ={description}", "copyright=", }, - }; - - Assert.True(task.Execute(), "The task should have passed"); - Assert.True(File.Exists(outputPath), "Should have produced a nupkg file in " + _tempDir); - - using (var reader = new PackageArchiveReader(outputPath)) - { - var metadata = new PackageBuilder(reader.GetNuspec(), basePath: null); - Assert.Equal(version, metadata.Version.ToString()); - Assert.Empty(metadata.Copyright); - Assert.Equal(description, metadata.Description); - } - } - - [Fact] - public void AddsDependencies() - { - var nuspec = CreateNuspec(@" - - - - HasDependencies - 1.0.0 - Test - Test - - - - - - - "); - - var task = new PackNuSpec - { - NuspecPath = nuspec, - BasePath = _tempDir, - BuildEngine = new MockEngine(), - DestinationFolder = _tempDir, - Dependencies = new[] - { - new TaskItem("OtherPackage", new Hashtable { ["Version"] = "[1.0.0, 2.0.0)"}), - new TaskItem("PackageInTfm", new Hashtable { ["TargetFramework"] = "netstandard1.0", ["Version"] = "0.1.0-beta" }), - new TaskItem("PackageInTfm", new Hashtable { ["TargetFramework"] = "netstandard1.1", ["Version"] = "0.2.0-beta" }), - } - }; - - Assert.True(task.Execute(), "The task should have passed"); - var result = Assert.Single(task.Packages); - - using (var reader = new PackageArchiveReader(result.ItemSpec)) - { - var metadata = new PackageBuilder(reader.GetNuspec(), basePath: null); - - var noTfmGroup = Assert.Single(metadata.DependencyGroups, d => d.TargetFramework.Equals(NuGetFramework.UnsupportedFramework)); - Assert.Equal(2, noTfmGroup.Packages.Count()); - Assert.Single(noTfmGroup.Packages, p => p.Id == "OtherPackage" && p.VersionRange.Equals(VersionRange.Parse("[1.0.0, 2.0.0)"))); - Assert.Single(noTfmGroup.Packages, p => p.Id == "AlreadyInNuspec" && p.VersionRange.Equals(VersionRange.Parse("[2.0.0]"))); - - var netstandard10Group = Assert.Single(metadata.DependencyGroups, d => d.TargetFramework.Equals(FrameworkConstants.CommonFrameworks.NetStandard10)); - var package1 = Assert.Single(netstandard10Group.Packages); - Assert.Equal("PackageInTfm", package1.Id); - Assert.Equal(VersionRange.Parse("0.1.0-beta"), package1.VersionRange); - - var netstandard11Group = Assert.Single(metadata.DependencyGroups, d => d.TargetFramework.Equals(FrameworkConstants.CommonFrameworks.NetStandard11)); - var package2 = Assert.Single(netstandard11Group.Packages); - Assert.Equal("PackageInTfm", package2.Id); - Assert.Equal(VersionRange.Parse("0.2.0-beta"), package2.VersionRange); - } - } - - [Fact] - public void WarnIfMissingFilesNodes() - { - var nuspec = CreateNuspec(@" - - - - HasNoFiles - 1.0.0 - Test - Test - - - "); - - var engine = new MockEngine(); - var task = new PackNuSpec - { - NuspecPath = nuspec, - BasePath = _tempDir, - BuildEngine = engine, - DestinationFolder = _tempDir, - }; - Assert.True(task.Execute()); - var warning = Assert.Single(engine.Warnings); - Assert.Equal("KRB" + KoreBuildErrors.NuspecMissingFilesNode, warning.Code); - } - - [Fact] - public void PacksFiles() - { - var files = new[] - { - Path.Combine("lib", "netstandard1.0", "_._"), - "top.txt", - }; - - var items = new List(); - - foreach (var file in files) - { - var path = Path.Combine(_tempDir, file); - Directory.CreateDirectory(Path.GetDirectoryName(path)); - File.WriteAllText(path, ""); - items.Add(new TaskItem(path, new Hashtable { ["PackagePath"] = file })); - } - - var nuspec = CreateNuspec(@" - - - - HasFiles - 1.0.0 - Test - Test - - - - "); - - var engine = new MockEngine(); - var task = new PackNuSpec - { - NuspecPath = nuspec, - BasePath = _tempDir, - BuildEngine = engine, - PackageFiles = items.ToArray(), - DestinationFolder = _tempDir, - }; - - Assert.True(task.Execute()); - var result = Assert.Single(task.Packages); - - using (var reader = new PackageArchiveReader(result.ItemSpec)) - { - Assert.Contains("lib/netstandard1.0/_._", reader.GetFiles()); - Assert.Contains("top.txt", reader.GetFiles()); - } - } - - [Theory] - [InlineData("")] - [InlineData("/")] - [InlineData("somedir/")] - public void FailsForBadPackagePath(string path) - { - var nuspec = CreateNuspec(@" - - - - HasFiles - 1.0.0 - Test - Test - - - - "); - - var engine = new MockEngine { ContinueOnError = true }; - var task = new PackNuSpec - { - NuspecPath = nuspec, - BasePath = _tempDir, - BuildEngine = engine, - PackageFiles = new[] { new TaskItem("file.txt", new Hashtable { ["PackagePath"] = path }) }, - DestinationFolder = _tempDir, - }; - - Assert.False(task.Execute(), "Task should fail"); - var error = Assert.Single(engine.Errors); - Assert.Equal("KRB" + KoreBuildErrors.InvalidPackagePathMetadata, error.Code); - } - - [Fact] - public void SetsLibraryIncludeFlagsOnDependency() - { - var nuspec = CreateNuspec(@" - - - - HasDependencies - 1.0.0 - Test - Test - - - - "); - - var task = new PackNuSpec - { - NuspecPath = nuspec, - BasePath = _tempDir, - BuildEngine = new MockEngine(), - DestinationFolder = _tempDir, - Dependencies = new[] - { - new TaskItem("Include", new Hashtable { ["Version"] = "1.0.0", ["IncludeAssets"] = "Build;Analyzers"}), - new TaskItem("Exclude", new Hashtable { ["Version"] = "1.0.0", ["ExcludeAssets"] = "Compile;Native"}), - new TaskItem("Both", new Hashtable { ["Version"] = "1.0.0", ["IncludeAssets"] = "Build; Analyzers", ["ExcludeAssets"] = "Build; Native; ContentFiles"}), - } - }; - - Assert.True(task.Execute(), "The task should have passed"); - var result = Assert.Single(task.Packages); - - using (var reader = new PackageArchiveReader(result.ItemSpec)) - { - var metadata = new PackageBuilder(reader.GetNuspec(), basePath: null); - var packages = Assert.Single(metadata.DependencyGroups).Packages; - Assert.Equal(3, packages.Count()); - - var include = Assert.Single(packages, p => p.Id == "Include").Include; - Assert.Equal(new[] { "Build", "Analyzers" }, include); - - var exclude = Assert.Single(packages, p => p.Id == "Exclude").Exclude; - Assert.Equal(new[] { "Compile", "Native" }, exclude); - - var both = Assert.Single(packages, p => p.Id == "Both"); - Assert.Equal(new[] { "Build", "Analyzers" }, both.Include); - Assert.Equal(new[] { "Build", "Native", "ContentFiles" }, both.Exclude); - } - } - - [Fact] - public void FailsIfBothOutputPathAndDestinationFolderAreGiven() - { - var engine = new MockEngine { ContinueOnError = true }; - var task = new PackNuSpec - { - BuildEngine = engine, - OutputPath = _tempDir, - DestinationFolder = _tempDir, - NuspecPath = CreateNuspec(""), - }; - - Assert.False(task.Execute(), "Task should fail"); - Assert.Contains("Either DestinationFolder and OutputPath must be specified, but only not both.", engine.Errors.Select(e => e.Message)); - } - - [Fact] - public void FailsIfNeitherOutputPathAndDestinationFolderAreGiven() - { - var engine = new MockEngine { ContinueOnError = true }; - var task = new PackNuSpec - { - BuildEngine = engine, - NuspecPath = CreateNuspec(""), - }; - - Assert.False(task.Execute(), "Task should fail"); - Assert.Contains("Either DestinationFolder and OutputPath must be specified, but only not both.", engine.Errors.Select(e => e.Message)); - } - - private string CreateNuspec(string xml) - { - var nuspecPath = Path.Combine(_tempDir, Path.GetRandomFileName() + ".nuspec"); - File.WriteAllText(nuspecPath, xml.Replace('`', '"').TrimStart()); - return nuspecPath; - } - - public void Dispose() - { - try - { - Directory.Delete(_tempDir, recursive: true); - } - catch - { - Console.WriteLine("Failed to delete " + _tempDir); - } - } - } -} diff --git a/test/KoreBuild.Tasks.Tests/SolutionInfoFactoryTests.cs b/test/KoreBuild.Tasks.Tests/SolutionInfoFactoryTests.cs deleted file mode 100644 index f2eaad004..000000000 --- a/test/KoreBuild.Tasks.Tests/SolutionInfoFactoryTests.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using KoreBuild.Tasks.ProjectModel; -using Xunit; - -namespace KoreBuild.Tasks.Tests -{ - public class SolutionInfoFactoryTests : IDisposable - { - private readonly string _slnFile; - - public SolutionInfoFactoryTests() - { - _slnFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - } - - [Theory] - [InlineData("", new[] { "ClassLib1", "VsixProject" })] - [InlineData("Debug", new[] { "ClassLib1", "VsixProject" })] - [InlineData("DebugNoVSIX", new[] { "ClassLib1" })] - public void FindsProjectsByDefaultConfiguration(string config, string[] projects) - { - File.WriteAllText(_slnFile, @" -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 -MinimumVisualStudioVersion = 15.0.26124.0 -Project(`{2150E333-8FDC-42A3-9474-1A3956D46DE8}`) = `src`, `src`, `{6BC8A037-601B-412E-B394-92F55C01C7A6}` -EndProject -Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `ClassLib1`, `src\ClassLib1\ClassLib1.csproj`, `{89EF0B05-98D4-4C4D-8870-718571091F79}` -EndProject -Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `VsixProject`, `src\VsixProject\VsixProject.csproj`, `{86986537-8DF5-423F-A3A8-0CA568A9FFC4}` -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - DebugNoVSIX|Any CPU = DebugNoVSIX|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {89EF0B05-98D4-4C4D-8870-718571091F79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {89EF0B05-98D4-4C4D-8870-718571091F79}.Debug|Any CPU.Build.0 = Debug|Any CPU - {86986537-8DF5-423F-A3A8-0CA568A9FFC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {86986537-8DF5-423F-A3A8-0CA568A9FFC4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {89EF0B05-98D4-4C4D-8870-718571091F79}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU - {89EF0B05-98D4-4C4D-8870-718571091F79}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU - {86986537-8DF5-423F-A3A8-0CA568A9FFC4}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {89EF0B05-98D4-4C4D-8870-718571091F79} = {6BC8A037-601B-412E-B394-92F55C01C7A6} - {86986537-8DF5-423F-A3A8-0CA568A9FFC4} = {6BC8A037-601B-412E-B394-92F55C01C7A6} - EndGlobalSection -EndGlobal -".Replace('`', '"')); - - var solution = SolutionInfoFactory.Create(_slnFile, config); - Assert.Equal(projects.Length, solution.Projects.Count); - Assert.All(projects, expected => Assert.Contains(solution.Projects, proj => Path.GetFileNameWithoutExtension(proj) == expected)); - } - - [Fact] - public void ThrowsForBadConfigName() - { - File.WriteAllText(_slnFile, @" -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 -MinimumVisualStudioVersion = 15.0.26124.0 -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal -".Replace('`', '"')); - - Assert.Throws(() => SolutionInfoFactory.Create(_slnFile, "Release")); - } - - public void Dispose() - { - try - { - File.Delete(_slnFile); - } - catch { } - } - } -} diff --git a/test/KoreBuild.Tasks.Tests/TaskTestBase.cs b/test/KoreBuild.Tasks.Tests/TaskTestBase.cs new file mode 100644 index 000000000..4b1f2c646 --- /dev/null +++ b/test/KoreBuild.Tasks.Tests/TaskTestBase.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using BuildTools.Tasks.Tests; +using System; +using System.IO; +using Xunit.Abstractions; + +namespace KoreBuild.Tasks.Tests +{ + public abstract class TaskTestBase : IDisposable + { + protected string TempDir { get; } + protected MockEngine MockEngine { get; } + protected ITestOutputHelper Output { get; } + + protected TaskTestBase(ITestOutputHelper output, MSBuildTestCollectionFixture fixture) + { + TempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + Directory.CreateDirectory(TempDir); + MockEngine = new MockEngine(output); + fixture.InitializeEnvironment(output); + Output = output; + } + + public void Dispose() + { + Directory.Delete(TempDir, recursive: true); + } + } +} diff --git a/test/KoreBuild.Tasks.Tests/TestResources/lorem.bin b/test/KoreBuild.Tasks.Tests/TestResources/lorem.bin deleted file mode 100644 index 2408fe952..000000000 --- a/test/KoreBuild.Tasks.Tests/TestResources/lorem.bin +++ /dev/null @@ -1 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque et nulla laoreet ex pharetra congue. Sed gravida justo orci. Nunc nec est vitae purus accumsan consectetur et vel risus. Sed lobortis nulla eu feugiat ornare. Pellentesque ornare semper lorem at vestibulum. Aliquam molestie erat nunc. Curabitur suscipit aliquet quam quis fringilla. diff --git a/test/KoreBuild.Tasks.Tests/UpgradeDependenciesTests.cs b/test/KoreBuild.Tasks.Tests/UpgradeDependenciesTests.cs deleted file mode 100644 index 3de7997f3..000000000 --- a/test/KoreBuild.Tasks.Tests/UpgradeDependenciesTests.cs +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Threading.Tasks; -using BuildTools.Tasks.Tests; -using KoreBuild.Tasks.Utilities; -using Microsoft.Build.Construction; -using Microsoft.Build.Evaluation; -using NuGet.Packaging; -using NuGet.Packaging.Core; -using NuGet.Versioning; -using Xunit; -using Xunit.Abstractions; - -namespace KoreBuild.Tasks.Tests -{ - [Collection(nameof(MSBuildTestCollection))] - public class UpgradeDependenciesTests : IDisposable - { - private readonly string _tempDir; - private readonly ITestOutputHelper _output; - - public UpgradeDependenciesTests(ITestOutputHelper output, MSBuildTestCollectionFixture fixture) - { - fixture.InitializeEnvironment(output); - _tempDir = Path.Combine(AppContext.BaseDirectory, Path.GetRandomFileName()); - Directory.CreateDirectory(_tempDir); - _output = output; - } - - [Fact] - public async Task WarnsWhenVariableIsNotInPackage() - { - // arrange - var packageId = new PackageIdentity("Lineup", NuGetVersion.Parse("1.0.0")); - var lineupPackagePath = CreateLineup(packageId); - var depsFilePath = CreateProjectDepsFile(new VersionVariable("PackageVersionVar", "1.0.0")); - var engine = new MockEngine(_output); - - // act - var task = new UpgradeDependencies - { - BuildEngine = engine, - DependenciesFile = depsFilePath, - LineupPackageId = packageId.Id, - LineupPackageRestoreSource = _tempDir, - }; - - // assert - Assert.True(await task.ExecuteAsync(), "Task is expected to pass"); - var warning = Assert.Single(engine.Warnings); - Assert.Equal(KoreBuildErrors.Prefix + KoreBuildErrors.PackageVersionNotFoundInLineup, warning.Code); - - var modifiedDepsFile = DependencyVersionsFile.Load(depsFilePath); - Assert.Equal("1.0.0", modifiedDepsFile.VersionVariables["PackageVersionVar"].Version); - } - - [Fact] - public async Task ModifiesVariableValue() - { - // arrange - var packageId = new PackageIdentity("Lineup", NuGetVersion.Parse("1.0.0")); - var lineupPackagePath = CreateLineup(packageId, new VersionVariable("PackageVersionVar", "2.0.0")); - var depsFilePath = CreateProjectDepsFile(new VersionVariable("PackageVersionVar", "1.0.0")); - - // act - var task = new UpgradeDependencies - { - BuildEngine = new MockEngine(_output), - DependenciesFile = depsFilePath, - LineupPackageId = packageId.Id, - LineupPackageRestoreSource = _tempDir, - }; - - // assert - Assert.True(await task.ExecuteAsync(), "Task is expected to pass"); - var modifiedDepsFile = DependencyVersionsFile.Load(depsFilePath); - Assert.Equal("2.0.0", modifiedDepsFile.VersionVariables["PackageVersionVar"].Version); - Assert.False(modifiedDepsFile.VersionVariables["PackageVersionVar"].IsReadOnly); - } - - - [Fact] - public async Task DoesNotModifyPinnedVariableValue() - { - // arrange - var packageId = new PackageIdentity("Lineup", NuGetVersion.Parse("1.0.0")); - var lineupPackagePath = CreateLineup(packageId, new VersionVariable("PackageVersionVar", "2.0.0")); - var depsFilePath = CreateProjectDepsFile(new VersionVariable("PackageVersionVar", "1.0.0") { IsReadOnly = true }); - - // act - var task = new UpgradeDependencies - { - BuildEngine = new MockEngine(_output), - DependenciesFile = depsFilePath, - LineupPackageId = packageId.Id, - LineupPackageRestoreSource = _tempDir, - }; - - // assert - Assert.True(await task.ExecuteAsync(), "Task is expected to pass"); - _output.WriteLine(File.ReadAllText(depsFilePath)); - var modifiedDepsFile = DependencyVersionsFile.Load(depsFilePath); - Assert.Equal("1.0.0", modifiedDepsFile.VersionVariables["PackageVersionVar"].Version); - Assert.True(modifiedDepsFile.VersionVariables["PackageVersionVar"].IsReadOnly); - } - - - [Fact] - public async Task ModifiesVariableValueUsingDepsFile() - { - // arrange - var depsFilePath = CreateProjectDepsFile(new VersionVariable("PackageVersionVar", "1.0.0")); - var updatedDepsFilePath = CreateProjectDepsFile(Path.Combine(_tempDir, "dependencies.props"), new VersionVariable("PackageVersionVar", "2.0.0")); - - // act - var task = new UpgradeDependencies - { - BuildEngine = new MockEngine(_output), - DependenciesFile = depsFilePath, - LineupDependenciesFile = updatedDepsFilePath - }; - - // assert - Assert.True(await task.ExecuteAsync(), "Task is expected to pass"); - var modifiedDepsFile = DependencyVersionsFile.Load(depsFilePath); - Assert.Equal("2.0.0", modifiedDepsFile.VersionVariables["PackageVersionVar"].Version); - } - - [Fact] - public async Task SnapsInternalAspNetCoreSdkToBuildTools() - { - // arrange - var packageId = new PackageIdentity("Lineup", NuGetVersion.Parse("1.0.0")); - var lineupPackagePath = CreateLineup(packageId, new VersionVariable("InternalAspNetCoreSdkPackageVersion", "2.0.0")); - var depsFilePath = CreateProjectDepsFile(new VersionVariable("InternalAspNetCoreSdkPackageVersion", "1.0.0")); - - // act - var task = new UpgradeDependencies - { - BuildEngine = new MockEngine(_output), - DependenciesFile = depsFilePath, - LineupPackageId = packageId.Id, - LineupPackageRestoreSource = _tempDir, - }; - - // assert - Assert.True(await task.ExecuteAsync(), "Task is expected to pass"); - var modifiedDepsFile = DependencyVersionsFile.Load(depsFilePath); - Assert.Equal(KoreBuildVersion.Current, modifiedDepsFile.VersionVariables["InternalAspNetCoreSdkPackageVersion"].Version); - } - - [Fact] - public async Task DoesNotModifiesFileIfNoChanges() - { - // arrange - var packageId = new PackageIdentity("Lineup", NuGetVersion.Parse("1.0.0")); - var pkg = new VersionVariable("PackageVersionVar", "1.0.0"); - var lineupPackagePath = CreateLineup(packageId, pkg); - var depsFilePath = CreateProjectDepsFile(pkg); - var created = File.GetLastWriteTime(depsFilePath); - - // act - var task = new UpgradeDependencies - { - BuildEngine = new MockEngine(_output), - DependenciesFile = depsFilePath, - LineupPackageId = packageId.Id, - LineupPackageRestoreSource = _tempDir, - }; - - // assert - Assert.True(await task.ExecuteAsync(), "Task is expected to pass"); - var modifiedDepsFile = DependencyVersionsFile.Load(depsFilePath); - Assert.Equal("1.0.0", modifiedDepsFile.VersionVariables["PackageVersionVar"].Version); - Assert.Equal(created, File.GetLastWriteTime(depsFilePath)); - } - - private string CreateProjectDepsFile(params VersionVariable[] variables) - { - return CreateProjectDepsFile(Path.Combine(_tempDir, "projectdeps.props"), variables); - } - - private string CreateProjectDepsFile(string depsFilePath, params VersionVariable[] variables) - { - var proj = ProjectRootElement.Create(NewProjectFileOptions.None); - var originalDepsFile = DependencyVersionsFile.Load(proj); - foreach (var item in variables) - { - if (item.IsReadOnly) - { - originalDepsFile.AddPinnedVariable(item.Name, item.Version); - } - else - { - originalDepsFile.Update(item.Name, item.Version); - } - } - originalDepsFile.Save(depsFilePath); - return depsFilePath; - } - - private string CreateLineup(PackageIdentity identity, params VersionVariable[] variables) - { - var output = Path.Combine(_tempDir, $"{identity.Id}.{identity.Version}.nupkg"); - - var proj = ProjectRootElement.Create(NewProjectFileOptions.None); - var depsFiles = DependencyVersionsFile.Load(proj); - foreach (var item in variables) - { - depsFiles.Update(item.Name, item.Version); - } - depsFiles.Save(Path.Combine(_tempDir, "dependencies.props")); - - var builder = new PackageBuilder - { - Id = identity.Id, - Version = identity.Version, - Owners = { "Test" }, - Authors = { "Test" }, - Description = "Test lineup package" - }; - - builder.AddFiles(_tempDir, "dependencies.props", "build/dependencies.props"); - - using (var stream = File.Create(output)) - { - builder.Save(stream); - } - - return output; - } - - public void Dispose() - { - Directory.Delete(_tempDir, recursive: true); - } - - private struct VersionVariable - { - public string Name; - public string Version; - internal bool IsReadOnly; - - public VersionVariable(string varName, string version) : this() - { - this.Name = varName; - this.Version = version; - } - } - } -} diff --git a/test/NuGetPackageVerifier.Tests/NuGetPackageVerifier.Tests.csproj b/test/NuGetPackageVerifier.Tests/NuGetPackageVerifier.Tests.csproj new file mode 100644 index 000000000..6b52ebb17 --- /dev/null +++ b/test/NuGetPackageVerifier.Tests/NuGetPackageVerifier.Tests.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + + + + + + diff --git a/test/NuGetPackageVerifier.Tests/Rules/PackageRepoMetadataRuleTests.cs b/test/NuGetPackageVerifier.Tests/Rules/PackageRepoMetadataRuleTests.cs new file mode 100644 index 000000000..b882d80fc --- /dev/null +++ b/test/NuGetPackageVerifier.Tests/Rules/PackageRepoMetadataRuleTests.cs @@ -0,0 +1,41 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using NuGet.Packaging; +using NuGet.Packaging.Core; +using NuGetPackageVerifier.Rules; +using NuGetPackageVerifier.Utilities; +using Xunit; +using Xunit.Abstractions; + +namespace NuGetPackageVerifier +{ + public class PackageRepoMetadataRuleTests + { + private readonly ITestOutputHelper _output; + + public PackageRepoMetadataRuleTests(ITestOutputHelper output) + { + _output = output; + } + + [Fact] + public void ItWarnsAboutMissingMetadata() + { + var metadata = new ManifestMetadata + { + Repository = new RepositoryMetadata { }, + }; + + var rule = new PackageRepoMetadataRule(); + + using (var context = TestPackageAnalysisContext.Create(_output, metadata)) + { + Assert.Contains(rule.Validate(context), r => string.Equals(r.IssueId, "PACKAGE_MISSING_REPO_TYPE", StringComparison.Ordinal)); + Assert.Contains(rule.Validate(context), r => string.Equals(r.IssueId, "PACKAGE_MISSING_REPO_URL", StringComparison.Ordinal)); + Assert.Contains(rule.Validate(context), r => string.Equals(r.IssueId, "PACKAGE_MISSING_REPO_COMMIT", StringComparison.Ordinal)); + } + } + } +} diff --git a/test/NuGetPackageVerifier.Tests/Rules/PackageSigningRuleTests.cs b/test/NuGetPackageVerifier.Tests/Rules/PackageSigningRuleTests.cs new file mode 100644 index 000000000..f8ef79bde --- /dev/null +++ b/test/NuGetPackageVerifier.Tests/Rules/PackageSigningRuleTests.cs @@ -0,0 +1,96 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Runtime.InteropServices; +using NuGetPackageVerifier.Rules; +using NuGetPackageVerifier.Utilities; +using Xunit; +using Xunit.Abstractions; + +namespace NuGetPackageVerifier +{ + public class PackageSigningRuleTests + { + private readonly ITestOutputHelper _output; + + public PackageSigningRuleTests(ITestOutputHelper output) + { + _output = output; + } + + [Fact] + public void Validate_ReturnsErrorIssue_IfPackageNotSigned() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // PackageSign verification only works on desktop + return; + } + + // Arrange + var context = TestPackageAnalysisContext.CreateContext( + _output, + new[] { "lib/netstandard2.0/Test.dll", "tools/MyScript.psd1" }); + + using (context) + { + var rule = GetRule(); + + // Act + var issues = rule.Validate(context); + + // Assert + Assert.Collection( + issues, + issue => + { + Assert.Equal(TestPackageAnalysisContext.PackageId, issue.Instance); + Assert.Equal("PACKAGE_SIGN_VERIFICATION_FAILED", issue.IssueId); + Assert.Equal(PackageIssueLevel.Error, issue.Level); + Assert.StartsWith($"Sign verification for package {TestPackageAnalysisContext.PackageId} failed:", issue.Issue); + }); + } + } + + [Fact] + public void Validate_ReturnsEmpty() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // PackageSign verification only works on desktop + return; + } + + // Arrange + var signedNupkgFile = Path.Combine(AppContext.BaseDirectory, "SignedNupkg.nupkg"); + + var context = new PackageAnalysisContext + { + Logger = new TestLogger(_output), + PackageFileInfo = new FileInfo(signedNupkgFile), + }; + + var rule = GetRule(); + + // Act + var issues = rule.Validate(context); + + // Assert + Assert.Empty(issues); + } + + private static PackageSigningRule GetRule() + { + var solutionDir = SolutionDirectory.GetSolutionRootDirectory(); + var nugetExe = Path.Combine(solutionDir, "obj", "nuget.exe"); + if (!File.Exists(nugetExe)) + { + throw new FileNotFoundException($"File {nugetExe} could not be found. Ensure build /t:Prepare is invoked from the root of this repository, before this test is executed."); + } + + return new PackageSigningRule(nugetExe); + } + } +} diff --git a/test/NuGetPackageVerifier.Tests/SignedNupkg.nupkg b/test/NuGetPackageVerifier.Tests/SignedNupkg.nupkg new file mode 100644 index 000000000..afcb98896 Binary files /dev/null and b/test/NuGetPackageVerifier.Tests/SignedNupkg.nupkg differ diff --git a/test/NuGetPackageVerifier.Tests/Utilities/DisposableDirectory.cs b/test/NuGetPackageVerifier.Tests/Utilities/DisposableDirectory.cs new file mode 100644 index 000000000..c3d21b2bc --- /dev/null +++ b/test/NuGetPackageVerifier.Tests/Utilities/DisposableDirectory.cs @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using IOPath = System.IO.Path; + +namespace NuGetPackageVerifier.Utilities +{ + internal class DisposableDirectory : IDisposable + { + public DisposableDirectory() + { + Path = IOPath.Combine(AppContext.BaseDirectory, IOPath.GetRandomFileName()); + Directory.CreateDirectory(Path); + } + + public string Path { get; } + + public void Dispose() + { + try + { + if (Directory.Exists(Path)) + { + Directory.Delete(Path, recursive: true); + } + } + catch + { + // Don't throw if we fail to delete the test directory. + } + } + } +} diff --git a/test/NuGetPackageVerifier.Tests/Utilities/SolutionDirectory.cs b/test/NuGetPackageVerifier.Tests/Utilities/SolutionDirectory.cs new file mode 100644 index 000000000..d121cf5ba --- /dev/null +++ b/test/NuGetPackageVerifier.Tests/Utilities/SolutionDirectory.cs @@ -0,0 +1,34 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; + +namespace NuGetPackageVerifier.Utilities +{ + internal static class SolutionDirectory + { + public static string GetSolutionRootDirectory() + { + const string SolutionFileName = "BuildTools.sln"; + var applicationBasePath = AppContext.BaseDirectory; + var directoryInfo = new DirectoryInfo(applicationBasePath); + + do + { + var projectFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, SolutionFileName)); + if (projectFileInfo.Exists) + { + return projectFileInfo.DirectoryName; + } + + directoryInfo = directoryInfo.Parent; + } + while (directoryInfo.Parent != null); + + throw new FileNotFoundException( + $"Solution file {SolutionFileName} could not be found in {applicationBasePath} or its parent directories.", + SolutionFileName); + } + } +} diff --git a/test/NuGetPackageVerifier.Tests/Utilities/TestLogger.cs b/test/NuGetPackageVerifier.Tests/Utilities/TestLogger.cs new file mode 100644 index 000000000..7d9d60928 --- /dev/null +++ b/test/NuGetPackageVerifier.Tests/Utilities/TestLogger.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using NuGetPackageVerifier.Logging; +using Xunit.Abstractions; + +namespace NuGetPackageVerifier.Utilities +{ + internal class TestLogger : IPackageVerifierLogger + { + private ITestOutputHelper _output; + + public TestLogger(ITestOutputHelper output) + { + _output = output; + } + + public void Log(LogLevel logLevel, string message) + { + _output.WriteLine($"{logLevel}: {message}"); + } + } +} diff --git a/test/NuGetPackageVerifier.Tests/Utilities/TestPackageAnalysisContext.cs b/test/NuGetPackageVerifier.Tests/Utilities/TestPackageAnalysisContext.cs new file mode 100644 index 000000000..d9386d28a --- /dev/null +++ b/test/NuGetPackageVerifier.Tests/Utilities/TestPackageAnalysisContext.cs @@ -0,0 +1,87 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.IO; +using System.Linq; +using NuGet.Packaging; +using NuGet.Versioning; +using Xunit.Abstractions; + +namespace NuGetPackageVerifier.Utilities +{ + internal class TestPackageAnalysisContext : PackageAnalysisContext + { + public const string PackageId = "TestPackage"; + private readonly DisposableDirectory _disposableDirectory; + + private TestPackageAnalysisContext(DisposableDirectory disposableDirectory) + { + _disposableDirectory = disposableDirectory; + } + + public static PackageAnalysisContext CreateContext( + ITestOutputHelper output, + string[] emptyFiles, + string version = "1.0.0") + { + return Create(output, + new ManifestMetadata + { + Id = PackageId, + Version = new NuGetVersion(version), + }, + emptyFiles); + } + + public static PackageAnalysisContext Create( + ITestOutputHelper output, + ManifestMetadata metadata, + string[] emptyFiles = null) + { + var disposableDirectory = new DisposableDirectory(); + var basePath = disposableDirectory.Path; + var nupkgFileName = $"{PackageId}.{metadata.Version}.nupkg"; + var nupkgPath = Path.Combine(basePath, nupkgFileName); + + // set required metadata + metadata.Id = metadata.Id ?? "Test"; + metadata.Version = metadata.Version ?? new NuGetVersion("1.0.0"); + metadata.Authors = metadata.Authors.Any() ? metadata.Authors : new[] { "test" }; + metadata.Description = metadata.Description ?? "Description"; + + // prevent PackageException for packages with no dependencies or content + emptyFiles = emptyFiles ?? new[] { "_._" }; + + var builder = new PackageBuilder(); + + builder.Populate(metadata); + + using (var nupkg = File.Create(nupkgPath)) + { + foreach (var dest in emptyFiles) + { + var fileName = Path.GetFileName(dest); + File.WriteAllText(Path.Combine(basePath, fileName), ""); + builder.AddFiles(basePath, fileName, dest); + } + + builder.Save(nupkg); + } + + var context = new TestPackageAnalysisContext(disposableDirectory) + { + Logger = new TestLogger(output), + PackageFileInfo = new FileInfo(nupkgPath), + Metadata = builder, + }; + + return context; + } + + public override void Dispose() + { + base.Dispose(); + _disposableDirectory.Dispose(); + } + } +} diff --git a/testassets/RepoThatShouldFailToBuild/korebuild.json b/testassets/RepoThatShouldFailToBuild/korebuild.json index 678d8bb94..9217392b1 100644 --- a/testassets/RepoThatShouldFailToBuild/korebuild.json +++ b/testassets/RepoThatShouldFailToBuild/korebuild.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json", - "channel": "release/2.1" + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/main/tools/korebuild.schema.json", + "channel": "main" } diff --git a/testassets/RepoThatShouldFailToBuild/src/BadConsole/BadConsole.csproj b/testassets/RepoThatShouldFailToBuild/src/BadConsole/BadConsole.csproj index 23df6047f..c73e0d169 100644 --- a/testassets/RepoThatShouldFailToBuild/src/BadConsole/BadConsole.csproj +++ b/testassets/RepoThatShouldFailToBuild/src/BadConsole/BadConsole.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.1 + netcoreapp3.1 diff --git a/testassets/RepoWithGlobalTool/Directory.Build.props b/testassets/RepoWithGlobalTool/Directory.Build.props deleted file mode 100644 index 058246e40..000000000 --- a/testassets/RepoWithGlobalTool/Directory.Build.props +++ /dev/null @@ -1 +0,0 @@ - diff --git a/testassets/RepoWithGlobalTool/Directory.Build.targets b/testassets/RepoWithGlobalTool/Directory.Build.targets deleted file mode 100644 index b207ca315..000000000 --- a/testassets/RepoWithGlobalTool/Directory.Build.targets +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/testassets/RepoWithGlobalTool/RepoWithGlobalTool.sln b/testassets/RepoWithGlobalTool/RepoWithGlobalTool.sln deleted file mode 100644 index af58340cc..000000000 --- a/testassets/RepoWithGlobalTool/RepoWithGlobalTool.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 -MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GlobalConsoleTool", "src\GlobalConsoleTool\GlobalConsoleTool.csproj", "{4F0E73BA-1E8D-41B2-8FE8-59E58228224F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Debug|x64.ActiveCfg = Debug|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Debug|x64.Build.0 = Debug|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Debug|x86.ActiveCfg = Debug|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Debug|x86.Build.0 = Debug|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Release|Any CPU.Build.0 = Release|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Release|x64.ActiveCfg = Release|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Release|x64.Build.0 = Release|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Release|x86.ActiveCfg = Release|Any CPU - {4F0E73BA-1E8D-41B2-8FE8-59E58228224F}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/testassets/RepoWithGlobalTool/build/dependencies.props b/testassets/RepoWithGlobalTool/build/dependencies.props deleted file mode 100644 index a932d8361..000000000 --- a/testassets/RepoWithGlobalTool/build/dependencies.props +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/testassets/RepoWithGlobalTool/korebuild.json b/testassets/RepoWithGlobalTool/korebuild.json deleted file mode 100644 index 678d8bb94..000000000 --- a/testassets/RepoWithGlobalTool/korebuild.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json", - "channel": "release/2.1" -} diff --git a/testassets/RepoWithGlobalTool/src/GlobalConsoleTool/GlobalConsoleTool.csproj b/testassets/RepoWithGlobalTool/src/GlobalConsoleTool/GlobalConsoleTool.csproj deleted file mode 100644 index d99c04c14..000000000 --- a/testassets/RepoWithGlobalTool/src/GlobalConsoleTool/GlobalConsoleTool.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - netcoreapp2.1 - true - win-x64;win-x86 - - - diff --git a/testassets/RepoWithGlobalTool/src/GlobalConsoleTool/Program.cs b/testassets/RepoWithGlobalTool/src/GlobalConsoleTool/Program.cs deleted file mode 100644 index e91098a2b..000000000 --- a/testassets/RepoWithGlobalTool/src/GlobalConsoleTool/Program.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace GlobalConsoleTool -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } - } -} diff --git a/testassets/SimpleRepo/Directory.Build.props b/testassets/SimpleRepo/Directory.Build.props index 49ef3296a..31b0d1447 100644 --- a/testassets/SimpleRepo/Directory.Build.props +++ b/testassets/SimpleRepo/Directory.Build.props @@ -1,5 +1,8 @@ - + + + true + diff --git a/testassets/SimpleRepo/NuGetPackageVerifier.json b/testassets/SimpleRepo/NuGetPackageVerifier.json index d2794bf11..08085b450 100644 --- a/testassets/SimpleRepo/NuGetPackageVerifier.json +++ b/testassets/SimpleRepo/NuGetPackageVerifier.json @@ -8,7 +8,7 @@ "Simple.CliTool": { "Exclusions": { "VERSION_INFORMATIONALVERSION": { - "tools/netcoreapp2.1/any/Newtonsoft.Json.dll": "Example exclusion" + "tools/netcoreapp3.1/any/Newtonsoft.Json.dll": "Example exclusion" } } } diff --git a/testassets/SimpleRepo/build/Sample.Lineup.nuspec b/testassets/SimpleRepo/build/Sample.Lineup.nuspec deleted file mode 100644 index 9dc148902..000000000 --- a/testassets/SimpleRepo/build/Sample.Lineup.nuspec +++ /dev/null @@ -1,15 +0,0 @@ - - - - Sample.Lineup - $version$ - KoreBuild - Description. - - - - - - - - diff --git a/testassets/SimpleRepo/build/dependencies.props b/testassets/SimpleRepo/build/dependencies.props index 0f0e6a4d7..86a4c4a5a 100644 --- a/testassets/SimpleRepo/build/dependencies.props +++ b/testassets/SimpleRepo/build/dependencies.props @@ -3,15 +3,10 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - 0.0.1 10.0.1 15.5.0 2.3.1 2.3.1 - - - $(KoreBuildVersion) - diff --git a/testassets/SimpleRepo/build/repo.targets b/testassets/SimpleRepo/build/repo.targets index c7f3af77e..6971488f7 100644 --- a/testassets/SimpleRepo/build/repo.targets +++ b/testassets/SimpleRepo/build/repo.targets @@ -1,27 +1,9 @@ $(PrepareDependsOn);Greet - $(PackageDependsOn);PackLineup - $(VerifyDependsOn);TestNuGetPush;UpgradeDependencies - - Sample.Lineup - $(Version) - $(IntermediateDir) - - - - - - - - - - - - diff --git a/testassets/SimpleRepo/build/sources.props b/testassets/SimpleRepo/build/sources.props deleted file mode 100644 index a5c9ae8bc..000000000 --- a/testassets/SimpleRepo/build/sources.props +++ /dev/null @@ -1,5 +0,0 @@ - - - $(RestoreAdditionalProjectSources);$(KoreBuildBundledPackageFolder) - - diff --git a/testassets/SimpleRepo/build/tasks/RepoTasks.csproj b/testassets/SimpleRepo/build/tasks/RepoTasks.csproj index c4fb6c59b..482a8fdf7 100644 --- a/testassets/SimpleRepo/build/tasks/RepoTasks.csproj +++ b/testassets/SimpleRepo/build/tasks/RepoTasks.csproj @@ -2,8 +2,7 @@ - - netcoreapp2.1 + netcoreapp3.1 diff --git a/testassets/SimpleRepo/korebuild.json b/testassets/SimpleRepo/korebuild.json index 678d8bb94..9217392b1 100644 --- a/testassets/SimpleRepo/korebuild.json +++ b/testassets/SimpleRepo/korebuild.json @@ -1,4 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json", - "channel": "release/2.1" + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/main/tools/korebuild.schema.json", + "channel": "main" } diff --git a/testassets/SimpleRepo/samples/Simple.Sample/Simple.Sample.csproj b/testassets/SimpleRepo/samples/Simple.Sample/Simple.Sample.csproj index 85e1fa1d0..4ef288727 100644 --- a/testassets/SimpleRepo/samples/Simple.Sample/Simple.Sample.csproj +++ b/testassets/SimpleRepo/samples/Simple.Sample/Simple.Sample.csproj @@ -6,7 +6,7 @@ Exe - netcoreapp2.1 + netcoreapp3.1 diff --git a/testassets/SimpleRepo/src/Simple.CliTool/Simple.CliTool.csproj b/testassets/SimpleRepo/src/Simple.CliTool/Simple.CliTool.csproj index 5d11ab4ec..524847a43 100644 --- a/testassets/SimpleRepo/src/Simple.CliTool/Simple.CliTool.csproj +++ b/testassets/SimpleRepo/src/Simple.CliTool/Simple.CliTool.csproj @@ -1,23 +1,21 @@ - netcoreapp2.1 + netcoreapp3.1 exe DotnetTool cowsay Simple.CliTool true - win-x64;win-x86 TestCert MyPackageSigningCert - - tools/$(TargetFramework)/any/Newtonsoft.Json.dll + tools/$(TargetFramework)/any/ diff --git a/testassets/SimpleRepo/src/Simple.Lib/Simple.Lib.csproj b/testassets/SimpleRepo/src/Simple.Lib/Simple.Lib.csproj index 864030fdb..72c1a4d8f 100644 --- a/testassets/SimpleRepo/src/Simple.Lib/Simple.Lib.csproj +++ b/testassets/SimpleRepo/src/Simple.Lib/Simple.Lib.csproj @@ -1,12 +1,9 @@ - netstandard2.0;net461 + netstandard2.0;net462 TestCert + NuGet - - - - diff --git a/testassets/SimpleRepo/test/Simple.Test/Simple.Test.csproj b/testassets/SimpleRepo/test/Simple.Test/Simple.Test.csproj index 0619259c6..3fd2ed02a 100644 --- a/testassets/SimpleRepo/test/Simple.Test/Simple.Test.csproj +++ b/testassets/SimpleRepo/test/Simple.Test/Simple.Test.csproj @@ -1,8 +1,8 @@ - netcoreapp2.1;net461 - netcoreapp2.1 + netcoreapp3.1;net462 + netcoreapp3.1 diff --git a/tools/KoreBuild.Console/Commands/ApiBaselinesGenerateCommand.cs b/tools/KoreBuild.Console/Commands/ApiBaselinesGenerateCommand.cs deleted file mode 100644 index e1bb37c57..000000000 --- a/tools/KoreBuild.Console/Commands/ApiBaselinesGenerateCommand.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using Microsoft.Extensions.CommandLineUtils; - -namespace KoreBuild.Console.Commands -{ - internal class ApiBaselinesGenerateCommand : SubCommandBase - { - public ApiBaselinesGenerateCommand(CommandContext context) : base(context) - { - } - - public override void Configure(CommandLineApplication application) - { - application.Description = "Generates baselines for all projects in this repo."; - - base.Configure(application); - } - - protected override int Execute() - { - var args = new List - { - "msbuild", - "/nologo", - "/m", - $"/p:KoreBuildVersion={this.Context.KoreBuildVersion}", - $"/p:RepositoryRoot=\"{this.Context.RepoPath}/\"", - "\"/p:GenerateBaselines=true\"", - "\"/p:SkipTests=true\"", - "/clp:Summary", - Path.Combine(Context.KoreBuildDir, "KoreBuild.proj") - }; - - if (Reporter.IsVerbose) - { - args.Add("\"/v:n\""); - } - else - { - args.Add("\"/v:m\""); - } - - return RunDotnet(args, Context.RepoPath); - } - } -} diff --git a/tools/KoreBuild.Console/Commands/CommandBase.cs b/tools/KoreBuild.Console/Commands/CommandBase.cs deleted file mode 100644 index bb8fcc8c9..000000000 --- a/tools/KoreBuild.Console/Commands/CommandBase.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.Extensions.CommandLineUtils; - -namespace KoreBuild.Console.Commands -{ - internal abstract class CommandBase - { - private CommandLineApplication _application; - - public virtual void Configure(CommandLineApplication application) - { - _application = application; - - application.HelpOption("-h|--help"); - - application.OnExecute( - () => - { - if (IsValid()) - { - return Execute(); - } - else - { - application.ShowHelp(); - return 1; - } - }); - } - - protected virtual int Execute() - { - _application.ShowHelp(); - - return 0; - } - - protected virtual bool IsValid() - { - return true; - } - } -} diff --git a/tools/KoreBuild.Console/Commands/CommandContext.cs b/tools/KoreBuild.Console/Commands/CommandContext.cs deleted file mode 100644 index 2373311c8..000000000 --- a/tools/KoreBuild.Console/Commands/CommandContext.cs +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using Microsoft.Extensions.CommandLineUtils; -using Microsoft.Extensions.Tools.Internal; - -namespace KoreBuild.Console.Commands -{ - internal class CommandContext - { - private const string _defaultToolsSource = "https://aspnetcore.blob.core.windows.net/buildtools"; - private const string _dotnetFolderName = ".dotnet"; - - private CommandOption _repoPathOption; - private CommandOption _dotNetHomeOption; - private CommandOption _toolsSourceOption; - private CommandOption _verbose; - - private string _koreBuildDir; - private CommandOption _korebuildOverrideOpt; - - public CommandContext(CommandLineApplication application) - { - _korebuildOverrideOpt = application.Option("--korebuild-override ", "Where is KoreBuild?", CommandOptionType.SingleValue, inherited: true); - // for local development only - _korebuildOverrideOpt.ShowInHelpText = false; - - _verbose = application.Option("-v|--verbose", "Show verbose output", CommandOptionType.NoValue, inherited: true); - _toolsSourceOption = application.Option("--tools-source", "The source to draw tools from.", CommandOptionType.SingleValue, inherited: true); - _repoPathOption = application.Option("--repo-path", "The path to the repo to work on.", CommandOptionType.SingleValue, inherited: true); - _dotNetHomeOption = application.Option("--dotnet-home", "The place where dotnet lives", CommandOptionType.SingleValue, inherited: true); - // TODO: Configure file - } - - public string KoreBuildDir - { - get - { - if (_koreBuildDir == null) - { - _koreBuildDir = FindKoreBuildDirectory(); - } - return _koreBuildDir; - } - } - - public string ConfigDirectory => Path.Combine(KoreBuildDir, "config"); - public string RepoPath => _repoPathOption.HasValue() ? _repoPathOption.Value() : Directory.GetCurrentDirectory(); - public string DotNetHome => GetDotNetHome(); - public string ToolsSource => _toolsSourceOption.HasValue() ? _toolsSourceOption.Value() : _defaultToolsSource; - public string SDKVersion => GetDotnetSDKVersion(); - - public string KoreBuildVersion => GetKoreBuildVersion(); - - public IReporter Reporter => new ConsoleReporter(PhysicalConsole.Singleton, _verbose != null, false); - - private string GetDotnetSDKVersion() - { - var sdkVersionEnv = Environment.GetEnvironmentVariable("KOREBUILD_DOTNET_VERSION"); - if (sdkVersionEnv != null) - { - return sdkVersionEnv; - } - else - { - var sdkVersionPath = Path.Combine(ConfigDirectory, "sdk.version"); - return File.ReadAllText(sdkVersionPath).Trim(); - } - } - - private string GetDotNetHome() - { - var dotnetHome = Environment.GetEnvironmentVariable("DOTNET_HOME"); - var userProfile = Environment.GetEnvironmentVariable("USERPROFILE"); - var home = Environment.GetEnvironmentVariable("HOME"); - - var result = Path.Combine(Directory.GetCurrentDirectory(), _dotnetFolderName); - if (_dotNetHomeOption.HasValue()) - { - result = _dotNetHomeOption.Value(); - } - else if (!string.IsNullOrEmpty(dotnetHome)) - { - result = dotnetHome; - } - else if (!string.IsNullOrEmpty(userProfile)) - { - result = Path.Combine(userProfile, _dotnetFolderName); - } - else if (!string.IsNullOrEmpty(home)) - { - result = home; - } - - return result; - } - - private string GetKoreBuildVersion() - { - var dir = new DirectoryInfo(FindKoreBuildDirectory()); - return dir.Parent.Name; - } - - private string FindKoreBuildDirectory() - { - if (_korebuildOverrideOpt.HasValue()) - { - return Path.GetFullPath(_korebuildOverrideOpt.Value()); - } - - var executingDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - var root = Directory.GetDirectoryRoot(executingDir); - while (executingDir != root) - { - var files = Directory.EnumerateFiles(executingDir); - var koreProj = Path.Combine(executingDir, "KoreBuild.proj"); - if (files.Contains(koreProj)) - { - return executingDir; - } - - var directories = Directory.EnumerateDirectories(executingDir); - - var fileDir = Path.Combine(executingDir, "files"); - if (directories.Contains(fileDir)) - { - return Path.Combine(fileDir, "KoreBuild"); - } - - executingDir = Directory.GetParent(executingDir).FullName; - } - - Reporter.Error("Couldn't find the KoreBuild directory."); - throw new DirectoryNotFoundException(); - } - - public string GetDotNetInstallDir() - { - var dotnetDir = DotNetHome; - if (IsWindows()) - { - dotnetDir = Path.Combine(dotnetDir, GetArchitecture()); - } - - return dotnetDir; - } - - public string GetDotNetExecutable() - { - var dotnetDir = GetDotNetInstallDir(); - - var dotnetFile = "dotnet"; - - if (IsWindows()) - { - dotnetFile += ".exe"; - } - - return Path.Combine(dotnetDir, dotnetFile); - } - - public string GetArchitecture() - { - return Environment.GetEnvironmentVariable("KOREBUILD_DOTNET_ARCH") ?? "x64"; - } - - public bool IsWindows() - { - return RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - } - } -} diff --git a/tools/KoreBuild.Console/Commands/DependenciesGenerateCommand.cs b/tools/KoreBuild.Console/Commands/DependenciesGenerateCommand.cs deleted file mode 100644 index 274de1c7f..000000000 --- a/tools/KoreBuild.Console/Commands/DependenciesGenerateCommand.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using Microsoft.Extensions.CommandLineUtils; - -namespace KoreBuild.Console.Commands -{ - internal class DependenciesGenerateCommand : SubCommandBase - { - private CommandOption _configOpt; - private CommandOption _fileOpt; - - public DependenciesGenerateCommand(CommandContext context) : base(context) - { - } - - public override void Configure(CommandLineApplication application) - { - application.Description = "Generates a build/dependencies.props file and updates csproj files to use variables"; - application.ExtendedHelpText = @" -MORE INFO: - - This command will generate a dependencies.props file and adjust all PackageReference's in csproj files - to use the MSBuild variables it generates. - - Example output: - - - - 1.0.0 - - -"; - - _configOpt = application.Option("-c|--configuration ", "The MSBuild configuration. Defaults to 'Debug'.", CommandOptionType.SingleValue); - _fileOpt = application.Option("--deps-file ", "The dependencies.props file to upgrade.", CommandOptionType.SingleValue); - - base.Configure(application); - } - - protected override int Execute() - { - var args = new List - { - "msbuild", - Path.Combine(Context.KoreBuildDir, "KoreBuild.proj"), - "-t:GenerateDependenciesPropsFile", - }; - - if (_configOpt.HasValue()) - { - args.Add("-p:Configuration=" + _configOpt.Value()); - } - - if (_fileOpt.HasValue()) - { - var filePath = _fileOpt.Value(); - if (!Path.IsPathRooted(filePath)) - { - filePath = Path.GetFullPath(filePath); - } - - args.Add("-p:DependencyVersionsFile=" + filePath); - } - - if (Reporter.IsVerbose) - { - args.Add("-v:n"); - } - - return RunDotnet(args, Context.RepoPath); - } - } -} diff --git a/tools/KoreBuild.Console/Commands/DependenciesUpgradeCommand.cs b/tools/KoreBuild.Console/Commands/DependenciesUpgradeCommand.cs deleted file mode 100644 index b830e71a5..000000000 --- a/tools/KoreBuild.Console/Commands/DependenciesUpgradeCommand.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using Microsoft.Extensions.CommandLineUtils; - -namespace KoreBuild.Console.Commands -{ - internal class DependenciesUpgradeCommand : SubCommandBase - { - private CommandOption _sourceOpt; - private CommandOption _packageIdOpt; - private CommandOption _packageVersionOpt; - private CommandOption _sourceDeps; - private CommandOption _fileOpt; - - public DependenciesUpgradeCommand(CommandContext context) : base(context) - { - } - - public override void Configure(CommandLineApplication application) - { - application.Description = "Upgrades the build/dependencies.props file to the latest package versions"; - application.ExtendedHelpText = @" -MORE INFO: - - The upgrade uses a 'lineup' package as the source of information about which versions to use. - - A lineup package is simply a nuget package that contains a file in build/dependencies.props. - Just like the version of the file in this local repo, this file is an MSBuild project file - with a list of MSBuild variables. Example: - - - - 1.0.0 - - -"; - - _sourceOpt = application.Option("-s|--source ", - "Specifies a NuGet package source to use to upgrade dependencies to the latest lineup package.", CommandOptionType.SingleValue); - _packageIdOpt = application.Option("--id ", "Specifies the lineup package id to use.", CommandOptionType.SingleValue); - _packageVersionOpt = application.Option("--version ", "Specifies the lineup package version to use.", CommandOptionType.SingleValue); - _sourceDeps = application.Option("--source-deps ", "The dependencies.props file to use as a source of versions.", CommandOptionType.SingleValue); - _fileOpt = application.Option("--deps-file ", "The dependencies.props file to upgrade.", CommandOptionType.SingleValue); - - base.Configure(application); - } - - protected override int Execute() - { - var args = new List - { - "msbuild", - Path.Combine(Context.KoreBuildDir, "KoreBuild.proj"), - "-t:UpgradeDependencies", - }; - - if (_sourceOpt.HasValue()) - { - args.Add("-p:LineupPackageRestoreSource=" + _sourceOpt.Value()); - } - - if (_packageIdOpt.HasValue()) - { - args.Add("-p:LineupPackageId=" + _packageIdOpt.Value()); - } - - if (_packageVersionOpt.HasValue()) - { - args.Add("-p:LineupPackageVersion=" + _packageVersionOpt.Value()); - } - - if (_sourceDeps.HasValue()) - { - args.Add("-p:LineupDependenciesFile=" + _sourceDeps.Value()); - } - - if (_fileOpt.HasValue()) - { - var filePath = _fileOpt.Value(); - if (!Path.IsPathRooted(filePath)) - { - filePath = Path.GetFullPath(filePath); - } - - args.Add("-p:DependencyVersionsFile=" + filePath); - } - - if (Reporter.IsVerbose) - { - args.Add("-v:n"); - } - - return RunDotnet(args, Context.RepoPath); - } - } -} diff --git a/tools/KoreBuild.Console/Commands/DockerBuildCommand.cs b/tools/KoreBuild.Console/Commands/DockerBuildCommand.cs deleted file mode 100644 index 7e8e8eb9f..000000000 --- a/tools/KoreBuild.Console/Commands/DockerBuildCommand.cs +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Reflection; -using Microsoft.Extensions.CommandLineUtils; - -namespace KoreBuild.Console.Commands -{ - internal class DockerBuildCommand : SubCommandBase - { - private const string DockerIgnore = ".dockerignore"; - private const string DockerfileExtension = ".dockerfile"; - private const string Owner = "aspnetbuild"; - private const string ImageName = "korebuild"; - - public DockerBuildCommand(CommandContext context) : base(context) - { - } - - public CommandArgument ImageVariant { get; set; } - - public List Arguments { get; set; } - - public string Tag => $@"{Owner}/{ImageName}:{ImageVariant.Value}"; - - public override void Configure(CommandLineApplication application) - { - ImageVariant = application.Argument("image", "The docker image to run on."); - Arguments = application.RemainingArguments; - - base.Configure(application); - } - - protected override bool IsValid() - { - if (string.IsNullOrEmpty(ImageVariant?.Value)) - { - Reporter.Error("Image is a required argument."); - return false; - } - - return true; - } - - protected override int Execute() - { - var dockerFileName = GetDockerFileName(ImageVariant.Value); - var dockerFileSource = GetDockerFileSource(dockerFileName); - var dockerFileDestination = Path.Combine(Context.RepoPath, GetDockerFileName(ImageVariant.Value)); - - File.Copy(dockerFileSource, dockerFileDestination, overwrite: true); - - var dockerIgnoreSource = GetDockerFileSource(DockerIgnore); - var dockerIgnoreDestination = Path.Combine(Context.RepoPath, DockerIgnore); - - File.Copy(dockerIgnoreSource, dockerIgnoreDestination, overwrite: true); - - // If our ToolSource isn't http copy it to the docker context - var dockerToolsSource = Context.ToolsSource; - string toolsSourceDestination = null; - if (!Context.ToolsSource.StartsWith("http")) - { - dockerToolsSource = "ToolsSource"; - toolsSourceDestination = Path.Combine(Context.RepoPath, dockerToolsSource); - DirectoryCopy(Context.ToolsSource, toolsSourceDestination); - } - - try - { - var buildArgs = new List { "build" }; - - buildArgs.AddRange(new string[] { "-t", Tag, "-f", dockerFileDestination, Context.RepoPath }); - var buildResult = RunDockerCommand(buildArgs); - - if (buildResult != 0) - { - return buildResult; - } - - var containerName = $"{Owner}_{DateTime.Now.ToString("yyyyMMddHHmmss")}"; - - var runArgs = new List { "run", "--rm", "-i", "--name", containerName, Tag }; - - runArgs.AddRange(new[] { "-ToolsSource", dockerToolsSource }); - - if (Arguments?.Count > 0) - { - runArgs.AddRange(Arguments); - } - - Reporter.Verbose($"Running in container '{containerName}'"); - return RunDockerCommand(runArgs); - } - finally - { - // Clean up the stuff we dumped there in order to get it in the docker context. - File.Delete(dockerFileDestination); - File.Delete(dockerIgnoreDestination); - if (toolsSourceDestination != null) - { - Directory.Delete(toolsSourceDestination, recursive: true); - } - } - } - - private string GetDockerFileSource(string fileName) - { - var executingDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - var source = Path.Combine(executingDir, "Commands", "DockerFiles", fileName); - - if (!File.Exists(source)) - { - Reporter.Error($"DockerFile '{source}' doesn't exist."); - throw new FileNotFoundException(); - } - - return source; - } - - private string GetDockerFileName(string platform) - { - return $"{platform}{DockerfileExtension}"; - } - - private int RunDockerCommand(List arguments) - { - var args = ArgumentEscaper.EscapeAndConcatenate(arguments.ToArray()); - Reporter.Verbose($"Running 'docker {args}'"); - - var psi = new ProcessStartInfo - { - FileName = "docker", - Arguments = args, - RedirectStandardError = true - }; - - var process = Process.Start(psi); - process.WaitForExit(); - - if (process.ExitCode != 0) - { - Reporter.Error(process.StandardError.ReadToEnd()); - } - - return process.ExitCode; - } - - private static void DirectoryCopy(string sourceDirName, string destDirName) - { - // Get the subdirectories for the specified directory. - DirectoryInfo dir = new DirectoryInfo(sourceDirName); - - if (!dir.Exists) - { - throw new DirectoryNotFoundException( - "Source directory does not exist or could not be found: " - + sourceDirName); - } - - DirectoryInfo[] dirs = dir.GetDirectories(); - // If the destination directory doesn't exist, create it. - if (!Directory.Exists(destDirName)) - { - Directory.CreateDirectory(destDirName); - } - - // Get the files in the directory and copy them to the new location. - FileInfo[] files = dir.GetFiles(); - foreach (FileInfo file in files) - { - string temppath = Path.Combine(destDirName, file.Name); - file.CopyTo(temppath, overwrite: true); - } - - // Copy subdirectories and their contents to the new location. - foreach (DirectoryInfo subdir in dirs) - { - string temppath = Path.Combine(destDirName, subdir.Name); - DirectoryCopy(subdir.FullName, temppath); - } - } - } -} diff --git a/tools/KoreBuild.Console/Commands/DockerFiles/.dockerignore b/tools/KoreBuild.Console/Commands/DockerFiles/.dockerignore deleted file mode 100644 index 26f97c87a..000000000 --- a/tools/KoreBuild.Console/Commands/DockerFiles/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -korebuild-lock.txt -**/bin -**/obj -artifacts diff --git a/tools/KoreBuild.Console/Commands/DockerFiles/jessie.dockerfile b/tools/KoreBuild.Console/Commands/DockerFiles/jessie.dockerfile deleted file mode 100644 index cef20b92f..000000000 --- a/tools/KoreBuild.Console/Commands/DockerFiles/jessie.dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM microsoft/dotnet:2.0-runtime-deps-jessie - -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - git \ - # KoreBuild dependencies - jq \ - curl \ - unzip \ - apt-transport-https \ - && rm -rf /var/lib/apt/lists/* - -ADD . . - -ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true - -RUN ./run.sh install-tools - -ENTRYPOINT ["./build.sh"] diff --git a/tools/KoreBuild.Console/Commands/DockerFiles/winservercore.dockerfile b/tools/KoreBuild.Console/Commands/DockerFiles/winservercore.dockerfile deleted file mode 100644 index a591f1adf..000000000 --- a/tools/KoreBuild.Console/Commands/DockerFiles/winservercore.dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM microsoft/aspnet:4.6.2 - - -# DevPack returns exit 0 immediately, but it's not done, so we wait. -# A more correct thing would be to block on a registry key existing or similar. -RUN \ - Invoke-WebRequest https://download.microsoft.com/download/F/1/D/F1DEB8DB-D277-4EF9-9F48-3A65D4D8F965/NDP461-DevPack-KB3105179-ENU.exe -OutFile ~\\net461dev.exe ; \ - ~\\net461dev.exe /Passive /NoRestart ; \ - Start-Sleep -s 10; \ - Remove-Item ~\\net461dev.exe -Force ; - -WORKDIR c:\\repo - -ADD . . - -ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true - -RUN ./run.ps1 install-tools - -ENTRYPOINT ["build.cmd"] diff --git a/tools/KoreBuild.Console/Commands/InstallToolsCommand.cs b/tools/KoreBuild.Console/Commands/InstallToolsCommand.cs deleted file mode 100644 index ab71baa8a..000000000 --- a/tools/KoreBuild.Console/Commands/InstallToolsCommand.cs +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using Microsoft.Extensions.CommandLineUtils; - -namespace KoreBuild.Console.Commands -{ - internal class InstallToolsCommand : SubCommandBase - { - public InstallToolsCommand(CommandContext context) : base(context) - { - } - - private string KoreBuildSkipRuntimeInstall => Environment.GetEnvironmentVariable("KOREBUILD_SKIP_RUNTIME_INSTALL"); - private string PathENV => Environment.GetEnvironmentVariable("PATH"); - private string DotNetInstallDir => Environment.GetEnvironmentVariable("DOTNET_INSTALL_DIR"); - - public override void Configure(CommandLineApplication application) - { - base.Configure(application); - } - - protected override int Execute() - { - var installDir = Context.GetDotNetInstallDir(); - - Reporter.Verbose($"Installing tools to '{installDir}'"); - - if (DotNetInstallDir != null && DotNetInstallDir != installDir) - { - Reporter.Verbose($"installDir = {installDir}"); - Reporter.Verbose($"DOTNET_INSTALL_DIR = {DotNetInstallDir}"); - Reporter.Verbose("The environment variable DOTNET_INSTALL_DIR is deprecated. The recommended alternative is DOTNET_HOME."); - } - - var dotnet = Context.GetDotNetExecutable(); - var dotnetOnPath = GetCommandFromPath("dotnet"); - - // TODO: decide case sensitivity and handly symbolic links - if (dotnetOnPath != null && (dotnetOnPath != dotnet)) - { - Reporter.Warn($"dotnet found on the system PATH is '{dotnetOnPath}' but KoreBuild will use '{dotnet}'"); - } - - var pathPrefix = Directory.GetParent(dotnet); - if (PathENV.StartsWith($"{pathPrefix}{Path.PathSeparator}", StringComparison.OrdinalIgnoreCase)) - { - Reporter.Output($"Adding {pathPrefix} to PATH"); - Environment.SetEnvironmentVariable("PATH", $"{pathPrefix};{PathENV}"); - } - - if (KoreBuildSkipRuntimeInstall == "1") - { - Reporter.Output("Skipping runtime installation because KOREBUILD_SKIP_RUNTIME_INSTALL = 1"); - return 0; - } - - var scriptExtension = Context.IsWindows() ? "ps1" : "sh"; - - var scriptPath = Path.Combine(Context.KoreBuildDir, "dotnet-install." + scriptExtension); - - if (!Context.IsWindows()) - { - var args = ArgumentEscaper.EscapeAndConcatenate(new string[] { "+x", scriptPath }); - var psi = new ProcessStartInfo - { - FileName = "chmod", - Arguments = args - }; - - var process = Process.Start(psi); - process.WaitForExit(); - } - - var architecture = Context.GetArchitecture(); - - InstallCLI(scriptPath, installDir, architecture, Context.SDKVersion); - - return 0; - } - - private void InstallCLI(string script, string installDir, string architecture, string version) - { - var sdkPath = Path.Combine(installDir, "sdk", version, "dotnet.dll"); - - if (!File.Exists(sdkPath)) - { - Reporter.Verbose($"Installing dotnet {version} to {installDir}"); - - var args = ArgumentEscaper.EscapeAndConcatenate(new string[] { - "-Version", version, - "-Architecture", architecture, - "-InstallDir", installDir - }); - - var psi = new ProcessStartInfo - { - FileName = script, - Arguments = args - }; - - var process = Process.Start(psi); - process.WaitForExit(); - } - else - { - Reporter.Output($".NET Core SDK {version} is already installed. Skipping installation."); - } - } - - private static string GetCommandFromPath(string command) - { - var values = Environment.GetEnvironmentVariable("PATH"); - foreach (var path in values.Split(';')) - { - var fullPath = Path.Combine(path, command); - if (File.Exists(fullPath)) - return fullPath; - } - return null; - } - } -} diff --git a/tools/KoreBuild.Console/Commands/MSBuildCommand.cs b/tools/KoreBuild.Console/Commands/MSBuildCommand.cs deleted file mode 100644 index 1ab4c4414..000000000 --- a/tools/KoreBuild.Console/Commands/MSBuildCommand.cs +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using Microsoft.Extensions.CommandLineUtils; - -namespace KoreBuild.Console.Commands -{ - internal class MSBuildCommand : SubCommandBase - { - public MSBuildCommand(CommandContext context) : base(context) - { - } - - private bool EnableBinaryLog => Environment.GetEnvironmentVariable("KOREBUILD_ENABLE_BINARY_LOG") == "1"; - - private List Arguments { get; set; } - - public override void Configure(CommandLineApplication application) - { - base.Configure(application); - Arguments = application.RemainingArguments; - } - - protected override int Execute() - { - Reporter.Verbose($"Building {Context.RepoPath}."); - Reporter.Verbose($"dotnet = {Context.RepoPath}"); - - if (Context.SDKVersion != "latest") - { - var globalFile = Path.Combine(Context.RepoPath, "global.json"); - File.WriteAllText(globalFile, $"{{ \"sdk\": {{ \"version\": \"{Context.SDKVersion}\" }} }}", System.Text.Encoding.ASCII); - } - else - { - Reporter.Verbose($"Skipping global.json generation because the SDKVersion = {Context.SDKVersion}"); - } - - var makeFileProj = Path.Combine(Context.KoreBuildDir, "KoreBuild.proj"); - var msBuildArtifactsDir = Path.Combine(Context.RepoPath, "artifacts", "msbuild"); - var msBuildResponseFile = Path.Combine(msBuildArtifactsDir, "msbuild.rsp"); - - var msBuildLogArgument = string.Empty; - - - if (EnableBinaryLog) - { - Reporter.Verbose("Enabling binary logging"); - var msBuildLogFilePath = Path.Combine(msBuildArtifactsDir, "msbuild.binlog"); - msBuildLogArgument = $"/bl:{msBuildLogFilePath}"; - } - - var msBuildArguments = string.Empty; - - foreach (var arg in Arguments) - { - msBuildArguments += Environment.NewLine + arg; - } - - // TODO: naturalize newlines - msBuildArguments += $@" -/nologo -/m -/p:RepositoryRoot={Context.RepoPath}\ -{msBuildLogArgument} -/clp:Summary -""{makeFileProj}"" -"; - - Directory.CreateDirectory(msBuildArtifactsDir); - - var noop = msBuildArguments.IndexOf("/t:Noop", StringComparison.OrdinalIgnoreCase) >= 0 - || msBuildArguments.IndexOf("/t:Cow", StringComparison.OrdinalIgnoreCase) >= 0; - - File.WriteAllText(msBuildResponseFile, msBuildArguments, System.Text.Encoding.ASCII); - Reporter.Verbose($"Noop = {noop}"); - var firstTime = Environment.GetEnvironmentVariable("DOTNET_SKIP_FIRST_TIME_EXPERIENCE"); - if (noop) - { - Environment.SetEnvironmentVariable("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "true"); - } - else - { - var buildTaskResult = BuildTaskProject(Context.RepoPath); - if (buildTaskResult != 0) - { - return buildTaskResult; - } - } - - return RunDotnet(new[] { "msbuild", $@"@""{msBuildResponseFile}""" }); - } - - private int BuildTaskProject(string path) - { - var taskFolder = Path.Combine(Context.RepoPath, "build", "tasks"); - var taskProj = Path.Combine(taskFolder, "RepoTasks.csproj"); - var publishFolder = Path.Combine(taskFolder, "bin", "publish"); - - if (File.Exists(taskProj)) - { - if (File.Exists(publishFolder)) - { - Directory.Delete(publishFolder, recursive: true); - } - - var sdkPath = $"/p:RepoTasksSdkPath={Path.Combine(Context.KoreBuildDir, "msbuild", "KoreBuild.RepoTasks.Sdk", "Sdk")}"; - - var restoreResult = RunDotnet(new[] { "restore", taskProj, sdkPath }); - if (restoreResult != 0) - { - return restoreResult; - } - - return RunDotnet(new[] { "publish", taskProj, "--configuration", "Release", "--output", publishFolder, "/nologo", sdkPath }); - } - - return 0; - } - } -} diff --git a/tools/KoreBuild.Console/Commands/RootCommand.cs b/tools/KoreBuild.Console/Commands/RootCommand.cs deleted file mode 100644 index d4ac33bdb..000000000 --- a/tools/KoreBuild.Console/Commands/RootCommand.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Reflection; -using Microsoft.Extensions.CommandLineUtils; - -namespace KoreBuild.Console.Commands -{ - internal class RootCommand : CommandBase - { - public override void Configure(CommandLineApplication application) - { - var context = new CommandContext(application); - - application.FullName = "korebuild"; - - application.Command("install-tools", new InstallToolsCommand(context).Configure, throwOnUnexpectedArg: false); - application.Command("msbuild", new MSBuildCommand(context).Configure, throwOnUnexpectedArg: false); - application.Command("docker-build", new DockerBuildCommand(context).Configure, throwOnUnexpectedArg: false); - - // Commands that upgrade things - application.Command("upgrade", c => - { - c.HelpOption("-h|--help"); - c.Command("deps", new DependenciesUpgradeCommand(context).Configure, throwOnUnexpectedArg: false); - - c.OnExecute(() => - { - c.ShowHelp(); - return 2; - }); - }); - - // Commands that generate code and files - application.Command("generate", c => - { - c.HelpOption("-h|--help"); - - c.Command("deps", new DependenciesGenerateCommand(context).Configure, throwOnUnexpectedArg: false); - c.Command("api-baselines", new ApiBaselinesGenerateCommand(context).Configure, throwOnUnexpectedArg: false); - - c.OnExecute(() => - { - c.ShowHelp(); - return 2; - }); - }); - - application.VersionOption("--version", GetVersion); - - base.Configure(application); - } - - private static string GetVersion() - => typeof(RootCommand).GetTypeInfo().Assembly.GetCustomAttribute().InformationalVersion; - } -} diff --git a/tools/KoreBuild.Console/Commands/SubCommandBase.cs b/tools/KoreBuild.Console/Commands/SubCommandBase.cs deleted file mode 100644 index ecd7f088b..000000000 --- a/tools/KoreBuild.Console/Commands/SubCommandBase.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using Microsoft.Extensions.CommandLineUtils; -using Microsoft.Extensions.Tools.Internal; - -namespace KoreBuild.Console.Commands -{ - internal abstract class SubCommandBase : CommandBase - { - protected SubCommandBase(CommandContext context) - { - Context = context; - } - - protected CommandContext Context { get; } - - protected IReporter Reporter => Context.Reporter; - - protected override bool IsValid() - { - if (!Directory.Exists(Context.RepoPath)) - { - Context.Reporter.Error($"The RepoPath '{Context.RepoPath}' doesn't exist."); - return false; - } - - return base.IsValid(); - } - - protected int RunDotnet(params string[] arguments) - => RunDotnet(arguments, Directory.GetCurrentDirectory()); - - protected int RunDotnet(IEnumerable arguments, string workingDir) - { - var args = ArgumentEscaper.EscapeAndConcatenate(arguments); - - // use the dotnet.exe file used to start this process - var dotnet = DotNetMuxer.MuxerPath; - // if it could not be found, fallback to detecting DOTNET_HOME or PATH - dotnet = string.IsNullOrEmpty(dotnet) || !Path.IsPathRooted(dotnet) - ? Context.GetDotNetExecutable() - : dotnet; - - var psi = new ProcessStartInfo - { - FileName = dotnet, - Arguments = args, - WorkingDirectory = workingDir, - }; - - Reporter.Verbose($"Executing '{psi.FileName} {psi.Arguments}'"); - - var process = Process.Start(psi); - process.WaitForExit(); - - return process.ExitCode; - } - } -} diff --git a/tools/KoreBuild.Console/KoreBuild.Console.csproj b/tools/KoreBuild.Console/KoreBuild.Console.csproj deleted file mode 100644 index ea26eda02..000000000 --- a/tools/KoreBuild.Console/KoreBuild.Console.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - Exe - netcoreapp2.1 - - - - - - - - - - - diff --git a/tools/KoreBuild.Console/Program.cs b/tools/KoreBuild.Console/Program.cs deleted file mode 100644 index 39262ff80..000000000 --- a/tools/KoreBuild.Console/Program.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using KoreBuild.Console.Commands; -using Microsoft.Extensions.CommandLineUtils; -using System; - -namespace KoreBuild.Console -{ - class Program - { - static int Main(string[] args) - { - var application = new CommandLineApplication() - { - Name = "korebuild" - }; - - new RootCommand().Configure(application); - - try - { - return application.Execute(args); - } - catch (Exception ex) - { - System.Console.Error.WriteLine($"Exception thrown: '{ex.ToString()}'"); - return 1; - } - } - } -} diff --git a/tools/KoreBuild.Console/Reporter/ConsoleReporter.cs b/tools/KoreBuild.Console/Reporter/ConsoleReporter.cs deleted file mode 100644 index a9fe89812..000000000 --- a/tools/KoreBuild.Console/Reporter/ConsoleReporter.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; - -namespace Microsoft.Extensions.Tools.Internal -{ - public class ConsoleReporter : IReporter - { - private object _writeLock = new object(); - - public ConsoleReporter(IConsole console) - : this(console, verbose: false, quiet: false) - { } - - public ConsoleReporter(IConsole console, bool verbose, bool quiet) - { - Console = console; - IsVerbose = verbose; - IsQuiet = quiet; - } - - protected IConsole Console { get; } - public bool IsVerbose { get; set; } - public bool IsQuiet { get; set; } - - protected virtual void WriteLine(TextWriter writer, string message, ConsoleColor? color) - { - lock (_writeLock) - { - if (color.HasValue) - { - Console.ForegroundColor = color.Value; - } - - writer.WriteLine(message); - - if (color.HasValue) - { - Console.ResetColor(); - } - } - } - - public virtual void Error(string message) - => WriteLine(Console.Error, message, ConsoleColor.Red); - public virtual void Warn(string message) - => WriteLine(Console.Out, message, ConsoleColor.Yellow); - - public virtual void Output(string message) - { - if (IsQuiet) - { - return; - } - WriteLine(Console.Out, message, color: null); - } - - public virtual void Verbose(string message) - { - if (!IsVerbose) - { - return; - } - - WriteLine(Console.Out, message, ConsoleColor.DarkGray); - } - } -} diff --git a/tools/KoreBuild.Console/Reporter/IConsole.cs b/tools/KoreBuild.Console/Reporter/IConsole.cs deleted file mode 100644 index 46cae4a05..000000000 --- a/tools/KoreBuild.Console/Reporter/IConsole.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; - -namespace Microsoft.Extensions.Tools.Internal -{ - public interface IConsole - { - event ConsoleCancelEventHandler CancelKeyPress; - TextWriter Out { get; } - TextWriter Error { get; } - TextReader In { get; } - bool IsInputRedirected { get; } - bool IsOutputRedirected { get; } - bool IsErrorRedirected { get; } - ConsoleColor ForegroundColor { get; set; } - void ResetColor(); - } -} diff --git a/tools/KoreBuild.Console/Reporter/IReporter.cs b/tools/KoreBuild.Console/Reporter/IReporter.cs deleted file mode 100644 index e57261401..000000000 --- a/tools/KoreBuild.Console/Reporter/IReporter.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.Extensions.Tools.Internal -{ - public interface IReporter - { - void Verbose(string message); - void Output(string message); - void Warn(string message); - void Error(string message); - bool IsVerbose { get; } - } -} diff --git a/tools/KoreBuild.Console/Reporter/PhysicalConsole.cs b/tools/KoreBuild.Console/Reporter/PhysicalConsole.cs deleted file mode 100644 index 429342ecc..000000000 --- a/tools/KoreBuild.Console/Reporter/PhysicalConsole.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; - -namespace Microsoft.Extensions.Tools.Internal -{ - public class PhysicalConsole : IConsole - { - private PhysicalConsole() - { - Console.CancelKeyPress += (o, e) => - { - CancelKeyPress?.Invoke(o, e); - }; - } - - public static IConsole Singleton { get; } = new PhysicalConsole(); - - public event ConsoleCancelEventHandler CancelKeyPress; - public TextWriter Error => Console.Error; - public TextReader In => Console.In; - public TextWriter Out => Console.Out; - public bool IsInputRedirected => Console.IsInputRedirected; - public bool IsOutputRedirected => Console.IsOutputRedirected; - public bool IsErrorRedirected => Console.IsErrorRedirected; - public ConsoleColor ForegroundColor - { - get => Console.ForegroundColor; - set => Console.ForegroundColor = value; - } - - public void ResetColor() => Console.ResetColor(); - } -} diff --git a/tools/korebuild.schema.json b/tools/korebuild.schema.json index 94a7015a1..932bb422b 100644 --- a/tools/korebuild.schema.json +++ b/tools/korebuild.schema.json @@ -109,9 +109,9 @@ "channel": { "description": "The channel of KoreBuild used to select a version when korebuild-lock.txt is not present.", "type": "string", - "default": "master", + "default": "main", "enum": [ - "master", + "main", "release/2.2", "release/2.1", "release/2.0" diff --git a/version.props b/version.props index b5b5f26f1..95243317c 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ - release/2.1 - 2.1.7 + main + 3.0.0 build t000 $(VersionSuffix)-$(BuildNumber)