Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experiment] Rework the dependencies in fake-cli / Fake.Runtime a little. #2825

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 70 additions & 104 deletions src/app/Fake.DotNet.Cli/DotNet.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,25 @@
/// .NET Core + CLI tools helpers
/// </summary>
[<RequireQualifiedAccess>]
#if FAKE_INTERNAL_DOTNET_CORE_CLI
module InternalDotNet =
#else
module DotNet =
#endif

// NOTE: The #if can be removed once we have a working release with the "new" API
// Currently we #load this file in build.fsx

open Fake.Core
open Fake.IO
open Fake.IO.FileSystemOperators
#if !FAKE_INTERNAL_DOTNET_CORE_CLI
open Fake.DotNet.NuGet
#endif
open System
open System.IO
open System.Security.Cryptography
open System.Text
open Newtonsoft.Json.Linq

/// <summary>
/// .NET Core SDK default install directory (set to default SDK installer paths
Expand All @@ -39,61 +44,19 @@
else
@"C:\Program Files\dotnet"

/// <summary>
/// Tries to get the DotNet SDK from the global.json, starts searching in the given directory.
/// Returns None if global.json is not found
/// </summary>
///
/// <param name="startDir">The directory to start search from</param>
let internal tryGetSDKVersionFromGlobalJsonDir startDir : string option =
let globalJsonPaths rootDir =
let rec loop (dir: DirectoryInfo) =
seq {
match dir.GetFiles "global.json" with
| [| json |] -> yield json
| _ -> ()

if not (isNull dir.Parent) then
yield! loop dir.Parent
}

loop (DirectoryInfo rootDir)

match Seq.tryHead (globalJsonPaths startDir) with
| None -> None
| Some globalJson ->
try
let content = File.ReadAllText globalJson.FullName
let json = JObject.Parse content
let sdk = json.Item("sdk") :?> JObject

match sdk.Property("version") with
| null -> None
| version -> Some(version.Value.ToString())
with exn ->
failwithf "Could not parse `sdk.version` from global.json at '%s': %s" globalJson.FullName exn.Message


/// <summary>
/// Gets the DotNet SDK from the global.json, starts searching in the given directory.
/// </summary>
let internal getSDKVersionFromGlobalJsonDir startDir : string =
tryGetSDKVersionFromGlobalJsonDir startDir
|> function
| Some version -> version
| None -> failwithf "global.json not found"

/// <summary>
/// Tries the DotNet SDK from the global.json. This file can exist in the working
/// directory or any of the parent directories Returns None if global.json is not found
/// </summary>
let tryGetSDKVersionFromGlobalJson () : string option = tryGetSDKVersionFromGlobalJsonDir "."
let tryGetSDKVersionFromGlobalJson () : string option =
GlobalJson.tryGetSDKVersionFromGlobalJson ()

/// <summary>
/// Gets the DotNet SDK from the global.json. This file can exist in the working
/// directory or any of the parent directories
/// </summary>
let getSDKVersionFromGlobalJson () : string = getSDKVersionFromGlobalJsonDir "."
let getSDKVersionFromGlobalJson () : string =
GlobalJson.getSDKVersionFromGlobalJson ()

/// <summary>
/// Get dotnet cli executable path. Probes the provided path first, then as a fallback tries the system PATH
Expand Down Expand Up @@ -152,7 +115,7 @@
use f = File.Open(fileName, FileMode.Create)
h.GetStreamAsync(url).Result.CopyTo(f)
#else
use w = new System.Net.WebClient()

Check warning on line 118 in src/app/Fake.DotNet.Cli/DotNet.fs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This construct is deprecated. WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.

Check warning on line 118 in src/app/Fake.DotNet.Cli/DotNet.fs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This construct is deprecated. WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.

Check warning on line 118 in src/app/Fake.DotNet.Cli/DotNet.fs

View workflow job for this annotation

GitHub Actions / build (macOS-13)

This construct is deprecated. WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.
w.DownloadFile(url, fileName) // Http.RequestStream url
#endif
//use outFile = File.Open(fileName, FileMode.Create)
Expand Down Expand Up @@ -695,7 +658,7 @@
| UsePreviousFile
| ReplaceWith of string list

