diff --git a/.azure-pipelines/pull-request.yml b/.azure-pipelines/pull-request.yml index 162b26bdad..5d0d292503 100644 --- a/.azure-pipelines/pull-request.yml +++ b/.azure-pipelines/pull-request.yml @@ -1,86 +1,90 @@ -trigger: - - master - - releases/* - -pr: - - master - - milestones/* - - releases/* - - servicing/* - -variables: - branchCounter: $[counter(variables['Build.SourceBranch'], 0)] - -jobs: - - job: Windows_Build_and_UnitTests - variables: - platformFriendlyName: Windows - strategy: - maxParallel: 2 - matrix: - debug: - configuration: Debug - release: - configuration: Release - pool: - vmImage: vs2017-win2016 - steps: - - powershell: $(Build.Repository.LocalPath)/Scripts/CI/Set-Version.ps1 -SourceBranchCounter $(branchCounter) - displayName: "Compute product version" - - template: templates/windows-build-and-unit-test.yml - - - job: macOS_Build_and_UnitTests - variables: - platformFriendlyName: macOS - strategy: - maxParallel: 2 - matrix: - debug: - configuration: Debug - release: - configuration: Release - pool: - name: 'Hosted macOS' - steps: - - powershell: $(Build.Repository.LocalPath)/Scripts/CI/Set-Version.ps1 -SourceBranchCounter $(branchCounter) - displayName: "Compute product version" - - template: templates/macos-build-and-unit-test.yml - - - job: macOS_FunctionalTests - variables: - platformFriendlyName: macOS - configuration: Release - timeoutInMinutes: 30 - pool: - name: 'Hosted macOS' - dependsOn: macOS_Build_and_UnitTests - condition: succeeded() - steps: - - checkout: none # Use the drop from macOS_Build_and_UnitTests job - - template: templates/macos-functional-test.yml - - - job: macOS_FunctionalTests_watchman - variables: - platformFriendlyName: macOS - configuration: Release - timeoutInMinutes: 30 - pool: - name: 'Hosted macOS' - dependsOn: macOS_Build_and_UnitTests - condition: succeeded() - steps: - - checkout: none # Use the drop from macOS_Build_and_UnitTests job - - template: templates/macos-functional-test-watchman.yml - - - job: Windows_FunctionalTests - timeoutInMinutes: 30 - variables: - platformFriendlyName: Windows - configuration: Release - pool: - vmImage: vs2017-win2016 - dependsOn: Windows_Build_and_UnitTests - condition: succeeded() - steps: - - checkout: none # We'll get the build drop from Windows_Build_and_UnitTests job - - template: templates/windows-functional-test.yml +trigger: + - master + - releases/* + +pr: + - master + - milestones/* + - releases/* + - servicing/* + +variables: + branchCounter: $[counter(variables['Build.SourceBranch'], 0)] + +jobs: + - job: Windows_Build_and_UnitTests + variables: + platformFriendlyName: Windows + strategy: + maxParallel: 2 + matrix: + debug: + configuration: Debug + release: + configuration: Release + pool: + vmImage: windows-2019 + steps: + - powershell: $(Build.Repository.LocalPath)/Scripts/CI/Set-Version.ps1 -SourceBranchCounter $(branchCounter) + displayName: "Compute product version" + - template: templates/windows-build-and-unit-test.yml + + - job: macOS_Build_and_UnitTests + variables: + platformFriendlyName: macOS + strategy: + maxParallel: 2 + matrix: + debug: + configuration: Debug + release: + configuration: Release + pool: + name: 'Hosted macOS' + steps: + - powershell: $(Build.Repository.LocalPath)/Scripts/CI/Set-Version.ps1 -SourceBranchCounter $(branchCounter) + displayName: "Compute product version" + - template: templates/macos-build-and-unit-test.yml + + - job: macOS_FunctionalTests + variables: + platformFriendlyName: macOS + configuration: Release + timeoutInMinutes: 30 + pool: + name: 'Hosted macOS' + dependsOn: macOS_Build_and_UnitTests + condition: succeeded() + steps: + - checkout: none # Use the drop from macOS_Build_and_UnitTests job + - template: templates/macos-functional-test.yml + parameters: + useWatchman: false + + - job: macOS_FunctionalTests_watchman + variables: + platformFriendlyName: macOS + configuration: Release + timeoutInMinutes: 30 + pool: + name: 'Hosted macOS' + dependsOn: macOS_Build_and_UnitTests + condition: succeeded() + steps: + - checkout: none # Use the drop from macOS_Build_and_UnitTests job + - template: templates/macos-functional-test.yml + parameters: + useWatchman: true + + - job: Windows_FunctionalTests + timeoutInMinutes: 30 + variables: + platformFriendlyName: Windows + configuration: Release + pool: + vmImage: windows-2019 + dependsOn: Windows_Build_and_UnitTests + condition: succeeded() + steps: + - checkout: none # We'll get the build drop from Windows_Build_and_UnitTests job + - template: templates/windows-functional-test.yml diff --git a/.azure-pipelines/templates/macos-build-and-unit-test.yml b/.azure-pipelines/templates/macos-build-and-unit-test.yml index e0a9333e7f..4852cd8161 100644 --- a/.azure-pipelines/templates/macos-build-and-unit-test.yml +++ b/.azure-pipelines/templates/macos-build-and-unit-test.yml @@ -1,35 +1,42 @@ steps: - - task: DotNetCoreInstaller@0 - displayName: Use .NET Core SDK 2.1.301 + - task: UseDotNet@2 + displayName: Use .NET Core SDK 3.0.100 inputs: packageType: sdk - version: '2.1.301' + version: 3.0.100 + + - script: $(Build.Repository.LocalPath)/Scripts/Mac/NukeBuildOutputs.sh + displayName: Delete previous build outputs + continueOnError: true - - task: InstallAppleCertificate@2 - displayName: 'Install Apple certificate' + - task: InstallAppleCertificate@2 + displayName: 'Install Apple certificate' inputs: - certSecureFile: 'PrjFSKextCertExpiresJun6_2020_v2.p12' - certPwd: '$(kext.certificate.password)' + certSecureFile: 'PrjFSKextCertExpiresJun6_2020_v2.p12' + certPwd: '$(kext.certificate.password)' - script: Scripts/Mac/BuildScalarForMac.sh $(configuration) $(majorAndMinorVersion).$(revision) displayName: Build Scalar ($(configuration)) + - script: Scripts/Mac/RunUnitTests.sh $(configuration) $(Common.TestResultsDirectory) + displayName: Run unit tests ($(configuration)) + - task: PublishTestResults@2 displayName: Publish test results inputs: - testRunner: NUnit - testResultsFiles: '**/TestResult.xml' - searchFolder: $(System.DefaultWorkingDirectory) + testRunner: VSTest + testResultsFiles: '**/*.trx' + searchFolder: $(Common.TestResultsDirectory) testRunTitle: Mac $(configuration) Unit Tests publishRunAttachments: true condition: succeededOrFailed() - - script: Scripts/Mac/CI/CreateBuildDrop.sh $(configuration) $(Build.ArtifactStagingDirectory)/Tests - displayName: Create functional test drop + - script: Scripts/Mac/CI/CreateFTDrop.sh $(configuration) $(Build.ArtifactStagingDirectory)/Tests + displayName: Create functional tests drop - task: PublishBuildArtifacts@1 - displayName: Publish functional test drop artifact. + displayName: Publish functional tests drop inputs: pathtoPublish: $(Build.ArtifactStagingDirectory)/Tests artifactName: "FunctionalTests_$(platformFriendlyName)_$(configuration)" @@ -38,10 +45,10 @@ steps: condition: and(succeeded(), eq(variables['configuration'], 'Release')) - script: Scripts/Mac/CI/CreateInstallerDrop.sh $(configuration) $(Build.ArtifactStagingDirectory)/Installers - displayName: Create installer drop + displayName: Create installers drop - task: PublishBuildArtifacts@1 - displayName: Publish installers + displayName: Publish installers drop inputs: pathToPublish: $(Build.ArtifactStagingDirectory)/Installers artifactName: "Installers_$(platformFriendlyName)_$(configuration)" diff --git a/.azure-pipelines/templates/macos-functional-test-watchman.yml b/.azure-pipelines/templates/macos-functional-test-watchman.yml deleted file mode 100644 index 2e739e3eeb..0000000000 --- a/.azure-pipelines/templates/macos-functional-test-watchman.yml +++ /dev/null @@ -1,60 +0,0 @@ -steps: - - - task: DotNetCoreInstaller@0 - displayName: Use .NET Core SDK 2.1.301 - inputs: - packageType: sdk - version: '2.1.301' - - - bash: rm -rf $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/BuildOutput/Git/* - displayName: Clean previous Git installations - - - bash: brew install watchman - displayName: Install watchman - - - task: DownloadBuildArtifacts@0 - displayName: Download functional test drop - inputs: - buildType: current - downloadType: specific - artifactName: FunctionalTests_$(platformFriendlyName)_$(configuration) - downloadPath: $(Build.BinariesDirectory) - - - bash: | - chmod +x $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/*.sh - chmod +x $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/Publish/* - displayName: Ensure tests assets are executable - - - bash: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/CleanupFunctionalTests.sh - displayName: Clean environment - - - bash: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/PrepFunctionalTests.sh - displayName: Prep functional tests - - - bash: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/RunFunctionalTests.sh $(configuration) --trace2-output=$(Build.ArtifactStagingDirectory)/trace2-event-mac.txt - displayName: Run functional tests - - - task: PublishTestResults@2 - displayName: Publish functional test results - inputs: - testRunner: NUnit - testResultsFiles: "**\\TestResult*.xml" - searchFolder: $(System.DefaultWorkingDirectory) - testRunTitle: macOS $(configuration) Functional Tests - publishRunAttachments: true - condition: succeededOrFailed() - - - task: PublishBuildArtifacts@1 - displayName: Publish Git trace2 log - inputs: - pathtoPublish: '$(Build.ArtifactStagingDirectory)' - artifactName: trace2-event-mac.txt - - - bash: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/CleanupFunctionalTests.sh - displayName: Cleanup - condition: always() - - - bash: sudo rm -rf $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration) - displayName: Cleanup phase 2 - condition: always() - diff --git a/.azure-pipelines/templates/macos-functional-test.yml b/.azure-pipelines/templates/macos-functional-test.yml index 6112422e12..d0a4b28f8c 100644 --- a/.azure-pipelines/templates/macos-functional-test.yml +++ b/.azure-pipelines/templates/macos-functional-test.yml @@ -1,45 +1,67 @@ +parameters: + useWatchman: true + steps: - - task: DotNetCoreInstaller@0 - displayName: Use .NET Core SDK 2.1.301 + - task: UseDotNet@2 + displayName: Use .NET Core SDK 3.0.100 inputs: packageType: sdk - version: '2.1.301' - - - bash: rm -rf $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/BuildOutput/Git/* - displayName: Clean previous Git installations + version: 3.0.100 - task: DownloadBuildArtifacts@0 - displayName: Download functional test drop + displayName: Download functional tests drop inputs: buildType: current downloadType: specific artifactName: FunctionalTests_$(platformFriendlyName)_$(configuration) downloadPath: $(Build.BinariesDirectory) + - task: DownloadBuildArtifacts@0 + displayName: Download installers drop + inputs: + buildType: current + downloadType: specific + artifactName: Installers_$(platformFriendlyName)_$(configuration) + downloadPath: $(Build.BinariesDirectory) + - bash: | chmod +x $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/*.sh - chmod +x $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/Publish/* - displayName: Ensure tests assets are executable + chmod +x $(Build.BinariesDirectory)/Installers_$(platformFriendlyName)_$(configuration)/*.sh + displayName: Ensure all scripts are executable - - bash: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/CleanupFunctionalTests.sh - displayName: Clean environment + - ${{ if eq(parameters.useWatchman, 'true') }}: + - bash: $(Build.BinariesDirectory)/Installers_$(platformFriendlyName)_$(configuration)/InstallScalar.sh + displayName: Install product (with watchman) - - bash: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/PrepFunctionalTests.sh - displayName: Prep functional tests + - ${{ if ne(parameters.useWatchman, 'true') }}: + - bash: $(Build.BinariesDirectory)/Installers_$(platformFriendlyName)_$(configuration)/InstallScalar.sh --no-watchman + displayName: Install product (without watchman) - - bash: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/RunFunctionalTests.sh $(configuration) --trace2-output=$(Build.ArtifactStagingDirectory)/trace2-event-mac.txt + - bash: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/Mac/RunFunctionalTests.sh $(configuration) --test-scalar-on-path --trace2-output=$(Build.ArtifactStagingDirectory)/trace2-event-mac.txt displayName: Run functional tests - - task: PublishTestResults@2 - displayName: Publish functional test results - inputs: - testRunner: NUnit - testResultsFiles: "**\\TestResult*.xml" - searchFolder: $(System.DefaultWorkingDirectory) - testRunTitle: macOS $(configuration) Functional Tests - publishRunAttachments: true - condition: succeededOrFailed() + - ${{ if eq(parameters.useWatchman, 'true') }}: + - task: PublishTestResults@2 + displayName: Publish functional tests results + inputs: + testRunner: NUnit + testResultsFiles: "**\\TestResult*.xml" + searchFolder: $(System.DefaultWorkingDirectory) + testRunTitle: macOS $(configuration) Functional Tests (with watchman) + publishRunAttachments: true + condition: succeededOrFailed() + + - ${{ if ne(parameters.useWatchman, 'true') }}: + - task: PublishTestResults@2 + displayName: Publish functional tests results + inputs: + testRunner: NUnit + testResultsFiles: "**\\TestResult*.xml" + searchFolder: $(System.DefaultWorkingDirectory) + testRunTitle: macOS $(configuration) Functional Tests (without watchman) + publishRunAttachments: true + condition: succeededOrFailed() - task: PublishBuildArtifacts@1 displayName: Publish Git trace2 log diff --git a/.azure-pipelines/templates/windows-build-and-unit-test.yml b/.azure-pipelines/templates/windows-build-and-unit-test.yml index 238bab9d5c..888b9fdb93 100644 --- a/.azure-pipelines/templates/windows-build-and-unit-test.yml +++ b/.azure-pipelines/templates/windows-build-and-unit-test.yml @@ -1,49 +1,54 @@ -steps: - - - script: $(Build.Repository.LocalPath)\\Scripts\\NukeBuildOutputs.bat - displayName: Delete previous build outputs - continueOnError: true - - - powershell: | - & 'C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\sn.exe' -Vr *,31bf3856ad364e35 - & 'C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\x64\sn.exe' -Vr *,31bf3856ad364e35 - displayName: Disable strong name validation for MS delay-signed assemblies - - - script: $(Build.Repository.LocalPath)\Scripts\BuildScalarForWindows.bat $(configuration) $(majorAndMinorVersion).$(revision) - displayName: Run Scalar build script ($(configuration)) - - - script: $(Build.Repository.LocalPath)\Scripts\RunUnitTests.bat $(configuration) - displayName: Run unit tests - - - task: PublishTestResults@2 - displayName: Publish unit test results - inputs: - testRunner: NUnit - testResultsFiles: "**\\TestResult.xml" - searchFolder: $(System.DefaultWorkingDirectory) - testRunTitle: Windows $(configuration) Unit Tests - publishRunAttachments: true - - - script: $(Build.Repository.LocalPath)\Scripts\CI\CreateBuildDrop.bat $(configuration) $(Build.ArtifactStagingDirectory)\Tests - displayName: Create functional test drop - - - task: PublishBuildArtifacts@1 - displayName: Publish functional test drop - inputs: - pathtoPublish: $(Build.ArtifactStagingDirectory)\Tests - artifactName: "FunctionalTests_$(platformFriendlyName)_$(configuration)" - parallel: true - parallelCount: 8 - condition: and(succeeded(), eq(variables['configuration'], 'Release')) - - - script: $(Build.Repository.LocalPath)\Scripts\CI\CreateInstallerDrop.bat $(configuration) $(Build.ArtifactStagingDirectory)\Installers - displayName: Create installer drop - - - task: PublishBuildArtifacts@1 - displayName: Publish installers - inputs: - pathToPublish: $(Build.ArtifactStagingDirectory)\Installers - artifactName: "Installers_$(platformFriendlyName)_$(configuration)" - parallel: true - parallelCount: 8 - condition: and(succeeded(), eq(variables['configuration'], 'Release')) +steps: + + - task: NuGetToolInstaller@0 + inputs: + versionSpec: '>=5.1' + + - task: UseDotNet@2 + displayName: Use .NET Core SDK 3.0.100 + inputs: + packageType: sdk + version: 3.0.100 + + - script: $(Build.Repository.LocalPath)\\Scripts\\NukeBuildOutputs.bat + displayName: Delete previous build outputs + continueOnError: true + + - script: $(Build.Repository.LocalPath)\Scripts\BuildScalarForWindows.bat $(configuration) $(majorAndMinorVersion).$(revision) + displayName: Build Scalar ($(configuration)) + + - script: $(Build.Repository.LocalPath)\Scripts\RunUnitTests.bat $(configuration) $(Common.TestResultsDirectory) + displayName: Run unit tests ($(configuration)) + + - task: PublishTestResults@2 + displayName: Publish unit test results + inputs: + testRunner: VSTest + testResultsFiles: "**\\*.trx" + searchFolder: $(Common.TestResultsDirectory) + testRunTitle: Windows $(configuration) Unit Tests + publishRunAttachments: true + + - script: $(Build.Repository.LocalPath)\Scripts\CI\CreateFTDrop.bat $(configuration) $(Build.ArtifactStagingDirectory)\Tests + displayName: Create functional tests drop + + - task: PublishBuildArtifacts@1 + displayName: Publish functional tests drop + inputs: + pathtoPublish: $(Build.ArtifactStagingDirectory)\Tests + artifactName: "FunctionalTests_$(platformFriendlyName)_$(configuration)" + parallel: true + parallelCount: 8 + condition: and(succeeded(), eq(variables['configuration'], 'Release')) + + - script: $(Build.Repository.LocalPath)\Scripts\CI\CreateInstallerDrop.bat $(configuration) $(Build.ArtifactStagingDirectory)\Installers + displayName: Create installers drop + + - task: PublishBuildArtifacts@1 + displayName: Publish installers drop + inputs: + pathToPublish: $(Build.ArtifactStagingDirectory)\Installers + artifactName: "Installers_$(platformFriendlyName)_$(configuration)" + parallel: true + parallelCount: 8 + condition: and(succeeded(), eq(variables['configuration'], 'Release')) diff --git a/.azure-pipelines/templates/windows-functional-test.yml b/.azure-pipelines/templates/windows-functional-test.yml index bcbab1f40d..ba7e09d714 100644 --- a/.azure-pipelines/templates/windows-functional-test.yml +++ b/.azure-pipelines/templates/windows-functional-test.yml @@ -1,35 +1,53 @@ -steps: - - - task: DownloadBuildArtifacts@0 - displayName: Download functional test drop - inputs: - buildType: current - downloadType: specific - artifactName: FunctionalTests_$(platformFriendlyName)_$(configuration) - downloadPath: $(Build.BinariesDirectory) - - - script: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/ReinstallScalar.bat $(configuration) - displayName: Run Scalar and G4W installers - - - script: git config --global credential.interactive never - displayName: Disable interactive auth - - - script: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/RunFunctionalTests.bat $(configuration) --test-scalar-on-path "--trace2-output=$(Build.ArtifactStagingDirectory)\trace2-event-windows.txt" - displayName: Run functional tests - - - task: PublishTestResults@2 - displayName: Publish functional test results - inputs: - testRunner: NUnit - testResultsFiles: "**\\TestResult*.xml" - searchFolder: $(System.DefaultWorkingDirectory) - testRunTitle: Windows $(configuration) Functional Tests - publishRunAttachments: true - condition: succeededOrFailed() - - - task: PublishBuildArtifacts@1 - displayName: Publish Git trace2 log - inputs: - pathtoPublish: '$(Build.ArtifactStagingDirectory)' - artifactName: trace2-event-windows.txt +steps: + + - task: NuGetToolInstaller@0 + inputs: + versionSpec: '>=5.1' + + - task: UseDotNet@2 + displayName: Use .NET Core SDK 3.0.100 + inputs: + packageType: sdk + version: 3.0.100 + + - task: DownloadBuildArtifacts@0 + displayName: Download functional tests drop + inputs: + buildType: current + downloadType: specific + artifactName: FunctionalTests_$(platformFriendlyName)_$(configuration) + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: Download installers drop + inputs: + buildType: current + downloadType: specific + artifactName: Installers_$(platformFriendlyName)_$(configuration) + downloadPath: $(Build.BinariesDirectory) + + - script: $(Build.BinariesDirectory)/Installers_$(platformFriendlyName)_$(configuration)/InstallScalar.bat + displayName: Install product + + - script: git config --global credential.interactive never + displayName: Disable interactive auth + + - script: $(Build.BinariesDirectory)/FunctionalTests_$(platformFriendlyName)_$(configuration)/src/Scripts/RunFunctionalTests.bat $(configuration) --test-scalar-on-path "--trace2-output=$(Build.ArtifactStagingDirectory)\trace2-event-windows.txt" + displayName: Run functional tests + + - task: PublishTestResults@2 + displayName: Publish functional tests results + inputs: + testRunner: NUnit + testResultsFiles: "**\\TestResult*.xml" + searchFolder: $(System.DefaultWorkingDirectory) + testRunTitle: Windows $(configuration) Functional Tests + publishRunAttachments: true + condition: succeededOrFailed() + + - task: PublishBuildArtifacts@1 + displayName: Publish Git trace2 log + inputs: + pathtoPublish: '$(Build.ArtifactStagingDirectory)' + artifactName: trace2-event-windows.txt condition: failed() diff --git a/.gitignore b/.gitignore index 902835ddb4..3d9413685d 100644 --- a/.gitignore +++ b/.gitignore @@ -226,3 +226,6 @@ ModelManifest.xml # VS Code private directory .vscode/ + +# JetBrains IDEs +.idea/ diff --git a/Dependencies.props b/Dependencies.props new file mode 100644 index 0000000000..7e1c7d8696 --- /dev/null +++ b/Dependencies.props @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Directory.Build.props b/Directory.Build.props index 2129a09159..d9ba02e7d5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,9 +1,61 @@ - - - + - $(MSBuildThisFileDirectory)\..\BuildOutput\$(MSBuildProjectName)\obj + + windows + osx + linux + true + false + + + Debug + + + $(MSBuildThisFileDirectory) + $(RepoPath) + $(RepoPath)..\out\ + $(RepoSrcPath)Scalar.MSBuild\ + + + $(RepoOutPath)$(MSBuildProjectName)\ + $(ProjectOutPath)bin\ + $(ProjectOutPath)obj\ + + + win-x64;osx-x64 + true + true + $(RepoPath)Scalar.ruleset + + + Scalar + Microsoft Corporation (c) + + + 0.2.173.2 + 2.20191106.6-sc + + + Microsoft400 + 8003 + + + + + + + + + + $(AuthenticodeCert) + false + + + false + + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000000..8c9828f413 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,18 @@ + + + + $(ScalarVersion) + $(OutputPath) + + + + + + + + + + + + + diff --git a/Scalar.Build/.gitignore b/Scalar.Build/.gitignore deleted file mode 100644 index 249d139c0d..0000000000 --- a/Scalar.Build/.gitignore +++ /dev/null @@ -1 +0,0 @@ -packages.config diff --git a/Scalar.Build/GenerateG4WNugetReference.cs b/Scalar.Build/GenerateG4WNugetReference.cs deleted file mode 100644 index 89bcdcf25d..0000000000 --- a/Scalar.Build/GenerateG4WNugetReference.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using System; -using System.IO; - -namespace Scalar.PreBuild -{ - public class GenerateG4WNugetReference : Task - { - [Required] - public string GitPackageVersion { get; set; } - - public override bool Execute() - { - this.Log.LogMessage(MessageImportance.High, "Creating packages.config for G4W package version " + this.GitPackageVersion); - - File.WriteAllText( - Path.Combine(Environment.CurrentDirectory, "packages.config"), - string.Format( -@" - - - - -", - this.GitPackageVersion)); - - return true; - } - } -} diff --git a/Scalar.Build/GenerateGitVersionConstants.cs b/Scalar.Build/GenerateGitVersionConstants.cs deleted file mode 100644 index 692e33e9b4..0000000000 --- a/Scalar.Build/GenerateGitVersionConstants.cs +++ /dev/null @@ -1,190 +0,0 @@ -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using System; -using System.IO; -using System.Linq; - -namespace Scalar.PreBuild -{ - public class GenerateGitVersionConstants : Task - { - [Required] - public string GitPackageVersion { get; set; } - - [Required] - public string PackagesPath { get; set; } - - [Required] - public string OutputFile {get; set; } - - [Output] - public string LatestInstaller { get; set; } - - [Output] - public string LatestInstallerFilename { get; set; } - - public override bool Execute() - { - this.Log.LogMessage(MessageImportance.High, "Creating constants for Git package " + this.GitPackageVersion); - - string installerDirectory = Path.Combine( - this.PackagesPath, - "GitForWindows.GVFS.Installer." + this.GitPackageVersion, - "tools"); - - if (!Directory.Exists(installerDirectory)) - { - this.Log.LogError("Git package not found. Re-run your build to allow the package to be downloaded by Visual Studio."); - return false; - } - - this.LatestInstaller = Path.GetFullPath(Directory.EnumerateFiles(installerDirectory).Single()); - this.LatestInstallerFilename = Path.GetFileName(this.LatestInstaller); - GitVersion version; - if (!GitVersion.TryParseInstallerName(this.LatestInstallerFilename, out version)) - { - this.Log.LogError("Unable to parse git version: " + this.LatestInstallerFilename); - return false; - } - - this.Log.LogMessage(MessageImportance.High, "Found Git version " + version.ToString()); - - string projectOutputPath = Path.GetDirectoryName(this.OutputFile); - if (!Directory.Exists(projectOutputPath)) - { - Directory.CreateDirectory(projectOutputPath); - } - - File.WriteAllText( - this.OutputFile, - string.Format( -@"// This file is auto-generated by Scalar.PreBuild.GenerateGitVersionConstants. Any changes made directly in this file will be lost. -using Scalar.Common.Git; - -namespace Scalar.Common -{{ - public static partial class ScalarConstants - {{ - public static readonly GitVersion SupportedGitVersion = new GitVersion({0}, {1}, {2}, ""{3}"", {4}, {5}); - }} -}}", - version.Major, - version.Minor, - version.Build, - version.Platform, - version.Revision, - version.MinorRevision)); - - return true; - } - - // This class was partially copied from Scalar.Common.Git.GitVersion for the parsing - private class GitVersion - { - private GitVersion(int major, int minor, int build, string platform, int revision, int minorRevision) - { - this.Major = major; - this.Minor = minor; - this.Build = build; - this.Platform = platform; - this.Revision = revision; - this.MinorRevision = minorRevision; - } - - public int Major { get; private set; } - public int Minor { get; private set; } - public string Platform { get; private set; } - public int Build { get; private set; } - public int Revision { get; private set; } - public int MinorRevision { get; private set; } - - public static bool TryParseInstallerName(string input, out GitVersion version) - { - // Installer name is of the form - // Git-2.14.1.scalar.1.1.gb16030b-64-bit.exe - - version = null; - - if (!input.StartsWith("Git-", StringComparison.InvariantCultureIgnoreCase)) - { - return false; - } - - if (!input.EndsWith("-64-bit.exe", StringComparison.InvariantCultureIgnoreCase)) - { - return false; - } - - return TryParseVersion(input.Substring(4, input.Length - 15), out version); - } - - private static bool TryParseVersion(string input, out GitVersion version) - { - version = null; - int major, minor, build, revision, minorRevision; - - if (string.IsNullOrWhiteSpace(input)) - { - return false; - } - - string[] parsedComponents = input.Split(new char[] { '.' }); - int parsedComponentsLength = parsedComponents.Length; - if (parsedComponentsLength < 5) - { - return false; - } - - if (!TryParseComponent(parsedComponents[0], out major)) - { - return false; - } - - if (!TryParseComponent(parsedComponents[1], out minor)) - { - return false; - } - - if (!TryParseComponent(parsedComponents[2], out build)) - { - return false; - } - - if (!TryParseComponent(parsedComponents[4], out revision)) - { - return false; - } - - if (parsedComponentsLength < 6 || !TryParseComponent(parsedComponents[5], out minorRevision)) - { - minorRevision = 0; - } - - string platform = parsedComponents[3]; - - version = new GitVersion(major, minor, build, platform, revision, minorRevision); - return true; - } - - public override string ToString() - { - return string.Format("{0}.{1}.{2}.{3}.{4}.{5}", this.Major, this.Minor, this.Build, this.Platform, this.Revision, this.MinorRevision); - } - - private static bool TryParseComponent(string component, out int parsedComponent) - { - if (!int.TryParse(component, out parsedComponent)) - { - return false; - } - - if (parsedComponent < 0) - { - return false; - } - - return true; - } - } - } -} diff --git a/Scalar.Build/GenerateInstallScripts.cs b/Scalar.Build/GenerateInstallScripts.cs deleted file mode 100644 index 968bcc6532..0000000000 --- a/Scalar.Build/GenerateInstallScripts.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using System.IO; -using System.Text; - -namespace Scalar.PreBuild -{ - public class GenerateInstallScripts : Task - { - [Required] - public string GitInstallerFilename { get; set; } - - [Required] - public string ScalarSetupFilename { get; set; } - - [Required] - public string GitInstallBatPath { get; set; } - - [Required] - public string ScalarInstallBatPath { get; set; } - - [Required] - public string UnifiedInstallBatPath { get; set; } - - public override bool Execute() - { - this.Log.LogMessage(MessageImportance.High, "Creating install scripts for " + this.GitInstallerFilename); - - File.WriteAllText( - this.GitInstallBatPath, - this.GetGitInstallCommand()); - - File.WriteAllText( - this.ScalarInstallBatPath, - this.GetScalarInstallCommand()); - - StringBuilder sb = new StringBuilder(); - sb.AppendLine("REM AUTOGENERATED DO NOT EDIT"); - sb.AppendLine(); - sb.AppendLine(this.GetGitInstallCommand()); - sb.AppendLine(); - sb.AppendLine(this.GetScalarInstallCommand()); - - File.WriteAllText( - this.UnifiedInstallBatPath, - sb.ToString()); - - return true; - } - - public string GetGitInstallCommand() - { - return "%~dp0\\" + this.GitInstallerFilename + @" /DIR=""C:\Program Files\Git"" /NOICONS /COMPONENTS=""ext,ext\shellhere,ext\guihere,assoc,assoc_sh"" /GROUP=""Git"" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART"; - } - - public string GetScalarInstallCommand() - { - return "%~dp0\\" + this.ScalarSetupFilename + " /VERYSILENT /SUPPRESSMSGBOXES /NORESTART"; - } - } -} diff --git a/Scalar.Build/GenerateScalarInstallersNuspec.cs b/Scalar.Build/GenerateScalarInstallersNuspec.cs deleted file mode 100644 index ab3da38c56..0000000000 --- a/Scalar.Build/GenerateScalarInstallersNuspec.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using System.IO; - -namespace Scalar.PreBuild -{ - public class GenerateScalarInstallersNuspec : Task - { - [Required] - public string ScalarSetupPath { get; set; } - - [Required] - public string GitPackageVersion { get; set; } - - [Required] - public string PackagesPath { get; set; } - - [Required] - public string OutputFile { get; set; } - - public override bool Execute() - { - this.Log.LogMessage(MessageImportance.High, "Generating Scalar.Installers.nuspec"); - - this.ScalarSetupPath = Path.GetFullPath(this.ScalarSetupPath); - this.PackagesPath = Path.GetFullPath(this.PackagesPath); - - File.WriteAllText( - this.OutputFile, - string.Format( -@" - - - Scalar.Installers - $ScalarVersion$ - Microsoft - false - Scalar and G4W installers - - - - - - -", - this.ScalarSetupPath, - this.PackagesPath, - this.GitPackageVersion)); - - return true; - } - } -} diff --git a/Scalar.Build/GenerateVersionInfo.cs b/Scalar.Build/GenerateVersionInfo.cs deleted file mode 100644 index 1895ecde1e..0000000000 --- a/Scalar.Build/GenerateVersionInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using System.IO; - -namespace Scalar.PreBuild -{ - public class GenerateVersionInfo : Task - { - [Required] - public string Version { get; set; } - - [Required] - public string BuildOutputPath { get; set; } - - [Required] - public string AssemblyVersion { get; set; } - - [Required] - public string VersionHeader { get; set; } - - public override bool Execute() - { - this.Log.LogMessage(MessageImportance.High, "Creating version files"); - - EnsureParentDirectoryExistsFor(this.AssemblyVersion); - File.WriteAllText( - this.AssemblyVersion, - string.Format( -@"using System.Reflection; - -[assembly: AssemblyVersion(""{0}"")] -[assembly: AssemblyFileVersion(""{0}"")] -", - this.Version)); - - string commaDelimetedVersion = this.Version.Replace('.', ','); - EnsureParentDirectoryExistsFor(this.VersionHeader); - File.WriteAllText( - this.VersionHeader, - string.Format( -@" -#define SCALAR_FILE_VERSION {0} -#define SCALAR_FILE_VERSION_STRING ""{1}"" -#define SCALAR_PRODUCT_VERSION {0} -#define SCALAR_PRODUCT_VERSION_STRING ""{1}"" -", - commaDelimetedVersion, - this.Version)); - - return true; - } - - private void EnsureParentDirectoryExistsFor(string filename) - { - string directory = Path.GetDirectoryName(filename); - if (!Directory.Exists(directory)) - { - Directory.CreateDirectory(directory); - } - - } - } -} diff --git a/Scalar.Build/Scalar.PreBuild.csproj b/Scalar.Build/Scalar.PreBuild.csproj deleted file mode 100644 index cebfb95367..0000000000 --- a/Scalar.Build/Scalar.PreBuild.csproj +++ /dev/null @@ -1,213 +0,0 @@ - - - - - - {A4984251-840E-4622-AD0C-66DFCE2B2574} - Library - Properties - Scalar.PreBuild - Scalar.PreBuild - v4.6.1 - 512 - - - true - DEBUG;TRACE - full - x64 - prompt - MinimumRecommendedRules.ruleset - true - - - TRACE - true - pdbonly - x64 - prompt - MinimumRecommendedRules.ruleset - - - - - - - - - - - - Designer - - - Designer - - - Designer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SetupScalar.$(ScalarVersion).exe - $(BuildOutputDir)\Scalar.Installer.Windows\bin\x64\$(Configuration)\SetupScalar.$(ScalarVersion).exe - $(BuildOutputDir)\Scalar.Build\ - $(OutDir)ScalarConstants.GitVersion.cs - $(OutDir)InstallG4W.bat - $(OutDir)InstallScalar.bat - $(OutDir)InstallProduct.bat - $(OutDir)Scalar.Installers.nuspec - $(BuildOutputDir)\CommonAssemblyVersion.cs - $(BuildOutputDir)\CommonVersionHeader.h - $(BuildOutputDir)\restore.timestamp - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Scalar.Build/Scalar.cpp.props b/Scalar.Build/Scalar.cpp.props deleted file mode 100644 index 9b2d260549..0000000000 --- a/Scalar.Build/Scalar.cpp.props +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - $(BuildOutputDir)\$(MSBuildProjectName)\bin\$(Platform)\$(Configuration)\ - $(BuildOutputDir)\$(MSBuildProjectName)\intermediate\$(Platform)\$(Configuration)\ - - - diff --git a/Scalar.Build/Scalar.cs.props b/Scalar.Build/Scalar.cs.props deleted file mode 100644 index 08537feae6..0000000000 --- a/Scalar.Build/Scalar.cs.props +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - $(BuildOutputDir)\$(MSBuildProjectName)\bin\$(Platform)\$(Configuration)\ - $(BuildOutputDir)\$(MSBuildProjectName)\obj\$(Platform)\$(Configuration)\ - $(BuildOutputDir)\$(MSBuildProjectName)\intermediate\$(Platform)\$(Configuration)\ - - - - true - $(MSBuildThisFileDirectory)\Scalar.ruleset - false - - - - - CommonAssemblyVersion.cs - - - - - $(DefaultItemExcludes);StyleCop.Cache;TestResults.xml - - - diff --git a/Scalar.Build/Scalar.props b/Scalar.Build/Scalar.props deleted file mode 100644 index 5ccd5698cb..0000000000 --- a/Scalar.Build/Scalar.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - 0.2.173.2 - 2.20191106.6-sc - - - - Debug - x64 - ..\ - $(SolutionDir)..\BuildOutput - $(SolutionDir)..\packages - - - diff --git a/Scalar.Common/DirectoryEx.cs b/Scalar.Common/DirectoryEx.cs new file mode 100644 index 0000000000..8e10c24108 --- /dev/null +++ b/Scalar.Common/DirectoryEx.cs @@ -0,0 +1,27 @@ +using System.IO; +using System.Security.AccessControl; + +namespace Scalar.Common +{ + public static class DirectoryEx + { + public static DirectorySecurity GetAccessControl(string path) + { + var di = new DirectoryInfo(path); + return di.GetAccessControl(); + } + + public static void SetAccessControl(string path, DirectorySecurity security) + { + var di = new DirectoryInfo(path); + di.SetAccessControl(security); + } + + public static void CreateDirectory(string path, DirectorySecurity security) + { + var di = new DirectoryInfo(path); + di.Create(); + di.SetAccessControl(security); + } + } +} diff --git a/Scalar.Common/AssemblyInfo.cs b/Scalar.Common/InternalsVisibleTo.cs similarity index 60% rename from Scalar.Common/AssemblyInfo.cs rename to Scalar.Common/InternalsVisibleTo.cs index 514010382c..ac7bc57a09 100644 --- a/Scalar.Common/AssemblyInfo.cs +++ b/Scalar.Common/InternalsVisibleTo.cs @@ -1,4 +1,3 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Scalar.UnitTests")] -[assembly: InternalsVisibleTo("Scalar.UnitTests.Windows")] diff --git a/Scalar.Common/NuGetUpgrade/NuGetFeed.cs b/Scalar.Common/NuGetUpgrade/NuGetFeed.cs index 162ec1ca2f..5669ef1909 100644 --- a/Scalar.Common/NuGetUpgrade/NuGetFeed.cs +++ b/Scalar.Common/NuGetUpgrade/NuGetFeed.cs @@ -169,7 +169,8 @@ private static PackageSourceCredential BuildCredentialsFromPAT(string personalAc "VfsForGitNugetUpgrader", "PersonalAccessToken", personalAccessToken, - storePasswordInClearText: storePasswordInClearText); + storePasswordInClearText: storePasswordInClearText, + validAuthenticationTypesText: null); // null means "all" } private void SetSourceRepository() diff --git a/Scalar.Platform.Mac/DiskLayoutUpgrades/MacDiskLayoutUpgradeData.cs b/Scalar.Common/Platforms/Mac/DiskLayoutUpgrades/MacDiskLayoutUpgradeData.cs similarity index 100% rename from Scalar.Platform.Mac/DiskLayoutUpgrades/MacDiskLayoutUpgradeData.cs rename to Scalar.Common/Platforms/Mac/DiskLayoutUpgrades/MacDiskLayoutUpgradeData.cs diff --git a/Scalar.Platform.Mac/MacDaemonController.cs b/Scalar.Common/Platforms/Mac/MacDaemonController.cs similarity index 100% rename from Scalar.Platform.Mac/MacDaemonController.cs rename to Scalar.Common/Platforms/Mac/MacDaemonController.cs diff --git a/Scalar.Platform.Mac/MacFileBasedLock.cs b/Scalar.Common/Platforms/Mac/MacFileBasedLock.cs similarity index 100% rename from Scalar.Platform.Mac/MacFileBasedLock.cs rename to Scalar.Common/Platforms/Mac/MacFileBasedLock.cs diff --git a/Scalar.Platform.Mac/MacFileSystem.cs b/Scalar.Common/Platforms/Mac/MacFileSystem.cs similarity index 100% rename from Scalar.Platform.Mac/MacFileSystem.cs rename to Scalar.Common/Platforms/Mac/MacFileSystem.cs diff --git a/Scalar.Platform.Mac/MacPlatform.Shared.cs b/Scalar.Common/Platforms/Mac/MacPlatform.Shared.cs similarity index 100% rename from Scalar.Platform.Mac/MacPlatform.Shared.cs rename to Scalar.Common/Platforms/Mac/MacPlatform.Shared.cs diff --git a/Scalar.Platform.Mac/MacPlatform.cs b/Scalar.Common/Platforms/Mac/MacPlatform.cs similarity index 100% rename from Scalar.Platform.Mac/MacPlatform.cs rename to Scalar.Common/Platforms/Mac/MacPlatform.cs diff --git a/Scalar.Platform.Mac/MacProductUpgraderPlatformStrategy.cs b/Scalar.Common/Platforms/Mac/MacProductUpgraderPlatformStrategy.cs similarity index 100% rename from Scalar.Platform.Mac/MacProductUpgraderPlatformStrategy.cs rename to Scalar.Common/Platforms/Mac/MacProductUpgraderPlatformStrategy.cs diff --git a/Scalar.Platform.POSIX/POSIXFileSystem.Shared.cs b/Scalar.Common/Platforms/POSIX/POSIXFileSystem.Shared.cs similarity index 100% rename from Scalar.Platform.POSIX/POSIXFileSystem.Shared.cs rename to Scalar.Common/Platforms/POSIX/POSIXFileSystem.Shared.cs diff --git a/Scalar.Platform.POSIX/POSIXFileSystem.cs b/Scalar.Common/Platforms/POSIX/POSIXFileSystem.cs similarity index 100% rename from Scalar.Platform.POSIX/POSIXFileSystem.cs rename to Scalar.Common/Platforms/POSIX/POSIXFileSystem.cs diff --git a/Scalar.Platform.POSIX/POSIXGitInstallation.cs b/Scalar.Common/Platforms/POSIX/POSIXGitInstallation.cs similarity index 100% rename from Scalar.Platform.POSIX/POSIXGitInstallation.cs rename to Scalar.Common/Platforms/POSIX/POSIXGitInstallation.cs diff --git a/Scalar.Platform.POSIX/POSIXPlatform.Shared.cs b/Scalar.Common/Platforms/POSIX/POSIXPlatform.Shared.cs similarity index 100% rename from Scalar.Platform.POSIX/POSIXPlatform.Shared.cs rename to Scalar.Common/Platforms/POSIX/POSIXPlatform.Shared.cs diff --git a/Scalar.Platform.POSIX/POSIXPlatform.cs b/Scalar.Common/Platforms/POSIX/POSIXPlatform.cs similarity index 100% rename from Scalar.Platform.POSIX/POSIXPlatform.cs rename to Scalar.Common/Platforms/POSIX/POSIXPlatform.cs diff --git a/Scalar.Common/Platforms/PlatformLoader.cs b/Scalar.Common/Platforms/PlatformLoader.cs new file mode 100644 index 0000000000..73a1f60eb2 --- /dev/null +++ b/Scalar.Common/Platforms/PlatformLoader.cs @@ -0,0 +1,27 @@ +using System; +using System.Runtime.InteropServices; +using Scalar.Common; +using Scalar.Platform.Mac; +using Scalar.Platform.Windows; + +namespace Scalar.PlatformLoader +{ + public static class ScalarPlatformLoader + { + public static void Initialize() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + ScalarPlatform.Register(new WindowsPlatform()); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + ScalarPlatform.Register(new MacPlatform()); + } + else + { + throw new NotImplementedException(); + } + } + } +} diff --git a/Scalar.Platform.Windows/CurrentUser.cs b/Scalar.Common/Platforms/Windows/CurrentUser.cs similarity index 100% rename from Scalar.Platform.Windows/CurrentUser.cs rename to Scalar.Common/Platforms/Windows/CurrentUser.cs diff --git a/Scalar.Platform.Windows/DiskLayoutUpgrades/WindowsDiskLayoutUpgradeData.cs b/Scalar.Common/Platforms/Windows/DiskLayoutUpgrades/WindowsDiskLayoutUpgradeData.cs similarity index 100% rename from Scalar.Platform.Windows/DiskLayoutUpgrades/WindowsDiskLayoutUpgradeData.cs rename to Scalar.Common/Platforms/Windows/DiskLayoutUpgrades/WindowsDiskLayoutUpgradeData.cs diff --git a/Scalar.Common/Platforms/Windows/NamedPipeServerStreamEx.cs b/Scalar.Common/Platforms/Windows/NamedPipeServerStreamEx.cs new file mode 100644 index 0000000000..3b93ea0032 --- /dev/null +++ b/Scalar.Common/Platforms/Windows/NamedPipeServerStreamEx.cs @@ -0,0 +1,191 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.IO.Pipes; +using System.Runtime.InteropServices; +using System.Security.AccessControl; +using System.Security.Principal; +using Microsoft.Win32.SafeHandles; + +namespace Scalar.Platform.Windows +{ + /// + /// The overload of NamedPipeServerStream.ctor with the PipeSecurity parameter was removed + /// in .NET Standard and .NET Core. + /// + /// Unfortunately, the default constructor does not provide WRITE_DAC, so attempting + /// to use SetAccessControl after construction will always fail. + /// (https://github.com/dotnet/corefx/issues/31190) + /// + /// Since the PipeAccessRights parameter was also removed, we cannot pass the + /// PipeAccessRights.ChangePermissions option either to provide WRITE_DAC to the pipe. + /// (https://github.com/dotnet/corefx/issues/24040) + /// + /// Instead we must manually create the underlying pipe handle with the correct security + /// attributes up-front, and then pass this native handle to the NamedPipeServerStream + /// managed object. Depressingly, the .NET Core codebase already contains all the methods + /// we need to call to do this, but they are all internal/private. We include a copy of + /// the minimum required code here to reinstate the removed constructor and functionality. + /// + /// All the code below was taken from the .NET Core codebase with comments pointing to + /// the source file and version. + /// + internal static class NamedPipeServerStreamEx + { + // https://github.com/dotnet/corefx/blob/e753ecfe12d6af9b7fec5dee154395e7d29caed9/src/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.cs#L20 + private const int MaxAllowedServerInstances = -1; + + // https://github.com/dotnet/corefx/blob/d3911035f2ba3eb5c44310342cc1d654e42aa316/src/Common/src/Interop/Windows/Kernel32/Interop.FileOperations.cs#L21 + private const uint FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000; + + // https://github.com/dotnet/corefx/blob/d3911035f2ba3eb5c44310342cc1d654e42aa316/src/Common/src/CoreLib/Interop/Windows/Interop.BOOL.cs + private enum BOOL : int + { + FALSE = 0, + TRUE = 1, + } + + // https://github.com/dotnet/corefx/blob/d3911035f2ba3eb5c44310342cc1d654e42aa316/src/Common/src/CoreLib/Interop/Windows/Kernel32/Interop.SECURITY_ATTRIBUTES.cs + [StructLayout(LayoutKind.Sequential)] + private struct SECURITY_ATTRIBUTES + { + internal uint nLength; + internal IntPtr lpSecurityDescriptor; + internal BOOL bInheritHandle; + } + + // https://github.com/dotnet/corefx/blob/8c5260061b11323dfd97fbab614d54402405513f/src/Common/src/Interop/Windows/Kernel32/Interop.CreateNamedPipe.cs + [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, EntryPoint = "CreateNamedPipeW")] + private static extern SafePipeHandle CreateNamedPipe( + string pipeName, + int openMode, + int pipeMode, + int maxInstances, + int outBufferSize, + int inBufferSize, + int defaultTimeout, + ref SECURITY_ATTRIBUTES securityAttributes); + + // https://github.com/dotnet/corefx/blob/8c5260061b11323dfd97fbab614d54402405513f/src/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs#L415-L435 + private static unsafe SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability, PipeSecurity pipeSecurity, ref GCHandle pinningHandle) + { + SECURITY_ATTRIBUTES secAttrs = default; + secAttrs.nLength = (uint)sizeof(SECURITY_ATTRIBUTES); + + if ((inheritability & HandleInheritability.Inheritable) != 0) + { + secAttrs.bInheritHandle = BOOL.TRUE; + } + + if (pipeSecurity != null) + { + byte[] securityDescriptor = pipeSecurity.GetSecurityDescriptorBinaryForm(); + pinningHandle = GCHandle.Alloc(securityDescriptor, GCHandleType.Pinned); + fixed (byte* pSecurityDescriptor = securityDescriptor) + { + secAttrs.lpSecurityDescriptor = (IntPtr)pSecurityDescriptor; + } + } + + return secAttrs; + } + + // https://github.com/dotnet/corefx/blob/e753ecfe12d6af9b7fec5dee154395e7d29caed9/src/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Windows.cs#L31-L108 + private static SafePipeHandle CreatePipeHandle(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, + PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, + PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights) + { + Debug.Assert(pipeName != null && pipeName.Length != 0, "fullPipeName is null or empty"); + Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction"); + Debug.Assert(inBufferSize >= 0, "inBufferSize is negative"); + Debug.Assert(outBufferSize >= 0, "outBufferSize is negative"); + Debug.Assert((maxNumberOfServerInstances >= 1 && maxNumberOfServerInstances <= 254) || (maxNumberOfServerInstances == MaxAllowedServerInstances), "maxNumberOfServerInstances is invalid"); + Debug.Assert(transmissionMode >= PipeTransmissionMode.Byte && transmissionMode <= PipeTransmissionMode.Message, "transmissionMode is out of range"); + + string fullPipeName = Path.GetFullPath(@"\\.\pipe\" + pipeName); + + // Make sure the pipe name isn't one of our reserved names for anonymous pipes. + if (string.Equals(fullPipeName, @"\\.\pipe\anonymous", StringComparison.OrdinalIgnoreCase)) + { + throw new ArgumentOutOfRangeException(nameof(pipeName)); + } + + if ((options & PipeOptions.CurrentUserOnly) != 0) + { + Debug.Assert(pipeSecurity == null); + + using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent()) + { + SecurityIdentifier identifier = currentIdentity.Owner; + + // Grant full control to the owner so multiple servers can be opened. + // Full control is the default per MSDN docs for CreateNamedPipe. + PipeAccessRule rule = new PipeAccessRule(identifier, PipeAccessRights.FullControl, AccessControlType.Allow); + pipeSecurity = new PipeSecurity(); + + pipeSecurity.AddAccessRule(rule); + pipeSecurity.SetOwner(identifier); + } + + // PipeOptions.CurrentUserOnly is special since it doesn't match directly to a corresponding Win32 valid flag. + // Remove it, while keeping others untouched since historically this has been used as a way to pass flags to CreateNamedPipe + // that were not defined in the enumeration. + options &= ~PipeOptions.CurrentUserOnly; + } + + int openMode = (int) direction | + (int) (maxNumberOfServerInstances == 1 ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0) | + (int) options | + (int) additionalAccessRights; + + // We automatically set the ReadMode to match the TransmissionMode. + int pipeModes = (int)transmissionMode << 2 | (int)transmissionMode << 1; + + // Convert -1 to 255 to match win32 (we asserted that it is between -1 and 254). + if (maxNumberOfServerInstances == MaxAllowedServerInstances) + { + maxNumberOfServerInstances = 255; + } + + var pinningHandle = new GCHandle(); + try + { + SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability, pipeSecurity, ref pinningHandle); + SafePipeHandle handle = CreateNamedPipe(fullPipeName, openMode, pipeModes, + maxNumberOfServerInstances, outBufferSize, inBufferSize, 0, ref secAttrs); + + if (handle.IsInvalid) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + return handle; + } + finally + { + if (pinningHandle.IsAllocated) + { + pinningHandle.Free(); + } + } + } + + /// + /// Create a named pipe server stream with pipe security options. + /// + public static NamedPipeServerStream Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, + PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, + PipeSecurity pipeSecurity, HandleInheritability inheritability) + { + SafePipeHandle handle = CreatePipeHandle(pipeName, direction, maxNumberOfServerInstances, + transmissionMode, options, inBufferSize, outBufferSize, + pipeSecurity, inheritability, (PipeAccessRights)0); + + bool isAsync = (options & PipeOptions.Asynchronous) != 0; + bool isConnected = false; + + return new NamedPipeServerStream(direction, isAsync, isConnected, handle); + } + } +} diff --git a/Scalar.Platform.Windows/WindowsFileBasedLock.cs b/Scalar.Common/Platforms/Windows/WindowsFileBasedLock.cs similarity index 100% rename from Scalar.Platform.Windows/WindowsFileBasedLock.cs rename to Scalar.Common/Platforms/Windows/WindowsFileBasedLock.cs diff --git a/Scalar.Platform.Windows/WindowsFileSystem.Shared.cs b/Scalar.Common/Platforms/Windows/WindowsFileSystem.Shared.cs similarity index 100% rename from Scalar.Platform.Windows/WindowsFileSystem.Shared.cs rename to Scalar.Common/Platforms/Windows/WindowsFileSystem.Shared.cs diff --git a/Scalar.Platform.Windows/WindowsFileSystem.cs b/Scalar.Common/Platforms/Windows/WindowsFileSystem.cs similarity index 96% rename from Scalar.Platform.Windows/WindowsFileSystem.cs rename to Scalar.Common/Platforms/Windows/WindowsFileSystem.cs index e533ba27fc..36ca3a4e93 100644 --- a/Scalar.Platform.Windows/WindowsFileSystem.cs +++ b/Scalar.Common/Platforms/Windows/WindowsFileSystem.cs @@ -127,7 +127,7 @@ public bool TryCreateDirectoryWithAdminAndUserModifyPermissions(string directory AddUsersAccessRulesToDirectorySecurity(directorySecurity, grantUsersModifyPermissions: true); AddAdminAccessRulesToDirectorySecurity(directorySecurity); - Directory.CreateDirectory(directoryPath, directorySecurity); + DirectoryEx.CreateDirectory(directoryPath, directorySecurity); } catch (Exception e) when (e is IOException || e is UnauthorizedAccessException || @@ -149,7 +149,7 @@ public bool TryCreateOrUpdateDirectoryToAdminModifyPermissions(ITracer tracer, s DirectorySecurity directorySecurity; if (Directory.Exists(directoryPath)) { - directorySecurity = Directory.GetAccessControl(directoryPath); + directorySecurity = DirectoryEx.GetAccessControl(directoryPath); } else { @@ -164,10 +164,10 @@ public bool TryCreateOrUpdateDirectoryToAdminModifyPermissions(ITracer tracer, s AddUsersAccessRulesToDirectorySecurity(directorySecurity, grantUsersModifyPermissions: false); AddAdminAccessRulesToDirectorySecurity(directorySecurity); - Directory.CreateDirectory(directoryPath, directorySecurity); + DirectoryEx.CreateDirectory(directoryPath, directorySecurity); // Ensure the ACLs are set correctly if the directory already existed - Directory.SetAccessControl(directoryPath, directorySecurity); + DirectoryEx.SetAccessControl(directoryPath, directorySecurity); } catch (Exception e) when (e is IOException || e is SystemException) { diff --git a/Scalar.Platform.Windows/WindowsGitInstallation.cs b/Scalar.Common/Platforms/Windows/WindowsGitInstallation.cs similarity index 100% rename from Scalar.Platform.Windows/WindowsGitInstallation.cs rename to Scalar.Common/Platforms/Windows/WindowsGitInstallation.cs diff --git a/Scalar.Platform.Windows/WindowsPhysicalDiskInfo.cs b/Scalar.Common/Platforms/Windows/WindowsPhysicalDiskInfo.cs similarity index 100% rename from Scalar.Platform.Windows/WindowsPhysicalDiskInfo.cs rename to Scalar.Common/Platforms/Windows/WindowsPhysicalDiskInfo.cs diff --git a/Scalar.Platform.Windows/WindowsPlatform.Shared.cs b/Scalar.Common/Platforms/Windows/WindowsPlatform.Shared.cs similarity index 100% rename from Scalar.Platform.Windows/WindowsPlatform.Shared.cs rename to Scalar.Common/Platforms/Windows/WindowsPlatform.Shared.cs diff --git a/Scalar.Platform.Windows/WindowsPlatform.cs b/Scalar.Common/Platforms/Windows/WindowsPlatform.cs similarity index 98% rename from Scalar.Platform.Windows/WindowsPlatform.cs rename to Scalar.Common/Platforms/Windows/WindowsPlatform.cs index 2b6f02bf4e..4373ae2d18 100644 --- a/Scalar.Platform.Windows/WindowsPlatform.cs +++ b/Scalar.Common/Platforms/Windows/WindowsPlatform.cs @@ -95,7 +95,7 @@ public override void InitializeEnlistmentACLs(string enlistmentPath) // GENERIC_EXECUTE // GENERIC_WRITE // GENERIC_READ - DirectorySecurity rootSecurity = Directory.GetAccessControl(enlistmentPath); + DirectorySecurity rootSecurity = DirectoryEx.GetAccessControl(enlistmentPath); AccessRule authenticatedUsersAccessRule = rootSecurity.AccessRuleFactory( new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), unchecked((int)(NativeMethods.FileAccess.DELETE | NativeMethods.FileAccess.GENERIC_EXECUTE | NativeMethods.FileAccess.GENERIC_WRITE | NativeMethods.FileAccess.GENERIC_READ)), @@ -107,7 +107,7 @@ public override void InitializeEnlistmentACLs(string enlistmentPath) // The return type of the AccessRuleFactory method is the base class, AccessRule, but the return value can be cast safely to the derived class. // https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemsecurity.accessrulefactory(v=vs.110).aspx rootSecurity.AddAccessRule((FileSystemAccessRule)authenticatedUsersAccessRule); - Directory.SetAccessControl(enlistmentPath, rootSecurity); + DirectoryEx.SetAccessControl(enlistmentPath, rootSecurity); } public override string GetOSVersionInformation() @@ -149,6 +149,7 @@ public override void StartBackgroundScalarProcess(ITracer tracer, string program programArguments = string.Join(" ", args.Select(arg => arg.Contains(' ') ? "\"" + arg + "\"" : arg)); ProcessStartInfo processInfo = new ProcessStartInfo(programName, programArguments); processInfo.WindowStyle = ProcessWindowStyle.Hidden; + processInfo.UseShellExecute = true; Process executingProcess = new Process(); executingProcess.StartInfo = processInfo; @@ -177,7 +178,7 @@ public override NamedPipeServerStream CreatePipeByName(string pipeName) security.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.CreatorOwnerSid, null), PipeAccessRights.FullControl, AccessControlType.Allow)); security.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), PipeAccessRights.FullControl, AccessControlType.Allow)); - NamedPipeServerStream pipe = new NamedPipeServerStream( + NamedPipeServerStream pipe = NamedPipeServerStreamEx.Create( pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, diff --git a/Scalar.Platform.Windows/WindowsProductUpgraderPlatformStrategy.cs b/Scalar.Common/Platforms/Windows/WindowsProductUpgraderPlatformStrategy.cs similarity index 100% rename from Scalar.Platform.Windows/WindowsProductUpgraderPlatformStrategy.cs rename to Scalar.Common/Platforms/Windows/WindowsProductUpgraderPlatformStrategy.cs diff --git a/Scalar.Common/Properties/AssemblyInfo.cs b/Scalar.Common/Properties/AssemblyInfo.cs deleted file mode 100644 index 4e841363cf..0000000000 --- a/Scalar.Common/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Scalar.Common")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Scalar.Common")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2019")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("9ea6ff63-6bb0-4440-9bfb-0ae79a8f9ba9")] diff --git a/Scalar.Common/Scalar.Common.csproj b/Scalar.Common/Scalar.Common.csproj index 0f694e3d05..fa393c79a5 100644 --- a/Scalar.Common/Scalar.Common.csproj +++ b/Scalar.Common/Scalar.Common.csproj @@ -1,34 +1,40 @@ - - - + - netcoreapp2.1;netstandard2.0 - x64 + netcoreapp3.0 true - true - - - $(ScalarVersion) - - - $(ScalarVersion) + scalar.common - + + + + + + - - - - - all - - - - - - - + + + + + + + + + + + + + + + + diff --git a/Scalar.Common/ServerScalarConfig.cs b/Scalar.Common/ServerScalarConfig.cs index 1600e807ff..5336f11eb7 100644 --- a/Scalar.Common/ServerScalarConfig.cs +++ b/Scalar.Common/ServerScalarConfig.cs @@ -7,9 +7,9 @@ namespace Scalar.Common { public class ServerScalarConfig { - public IEnumerable AllowedScalarClientVersions { get; set; } + public IList AllowedScalarClientVersions { get; set; } - public IEnumerable CacheServers { get; set; } = Enumerable.Empty(); + public IList CacheServers { get; set; } = new CacheServerInfo[0]; public class VersionRange { diff --git a/Scripts/Mac/InstallScalarTemplate.sh b/Scalar.Distribution.Mac/InstallScalar.template.sh old mode 100644 new mode 100755 similarity index 62% rename from Scripts/Mac/InstallScalarTemplate.sh rename to Scalar.Distribution.Mac/InstallScalar.template.sh index 3023110689..e7ce580065 --- a/Scripts/Mac/InstallScalarTemplate.sh +++ b/Scalar.Distribution.Mac/InstallScalar.template.sh @@ -1,11 +1,9 @@ #!/bin/sh # --------------------------------------------------------- -# ScalarInstall.sh +# InstallScalar.sh # # Description: Main logic for installing Scalar and supporting -# Components. Before this script can be run, the -# necessary version configuration variables below -# must be set. +# Components. # --------------------------------------------------------- set -e @@ -14,12 +12,24 @@ GIT_INSTALLER_PKG="##GIT_INSTALLER_PKG_PLACEHOLDER##" GCM_CORE_INSTALLER_PKG="##GCM_CORE_INSTALLER_PKG_PLACEHOLDER##" SCALAR_INSTALLER_PKG="##SCALAR_INSTALLER_PKG_PLACEHOLDER##" -SCRIPTDIR="$(dirname ${BASH_SOURCE[0]})" +SCALAR_DISTRIBUTION_ROOT="$(dirname ${BASH_SOURCE[0]})" -## Argument 1 is the directory containing the sources for installation -## Assume it is the current directory. -SCALAR_DISTRIBUTION_ROOT=$1 -SCALAR_DISTRIBUTION_ROOT=${SCALAR_DISTRIBUTION_ROOT:-"$SCRIPTDIR"} +# Default installation flags +INSTALL_WATCHMAN=1 + +# Check the presence of known installation flags +for arg in "$@" +do + if [ "$arg" = "--no-watchman" ]; then + INSTALL_WATCHMAN=0 + fi +done + +# Check if any of the installation options require Homebrew +REQUIRE_HOMEBREW=0 +if [ $INSTALL_WATCHMAN -eq 1 ]; then + REQUIRE_HOMEBREW=1 +fi echo "" echo "Welcome - running Scalar installation script" @@ -50,24 +60,27 @@ echo "" echo "==============================" echo "Checking prerequisites..." -## Check for brew installation -BREW_INSTALLED=0 - -if which -s brew; then - BREW_INSTALLED=1 -else +if [ $REQUIRE_HOMEBREW -eq 1 ]; then + ## Check for brew installation BREW_INSTALLED=0 -fi -if [ $BREW_INSTALLED -eq 0 ]; then - echo "" - echo "Homebrew is required to install watchman. Please install Homebrew with the following command and run the installation script again:" - echo "/usr/bin/ruby -e \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"" - exit 1 -else - echo "brew already installed!" + if which -s brew; then + BREW_INSTALLED=1 + else + BREW_INSTALLED=0 + fi + + if [ $BREW_INSTALLED -eq 0 ]; then + echo "" + echo "Homebrew is required to install watchman. Please install Homebrew with the following command and run the installation script again:" + echo "/usr/bin/ruby -e \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"" + exit 1 + else + echo "Homebrew already installed!" + fi fi + # Install Git echo "" echo "==============================" @@ -80,27 +93,26 @@ echo "==============================" echo "Installing GCM Core" sudo /usr/sbin/installer -pkg "$SCALAR_DISTRIBUTION_ROOT/GCM/$GCM_CORE_INSTALLER_PKG" -target / -# Configure GCM -# GCM Core installer does not current configure itself properly in all scenarios -# Configure it here to ensure it is configured correctly -echo "" -echo "==============================" -echo "Configuring Git to use GCM" -sudo /usr/local/bin/git config --system credential.helper /usr/local/share/gcm-core/git-credential-manager -sudo /usr/local/bin/git config --system credential.dev.azure.com.usehttppath true - # Install Scalar echo "" echo "==============================" echo "Installing Scalar" sudo /usr/sbin/installer -pkg "$SCALAR_DISTRIBUTION_ROOT/Scalar/$SCALAR_INSTALLER_PKG" -target / -echo "" -echo "==============================" -echo "Installing watchman as: $CURRENT_USER" +# Install Watchman +if [ $INSTALL_WATCHMAN -eq 1 ]; then + echo "" + echo "==============================" + echo "Installing watchman as: $CURRENT_USER" -sudo -u $CURRENT_USER brew update -sudo -u $CURRENT_USER brew install watchman + sudo -u $CURRENT_USER brew update + sudo -u $CURRENT_USER brew install watchman +else + echo "" + echo "==============================" + echo "Skipping watchman installation" + echo "(--no-watchman was specified)" +fi # Install optional package if specified if [ ! -z "$OPTIONAL_INSTALLER_PKG" ]; then diff --git a/Scalar.Distribution.Mac/Scalar.Distribution.Mac.csproj b/Scalar.Distribution.Mac/Scalar.Distribution.Mac.csproj new file mode 100644 index 0000000000..894dfc0dbb --- /dev/null +++ b/Scalar.Distribution.Mac/Scalar.Distribution.Mac.csproj @@ -0,0 +1,44 @@ + + + + netcoreapp3.0 + $(ProjectOutPath)dist\$(Configuration)\ + v2.0.79-beta + gcmcore-osx-2.0.79.64449.pkg + + + + + + + + + + + + + + + + + + + + + %(ScalarPackage.Filename)%(ScalarPackage.Extension) + %(GitPackage.Filename)%(GitPackage.Extension) + + + + + + + + diff --git a/Scalar.Distribution.Windows/InstallScalar.template.bat b/Scalar.Distribution.Windows/InstallScalar.template.bat new file mode 100644 index 0000000000..4fcd834020 --- /dev/null +++ b/Scalar.Distribution.Windows/InstallScalar.template.bat @@ -0,0 +1,40 @@ +@ECHO OFF +REM --------------------------------------------------------- +REM InstallScalar.bat +REM +REM Description: Main logic for installing Scalar and supporting +REM Components. +REM --------------------------------------------------------- + +SET SCALAR_DISTRIBUTION_ROOT=%~dp0 +SET GIT_INSTALLER_EXE=##GIT_INSTALLER_EXE_PLACEHOLDER## +SET SCALAR_INSTALLER_EXE=##SCALAR_INSTALLER_EXE_PLACEHOLDER## + +ECHO Scalar distribution root: %SCALAR_DISTRIBUTION_ROOT% +ECHO Git installer exe: %GIT_INSTALLER_EXE% +ECHO Scalar installer exe: %SCALAR_INSTALLER_EXE% + +REM Install Git +ECHO. +ECHO ============================== +ECHO Installing Git for Windows for Scalar +%SCALAR_DISTRIBUTION_ROOT%\Git\%GIT_INSTALLER_EXE% /DIR="C:\Program Files\Git" /NOICONS /COMPONENTS="ext,ext\shellhere,ext\guihere,assoc,assoc_sh" /GROUP="Git" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART || EXIT /B 1 + +REM Install Scalar +ECHO. +ECHO ============================== +ECHO Installing Scalar +%SCALAR_DISTRIBUTION_ROOT%\Scalar\%SCALAR_INSTALLER_EXE% /VERYSILENT /SUPPRESSMSGBOXES /NORESTART || EXIT /B 1 + +REM Run the post install script (if any) +IF EXIST "%SCALAR_DISTRIBUTION_ROOT%\Scripts\PostInstall.bat" ( + ECHO. + ECHO ============================== + ECHO Running post install script + START "%SCALAR_DISTRIBUTION_ROOT%\Scripts\PostInstall.bat" +) + +REM Installation Complete! +ECHO. +ECHO ============================== +ECHO Installation Complete!!! diff --git a/Scalar.Distribution.Windows/Scalar.Distribution.Windows.csproj b/Scalar.Distribution.Windows/Scalar.Distribution.Windows.csproj new file mode 100644 index 0000000000..5db212f0d8 --- /dev/null +++ b/Scalar.Distribution.Windows/Scalar.Distribution.Windows.csproj @@ -0,0 +1,35 @@ + + + + netcoreapp3.0 + $(ProjectOutPath)dist\$(Configuration)\ + + + + + + + + + + + + + + + + %(ScalarPackage.Filename)%(ScalarPackage.Extension) + %(GitPackage.Filename)%(GitPackage.Extension) + + + + + + + + + diff --git a/Scalar.Tests/NUnitRunner.cs b/Scalar.FunctionalTests/NUnitRunner.cs similarity index 100% rename from Scalar.Tests/NUnitRunner.cs rename to Scalar.FunctionalTests/NUnitRunner.cs diff --git a/Scalar.FunctionalTests/Scalar.FunctionalTests.csproj b/Scalar.FunctionalTests/Scalar.FunctionalTests.csproj index 77da6dfc27..1a678b910d 100644 --- a/Scalar.FunctionalTests/Scalar.FunctionalTests.csproj +++ b/Scalar.FunctionalTests/Scalar.FunctionalTests.csproj @@ -1,52 +1,20 @@ - - - Exe - netcoreapp2.1 - x64 - - true - true - win-x64;osx-x64 - - Scalar.FunctionalTests - Scalar.FunctionalTests - - - $(ScalarVersion) - - - $(ScalarVersion) + Exe + netcoreapp3.0 + false - - - - - all - - - - - - + - - - - - - - + + + + - - - - diff --git a/Scalar.Installer.Mac/CreateMacInstaller.sh b/Scalar.Installer.Mac/CreateMacInstaller.sh deleted file mode 100755 index 1d8f998b91..0000000000 --- a/Scalar.Installer.Mac/CreateMacInstaller.sh +++ /dev/null @@ -1,208 +0,0 @@ -#!/bin/bash - -SOURCEDIRECTORY=$1 -if [ -z $SOURCEDIRECTORY ]; then - echo "Error: Source directory not specified" - exit 1 -fi - -CONFIGURATION=$2 -if [ -z $CONFIGURATION ]; then - echo "Error: Build configuration not specified" - exit 1 -fi - -PACKAGEVERSION=$3 -if [ -z $PACKAGEVERSION ]; then - echo "Error: Installer package version not specified" - exit 1 -fi - -BUILDOUTPUTDIR=${4%/} -if [ -z $BUILDOUTPUTDIR ]; then - echo "Error: Build output directory not specified" - exit 1 -fi - -if [ -z $Scalar_OUTPUTDIR ]; then - echo "Error: Missing environment variable. Scalar_OUTPUTDIR is not set" - exit 1 -fi - -if [ -z $Scalar_PUBLISHDIR ]; then - echo "Error: Missing environment variable. Scalar_PUBLISHDIR is not set" - exit 1 -fi - -STAGINGDIR="${BUILDOUTPUTDIR}/Staging" -PACKAGESTAGINGDIR="${BUILDOUTPUTDIR}/Packages" -ScalarFORGITDESTINATION="usr/local/scalar" -DAEMONPLISTDESTINATION="Library/LaunchDaemons" -AGENTPLISTDESTINATION="Library/LaunchAgents" -LIBRARYEXTENSIONSDESTINATION="Library/Extensions" -LIBRARYAPPSUPPORTDESTINATION="Library/Application Support/Scalar" -INSTALLERPACKAGENAME="Scalar.$PACKAGEVERSION" -INSTALLERPACKAGEID="com.scalar.pkg" -UNINSTALLERPATH="${SOURCEDIRECTORY}/uninstall_scalar.sh" -SCRIPTSPATH="${SOURCEDIRECTORY}/scripts" -COMPONENTSPLISTPATH="${SOURCEDIRECTORY}/scalar_components.plist" -DIST_FILE_NAME="Distribution.updated.xml" - -function CheckBuildIsAvailable() -{ - if [ ! -d "$Scalar_OUTPUTDIR" ] || [ ! -d "$Scalar_PUBLISHDIR" ]; then - echo "Error: Could not find Scalar Build to package." - exit 1 - fi -} - -function SetPermissions() -{ - chmodCommand="chmod -R 755 \"${STAGINGDIR}\"" - eval $chmodCommand || exit 1 -} - -function CreateInstallerRoot() -{ - mkdirVfsForGit="mkdir -p \"${STAGINGDIR}/$ScalarFORGITDESTINATION\"" - eval $mkdirVfsForGit || exit 1 - - mkdirPkgStaging="mkdir -p \"${PACKAGESTAGINGDIR}\"" - eval $mkdirPkgStaging || exit 1 - - mkdirBin="mkdir -p \"${STAGINGDIR}/usr/local/bin\"" - eval $mkdirBin || exit 1 - - mkdirBin="mkdir -p \"${STAGINGDIR}/$LIBRARYEXTENSIONSDESTINATION\"" - eval $mkdirBin || exit 1 - - mkdirBin="mkdir -p \"${STAGINGDIR}/$LIBRARYAPPSUPPORTDESTINATION\"" - eval $mkdirBin || exit 1 - - mkdirBin="mkdir -p \"${STAGINGDIR}/$DAEMONPLISTDESTINATION\"" - eval $mkdirBin || exit 1 - - mkdirBin="mkdir -p \"${STAGINGDIR}/$AGENTPLISTDESTINATION\"" - eval $mkdirBin || exit 1 -} - -function CopyBinariesToInstall() -{ - copyPublishDirectory="cp -Rf \"${Scalar_PUBLISHDIR}\"/* \"${STAGINGDIR}/${ScalarFORGITDESTINATION}/.\"" - eval $copyPublishDirectory || exit 1 - - removeTestAssemblies="find \"${STAGINGDIR}/${ScalarFORGITDESTINATION}\" -name \"*Scalar.*Tests*\" -exec rm -f \"{}\" \";\"" - eval $removeTestAssemblies || exit 1 - - removeDataDirectory="rm -Rf \"${STAGINGDIR}/${ScalarFORGITDESTINATION}/Data\"" - eval $removeDataDirectory || exit 1 - - copyUnInstaller="cp -f \"${UNINSTALLERPATH}\" \"${STAGINGDIR}/${ScalarFORGITDESTINATION}/.\"" - eval $copyUnInstaller || exit 1 - - copyNotificationApp="cp -Rf \"${Scalar_OUTPUTDIR}/Scalar.Notifications/Scalar.Mac/Build/Products/$CONFIGURATION/Scalar.app\" \"${STAGINGDIR}/${LIBRARYAPPSUPPORTDESTINATION}/.\"" - eval $copyNotificationApp || exit 1 - - copyNotificationPlist="cp -Rf \"${SOURCEDIRECTORY}/../Scalar.Notifications/Scalar.Mac/org.scalar.usernotification.plist\" \"${STAGINGDIR}/${AGENTPLISTDESTINATION}/.\"" - eval $copyNotificationPlist || exit 1 - - copyServicePlist="cp -Rf \"${SOURCEDIRECTORY}/../Scalar.Service/Mac/org.scalar.service.plist\" \"${STAGINGDIR}/${AGENTPLISTDESTINATION}/.\"" - eval $copyServicePlist || exit 1 - - currentDirectory=`pwd` - cd "${STAGINGDIR}/usr/local/bin" - linkCommand="ln -sf ../scalar/scalar scalar" - eval $linkCommand - cd $currentDirectory -} - -function CreateScalarInstaller() -{ - pkgBuildCommand="/usr/bin/pkgbuild --identifier $INSTALLERPACKAGEID --component-plist \"${COMPONENTSPLISTPATH}\" --scripts \"${SCRIPTSPATH}\" --root \"${STAGINGDIR}\" \"${PACKAGESTAGINGDIR}/$INSTALLERPACKAGENAME.pkg\"" - eval $pkgBuildCommand || exit 1 -} - -function UpdateDistributionFile() -{ - ScalarFORGIT_PKG_VERSION=$PACKAGEVERSION - ScalarFORGIT_PKG_NAME="$INSTALLERPACKAGENAME.pkg" - GIT_PKG_NAME=$1 - GIT_PKG_VERSION=$2 - - /usr/bin/sed -e "s|ScalarFORGIT_VERSION_PLACHOLDER|$ScalarFORGIT_PKG_VERSION|g" "$SCRIPTSPATH/Distribution.xml" > "${BUILDOUTPUTDIR}/$DIST_FILE_NAME" - /usr/bin/sed -i.bak "s|ScalarFORGIT_PKG_NAME_PLACEHOLDER|$ScalarFORGIT_PKG_NAME|g" "${BUILDOUTPUTDIR}/$DIST_FILE_NAME" - - if [ ! -z "$GIT_PKG_NAME" ] && [ ! -z "$GIT_PKG_VERSION" ]; then - GIT_CHOICE_OUTLINE_ELEMENT_TEXT="" - GIT_CHOICE_ID_ELEMENT_TEXT=" " - GIT_PKG_REF_ELEMENT_TEXT="$GIT_PKG_NAME" - else - GIT_CHOICE_OUTLINE_ELEMENT_TEXT="" - GIT_CHOICE_ID_ELEMENT_TEXT="" - GIT_PKG_REF_ELEMENT_TEXT="" - fi - - /usr/bin/sed -i.bak "s|GIT_CHOICE_OUTLINE_PLACEHOLDER|$GIT_CHOICE_OUTLINE_ELEMENT_TEXT|g" "${BUILDOUTPUTDIR}/$DIST_FILE_NAME" - /usr/bin/sed -i.bak "s|GIT_CHOICE_ID_PLACEHOLDER|$GIT_CHOICE_ID_ELEMENT_TEXT|g" "${BUILDOUTPUTDIR}/$DIST_FILE_NAME" - /usr/bin/sed -i.bak "s|GIT_PKG_REF_PLACEHOLDER|$GIT_PKG_REF_ELEMENT_TEXT|g" "${BUILDOUTPUTDIR}/$DIST_FILE_NAME" - - /bin/rm -f "${BUILDOUTPUTDIR}/$DIST_FILE_NAME.bak" -} - -function CreateScalarDistribution() -{ - # Update distribution file(removes Git info from template.) - UpdateDistributionFile "" "" - - buildScalarDistCmd="/usr/bin/productbuild --distribution \"${BUILDOUTPUTDIR}/Distribution.updated.xml\" --package-path \"$PACKAGESTAGINGDIR\" \"${BUILDOUTPUTDIR}/$INSTALLERPACKAGENAME.pkg\"" - echo $buildScalarDistCmd - eval $buildScalarDistCmd || exit 1 - - /bin/rm -f "${BUILDOUTPUTDIR}/$DIST_FILE_NAME" -} - -function CreateMetaDistribution() -{ - GITVERSION="$($Scalar_SCRIPTDIR/GetGitVersionNumber.sh)" - GITINSTALLERPKGPATH="$(find $Scalar_PACKAGESDIR/gitformac.gvfs.installer/$GITVERSION -type f -name *.pkg)" || exit 1 - - GITPKGNAME="${GITINSTALLERPKGPATH##*/}" - GITINSTALLERPKGNAME="${GITPKGNAME%.pkg}" - GITVERSIONSTRING=`echo $GITINSTALLERPKGNAME | cut -d"-" -f2` - - if [[ -z "$GITVERSION" || -z "$GITVERSIONSTRING" ]]; then - echo "Error creating metapackage: could not determine Git package version." - exit 1 - fi - - if [ ! -f "$GITINSTALLERPKGPATH" ]; then - echo "Error creating metapackage: could not find Git installer package." - exit 1 - fi - - copyGitInstallerPkgToStgCmd="/bin/cp -Rf \"${GITINSTALLERPKGPATH}\" \"${PACKAGESTAGINGDIR}/.\"" - echo $copyGitInstallerPkgToStgCmd - eval $copyGitInstallerPkgToStgCmd || exit 1 - - UpdateDistributionFile "$GITPKGNAME" "$GITVERSIONSTRING" - - METAPACKAGENAME="$INSTALLERPACKAGENAME-Git.$GITVERSION.pkg" - buildMetapkgCmd="/usr/bin/productbuild --distribution \"${BUILDOUTPUTDIR}/Distribution.updated.xml\" --package-path \"$PACKAGESTAGINGDIR\" \"${BUILDOUTPUTDIR}/$METAPACKAGENAME\"" - echo $buildMetapkgCmd - eval $buildMetapkgCmd || exit 1 - - /bin/rm -f "${BUILDOUTPUTDIR}/$DIST_FILE_NAME" -} - -function Run() -{ - CheckBuildIsAvailable - CreateInstallerRoot - CopyBinariesToInstall - SetPermissions - CreateScalarInstaller - CreateScalarDistribution - CreateMetaDistribution -} - -Run diff --git a/Scalar.Installer.Mac/Scalar.Installer.Mac.csproj b/Scalar.Installer.Mac/Scalar.Installer.Mac.csproj index 5b2c796cf4..c0fcba5550 100644 --- a/Scalar.Installer.Mac/Scalar.Installer.Mac.csproj +++ b/Scalar.Installer.Mac/Scalar.Installer.Mac.csproj @@ -1,37 +1,32 @@ - - - - + + - Scalar.Installer.Mac - Scalar.Installer.Mac - netcoreapp2.1 - x64 - osx-x64 - - - - $(ScalarVersion) + netcoreapp3.0 + osx-x64 + $(ProjectOutPath)layout\$(Configuration)\ + $(ProjectOutPath)installer\$(Configuration)\ - - - $(ScalarVersion) - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + + diff --git a/Scalar.Installer.Mac/scripts/Distribution.xml b/Scalar.Installer.Mac/distribution.template.xml similarity index 84% rename from Scalar.Installer.Mac/scripts/Distribution.xml rename to Scalar.Installer.Mac/distribution.template.xml index 235df0b759..98121326ee 100644 --- a/Scalar.Installer.Mac/scripts/Distribution.xml +++ b/Scalar.Installer.Mac/distribution.template.xml @@ -2,21 +2,17 @@ Scalar - - GIT_CHOICE_OUTLINE_PLACEHOLDER - ScalarFORGIT_PKG_NAME_PLACEHOLDER - GIT_CHOICE_ID_PLACEHOLDER - GIT_PKG_REF_PLACEHOLDER + SCALAR_PKG_NAME_PLACEHOLDER