From 5b4cdcbc5f1950b8334ed2220628d393391bd5b1 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Thu, 28 Nov 2019 23:51:06 +0100 Subject: [PATCH 1/8] paket local/global --- src/Paket/Program.fs | 52 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index 56d142682a..c32656284d 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -866,6 +866,28 @@ let handleCommand silent command = | Version | Log_File _ -> failwithf "internal error: this code should never be reached." +#if PAKET_GLOBAL_LOCAL + +let rec findRootInHierarchyFrom dir = + let dotPaketDir = + Path.Combine(dir.FullName, Constants.PaketFolderName) + |> DirectoryInfo + if dotPaketDir.Exists then + Some dotPaketDir + else + match dotPaketDir.Parent with + | null -> None + | parent -> findRootInHierarchyFrom parent + +let findRootInHierarchy () = + (Directory.GetCurrentDirectory() |> DirectoryInfo) + |> findRootInHierarchyHelper + +let runIt exeName exeArgs = + printfn "%s %A" exeName exeArgs + +#endif + let main() = let waitDebuggerEnvVar = Environment.GetEnvironmentVariable ("PAKET_WAIT_DEBUGGER") if waitDebuggerEnvVar = "1" then @@ -940,4 +962,32 @@ let main() = printErrorExt true true true exn else printError exn -main() + +[] +let theMain argv = + +#if PAKET_GLOBAL_LOCAL + + let isToolGlobal = true + let isToolLocal = not isToolGlobal + + let isToolLocal then + main () + else + let paketRoot = findRootInHierarchy () + match paketRoot with + | None -> + // act as global tool + mainGlobal () + | Some dir -> + let existsDotConfigAlonsideDotPaket = true + if existsDotConfigAlonsideDotPaket then + // paket as local tool => `dotnet paket` + runIt "dotnet" ("paket" :: argv) + else + // old paket => `.paket/paket` + runIt ".paket/paket" argv + +#else + main () +#endif From e5dce5707f4dd261b1b823fc2343cc14bd351045 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Sat, 30 Nov 2019 15:18:44 +0100 Subject: [PATCH 2/8] intellisense for .net core in ionide --- src/Paket/Paket.fsproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Paket/Paket.fsproj b/src/Paket/Paket.fsproj index 56ac8eb56a..dc4eb4d13e 100644 --- a/src/Paket/Paket.fsproj +++ b/src/Paket/Paket.fsproj @@ -1,7 +1,7 @@  Exe - net461;netcoreapp2.1 + netcoreapp2.1;net461 false Paket paket From 46d11da746f74e20a707b4755ef726d225fba86d Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Sat, 30 Nov 2019 15:20:00 +0100 Subject: [PATCH 3/8] return exit code --- src/Paket/Program.fs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index c32656284d..9eea1221d7 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -37,10 +37,11 @@ let processWithValidationEx printUsage silent validateF commandF result = traceError (" " + String.Join(" ",Environment.GetCommandLineArgs())) printUsage result - Environment.ExitCode <- 1 + 1 else try commandF result + 0 finally sw.Stop() if not silent then @@ -954,13 +955,15 @@ let main() = | None -> null handleCommand silent (results.GetSubCommand()) + else + 0 with | exn when not (exn :? System.NullReferenceException) -> - Environment.ExitCode <- 1 traceErrorfn "Paket failed with" if Environment.GetEnvironmentVariable "PAKET_DETAILED_ERRORS" = "true" then printErrorExt true true true exn else printError exn + 1 [] From a5798cc22fa2cce0525e0981eb600af1dd889c97 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Sat, 30 Nov 2019 15:20:14 +0100 Subject: [PATCH 4/8] wip --- src/Paket/Paket.fsproj | 3 +++ src/Paket/Program.fs | 25 +++++++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/Paket/Paket.fsproj b/src/Paket/Paket.fsproj index dc4eb4d13e..896907909e 100644 --- a/src/Paket/Paket.fsproj +++ b/src/Paket/Paket.fsproj @@ -11,6 +11,9 @@ https://raw.githubusercontent.com/fsprojects/Paket/master/docs/files/img/logo.png nuget;bundler;F# + + PAKET_GLOBAL_LOCAL;$(DefineConstants) + diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index 9eea1221d7..d6d239a265 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -869,12 +869,12 @@ let handleCommand silent command = #if PAKET_GLOBAL_LOCAL -let rec findRootInHierarchyFrom dir = +let rec findRootInHierarchyFrom (dir: DirectoryInfo) = let dotPaketDir = Path.Combine(dir.FullName, Constants.PaketFolderName) |> DirectoryInfo if dotPaketDir.Exists then - Some dotPaketDir + Some dir else match dotPaketDir.Parent with | null -> None @@ -882,10 +882,18 @@ let rec findRootInHierarchyFrom dir = let findRootInHierarchy () = (Directory.GetCurrentDirectory() |> DirectoryInfo) - |> findRootInHierarchyHelper + |> findRootInHierarchyFrom let runIt exeName exeArgs = printfn "%s %A" exeName exeArgs + 0 + +let mainGlobal () = + 0 + +let dotnetToolManifestPath (dir: DirectoryInfo) = + Path.Combine(dir.FullName, ".config", "dotnet-tools.json") + |> FileInfo #endif @@ -974,7 +982,7 @@ let theMain argv = let isToolGlobal = true let isToolLocal = not isToolGlobal - let isToolLocal then + if isToolLocal then main () else let paketRoot = findRootInHierarchy () @@ -983,13 +991,14 @@ let theMain argv = // act as global tool mainGlobal () | Some dir -> - let existsDotConfigAlonsideDotPaket = true - if existsDotConfigAlonsideDotPaket then + let manifestToolPath = dotnetToolManifestPath dir + printfn "%O" manifestToolPath + if manifestToolPath.Exists then // paket as local tool => `dotnet paket` - runIt "dotnet" ("paket" :: argv) + runIt "dotnet" [| yield "paket"; yield! argv |] else // old paket => `.paket/paket` - runIt ".paket/paket" argv + runIt (Path.Combine(Constants.PaketFolderName, Constants.PaketFileName)) argv #else main () From 1a2122bbe35ed1a54d6d74b1090807821f2822f1 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Sat, 30 Nov 2019 16:14:30 +0100 Subject: [PATCH 5/8] is global tool if assembly path contains ".store". --- src/Paket/Program.fs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index d6d239a265..c6be8cde7b 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -895,6 +895,26 @@ let dotnetToolManifestPath (dir: DirectoryInfo) = Path.Combine(dir.FullName, ".config", "dotnet-tools.json") |> FileInfo +open System.Reflection + +let isToolLocal () = + let x = typeof.Assembly.Location + printfn "%s" x + + // local + // C:\Users\e0s01ao\.nuget\packages\paket\5.239.0-beta-0001\tools\netcoreapp2.1\any\paket.dll + + // global + // C:\Users\e0s01ao\.dotnet\tools\.store\paket\5.239.0-beta-0001\paket\5.239.0-beta-0001\tools\netcoreapp2.1\any\paket.dll + + let isToolGlobal = x.Contains(".store") + + printfn "tg %O" isToolGlobal + + let isToolLocal = not isToolGlobal + + isToolLocal + #endif let main() = @@ -976,19 +996,22 @@ let main() = [] let theMain argv = + printfn "real main" #if PAKET_GLOBAL_LOCAL + let isToolLocal = isToolLocal () - let isToolGlobal = true - let isToolLocal = not isToolGlobal + printfn "local: %O" isToolLocal if isToolLocal then + printfn "localtool: run main" main () else let paketRoot = findRootInHierarchy () match paketRoot with | None -> // act as global tool + printfn "globaltool: run mainglobal" mainGlobal () | Some dir -> let manifestToolPath = dotnetToolManifestPath dir @@ -1001,5 +1024,7 @@ let theMain argv = runIt (Path.Combine(Constants.PaketFolderName, Constants.PaketFileName)) argv #else + printfn "main not g" + main () #endif From 1507707a284b3f3c700ec21db72618f6b9057bd2 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Sat, 30 Nov 2019 17:20:16 +0100 Subject: [PATCH 6/8] run process, fix stackoverflow --- .../WindowsProcessArguments.cs | 2 +- .../Paket.CmdLineHelpers.csproj | 11 +++++++ src/Paket.CmdLineHelpers/paket.references | 0 src/Paket/Paket.fsproj | 1 + src/Paket/Program.fs | 31 +++++++++++++------ 5 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 src/Paket.CmdLineHelpers/Paket.CmdLineHelpers.csproj create mode 100644 src/Paket.CmdLineHelpers/paket.references diff --git a/src/Paket.Bootstrapper/WindowsProcessArguments.cs b/src/Paket.Bootstrapper/WindowsProcessArguments.cs index e1b9df7e51..3912aea55e 100644 --- a/src/Paket.Bootstrapper/WindowsProcessArguments.cs +++ b/src/Paket.Bootstrapper/WindowsProcessArguments.cs @@ -3,7 +3,7 @@ namespace Paket.Bootstrapper { - static class WindowsProcessArguments + public static class WindowsProcessArguments { static void AddBackslashes(StringBuilder builder, int backslashes, bool beforeQuote) { diff --git a/src/Paket.CmdLineHelpers/Paket.CmdLineHelpers.csproj b/src/Paket.CmdLineHelpers/Paket.CmdLineHelpers.csproj new file mode 100644 index 0000000000..84184ed101 --- /dev/null +++ b/src/Paket.CmdLineHelpers/Paket.CmdLineHelpers.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp2.1 + + + + + + + diff --git a/src/Paket.CmdLineHelpers/paket.references b/src/Paket.CmdLineHelpers/paket.references new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Paket/Paket.fsproj b/src/Paket/Paket.fsproj index 896907909e..a8abd1d1d9 100644 --- a/src/Paket/Paket.fsproj +++ b/src/Paket/Paket.fsproj @@ -36,6 +36,7 @@ + \ No newline at end of file diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index c6be8cde7b..ac738e846e 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -870,23 +870,36 @@ let handleCommand silent command = #if PAKET_GLOBAL_LOCAL let rec findRootInHierarchyFrom (dir: DirectoryInfo) = - let dotPaketDir = - Path.Combine(dir.FullName, Constants.PaketFolderName) - |> DirectoryInfo - if dotPaketDir.Exists then - Some dir + printfn "searching in %s" dir.FullName + if not (dir.Exists) then + None else - match dotPaketDir.Parent with - | null -> None - | parent -> findRootInHierarchyFrom parent + let dotPaketDir = + Path.Combine(dir.FullName, Constants.PaketFolderName) + |> DirectoryInfo + if dotPaketDir.Exists then + Some dir + else + printfn "parent %O" dotPaketDir.Parent + match dir.Parent with + | null -> None + | root -> findRootInHierarchyFrom root let findRootInHierarchy () = (Directory.GetCurrentDirectory() |> DirectoryInfo) |> findRootInHierarchyFrom +open System.Text + let runIt exeName exeArgs = printfn "%s %A" exeName exeArgs - 0 + + use p = new Process() + let argString : string = Paket.Bootstrapper.WindowsProcessArguments.ToString(exeArgs) + p.StartInfo <- ProcessStartInfo(FileName = exeName, Arguments = argString, UseShellExecute = false) + p.Start() |> ignore + p.WaitForExit() + p.ExitCode let mainGlobal () = 0 From ea16667fc912c80373d4b0429fa3aa9723e93e02 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Sat, 30 Nov 2019 17:41:45 +0100 Subject: [PATCH 7/8] revert before commit, dev stuff `dotnet msbuild /t:Install /v:n` to pack, and reinstall the built version (global and local) --- src/Paket/Paket.fsproj | 29 +++++++++++++++++++++++++++-- src/Paket/Program.fs | 11 +++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/Paket/Paket.fsproj b/src/Paket/Paket.fsproj index a8abd1d1d9..88d0d0dcaf 100644 --- a/src/Paket/Paket.fsproj +++ b/src/Paket/Paket.fsproj @@ -2,6 +2,7 @@ Exe netcoreapp2.1;net461 + 5.239.0-beta-0001 false Paket paket @@ -18,6 +19,7 @@ netcoreapp2.1 + PAKET_GLOBAL_LOCAL;$(DefineConstants) @@ -28,15 +30,38 @@ - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index ac738e846e..3d9819d274 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -869,6 +869,15 @@ let handleCommand silent command = #if PAKET_GLOBAL_LOCAL +(* +#load @"..\Paket.Core\Common\Domain.fs" +#load @"..\Paket.Core\Common\Logging.fs" +#load @"..\Paket.Core\Common\Constants.fs" +open System +open System.IO +open Paket +*) + let rec findRootInHierarchyFrom (dir: DirectoryInfo) = printfn "searching in %s" dir.FullName if not (dir.Exists) then @@ -889,8 +898,6 @@ let findRootInHierarchy () = (Directory.GetCurrentDirectory() |> DirectoryInfo) |> findRootInHierarchyFrom -open System.Text - let runIt exeName exeArgs = printfn "%s %A" exeName exeArgs From 81b702f344815933a7693d07ade453262d03ddf2 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Sat, 30 Nov 2019 18:28:19 +0100 Subject: [PATCH 8/8] wip --- src/Paket/Program.fs | 110 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 23 deletions(-) diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index 3d9819d274..fcb0ef69e1 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -879,7 +879,6 @@ open Paket *) let rec findRootInHierarchyFrom (dir: DirectoryInfo) = - printfn "searching in %s" dir.FullName if not (dir.Exists) then None else @@ -889,7 +888,6 @@ let rec findRootInHierarchyFrom (dir: DirectoryInfo) = if dotPaketDir.Exists then Some dir else - printfn "parent %O" dotPaketDir.Parent match dir.Parent with | null -> None | root -> findRootInHierarchyFrom root @@ -899,17 +897,40 @@ let findRootInHierarchy () = |> findRootInHierarchyFrom let runIt exeName exeArgs = - printfn "%s %A" exeName exeArgs - use p = new Process() - let argString : string = Paket.Bootstrapper.WindowsProcessArguments.ToString(exeArgs) - p.StartInfo <- ProcessStartInfo(FileName = exeName, Arguments = argString, UseShellExecute = false) + + // let argString : string = Paket.Bootstrapper.WindowsProcessArguments.ToString(exeArgs) + // let psi = ProcessStartInfo(FileName = exeName, Arguments = argString, UseShellExecute = false) + // printfn "Running: %s %A" exeName (psi.Arguments) + + let psi = ProcessStartInfo(FileName = exeName, Arguments = "", UseShellExecute = false) + for arg in exeArgs do + psi.ArgumentList.Add(arg) + printfn "Running: %s %A" exeName (psi.ArgumentList |> Seq.toList) + + p.StartInfo <- psi + p.Start() |> ignore p.WaitForExit() p.ExitCode -let mainGlobal () = - 0 + +[] +type GlobalCommand = + // global options + | [] Silent + | [] Verbose + // subcommands + | [] Init of ParseResults +with + interface IArgParserTemplate with + member this.Usage = + match this with + | Init _ -> "create an empty paket.dependencies file in the current working directory" + | Silent -> "suppress console output" + | Verbose -> "print detailed information to the console" + +let globalCommandParser = ArgumentParser.Create(programName = "paket", errorHandler = new ProcessExiter(), checkStructure = false) let dotnetToolManifestPath (dir: DirectoryInfo) = Path.Combine(dir.FullName, ".config", "dotnet-tools.json") @@ -919,17 +940,17 @@ open System.Reflection let isToolLocal () = let x = typeof.Assembly.Location - printfn "%s" x + // printfn "%s" x - // local + // local is like // C:\Users\e0s01ao\.nuget\packages\paket\5.239.0-beta-0001\tools\netcoreapp2.1\any\paket.dll - // global + // global is like // C:\Users\e0s01ao\.dotnet\tools\.store\paket\5.239.0-beta-0001\paket\5.239.0-beta-0001\tools\netcoreapp2.1\any\paket.dll let isToolGlobal = x.Contains(".store") - printfn "tg %O" isToolGlobal + // printfn "tg %O" isToolGlobal let isToolLocal = not isToolGlobal @@ -1013,38 +1034,81 @@ let main() = else printError exn 1 +#if PAKET_GLOBAL_LOCAL + +let handleGlobalCommand silent command = + match command with + | GlobalCommand.Init r -> processCommand silent (init) r + // global options; list here in order to maintain compiler warnings + // in case of new subcommands added + | GlobalCommand.Verbose + | GlobalCommand.Silent -> failwithf "internal error: this code should never be reached." + +let mainGlobal () = + let waitDebuggerEnvVar = Environment.GetEnvironmentVariable ("PAKET_WAIT_DEBUGGER") + if waitDebuggerEnvVar = "1" then + waitForDebugger() + + Logging.verboseWarnings <- Environment.GetEnvironmentVariable "PAKET_DETAILED_WARNINGS" = "true" + use consoleTrace = Logging.event.Publish |> Observable.subscribe Logging.traceToConsole + + // TODO ^--- no need to duplicate these, move in entrypoint + + try + let parser = ArgumentParser.Create(programName = "paket", + helpTextMessage = sprintf "Paket version %s%sHelp was requested:" paketVersion Environment.NewLine, + errorHandler = new PaketExiter(), + checkStructure = false) + + let results = parser.ParseCommandLine(raiseOnUsage = true) + let silent = results.Contains <@ GlobalCommand.Silent @> + tracePaketVersion silent + + if results.Contains <@ GlobalCommand.Verbose @> then + Logging.verbose <- true + Logging.verboseWarnings <- true + + handleGlobalCommand silent (results.GetSubCommand()) + + //TODO v---- no need to duplicate, move in entrypoint? or not + with + | exn when not (exn :? System.NullReferenceException) -> + traceErrorfn "Paket failed with" + if Environment.GetEnvironmentVariable "PAKET_DETAILED_ERRORS" = "true" then + printErrorExt true true true exn + else printError exn + 1 + +#endif [] let theMain argv = - printfn "real main" - #if PAKET_GLOBAL_LOCAL let isToolLocal = isToolLocal () - printfn "local: %O" isToolLocal - if isToolLocal then - printfn "localtool: run main" main () else let paketRoot = findRootInHierarchy () match paketRoot with | None -> - // act as global tool - printfn "globaltool: run mainglobal" + // act as global tool (subset of commands) mainGlobal () | Some dir -> let manifestToolPath = dotnetToolManifestPath dir - printfn "%O" manifestToolPath if manifestToolPath.Exists then // paket as local tool => `dotnet paket` + + //TODO check if paket is installed in manifest! otherwise tell to user! + runIt "dotnet" [| yield "paket"; yield! argv |] else // old paket => `.paket/paket` - runIt (Path.Combine(Constants.PaketFolderName, Constants.PaketFileName)) argv + let paketExePath = + Path.Combine(dir.FullName, Constants.PaketFolderName, Constants.PaketFileName) + |> Path.GetFullPath + runIt paketExePath argv #else - printfn "main not g" - main () #endif