diff --git a/azure-pipelines-PR.yml b/azure-pipelines-PR.yml
index d73955cdb18..313ddee65cc 100644
--- a/azure-pipelines-PR.yml
+++ b/azure-pipelines-PR.yml
@@ -118,7 +118,7 @@ stages:
inputs:
packageType: sdk
useGlobalJson: true
- includePreviewVersions: false
+ includePreviewVersions: true
workingDirectory: $(Build.SourcesDirectory)
installationPath: $(Build.SourcesDirectory)/.dotnet
- script: .\eng\test-determinism.cmd -configuration Debug
@@ -230,7 +230,7 @@ stages:
- checkout: self
clean: true
- - script: eng\CIBuild.cmd -compressallmetadata -configuration Release /p:FSharpLangVersion=preview
+ - script: eng\CIBuildNoPublish.cmd -compressallmetadata -configuration Release /p:FSharpLangVersion=preview
env:
DOTNET_DbgEnableMiniDump: 1
DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing.
@@ -270,7 +270,7 @@ stages:
- checkout: self
clean: true
- - script: eng\CIBuild.cmd -compressallmetadata -buildnorealsig -testCoreclr -configuration Release
+ - script: eng\CIBuildNoPublish.cmd -compressallmetadata -buildnorealsig -testCoreclr -configuration Release
env:
DOTNET_DbgEnableMiniDump: 1
DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing.
@@ -322,7 +322,7 @@ stages:
- checkout: self
clean: true
- - script: eng\CIBuild.cmd -compressallmetadata -buildnorealsig -testDesktop -configuration Release -testBatch $(System.JobPositionInPhase)
+ - script: eng\CIBuildNoPublish.cmd -compressallmetadata -buildnorealsig -testDesktop -configuration Release -testBatch $(System.JobPositionInPhase)
env:
DOTNET_DbgEnableMiniDump: 1
DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing.
@@ -372,7 +372,7 @@ stages:
- checkout: self
clean: true
- - script: eng\CIBuild.cmd -compressallmetadata -configuration Release /p:AdditionalFscCmdFlags=--strict-indentation+
+ - script: eng\CIBuildNoPublish.cmd -compressallmetadata -configuration Release /p:AdditionalFscCmdFlags=--strict-indentation+
env:
DOTNET_DbgEnableMiniDump: 1
DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing.
@@ -408,7 +408,7 @@ stages:
- checkout: self
clean: true
- - script: eng\CIBuild.cmd -compressallmetadata -configuration Release /p:AdditionalFscCmdFlags=--strict-indentation-
+ - script: eng\CIBuildNoPublish.cmd -compressallmetadata -configuration Release /p:AdditionalFscCmdFlags=--strict-indentation-
env:
DOTNET_DbgEnableMiniDump: 1
DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing.
@@ -482,7 +482,7 @@ stages:
displayName: Setup VS Hive
condition: eq(variables.setupVsHive, 'true')
- - script: eng\CIBuild.cmd -compressallmetadata -configuration $(_configuration) -$(_testKind)
+ - script: eng\CIBuildNoPublish.cmd -compressallmetadata -configuration $(_configuration) -$(_testKind)
env:
DOTNET_DbgEnableMiniDump: 1
DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing.
@@ -560,7 +560,7 @@ stages:
- checkout: self
clean: true
- - script: eng\CIBuild.cmd -compressallmetadata -configuration Release -testDesktop -testBatch $(System.JobPositionInPhase)
+ - script: eng\CIBuildNoPublish.cmd -compressallmetadata -configuration Release -testDesktop -testBatch $(System.JobPositionInPhase)
env:
DOTNET_DbgEnableMiniDump: 1
DOTNET_DbgMiniDumpType: 3 # Triage dump, 1 for mini, 2 for Heap, 3 for triage, 4 for full. Don't use 4 unless you know what you're doing.
diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
index a3949c5b823..6df96779eb3 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
@@ -11,6 +11,7 @@
* Fix find all references for F# exceptions ([PR #18565](https://github.com/dotnet/fsharp/pull/18565))
* Shorthand lambda: fix completion for chained calls and analysis for unfinished expression ([PR #18560](https://github.com/dotnet/fsharp/pull/18560))
* Completion: fix previous namespace considered opened [PR #18609](https://github.com/dotnet/fsharp/pull/18609)
+* Fix active pattern typechecking regression. ([Issue #18638](https://github.com/dotnet/fsharp/issues/18638), [PR #18642](https://github.com/dotnet/fsharp/pull/18642))
### Added
@@ -18,4 +19,4 @@
### Breaking Changes
-* Scoped Nowarn: Add the #warnon compiler directive ([Language suggestion #278](https://github.com/fsharp/fslang-suggestions/issues/278), [RFC FS-1146 PR](https://github.com/fsharp/fslang-design/pull/782), [PR #18049](https://github.com/dotnet/fsharp/pull/18049))
+* Scoped Nowarn: Add the #warnon compiler directive ([Language suggestion #278](https://github.com/fsharp/fslang-suggestions/issues/278), [RFC FS-1146 PR](https://github.com/fsharp/fslang-design/pull/782), [PR #18049](https://github.com/dotnet/fsharp/pull/18049) and [PR #18637](https://github.com/dotnet/fsharp/pull/18637))
diff --git a/eng/CIBuildNoPublish.cmd b/eng/CIBuildNoPublish.cmd
new file mode 100644
index 00000000000..8a38abfc51e
--- /dev/null
+++ b/eng/CIBuildNoPublish.cmd
@@ -0,0 +1,2 @@
+@echo off
+powershell -noprofile -executionPolicy RemoteSigned -file "%~dp0\Build.ps1" -ci -restore -build -bootstrap -pack -sign -binaryLog %*
diff --git a/eng/DotNetBuild.props b/eng/DotNetBuild.props
deleted file mode 100644
index 621afcc340f..00000000000
--- a/eng/DotNetBuild.props
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
- fsharp
- true
- $(DotNetBuildOrchestrator)
- false
- false
-
-
-
-
-
- --tfm $(SourceBuildBootstrapTfm)
- false
- /p:RestoreConfigFile=$(RestoreConfigFile)
-
-
-
-
-
-
-
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 963b1dd98be..e59e5a396ba 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -36,29 +36,29 @@
-
+
https://github.com/dotnet/arcade
- 086a1771875b63404b4a710d27250fe384dc2810
+ 12d3a9f5d6138e22270694574e73e4c58a815795
-
+
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
- a68196f69e40740fce716778138acaa26488b333
+ 5be52292950378f4737c2330406ffa4df9ef43f0
-
+
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
- a68196f69e40740fce716778138acaa26488b333
+ 5be52292950378f4737c2330406ffa4df9ef43f0
-
+
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
- a68196f69e40740fce716778138acaa26488b333
+ 5be52292950378f4737c2330406ffa4df9ef43f0
-
+
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
- a68196f69e40740fce716778138acaa26488b333
+ 5be52292950378f4737c2330406ffa4df9ef43f0
-
+
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
- a68196f69e40740fce716778138acaa26488b333
+ 5be52292950378f4737c2330406ffa4df9ef43f0
diff --git a/eng/Versions.props b/eng/Versions.props
index 689e3a5d77b..f6c048d1622 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -204,10 +204,10 @@
2.2.0
- 1.0.0-prerelease.25256.1
- 1.0.0-prerelease.25256.1
- 1.0.0-prerelease.25256.1
- 1.0.0-prerelease.25256.1
- 1.0.0-prerelease.25256.1
+ 1.0.0-prerelease.25302.1
+ 1.0.0-prerelease.25302.1
+ 1.0.0-prerelease.25302.1
+ 1.0.0-prerelease.25302.1
+ 1.0.0-prerelease.25302.1
diff --git a/eng/common/CIBuild.cmd b/eng/common/CIBuild.cmd
index 56c2f25ac22..ac1f72bf94e 100644
--- a/eng/common/CIBuild.cmd
+++ b/eng/common/CIBuild.cmd
@@ -1,2 +1,2 @@
@echo off
-powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*"
\ No newline at end of file
+powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*"
diff --git a/eng/common/build.ps1 b/eng/common/build.ps1
index 438f9920c43..ae2309e312d 100644
--- a/eng/common/build.ps1
+++ b/eng/common/build.ps1
@@ -7,6 +7,7 @@ Param(
[string] $msbuildEngine = $null,
[bool] $warnAsError = $true,
[bool] $nodeReuse = $true,
+ [switch] $buildCheck = $false,
[switch][Alias('r')]$restore,
[switch] $deployDeps,
[switch][Alias('b')]$build,
@@ -71,6 +72,8 @@ function Print-Usage() {
Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)."
Write-Host " -excludePrereleaseVS Set to exclude build engines in prerelease versions of Visual Studio"
Write-Host " -nativeToolsOnMachine Sets the native tools on machine environment variable (indicating that the script should use native tools on machine)"
+ Write-Host " -nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')"
+ Write-Host " -buildCheck Sets /check msbuild parameter"
Write-Host ""
Write-Host "Command line arguments not listed above are passed thru to msbuild."
@@ -97,6 +100,7 @@ function Build {
$bl = if ($binaryLog) { '/bl:' + (Join-Path $LogDir 'Build.binlog') } else { '' }
$platformArg = if ($platform) { "/p:Platform=$platform" } else { '' }
+ $check = if ($buildCheck) { '/check' } else { '' }
if ($projects) {
# Re-assign properties to a new variable because PowerShell doesn't let us append properties directly for unclear reasons.
@@ -113,6 +117,7 @@ function Build {
MSBuild $toolsetBuildProj `
$bl `
$platformArg `
+ $check `
/p:Configuration=$configuration `
/p:RepoRoot=$RepoRoot `
/p:Restore=$restore `
@@ -122,11 +127,12 @@ function Build {
/p:Deploy=$deploy `
/p:Test=$test `
/p:Pack=$pack `
- /p:DotNetBuildRepo=$productBuild `
+ /p:DotNetBuild=$productBuild `
/p:IntegrationTest=$integrationTest `
/p:PerformanceTest=$performanceTest `
/p:Sign=$sign `
/p:Publish=$publish `
+ /p:RestoreStaticGraphEnableBinaryLogger=$binaryLog `
@properties
}
diff --git a/eng/common/build.sh b/eng/common/build.sh
index ac1ee8620cd..da906da2026 100755
--- a/eng/common/build.sh
+++ b/eng/common/build.sh
@@ -42,6 +42,7 @@ usage()
echo " --prepareMachine Prepare machine for CI run, clean up processes after build"
echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')"
echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')"
+ echo " --buildCheck Sets /check msbuild parameter"
echo ""
echo "Command line arguments not listed above are passed thru to msbuild."
echo "Arguments can also be passed in with a single hyphen."
@@ -76,6 +77,7 @@ clean=false
warn_as_error=true
node_reuse=true
+build_check=false
binary_log=false
exclude_ci_binary_log=false
pipelines_log=false
@@ -127,14 +129,14 @@ while [[ $# > 0 ]]; do
-pack)
pack=true
;;
- -sourcebuild|-sb)
+ -sourcebuild|-source-build|-sb)
build=true
source_build=true
product_build=true
restore=true
pack=true
;;
- -productBuild|-pb)
+ -productbuild|-product-build|-pb)
build=true
product_build=true
restore=true
@@ -173,6 +175,9 @@ while [[ $# > 0 ]]; do
node_reuse=$2
shift
;;
+ -buildcheck)
+ build_check=true
+ ;;
-runtimesourcefeed)
runtime_source_feed=$2
shift
@@ -224,14 +229,19 @@ function Build {
bl="/bl:\"$log_dir/Build.binlog\""
fi
+ local check=""
+ if [[ "$build_check" == true ]]; then
+ check="/check"
+ fi
+
MSBuild $_InitializeToolset \
$bl \
+ $check \
/p:Configuration=$configuration \
/p:RepoRoot="$repo_root" \
/p:Restore=$restore \
/p:Build=$build \
- /p:DotNetBuildRepo=$product_build \
- /p:ArcadeBuildFromSource=$source_build \
+ /p:DotNetBuild=$product_build \
/p:DotNetBuildSourceOnly=$source_build \
/p:Rebuild=$rebuild \
/p:Test=$test \
@@ -240,6 +250,7 @@ function Build {
/p:PerformanceTest=$performance_test \
/p:Sign=$sign \
/p:Publish=$publish \
+ /p:RestoreStaticGraphEnableBinaryLogger=$binary_log \
$properties
ExitWithExitCode 0
diff --git a/eng/common/cibuild.sh b/eng/common/cibuild.sh
index 1a02c0dec8f..66e3b0ac61c 100755
--- a/eng/common/cibuild.sh
+++ b/eng/common/cibuild.sh
@@ -13,4 +13,4 @@ while [[ -h $source ]]; do
done
scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
-. "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@
\ No newline at end of file
+. "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@
diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml
index ba53ebfbd51..6badecba7bc 100644
--- a/eng/common/core-templates/job/job.yml
+++ b/eng/common/core-templates/job/job.yml
@@ -19,10 +19,10 @@ parameters:
# publishing defaults
artifacts: ''
enableMicrobuild: false
+ enableMicrobuildForMacAndLinux: false
enablePublishBuildArtifacts: false
enablePublishBuildAssets: false
enablePublishTestResults: false
- enablePublishUsingPipelines: false
enableBuildRetry: false
mergeTestResults: false
testRunTitle: ''
@@ -73,9 +73,6 @@ jobs:
- ${{ if ne(parameters.enableTelemetry, 'false') }}:
- name: DOTNET_CLI_TELEMETRY_PROFILE
value: '$(Build.Repository.Uri)'
- - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}:
- - name: EnableRichCodeNavigation
- value: 'true'
# Retry signature validation up to three times, waiting 2 seconds between attempts.
# See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures
- name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY
@@ -127,18 +124,11 @@ jobs:
- ${{ preStep }}
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
- - task: MicroBuildSigningPlugin@4
- displayName: Install MicroBuild plugin
- inputs:
- signType: $(_SignType)
- zipSources: false
- feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
- env:
- TeamName: $(_TeamName)
- MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)'
+ - template: /eng/common/core-templates/steps/install-microbuild.yml
+ parameters:
+ enableMicrobuild: ${{ parameters.enableMicrobuild }}
+ enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }}
continueOnError: ${{ parameters.continueOnError }}
- condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
- ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}:
- task: NuGetAuthenticate@1
@@ -154,27 +144,15 @@ jobs:
- ${{ each step in parameters.steps }}:
- ${{ step }}
- - ${{ if eq(parameters.enableRichCodeNavigation, true) }}:
- - task: RichCodeNavIndexer@0
- displayName: RichCodeNav Upload
- inputs:
- languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }}
- environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'internal') }}
- richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin
- uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }}
- continueOnError: true
-
- ${{ each step in parameters.componentGovernanceSteps }}:
- ${{ step }}
- - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - task: MicroBuildCleanup@1
- displayName: Execute Microbuild cleanup tasks
- condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - template: /eng/common/core-templates/steps/cleanup-microbuild.yml
+ parameters:
+ enableMicrobuild: ${{ parameters.enableMicrobuild }}
+ enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }}
continueOnError: ${{ parameters.continueOnError }}
- env:
- TeamName: $(_TeamName)
# Publish test results
- ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}:
diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml
index 3d3356e3196..4f1dc42e02c 100644
--- a/eng/common/core-templates/job/publish-build-assets.yml
+++ b/eng/common/core-templates/job/publish-build-assets.yml
@@ -20,9 +20,6 @@ parameters:
# if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.
runAsPublic: false
- # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
- publishUsingPipelines: false
-
# Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
publishAssetsImmediately: false
@@ -32,6 +29,9 @@ parameters:
is1ESPipeline: ''
+ # Optional: 🌤️ or not the build has assets it wants to publish to BAR
+ isAssetlessBuild: false
+
jobs:
- job: Asset_Registry_Publish
@@ -75,15 +75,15 @@ jobs:
- checkout: self
fetchDepth: 3
clean: true
-
- - task: DownloadBuildArtifacts@0
- displayName: Download artifact
- inputs:
- artifactName: AssetManifests
- downloadPath: '$(Build.StagingDirectory)/Download'
- checkDownloadedFiles: true
- condition: ${{ parameters.condition }}
- continueOnError: ${{ parameters.continueOnError }}
+
+ - ${{ if eq(parameters.isAssetlessBuild, 'false') }}:
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Asset Manifests
+ inputs:
+ artifactName: AssetManifests
+ targetPath: '$(Build.StagingDirectory)/AssetManifests'
+ condition: ${{ parameters.condition }}
+ continueOnError: ${{ parameters.continueOnError }}
- task: NuGetAuthenticate@1
@@ -95,9 +95,9 @@ jobs:
scriptLocation: scriptPath
scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1
arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet
- /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests'
+ /p:ManifestsPath='$(Build.StagingDirectory)/AssetManifests'
+ /p:IsAssetlessBuild=${{ parameters.isAssetlessBuild }}
/p:MaestroApiEndpoint=https://maestro.dot.net
- /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }}
/p:OfficialBuildId=$(Build.BuildNumber)
condition: ${{ parameters.condition }}
continueOnError: ${{ parameters.continueOnError }}
@@ -129,7 +129,7 @@ jobs:
publishLocation: Container
artifactName: ReleaseConfigs
- - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
+ - ${{ if or(eq(parameters.publishAssetsImmediately, 'true'), eq(parameters.isAssetlessBuild, 'true')) }}:
- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
parameters:
BARBuildId: ${{ parameters.BARBuildId }}
@@ -150,6 +150,7 @@ jobs:
-WaitPublishingFinish true
-ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
-SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
+ -SkipAssetsPublishing '${{ parameters.isAssetlessBuild }}'
- ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
- template: /eng/common/core-templates/steps/publish-logs.yml
diff --git a/eng/common/core-templates/job/source-build.yml b/eng/common/core-templates/job/source-build.yml
index d47f09d58fd..d805d5faeb9 100644
--- a/eng/common/core-templates/job/source-build.yml
+++ b/eng/common/core-templates/job/source-build.yml
@@ -12,9 +12,10 @@ parameters:
# The name of the job. This is included in the job ID.
# targetRID: ''
# The name of the target RID to use, instead of the one auto-detected by Arcade.
- # nonPortable: false
+ # portableBuild: false
# Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than
- # linux-x64), and compiling against distro-provided packages rather than portable ones.
+ # linux-x64), and compiling against distro-provided packages rather than portable ones. The
+ # default is portable mode.
# skipPublishValidation: false
# Disables publishing validation. By default, a check is performed to ensure no packages are
# published by source-build.
diff --git a/eng/common/core-templates/job/source-index-stage1.yml b/eng/common/core-templates/job/source-index-stage1.yml
index 8b833332b3e..30530359a5d 100644
--- a/eng/common/core-templates/job/source-index-stage1.yml
+++ b/eng/common/core-templates/job/source-index-stage1.yml
@@ -1,8 +1,5 @@
parameters:
runAsPublic: false
- sourceIndexUploadPackageVersion: 2.0.0-20250425.2
- sourceIndexProcessBinlogPackageVersion: 1.0.1-20250425.2
- sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
preSteps: []
binlogPath: artifacts/log/Debug/Build.binlog
@@ -16,12 +13,6 @@ jobs:
dependsOn: ${{ parameters.dependsOn }}
condition: ${{ parameters.condition }}
variables:
- - name: SourceIndexUploadPackageVersion
- value: ${{ parameters.sourceIndexUploadPackageVersion }}
- - name: SourceIndexProcessBinlogPackageVersion
- value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }}
- - name: SourceIndexPackageSource
- value: ${{ parameters.sourceIndexPackageSource }}
- name: BinlogPath
value: ${{ parameters.binlogPath }}
- template: /eng/common/core-templates/variables/pool-providers.yml
@@ -34,12 +25,10 @@ jobs:
pool:
${{ if eq(variables['System.TeamProject'], 'public') }}:
name: $(DncEngPublicBuildPool)
- image: 1es-windows-2022-open
- os: windows
+ image: windows.vs2022.amd64.open
${{ if eq(variables['System.TeamProject'], 'internal') }}:
name: $(DncEngInternalBuildPool)
- image: 1es-windows-2022
- os: windows
+ image: windows.vs2022.amd64
steps:
- ${{ if eq(parameters.is1ESPipeline, '') }}:
@@ -47,35 +36,9 @@ jobs:
- ${{ each preStep in parameters.preSteps }}:
- ${{ preStep }}
-
- - task: UseDotNet@2
- displayName: Use .NET 8 SDK
- inputs:
- packageType: sdk
- version: 8.0.x
- installationPath: $(Agent.TempDirectory)/dotnet
- workingDirectory: $(Agent.TempDirectory)
-
- - script: |
- $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
- $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
- displayName: Download Tools
- # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
- workingDirectory: $(Agent.TempDirectory)
-
- script: ${{ parameters.sourceIndexBuildCommand }}
displayName: Build Repository
- - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
- displayName: Process Binlog into indexable sln
-
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - task: AzureCLI@2
- displayName: Log in to Azure and upload stage1 artifacts to source index
- inputs:
- azureSubscription: 'SourceDotNet Stage1 Publish'
- addSpnToEnvironment: true
- scriptType: 'ps'
- scriptLocation: 'inlineScript'
- inlineScript: |
- $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1
+ - template: /eng/common/core-templates/steps/source-index-stage1-publish.yml
+ parameters:
+ binLogPath: ${{ parameters.binLogPath }}
\ No newline at end of file
diff --git a/eng/common/core-templates/jobs/codeql-build.yml b/eng/common/core-templates/jobs/codeql-build.yml
index f2144252cc6..693b00b3704 100644
--- a/eng/common/core-templates/jobs/codeql-build.yml
+++ b/eng/common/core-templates/jobs/codeql-build.yml
@@ -15,7 +15,6 @@ jobs:
enablePublishBuildArtifacts: false
enablePublishTestResults: false
enablePublishBuildAssets: false
- enablePublishUsingPipelines: false
enableTelemetry: true
variables:
diff --git a/eng/common/core-templates/jobs/jobs.yml b/eng/common/core-templates/jobs/jobs.yml
index ea69be4341c..bf35b78faa6 100644
--- a/eng/common/core-templates/jobs/jobs.yml
+++ b/eng/common/core-templates/jobs/jobs.yml
@@ -5,9 +5,6 @@ parameters:
# Optional: Include PublishBuildArtifacts task
enablePublishBuildArtifacts: false
- # Optional: Enable publishing using release pipelines
- enablePublishUsingPipelines: false
-
# Optional: Enable running the source-build jobs to build repo from source
enableSourceBuild: false
@@ -30,6 +27,9 @@ parameters:
# Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage.
publishAssetsImmediately: false
+ # Optional: 🌤️ or not the build has assets it wants to publish to BAR
+ isAssetlessBuild: false
+
# Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml)
artifactsPublishingAdditionalParameters: ''
signingValidationAdditionalParameters: ''
@@ -96,7 +96,7 @@ jobs:
${{ parameter.key }}: ${{ parameter.value }}
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}:
+ - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, ''), eq(parameters.isAssetlessBuild, true)) }}:
- template: ../job/publish-build-assets.yml
parameters:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
@@ -112,8 +112,8 @@ jobs:
- Source_Build_Complete
runAsPublic: ${{ parameters.runAsPublic }}
- publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }}
- publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }}
+ publishAssetsImmediately: ${{ or(parameters.publishAssetsImmediately, parameters.isAssetlessBuild) }}
+ isAssetlessBuild: ${{ parameters.isAssetlessBuild }}
enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }}
diff --git a/eng/common/core-templates/jobs/source-build.yml b/eng/common/core-templates/jobs/source-build.yml
index a10ccfbee6d..df24c948ba1 100644
--- a/eng/common/core-templates/jobs/source-build.yml
+++ b/eng/common/core-templates/jobs/source-build.yml
@@ -14,7 +14,7 @@ parameters:
# This is the default platform provided by Arcade, intended for use by a managed-only repo.
defaultManagedPlatform:
name: 'Managed'
- container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9'
+ container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream-10-amd64'
# Defines the platforms on which to run build jobs. One job is created for each platform, and the
# object in this array is sent to the job template as 'platform'. If no platforms are specified,
diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml
index 454fd75c7af..a151fd811e3 100644
--- a/eng/common/core-templates/post-build/post-build.yml
+++ b/eng/common/core-templates/post-build/post-build.yml
@@ -44,6 +44,11 @@ parameters:
displayName: Publish installers and checksums
type: boolean
default: true
+
+ - name: requireDefaultChannels
+ displayName: Fail the build if there are no default channel(s) registrations for the current build
+ type: boolean
+ default: false
- name: SDLValidationParameters
type: object
@@ -55,6 +60,11 @@ parameters:
artifactNames: ''
downloadArtifacts: true
+ - name: isAssetlessBuild
+ type: boolean
+ displayName: Is Assetless Build
+ default: false
+
# These parameters let the user customize the call to sdk-task.ps1 for publishing
# symbols & general artifacts as well as for signing validation
- name: symbolPublishingAdditionalParameters
@@ -183,9 +193,6 @@ stages:
buildId: $(AzDOBuildId)
artifactName: PackageArtifacts
checkDownloadedFiles: true
- itemPattern: |
- **
- !**/Microsoft.SourceBuild.Intermediate.*.nupkg
# This is necessary whenever we want to publish/restore to an AzDO private feed
# Since sdk-task.ps1 tries to restore packages we need to do this authentication here
@@ -312,5 +319,7 @@ stages:
-PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
-AzdoToken '$(System.AccessToken)'
-WaitPublishingFinish true
+ -RequireDefaultChannels ${{ parameters.requireDefaultChannels }}
-ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
-SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
+ -SkipAssetsPublishing '${{ parameters.isAssetlessBuild }}'
diff --git a/eng/common/core-templates/steps/cleanup-microbuild.yml b/eng/common/core-templates/steps/cleanup-microbuild.yml
new file mode 100644
index 00000000000..c0fdcd3379d
--- /dev/null
+++ b/eng/common/core-templates/steps/cleanup-microbuild.yml
@@ -0,0 +1,28 @@
+parameters:
+ # Enable cleanup tasks for MicroBuild
+ enableMicrobuild: false
+ # Enable cleanup tasks for MicroBuild on Mac and Linux
+ # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT'
+ enableMicrobuildForMacAndLinux: false
+ continueOnError: false
+
+steps:
+ - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
+ - task: MicroBuildCleanup@1
+ displayName: Execute Microbuild cleanup tasks
+ condition: and(
+ always(),
+ or(
+ and(
+ eq(variables['Agent.Os'], 'Windows_NT'),
+ in(variables['_SignType'], 'real', 'test')
+ ),
+ and(
+ ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }},
+ ne(variables['Agent.Os'], 'Windows_NT'),
+ eq(variables['_SignType'], 'real')
+ )
+ ))
+ continueOnError: ${{ parameters.continueOnError }}
+ env:
+ TeamName: $(_TeamName)
diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml
index 56a09009482..44a9636cdff 100644
--- a/eng/common/core-templates/steps/generate-sbom.yml
+++ b/eng/common/core-templates/steps/generate-sbom.yml
@@ -5,7 +5,7 @@
# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
parameters:
- PackageVersion: 9.0.0
+ PackageVersion: 10.0.0
BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
PackageName: '.NET'
ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
diff --git a/eng/common/core-templates/steps/get-delegation-sas.yml b/eng/common/core-templates/steps/get-delegation-sas.yml
index 9db5617ea7d..d2901470a7f 100644
--- a/eng/common/core-templates/steps/get-delegation-sas.yml
+++ b/eng/common/core-templates/steps/get-delegation-sas.yml
@@ -31,16 +31,7 @@ steps:
# Calculate the expiration of the SAS token and convert to UTC
$expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
- # Temporarily work around a helix issue where SAS tokens with / in them will cause incorrect downloads
- # of correlation payloads. https://github.com/dotnet/dnceng/issues/3484
- $sas = ""
- do {
- $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv
- if ($LASTEXITCODE -ne 0) {
- Write-Error "Failed to generate SAS token."
- exit 1
- }
- } while($sas.IndexOf('/') -ne -1)
+ $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to generate SAS token."
diff --git a/eng/common/core-templates/steps/install-microbuild.yml b/eng/common/core-templates/steps/install-microbuild.yml
new file mode 100644
index 00000000000..a3540ba00c7
--- /dev/null
+++ b/eng/common/core-templates/steps/install-microbuild.yml
@@ -0,0 +1,50 @@
+parameters:
+ # Enable install tasks for MicroBuild
+ enableMicrobuild: false
+ # Enable install tasks for MicroBuild on Mac and Linux
+ # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT'
+ enableMicrobuildForMacAndLinux: false
+ # Location of the MicroBuild output folder
+ microBuildOutputFolder: '$(Build.SourcesDirectory)'
+ continueOnError: false
+
+steps:
+ - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
+ - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, 'true') }}:
+ # Needed to download the MicroBuild plugin nupkgs on Mac and Linux when nuget.exe is unavailable
+ - task: UseDotNet@2
+ displayName: Install .NET 8.0 SDK for MicroBuild Plugin
+ inputs:
+ packageType: sdk
+ version: 8.0.x
+ installationPath: ${{ parameters.microBuildOutputFolder }}/.dotnet
+ workingDirectory: ${{ parameters.microBuildOutputFolder }}
+ condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
+
+ - task: MicroBuildSigningPlugin@4
+ displayName: Install MicroBuild plugin
+ inputs:
+ signType: $(_SignType)
+ zipSources: false
+ feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
+ ${{ if and(eq(parameters.enableMicrobuildForMacAndLinux, 'true'), ne(variables['Agent.Os'], 'Windows_NT')) }}:
+ azureSubscription: 'MicroBuild Signing Task (DevDiv)'
+ useEsrpCli: true
+ env:
+ TeamName: $(_TeamName)
+ MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: and(
+ succeeded(),
+ or(
+ and(
+ eq(variables['Agent.Os'], 'Windows_NT'),
+ in(variables['_SignType'], 'real', 'test')
+ ),
+ and(
+ ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }},
+ ne(variables['Agent.Os'], 'Windows_NT'),
+ eq(variables['_SignType'], 'real')
+ )
+ ))
diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml
index 80788c52319..de24d0087c5 100644
--- a/eng/common/core-templates/steps/publish-logs.yml
+++ b/eng/common/core-templates/steps/publish-logs.yml
@@ -34,7 +34,9 @@ steps:
'$(akams-client-id)'
'$(microsoft-symbol-server-pat)'
'$(symweb-symbol-server-pat)'
+ '$(dnceng-symbol-server-pat)'
'$(dn-bot-all-orgs-build-rw-code-rw)'
+ '$(System.AccessToken)'
${{parameters.CustomSensitiveDataList}}
continueOnError: true
condition: always()
@@ -45,6 +47,7 @@ steps:
SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
+ condition: always()
- template: /eng/common/core-templates/steps/publish-build-artifacts.yml
parameters:
diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml
index 37133b55b75..0dde553c3eb 100644
--- a/eng/common/core-templates/steps/source-build.yml
+++ b/eng/common/core-templates/steps/source-build.yml
@@ -19,25 +19,12 @@ steps:
set -x
df -h
- # If file changes are detected, set CopyWipIntoInnerSourceBuildRepo to copy the WIP changes into the inner source build repo.
- internalRestoreArgs=
- if ! git diff --quiet; then
- internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true'
- # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo.
- # This only works if there is a username/email configured, which won't be the case in most CI runs.
- git config --get user.email
- if [ $? -ne 0 ]; then
- git config user.email dn-bot@microsoft.com
- git config user.name dn-bot
- fi
- fi
-
# If building on the internal project, the internal storage variable may be available (usually only if needed)
# In that case, add variables to allow the download of internal runtimes if the specified versions are not found
# in the default public locations.
internalRuntimeDownloadArgs=
if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then
- internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)'
+ internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://ci.dot.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://ci.dot.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)'
fi
buildConfig=Release
@@ -46,85 +33,39 @@ steps:
buildConfig='$(_BuildConfig)'
fi
- officialBuildArgs=
- if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then
- officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)'
- fi
-
targetRidArgs=
if [ '${{ parameters.platform.targetRID }}' != '' ]; then
targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}'
fi
- runtimeOsArgs=
- if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then
- runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}'
- fi
-
- baseOsArgs=
- if [ '${{ parameters.platform.baseOS }}' != '' ]; then
- baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}'
+ baseRidArgs=
+ if [ '${{ parameters.platform.baseRID }}' != '' ]; then
+ baseRidArgs='/p:BaseRid=${{ parameters.platform.baseRID }}'
fi
- publishArgs=
- if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then
- publishArgs='--publish'
- fi
-
- assetManifestFileName=SourceBuild_RidSpecific.xml
- if [ '${{ parameters.platform.name }}' != '' ]; then
- assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml
+ portableBuildArgs=
+ if [ '${{ parameters.platform.portableBuild }}' != '' ]; then
+ portableBuildArgs='/p:PortableBuild=${{ parameters.platform.portableBuild }}'
fi
${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \
--configuration $buildConfig \
- --restore --build --pack $publishArgs -bl \
+ --restore --build --pack -bl \
+ --source-build \
${{ parameters.platform.buildArguments }} \
- $officialBuildArgs \
$internalRuntimeDownloadArgs \
- $internalRestoreArgs \
$targetRidArgs \
- $runtimeOsArgs \
- $baseOsArgs \
- /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \
- /p:ArcadeBuildFromSource=true \
- /p:DotNetBuildSourceOnly=true \
- /p:DotNetBuildRepo=true \
- /p:AssetManifestFileName=$assetManifestFileName
+ $baseRidArgs \
+ $portableBuildArgs \
displayName: Build
-# Upload build logs for diagnosis.
-- task: CopyFiles@2
- displayName: Prepare BuildLogs staging directory
- inputs:
- SourceFolder: '$(Build.SourcesDirectory)'
- Contents: |
- **/*.log
- **/*.binlog
- artifacts/sb/prebuilt-report/**
- TargetFolder: '$(Build.StagingDirectory)/BuildLogs'
- CleanTargetFolder: true
- continueOnError: true
- condition: succeededOrFailed()
-
- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
parameters:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
args:
displayName: Publish BuildLogs
- targetPath: '$(Build.StagingDirectory)/BuildLogs'
+ targetPath: artifacts/log/${{ coalesce(variables._BuildConfig, 'Release') }}
artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)
continueOnError: true
condition: succeededOrFailed()
sbomEnabled: false # we don't need SBOM for logs
-
-# Manually inject component detection so that we can ignore the source build upstream cache, which contains
-# a nupkg cache of input packages (a local feed).
-# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir'
-# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets
-- template: /eng/common/core-templates/steps/component-governance.yml
- parameters:
- displayName: Component Detection (Exclude upstream cache)
- is1ESPipeline: ${{ parameters.is1ESPipeline }}
- componentGovernanceIgnoreDirectories: '$(Build.SourcesDirectory)/artifacts/sb/src/artifacts/obj/source-built-upstream-cache'
- disableComponentGovernance: ${{ eq(variables['System.TeamProject'], 'public') }}
diff --git a/eng/common/core-templates/steps/source-index-stage1-publish.yml b/eng/common/core-templates/steps/source-index-stage1-publish.yml
new file mode 100644
index 00000000000..99c2326fc19
--- /dev/null
+++ b/eng/common/core-templates/steps/source-index-stage1-publish.yml
@@ -0,0 +1,35 @@
+parameters:
+ sourceIndexUploadPackageVersion: 2.0.0-20250425.2
+ sourceIndexProcessBinlogPackageVersion: 1.0.1-20250425.2
+ sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
+ binlogPath: artifacts/log/Debug/Build.binlog
+
+steps:
+- task: UseDotNet@2
+ displayName: "Source Index: Use .NET 8 SDK"
+ inputs:
+ packageType: sdk
+ version: 8.0.x
+ installationPath: $(Agent.TempDirectory)/dotnet
+ workingDirectory: $(Agent.TempDirectory)
+
+- script: |
+ $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ displayName: "Source Index: Download netsourceindex Tools"
+ # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
+ workingDirectory: $(Agent.TempDirectory)
+
+- script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
+ displayName: "Source Index: Process Binlog into indexable sln"
+
+- ${{ if and(ne(parameters.runAsPublic, 'true'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - task: AzureCLI@2
+ displayName: "Source Index: Upload Source Index stage1 artifacts to Azure"
+ inputs:
+ azureSubscription: 'SourceDotNet Stage1 Publish'
+ addSpnToEnvironment: true
+ scriptType: 'ps'
+ scriptLocation: 'inlineScript'
+ inlineScript: |
+ $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1
diff --git a/eng/common/cross/arm64/tizen/tizen.patch b/eng/common/cross/arm64/tizen/tizen.patch
index af7c8be0590..2cebc547382 100644
--- a/eng/common/cross/arm64/tizen/tizen.patch
+++ b/eng/common/cross/arm64/tizen/tizen.patch
@@ -5,5 +5,5 @@ diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-littleaarch64)
--GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) )
+-GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-aarch64.so.1 ) )
+GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-aarch64.so.1 ) )
diff --git a/eng/common/cross/armel/armel.jessie.patch b/eng/common/cross/armel/armel.jessie.patch
deleted file mode 100644
index 2d261561935..00000000000
--- a/eng/common/cross/armel/armel.jessie.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-diff -u -r a/usr/include/urcu/uatomic/generic.h b/usr/include/urcu/uatomic/generic.h
---- a/usr/include/urcu/uatomic/generic.h 2014-10-22 15:00:58.000000000 -0700
-+++ b/usr/include/urcu/uatomic/generic.h 2020-10-30 21:38:28.550000000 -0700
-@@ -69,10 +69,10 @@
- #endif
- #ifdef UATOMIC_HAS_ATOMIC_SHORT
- case 2:
-- return __sync_val_compare_and_swap_2(addr, old, _new);
-+ return __sync_val_compare_and_swap_2((uint16_t*) addr, old, _new);
- #endif
- case 4:
-- return __sync_val_compare_and_swap_4(addr, old, _new);
-+ return __sync_val_compare_and_swap_4((uint32_t*) addr, old, _new);
- #if (CAA_BITS_PER_LONG == 64)
- case 8:
- return __sync_val_compare_and_swap_8(addr, old, _new);
-@@ -109,7 +109,7 @@
- return;
- #endif
- case 4:
-- __sync_and_and_fetch_4(addr, val);
-+ __sync_and_and_fetch_4((uint32_t*) addr, val);
- return;
- #if (CAA_BITS_PER_LONG == 64)
- case 8:
-@@ -148,7 +148,7 @@
- return;
- #endif
- case 4:
-- __sync_or_and_fetch_4(addr, val);
-+ __sync_or_and_fetch_4((uint32_t*) addr, val);
- return;
- #if (CAA_BITS_PER_LONG == 64)
- case 8:
-@@ -187,7 +187,7 @@
- return __sync_add_and_fetch_2(addr, val);
- #endif
- case 4:
-- return __sync_add_and_fetch_4(addr, val);
-+ return __sync_add_and_fetch_4((uint32_t*) addr, val);
- #if (CAA_BITS_PER_LONG == 64)
- case 8:
- return __sync_add_and_fetch_8(addr, val);
diff --git a/eng/common/cross/build-android-rootfs.sh b/eng/common/cross/build-android-rootfs.sh
index 7e9ba2b75ed..fbd8d80848a 100755
--- a/eng/common/cross/build-android-rootfs.sh
+++ b/eng/common/cross/build-android-rootfs.sh
@@ -6,10 +6,11 @@ usage()
{
echo "Creates a toolchain and sysroot used for cross-compiling for Android."
echo
- echo "Usage: $0 [BuildArch] [ApiLevel]"
+ echo "Usage: $0 [BuildArch] [ApiLevel] [--ndk NDKVersion]"
echo
echo "BuildArch is the target architecture of Android. Currently only arm64 is supported."
echo "ApiLevel is the target Android API level. API levels usually match to Android releases. See https://source.android.com/source/build-numbers.html"
+ echo "NDKVersion is the version of Android NDK. The default is r21. See https://developer.android.com/ndk/downloads/revision_history"
echo
echo "By default, the toolchain and sysroot will be generated in cross/android-rootfs/toolchain/[BuildArch]. You can change this behavior"
echo "by setting the TOOLCHAIN_DIR environment variable"
@@ -25,10 +26,15 @@ __BuildArch=arm64
__AndroidArch=aarch64
__AndroidToolchain=aarch64-linux-android
-for i in "$@"
- do
- lowerI="$(echo $i | tr "[:upper:]" "[:lower:]")"
- case $lowerI in
+while :; do
+ if [[ "$#" -le 0 ]]; then
+ break
+ fi
+
+ i=$1
+
+ lowerI="$(echo $i | tr "[:upper:]" "[:lower:]")"
+ case $lowerI in
-?|-h|--help)
usage
exit 1
@@ -43,6 +49,10 @@ for i in "$@"
__AndroidArch=arm
__AndroidToolchain=arm-linux-androideabi
;;
+ --ndk)
+ shift
+ __NDK_Version=$1
+ ;;
*[0-9])
__ApiLevel=$i
;;
@@ -50,8 +60,17 @@ for i in "$@"
__UnprocessedBuildArgs="$__UnprocessedBuildArgs $i"
;;
esac
+ shift
done
+if [[ "$__NDK_Version" == "r21" ]] || [[ "$__NDK_Version" == "r22" ]]; then
+ __NDK_File_Arch_Spec=-x86_64
+ __SysRoot=sysroot
+else
+ __NDK_File_Arch_Spec=
+ __SysRoot=toolchains/llvm/prebuilt/linux-x86_64/sysroot
+fi
+
# Obtain the location of the bash script to figure out where the root of the repo is.
__ScriptBaseDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
@@ -78,6 +97,7 @@ fi
echo "Target API level: $__ApiLevel"
echo "Target architecture: $__BuildArch"
+echo "NDK version: $__NDK_Version"
echo "NDK location: $__NDK_Dir"
echo "Target Toolchain location: $__ToolchainDir"
@@ -85,8 +105,8 @@ echo "Target Toolchain location: $__ToolchainDir"
if [ ! -d $__NDK_Dir ]; then
echo Downloading the NDK into $__NDK_Dir
mkdir -p $__NDK_Dir
- wget -q --progress=bar:force:noscroll --show-progress https://dl.google.com/android/repository/android-ndk-$__NDK_Version-linux-x86_64.zip -O $__CrossDir/android-ndk-$__NDK_Version-linux-x86_64.zip
- unzip -q $__CrossDir/android-ndk-$__NDK_Version-linux-x86_64.zip -d $__CrossDir
+ wget -q --progress=bar:force:noscroll --show-progress https://dl.google.com/android/repository/android-ndk-$__NDK_Version-linux$__NDK_File_Arch_Spec.zip -O $__CrossDir/android-ndk-$__NDK_Version-linux.zip
+ unzip -q $__CrossDir/android-ndk-$__NDK_Version-linux.zip -d $__CrossDir
fi
if [ ! -d $__lldb_Dir ]; then
@@ -116,16 +136,11 @@ for path in $(wget -qO- https://packages.termux.dev/termux-main-21/dists/stable/
fi
done
-cp -R "$__TmpDir/data/data/com.termux/files/usr/"* "$__ToolchainDir/sysroot/usr/"
+cp -R "$__TmpDir/data/data/com.termux/files/usr/"* "$__ToolchainDir/$__SysRoot/usr/"
# Generate platform file for build.sh script to assign to __DistroRid
echo "Generating platform file..."
-echo "RID=android.${__ApiLevel}-${__BuildArch}" > $__ToolchainDir/sysroot/android_platform
-
-echo "Now to build coreclr, libraries and installers; run:"
-echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \
- --subsetCategory coreclr
-echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \
- --subsetCategory libraries
-echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \
- --subsetCategory installer
+echo "RID=android.${__ApiLevel}-${__BuildArch}" > $__ToolchainDir/$__SysRoot/android_platform
+
+echo "Now to build coreclr, libraries and host; run:"
+echo ROOTFS_DIR=$(realpath $__ToolchainDir/$__SysRoot) ./build.sh clr+libs+host --cross --arch $__BuildArch
diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh
index 4b5e8d7166b..d6f005b5dab 100755
--- a/eng/common/cross/build-rootfs.sh
+++ b/eng/common/cross/build-rootfs.sh
@@ -5,7 +5,7 @@ set -e
usage()
{
echo "Usage: $0 [BuildArch] [CodeName] [lldbx.y] [llvmx[.y]] [--skipunmount] --rootfsdir ]"
- echo "BuildArch can be: arm(default), arm64, armel, armv6, ppc64le, riscv64, s390x, x64, x86"
+ echo "BuildArch can be: arm(default), arm64, armel, armv6, loongarch64, ppc64le, riscv64, s390x, x64, x86"
echo "CodeName - optional, Code name for Linux, can be: xenial(default), zesty, bionic, alpine"
echo " for alpine can be specified with version: alpineX.YY or alpineedge"
echo " for FreeBSD can be: freebsd13, freebsd14"
@@ -15,6 +15,7 @@ usage()
echo "llvmx[.y] - optional, LLVM version for LLVM related packages."
echo "--skipunmount - optional, will skip the unmount of rootfs folder."
echo "--skipsigcheck - optional, will skip package signature checks (allowing untrusted packages)."
+ echo "--skipemulation - optional, will skip qemu and debootstrap requirement when building environment for debian based systems."
echo "--use-mirror - optional, use mirror URL to fetch resources, when available."
echo "--jobs N - optional, restrict to N jobs."
exit 1
@@ -52,28 +53,27 @@ __UbuntuPackages+=" symlinks"
__UbuntuPackages+=" libicu-dev"
__UbuntuPackages+=" liblttng-ust-dev"
__UbuntuPackages+=" libunwind8-dev"
-__UbuntuPackages+=" libnuma-dev"
__AlpinePackages+=" gettext-dev"
__AlpinePackages+=" icu-dev"
__AlpinePackages+=" libunwind-dev"
__AlpinePackages+=" lttng-ust-dev"
__AlpinePackages+=" compiler-rt"
-__AlpinePackages+=" numactl-dev"
# runtime libraries' dependencies
__UbuntuPackages+=" libcurl4-openssl-dev"
__UbuntuPackages+=" libkrb5-dev"
__UbuntuPackages+=" libssl-dev"
__UbuntuPackages+=" zlib1g-dev"
+__UbuntuPackages+=" libbrotli-dev"
__AlpinePackages+=" curl-dev"
__AlpinePackages+=" krb5-dev"
__AlpinePackages+=" openssl-dev"
__AlpinePackages+=" zlib-dev"
-__FreeBSDBase="13.3-RELEASE"
-__FreeBSDPkg="1.17.0"
+__FreeBSDBase="13.4-RELEASE"
+__FreeBSDPkg="1.21.3"
__FreeBSDABI="13"
__FreeBSDPackages="libunwind"
__FreeBSDPackages+=" icu"
@@ -91,18 +91,18 @@ __HaikuPackages="gcc_syslibs"
__HaikuPackages+=" gcc_syslibs_devel"
__HaikuPackages+=" gmp"
__HaikuPackages+=" gmp_devel"
-__HaikuPackages+=" icu66"
-__HaikuPackages+=" icu66_devel"
+__HaikuPackages+=" icu[0-9]+"
+__HaikuPackages+=" icu[0-9]*_devel"
__HaikuPackages+=" krb5"
__HaikuPackages+=" krb5_devel"
__HaikuPackages+=" libiconv"
__HaikuPackages+=" libiconv_devel"
-__HaikuPackages+=" llvm12_libunwind"
-__HaikuPackages+=" llvm12_libunwind_devel"
+__HaikuPackages+=" llvm[0-9]*_libunwind"
+__HaikuPackages+=" llvm[0-9]*_libunwind_devel"
__HaikuPackages+=" mpfr"
__HaikuPackages+=" mpfr_devel"
-__HaikuPackages+=" openssl"
-__HaikuPackages+=" openssl_devel"
+__HaikuPackages+=" openssl3"
+__HaikuPackages+=" openssl3_devel"
__HaikuPackages+=" zlib"
__HaikuPackages+=" zlib_devel"
@@ -128,10 +128,12 @@ __AlpineKeys='
616adfeb:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq0BFD1D4lIxQcsqEpQzU\npNCYM3aP1V/fxxVdT4DWvSI53JHTwHQamKdMWtEXetWVbP5zSROniYKFXd/xrD9X\n0jiGHey3lEtylXRIPxe5s+wXoCmNLcJVnvTcDtwx/ne2NLHxp76lyc25At+6RgE6\nADjLVuoD7M4IFDkAsd8UQ8zM0Dww9SylIk/wgV3ZkifecvgUQRagrNUdUjR56EBZ\nraQrev4hhzOgwelT0kXCu3snbUuNY/lU53CoTzfBJ5UfEJ5pMw1ij6X0r5S9IVsy\nKLWH1hiO0NzU2c8ViUYCly4Fe9xMTFc6u2dy/dxf6FwERfGzETQxqZvSfrRX+GLj\n/QZAXiPg5178hT/m0Y3z5IGenIC/80Z9NCi+byF1WuJlzKjDcF/TU72zk0+PNM/H\nKuppf3JT4DyjiVzNC5YoWJT2QRMS9KLP5iKCSThwVceEEg5HfhQBRT9M6KIcFLSs\nmFjx9kNEEmc1E8hl5IR3+3Ry8G5/bTIIruz14jgeY9u5jhL8Vyyvo41jgt9sLHR1\n/J1TxKfkgksYev7PoX6/ZzJ1ksWKZY5NFoDXTNYUgzFUTOoEaOg3BAQKadb3Qbbq\nXIrxmPBdgrn9QI7NCgfnAY3Tb4EEjs3ON/BNyEhUENcXOH6I1NbcuBQ7g9P73kE4\nVORdoc8MdJ5eoKBpO8Ww8HECAwEAAQ==
616ae350:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyduVzi1mWm+lYo2Tqt/0\nXkCIWrDNP1QBMVPrE0/ZlU2bCGSoo2Z9FHQKz/mTyMRlhNqTfhJ5qU3U9XlyGOPJ\npiM+b91g26pnpXJ2Q2kOypSgOMOPA4cQ42PkHBEqhuzssfj9t7x47ppS94bboh46\nxLSDRff/NAbtwTpvhStV3URYkxFG++cKGGa5MPXBrxIp+iZf9GnuxVdST5PGiVGP\nODL/b69sPJQNbJHVquqUTOh5Ry8uuD2WZuXfKf7/C0jC/ie9m2+0CttNu9tMciGM\nEyKG1/Xhk5iIWO43m4SrrT2WkFlcZ1z2JSf9Pjm4C2+HovYpihwwdM/OdP8Xmsnr\nDzVB4YvQiW+IHBjStHVuyiZWc+JsgEPJzisNY0Wyc/kNyNtqVKpX6dRhMLanLmy+\nf53cCSI05KPQAcGj6tdL+D60uKDkt+FsDa0BTAobZ31OsFVid0vCXtsbplNhW1IF\nHwsGXBTVcfXg44RLyL8Lk/2dQxDHNHzAUslJXzPxaHBLmt++2COa2EI1iWlvtznk\nOk9WP8SOAIj+xdqoiHcC4j72BOVVgiITIJNHrbppZCq6qPR+fgXmXa+sDcGh30m6\n9Wpbr28kLMSHiENCWTdsFij+NQTd5S47H7XTROHnalYDuF1RpS+DpQidT5tUimaT\nJZDr++FjKrnnijbyNF8b98UCAwEAAQ==
616db30d:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpUpyWDWjlUk3smlWeA0\nlIMW+oJ38t92CRLHH3IqRhyECBRW0d0aRGtq7TY8PmxjjvBZrxTNDpJT6KUk4LRm\na6A6IuAI7QnNK8SJqM0DLzlpygd7GJf8ZL9SoHSH+gFsYF67Cpooz/YDqWrlN7Vw\ntO00s0B+eXy+PCXYU7VSfuWFGK8TGEv6HfGMALLjhqMManyvfp8hz3ubN1rK3c8C\nUS/ilRh1qckdbtPvoDPhSbTDmfU1g/EfRSIEXBrIMLg9ka/XB9PvWRrekrppnQzP\nhP9YE3x/wbFc5QqQWiRCYyQl/rgIMOXvIxhkfe8H5n1Et4VAorkpEAXdsfN8KSVv\nLSMazVlLp9GYq5SUpqYX3KnxdWBgN7BJoZ4sltsTpHQ/34SXWfu3UmyUveWj7wp0\nx9hwsPirVI00EEea9AbP7NM2rAyu6ukcm4m6ATd2DZJIViq2es6m60AE6SMCmrQF\nwmk4H/kdQgeAELVfGOm2VyJ3z69fQuywz7xu27S6zTKi05Qlnohxol4wVb6OB7qG\nLPRtK9ObgzRo/OPumyXqlzAi/Yvyd1ZQk8labZps3e16bQp8+pVPiumWioMFJDWV\nGZjCmyMSU8V6MB6njbgLHoyg2LCukCAeSjbPGGGYhnKLm1AKSoJh3IpZuqcKCk5C\n8CM1S15HxV78s9dFntEqIokCAwEAAQ==
+66ba20fe:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtfB12w4ZgqsXWZDfUAV/\n6Y4aHUKIu3q4SXrNZ7CXF9nXoAVYrS7NAxJdAodsY3vPCN0g5O8DFXR+390LdOuQ\n+HsGKCc1k5tX5ZXld37EZNTNSbR0k+NKhd9h6X3u6wqPOx7SIKxwAQR8qeeFq4pP\nrt9GAGlxtuYgzIIcKJPwE0dZlcBCg+GnptCUZXp/38BP1eYC+xTXSL6Muq1etYfg\nodXdb7Yl+2h1IHuOwo5rjgY5kpY7GcAs8AjGk3lDD/av60OTYccknH0NCVSmPoXK\nvrxDBOn0LQRNBLcAfnTKgHrzy0Q5h4TNkkyTgxkoQw5ObDk9nnabTxql732yy9BY\ns+hM9+dSFO1HKeVXreYSA2n1ndF18YAvAumzgyqzB7I4pMHXq1kC/8bONMJxwSkS\nYm6CoXKyavp7RqGMyeVpRC7tV+blkrrUml0BwNkxE+XnwDRB3xDV6hqgWe0XrifD\nYTfvd9ScZQP83ip0r4IKlq4GMv/R5shcCRJSkSZ6QSGshH40JYSoiwJf5FHbj9ND\n7do0UAqebWo4yNx63j/wb2ULorW3AClv0BCFSdPsIrCStiGdpgJDBR2P2NZOCob3\nG9uMj+wJD6JJg2nWqNJxkANXX37Qf8plgzssrhrgOvB0fjjS7GYhfkfmZTJ0wPOw\nA8+KzFseBh4UFGgue78KwgkCAwEAAQ==
'
__Keyring=
__KeyringFile="/usr/share/keyrings/ubuntu-archive-keyring.gpg"
__SkipSigCheck=0
+__SkipEmulation=0
__UseMirror=0
__UnprocessedBuildArgs=
@@ -162,9 +164,13 @@ while :; do
armel)
__BuildArch=armel
__UbuntuArch=armel
- __UbuntuRepo="http://ftp.debian.org/debian/"
- __CodeName=jessie
+ __UbuntuRepo="http://archive.debian.org/debian/"
+ __CodeName=buster
__KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
+ __LLDB_Package="liblldb-6.0-dev"
+ __UbuntuPackages="${__UbuntuPackages// libomp-dev/}"
+ __UbuntuPackages="${__UbuntuPackages// libomp5/}"
+ __UbuntuSuites=
;;
armv6)
__BuildArch=armv6
@@ -180,6 +186,18 @@ while :; do
__Keyring="--keyring $__KeyringFile"
fi
;;
+ loongarch64)
+ __BuildArch=loongarch64
+ __AlpineArch=loongarch64
+ __QEMUArch=loongarch64
+ __UbuntuArch=loong64
+ __UbuntuSuites=unreleased
+ __LLDB_Package="liblldb-19-dev"
+
+ if [[ "$__CodeName" == "sid" ]]; then
+ __UbuntuRepo="http://ftp.ports.debian.org/debian-ports/"
+ fi
+ ;;
riscv64)
__BuildArch=riscv64
__AlpineArch=riscv64
@@ -264,46 +282,23 @@ while :; do
;;
xenial) # Ubuntu 16.04
- if [[ "$__CodeName" != "jessie" ]]; then
- __CodeName=xenial
- fi
- ;;
- zesty) # Ubuntu 17.04
- if [[ "$__CodeName" != "jessie" ]]; then
- __CodeName=zesty
- fi
+ __CodeName=xenial
;;
bionic) # Ubuntu 18.04
- if [[ "$__CodeName" != "jessie" ]]; then
- __CodeName=bionic
- fi
+ __CodeName=bionic
;;
focal) # Ubuntu 20.04
- if [[ "$__CodeName" != "jessie" ]]; then
- __CodeName=focal
- fi
+ __CodeName=focal
;;
jammy) # Ubuntu 22.04
- if [[ "$__CodeName" != "jessie" ]]; then
- __CodeName=jammy
- fi
+ __CodeName=jammy
;;
noble) # Ubuntu 24.04
- if [[ "$__CodeName" != "jessie" ]]; then
- __CodeName=noble
- fi
+ __CodeName=noble
if [[ -n "$__LLDB_Package" ]]; then
__LLDB_Package="liblldb-18-dev"
fi
;;
- jessie) # Debian 8
- __CodeName=jessie
- __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
-
- if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://ftp.debian.org/debian/"
- fi
- ;;
stretch) # Debian 9
__CodeName=stretch
__LLDB_Package="liblldb-6.0-dev"
@@ -319,7 +314,7 @@ while :; do
__KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://ftp.debian.org/debian/"
+ __UbuntuRepo="http://archive.debian.org/debian/"
fi
;;
bullseye) # Debian 11
@@ -340,10 +335,28 @@ while :; do
;;
sid) # Debian sid
__CodeName=sid
- __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
+ __UbuntuSuites=
- if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://ftp.debian.org/debian/"
+ # Debian-Ports architectures need different values
+ case "$__UbuntuArch" in
+ amd64|arm64|armel|armhf|i386|mips64el|ppc64el|riscv64|s390x)
+ __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
+
+ if [[ -z "$__UbuntuRepo" ]]; then
+ __UbuntuRepo="http://ftp.debian.org/debian/"
+ fi
+ ;;
+ *)
+ __KeyringFile="/usr/share/keyrings/debian-ports-archive-keyring.gpg"
+
+ if [[ -z "$__UbuntuRepo" ]]; then
+ __UbuntuRepo="http://ftp.ports.debian.org/debian-ports/"
+ fi
+ ;;
+ esac
+
+ if [[ -e "$__KeyringFile" ]]; then
+ __Keyring="--keyring $__KeyringFile"
fi
;;
tizen)
@@ -370,7 +383,7 @@ while :; do
;;
freebsd14)
__CodeName=freebsd
- __FreeBSDBase="14.0-RELEASE"
+ __FreeBSDBase="14.2-RELEASE"
__FreeBSDABI="14"
__SkipUnmount=1
;;
@@ -388,6 +401,9 @@ while :; do
--skipsigcheck)
__SkipSigCheck=1
;;
+ --skipemulation)
+ __SkipEmulation=1
+ ;;
--rootfsdir|-rootfsdir)
shift
__RootfsDir="$1"
@@ -420,16 +436,15 @@ case "$__AlpineVersion" in
elif [[ "$__AlpineArch" == "x86" ]]; then
__AlpineVersion=3.17 # minimum version that supports lldb-dev
__AlpinePackages+=" llvm15-libs"
- elif [[ "$__AlpineArch" == "riscv64" ]]; then
+ elif [[ "$__AlpineArch" == "riscv64" || "$__AlpineArch" == "loongarch64" ]]; then
+ __AlpineVersion=3.21 # minimum version that supports lldb-dev
+ __AlpinePackages+=" llvm19-libs"
+ elif [[ -n "$__AlpineMajorVersion" ]]; then
+ # use whichever alpine version is provided and select the latest toolchain libs
__AlpineLlvmLibsLookup=1
- __AlpineVersion=edge # minimum version with APKINDEX.tar.gz (packages archive)
else
__AlpineVersion=3.13 # 3.13 to maximize compatibility
__AlpinePackages+=" llvm10-libs"
-
- if [[ "$__AlpineArch" == "armv7" ]]; then
- __AlpinePackages="${__AlpinePackages//numactl-dev/}"
- fi
fi
esac
@@ -439,15 +454,6 @@ if [[ "$__AlpineVersion" =~ 3\.1[345] ]]; then
__AlpinePackages="${__AlpinePackages/compiler-rt/compiler-rt-static}"
fi
-if [[ "$__BuildArch" == "armel" ]]; then
- __LLDB_Package="lldb-3.5-dev"
-fi
-
-if [[ "$__CodeName" == "xenial" && "$__UbuntuArch" == "armhf" ]]; then
- # libnuma-dev is not available on armhf for xenial
- __UbuntuPackages="${__UbuntuPackages//libnuma-dev/}"
-fi
-
__UbuntuPackages+=" ${__LLDB_Package:-}"
if [[ -z "$__UbuntuRepo" ]]; then
@@ -496,7 +502,7 @@ if [[ "$__CodeName" == "alpine" ]]; then
arch="$(uname -m)"
ensureDownloadTool
-
+
if [[ "$__hasWget" == 1 ]]; then
wget -P "$__ApkToolsDir" "https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v$__ApkToolsVersion/$arch/apk.static"
else
@@ -512,11 +518,6 @@ if [[ "$__CodeName" == "alpine" ]]; then
echo "$__ApkToolsSHA512SUM $__ApkToolsDir/apk.static" | sha512sum -c
chmod +x "$__ApkToolsDir/apk.static"
- if [[ -f "/usr/bin/qemu-$__QEMUArch-static" ]]; then
- mkdir -p "$__RootfsDir"/usr/bin
- cp -v "/usr/bin/qemu-$__QEMUArch-static" "$__RootfsDir/usr/bin"
- fi
-
if [[ "$__AlpineVersion" == "edge" ]]; then
version=edge
else
@@ -536,6 +537,10 @@ if [[ "$__CodeName" == "alpine" ]]; then
__ApkSignatureArg="--keys-dir $__ApkKeysDir"
fi
+ if [[ "$__SkipEmulation" == "1" ]]; then
+ __NoEmulationArg="--no-scripts"
+ fi
+
# initialize DB
# shellcheck disable=SC2086
"$__ApkToolsDir/apk.static" \
@@ -557,7 +562,7 @@ if [[ "$__CodeName" == "alpine" ]]; then
"$__ApkToolsDir/apk.static" \
-X "http://dl-cdn.alpinelinux.org/alpine/$version/main" \
-X "http://dl-cdn.alpinelinux.org/alpine/$version/community" \
- -U $__ApkSignatureArg --root "$__RootfsDir" --arch "$__AlpineArch" \
+ -U $__ApkSignatureArg --root "$__RootfsDir" --arch "$__AlpineArch" $__NoEmulationArg \
add $__AlpinePackages
rm -r "$__ApkToolsDir"
@@ -573,7 +578,7 @@ elif [[ "$__CodeName" == "freebsd" ]]; then
curl -SL "https://download.freebsd.org/ftp/releases/${__FreeBSDArch}/${__FreeBSDMachineArch}/${__FreeBSDBase}/base.txz" | tar -C "$__RootfsDir" -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version
fi
echo "ABI = \"FreeBSD:${__FreeBSDABI}:${__FreeBSDMachineArch}\"; FINGERPRINTS = \"${__RootfsDir}/usr/share/keys\"; REPOS_DIR = [\"${__RootfsDir}/etc/pkg\"]; REPO_AUTOUPDATE = NO; RUN_SCRIPTS = NO;" > "${__RootfsDir}"/usr/local/etc/pkg.conf
- echo "FreeBSD: { url: \"pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"${__RootfsDir}/usr/share/keys/pkg\", enabled: yes }" > "${__RootfsDir}"/etc/pkg/FreeBSD.conf
+ echo "FreeBSD: { url: \"pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"/usr/share/keys/pkg\", enabled: yes }" > "${__RootfsDir}"/etc/pkg/FreeBSD.conf
mkdir -p "$__RootfsDir"/tmp
# get and build package manager
if [[ "$__hasWget" == 1 ]]; then
@@ -681,7 +686,7 @@ elif [[ "$__CodeName" == "haiku" ]]; then
ensureDownloadTool
- echo "Downloading Haiku package tool"
+ echo "Downloading Haiku package tools"
git clone https://github.com/haiku/haiku-toolchains-ubuntu --depth 1 "$__RootfsDir/tmp/script"
if [[ "$__hasWget" == 1 ]]; then
wget -O "$__RootfsDir/tmp/download/hosttools.zip" "$("$__RootfsDir/tmp/script/fetch.sh" --hosttools)"
@@ -691,34 +696,42 @@ elif [[ "$__CodeName" == "haiku" ]]; then
unzip -o "$__RootfsDir/tmp/download/hosttools.zip" -d "$__RootfsDir/tmp/bin"
- DepotBaseUrl="https://depot.haiku-os.org/__api/v2/pkg/get-pkg"
- HpkgBaseUrl="https://eu.hpkg.haiku-os.org/haiku/master/$__HaikuArch/current"
+ HaikuBaseUrl="https://eu.hpkg.haiku-os.org/haiku/master/$__HaikuArch/current"
+ HaikuPortsBaseUrl="https://eu.hpkg.haiku-os.org/haikuports/master/$__HaikuArch/current"
+
+ echo "Downloading HaikuPorts package repository index..."
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -P "$__RootfsDir/tmp/download" "$HaikuPortsBaseUrl/repo"
+ else
+ curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HaikuPortsBaseUrl/repo"
+ fi
- # Download Haiku packages
echo "Downloading Haiku packages"
read -ra array <<<"$__HaikuPackages"
for package in "${array[@]}"; do
echo "Downloading $package..."
- # API documented here: https://github.com/haiku/haikudepotserver/blob/master/haikudepotserver-api2/src/main/resources/api2/pkg.yaml#L60
- # The schema here: https://github.com/haiku/haikudepotserver/blob/master/haikudepotserver-api2/src/main/resources/api2/pkg.yaml#L598
+ hpkgFilename="$(LD_LIBRARY_PATH="$__RootfsDir/tmp/bin" "$__RootfsDir/tmp/bin/package_repo" list -f "$__RootfsDir/tmp/download/repo" |
+ grep -E "${package}-" | sort -V | tail -n 1 | xargs)"
+ if [ -z "$hpkgFilename" ]; then
+ >&2 echo "ERROR: package $package missing."
+ exit 1
+ fi
+ echo "Resolved filename: $hpkgFilename..."
+ hpkgDownloadUrl="$HaikuPortsBaseUrl/packages/$hpkgFilename"
if [[ "$__hasWget" == 1 ]]; then
- hpkgDownloadUrl="$(wget -qO- --post-data '{"name":"'"$package"'","repositorySourceCode":"haikuports_'$__HaikuArch'","versionType":"LATEST","naturalLanguageCode":"en"}' \
- --header 'Content-Type:application/json' "$DepotBaseUrl" | jq -r '.result.versions[].hpkgDownloadURL')"
wget -P "$__RootfsDir/tmp/download" "$hpkgDownloadUrl"
else
- hpkgDownloadUrl="$(curl -sSL -XPOST --data '{"name":"'"$package"'","repositorySourceCode":"haikuports_'$__HaikuArch'","versionType":"LATEST","naturalLanguageCode":"en"}' \
- --header 'Content-Type:application/json' "$DepotBaseUrl" | jq -r '.result.versions[].hpkgDownloadURL')"
curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$hpkgDownloadUrl"
fi
done
for package in haiku haiku_devel; do
echo "Downloading $package..."
if [[ "$__hasWget" == 1 ]]; then
- hpkgVersion="$(wget -qO- "$HpkgBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')"
- wget -P "$__RootfsDir/tmp/download" "$HpkgBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg"
+ hpkgVersion="$(wget -qO- "$HaikuBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')"
+ wget -P "$__RootfsDir/tmp/download" "$HaikuBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg"
else
- hpkgVersion="$(curl -sSL "$HpkgBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')"
- curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HpkgBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg"
+ hpkgVersion="$(curl -sSL "$HaikuBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')"
+ curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HaikuBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg"
fi
done
@@ -744,25 +757,67 @@ elif [[ "$__CodeName" == "haiku" ]]; then
popd
rm -rf "$__RootfsDir/tmp"
elif [[ -n "$__CodeName" ]]; then
+ __Suites="$__CodeName $(for suite in $__UbuntuSuites; do echo -n "$__CodeName-$suite "; done)"
+
+ if [[ "$__SkipEmulation" == "1" ]]; then
+ if [[ -z "$AR" ]]; then
+ if command -v ar &>/dev/null; then
+ AR="$(command -v ar)"
+ elif command -v llvm-ar &>/dev/null; then
+ AR="$(command -v llvm-ar)"
+ else
+ echo "Unable to find ar or llvm-ar on PATH, add them to PATH or set AR environment variable pointing to the available AR tool"
+ exit 1
+ fi
+ fi
+
+ PYTHON=${PYTHON_EXECUTABLE:-python3}
+
+ # shellcheck disable=SC2086,SC2046
+ echo running "$PYTHON" "$__CrossDir/install-debs.py" --arch "$__UbuntuArch" --mirror "$__UbuntuRepo" --rootfsdir "$__RootfsDir" --artool "$AR" \
+ $(for suite in $__Suites; do echo -n "--suite $suite "; done) \
+ $__UbuntuPackages
+
+ # shellcheck disable=SC2086,SC2046
+ "$PYTHON" "$__CrossDir/install-debs.py" --arch "$__UbuntuArch" --mirror "$__UbuntuRepo" --rootfsdir "$__RootfsDir" --artool "$AR" \
+ $(for suite in $__Suites; do echo -n "--suite $suite "; done) \
+ $__UbuntuPackages
+ exit 0
+ fi
+
+ __UpdateOptions=
if [[ "$__SkipSigCheck" == "0" ]]; then
__Keyring="$__Keyring --force-check-gpg"
+ else
+ __Keyring=
+ __UpdateOptions="--allow-unauthenticated --allow-insecure-repositories"
fi
# shellcheck disable=SC2086
echo running debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"
- debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"
+ # shellcheck disable=SC2086
+ if ! debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"; then
+ echo "debootstrap failed! dumping debootstrap.log"
+ cat "$__RootfsDir/debootstrap/debootstrap.log"
+ exit 1
+ fi
+
+ rm -rf "$__RootfsDir"/etc/apt/*.{sources,list} "$__RootfsDir"/etc/apt/sources.list.d
mkdir -p "$__RootfsDir/etc/apt/sources.list.d/"
+
+ # shellcheck disable=SC2086
cat > "$__RootfsDir/etc/apt/sources.list.d/$__CodeName.sources" < token2) - (token1 < token2)
+ else:
+ return -1 if isinstance(token1, str) else 1
+
+ return len(tokens1) - len(tokens2)
+
+def compare_debian_versions(version1, version2):
+ """Compare two Debian package versions."""
+ epoch1, upstream1, revision1 = parse_debian_version(version1)
+ epoch2, upstream2, revision2 = parse_debian_version(version2)
+
+ if epoch1 != epoch2:
+ return epoch1 - epoch2
+
+ result = compare_upstream_version(upstream1, upstream2)
+ if result != 0:
+ return result
+
+ return compare_upstream_version(revision1, revision2)
+
+def resolve_dependencies(packages, aliases, desired_packages):
+ """Recursively resolves dependencies for the desired packages."""
+ resolved = []
+ to_process = deque(desired_packages)
+
+ while to_process:
+ current = to_process.popleft()
+ resolved_package = current if current in packages else aliases.get(current, [None])[0]
+
+ if not resolved_package:
+ print(f"Error: Package '{current}' was not found in the available packages.")
+ sys.exit(1)
+
+ if resolved_package not in resolved:
+ resolved.append(resolved_package)
+
+ deps = packages.get(resolved_package, {}).get("Depends", "")
+ if deps:
+ deps = [dep.split(' ')[0] for dep in deps.split(', ') if dep]
+ for dep in deps:
+ if dep not in resolved and dep not in to_process and dep in packages:
+ to_process.append(dep)
+
+ return resolved
+
+def parse_package_index(content):
+ """Parses the Packages.gz file and returns package information."""
+ packages = {}
+ aliases = {}
+ entries = re.split(r'\n\n+', content)
+
+ for entry in entries:
+ fields = dict(re.findall(r'^(\S+): (.+)$', entry, re.MULTILINE))
+ if "Package" in fields:
+ package_name = fields["Package"]
+ version = fields.get("Version")
+ filename = fields.get("Filename")
+ depends = fields.get("Depends")
+ provides = fields.get("Provides", None)
+
+ # Only update if package_name is not in packages or if the new version is higher
+ if package_name not in packages or compare_debian_versions(version, packages[package_name]["Version"]) > 0:
+ packages[package_name] = {
+ "Version": version,
+ "Filename": filename,
+ "Depends": depends
+ }
+
+ # Update aliases if package provides any alternatives
+ if provides:
+ provides_list = [x.strip() for x in provides.split(",")]
+ for alias in provides_list:
+ # Strip version specifiers
+ alias_name = re.sub(r'\s*\(=.*\)', '', alias)
+ if alias_name not in aliases:
+ aliases[alias_name] = []
+ if package_name not in aliases[alias_name]:
+ aliases[alias_name].append(package_name)
+
+ return packages, aliases
+
+def install_packages(mirror, packages_info, aliases, tmp_dir, extract_dir, ar_tool, desired_packages):
+ """Downloads .deb files and extracts them."""
+ resolved_packages = resolve_dependencies(packages_info, aliases, desired_packages)
+ print(f"Resolved packages (including dependencies): {resolved_packages}")
+
+ packages_to_download = {}
+
+ for pkg in resolved_packages:
+ if pkg in packages_info:
+ packages_to_download[pkg] = packages_info[pkg]
+
+ if pkg in aliases:
+ for alias in aliases[pkg]:
+ if alias in packages_info:
+ packages_to_download[alias] = packages_info[alias]
+
+ asyncio.run(download_deb_files_parallel(mirror, packages_to_download, tmp_dir))
+
+ package_to_deb_file_map = {}
+ for pkg in resolved_packages:
+ pkg_info = packages_info.get(pkg)
+ if pkg_info:
+ deb_filename = pkg_info.get("Filename")
+ if deb_filename:
+ deb_file_path = os.path.join(tmp_dir, os.path.basename(deb_filename))
+ package_to_deb_file_map[pkg] = deb_file_path
+
+ for pkg in reversed(resolved_packages):
+ deb_file = package_to_deb_file_map.get(pkg)
+ if deb_file and os.path.exists(deb_file):
+ extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool)
+
+ print("All done!")
+
+def extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool):
+ """Extract .deb file contents"""
+
+ os.makedirs(extract_dir, exist_ok=True)
+
+ with tempfile.TemporaryDirectory(dir=tmp_dir) as tmp_subdir:
+ result = subprocess.run(f"{ar_tool} t {os.path.abspath(deb_file)}", cwd=tmp_subdir, check=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ tar_filename = None
+ for line in result.stdout.decode().splitlines():
+ if line.startswith("data.tar"):
+ tar_filename = line.strip()
+ break
+
+ if not tar_filename:
+ raise FileNotFoundError(f"Could not find 'data.tar.*' in {deb_file}.")
+
+ tar_file_path = os.path.join(tmp_subdir, tar_filename)
+ print(f"Extracting {tar_filename} from {deb_file}..")
+
+ subprocess.run(f"{ar_tool} p {os.path.abspath(deb_file)} {tar_filename} > {tar_file_path}", check=True, shell=True)
+
+ file_extension = os.path.splitext(tar_file_path)[1].lower()
+
+ if file_extension == ".xz":
+ mode = "r:xz"
+ elif file_extension == ".gz":
+ mode = "r:gz"
+ elif file_extension == ".zst":
+ # zstd is not supported by standard library yet
+ decompressed_tar_path = tar_file_path.replace(".zst", "")
+ with open(tar_file_path, "rb") as zst_file, open(decompressed_tar_path, "wb") as decompressed_file:
+ dctx = zstandard.ZstdDecompressor()
+ dctx.copy_stream(zst_file, decompressed_file)
+
+ tar_file_path = decompressed_tar_path
+ mode = "r"
+ else:
+ raise ValueError(f"Unsupported compression format: {file_extension}")
+
+ with tarfile.open(tar_file_path, mode) as tar:
+ tar.extractall(path=extract_dir, filter='fully_trusted')
+
+def finalize_setup(rootfsdir):
+ lib_dir = os.path.join(rootfsdir, 'lib')
+ usr_lib_dir = os.path.join(rootfsdir, 'usr', 'lib')
+
+ if os.path.exists(lib_dir):
+ if os.path.islink(lib_dir):
+ os.remove(lib_dir)
+ else:
+ os.makedirs(usr_lib_dir, exist_ok=True)
+
+ for item in os.listdir(lib_dir):
+ src = os.path.join(lib_dir, item)
+ dest = os.path.join(usr_lib_dir, item)
+
+ if os.path.isdir(src):
+ shutil.copytree(src, dest, dirs_exist_ok=True)
+ else:
+ shutil.copy2(src, dest)
+
+ shutil.rmtree(lib_dir)
+
+ os.symlink(usr_lib_dir, lib_dir)
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description="Generate rootfs for .NET runtime on Debian-like OS")
+ parser.add_argument("--distro", required=False, help="Distro name (e.g., debian, ubuntu, etc.)")
+ parser.add_argument("--arch", required=True, help="Architecture (e.g., amd64, loong64, etc.)")
+ parser.add_argument("--rootfsdir", required=True, help="Destination directory.")
+ parser.add_argument('--suite', required=True, action='append', help='Specify one or more repository suites to collect index data.')
+ parser.add_argument("--mirror", required=False, help="Mirror (e.g., http://ftp.debian.org/debian-ports etc.)")
+ parser.add_argument("--artool", required=False, default="ar", help="ar tool to extract debs (e.g., ar, llvm-ar etc.)")
+ parser.add_argument("packages", nargs="+", help="List of package names to be installed.")
+
+ args = parser.parse_args()
+
+ if args.mirror is None:
+ if args.distro == "ubuntu":
+ args.mirror = "http://archive.ubuntu.com/ubuntu" if args.arch in ["amd64", "i386"] else "http://ports.ubuntu.com/ubuntu-ports"
+ elif args.distro == "debian":
+ args.mirror = "http://ftp.debian.org/debian-ports"
+ else:
+ raise Exception("Unsupported distro")
+
+ DESIRED_PACKAGES = args.packages + [ # base packages
+ "dpkg",
+ "busybox",
+ "libc-bin",
+ "base-files",
+ "base-passwd",
+ "debianutils"
+ ]
+
+ print(f"Creating rootfs. rootfsdir: {args.rootfsdir}, distro: {args.distro}, arch: {args.arch}, suites: {args.suite}, mirror: {args.mirror}")
+
+ package_index_content = asyncio.run(download_package_index_parallel(args.mirror, args.arch, args.suite))
+
+ packages_info, aliases = parse_package_index(package_index_content)
+
+ with tempfile.TemporaryDirectory() as tmp_dir:
+ install_packages(args.mirror, packages_info, aliases, tmp_dir, args.rootfsdir, args.artool, DESIRED_PACKAGES)
+
+ finalize_setup(args.rootfsdir)
diff --git a/eng/common/cross/tizen-fetch.sh b/eng/common/cross/tizen-fetch.sh
index 28936ceef3a..37c3a61f1de 100755
--- a/eng/common/cross/tizen-fetch.sh
+++ b/eng/common/cross/tizen-fetch.sh
@@ -156,13 +156,8 @@ fetch_tizen_pkgs()
done
}
-if [ "$TIZEN_ARCH" == "riscv64" ]; then
- BASE="Tizen-Base-RISCV"
- UNIFIED="Tizen-Unified-RISCV"
-else
- BASE="Tizen-Base"
- UNIFIED="Tizen-Unified"
-fi
+BASE="Tizen-Base"
+UNIFIED="Tizen-Unified"
Inform "Initialize ${TIZEN_ARCH} base"
fetch_tizen_pkgs_init standard $BASE
diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake
index 9a7ecfbd42c..0ff85cf0367 100644
--- a/eng/common/cross/toolchain.cmake
+++ b/eng/common/cross/toolchain.cmake
@@ -67,6 +67,13 @@ elseif(TARGET_ARCH_NAME STREQUAL "armv6")
else()
set(TOOLCHAIN "arm-linux-gnueabihf")
endif()
+elseif(TARGET_ARCH_NAME STREQUAL "loongarch64")
+ set(CMAKE_SYSTEM_PROCESSOR "loongarch64")
+ if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/loongarch64-alpine-linux-musl)
+ set(TOOLCHAIN "loongarch64-alpine-linux-musl")
+ else()
+ set(TOOLCHAIN "loongarch64-linux-gnu")
+ endif()
elseif(TARGET_ARCH_NAME STREQUAL "ppc64le")
set(CMAKE_SYSTEM_PROCESSOR ppc64le)
if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/powerpc64le-alpine-linux-musl)
@@ -118,7 +125,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "x86")
set(TIZEN_TOOLCHAIN "i586-tizen-linux-gnu")
endif()
else()
- message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm, arm64, armel, armv6, ppc64le, riscv64, s390x, x64 and x86 are supported!")
+ message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm, arm64, armel, armv6, loongarch64, ppc64le, riscv64, s390x, x64 and x86 are supported!")
endif()
if(DEFINED ENV{TOOLCHAIN})
@@ -148,6 +155,25 @@ if(TIZEN)
include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++/${TIZEN_TOOLCHAIN})
endif()
+function(locate_toolchain_exec exec var)
+ set(TOOLSET_PREFIX ${TOOLCHAIN}-)
+ string(TOUPPER ${exec} EXEC_UPPERCASE)
+ if(NOT "$ENV{CLR_${EXEC_UPPERCASE}}" STREQUAL "")
+ set(${var} "$ENV{CLR_${EXEC_UPPERCASE}}" PARENT_SCOPE)
+ return()
+ endif()
+
+ find_program(EXEC_LOCATION_${exec}
+ NAMES
+ "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}"
+ "${TOOLSET_PREFIX}${exec}")
+
+ if (EXEC_LOCATION_${exec} STREQUAL "EXEC_LOCATION_${exec}-NOTFOUND")
+ message(FATAL_ERROR "Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.")
+ endif()
+ set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE)
+endfunction()
+
if(ANDROID)
if(TARGET_ARCH_NAME STREQUAL "arm")
set(ANDROID_ABI armeabi-v7a)
@@ -178,66 +204,24 @@ elseif(FREEBSD)
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fuse-ld=lld")
elseif(ILLUMOS)
set(CMAKE_SYSROOT "${CROSS_ROOTFS}")
+ set(CMAKE_SYSTEM_PREFIX_PATH "${CROSS_ROOTFS}")
+ set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp")
+ set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp")
include_directories(SYSTEM ${CROSS_ROOTFS}/include)
- set(TOOLSET_PREFIX ${TOOLCHAIN}-)
- function(locate_toolchain_exec exec var)
- string(TOUPPER ${exec} EXEC_UPPERCASE)
- if(NOT "$ENV{CLR_${EXEC_UPPERCASE}}" STREQUAL "")
- set(${var} "$ENV{CLR_${EXEC_UPPERCASE}}" PARENT_SCOPE)
- return()
- endif()
-
- find_program(EXEC_LOCATION_${exec}
- NAMES
- "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}"
- "${TOOLSET_PREFIX}${exec}")
-
- if (EXEC_LOCATION_${exec} STREQUAL "EXEC_LOCATION_${exec}-NOTFOUND")
- message(FATAL_ERROR "Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.")
- endif()
- set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE)
- endfunction()
-
- set(CMAKE_SYSTEM_PREFIX_PATH "${CROSS_ROOTFS}")
-
locate_toolchain_exec(gcc CMAKE_C_COMPILER)
locate_toolchain_exec(g++ CMAKE_CXX_COMPILER)
-
- set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp")
- set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp")
elseif(HAIKU)
set(CMAKE_SYSROOT "${CROSS_ROOTFS}")
set(CMAKE_PROGRAM_PATH "${CMAKE_PROGRAM_PATH};${CROSS_ROOTFS}/cross-tools-x86_64/bin")
-
- set(TOOLSET_PREFIX ${TOOLCHAIN}-)
- function(locate_toolchain_exec exec var)
- string(TOUPPER ${exec} EXEC_UPPERCASE)
- if(NOT "$ENV{CLR_${EXEC_UPPERCASE}}" STREQUAL "")
- set(${var} "$ENV{CLR_${EXEC_UPPERCASE}}" PARENT_SCOPE)
- return()
- endif()
-
- find_program(EXEC_LOCATION_${exec}
- NAMES
- "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}"
- "${TOOLSET_PREFIX}${exec}")
-
- if (EXEC_LOCATION_${exec} STREQUAL "EXEC_LOCATION_${exec}-NOTFOUND")
- message(FATAL_ERROR "Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.")
- endif()
- set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE)
- endfunction()
-
set(CMAKE_SYSTEM_PREFIX_PATH "${CROSS_ROOTFS}")
+ set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp")
+ set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp")
locate_toolchain_exec(gcc CMAKE_C_COMPILER)
locate_toolchain_exec(g++ CMAKE_CXX_COMPILER)
- set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp")
- set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp")
-
# let CMake set up the correct search paths
include(Platform/Haiku)
else()
@@ -307,7 +291,7 @@ endif()
# Specify compile options
-if((TARGET_ARCH_NAME MATCHES "^(arm|arm64|armel|armv6|ppc64le|riscv64|s390x|x64|x86)$" AND NOT ANDROID AND NOT FREEBSD) OR ILLUMOS OR HAIKU)
+if((TARGET_ARCH_NAME MATCHES "^(arm|arm64|armel|armv6|loongarch64|ppc64le|riscv64|s390x|x64|x86)$" AND NOT ANDROID AND NOT FREEBSD) OR ILLUMOS OR HAIKU)
set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN})
set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN})
set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN})
diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh
index 36dbd45e1ce..e889f439b8d 100755
--- a/eng/common/darc-init.sh
+++ b/eng/common/darc-init.sh
@@ -68,7 +68,7 @@ function InstallDarcCli {
fi
fi
- local arcadeServicesSource="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json"
+ local arcadeServicesSource="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json"
echo "Installing Darc CLI version $darcVersion..."
echo "You may need to restart your command shell if this is the first dotnet tool you have installed."
diff --git a/eng/common/native/install-dependencies.sh b/eng/common/native/install-dependencies.sh
new file mode 100644
index 00000000000..477a44f335b
--- /dev/null
+++ b/eng/common/native/install-dependencies.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+set -e
+
+# This is a simple script primarily used for CI to install necessary dependencies
+#
+# Usage:
+#
+# ./install-dependencies.sh
+
+os="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
+
+if [ -z "$os" ]; then
+ . "$(dirname "$0")"/init-os-and-arch.sh
+fi
+
+case "$os" in
+ linux)
+ if [ -e /etc/os-release ]; then
+ . /etc/os-release
+ fi
+
+ if [ "$ID" = "debian" ] || [ "$ID_LIKE" = "debian" ]; then
+ apt update
+
+ apt install -y build-essential gettext locales cmake llvm clang lld lldb liblldb-dev libunwind8-dev libicu-dev liblttng-ust-dev \
+ libssl-dev libkrb5-dev pigz cpio
+
+ localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
+ elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ]; then
+ pkg_mgr="$(command -v tdnf 2>/dev/null || command -v dnf)"
+ $pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio
+ elif [ "$ID" = "alpine" ]; then
+ apk add build-base cmake bash curl clang llvm-dev lld lldb krb5-dev lttng-ust-dev icu-dev openssl-dev pigz cpio
+ else
+ echo "Unsupported distro. distro: $ID"
+ exit 1
+ fi
+ ;;
+
+ osx|maccatalyst|ios|iossimulator|tvos|tvossimulator)
+ echo "Installed xcode version: $(xcode-select -p)"
+
+ export HOMEBREW_NO_INSTALL_CLEANUP=1
+ export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
+ # Skip brew update for now, see https://github.com/actions/setup-python/issues/577
+ # brew update --preinstall
+ brew bundle --no-upgrade --file=- < Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)."
+ Write-Host " -excludeCIBinaryLog When running on CI, allow no binary log (short: -nobl)"
Write-Host ""
Write-Host "Command line arguments not listed above are passed thru to msbuild."
}
@@ -34,10 +36,11 @@ function Print-Usage() {
function Build([string]$target) {
$logSuffix = if ($target -eq 'Execute') { '' } else { ".$target" }
$log = Join-Path $LogDir "$task$logSuffix.binlog"
+ $binaryLogArg = if ($binaryLog) { "/bl:$log" } else { "" }
$outputPath = Join-Path $ToolsetDir "$task\"
MSBuild $taskProject `
- /bl:$log `
+ $binaryLogArg `
/t:$target `
/p:Configuration=$configuration `
/p:RepoRoot=$RepoRoot `
@@ -64,7 +67,7 @@ try {
$GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty
}
if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) {
- $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.12.0" -MemberType NoteProperty
+ $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.13.0" -MemberType NoteProperty
}
if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") {
$xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true
diff --git a/eng/common/sdk-task.sh b/eng/common/sdk-task.sh
new file mode 100644
index 00000000000..2f83adc0269
--- /dev/null
+++ b/eng/common/sdk-task.sh
@@ -0,0 +1,116 @@
+#!/usr/bin/env bash
+
+show_usage() {
+ echo "Common settings:"
+ echo " --task Name of Arcade task (name of a project in SdkTasks directory of the Arcade SDK package)"
+ echo " --restore Restore dependencies"
+ echo " --verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]"
+ echo " --help Print help and exit"
+ echo ""
+
+ echo "Advanced settings:"
+ echo " --excludeCIBinarylog Don't output binary log (short: -nobl)"
+ echo ""
+ echo "Command line arguments not listed above are passed thru to msbuild."
+}
+
+source="${BASH_SOURCE[0]}"
+
+# resolve $source until the file is no longer a symlink
+while [[ -h "$source" ]]; do
+ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+ source="$(readlink "$source")"
+ # if $source was a relative symlink, we need to resolve it relative to the path where the
+ # symlink file was located
+ [[ $source != /* ]] && source="$scriptroot/$source"
+done
+scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+
+Build() {
+ local target=$1
+ local log_suffix=""
+ [[ "$target" != "Execute" ]] && log_suffix=".$target"
+ local log="$log_dir/$task$log_suffix.binlog"
+ local binaryLogArg=""
+ [[ $binary_log == true ]] && binaryLogArg="/bl:$log"
+ local output_path="$toolset_dir/$task/"
+
+ MSBuild "$taskProject" \
+ $binaryLogArg \
+ /t:"$target" \
+ /p:Configuration="$configuration" \
+ /p:RepoRoot="$repo_root" \
+ /p:BaseIntermediateOutputPath="$output_path" \
+ /v:"$verbosity" \
+ $properties
+}
+
+binary_log=true
+configuration="Debug"
+verbosity="minimal"
+exclude_ci_binary_log=false
+restore=false
+help=false
+properties=''
+
+while (($# > 0)); do
+ lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")"
+ case $lowerI in
+ --task)
+ task=$2
+ shift 2
+ ;;
+ --restore)
+ restore=true
+ shift 1
+ ;;
+ --verbosity)
+ verbosity=$2
+ shift 2
+ ;;
+ --excludecibinarylog|--nobl)
+ binary_log=false
+ exclude_ci_binary_log=true
+ shift 1
+ ;;
+ --help)
+ help=true
+ shift 1
+ ;;
+ *)
+ properties="$properties $1"
+ shift 1
+ ;;
+ esac
+done
+
+ci=true
+warnAsError=true
+
+if $help; then
+ show_usage
+ exit 0
+fi
+
+. "$scriptroot/tools.sh"
+InitializeToolset
+
+if [[ -z "$task" ]]; then
+ Write-PipelineTelemetryError -Category 'Task' -Name 'MissingTask' -Message "Missing required parameter '-task '"
+ ExitWithExitCode 1
+fi
+
+taskProject=$(GetSdkTaskProject "$task")
+if [[ ! -e "$taskProject" ]]; then
+ Write-PipelineTelemetryError -Category 'Task' -Name 'UnknownTask' -Message "Unknown task: $task"
+ ExitWithExitCode 1
+fi
+
+if $restore; then
+ Build "Restore"
+fi
+
+Build "Execute"
+
+
+ExitWithExitCode 0
diff --git a/eng/common/sdl/packages.config b/eng/common/sdl/packages.config
index 4585cfd6bba..e5f543ea68c 100644
--- a/eng/common/sdl/packages.config
+++ b/eng/common/sdl/packages.config
@@ -1,4 +1,4 @@
-
+
diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml
index 817555505aa..a8a94328745 100644
--- a/eng/common/templates-official/job/job.yml
+++ b/eng/common/templates-official/job/job.yml
@@ -31,6 +31,7 @@ jobs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
condition: always()
+ retryCountOnTaskFailure: 10 # for any logs being locked
continueOnError: true
- ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
- output: pipelineArtifact
@@ -39,6 +40,7 @@ jobs:
displayName: 'Publish logs'
continueOnError: true
condition: always()
+ retryCountOnTaskFailure: 10 # for any logs being locked
sbomEnabled: false # we don't need SBOM for logs
- ${{ if eq(parameters.enablePublishBuildArtifacts, true) }}:
@@ -46,7 +48,7 @@ jobs:
displayName: Publish Logs
PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
publishLocation: Container
- ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}
+ ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }}
continueOnError: true
condition: always()
sbomEnabled: false # we don't need SBOM for logs
diff --git a/eng/common/templates-official/steps/publish-build-artifacts.yml b/eng/common/templates-official/steps/publish-build-artifacts.yml
index 100a3fc9849..fcf6637b2eb 100644
--- a/eng/common/templates-official/steps/publish-build-artifacts.yml
+++ b/eng/common/templates-official/steps/publish-build-artifacts.yml
@@ -24,6 +24,10 @@ parameters:
- name: is1ESPipeline
type: boolean
default: true
+
+- name: retryCountOnTaskFailure
+ type: string
+ default: 10
steps:
- ${{ if ne(parameters.is1ESPipeline, true) }}:
@@ -38,4 +42,5 @@ steps:
PathtoPublish: ${{ parameters.pathToPublish }}
${{ if parameters.artifactName }}:
ArtifactName: ${{ parameters.artifactName }}
-
+ ${{ if parameters.retryCountOnTaskFailure }}:
+ retryCountOnTaskFailure: ${{ parameters.retryCountOnTaskFailure }}
diff --git a/eng/common/templates-official/steps/source-index-stage1-publish.yml b/eng/common/templates-official/steps/source-index-stage1-publish.yml
new file mode 100644
index 00000000000..9b8b80942b5
--- /dev/null
+++ b/eng/common/templates-official/steps/source-index-stage1-publish.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index d1aeb92fcea..7cbf668c22b 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -46,6 +46,7 @@ jobs:
artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
continueOnError: true
condition: always()
+ retryCountOnTaskFailure: 10 # for any logs being locked
- ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
parameters:
@@ -56,6 +57,7 @@ jobs:
displayName: 'Publish logs'
continueOnError: true
condition: always()
+ retryCountOnTaskFailure: 10 # for any logs being locked
sbomEnabled: false # we don't need SBOM for logs
- ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}:
@@ -66,7 +68,7 @@ jobs:
displayName: Publish Logs
pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
publishLocation: Container
- artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}
+ artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }}
continueOnError: true
condition: always()
diff --git a/eng/common/templates/steps/publish-build-artifacts.yml b/eng/common/templates/steps/publish-build-artifacts.yml
index 6428a98dfef..605e602e94d 100644
--- a/eng/common/templates/steps/publish-build-artifacts.yml
+++ b/eng/common/templates/steps/publish-build-artifacts.yml
@@ -25,6 +25,10 @@ parameters:
type: string
default: 'Container'
+- name: retryCountOnTaskFailure
+ type: string
+ default: 10
+
steps:
- ${{ if eq(parameters.is1ESPipeline, true) }}:
- 'eng/common/templates cannot be referenced from a 1ES managed template': error
@@ -37,4 +41,6 @@ steps:
PublishLocation: ${{ parameters.publishLocation }}
PathtoPublish: ${{ parameters.pathToPublish }}
${{ if parameters.artifactName }}:
- ArtifactName: ${{ parameters.artifactName }}
\ No newline at end of file
+ ArtifactName: ${{ parameters.artifactName }}
+ ${{ if parameters.retryCountOnTaskFailure }}:
+ retryCountOnTaskFailure: ${{ parameters.retryCountOnTaskFailure }}
diff --git a/eng/common/templates/steps/source-index-stage1-publish.yml b/eng/common/templates/steps/source-index-stage1-publish.yml
new file mode 100644
index 00000000000..182cec33a7b
--- /dev/null
+++ b/eng/common/templates/steps/source-index-stage1-publish.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/vmr-sync.yml b/eng/common/templates/steps/vmr-sync.yml
new file mode 100644
index 00000000000..599afb6186b
--- /dev/null
+++ b/eng/common/templates/steps/vmr-sync.yml
@@ -0,0 +1,207 @@
+### These steps synchronize new code from product repositories into the VMR (https://github.com/dotnet/dotnet).
+### They initialize the darc CLI and pull the new updates.
+### Changes are applied locally onto the already cloned VMR (located in $vmrPath).
+
+parameters:
+- name: targetRef
+ displayName: Target revision in dotnet/ to synchronize
+ type: string
+ default: $(Build.SourceVersion)
+
+- name: vmrPath
+ displayName: Path where the dotnet/dotnet is checked out to
+ type: string
+ default: $(Agent.BuildDirectory)/vmr
+
+- name: additionalSyncs
+ displayName: Optional list of package names whose repo's source will also be synchronized in the local VMR, e.g. NuGet.Protocol
+ type: object
+ default: []
+
+steps:
+- checkout: vmr
+ displayName: Clone dotnet/dotnet
+ path: vmr
+ clean: true
+
+- checkout: self
+ displayName: Clone $(Build.Repository.Name)
+ path: repo
+ fetchDepth: 0
+
+# This step is needed so that when we get a detached HEAD / shallow clone,
+# we still pull the commit into the temporary repo clone to use it during the sync.
+# Also unshallow the clone so that forwardflow command would work.
+- script: |
+ git branch repo-head
+ git rev-parse HEAD
+ displayName: Label PR commit
+ workingDirectory: $(Agent.BuildDirectory)/repo
+
+- script: |
+ vmr_sha=$(grep -oP '(?<=Sha=")[^"]*' $(Agent.BuildDirectory)/repo/eng/Version.Details.xml)
+ echo "##vso[task.setvariable variable=vmr_sha]$vmr_sha"
+ displayName: Obtain the vmr sha from Version.Details.xml (Unix)
+ condition: ne(variables['Agent.OS'], 'Windows_NT')
+ workingDirectory: $(Agent.BuildDirectory)/repo
+
+- powershell: |
+ [xml]$xml = Get-Content -Path $(Agent.BuildDirectory)/repo/eng/Version.Details.xml
+ $vmr_sha = $xml.SelectSingleNode("//Source").Sha
+ Write-Output "##vso[task.setvariable variable=vmr_sha]$vmr_sha"
+ displayName: Obtain the vmr sha from Version.Details.xml (Windows)
+ condition: eq(variables['Agent.OS'], 'Windows_NT')
+ workingDirectory: $(Agent.BuildDirectory)/repo
+
+- script: |
+ git fetch --all
+ git checkout $(vmr_sha)
+ displayName: Checkout VMR at correct sha for repo flow
+ workingDirectory: ${{ parameters.vmrPath }}
+
+- script: |
+ git config --global user.name "dotnet-maestro[bot]"
+ git config --global user.email "dotnet-maestro[bot]@users.noreply.github.com"
+ displayName: Set git author to dotnet-maestro[bot]
+ workingDirectory: ${{ parameters.vmrPath }}
+
+- script: |
+ ./eng/common/vmr-sync.sh \
+ --vmr ${{ parameters.vmrPath }} \
+ --tmp $(Agent.TempDirectory) \
+ --azdev-pat '$(dn-bot-all-orgs-code-r)' \
+ --ci \
+ --debug
+
+ if [ "$?" -ne 0 ]; then
+ echo "##vso[task.logissue type=error]Failed to synchronize the VMR"
+ exit 1
+ fi
+ displayName: Sync repo into VMR (Unix)
+ condition: ne(variables['Agent.OS'], 'Windows_NT')
+ workingDirectory: $(Agent.BuildDirectory)/repo
+
+- script: |
+ git config --global diff.astextplain.textconv echo
+ git config --system core.longpaths true
+ displayName: Configure Windows git (longpaths, astextplain)
+ condition: eq(variables['Agent.OS'], 'Windows_NT')
+
+- powershell: |
+ ./eng/common/vmr-sync.ps1 `
+ -vmr ${{ parameters.vmrPath }} `
+ -tmp $(Agent.TempDirectory) `
+ -azdevPat '$(dn-bot-all-orgs-code-r)' `
+ -ci `
+ -debugOutput
+
+ if ($LASTEXITCODE -ne 0) {
+ echo "##vso[task.logissue type=error]Failed to synchronize the VMR"
+ exit 1
+ }
+ displayName: Sync repo into VMR (Windows)
+ condition: eq(variables['Agent.OS'], 'Windows_NT')
+ workingDirectory: $(Agent.BuildDirectory)/repo
+
+- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
+ - task: CopyFiles@2
+ displayName: Collect failed patches
+ condition: failed()
+ inputs:
+ SourceFolder: '$(Agent.TempDirectory)'
+ Contents: '*.patch'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/FailedPatches'
+
+ - publish: '$(Build.ArtifactStagingDirectory)/FailedPatches'
+ artifact: $(System.JobDisplayName)_FailedPatches
+ displayName: Upload failed patches
+ condition: failed()
+
+- ${{ each assetName in parameters.additionalSyncs }}:
+ # The vmr-sync script ends up staging files in the local VMR so we have to commit those
+ - script:
+ git commit --allow-empty -am "Forward-flow $(Build.Repository.Name)"
+ displayName: Commit local VMR changes
+ workingDirectory: ${{ parameters.vmrPath }}
+
+ - script: |
+ set -ex
+
+ echo "Searching for details of asset ${{ assetName }}..."
+
+ # Use darc to get dependencies information
+ dependencies=$(./.dotnet/dotnet darc get-dependencies --name '${{ assetName }}' --ci)
+
+ # Extract repository URL and commit hash
+ repository=$(echo "$dependencies" | grep 'Repo:' | sed 's/Repo:[[:space:]]*//' | head -1)
+
+ if [ -z "$repository" ]; then
+ echo "##vso[task.logissue type=error]Asset ${{ assetName }} not found in the dependency list"
+ exit 1
+ fi
+
+ commit=$(echo "$dependencies" | grep 'Commit:' | sed 's/Commit:[[:space:]]*//' | head -1)
+
+ echo "Updating the VMR from $repository / $commit..."
+ cd ..
+ git clone $repository ${{ assetName }}
+ cd ${{ assetName }}
+ git checkout $commit
+ git branch "sync/$commit"
+
+ ./eng/common/vmr-sync.sh \
+ --vmr ${{ parameters.vmrPath }} \
+ --tmp $(Agent.TempDirectory) \
+ --azdev-pat '$(dn-bot-all-orgs-code-r)' \
+ --ci \
+ --debug
+
+ if [ "$?" -ne 0 ]; then
+ echo "##vso[task.logissue type=error]Failed to synchronize the VMR"
+ exit 1
+ fi
+ displayName: Sync ${{ assetName }} into (Unix)
+ condition: ne(variables['Agent.OS'], 'Windows_NT')
+ workingDirectory: $(Agent.BuildDirectory)/repo
+
+ - powershell: |
+ $ErrorActionPreference = 'Stop'
+
+ Write-Host "Searching for details of asset ${{ assetName }}..."
+
+ $dependencies = .\.dotnet\dotnet darc get-dependencies --name '${{ assetName }}' --ci
+
+ $repository = $dependencies | Select-String -Pattern 'Repo:\s+([^\s]+)' | Select-Object -First 1
+ $repository -match 'Repo:\s+([^\s]+)' | Out-Null
+ $repository = $matches[1]
+
+ if ($repository -eq $null) {
+ Write-Error "Asset ${{ assetName }} not found in the dependency list"
+ exit 1
+ }
+
+ $commit = $dependencies | Select-String -Pattern 'Commit:\s+([^\s]+)' | Select-Object -First 1
+ $commit -match 'Commit:\s+([^\s]+)' | Out-Null
+ $commit = $matches[1]
+
+ Write-Host "Updating the VMR from $repository / $commit..."
+ cd ..
+ git clone $repository ${{ assetName }}
+ cd ${{ assetName }}
+ git checkout $commit
+ git branch "sync/$commit"
+
+ .\eng\common\vmr-sync.ps1 `
+ -vmr ${{ parameters.vmrPath }} `
+ -tmp $(Agent.TempDirectory) `
+ -azdevPat '$(dn-bot-all-orgs-code-r)' `
+ -ci `
+ -debugOutput
+
+ if ($LASTEXITCODE -ne 0) {
+ echo "##vso[task.logissue type=error]Failed to synchronize the VMR"
+ exit 1
+ }
+ displayName: Sync ${{ assetName }} into (Windows)
+ condition: ne(variables['Agent.OS'], 'Windows_NT')
+ workingDirectory: $(Agent.BuildDirectory)/repo
diff --git a/eng/common/templates/vmr-build-pr.yml b/eng/common/templates/vmr-build-pr.yml
new file mode 100644
index 00000000000..670cf32c3bd
--- /dev/null
+++ b/eng/common/templates/vmr-build-pr.yml
@@ -0,0 +1,33 @@
+trigger: none
+pr:
+ branches:
+ include:
+ - main
+ - release/*
+ paths:
+ exclude:
+ - documentation/*
+ - README.md
+ - CODEOWNERS
+
+variables:
+- template: /eng/common/templates/variables/pool-providers.yml@self
+
+- name: skipComponentGovernanceDetection # we run CG on internal builds only
+ value: true
+
+- name: Codeql.Enabled # we run CodeQL on internal builds only
+ value: false
+
+resources:
+ repositories:
+ - repository: vmr
+ type: github
+ name: dotnet/dotnet
+ endpoint: dotnet
+
+stages:
+- template: /eng/pipelines/templates/stages/vmr-build.yml@vmr
+ parameters:
+ isBuiltFromVmr: false
+ scope: lite
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index 22b49e09d09..5f40a3f8238 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -68,8 +68,6 @@ $ErrorActionPreference = 'Stop'
# True if the build is a product build
[bool]$productBuild = if (Test-Path variable:productBuild) { $productBuild } else { $false }
-[String[]]$properties = if (Test-Path variable:properties) { $properties } else { @() }
-
function Create-Directory ([string[]] $path) {
New-Item -Path $path -Force -ItemType 'Directory' | Out-Null
}
@@ -383,8 +381,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements =
# If the version of msbuild is going to be xcopied,
# use this version. Version matches a package here:
- # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.12.0
- $defaultXCopyMSBuildVersion = '17.12.0'
+ # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.13.0
+ $defaultXCopyMSBuildVersion = '17.13.0'
if (!$vsRequirements) {
if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') {
@@ -604,14 +602,7 @@ function InitializeBuildTool() {
}
$dotnetPath = Join-Path $dotnetRoot (GetExecutableFileName 'dotnet')
- # Use override if it exists - commonly set by source-build
- if ($null -eq $env:_OverrideArcadeInitializeBuildToolFramework) {
- $initializeBuildToolFramework="net9.0"
- } else {
- $initializeBuildToolFramework=$env:_OverrideArcadeInitializeBuildToolFramework
- }
-
- $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = $initializeBuildToolFramework }
+ $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = 'net' }
} elseif ($msbuildEngine -eq "vs") {
try {
$msbuildPath = InitializeVisualStudioMSBuild -install:$restore
@@ -620,7 +611,7 @@ function InitializeBuildTool() {
ExitWithExitCode 1
}
- $buildTool = @{ Path = $msbuildPath; Command = ""; Tool = "vs"; Framework = "net472"; ExcludePrereleaseVS = $excludePrereleaseVS }
+ $buildTool = @{ Path = $msbuildPath; Command = ""; Tool = "vs"; Framework = "netframework"; ExcludePrereleaseVS = $excludePrereleaseVS }
} else {
Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Unexpected value of -msbuildEngine: '$msbuildEngine'."
ExitWithExitCode 1
@@ -779,8 +770,10 @@ function MSBuild() {
# new scripts need to work with old packages, so we need to look for the old names/versions
(Join-Path $basePath (Join-Path $buildTool.Framework 'Microsoft.DotNet.ArcadeLogging.dll')),
(Join-Path $basePath (Join-Path $buildTool.Framework 'Microsoft.DotNet.Arcade.Sdk.dll')),
- (Join-Path $basePath (Join-Path net7.0 'Microsoft.DotNet.ArcadeLogging.dll')),
- (Join-Path $basePath (Join-Path net7.0 'Microsoft.DotNet.Arcade.Sdk.dll')),
+
+ # This list doesn't need to be updated anymore and can eventually be removed.
+ (Join-Path $basePath (Join-Path net9.0 'Microsoft.DotNet.ArcadeLogging.dll')),
+ (Join-Path $basePath (Join-Path net9.0 'Microsoft.DotNet.Arcade.Sdk.dll')),
(Join-Path $basePath (Join-Path net8.0 'Microsoft.DotNet.ArcadeLogging.dll')),
(Join-Path $basePath (Join-Path net8.0 'Microsoft.DotNet.Arcade.Sdk.dll'))
)
@@ -858,7 +851,7 @@ function MSBuild-Core() {
# When running on Azure Pipelines, override the returned exit code to avoid double logging.
# Skip this when the build is a child of the VMR orchestrator build.
- if ($ci -and $env:SYSTEM_TEAMPROJECT -ne $null -and !$productBuild -and -not($properties -like "*DotNetBuildRepo=true*")) {
+ if ($ci -and $env:SYSTEM_TEAMPROJECT -ne $null -and !$productBuild) {
Write-PipelineSetResult -Result "Failed" -Message "msbuild execution failed."
# Exiting with an exit code causes the azure pipelines task to log yet another "noise" error
# The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error
diff --git a/eng/common/tools.sh b/eng/common/tools.sh
index 01b09b65796..25f5932eee9 100755
--- a/eng/common/tools.sh
+++ b/eng/common/tools.sh
@@ -5,6 +5,9 @@
# CI mode - set to true on CI server for PR validation build or official build.
ci=${ci:-false}
+# Build mode
+source_build=${source_build:-false}
+
# Set to true to use the pipelines logger which will enable Azure logging output.
# https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md
# This flag is meant as a temporary opt-opt for the feature while validate it across
@@ -58,7 +61,8 @@ use_installed_dotnet_cli=${use_installed_dotnet_cli:-true}
dotnetInstallScriptVersion=${dotnetInstallScriptVersion:-'v1'}
# True to use global NuGet cache instead of restoring packages to repository-local directory.
-if [[ "$ci" == true ]]; then
+# Keep in sync with NuGetPackageroot in Arcade SDK's RepositoryLayout.props.
+if [[ "$ci" == true || "$source_build" == true ]]; then
use_global_nuget_cache=${use_global_nuget_cache:-false}
else
use_global_nuget_cache=${use_global_nuget_cache:-true}
@@ -339,12 +343,6 @@ function InitializeBuildTool {
# return values
_InitializeBuildTool="$_InitializeDotNetCli/dotnet"
_InitializeBuildToolCommand="msbuild"
- # use override if it exists - commonly set by source-build
- if [[ "${_OverrideArcadeInitializeBuildToolFramework:-x}" == "x" ]]; then
- _InitializeBuildToolFramework="net9.0"
- else
- _InitializeBuildToolFramework="${_OverrideArcadeInitializeBuildToolFramework}"
- fi
}
# Set RestoreNoHttpCache as a workaround for https://github.com/NuGet/Home/issues/3116
@@ -454,10 +452,12 @@ function MSBuild {
# new scripts need to work with old packages, so we need to look for the old names/versions
local selectedPath=
local possiblePaths=()
- possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.ArcadeLogging.dll" )
- possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.Arcade.Sdk.dll" )
- possiblePaths+=( "$toolset_dir/net7.0/Microsoft.DotNet.ArcadeLogging.dll" )
- possiblePaths+=( "$toolset_dir/net7.0/Microsoft.DotNet.Arcade.Sdk.dll" )
+ possiblePaths+=( "$toolset_dir/net/Microsoft.DotNet.ArcadeLogging.dll" )
+ possiblePaths+=( "$toolset_dir/net/Microsoft.DotNet.Arcade.Sdk.dll" )
+
+ # This list doesn't need to be updated anymore and can eventually be removed.
+ possiblePaths+=( "$toolset_dir/net9.0/Microsoft.DotNet.ArcadeLogging.dll" )
+ possiblePaths+=( "$toolset_dir/net9.0/Microsoft.DotNet.Arcade.Sdk.dll" )
possiblePaths+=( "$toolset_dir/net8.0/Microsoft.DotNet.ArcadeLogging.dll" )
possiblePaths+=( "$toolset_dir/net8.0/Microsoft.DotNet.Arcade.Sdk.dll" )
for path in "${possiblePaths[@]}"; do
@@ -507,7 +507,7 @@ function MSBuild-Core {
# When running on Azure Pipelines, override the returned exit code to avoid double logging.
# Skip this when the build is a child of the VMR orchestrator build.
- if [[ "$ci" == true && -n ${SYSTEM_TEAMPROJECT:-} && "$product_build" != true && "$properties" != *"DotNetBuildRepo=true"* ]]; then
+ if [[ "$ci" == true && -n ${SYSTEM_TEAMPROJECT:-} && "$product_build" != true ]]; then
Write-PipelineSetResult -result "Failed" -message "msbuild execution failed."
# Exiting with an exit code causes the azure pipelines task to log yet another "noise" error
# The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error
@@ -532,6 +532,12 @@ function GetDarc {
"$eng_root/common/darc-init.sh" --toolpath "$darc_path" $version
}
+# Returns a full path to an Arcade SDK task project file.
+function GetSdkTaskProject {
+ taskName=$1
+ echo "$(dirname $_InitializeToolset)/SdkTasks/$taskName.proj"
+}
+
ResolvePath "${BASH_SOURCE[0]}"
_script_dir=`dirname "$_ResolvePath"`
diff --git a/eng/common/vmr-sync.ps1 b/eng/common/vmr-sync.ps1
new file mode 100644
index 00000000000..8c3c91ce8de
--- /dev/null
+++ b/eng/common/vmr-sync.ps1
@@ -0,0 +1,138 @@
+<#
+.SYNOPSIS
+
+This script is used for synchronizing the current repository into a local VMR.
+It pulls the current repository's code into the specified VMR directory for local testing or
+Source-Build validation.
+
+.DESCRIPTION
+
+The tooling used for synchronization will clone the VMR repository into a temporary folder if
+it does not already exist. These clones can be reused in future synchronizations, so it is
+recommended to dedicate a folder for this to speed up re-runs.
+
+.EXAMPLE
+ Synchronize current repository into a local VMR:
+ ./vmr-sync.ps1 -vmrDir "$HOME/repos/dotnet" -tmpDir "$HOME/repos/tmp"
+
+.PARAMETER tmpDir
+Required. Path to the temporary folder where repositories will be cloned
+
+.PARAMETER vmrBranch
+Optional. Branch of the 'dotnet/dotnet' repo to synchronize. The VMR will be checked out to this branch
+
+.PARAMETER azdevPat
+Optional. Azure DevOps PAT to use for cloning private repositories.
+
+.PARAMETER vmrDir
+Optional. Path to the dotnet/dotnet repository. When null, gets cloned to the temporary folder
+
+.PARAMETER debugOutput
+Optional. Enables debug logging in the darc vmr command.
+
+.PARAMETER ci
+Optional. Denotes that the script is running in a CI environment.
+#>
+param (
+ [Parameter(Mandatory=$true, HelpMessage="Path to the temporary folder where repositories will be cloned")]
+ [string][Alias('t', 'tmp')]$tmpDir,
+ [string][Alias('b', 'branch')]$vmrBranch,
+ [string]$remote,
+ [string]$azdevPat,
+ [string][Alias('v', 'vmr')]$vmrDir,
+ [switch]$ci,
+ [switch]$debugOutput
+)
+
+function Fail {
+ Write-Host "> $($args[0])" -ForegroundColor 'Red'
+}
+
+function Highlight {
+ Write-Host "> $($args[0])" -ForegroundColor 'Cyan'
+}
+
+$verbosity = 'verbose'
+if ($debugOutput) {
+ $verbosity = 'debug'
+}
+# Validation
+
+if (-not $tmpDir) {
+ Fail "Missing -tmpDir argument. Please specify the path to the temporary folder where the repositories will be cloned"
+ exit 1
+}
+
+# Sanitize the input
+
+if (-not $vmrDir) {
+ $vmrDir = Join-Path $tmpDir 'dotnet'
+}
+
+if (-not (Test-Path -Path $tmpDir -PathType Container)) {
+ New-Item -ItemType Directory -Path $tmpDir | Out-Null
+}
+
+# Prepare the VMR
+
+if (-not (Test-Path -Path $vmrDir -PathType Container)) {
+ Highlight "Cloning 'dotnet/dotnet' into $vmrDir.."
+ git clone https://github.com/dotnet/dotnet $vmrDir
+
+ if ($vmrBranch) {
+ git -C $vmrDir switch -c $vmrBranch
+ }
+}
+else {
+ if ((git -C $vmrDir diff --quiet) -eq $false) {
+ Fail "There are changes in the working tree of $vmrDir. Please commit or stash your changes"
+ exit 1
+ }
+
+ if ($vmrBranch) {
+ Highlight "Preparing $vmrDir"
+ git -C $vmrDir checkout $vmrBranch
+ git -C $vmrDir pull
+ }
+}
+
+Set-StrictMode -Version Latest
+
+# Prepare darc
+
+Highlight 'Installing .NET, preparing the tooling..'
+. .\eng\common\tools.ps1
+$dotnetRoot = InitializeDotNetCli -install:$true
+$dotnet = "$dotnetRoot\dotnet.exe"
+& "$dotnet" tool restore
+
+Highlight "Starting the synchronization of VMR.."
+
+# Synchronize the VMR
+$darcArgs = (
+ "darc", "vmr", "forwardflow",
+ "--tmp", $tmpDir,
+ "--$verbosity",
+ $vmrDir
+)
+
+if ($ci) {
+ $darcArgs += ("--ci")
+}
+
+if ($azdevPat) {
+ $darcArgs += ("--azdev-pat", $azdevPat)
+}
+
+& "$dotnet" $darcArgs
+
+if ($LASTEXITCODE -eq 0) {
+ Highlight "Synchronization succeeded"
+}
+else {
+ Fail "Synchronization of repo to VMR failed!"
+ Fail "'$vmrDir' is left in its last state (re-run of this script will reset it)."
+ Fail "Please inspect the logs which contain path to the failing patch file (use -debugOutput to get all the details)."
+ Fail "Once you make changes to the conflicting VMR patch, commit it locally and re-run this script."
+ exit 1
+}
diff --git a/eng/common/vmr-sync.sh b/eng/common/vmr-sync.sh
new file mode 100644
index 00000000000..86d77ccf5b4
--- /dev/null
+++ b/eng/common/vmr-sync.sh
@@ -0,0 +1,205 @@
+#!/bin/bash
+
+### This script is used for synchronizing the current repository into a local VMR.
+### It pulls the current repository's code into the specified VMR directory for local testing or
+### Source-Build validation.
+###
+### The tooling used for synchronization will clone the VMR repository into a temporary folder if
+### it does not already exist. These clones can be reused in future synchronizations, so it is
+### recommended to dedicate a folder for this to speed up re-runs.
+###
+### USAGE:
+### Synchronize current repository into a local VMR:
+### ./vmr-sync.sh --tmp "$HOME/repos/tmp" "$HOME/repos/dotnet"
+###
+### Options:
+### -t, --tmp, --tmp-dir PATH
+### Required. Path to the temporary folder where repositories will be cloned
+###
+### -b, --branch, --vmr-branch BRANCH_NAME
+### Optional. Branch of the 'dotnet/dotnet' repo to synchronize. The VMR will be checked out to this branch
+###
+### --debug
+### Optional. Turns on the most verbose logging for the VMR tooling
+###
+### --remote name:URI
+### Optional. Additional remote to use during the synchronization
+### This can be used to synchronize to a commit from a fork of the repository
+### Example: 'runtime:https://github.com/yourfork/runtime'
+###
+### --azdev-pat
+### Optional. Azure DevOps PAT to use for cloning private repositories.
+###
+### -v, --vmr, --vmr-dir PATH
+### Optional. Path to the dotnet/dotnet repository. When null, gets cloned to the temporary folder
+
+source="${BASH_SOURCE[0]}"
+
+# resolve $source until the file is no longer a symlink
+while [[ -h "$source" ]]; do
+ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+ source="$(readlink "$source")"
+ # if $source was a relative symlink, we need to resolve it relative to the path where the
+ # symlink file was located
+ [[ $source != /* ]] && source="$scriptroot/$source"
+done
+scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+
+function print_help () {
+ sed -n '/^### /,/^$/p' "$source" | cut -b 5-
+}
+
+COLOR_RED=$(tput setaf 1 2>/dev/null || true)
+COLOR_CYAN=$(tput setaf 6 2>/dev/null || true)
+COLOR_CLEAR=$(tput sgr0 2>/dev/null || true)
+COLOR_RESET=uniquesearchablestring
+FAILURE_PREFIX='> '
+
+function fail () {
+ echo "${COLOR_RED}$FAILURE_PREFIX${1//${COLOR_RESET}/${COLOR_RED}}${COLOR_CLEAR}" >&2
+}
+
+function highlight () {
+ echo "${COLOR_CYAN}$FAILURE_PREFIX${1//${COLOR_RESET}/${COLOR_CYAN}}${COLOR_CLEAR}"
+}
+
+tmp_dir=''
+vmr_dir=''
+vmr_branch=''
+additional_remotes=''
+verbosity=verbose
+azdev_pat=''
+ci=false
+
+while [[ $# -gt 0 ]]; do
+ opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
+ case "$opt" in
+ -t|--tmp|--tmp-dir)
+ tmp_dir=$2
+ shift
+ ;;
+ -v|--vmr|--vmr-dir)
+ vmr_dir=$2
+ shift
+ ;;
+ -b|--branch|--vmr-branch)
+ vmr_branch=$2
+ shift
+ ;;
+ --remote)
+ additional_remotes="$additional_remotes $2"
+ shift
+ ;;
+ --azdev-pat)
+ azdev_pat=$2
+ shift
+ ;;
+ --ci)
+ ci=true
+ ;;
+ -d|--debug)
+ verbosity=debug
+ ;;
+ -h|--help)
+ print_help
+ exit 0
+ ;;
+ *)
+ fail "Invalid argument: $1"
+ print_help
+ exit 1
+ ;;
+ esac
+
+ shift
+done
+
+# Validation
+
+if [[ -z "$tmp_dir" ]]; then
+ fail "Missing --tmp-dir argument. Please specify the path to the temporary folder where the repositories will be cloned"
+ exit 1
+fi
+
+# Sanitize the input
+
+if [[ -z "$vmr_dir" ]]; then
+ vmr_dir="$tmp_dir/dotnet"
+fi
+
+if [[ ! -d "$tmp_dir" ]]; then
+ mkdir -p "$tmp_dir"
+fi
+
+if [[ "$verbosity" == "debug" ]]; then
+ set -x
+fi
+
+# Prepare the VMR
+
+if [[ ! -d "$vmr_dir" ]]; then
+ highlight "Cloning 'dotnet/dotnet' into $vmr_dir.."
+ git clone https://github.com/dotnet/dotnet "$vmr_dir"
+
+ if [[ -n "$vmr_branch" ]]; then
+ git -C "$vmr_dir" switch -c "$vmr_branch"
+ fi
+else
+ if ! git -C "$vmr_dir" diff --quiet; then
+ fail "There are changes in the working tree of $vmr_dir. Please commit or stash your changes"
+ exit 1
+ fi
+
+ if [[ -n "$vmr_branch" ]]; then
+ highlight "Preparing $vmr_dir"
+ git -C "$vmr_dir" checkout "$vmr_branch"
+ git -C "$vmr_dir" pull
+ fi
+fi
+
+set -e
+
+# Prepare darc
+
+highlight 'Installing .NET, preparing the tooling..'
+source "./eng/common/tools.sh"
+InitializeDotNetCli true
+dotnetDir=$( cd ./.dotnet/; pwd -P )
+dotnet=$dotnetDir/dotnet
+"$dotnet" tool restore
+
+highlight "Starting the synchronization of VMR.."
+set +e
+
+if [[ -n "$additional_remotes" ]]; then
+ additional_remotes="--additional-remotes $additional_remotes"
+fi
+
+if [[ -n "$azdev_pat" ]]; then
+ azdev_pat="--azdev-pat $azdev_pat"
+fi
+
+ci_arg=''
+if [[ "$ci" == "true" ]]; then
+ ci_arg="--ci"
+fi
+
+# Synchronize the VMR
+
+"$dotnet" darc vmr forwardflow \
+ --tmp "$tmp_dir" \
+ $azdev_pat \
+ --$verbosity \
+ $ci_arg \
+ $additional_remotes \
+ "$vmr_dir"
+
+if [[ $? == 0 ]]; then
+ highlight "Synchronization succeeded"
+else
+ fail "Synchronization of repo to VMR failed!"
+ fail "'$vmr_dir' is left in its last state (re-run of this script will reset it)."
+ fail "Please inspect the logs which contain path to the failing patch file (use --debug to get all the details)."
+ fail "Once you make changes to the conflicting VMR patch, commit it locally and re-run this script."
+ exit 1
+fi
diff --git a/global.json b/global.json
index a85e3a5fec3..d18020f5c59 100644
--- a/global.json
+++ b/global.json
@@ -17,7 +17,7 @@
"perl": "5.38.2.2"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25271.1",
+ "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25271.2",
"Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2"
}
}
diff --git a/proto.proj b/proto.proj
index d3355d8ae96..313cf2efdca 100644
--- a/proto.proj
+++ b/proto.proj
@@ -4,11 +4,7 @@
Bootstrap
-
-
-
+
diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs
index 4ce2fb1700b..e1410e8c595 100644
--- a/src/Compiler/Checking/Expressions/CheckExpressions.fs
+++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs
@@ -5259,6 +5259,8 @@ and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags
| _, _ -> FSComp.SR.tcActivePatternArgsCountNotMatchArgsAndPat(paramCount, caseName, fmtExprArgs paramCount)
error(Error(msg, m))
+ let isUnsolvedTyparTy g ty = tryDestTyparTy g ty |> ValueOption.exists (fun typar -> not typar.IsSolved)
+
// partial active pattern (returning bool) doesn't have output arg
if (not apinfo.IsTotal && isBoolTy g retTy) then
checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern m
@@ -5281,7 +5283,8 @@ and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags
showErrMsg 1
// active pattern in function param (e.g. let f (|P|_|) = ...)
- elif tryDestTyparTy g vExprTy |> ValueOption.exists (fun typar -> not typar.IsSolved) then
+ // or in mutual recursion with a lambda: `and (|P|) x = fun y -> …`
+ elif isUnsolvedTyparTy g vExprTy || tryDestFunTy g vExprTy |> ValueOption.exists (fun (_, rangeTy) -> isUnsolvedTyparTy g rangeTy) then
List.frontAndBack args
// args count should equal to AP function params count
diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs
index 1ce85b734fa..1eb950fd990 100644
--- a/src/Compiler/Driver/ParseAndCheckInputs.fs
+++ b/src/Compiler/Driver/ParseAndCheckInputs.fs
@@ -221,7 +221,6 @@ let private collectCodeComments (lexbuf: UnicodeLexing.Lexbuf) =
[
yield! CommentStore.GetComments(lexbuf)
yield! (List.map CommentTrivia.LineComment tripleSlashComments)
- yield! WarnScopes.getCommentTrivia lexbuf
]
|> List.sortBy (function
| CommentTrivia.LineComment r
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
index 2137ffe4275..4b5e04d64c4 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
@@ -24,8 +24,8 @@ and [] IfDirectiveExpression =
[]
type WarnDirectiveTrivia =
- | Nowarn of warnNumbers: int list * range
- | Warnon of warnNumbers: int list * range
+ | Nowarn of range
+ | Warnon of range
[]
type CommentTrivia =
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
index 9d4e50ce1f4..89d7124e5f1 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
@@ -36,8 +36,8 @@ type IfDirectiveExpression =
[]
type WarnDirectiveTrivia =
- | Nowarn of warnNumbers: int list * range
- | Warnon of warnNumbers: int list * range
+ | Nowarn of range
+ | Warnon of range
[]
type CommentTrivia =
diff --git a/src/Compiler/SyntaxTree/WarnScopes.fs b/src/Compiler/SyntaxTree/WarnScopes.fs
index 2efab44f5de..cf5e8431d42 100644
--- a/src/Compiler/SyntaxTree/WarnScopes.fs
+++ b/src/Compiler/SyntaxTree/WarnScopes.fs
@@ -36,9 +36,8 @@ module internal WarnScopes =
type private WarnDirective =
{
- DirectiveRange: range
- CommentRange: range option
WarnCmds: WarnCmd list
+ DirectiveRange: range
}
let private isWarnonDirective (w: WarnDirective) =
@@ -148,11 +147,9 @@ module internal WarnScopes =
let startPos = lexbuf.StartPos
let mGroups = (regex.Match text).Groups
- let dIdentGroup = mGroups[2]
- let dIdent = dIdentGroup.Value
- let argsGroup = mGroups[3]
- let argCaptures = [ for c in argsGroup.Captures -> c ]
- let commentGroup = mGroups[5]
+ let totalLength = mGroups[0].Length
+ let dIdent = mGroups[2].Value
+ let argCaptures = [ for c in mGroups[3].Captures -> c ]
let positions line offset length =
mkPos line (startPos.Column + offset), mkPos line (startPos.Column + offset + length)
@@ -165,19 +162,7 @@ module internal WarnScopes =
positions lexbuf.StartPos.OriginalLine offset length
||> mkFileIndexRange originalFileIndex
- let directiveLength =
- if argsGroup.Success then
- argsGroup.Index - (dIdentGroup.Index - 1) + argsGroup.Length
- else
- dIdentGroup.Length + 1
-
- let directiveRange = mkRange (dIdentGroup.Index - 1) directiveLength
-
- let commentRange =
- if commentGroup.Success then
- Some(mkRange commentGroup.Index commentGroup.Length)
- else
- None
+ let directiveRange = mkRange 0 totalLength
if argCaptures.IsEmpty then
errorR (Error(FSComp.SR.lexWarnDirectiveMustHaveArgs (), directiveRange))
@@ -190,13 +175,12 @@ module internal WarnScopes =
match dIdent with
| "warnon" -> argCaptures |> List.choose (mkDirective WarnCmd.Warnon)
| "nowarn" -> argCaptures |> List.choose (mkDirective WarnCmd.Nowarn)
- | _ ->
+ | _ -> // like "warnonx"
errorR (Error(FSComp.SR.fsiInvalidDirective ($"#{dIdent}", ""), directiveRange))
[]
{
DirectiveRange = directiveRange
- CommentRange = commentRange
WarnCmds = warnCmds
}
@@ -365,18 +349,12 @@ module internal WarnScopes =
let getDirectiveTrivia (lexbuf: Lexbuf) =
let mkTrivia d =
if isWarnonDirective d then
- WarnDirectiveTrivia.Warnon(d.WarnCmds |> List.map _.WarningNumber, d.DirectiveRange)
+ WarnDirectiveTrivia.Warnon d.DirectiveRange
else
- WarnDirectiveTrivia.Nowarn(d.WarnCmds |> List.map _.WarningNumber, d.DirectiveRange)
+ WarnDirectiveTrivia.Nowarn d.DirectiveRange
(getLexbufData lexbuf).WarnDirectives |> List.rev |> List.map mkTrivia
- let getCommentTrivia (lexbuf: Lexbuf) =
- (getLexbufData lexbuf).WarnDirectives
- |> List.rev
- |> List.choose _.CommentRange
- |> List.map CommentTrivia.LineComment
-
// *************************************
// Apply the warn scopes after lexing
// *************************************
diff --git a/src/Compiler/SyntaxTree/WarnScopes.fsi b/src/Compiler/SyntaxTree/WarnScopes.fsi
index 1cdecc76149..36539973a58 100644
--- a/src/Compiler/SyntaxTree/WarnScopes.fsi
+++ b/src/Compiler/SyntaxTree/WarnScopes.fsi
@@ -23,9 +23,6 @@ module internal WarnScopes =
/// Get the collected ranges of the warn directives
val getDirectiveTrivia: Lexbuf -> WarnDirectiveTrivia list
- /// Get the ranges of comments after warn directives
- val getCommentTrivia: Lexbuf -> CommentTrivia list
-
/// Check if the range is inside a "warnon" scope for the given warning number.
val IsWarnon: FSharpDiagnosticOptions -> warningNumber: int -> mo: range option -> bool
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ActivePatternArgCountMismatchTest.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ActivePatternArgCountMismatchTest.fs
index 8c2133721d2..09de043f4fd 100644
--- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ActivePatternArgCountMismatchTest.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ActivePatternArgCountMismatchTest.fs
@@ -761,6 +761,26 @@ match 1 with P expr2 pat -> ()
|> typecheck
|> shouldSucceed
+ module ``Recursive active pattern definition with and`` =
+ /// See https://github.com/dotnet/fsharp/issues/18638
+ []
+ let ``match expr1 with P expr2 pat -> …`` () =
+ FSharp """
+let rec parse p =
+ function
+ | IsSomething p v -> Some v
+ | _ -> None
+
+and (|IsSomething|_|) p =
+ function
+ | "nested" -> parse p "42"
+ | "42" -> Some 42
+ | _ -> None
+ """
+ |> withNoWarn IncompletePatternMatches
+ |> typecheck
+ |> shouldSucceed
+
module ``int → int → int voption`` =
// Normal usage; pat is int.
[]
diff --git a/tests/FSharp.Compiler.Service.Tests/Checker.fs b/tests/FSharp.Compiler.Service.Tests/Checker.fs
new file mode 100644
index 00000000000..4768aa89637
--- /dev/null
+++ b/tests/FSharp.Compiler.Service.Tests/Checker.fs
@@ -0,0 +1,105 @@
+namespace FSharp.Compiler.Service.Tests
+
+open System
+open FSharp.Compiler.CodeAnalysis
+open FSharp.Compiler.EditorServices
+open FSharp.Compiler.Text
+open FSharp.Compiler.Tokenization
+
+type SourceContext =
+ { Source: string
+ LineText: string
+ CaretPos: pos }
+
+type ResolveContext =
+ { SourceContext: SourceContext
+ Pos: pos
+ Names: string list }
+
+ member this.Source = this.SourceContext.Source
+ member this.LineText = this.SourceContext.LineText
+
+type CodeCompletionContext =
+ { SourceContext: SourceContext
+ Pos: pos
+ PartialIdentifier: PartialLongName }
+
+ member this.Source = this.SourceContext.Source
+ member this.LineText = this.SourceContext.LineText
+
+[]
+module SourceContext =
+ let fromMarkedSource (markedSource: string) : SourceContext =
+ let lines = markedSource.Split([|"\r\n"; "\n"|], StringSplitOptions.None)
+ let line = lines |> Seq.findIndex _.Contains("{caret}")
+ let lineText = lines[line]
+ let column = lineText.IndexOf("{caret}")
+
+ let source = markedSource.Replace("{caret}", "")
+ let pos = Position.mkPos (line + 1) (column - 1)
+ let lineText = lineText.Replace("{caret}", "")
+ { Source = source; CaretPos = pos; LineText = lineText }
+
+
+[]
+module CheckResultsExtensions =
+ type FSharpCheckFileResults with
+ member this.GetSymbolUses(context: ResolveContext) =
+ this.GetSymbolUsesAtLocation(context.Pos.Line, context.Pos.Column, context.LineText, context.Names)
+
+ member this.GetSymbolUse(context: ResolveContext) =
+ this.GetSymbolUses(context) |> List.exactlyOne
+
+ member this.GetTooltip(context: ResolveContext) =
+ this.GetToolTip(context.Pos.Line, context.Pos.Column, context.LineText, context.Names, FSharpTokenTag.Identifier)
+
+ member this.GetTooltip(context: ResolveContext, width) =
+ this.GetToolTip(context.Pos.Line, context.Pos.Column, context.LineText, context.Names, FSharpTokenTag.Identifier, width)
+
+ member this.GetCodeCompletionSuggestions(context: CodeCompletionContext, parseResults: FSharpParseFileResults) =
+ this.GetDeclarationListInfo(Some parseResults, context.Pos.Line, context.LineText, context.PartialIdentifier)
+
+[]
+module Checker =
+ let getResolveContext (markedSource: string) =
+ let context = SourceContext.fromMarkedSource markedSource
+ let pos =
+ match QuickParse.GetCompleteIdentifierIsland false context.LineText context.CaretPos.Column with
+ | Some(_, column, _) -> Position.mkPos context.CaretPos.Line column
+ | _ -> context.CaretPos
+
+ let plid = QuickParse.GetPartialLongNameEx(context.LineText, pos.Column - 1)
+ let names = plid.QualifyingIdents @ [plid.PartialIdent]
+ { SourceContext = context; Pos = pos; Names = names }
+
+ let getCompletionContext (markedSource: string) =
+ let context = SourceContext.fromMarkedSource markedSource
+ let plid = QuickParse.GetPartialLongNameEx(context.LineText, context.CaretPos.Column)
+ let names = plid.QualifyingIdents @ [plid.PartialIdent]
+ { SourceContext = context; Pos = context.CaretPos; PartialIdentifier = plid }
+
+ let getCheckedResolveContext (markedSource: string) =
+ let context = getResolveContext markedSource
+ let _, checkResults = getParseAndCheckResults context.Source
+ context, checkResults
+
+ let getCompletionInfo (markedSource: string) =
+ let context = getCompletionContext markedSource
+ let parseResults, checkResults = getParseAndCheckResults context.Source
+ checkResults.GetCodeCompletionSuggestions(context, parseResults)
+
+ let getSymbolUses (markedSource: string) =
+ let context, checkResults = getCheckedResolveContext markedSource
+ checkResults.GetSymbolUses(context)
+
+ let getSymbolUse (markedSource: string) =
+ let symbolUses = getSymbolUses markedSource
+ symbolUses |> List.exactlyOne
+
+ let getTooltipWithOptions (options: string array) (markedSource: string) =
+ let context = getResolveContext markedSource
+ let _, checkResults = getParseAndCheckResultsWithOptions options context.Source
+ checkResults.GetToolTip(context.Pos.Line, context.Pos.Column, context.LineText, context.Names, FSharpTokenTag.Identifier)
+
+ let getTooltip (markedSource: string) =
+ getTooltipWithOptions [||] markedSource
diff --git a/tests/FSharp.Compiler.Service.Tests/Common.fs b/tests/FSharp.Compiler.Service.Tests/Common.fs
index 8bc685b544b..74368c9b1f3 100644
--- a/tests/FSharp.Compiler.Service.Tests/Common.fs
+++ b/tests/FSharp.Compiler.Service.Tests/Common.fs
@@ -342,24 +342,6 @@ let rec allSymbolsInEntities compGen (entities: IList) =
yield! allSymbolsInEntities compGen entity.NestedEntities ]
-let getCursorPosAndPrepareSource (source: string) : string * string * pos =
- let lines = source.Split([|"\r\n"; "\n"|], StringSplitOptions.None)
- let line = lines |> Seq.findIndex _.Contains("{caret}")
- let lineText = lines[line]
- let column = lineText.IndexOf("{caret}")
-
- let source = source.Replace("{caret}", "")
- let lineText = lineText.Replace("{caret}", "")
- source, lineText, Position.mkPos (line + 1) (column - 1)
-
-let getPartialIdentifierAndPrepareSource source =
- let source, lineText, pos = getCursorPosAndPrepareSource source
- let _, column, _ = QuickParse.GetCompleteIdentifierIsland false lineText pos.Column |> Option.get
- let pos = Position.mkPos pos.Line column
- let plid = QuickParse.GetPartialLongNameEx(lineText, column - 1)
- let names = plid.QualifyingIdents @ [plid.PartialIdent]
- source, lineText, pos, plid, names
-
let getParseResults (source: string) =
parseSourceCode("Test.fsx", source)
@@ -369,6 +351,9 @@ let getParseResultsOfSignatureFile (source: string) =
let getParseAndCheckResults (source: string) =
parseAndCheckScript("Test.fsx", source)
+let getParseAndCheckResultsWithOptions options source =
+ parseAndCheckScriptWithOptions ("Test.fsx", source, options)
+
let getParseAndCheckResultsOfSignatureFile (source: string) =
parseAndCheckScript("Test.fsi", source)
diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs
index 76106a92b34..c356991673e 100644
--- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs
+++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs
@@ -1,20 +1,10 @@
module FSharp.Compiler.Service.Tests.CompletionTests
-open FSharp.Compiler.Service.Tests.Common
open FSharp.Compiler.EditorServices
open Xunit
-let getCompletionInfo source =
- let source, lineText, pos = getCursorPosAndPrepareSource source
- let parseResults, checkResults = getParseAndCheckResultsPreview source
- let plid = QuickParse.GetPartialLongNameEx(lineText, pos.Column)
- checkResults.GetDeclarationListInfo(Some parseResults, pos.Line, lineText, plid)
-
-let getCompletionItemNames (completionInfo: DeclarationListInfo) =
- completionInfo.Items |> Array.map (fun item -> item.NameInCode)
-
let private assertItemsWithNames contains names (completionInfo: DeclarationListInfo) =
- let itemNames = getCompletionItemNames completionInfo |> set
+ let itemNames = completionInfo.Items |> Array.map _.NameInCode |> set
for name in names do
Assert.True(Set.contains name itemNames = contains)
@@ -27,7 +17,7 @@ let assertHasNoItemsWithNames names (completionInfo: DeclarationListInfo) =
[]
let ``Expr - After record decl 01`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
type Record = { Field: int }
{ Fi{caret} }
@@ -36,7 +26,7 @@ type Record = { Field: int }
[]
let ``Expr - After record decl 02`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
type Record = { Field: int }
{caret}
@@ -45,7 +35,7 @@ type Record = { Field: int }
[]
let ``Expr - record - field 01 - anon module`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
type Record = { Field: int }
{ Fi{caret} }
@@ -54,7 +44,7 @@ type Record = { Field: int }
[]
let ``Expr - record - field 02 - anon module`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
type Record = { Field: int }
let record = { Field = 1 }
@@ -65,7 +55,7 @@ let record = { Field = 1 }
[]
let ``Expr - record - empty 01`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
type Record = { Field: int }
{ {caret} }
@@ -74,7 +64,7 @@ type Record = { Field: int }
[]
let ``Expr - record - empty 02`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
type Record = { Field: int }
let record = { Field = 1 }
@@ -85,56 +75,56 @@ let record = { Field = 1 }
[]
let ``Underscore dot lambda - completion 01`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
"" |> _.Len{caret}"""
assertHasItemWithNames ["Length"] info
[]
let ``Underscore dot lambda - completion 02`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
System.DateTime.Now |> _.TimeOfDay.Mill{caret}"""
assertHasItemWithNames ["Milliseconds"] info
[]
let ``Underscore dot lambda - completion 03`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
"" |> _.ToString().Len{caret}"""
assertHasItemWithNames ["Length"] info
[]
let ``Underscore dot lambda - completion 04`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
"" |> _.Len{caret}gth.ToString()"""
assertHasItemWithNames ["Length"] info
[]
let ``Underscore dot lambda - completion 05`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
"" |> _.Length.ToString().Chars("".Len{caret})"""
assertHasItemWithNames ["Length"] info
[]
let ``Underscore dot lambda - completion 06`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
"" |> _.Chars(System.DateTime.UtcNow.Tic{caret}).ToString()"""
assertHasItemWithNames ["Ticks"] info
[]
let ``Underscore dot lambda - completion 07`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
"" |> _.Length.ToString().Len{caret}"""
assertHasItemWithNames ["Length"] info
[]
let ``Underscore dot lambda - completion 08`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
System.DateTime.Now |> _.TimeOfDay
.Mill{caret}"""
@@ -142,21 +132,21 @@ System.DateTime.Now |> _.TimeOfDay
[]
let ``Underscore dot lambda - completion 09`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
"" |> _.Length.ToSt{caret}.Length"""
assertHasItemWithNames ["ToString"] info
[]
let ``Underscore dot lambda - completion 10`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
"" |> _.Chars(0).ToStr{caret}.Length"""
assertHasItemWithNames ["ToString"] info
[]
let ``Underscore dot lambda - completion 11`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
open System.Linq
[[""]] |> _.Select(_.Head.ToL{caret})"""
@@ -165,7 +155,7 @@ open System.Linq
[]
let ``Underscore dot lambda - completion 12`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
open System.Linq
[[[""]]] |> _.Head.Select(_.Head.ToL{caret})"""
@@ -174,7 +164,7 @@ open System.Linq
[]
let ``Underscore dot lambda - completion 13`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
let myFancyFunc (x:string) =
x
|> _.ToL{caret}"""
@@ -182,7 +172,7 @@ let myFancyFunc (x:string) =
[]
let ``Underscore dot lambda - completion 14`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
let myFancyFunc (x:System.DateTime) =
x
|> _.TimeOfDay.Mill{caret}
@@ -191,14 +181,14 @@ let myFancyFunc (x:System.DateTime) =
[]
let ``Underscore dot lambda - completion 15`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
let _a = 5
"" |> _{caret}.Length.ToString() """
assertHasItemWithNames ["_a"] info
[]
let ``Underscore dot lambda - No prefix 01`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
let s = ""
[s] |> List.map _.{caret}
"""
@@ -206,21 +196,21 @@ let s = ""
[]
let ``Underscore dot lambda - No prefix 02`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
System.DateTime.Now |> _.TimeOfDay.{caret}"""
assertHasItemWithNames ["Milliseconds"] info
[]
let ``Underscore dot lambda - No prefix 03`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
"" |> _.Length.ToString().{caret}"""
assertHasItemWithNames ["Length"] info
[]
let ``Type decl - Record - Field type 01`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
type Record = { Field: {caret} }
"""
assertHasItemWithNames ["string"] info
@@ -228,7 +218,7 @@ type Record = { Field: {caret} }
[]
let ``Expr - Qualifier 01`` () =
- let info = getCompletionInfo """
+ let info = Checker.getCompletionInfo """
let f (s: string) =
s.Trim().{caret}
s.Trim()
@@ -239,8 +229,7 @@ let f (s: string) =
[]
let ``Expr - Qualifier 02`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
let f (s: string) =
s.Trim()
s.Trim().{caret}
@@ -251,8 +240,7 @@ let f (s: string) =
[]
let ``Expr - Qualifier 03`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
let f (s: string) =
s.Trim()
s.Trim()
@@ -263,8 +251,7 @@ let f (s: string) =
[]
let ``Expr - Qualifier 04`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
type T() =
do
System.String.Empty.ToString().L{caret}
@@ -273,24 +260,21 @@ type T() =
[]
let ``Expr - Qualifier 05`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
System.String.Empty.ToString().{caret}
"""
assertHasItemWithNames ["Length"] info
[]
let ``Expr - Qualifier 06`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
System.String.Empty.ToString().L{caret}
"""
assertHasItemWithNames ["Length"] info
[]
let ``Expr - Qualifier 07`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
type T() =
do
System.String.Empty.ToString().L{caret}
@@ -300,8 +284,7 @@ type T() =
[]
let ``Import - Ns 01`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
namespace Ns
type Rec1 = { F: int }
@@ -321,8 +304,7 @@ module M =
[]
let ``Import - Ns 02 - Rec`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
namespace Ns
type Rec1 = { F: int }
@@ -342,8 +324,7 @@ module M =
[]
let ``Import - Ns 03 - Rec`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
namespace Ns
type Rec1 = { F: int }
@@ -363,8 +344,7 @@ module rec M =
[]
let ``Not in scope 01`` () =
- let info =
- getCompletionInfo """
+ let info = Checker.getCompletionInfo """
namespace Ns1
type E =
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
index 6fccd622eca..566ff039e93 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
@@ -10829,22 +10829,18 @@ FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Microsoft.FSharp.Core.FSharpOption
FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_WithKeyword()
FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Void .ctor(FSharp.Compiler.SyntaxTrivia.SynLeadingKeyword, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Nowarn: FSharp.Compiler.Text.Range Item2
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Nowarn: FSharp.Compiler.Text.Range get_Item2()
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Nowarn: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] get_warnNumbers()
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Nowarn: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] warnNumbers
+FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Nowarn: FSharp.Compiler.Text.Range Item
+FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Nowarn: FSharp.Compiler.Text.Range get_Item()
FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Tags: Int32 Nowarn
FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Tags: Int32 Warnon
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Warnon: FSharp.Compiler.Text.Range Item2
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Warnon: FSharp.Compiler.Text.Range get_Item2()
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Warnon: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] get_warnNumbers()
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Warnon: Microsoft.FSharp.Collections.FSharpList`1[System.Int32] warnNumbers
+FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Warnon: FSharp.Compiler.Text.Range Item
+FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Warnon: FSharp.Compiler.Text.Range get_Item()
FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: Boolean IsNowarn
FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: Boolean IsWarnon
FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: Boolean get_IsNowarn()
FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: Boolean get_IsWarnon()
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia NewNowarn(Microsoft.FSharp.Collections.FSharpList`1[System.Int32], FSharp.Compiler.Text.Range)
-FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia NewWarnon(Microsoft.FSharp.Collections.FSharpList`1[System.Int32], FSharp.Compiler.Text.Range)
+FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia NewNowarn(FSharp.Compiler.Text.Range)
+FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia NewWarnon(FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Nowarn
FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Tags
FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia: FSharp.Compiler.SyntaxTrivia.WarnDirectiveTrivia+Warnon
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
index fc325ec28aa..4f5cdab60f5 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
@@ -25,6 +25,7 @@
XunitSetup.fs
+
diff --git a/tests/FSharp.Compiler.Service.Tests/Symbols.fs b/tests/FSharp.Compiler.Service.Tests/Symbols.fs
index 181cbfe40af..2da98810e0a 100644
--- a/tests/FSharp.Compiler.Service.Tests/Symbols.fs
+++ b/tests/FSharp.Compiler.Service.Tests/Symbols.fs
@@ -9,7 +9,6 @@ open FSharp.Test.Assert
open Xunit
module ActivePatterns =
-
let completePatternInput = """
let (|True|False|) = function
| true -> True
@@ -515,18 +514,18 @@ module FSharpMemberOrFunctionOrValue =
[]
let ``Both Set and Get symbols are present`` () =
- let _, checkResults = getParseAndCheckResults """
+ let context, checkResults = Checker.getCheckedResolveContext """
namespace Foo
type Foo =
- member _.X
+ member _.X{caret}
with get (y: int) : string = ""
and set (a: int) (b: float) = ()
"""
// "X" resolves a symbol but it will either be the property, get or set symbol.
// Use get_ or set_ to differentiate.
- let xPropertySymbol, _ = checkResults.GetSymbolUsesAtLocation(5, 14, " member _.X", [ "X" ]) |> List.pick pickPropertySymbol
+ let xPropertySymbol, _ = checkResults.GetSymbolUses(context) |> List.pick pickPropertySymbol
Assert.True xPropertySymbol.IsProperty
Assert.True xPropertySymbol.HasGetterMethod
@@ -545,20 +544,14 @@ type Foo =
| symbol -> failwith $"Expected {symbol} to be FSharpMemberOrFunctionOrValue"
[]
- let ``AutoProperty with get,set has property symbol!`` () =
- let _, checkResults = getParseAndCheckResults """
+ let ``AutoProperty with get, set has property symbol 01`` () =
+ let symbols = Checker.getSymbolUses """
namespace Foo
type Foo =
- member val AutoPropGetSet = 0 with get, set
+ member val AutoPropGe{caret}tSet = 0 with get, set
"""
-
- let symbols = checkResults.GetSymbolUsesAtLocation(5, 29, " member val AutoPropGetSet = 0 with get, set", ["AutoPropGetSet"])
-
- let autoPropertySymbol, mAutoPropSymbolUse =
- symbols
- |> List.pick pickPropertySymbol
-
+ let autoPropertySymbol, mAutoPropSymbolUse = symbols |> List.pick pickPropertySymbol
Assert.True autoPropertySymbol.IsProperty
Assert.True autoPropertySymbol.HasGetterMethod
Assert.True autoPropertySymbol.HasSetterMethod
@@ -566,39 +559,34 @@ type Foo =
Assert.True (autoPropertySymbol.SetterMethod.CompiledName.StartsWith("set_"))
assertRange (5, 15) (5, 29) mAutoPropSymbolUse
- let symbols =
- symbols
- |> List.choose chooseMemberOrFunctionOrValue
-
+ let symbols = symbols |> List.choose chooseMemberOrFunctionOrValue
match symbols with
- | [ propMfv
- setMfv
- getMfv ] ->
+ | [ propMfv; setMfv; getMfv ] ->
Assert.True propMfv.IsProperty
Assert.True(getMfv.CompiledName.StartsWith("get_"))
Assert.True(setMfv.CompiledName.StartsWith("set_"))
| _ -> failwith $"Expected three symbols, got %A{symbols}"
-
- // The setter should have a symbol for the generated parameter `v`.
- let setVMfv =
- checkResults.GetSymbolUsesAtLocation(5, 29, " member val AutoPropGetSet = 0 with get, set", ["v"])
- |> List.tryExactlyOne
- |> Option.map chooseMemberOrFunctionOrValue
- if Option.isNone setVMfv then failwith "No generated v symbol for the setter was found"
+ []
+ let ``AutoProperty with get, set has property symbol 02`` () =
+ let symbol = Checker.getSymbolUse """
+namespace Foo
+
+type Foo =
+ member val AutoPropGetSet{caret} = 0 with get, set
+"""
+ // The setter should have a symbol for the generated parameter `v`.
+ let setVMfv = symbol |> chooseMemberOrFunctionOrValue
+ if Option.isNone setVMfv then
+ failwith "No generated v symbol for the setter was found"
[]
let ``Property symbol is resolved for property`` () =
- let source = """
+ let symbols = Checker.getSymbolUses """
type X(y: string) =
- member val Y = y with get, set
+ member val Y{caret} = y with get, set
"""
-
- let _, checkResults = getParseAndCheckResults source
- let propSymbol, _ =
- checkResults.GetSymbolUsesAtLocation(3, 16, " member val Y = y with get, set", [ "Y" ])
- |> List.pick pickPropertySymbol
-
+ let propSymbol, _ = symbols |> List.pick pickPropertySymbol
Assert.True propSymbol.IsProperty
Assert.True propSymbol.HasGetterMethod
Assert.True propSymbol.HasSetterMethod
@@ -606,11 +594,11 @@ type X(y: string) =
[]
let ``Multiple relevant symbols for type name`` () =
- let _, checkResults = getParseAndCheckResults """
+ let context, checkResults = Checker.getCheckedResolveContext """
// This is a generated file; the original input is 'FSInteractiveSettings.txt'
namespace FSInteractiveSettings
-type internal SR () =
+type internal SR{caret} () =
static let mutable swallowResourceText = false
@@ -619,11 +607,8 @@ type internal SR () =
and set (b) = swallowResourceText <- b
// END BOILERPLATE
"""
-
- let symbols =
- checkResults.GetSymbolUsesAtLocation(5, 16, "type internal SR () =", [ "" ])
- |> List.map (fun su -> su.Symbol)
-
+ let context = { context with Names = [""] } // Override the context to get the extra symbols
+ let symbols = checkResults.GetSymbolUses(context) |> List.map _.Symbol
match symbols with
| [ :? FSharpMemberOrFunctionOrValue as cctor
:? FSharpMemberOrFunctionOrValue as ctor
@@ -635,79 +620,58 @@ type internal SR () =
[]
let ``AutoProperty with get has get symbol attached to property name`` () =
- let _, checkResults = getParseAndCheckResults """
+ let symbolUse = Checker.getSymbolUse """
namespace Foo
type Foo() =
- member val Bar = 0 with get
+ member val B{caret}ar = 0 with get
"""
-
- let autoPropertySymbolUses =
- checkResults.GetSymbolUsesAtLocation(5, 18, " member val Bar = 0 with get", ["Bar"])
- |> List.map (fun su -> su.Symbol)
-
- match autoPropertySymbolUses with
- | [ :? FSharpMemberOrFunctionOrValue as mfv ] ->
+ match symbolUse.Symbol with
+ | :? FSharpMemberOrFunctionOrValue as mfv ->
Assert.True mfv.IsPropertyGetterMethod
assertRange (5, 15) (5, 18) mfv.SignatureLocation.Value
| symbols -> failwith $"Unexpected symbols, got %A{symbols}"
[]
let ``Property with get has symbol attached to property name`` () =
- let _, checkResults = getParseAndCheckResults """
+ let symbolUse = Checker.getSymbolUse """
namespace F
type Foo() =
let mutable b = 0
- member this.Count with get () = b
+ member this.Coun{caret}t with get () = b
"""
-
- let getSymbolUses =
- checkResults.GetSymbolUsesAtLocation(6, 21, " member this.Count with get () = b", ["Count"])
- |> List.map (fun su -> su.Symbol)
-
- match getSymbolUses with
- | [ :? FSharpMemberOrFunctionOrValue as mfv ] ->
+ match symbolUse.Symbol with
+ | :? FSharpMemberOrFunctionOrValue as mfv ->
Assert.True mfv.IsPropertyGetterMethod
assertRange (6, 16) (6, 21) mfv.SignatureLocation.Value
| symbols -> failwith $"Unexpected symbols, got %A{symbols}"
[]
let ``Property with set has symbol attached to property name`` () =
- let _, checkResults = getParseAndCheckResults """
+ let symbolUse = Checker.getSymbolUse """
namespace F
type Foo() =
let mutable b = 0
- member this.Count with set (v:int) = b <- v
+ member this.Coun{caret}t with set (v:int) = b <- v
"""
-
- let _all = checkResults.GetAllUsesOfAllSymbolsInFile()
-
- let getSymbolUses =
- checkResults.GetSymbolUsesAtLocation(6, 21, " member this.Count with set (v:int) = b <- v", ["Count"])
- |> List.map (fun su -> su.Symbol)
-
- match getSymbolUses with
- | [ :? FSharpMemberOrFunctionOrValue as mfv ] ->
+ match symbolUse.Symbol with
+ | :? FSharpMemberOrFunctionOrValue as mfv ->
Assert.True mfv.IsPropertySetterMethod
assertRange (6, 16) (6, 21) mfv.SignatureLocation.Value
| symbols -> failwith $"Unexpected symbols, got %A{symbols}"
[]
let ``Property with set/get has property symbol`` () =
- let _, checkResults = getParseAndCheckResults """
+ let symbolUses = Checker.getSymbolUses """
namespace F
type Foo() =
let mutable b = 0
- member this.Count with set (v:int) = b <- v and get () = b
+ member this.Coun{caret}t with set (v:int) = b <- v and get () = b
"""
-
- let propSymbol, _ =
- checkResults.GetSymbolUsesAtLocation(6, 21, " member this.Count with set (v:int) = b <- v", ["Count"])
- |> List.pick pickPropertySymbol
-
+ let propSymbol, _ = symbolUses |> List.pick pickPropertySymbol
Assert.True propSymbol.IsProperty
Assert.True propSymbol.HasGetterMethod
Assert.True propSymbol.HasSetterMethod
@@ -715,22 +679,18 @@ type Foo() =
[]
let ``Property usage is reported properly`` () =
- let _, checkResults = getParseAndCheckResults """
+ let context, checkResults = Checker.getCheckedResolveContext """
module X
type Foo() =
let mutable b = 0
- member x.Name
+ member x.Nam{caret}e
with get() = 0
and set (v: int) = ()
ignore (Foo().Name)
"""
-
- let propertySymbolUse, _ =
- checkResults.GetSymbolUsesAtLocation(6, 17, " member x.Name", ["Name"])
- |> List.pick pickPropertySymbol
-
+ let propertySymbolUse, _ = checkResults.GetSymbolUses(context) |> List.pick pickPropertySymbol
let usages = checkResults.GetUsesOfSymbolInFile(propertySymbolUse)
Assert.Equal(2, usages.Length)
Assert.True usages.[0].IsFromDefinition
@@ -738,39 +698,31 @@ ignore (Foo().Name)
[]
let ``Property symbol is present after critical error`` () =
- let _, checkResults = getParseAndCheckResults """
+ let context, checkResults = Checker.getCheckedResolveContext """
module X
let _ = UnresolvedName
type X() =
- member val Y = 1 with get, set
+ member val Y{caret} = 1 with get, set
"""
-
- let _propertySymbolUse, _ =
- checkResults.GetSymbolUsesAtLocation(7, 16, " member val Y = 1 with get, set", ["Y"])
- |> List.pick pickPropertySymbol
-
- Assert.False (Array.isEmpty checkResults.Diagnostics)
+ let _propertySymbolUse, _ = checkResults.GetSymbolUses(context) |> List.pick pickPropertySymbol
+ Assert.False(Array.isEmpty checkResults.Diagnostics)
[]
let ``Property symbol is present after critical error in property`` () =
- let _, checkResults = getParseAndCheckResults """
+ let context, checkResults = Checker.getCheckedResolveContext """
module Z
type X() =
- member val Y = UnresolvedName with get, set
+ member val Y{caret} = UnresolvedName with get, set
"""
-
- let _propertySymbolUse, _ =
- checkResults.GetSymbolUsesAtLocation(5, 16, " member val Y = UnresolvedName with get, set", ["Y"])
- |> List.pick pickPropertySymbol
-
+ let _propertySymbolUse, _ = checkResults.GetSymbolUses(context) |> List.pick pickPropertySymbol
Assert.False (Array.isEmpty checkResults.Diagnostics)
[]
let ``Property symbol on interface implementation`` () =
- let _, checkResults = getParseAndCheckResults """
+ let context, checkResults = Checker.getCheckedResolveContext """
module Z
type I =
@@ -778,13 +730,9 @@ type I =
type T() =
interface I with
- member val P = 1 with get, set
+ member val P{caret} = 1 with get, set
"""
-
- let _propertySymbolUse, mProp =
- checkResults.GetSymbolUsesAtLocation(9, 20, " member val P = 1 with get, set", ["P"])
- |> List.pick pickPropertySymbol
-
+ let _propertySymbolUse, mProp = checkResults.GetSymbolUses(context) |> List.pick pickPropertySymbol
assertRange (9, 19) (9, 20) mProp
@@ -1003,118 +951,79 @@ let f (r: {| A: int; C: int |}) =
Assert.Equal(5, getSymbolUses.Length)
- []
- let ``Symbols for fields in nested copy-and-update are present`` () =
- let _, checkResults = getParseAndCheckResults """
-type RecordA<'a> = { Foo: 'a; Bar: int; Zoo: RecordA<'a> }
-
-let nestedFunc (a: RecordA) = { a with Zoo.Foo = 1; Zoo.Zoo.Bar = 2; Zoo.Bar = 3; Foo = 4 }
-"""
-
- let line = "let nestedFunc (a: RecordA) = { a with Zoo.Foo = 1; Zoo.Zoo.Bar = 2; Zoo.Bar = 3; Foo = 4 }"
-
- let fieldSymbolUse =
- checkResults.GetSymbolUsesAtLocation(4, 47, line, [ "Zoo" ])
- |> List.exactlyOne
-
+ let private checkFieldUsage name typeName range source =
+ let fieldSymbolUse = Checker.getSymbolUse source
match fieldSymbolUse.Symbol with
| :? FSharpField as field ->
- Assert.Equal ("Zoo", field.Name)
- Assert.Equal ("RecordA`1", field.DeclaringEntity.Value.CompiledName)
- assertRange (4, 44) (4, 47) fieldSymbolUse.Range
+ Assert.Equal(name, field.Name)
+ Assert.Equal(typeName, field.DeclaringEntity.Value.CompiledName)
+ assertRange (fst range) (snd range) fieldSymbolUse.Range
| _ -> failwith "Symbol was not FSharpField"
+ []
+ let ``Nested copy-and-update 01`` () =
+ checkFieldUsage "Zoo" "RecordA`1" ((4, 44), (4, 47)) """
+type RecordA<'a> = { Foo: 'a; Bar: int; Zoo: RecordA<'a> }
- let fieldSymbolUse =
- checkResults.GetSymbolUsesAtLocation(4, 51, line, [ "Foo" ])
- |> List.exactlyOne
-
- match fieldSymbolUse.Symbol with
- | :? FSharpField as field ->
- Assert.Equal ("Foo", field.Name)
- Assert.Equal ("RecordA`1", field.DeclaringEntity.Value.CompiledName)
- assertRange (4, 48) (4, 51) fieldSymbolUse.Range
-
- | _ -> failwith "Symbol was not FSharpField"
-
-
- let fieldSymbolUse =
- checkResults.GetSymbolUsesAtLocation(4, 60, line, [ "Zoo" ])
- |> List.exactlyOne
-
- match fieldSymbolUse.Symbol with
- | :? FSharpField as field ->
- Assert.Equal ("Zoo", field.Name)
- Assert.Equal ("RecordA`1", field.DeclaringEntity.Value.CompiledName)
- assertRange (4, 57) (4, 60) fieldSymbolUse.Range
-
- | _ -> failwith "Symbol was not FSharpField"
-
+let nestedFunc (a: RecordA) = { a with Zo{caret}o.Foo = 1; Zoo.Zoo.Bar = 2; Zoo.Bar = 3; Foo = 4 }
+"""
- let fieldSymbolUse =
- checkResults.GetSymbolUsesAtLocation(4, 64, line, [ "Zoo" ])
- |> List.exactlyOne
-
- match fieldSymbolUse.Symbol with
- | :? FSharpField as field ->
- Assert.Equal ("Zoo", field.Name)
- Assert.Equal ("RecordA`1", field.DeclaringEntity.Value.CompiledName)
- assertRange (4, 61) (4, 64) fieldSymbolUse.Range
+ []
+ let ``Nested copy-and-update 02`` () =
+ checkFieldUsage "Foo" "RecordA`1" ((4, 48), (4, 51)) """
+type RecordA<'a> = { Foo: 'a; Bar: int; Zoo: RecordA<'a> }
- | _ -> failwith "Symbol was not FSharpField"
+let nestedFunc (a: RecordA) = { a with Zoo.Fo{caret}o = 1; Zoo.Zoo.Bar = 2; Zoo.Bar = 3; Foo = 4 }
+"""
+ []
+ let ``Nested copy-and-update 03`` () =
+ checkFieldUsage "Zoo" "RecordA`1" ((4, 57), (4, 60)) """
+type RecordA<'a> = { Foo: 'a; Bar: int; Zoo: RecordA<'a> }
- let fieldSymbolUse =
- checkResults.GetSymbolUsesAtLocation(4, 68, line, [ "Bar" ])
- |> List.exactlyOne
-
- match fieldSymbolUse.Symbol with
- | :? FSharpField as field ->
- Assert.Equal ("Bar", field.Name)
- Assert.Equal ("RecordA`1", field.DeclaringEntity.Value.CompiledName)
- assertRange (4, 65) (4, 68) fieldSymbolUse.Range
+let nestedFunc (a: RecordA) = { a with Zoo.Foo = 1; Z{caret}oo.Zoo.Bar = 2; Zoo.Bar = 3; Foo = 4 }
+"""
- | _ -> failwith "Symbol was not FSharpField"
+ []
+ let ``Nested copy-and-update 04`` () =
+ checkFieldUsage "Zoo" "RecordA`1" ((4, 61), (4, 64)) """
+type RecordA<'a> = { Foo: 'a; Bar: int; Zoo: RecordA<'a> }
+let nestedFunc (a: RecordA) = { a with Zoo.Foo = 1; Zoo.Zo{caret}o.Bar = 2; Zoo.Bar = 3; Foo = 4 }
+"""
- let fieldSymbolUse =
- checkResults.GetSymbolUsesAtLocation(4, 77, line, [ "Zoo" ])
- |> List.exactlyOne
-
- match fieldSymbolUse.Symbol with
- | :? FSharpField as field ->
- Assert.Equal ("Zoo", field.Name)
- Assert.Equal ("RecordA`1", field.DeclaringEntity.Value.CompiledName)
- assertRange (4, 74) (4, 77) fieldSymbolUse.Range
+ []
+ let ``Nested copy-and-update 05`` () =
+ checkFieldUsage "Bar" "RecordA`1" ((4, 65), (4, 68)) """
+type RecordA<'a> = { Foo: 'a; Bar: int; Zoo: RecordA<'a> }
- | _ -> failwith "Symbol was not FSharpField"
+let nestedFunc (a: RecordA) = { a with Zoo.Foo = 1; Zoo.Zoo.B{caret}ar = 2; Zoo.Bar = 3; Foo = 4 }
+"""
+ []
+ let ``Nested copy-and-update 06`` () =
+ checkFieldUsage "Zoo" "RecordA`1" ((4, 74), (4, 77)) """
+type RecordA<'a> = { Foo: 'a; Bar: int; Zoo: RecordA<'a> }
- let fieldSymbolUse =
- checkResults.GetSymbolUsesAtLocation(4, 81, line, [ "Bar" ])
- |> List.exactlyOne
-
- match fieldSymbolUse.Symbol with
- | :? FSharpField as field ->
- Assert.Equal ("Bar", field.Name)
- Assert.Equal ("RecordA`1", field.DeclaringEntity.Value.CompiledName)
- assertRange (4, 78) (4, 81) fieldSymbolUse.Range
+let nestedFunc (a: RecordA) = { a with Zoo.Foo = 1; Zoo.Zoo.Bar = 2; Z{caret}oo.Bar = 3; Foo = 4 }
+"""
- | _ -> failwith "Symbol was not FSharpField"
+ []
+ let ``Nested copy-and-update 07`` () =
+ checkFieldUsage "Bar" "RecordA`1" ((4, 78), (4, 81)) """
+type RecordA<'a> = { Foo: 'a; Bar: int; Zoo: RecordA<'a> }
+let nestedFunc (a: RecordA) = { a with Zoo.Foo = 1; Zoo.Zoo.Bar = 2; Zoo.B{caret}ar = 3; Foo = 4 }
+"""
- let fieldSymbolUse =
- checkResults.GetSymbolUsesAtLocation(4, 90, line, [ "Foo" ])
- |> List.exactlyOne
-
- match fieldSymbolUse.Symbol with
- | :? FSharpField as field ->
- Assert.Equal ("Foo", field.Name)
- Assert.Equal ("RecordA`1", field.DeclaringEntity.Value.CompiledName)
- assertRange (4, 87) (4, 90) fieldSymbolUse.Range
+ []
+ let ``Nested copy-and-update 08`` () =
+ checkFieldUsage "Foo" "RecordA`1" ((4, 87), (4, 90)) """
+type RecordA<'a> = { Foo: 'a; Bar: int; Zoo: RecordA<'a> }
- | _ -> failwith "Symbol was not FSharpField"
+let nestedFunc (a: RecordA) = { a with Zoo.Foo = 1; Zoo.Zoo.Bar = 2; Zoo.Bar = 3; Fo{caret}o = 4 }
+"""
module ComputationExpressions =
[]
@@ -1294,14 +1203,11 @@ type T() =
module Event =
[]
let ``CLIEvent member does not produce additional property symbol`` () =
- let _, checkResults = getParseAndCheckResults """
-type T() =
+ let allSymbols = Checker.getSymbolUses """
+type T() =
[]
- member this.Event = Event().Publish
+ member this.Ev{caret}ent = Event().Publish
"""
- let allSymbols =
- checkResults.GetSymbolUsesAtLocation(4, 21, " member this.Event = Event().Publish", [ "Event" ])
-
let hasPropertySymbols =
allSymbols
|> List.exists (fun su ->
diff --git a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs
index 90a74ed3e4e..9fd5f364b0c 100644
--- a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs
+++ b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs
@@ -6,31 +6,24 @@
open FSharp.Compiler.CodeAnalysis
open FSharp.Compiler.Service.Tests.Common
open FSharp.Compiler.Text
-open FSharp.Compiler.Tokenization
open FSharp.Compiler.EditorServices
open FSharp.Compiler.Symbols
open FSharp.Test
open Xunit
let testXmlDocFallbackToSigFileWhileInImplFile sigSource implSource (expectedContent: string) =
- let implSource, lineText, pos, plid, names = getPartialIdentifierAndPrepareSource implSource
+ let context = Checker.getResolveContext implSource
let files =
Map.ofArray
- [| "A.fsi",
- SourceText.ofString sigSource
-
-
- "A.fs",
- SourceText.ofString implSource |]
+ [| "A.fsi", SourceText.ofString sigSource
+ "A.fs", SourceText.ofString context.Source |]
let documentSource fileName = Map.tryFind fileName files |> async.Return
let projectOptions =
let _, projectOptions = mkTestFileAndOptions Array.empty
-
- { projectOptions with
- SourceFiles = [| "A.fsi"; "A.fs" |] }
+ { projectOptions with SourceFiles = [| "A.fsi"; "A.fs" |] }
let checker =
FSharpChecker.Create(documentSource = DocumentSource.Custom documentSource,
@@ -43,9 +36,7 @@ let testXmlDocFallbackToSigFileWhileInImplFile sigSource implSource (expectedCon
match checkResult with
| _, FSharpCheckFileAnswer.Succeeded(checkResults) ->
// Get the tooltip for (line, colAtEndOfNames) in the implementation file
- let (ToolTipText tooltipElements) =
- checkResults.GetToolTip(pos.Line, pos.Column, lineText, names, FSharpTokenTag.Identifier)
-
+ let (ToolTipText tooltipElements) = checkResults.GetTooltip(context)
match tooltipElements with
| ToolTipElement.Group [ element ] :: _ ->
match element.XmlDoc with
@@ -264,11 +255,8 @@ let a = 23
let testToolTipSquashing source =
- let source, lineText, pos, plid, names = getPartialIdentifierAndPrepareSource source
- let files =
- Map.ofArray
- [| "A.fs",
- SourceText.ofString source |]
+ let context = Checker.getResolveContext source
+ let files = Map.ofArray [| "A.fs", SourceText.ofString context.Source |]
let documentSource fileName = Map.tryFind fileName files |> async.Return
@@ -288,13 +276,10 @@ let testToolTipSquashing source =
match checkResult with
| _, FSharpCheckFileAnswer.Succeeded(checkResults) ->
-
// Get the tooltip for `bar`
- let (ToolTipText tooltipElements) =
- checkResults.GetToolTip(pos.Line, pos.Column, lineText, names, FSharpTokenTag.Identifier)
+ let (ToolTipText tooltipElements) = checkResults.GetTooltip(context)
+ let (ToolTipText tooltipElementsSquashed) = checkResults.GetTooltip(context, 10)
- let (ToolTipText tooltipElementsSquashed) =
- checkResults.GetToolTip(pos.Line, pos.Column, lineText, names, FSharpTokenTag.Identifier, 10)
match tooltipElements, tooltipElementsSquashed with
| groups, groupsSquashed ->
let breaks =
@@ -388,56 +373,53 @@ let taggedTextsToString (t: TaggedText array) =
t
|> Array.map (fun taggedText -> taggedText.Text)
|> String.concat ""
+
let assertAndExtractTooltip (ToolTipText(items)) =
Assert.Equal(1,items.Length)
- match items.[0] with
+ match items[0] with
| ToolTipElement.Group [ singleElement ] ->
let toolTipText =
singleElement.MainDescription
|> taggedTextsToString
toolTipText, singleElement.XmlDoc, singleElement.Remarks |> Option.map taggedTextsToString
- | _ -> failwith $"Expected group, got {items.[0]}"
+ | _ -> failwith $"Expected group, got {items[0]}"
let assertAndGetSingleToolTipText items =
let text,_xml,_remarks = assertAndExtractTooltip items
text
-let normalize (s:string) = s.Replace("\r\n", "\n").Replace("\n\n", "\n")
+let normalize (s: string) = s.Replace("\r\n", "\n").Replace("\n\n", "\n")
[]
let ``Auto property should display a single tool tip`` () =
- let source = """
+ Checker.getTooltip """
namespace Foo
/// Some comment on class
type Bar() =
/// Some comment on class member
- member val Foo = "bla" with get, set
+ member val Fo{caret}o = "bla" with get, set
"""
- let checkResults = getCheckResults source Array.empty
- checkResults.GetToolTip(7, 18, " member val Foo = \"bla\" with get, set", [ "Foo" ], FSharpTokenTag.Identifier)
|> assertAndGetSingleToolTipText
|> Assert.shouldBeEquivalentTo "property Bar.Foo: string with get, set"
[]
let ``Should display nullable Csharp code analysis annotations on method argument`` () =
-
- let source = """module Foo
-let exists() = System.IO.Path.Exists(null:string)
+ Checker.getTooltipWithOptions [|"--checknulls+";"--langversion:preview"|] """
+module Foo
+
+let exists() = System.IO.Path.Exist{caret}s(null:string)
"""
- let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
- checkResults.GetToolTip(2, 36, "let exists() = System.IO.Path.Exists(null:string)", [ "Exists" ], FSharpTokenTag.Identifier)
|> assertAndGetSingleToolTipText
|> Assert.shouldBeEquivalentTo "System.IO.Path.Exists([] path: string | null) : bool"
[]
let ``Should display xml doc on a nullable BLC method`` () =
-
- let source = """module Foo
-let exists() = System.IO.Path.Exists(null:string)
+ Checker.getTooltipWithOptions [|"--checknulls+";"--langversion:preview"|] """
+module Foo
+
+let exists() = System.IO.Path.Exi{caret}sts(null:string)
"""
- let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
- checkResults.GetToolTip(2, 36, "let exists() = System.IO.Path.Exists(null:string)", [ "Exists" ], FSharpTokenTag.Identifier)
|> assertAndExtractTooltip
|> fun (text,xml,_remarks) ->
text |> Assert.shouldBeEquivalentTo "System.IO.Path.Exists([] path: string | null) : bool"
@@ -448,15 +430,14 @@ let exists() = System.IO.Path.Exists(null:string)
[]
let ``Should display xml doc on fsharp hosted nullable function`` () =
-
- let source = """module Foo
+ Checker.getTooltipWithOptions [|"--checknulls+";"--langversion:preview"|] """
+module Foo
+
/// This is a xml doc above myFunc
let myFunc(x:string|null) : string | null = x
-let exists() = myFunc(null)
+let exists() = myFu{caret}nc(null)
"""
- let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
- checkResults.GetToolTip(5, 21, "let exists() = myFunc(null)", [ "myFunc" ], FSharpTokenTag.Identifier)
|> assertAndExtractTooltip
|> fun (text,xml,remarks) ->
match xml with
@@ -469,78 +450,76 @@ let exists() = myFunc(null)
[]
let ``Should display nullable Csharp code analysis annotations on method return type`` () =
-
- let source = """module Foo
-let getPath() = System.IO.Path.GetFileName(null:string)
+ Checker.getTooltipWithOptions [|"--checknulls+";"--langversion:preview"|] """
+module Foo
+
+let getPath() = System.IO.Path.GetFile{caret}Name(null:string)
"""
- let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
- checkResults.GetToolTip(2, 42, "let getPath() = System.IO.Path.GetFileName(null:string)", [ "GetFileName" ], FSharpTokenTag.Identifier)
|> assertAndGetSingleToolTipText
|> Assert.shouldBeEquivalentTo ("""[]
System.IO.Path.GetFileName(path: string | null) : string | null""" |> normalize)
[]
let ``Should display nullable Csharp code analysis annotations on TryParse pattern`` () =
- let source = """module Foo
-let success,version = System.Version.TryParse(null)
+ Checker.getTooltipWithOptions [|"--checknulls+";"--langversion:preview"|] """
+module Foo
+
+let success,version = System.Version.TryPar{caret}se(null)
"""
- let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
- checkResults.GetToolTip(2, 45, "let success,version = System.Version.TryParse(null)", [ "TryParse" ], FSharpTokenTag.Identifier)
|> assertAndGetSingleToolTipText
- |> Assert.shouldBeEquivalentTo ("""System.Version.TryParse([] input: string | null, [] result: byref) : bool""")
+ |> Assert.shouldBeEquivalentTo """System.Version.TryParse([] input: string | null, [] result: byref) : bool"""
[]
let ``Display with nullable annotations can be squashed`` () =
- let source = """module Foo
-let success,version = System.Version.TryParse(null)
+ Checker.getTooltipWithOptions [|"--checknulls+";"--langversion:preview"|] """
+module Foo
+
+let success,version = System.Version.Try{caret}Parse(null)
"""
- let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
- checkResults.GetToolTip(2, 45, "let success,version = System.Version.TryParse(null)", [ "TryParse" ], FSharpTokenTag.Identifier,width=100)
|> assertAndGetSingleToolTipText
- |> Assert.shouldBeEquivalentTo ("""System.Version.TryParse([] input: string | null,
- [] result: byref) : bool""" |> normalize)
+ |> Assert.shouldBeEquivalentTo ("""System.Version.TryParse([] input: string | null, [] result: byref) : bool""" |> normalize)
[]
let ``Allows ref struct is shown on BCL interface declaration`` () =
- let source = """module Foo
+ Checker.getTooltipWithOptions [|"--checknulls+";"--langversion:preview"|] """
+module Foo
+
open System
-let myAction : Action | null = null
+let myAction : Acti{caret}on | null = null
"""
- let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
- checkResults.GetToolTip(3, 21, "let myAction : Action | null = null", [ "Action" ], FSharpTokenTag.Identifier)
|> assertAndGetSingleToolTipText
|> Assert.shouldStartWith ("""type Action<'T (allows ref struct)>""" |> normalize)
[]
let ``Allows ref struct is shown for each T on BCL interface declaration`` () =
- let source = """module Foo
+ Checker.getTooltipWithOptions [|"--checknulls+";"--langversion:preview"|] """
+module Foo
+
open System
-let myAction : Action | null = null
+let myAction : Acti{caret}on | null = null
"""
- let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|]
- checkResults.GetToolTip(3, 21, "let myAction : Action | null = null", [ "Action" ], FSharpTokenTag.Identifier)
|> assertAndGetSingleToolTipText
|> Assert.shouldStartWith ("""type Action<'T1,'T2,'T3,'T4 (allows ref struct and allows ref struct and allows ref struct and allows ref struct)>""" |> normalize)
[]
let ``Allows ref struct is shown on BCL method usage`` () =
- let source = """module Foo
+ Checker.getTooltip """
+module Foo
+
open System
open System.Collections.Generic
-let doIt (dict:Dictionary<'a,'b>) = dict.GetAlternateLookup<'a,'b,ReadOnlySpan>()
+let doIt (dict:Dictionary<'a,'b>) = dict.GetAltern{caret}ateLookup<'a,'b,ReadOnlySpan>()
"""
- let checkResults = getCheckResults source [|"--langversion:preview"|]
- checkResults.GetToolTip(4, 59, "let doIt (dict:Dictionary<'a,'b>) = dict.GetAlternateLookup<'a,'b,ReadOnlySpan>()", [ "GetAlternateLookup" ], FSharpTokenTag.Identifier)
|> assertAndGetSingleToolTipText
|> Assert.shouldContain ("""'TAlternateKey (allows ref struct)""" |> normalize)
[]
let ``Allows ref struct is not shown on BCL interface usage`` () =
- let source = """module Foo
+ Checker.getTooltip """
+module Foo
+
open System
-let doIt(myAction : Action) = myAction.Invoke(42)
+let doIt(myAction : Action) = myAc{caret}tion.Invoke(42)
"""
- let checkResults = getCheckResults source [|"--langversion:preview"|]
- checkResults.GetToolTip(3, 43, "let doIt(myAction : Action) = myAction.Invoke(42)", [ "myAction" ], FSharpTokenTag.Identifier)
|> assertAndGetSingleToolTipText
|> Assert.shouldBeEquivalentTo ("""val myAction: Action""" |> normalize)
\ No newline at end of file
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
index ddc350b30c8..da08a645140 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
@@ -37,8 +37,8 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+getOptionArgList@307::Invoke([FSharp.Compiler.Service]FSharp.Compiler.CompilerOptions+CompilerOption, string)][offset 0x0000003E][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+getSwitch@325::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+attempt@373::Invoke([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)][offset 0x00000E9F][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1781@1781::Invoke(int32)][offset 0x00000030][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1781@1781::Invoke(int32)][offset 0x00000039][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1780@1780::Invoke(int32)][offset 0x00000030][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1780@1780::Invoke(int32)][offset 0x00000039][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x0000062B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000634][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000065][found Byte] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
index 239ffc5ea9a..92de58c4615 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
@@ -53,8 +53,8 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+attempt@373::Invoke([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)][offset 0x00000E9F][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+processArg@333::Invoke([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)][offset 0x0000004D][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+ResponseFile+parseLine@239::Invoke(string)][offset 0x00000031][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1781@1781::Invoke(int32)][offset 0x00000030][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1781@1781::Invoke(int32)][offset 0x00000039][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1780@1780::Invoke(int32)][offset 0x00000030][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+Pipe #1 stage #1 at line 1780@1780::Invoke(int32)][offset 0x00000039][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerImports+line@570-1::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x0000062B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000634][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
index cdd91d6dfee..7126edcff60 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
@@ -39,8 +39,8 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::attempt@372([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, string, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)][offset 0x00000A99][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::AddPathMapping([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, string)][offset 0x0000000B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnderflow]: : FSharp.Compiler.CompilerOptions::DoWithColor([System.Console]System.ConsoleColor, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2)][offset 0x0000005E] Stack underflow.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1781::Invoke(int32)][offset 0x00000031][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1781::Invoke(int32)][offset 0x0000003A][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1780::Invoke(int32)][offset 0x00000031][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1780::Invoke(int32)][offset 0x0000003A][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x0000059C][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x000005A5][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.IlxGen::HashRangeSorted([S.P.CoreLib]System.Collections.Generic.IDictionary`2>)][offset 0x00000011][found ref '[FSharp.Compiler.Service]FSharp.Compiler.IlxGen+HashRangeSorted@1873-1'][expected ref '[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,int32>'] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index f0ae4b53b2f..60128c71130 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -55,8 +55,8 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::subSystemVersionSwitch$cont@656([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, string, [FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000000B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnderflow]: : FSharp.Compiler.CompilerOptions::DoWithColor([System.Console]System.ConsoleColor, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2)][offset 0x0000005E] Stack underflow.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions+ResponseFile+parseLine@239::Invoke(string)][offset 0x00000026][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1781::Invoke(int32)][offset 0x00000031][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1781::Invoke(int32)][offset 0x0000003A][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1780::Invoke(int32)][offset 0x00000031][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.ParseAndCheckInputs+CheckMultipleInputsUsingGraphMode@1780::Invoke(int32)][offset 0x0000003A][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerImports+TcConfig-TryResolveLibWithDirectories@568-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000021][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerImports+TcConfig-TryResolveLibWithDirectories@568-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000003B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x0000059C][found Char] Unexpected type on the stack.
diff --git a/tests/service/data/SyntaxTree/ParsedHashDirective/TripleQuoteStringAsParsedHashDirectiveArgument.fs.bsl b/tests/service/data/SyntaxTree/ParsedHashDirective/TripleQuoteStringAsParsedHashDirectiveArgument.fs.bsl
index 6321ae9bfdd..e6bbce906b4 100644
--- a/tests/service/data/SyntaxTree/ParsedHashDirective/TripleQuoteStringAsParsedHashDirectiveArgument.fs.bsl
+++ b/tests/service/data/SyntaxTree/ParsedHashDirective/TripleQuoteStringAsParsedHashDirectiveArgument.fs.bsl
@@ -7,5 +7,5 @@ ImplFile
([TripleQuoteStringAsParsedHashDirectiveArgument], false, AnonModule,
[], PreXmlDocEmpty, [], None, (3,0--3,0), { LeadingKeyword = None })],
(true, true), { ConditionalDirectives = []
- WarnDirectives = [Nowarn ([40], (2,0--2,16))]
+ WarnDirectives = [Nowarn (2,0--2,16)]
CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/WarnScope/WarnScope.fs.bsl b/tests/service/data/SyntaxTree/WarnScope/WarnScope.fs.bsl
index ae8bcd1dbd2..e6ae4ca8338 100644
--- a/tests/service/data/SyntaxTree/WarnScope/WarnScope.fs.bsl
+++ b/tests/service/data/SyntaxTree/WarnScope/WarnScope.fs.bsl
@@ -7,6 +7,5 @@ ImplFile
Expr (Const (Unit, (4,0--4,2)), (4,0--4,2))], PreXmlDocEmpty, [],
None, (2,0--4,2), { LeadingKeyword = None })], (true, true),
{ ConditionalDirectives = []
- WarnDirectives =
- [Nowarn ([20], (1,0--1,10)); Warnon ([20], (3,0--3,10))]
- CodeComments = [LineComment (3,12--3,24)] }, set []))
+ WarnDirectives = [Nowarn (1,0--1,10); Warnon (3,0--3,24)]
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/WarnScope/WarnScopeInSubmodule.fs.bsl b/tests/service/data/SyntaxTree/WarnScope/WarnScopeInSubmodule.fs.bsl
index 40470a3603c..380bad05336 100644
--- a/tests/service/data/SyntaxTree/WarnScope/WarnScopeInSubmodule.fs.bsl
+++ b/tests/service/data/SyntaxTree/WarnScope/WarnScopeInSubmodule.fs.bsl
@@ -17,6 +17,5 @@ ImplFile
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--7,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
- WarnDirectives =
- [Nowarn ([20; 25], (3,4--3,17)); Warnon ([20; 25], (5,4--5,17))]
- CodeComments = [LineComment (5,18--5,30)] }, set []))
+ WarnDirectives = [Nowarn (3,0--3,17); Warnon (5,0--5,30)]
+ CodeComments = [] }, set []))