let internal runRaw (firstArg: FirstArgReplacement) options (c: CreateProcess<'a>) =
let internal runRaw (firstArg: FirstArgReplacement) (options: Options) (c: CreateProcess<'a>) =
//let timeout = TimeSpan.MaxValue
let results = System.Collections.Generic.List<ConsoleMessage>()

Expand Down Expand Up @@ -806,6 +769,64 @@
|> runRaw (FirstArgReplacement.ReplaceWith firstArgs) options
|> CreateProcess.map fst


/// <summary>
/// dotnet --version command options
/// </summary>
type VersionOptions =
{
/// Common tool options
Common: Options
}

/// Parameter default values.
static member Create() =
{ Common = Options.Create().WithRedirectOutput true }

/// Gets the current environment
member x.Environment = x.Common.Environment

/// Changes the "Common" properties according to the given function
member inline x.WithCommon f = { x with Common = f x.Common }

/// Sets the current environment variables.
member x.WithEnvironment map =
x.WithCommon(fun c -> { c with Environment = map })

/// Sets a value indicating whether the output for the given process is redirected.
member x.WithRedirectOutput shouldRedirect =
{ x with Common = x.Common.WithRedirectOutput shouldRedirect }


/// <summary>
/// dotnet info result
/// </summary>
type VersionResult = string

/// <summary>
/// Execute dotnet --version command
/// </summary>
///
/// <param name="setParams">set version command parameters</param>
let getVersion setParams =
use __ = Trace.traceTask "DotNet:version" "running dotnet --version"
let param = VersionOptions.Create() |> setParams
let args = "--version"
let result = exec (fun _ -> param.Common) "" args

if not result.OK then
failwithf "dotnet --version failed with code %i" result.ExitCode

let version = result.Messages |> String.separated "\n" |> String.trim

if String.isNullOrWhiteSpace version then
failwithf "could not read version from output: \n%s" (String.Join("\n", result.Messages))

__.MarkSuccess()
version

#if !FAKE_INTERNAL_DOTNET_CORE_CLI

/// <summary>
/// Setup the environment (<c>PATH</c> and <c>DOTNET_ROOT</c>) in such a way that started processes use the given
/// dotnet SDK installation. This is useful for example when using fable,
Expand Down Expand Up @@ -916,62 +937,6 @@
__.MarkSuccess()
{ RID = rid.Value }


/// <summary>
/// dotnet --version command options
/// </summary>
type VersionOptions =
{
/// Common tool options
Common: Options
}

/// Parameter default values.
static member Create() =
{ Common = Options.Create().WithRedirectOutput true }

/// Gets the current environment
member x.Environment = x.Common.Environment

/// Changes the "Common" properties according to the given function
member inline x.WithCommon f = { x with Common = f x.Common }

/// Sets the current environment variables.
member x.WithEnvironment map =
x.WithCommon(fun c -> { c with Environment = map })

/// Sets a value indicating whether the output for the given process is redirected.
member x.WithRedirectOutput shouldRedirect =
{ x with Common = x.Common.WithRedirectOutput shouldRedirect }


/// <summary>
/// dotnet info result
/// </summary>
type VersionResult = string

/// <summary>
/// Execute dotnet --version command
/// </summary>
///
/// <param name="setParams">set version command parameters</param>
let getVersion setParams =
use __ = Trace.traceTask "DotNet:version" "running dotnet --version"
let param = VersionOptions.Create() |> setParams
let args = "--version"
let result = exec (fun _ -> param.Common) "" args

if not result.OK then
failwithf "dotnet --version failed with code %i" result.ExitCode

let version = result.Messages |> String.separated "\n" |> String.trim

if String.isNullOrWhiteSpace version then
failwithf "could not read version from output: \n%s" (String.Join("\n", result.Messages))

__.MarkSuccess()
version

/// <summary>
/// Install .NET Core SDK if required
/// </summary>
Expand Down Expand Up @@ -2073,3 +2038,4 @@
| false -> failwithf $"dotnet new --uninstall failed with code %i{result.ExitCode}"

__.MarkSuccess()
#endif
1 change: 1 addition & 0 deletions src/app/Fake.DotNet.Cli/Fake.DotNet.Cli.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="VisibleTo.fs" />
<Compile Include="GlobalJson.fs" />
<Compile Include="DotNet.fs" />
<Compile Include="CreateProcessExt.fs" />
</ItemGroup>
Expand Down
60 changes: 60 additions & 0 deletions src/app/Fake.DotNet.Cli/GlobalJson.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module internal GlobalJson

open System.IO
open Newtonsoft.Json.Linq

/// <summary>
/// Tries to get the DotNet SDK from the global.json, starts searching in the given directory.
/// Returns None if global.json is not found
/// </summary>
///
/// <param name="startDir">The directory to start search from</param>
let internal tryGetSDKVersionFromGlobalJsonDir startDir : string option =
let globalJsonPaths rootDir =
let rec loop (dir: DirectoryInfo) =
seq {
match dir.GetFiles "global.json" with
| [| json |] -> yield json
| _ -> ()

if not (isNull dir.Parent) then
yield! loop dir.Parent
}

loop (DirectoryInfo rootDir)

match Seq.tryHead (globalJsonPaths startDir) with
| None -> None
| Some globalJson ->
try
let content = File.ReadAllText globalJson.FullName
let json = JObject.Parse content
let sdk = json.Item("sdk") :?> JObject

match sdk.Property("version") with
| null -> None
| version -> Some(version.Value.ToString())
with exn ->
failwithf "Could not parse `sdk.version` from global.json at '%s': %s" globalJson.FullName exn.Message


/// <summary>
/// Gets the DotNet SDK from the global.json, starts searching in the given directory.
/// </summary>
let internal getSDKVersionFromGlobalJsonDir startDir : string =
tryGetSDKVersionFromGlobalJsonDir startDir
|> function
| Some version -> version
| None -> failwithf "global.json not found"

/// <summary>
/// Tries the DotNet SDK from the global.json. This file can exist in the working
/// directory or any of the parent directories Returns None if global.json is not found
/// </summary>
let tryGetSDKVersionFromGlobalJson () : string option = tryGetSDKVersionFromGlobalJsonDir "."

/// <summary>
/// Gets the DotNet SDK from the global.json. This file can exist in the working
/// directory or any of the parent directories
/// </summary>
let getSDKVersionFromGlobalJson () : string = getSDKVersionFromGlobalJsonDir "."
8 changes: 5 additions & 3 deletions src/app/Fake.Runtime/Fake.Runtime.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<DefineConstants>$(DefineConstants);CORE_CLR;DOTNETCORE;EXPLICIT_DEPENDENCIES;NETSTANDARD;FAKE_RUNTIME</DefineConstants>
<DefineConstants>$(DefineConstants);CORE_CLR;DOTNETCORE;EXPLICIT_DEPENDENCIES;NETSTANDARD;FAKE_RUNTIME;FAKE_INTERNAL_DOTNET_CORE_CLI</DefineConstants>
<AssemblyName>Fake.Runtime</AssemblyName>
<NoWarn>FS3186</NoWarn>
</PropertyGroup>
Expand All @@ -13,6 +13,8 @@
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Fake.DotNet.Cli\GlobalJson.fs" Link="GlobalJson.fs" />
<Compile Include="..\Fake.DotNet.Cli\DotNet.fs" Link="DotNet.fs" />
<Compile Include="YaafFSharpScripting.fs" />
<Compile Include="ThisAssemblyInfo.fs" />
<Compile Include="..\Fake.Core.Process\CmdLineParsing.fs" />
Expand All @@ -36,7 +38,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Fake.Core.Context\Fake.Core.Context.fsproj" />
<ProjectReference Include="..\Fake.DotNet.Cli\Fake.DotNet.Cli.fsproj" />
<ProjectReference Include="..\Fake.Core.Process\Fake.Core.Process.fsproj" />
<ProjectReference Include="..\Fake.IO.FileSystem\Fake.IO.FileSystem.fsproj" />
<ProjectReference Include="..\Fake.Core.DependencyManager.Paket\Fake.Core.DependencyManager.Paket.fsproj" />
</ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions src/app/Fake.Runtime/SdkAssemblyResolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type SdkAssemblyResolver(logLevel: Trace.VerboseLevel) =
member this.SdkVersion = this.SdkVersions |> Seq.head
member this.PaketFrameworkIdentifier = this.PaketFrameworkIdentifiers |> Seq.head

member this.SdkVersionFromGlobalJson = DotNet.tryGetSDKVersionFromGlobalJson ()
member this.SdkVersionFromGlobalJson = GlobalJson.tryGetSDKVersionFromGlobalJson ()

member this.IsSdkVersionFromGlobalJsonSameAsSdkVersion() =
match this.SdkVersionFromGlobalJson with
Expand Down Expand Up @@ -217,7 +217,7 @@ type SdkAssemblyResolver(logLevel: Trace.VerboseLevel) =
this.GetProductReleasesForSdk version |> List.tryHead

member this.ResolveSdkRuntimeVersions() =
let versionOptions (options: DotNet.VersionOptions) =
let versionOptions (options: InternalDotNet.VersionOptions) =
// If a custom CLI path is provided, configure the version command
// to use that path. This really only accomodates a test scenarios
// in which FAKE_SDK_RESOLVER_CUSTOM_DOTNET_PATH is set.
Expand All @@ -226,7 +226,7 @@ type SdkAssemblyResolver(logLevel: Trace.VerboseLevel) =
options.WithCommon(fun common -> { common with DotNetCliPath = root </> this.DotNetBinaryName })
| None -> options

let sdkVersion = DotNet.getVersion versionOptions |> ReleaseVersion
let sdkVersion = InternalDotNet.getVersion versionOptions |> ReleaseVersion

match this.GetProductReleasesForSdk sdkVersion with
| [] ->
Expand Down
Loading