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