diff --git a/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs b/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs
index 311888a6a65..c8acf99d7e7 100644
--- a/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs
+++ b/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.ProjectFile.fs
@@ -41,7 +41,7 @@ $(POUND_R)
projectTemplate.Replace("$(POUND_R)", expandReferences)
- let generateProjectBody =
+ let generateProjectFile =
"""
@@ -193,3 +193,13 @@ $(PACKAGEREFERENCES)
"""
+
+ let generateProjectNugetConfigFile =
+ """
+
+
+
+$(NUGET_SOURCES)
+
+
+ """
diff --git a/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs b/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs
index 14f55dc6fb4..31a9e003457 100644
--- a/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs
+++ b/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.Utilities.fs
@@ -6,6 +6,7 @@ open System.Diagnostics
open System.IO
open System.Reflection
open System.Security.Cryptography
+open System.Text.RegularExpressions
open FSDependencyManager
open Internal.Utilities.FSharpEnvironment
@@ -285,7 +286,7 @@ module internal Utilities =
let generateSourcesFromNugetConfigs scriptDirectory workingDir timeout =
let dotnetHostPath = getDotnetHostPath ()
- let args = "nuget list source --format short"
+ let args = "nuget list source --format detailed"
let success, stdOut, stdErr =
executeTool dotnetHostPath args scriptDirectory timeout
@@ -304,17 +305,36 @@ module internal Utilities =
ignore workingDir
ignore stdErr
#endif
- seq {
- if success then
- for source in stdOut do
- // String returned by `dotnet nuget list source --format short` is formatted similar to:
- // E https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json
- // Use enabled feeds only (see NuGet.Commands.ListSourceRunner.Run) and strip off the flags.
- if source.Length > 0 && source.[0] = 'E' then
- let pos = source.IndexOf(" ")
-
- if pos >= 0 then
- "i", source.Substring(pos).Trim()
- }
+ if success then
+ // String returned by `dotnet nuget list source --format detailed` is formatted similar to:
+ // Registered Sources:
+ // 1. dotnet-eng [Enabled]
+ // https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json
+ // 2. dotnet-tools [Enabled]
+ // https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
+ // 3. dotnet5 [Enabled]
+ // https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json
+ // Use enabled feeds only (see NuGet.Commands.ListSourceRunner.Run) and strip off the flags.
+ let pattern =
+ @"(\s*\d+\.+\s*)(?'name'\S*)(\s*)\[(?'enabled'Enabled|Disabled)\](\s*)$(\s*)(?'uri'\S*)"
+
+ let regex =
+ new Regex(pattern, RegexOptions.Multiline ||| RegexOptions.ExplicitCapture)
+
+ let sourcelist = String.concat Environment.NewLine stdOut
+
+ String.concat
+ Environment.NewLine
+ [|
+ for m in regex.Matches(sourcelist) do
+ let name = m.Groups["name"].Value
+ let enabled = m.Groups["enabled"].Value
+ let uri = m.Groups["uri"].Value
+
+ if enabled.Length > 0 && enabled[0] = 'E' then
+ $""" """
+ |]
+ else
+ ""
let computeSha256HashOfBytes (bytes: byte[]) : byte[] = SHA256.Create().ComputeHash(bytes)
diff --git a/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fs b/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fs
index 0740f5aa753..90193a2f57e 100644
--- a/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fs
+++ b/src/FSharp.DependencyManager.Nuget/FSharp.DependencyManager.fs
@@ -347,6 +347,7 @@ type FSharpDependencyManager(outputDirectory: string option, useResultsCache: bo
let prepareDependencyResolutionFiles
(
+ scriptDirectory: string,
scriptExt: string,
directiveLines: (string * string) seq,
targetFrameworkMoniker: string,
@@ -368,28 +369,36 @@ type FSharpDependencyManager(outputDirectory: string option, useResultsCache: bo
|> List.map FSharpDependencyManager.formatPackageReference
|> Seq.concat
+ let generatedNugetSources =
+ generateSourcesFromNugetConfigs scriptDirectory projectDirectory.Value timeout
+
let packageReferenceText = String.Join(Environment.NewLine, packageReferenceLines)
let projectPath = Path.Combine(projectDirectory.Value, "Project.fsproj")
+ let nugetPath = Path.Combine(projectDirectory.Value, "NuGet.config")
let generateAndBuildProjectArtifacts =
let writeFile path body =
if not (generatedScripts.ContainsKey(body.GetHashCode().ToString())) then
emitFile path body
- let generateProjBody =
- generateProjectBody
+ let generateProjectFile =
+ generateProjectFile
.Replace("$(TARGETFRAMEWORK)", targetFrameworkMoniker)
.Replace("$(RUNTIMEIDENTIFIER)", runtimeIdentifier)
.Replace("$(PACKAGEREFERENCES)", packageReferenceText)
.Replace("$(SCRIPTEXTENSION)", scriptExt)
+ let generateProjectNugetConfigFile =
+ generateProjectNugetConfigFile.Replace("$(NUGET_SOURCES)", generatedNugetSources)
+
let timeout =
match package_timeout with
| Some _ -> package_timeout
| None -> Some timeout
- writeFile projectPath generateProjBody
+ writeFile projectPath generateProjectFile
+ writeFile nugetPath generateProjectNugetConfigFile
buildProject projectPath binLogPath timeout
generateAndBuildProjectArtifacts
@@ -469,15 +478,10 @@ type FSharpDependencyManager(outputDirectory: string option, useResultsCache: bo
| _ -> "#r @\""
let generateAndBuildProjectArtifacts =
- let configIncludes =
- generateSourcesFromNugetConfigs scriptDirectory projectDirectory.Value timeout
-
- let directiveLines = Seq.append packageManagerTextLines configIncludes
-
let resolutionHash =
FSharpDependencyManager.computeHashForResolutionInputs (
scriptExt,
- directiveLines,
+ packageManagerTextLines,
targetFrameworkMoniker,
runtimeIdentifier
)
@@ -486,7 +490,15 @@ type FSharpDependencyManager(outputDirectory: string option, useResultsCache: bo
match tryGetResultsForResolutionHash resolutionHash projectDirectory with
| Some resolutionResult -> true, resolutionResult
| None ->
- false, prepareDependencyResolutionFiles (scriptExt, directiveLines, targetFrameworkMoniker, runtimeIdentifier, timeout)
+ false,
+ prepareDependencyResolutionFiles (
+ scriptDirectory,
+ scriptExt,
+ packageManagerTextLines,
+ targetFrameworkMoniker,
+ runtimeIdentifier,
+ timeout
+ )
match resolutionResult.resolutionsFile with
| Some file ->
diff --git a/tests/fsharp/core/printing/output.1000.stdout.bsl b/tests/fsharp/core/printing/output.1000.stdout.bsl
index 71b706800bb..ebe47979ccd 100644
--- a/tests/fsharp/core/printing/output.1000.stdout.bsl
+++ b/tests/fsharp/core/printing/output.1000.stdout.bsl
@@ -2765,7 +2765,7 @@ val ShortName: string = "hi"
> val list2: int list = [1]
module FSI_0317.
- C6f6ae524efb4d95b2b2eaa363022f9d4a28c777f788498ca81a55b9ec1aad1a
+ A8a951db8294f99e95ae1d276a7ddaefd93d1548e6bf749bdeae55d2649682b3
{"ImmutableField0":6}
type R1 =
diff --git a/tests/fsharp/core/printing/output.200.stdout.bsl b/tests/fsharp/core/printing/output.200.stdout.bsl
index ad24f0b8ff0..07f0bcee374 100644
--- a/tests/fsharp/core/printing/output.200.stdout.bsl
+++ b/tests/fsharp/core/printing/output.200.stdout.bsl
@@ -2010,7 +2010,7 @@ val ShortName: string = "hi"
> val list2: int list = [1]
module FSI_0317.
- C6f6ae524efb4d95b2b2eaa363022f9d4a28c777f788498ca81a55b9ec1aad1a
+ A8a951db8294f99e95ae1d276a7ddaefd93d1548e6bf749bdeae55d2649682b3
{"ImmutableField0":6}
type R1 =
diff --git a/tests/fsharp/core/printing/output.multiemit.stdout.bsl b/tests/fsharp/core/printing/output.multiemit.stdout.bsl
index ef51dfc4078..5848b02b5d4 100644
--- a/tests/fsharp/core/printing/output.multiemit.stdout.bsl
+++ b/tests/fsharp/core/printing/output.multiemit.stdout.bsl
@@ -6312,7 +6312,7 @@ val ShortName: string = "hi"
> val list2: int list = [1]
module FSI_0316.
- C6f6ae524efb4d95b2b2eaa363022f9d4a28c777f788498ca81a55b9ec1aad1a
+ A8a951db8294f99e95ae1d276a7ddaefd93d1548e6bf749bdeae55d2649682b3
{"ImmutableField0":6}
type R1 =
diff --git a/tests/fsharp/core/printing/output.off.stdout.bsl b/tests/fsharp/core/printing/output.off.stdout.bsl
index 234cfc2e4fd..361d16bc019 100644
--- a/tests/fsharp/core/printing/output.off.stdout.bsl
+++ b/tests/fsharp/core/printing/output.off.stdout.bsl
@@ -1779,7 +1779,7 @@ val ShortName: string = "hi"
> val list2: int list
module FSI_0317.
- C6f6ae524efb4d95b2b2eaa363022f9d4a28c777f788498ca81a55b9ec1aad1a
+ A8a951db8294f99e95ae1d276a7ddaefd93d1548e6bf749bdeae55d2649682b3
{"ImmutableField0":6}
type R1 =
diff --git a/tests/fsharp/core/printing/output.stdout.bsl b/tests/fsharp/core/printing/output.stdout.bsl
index ef51dfc4078..5848b02b5d4 100644
--- a/tests/fsharp/core/printing/output.stdout.bsl
+++ b/tests/fsharp/core/printing/output.stdout.bsl
@@ -6312,7 +6312,7 @@ val ShortName: string = "hi"
> val list2: int list = [1]
module FSI_0316.
- C6f6ae524efb4d95b2b2eaa363022f9d4a28c777f788498ca81a55b9ec1aad1a
+ A8a951db8294f99e95ae1d276a7ddaefd93d1548e6bf749bdeae55d2649682b3
{"ImmutableField0":6}
type R1 =
diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs
index a64bc715582..12ca78b4aab 100644
--- a/tests/service/ProjectAnalysisTests.fs
+++ b/tests/service/ProjectAnalysisTests.fs
@@ -5719,7 +5719,7 @@ let checkContentAsScript content =
// set).
// because of this we have to do it all manually
let scriptName = "test.fsx"
- let tempDir = Path.GetTempPath()
+ let tempDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
let scriptFullPath = Path.Combine(tempDir, scriptName)
let sourceText = SourceText.ofString content
let projectOptions, _ = checker.GetProjectOptionsFromScript(scriptFullPath, sourceText, useSdkRefs = true, assumeDotNetFramework = false) |> Async.RunImmediate
@@ -5732,17 +5732,13 @@ let checkContentAsScript content =
[]
let ``References from #r nuget are included in script project options`` () =
- let isMacos = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX)
- if isMacos then
- Assert.Inconclusive("This test is failing on MacOS VMs now")
- else
- let checkResults = checkContentAsScript """
+ let checkResults = checkContentAsScript """
#i "nuget:https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json"
#r "nuget: Dapper"
"""
- let assemblyNames =
- checkResults.ProjectContext.GetReferencedAssemblies()
- |> Seq.choose (fun f -> f.FileName |> Option.map Path.GetFileName)
- |> Seq.distinct
- printfn "%s" (assemblyNames |> String.concat "\n")
- assemblyNames |> should contain "Dapper.dll"
+ let assemblyNames =
+ checkResults.ProjectContext.GetReferencedAssemblies()
+ |> Seq.choose (fun f -> f.FileName |> Option.map Path.GetFileName)
+ |> Seq.distinct
+ printfn "%s" (assemblyNames |> String.concat "\n")
+ assemblyNames |> should contain "Dapper.dll"
diff --git a/tests/service/ScriptOptionsTests.fs b/tests/service/ScriptOptionsTests.fs
index 083f1095979..6b692543572 100644
--- a/tests/service/ScriptOptionsTests.fs
+++ b/tests/service/ScriptOptionsTests.fs
@@ -23,85 +23,47 @@ open System
let pi = Math.PI
"""
-[]
+[]
+[]
+[]
+[]
+[]
+[]
[]
[]
+[]
[]
-let ``can generate options for different frameworks regardless of execution environment``(assumeNetFx, useSdk, flags) =
+let ``can generate options for different frameworks regardless of execution environment - useSdkRefs = false``(assumeDotNetFramework, useSdkRefs, flags) =
let path = Path.GetTempPath()
let file = tryCreateTemporaryFileName () + ".fsx"
let tempFile = Path.Combine(path, file)
let _, errors =
- checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = assumeNetFx, useSdkRefs = useSdk, otherFlags = flags)
+ checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = assumeDotNetFramework, useSdkRefs = useSdkRefs, otherFlags = flags)
|> Async.RunImmediate
match errors with
| [] -> ()
- | errors -> failwithf "Error while parsing script with assumeDotNetFramework:%b, useSdkRefs:%b, and otherFlags:%A:\n%A" assumeNetFx useSdk flags errors
+ | errors -> failwithf "Error while parsing script with otherFlags:%A:\n%A" flags errors
-#if NETFRAMEWORK
-// See https://github.com/dotnet/fsharp/pull/13994#issuecomment-1259663865
-//
-// .NET Core-based tooling can't resolve nuget packages to .NET Framework references
-[]
-#endif
-[]
+// Bugbug: https://github.com/dotnet/fsharp/issues/14781
+//[]
+[]
+[]
[]
-let ``can resolve nuget packages to right target framework for different frameworks regardless of execution environment``(assumeNetFx, useSdk, flags) =
- let isMacos = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX)
- if isMacos then
- Assert.Inconclusive("This test is failing on MacOS VMs now")
- else
- let path = Path.GetTempPath()
- let file = tryCreateTemporaryFileName () + ".fsx"
- let tempFile = Path.Combine(path, file)
- let scriptSource = """
+let ``can resolve nuget packages to right target framework for different frameworks regardless of execution environment``(flags) =
+ let path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
+ let file = tryCreateTemporaryFileNameInDirectory(path) + ".fsx"
+ let scriptFullPath = Path.Combine(path, file)
+ let scriptSource = """
#r "nuget: FSharp.Data, 3.3.3"
open System
let pi = Math.PI
"""
- let options, errors =
- checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = assumeNetFx, useSdkRefs = useSdk, otherFlags = flags)
- |> Async.RunImmediate
- match errors with
- | [] -> ()
- | errors -> failwithf "Error while parsing script with assumeDotNetFramework:%b, useSdkRefs:%b, and otherFlags:%A:\n%A" assumeNetFx useSdk flags errors
- let expectedReferenceText = (if assumeNetFx then "net45" else "netstandard2.0")
- let found = options.OtherOptions |> Array.exists (fun s -> s.Contains(expectedReferenceText) && s.Contains("FSharp.Data.dll"))
- Assert.IsTrue(found)
-
-// This test atempts to use a bad SDK number 666.666.666
-//
-// It's disabled because on CI server the SDK is still being resolved to 5.0.101 by `dotnet --version`.
-//
-// This must be because of some setting in the CI build scripts - e.g. an environment variable
-// that allows SDK resolution to be overriden. I've tried to track this down by looking through
-// https://learn.microsoft.com/dotnet/core/tools/dotnet resolution rules
-// and the F# and CI settings but can't find the setting that is causing this.
-//
-// Because of this the test has been manually verified by running locally.
-//[]
-let ``sdk dir with dodgy global json gives warning``() =
- let tempFile = tryCreateTemporaryFileName () + ".fsx"
- let tempPath = Path.GetDirectoryName(tempFile)
- let globalJsonPath = Path.Combine(tempPath, "global.json")
- FileSystem.OpenFileForWriteShim(globalJsonPath).Write("""{ "sdk": { "version": "666.666.666" } }""")
let options, errors =
- checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = false, useSdkRefs = true, otherFlags = [| |])
+ checker.GetProjectOptionsFromScript(file, SourceText.ofString scriptSource, assumeDotNetFramework = false, useSdkRefs = true, otherFlags = flags)
|> Async.RunImmediate
- FileSystem.FileDeleteShim(globalJsonPath)
match errors with
- | [] ->
- printfn "Failure!"
- printfn "tempPath = %A" tempPath
- printfn "options = %A" options
- let fxResolver = FSharp.Compiler.FxResolver(false, tempPath, rangeForErrors=range0, useSdkRefs=true, isInteractive=false, sdkDirOverride=None)
- let result = fxResolver.TryGetDesiredDotNetSdkVersionForDirectory()
- printfn "sdkVersion = %A" result
-
- printfn "options = %A" options
- failwith "Expected error while parsing script"
- | errors ->
- for error in errors do
- // {C:\Users\Administrator\AppData\Local\Temp\tmp6F0F.tmp.fsx (0,1)-(0,1) The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' ensure the relevant .NET SDK is installed. The output from 'C:\Program Files\dotnet\dotnet.exe --version' in the script directory was: ' 2.1.300 [C:\Program Files\dotnet\sdk]
- Assert.AreEqual(3384, error.ErrorNumber)
- Assert.AreEqual(tempFile, error.FileName)
+ | [] -> ()
+ | errors -> failwithf "Error while parsing script with assumeDotNetFramework:%b, useSdkRefs:%b, and otherFlags:%A:\n%A" false true flags errors
+ let expectedReferenceText = match flags |> Array.tryFind(fun f -> f = "--targetprofile:mscorlib") with | Some _ -> "net45" | _ -> "netstandard2.0"
+ let found = options.OtherOptions |> Array.exists (fun s -> s.Contains(expectedReferenceText) && s.Contains("FSharp.Data.dll"))
+ Assert.IsTrue(found)