From 144a23bb9682c452b1904cb387d9fe40fc725ad6 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Wed, 25 Oct 2017 11:29:53 +0200 Subject: [PATCH] support old fsproj (#9) add more cli options: `--msbuild` => path to msbuild `--dotnetcli` => path to dotnet, used for "dotnet msbuild" `--msbuild-host` => what msbuild host to run, to force specific or auto (oldsdk/dotnetsdk). By default for oldsdk is `msbuild` and dotnetsdk is `dotnet` ### Old fsproj parser Use `msbuild` from command line to ask msbuild info about the project (not using msbuild as library) How works: - override the `CoreCompile` target, to gather info about the project properties (OutputType, etc) - convert the msbuild properties to fsc args, using the Fsc task code To override the `CoreCompile` target, the `CustomAfterMicrosoftCommonTargets` property is used as hook to import the generate .target file after F# targets are imported (msbuild override targets with same name, based on import sequence) To convert msbuild properties to fsc compiler args, use the same Fsc msbuild task class code. - `Fsc` msbuild task from microsoft/visualfsharp repo - msbuild classes from mono/mono repo The strategy for `msbuild properties -> fsc args` can be customized Additional: - move repo to .net core 2.0 - `dotnet-proj-info` support `netcoreapp2.0` framework - `Dotnet.ProjInfo` support `netstandard2.0` framework - the `Fsc` task is not bundled with `Dotnet.ProjInfo`, so clients can pin another version if needed --- .gitignore | 2 + .paket/paket.bootstrapper.exe | Bin 0 -> 39936 bytes .travis.yml | 20 +++ README.md | 22 ++- appveyor.yml | 20 +++ build.cmd | 13 -- build.proj | 26 +++ examples/.vscode/launch.json | 52 ------ examples/.vscode/tasks.json | 17 -- examples/NuGet.Config | 1 - examples/README.md | 25 +-- examples/{ => sdk1}/c1/Program.fs | 0 examples/{ => sdk1}/c1/c1.fsproj | 0 examples/{ => sdk1}/l1/Library.fs | 0 examples/{ => sdk1}/l1/l1.fsproj | 0 examples/{ => sdk1}/l2/Library.fs | 0 examples/{ => sdk1}/l2/l2.fsproj | 0 examples/tools/tools.proj | 4 + paket.dependencies | 12 ++ paket.lock | 12 ++ ...ckagesInfo.props => Directory.Build.props} | 6 +- .../Dotnet.ProjInfo.Helpers.csproj | 16 ++ src/Dotnet.ProjInfo/Dotnet.ProjInfo.fsproj | 30 +++- .../ExternalFSharp/FscConfig.fs | 153 ++++++++++++++++++ .../ExternalFSharp/MissingApi.fs | 57 +++++++ src/dotnet-proj-info.sln | 69 ++++++++ src/dotnet-proj-info/.vscode/tasks.json | 17 -- src/dotnet-proj-info/Inspect.fs | 130 +++++++++++++-- src/dotnet-proj-info/Program.fs | 115 +++++++++++-- src/dotnet-proj-info/dotnet-proj-info.fsproj | 12 +- test/Directory.Build.props | 4 + test/oldsdk/l1/AssemblyInfo.fs | 41 +++++ test/oldsdk/l1/Library.fs | 22 +++ test/oldsdk/l1/Script.fsx | 8 + test/oldsdk/l1/l1.fsproj | 82 ++++++++++ test/oldsdk/l1/packages.config | 5 + test/{ => sdk1}/app c1/Program.fs | 0 test/{ => sdk1}/app c1/app c1.fsproj | 0 test/tests.proj | 32 ++++ 39 files changed, 876 insertions(+), 149 deletions(-) create mode 100644 .paket/paket.bootstrapper.exe create mode 100644 .travis.yml create mode 100644 appveyor.yml delete mode 100644 build.cmd create mode 100644 build.proj delete mode 100644 examples/.vscode/launch.json delete mode 100644 examples/.vscode/tasks.json rename examples/{ => sdk1}/c1/Program.fs (100%) rename examples/{ => sdk1}/c1/c1.fsproj (100%) rename examples/{ => sdk1}/l1/Library.fs (100%) rename examples/{ => sdk1}/l1/l1.fsproj (100%) rename examples/{ => sdk1}/l2/Library.fs (100%) rename examples/{ => sdk1}/l2/l2.fsproj (100%) create mode 100644 paket.dependencies create mode 100644 paket.lock rename src/{PackagesInfo.props => Directory.Build.props} (60%) create mode 100644 src/Dotnet.ProjInfo.Helpers/Dotnet.ProjInfo.Helpers.csproj create mode 100644 src/Dotnet.ProjInfo/ExternalFSharp/FscConfig.fs create mode 100644 src/Dotnet.ProjInfo/ExternalFSharp/MissingApi.fs create mode 100644 src/dotnet-proj-info.sln delete mode 100644 src/dotnet-proj-info/.vscode/tasks.json create mode 100644 test/Directory.Build.props create mode 100644 test/oldsdk/l1/AssemblyInfo.fs create mode 100644 test/oldsdk/l1/Library.fs create mode 100644 test/oldsdk/l1/Script.fsx create mode 100644 test/oldsdk/l1/l1.fsproj create mode 100644 test/oldsdk/l1/packages.config rename test/{ => sdk1}/app c1/Program.fs (100%) rename test/{ => sdk1}/app c1/app c1.fsproj (100%) create mode 100644 test/tests.proj diff --git a/.gitignore b/.gitignore index ffe604f8..74172bfb 100644 --- a/.gitignore +++ b/.gitignore @@ -238,3 +238,5 @@ _Pvt_Extensions # Repo-specific files .dotnetsdk +/.paket/ +/paket-files/ diff --git a/.paket/paket.bootstrapper.exe b/.paket/paket.bootstrapper.exe new file mode 100644 index 0000000000000000000000000000000000000000..48af410620b51cd5a196929001a7edc0806e5681 GIT binary patch literal 39936 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 literal 0 HcmV?d00001 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..942ee772 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +language: csharp + +mono: 5.2.0 +dotnet: 2.0.0 + +install: + # workaround for missing .net 4.5 targing pack + - export FrameworkPathOverride=$(dirname $(which mono))/../lib/mono/4.5/ + +script: + - dotnet pack -v n + - dotnet test -v n + +matrix: + include: + - os: linux + dist: trusty + sudo: required + - os: osx + osx_image: xcode9 diff --git a/README.md b/README.md index 3c7516dc..d154ee7b 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,25 @@ see `examples` directory ## Build -to create packages: +Run: +```bash +dotnet build ``` -set VERSION=1.2.3 -build.cmd + +To run tests: + +```bash +dotnet test -v n ``` -will create packages with version `1.2.3` in `artifacts\nupkgs` +To create packages: + +```bash +dotnet pack +``` + +will create packages in `artifacts\nupkgs` + +pass `/p:Version=1.2.3` to create a package with version `1.2.3` + diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..5ff8861b --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,20 @@ +image: + - Visual Studio 2017 + +before_build: + - ps: >- + $buildId = $env:APPVEYOR_BUILD_NUMBER.PadLeft(5, '0'); + $versionSuffixPR = "-PR$($env:APPVEYOR_PULL_REQUEST_NUMBER)-$buildId"; + $branchName = "$env:APPVEYOR_REPO_BRANCH".Replace("_",""); + $versionSuffixBRANCH = "-$branchName-$buildId"; + $env:VersionSuffix = if ("$env:APPVEYOR_REPO_TAG" -eq "true") { "" } else { if ("$env:APPVEYOR_PULL_REQUEST_NUMBER") { $versionSuffixPR } else { $versionSuffixBRANCH } }; + +build_script: + - cmd: echo vs %VersionSuffix%" + - cmd: dotnet pack -v n + - cmd: dotnet test -v n + +artifacts: + - path: bin\nupkg\*.nupkg + name: nupkgs + type: NuGetPackage diff --git a/build.cmd b/build.cmd deleted file mode 100644 index 98764077..00000000 --- a/build.cmd +++ /dev/null @@ -1,13 +0,0 @@ -set Configuration=Release -set "PackageOutputPath=%~dp0\artifacts\nupkgs" - -dotnet restore "%~dp0\src\dotnet-proj-info\dotnet-proj-info.fsproj" -@if ERRORLEVEL 1 exit /b 1 - -dotnet pack "%~dp0\src\Dotnet.ProjInfo\Dotnet.ProjInfo.fsproj" -@if ERRORLEVEL 1 exit /b 1 - -dotnet pack "%~dp0\src\dotnet-proj-info\dotnet-proj-info.fsproj" -@if ERRORLEVEL 1 exit /b 1 - -exit /b 0 diff --git a/build.proj b/build.proj new file mode 100644 index 00000000..28d8d0bb --- /dev/null +++ b/build.proj @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/.vscode/launch.json b/examples/.vscode/launch.json deleted file mode 100644 index e00a0914..00000000 --- a/examples/.vscode/launch.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": ".NET Core Launch (console)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceRoot}/c1/bin/Debug/netcoreapp1.0/c1.dll", - "args": [], - "cwd": "${workspaceRoot}", - "stopAtEntry": false, - "externalConsole": false - }, - { - "name": ".NET Core Launch (web)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceRoot}/bin/Debug//", - "args": [], - "cwd": "${workspaceRoot}", - "stopAtEntry": false, - "launchBrowser": { - "enabled": true, - "args": "${auto-detect-url}", - "windows": { - "command": "cmd.exe", - "args": "/C start ${auto-detect-url}" - }, - "osx": { - "command": "open" - }, - "linux": { - "command": "xdg-open" - } - }, - "env": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "sourceFileMap": { - "/Views": "${workspaceRoot}/Views" - } - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach", - "processId": "${command.pickProcess}" - } - ] -} \ No newline at end of file diff --git a/examples/.vscode/tasks.json b/examples/.vscode/tasks.json deleted file mode 100644 index 15593ebf..00000000 --- a/examples/.vscode/tasks.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "0.1.0", - "command": "dotnet", - "isShellCommand": true, - "args": [], - "tasks": [ - { - "taskName": "build", - "args": [ "c1" ], - "isBuildCommand": true, - "showOutput": "silent", - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/examples/NuGet.Config b/examples/NuGet.Config index 745a9280..8a81e580 100644 --- a/examples/NuGet.Config +++ b/examples/NuGet.Config @@ -3,7 +3,6 @@ - diff --git a/examples/README.md b/examples/README.md index d7bf0745..24250b85 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,41 +2,42 @@ First restore the sample the packages and the tool -``` +```bash dotnet restore tools -dotnet restore c1 +dotnet restore sdk1/c1 ``` **NOTE** Because is a dotnet cli command, must be executed from same directory of project where is declared. The project can be passed, if not it search the working directory for a project (single .*proj) -``` +```bash cd tools ``` -and -``` -dotnet proj-info ..\c1\c1.fsproj --project-refs +Some examples of commands: + +```bash +dotnet proj-info ../sdk1/c1/c1.fsproj --project-refs ``` or -``` -dotnet proj-info ..\c1\c1.fsproj --fsc-args +```bash +dotnet proj-info ../sdk1/c1/c1.fsproj --fsc-args ``` or -``` -dotnet proj-info ..\c1\c1.fsproj --get-property OutputType Version Configuration +```bash +dotnet proj-info ../sdk1/c1/c1.fsproj --get-property OutputType Version Configuration ``` It's possibile to pass usual .NET Core Tools arguments (like `-c`, `-f`, `-r`). See `--help` for more info -``` -dotnet proj-info ..\l1\l1.fsproj --gp MyCustomProp OutputType Version Configuration -c Release +```bash +dotnet proj-info ../sdk1/l1/l1.fsproj --gp MyCustomProp OutputType Version Configuration -c Release ``` diff --git a/examples/c1/Program.fs b/examples/sdk1/c1/Program.fs similarity index 100% rename from examples/c1/Program.fs rename to examples/sdk1/c1/Program.fs diff --git a/examples/c1/c1.fsproj b/examples/sdk1/c1/c1.fsproj similarity index 100% rename from examples/c1/c1.fsproj rename to examples/sdk1/c1/c1.fsproj diff --git a/examples/l1/Library.fs b/examples/sdk1/l1/Library.fs similarity index 100% rename from examples/l1/Library.fs rename to examples/sdk1/l1/Library.fs diff --git a/examples/l1/l1.fsproj b/examples/sdk1/l1/l1.fsproj similarity index 100% rename from examples/l1/l1.fsproj rename to examples/sdk1/l1/l1.fsproj diff --git a/examples/l2/Library.fs b/examples/sdk1/l2/Library.fs similarity index 100% rename from examples/l2/Library.fs rename to examples/sdk1/l2/Library.fs diff --git a/examples/l2/l2.fsproj b/examples/sdk1/l2/l2.fsproj similarity index 100% rename from examples/l2/l2.fsproj rename to examples/sdk1/l2/l2.fsproj diff --git a/examples/tools/tools.proj b/examples/tools/tools.proj index 89790f87..f6321819 100644 --- a/examples/tools/tools.proj +++ b/examples/tools/tools.proj @@ -1,5 +1,9 @@  + + netstandard2.0 + + diff --git a/paket.dependencies b/paket.dependencies new file mode 100644 index 00000000..281f0836 --- /dev/null +++ b/paket.dependencies @@ -0,0 +1,12 @@ + +// the Fsc build task +github Microsoft/visualfsharp:Visual-Studio-2017-Version-15.4 src/fsharp/FSharp.Build/Fsc.fs +github Microsoft/visualfsharp:Visual-Studio-2017-Version-15.4 src/fsharp/FSharp.Build/Microsoft.FSharp.Targets + +// msbuild classes from Mono +github mono/mono:mono-5.2.0.224 mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/CommandLineBuilder.cs +github mono/mono:mono-5.2.0.224 mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskItem.cs +github mono/mono:mono-5.2.0.224 mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskItem2.cs +github mono/mono:mono-5.2.0.224 mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/MSBuildUtils.cs +github mono/mono:mono-5.2.0.224 mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs +github mono/mono:mono-5.2.0.224 mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TaskItem.cs diff --git a/paket.lock b/paket.lock new file mode 100644 index 00000000..01993822 --- /dev/null +++ b/paket.lock @@ -0,0 +1,12 @@ + +GITHUB + remote: Microsoft/visualfsharp + src/fsharp/FSharp.Build/Fsc.fs (cc1b137bc17f401a0cc669ff8fc598714d0fe652) + src/fsharp/FSharp.Build/Microsoft.FSharp.Targets (cc1b137bc17f401a0cc669ff8fc598714d0fe652) + remote: mono/mono + mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskItem.cs (14f2c814ccc4b98f11dae3074ba6a081956e9079) + mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskItem2.cs (14f2c814ccc4b98f11dae3074ba6a081956e9079) + mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/CommandLineBuilder.cs (14f2c814ccc4b98f11dae3074ba6a081956e9079) + mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TaskItem.cs (14f2c814ccc4b98f11dae3074ba6a081956e9079) + mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/MSBuildUtils.cs (14f2c814ccc4b98f11dae3074ba6a081956e9079) + mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs (14f2c814ccc4b98f11dae3074ba6a081956e9079) \ No newline at end of file diff --git a/src/PackagesInfo.props b/src/Directory.Build.props similarity index 60% rename from src/PackagesInfo.props rename to src/Directory.Build.props index cc046d6e..0eb39405 100644 --- a/src/PackagesInfo.props +++ b/src/Directory.Build.props @@ -1,10 +1,14 @@ - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) Enrico Sada https://github.com/enricosada/dotnet-proj-info/ mbuild;dotnet;sdk;csproj;fsproj https://github.com/enricosada/dotnet-proj-info.git + + $([System.IO.Path]::GetFullPath("$(MSBuildThisFileDirectory)\..")) + $(RepoRootDir)/bin/nupkg + 0.8.0$(VersionSuffix) + mono diff --git a/src/Dotnet.ProjInfo.Helpers/Dotnet.ProjInfo.Helpers.csproj b/src/Dotnet.ProjInfo.Helpers/Dotnet.ProjInfo.Helpers.csproj new file mode 100644 index 00000000..540cfbd3 --- /dev/null +++ b/src/Dotnet.ProjInfo.Helpers/Dotnet.ProjInfo.Helpers.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.0;net45 + + + + + + + + + + + + diff --git a/src/Dotnet.ProjInfo/Dotnet.ProjInfo.fsproj b/src/Dotnet.ProjInfo/Dotnet.ProjInfo.fsproj index 77e30e06..0f8f7ed9 100644 --- a/src/Dotnet.ProjInfo/Dotnet.ProjInfo.fsproj +++ b/src/Dotnet.ProjInfo/Dotnet.ProjInfo.fsproj @@ -1,10 +1,20 @@ - + - netstandard1.6;net45 + netstandard2.0;netstandard1.6;net45 Get msbuild info + + + + + + + + + + @@ -12,9 +22,21 @@ - - + + + true + + + + + $(TargetsForTfmSpecificBuildOutput);IncludeP2POutput + + + + + + diff --git a/src/Dotnet.ProjInfo/ExternalFSharp/FscConfig.fs b/src/Dotnet.ProjInfo/ExternalFSharp/FscConfig.fs new file mode 100644 index 00000000..168221cc --- /dev/null +++ b/src/Dotnet.ProjInfo/ExternalFSharp/FscConfig.fs @@ -0,0 +1,153 @@ +module Dotnet.ProjInfo.FakeMsbuildTasks + +open System + +// SRTP: how to set a property: +// +// let inline setReferences (e: ^a) x = +// (^a: (member set_References: Microsoft.Build.Framework.ITaskItem array -> unit) (e, x)) +// + +type ITaskItemArray = Microsoft.Build.Framework.ITaskItem array + +let inline getResponseFileFromTask props (fsc: ^a) = + + let m : Map = props |> Map.ofList + let prop k = + match m |> Map.tryFind k with + | Some x -> + if String.IsNullOrWhiteSpace(x) then + None + else + Some x + | None -> failwithf "not found k=%s in '%0A" k m + + let bind f p = + p |> prop |> Option.iter f + let bindBool f p = + let propBool k = + let s = (prop k) + try + s + |> Option.map (bool.Parse) + with x -> + failwithf "invalid k=%s s=%A" k s + p |> propBool |> Option.iter f + let bindArray f p = + let propArray k = + let x = prop k + let f (s: string) = s.Split([| ';' |], StringSplitOptions.RemoveEmptyEntries) + x |> Option.map f + match p |> propArray with + | None -> () + | Some l -> + l + |> Array.map Microsoft.Build.Utilities.TaskItem + |> Array.map (fun x -> x :> Microsoft.Build.Framework.ITaskItem) + |> f + + "BaseAddress"|> bind (fun prop -> (^a: (member set_BaseAddress: string -> unit) (fsc, prop))) + "CodePage" |> bind (fun prop -> (^a: (member set_CodePage: string -> unit) (fsc, prop))) + "DebugSymbols" |> bindBool (fun prop -> (^a: (member set_DebugSymbols: bool -> unit) (fsc, prop))) + "DebugType" |> bind (fun prop -> (^a: (member set_DebugType: string -> unit) (fsc, prop))) + "DefineConstants" |> bindArray (fun prop -> (^a: (member set_DefineConstants: ITaskItemArray -> unit) (fsc, prop))) + "DelaySign" |> bindBool (fun prop -> (^a: (member set_DelaySign: bool -> unit) (fsc, prop))) + "DisabledWarnings" |> bind (fun prop -> (^a: (member set_DisabledWarnings: string -> unit) (fsc, prop))) + "DocumentationFile" |> bind (fun prop -> (^a: (member set_DocumentationFile: string -> unit) (fsc, prop))) + "DotnetFscCompilerPath" |> bind (fun prop -> (^a: (member set_DotnetFscCompilerPath: string -> unit) (fsc, prop))) + "EmbedAllSources" |> bindBool (fun prop -> (^a: (member set_EmbedAllSources: bool -> unit) (fsc, prop))) + "Embed" |> bind (fun prop -> (^a: (member set_Embed: string -> unit) (fsc, prop))) + "GenerateInterfaceFile" |> bind (fun prop -> (^a: (member set_GenerateInterfaceFile: string -> unit) (fsc, prop))) + "HighEntropyVA" |> bindBool (fun prop -> (^a: (member set_HighEntropyVA: bool -> unit) (fsc, prop))) + "KeyFile" |> bind (fun prop -> (^a: (member set_KeyFile: string -> unit) (fsc, prop))) + "LCID" |> bind (fun prop -> (^a: (member set_LCID: string -> unit) (fsc, prop))) + "NoFramework" |> bindBool (fun prop -> (^a: (member set_NoFramework: bool -> unit) (fsc, prop))) + "Optimize" |> bindBool (fun prop -> (^a: (member set_Optimize: bool -> unit) (fsc, prop))) + "OtherFlags" |> bind (fun prop -> (^a: (member set_OtherFlags: string -> unit) (fsc, prop))) + "OutputAssembly" |> bind (fun prop -> (^a: (member set_OutputAssembly: string -> unit) (fsc, prop))) + "PdbFile" |> bind (fun prop -> (^a: (member set_PdbFile: string -> unit) (fsc, prop))) + "Platform" |> bind (fun prop -> (^a: (member set_Platform: string -> unit) (fsc, prop))) + "Prefer32Bit" |>bindBool (fun prop -> (^a: (member set_Prefer32Bit: bool -> unit) (fsc, prop))) + "PreferredUILang" |> bind (fun prop -> (^a: (member set_PreferredUILang: string -> unit) (fsc, prop))) + "ProvideCommandLineArgs" |> bindBool (fun prop -> (^a: (member set_ProvideCommandLineArgs: bool -> unit) (fsc, prop))) + "PublicSign" |> bindBool (fun prop -> (^a: (member set_PublicSign: bool -> unit) (fsc, prop))) + "References" |> bindArray (fun prop -> (^a: (member set_References: ITaskItemArray -> unit) (fsc, prop))) + "ReferencePath" |> bind (fun prop -> (^a: (member set_ReferencePath: string -> unit) (fsc, prop))) + "Resources" |> bindArray (fun prop -> (^a: (member set_Resources: ITaskItemArray -> unit) (fsc, prop))) + "SkipCompilerExecution" |> bindBool (fun prop -> (^a: (member set_SkipCompilerExecution: bool -> unit) (fsc, prop))) + "SourceLink" |> bind (fun prop -> (^a: (member set_SourceLink: string -> unit) (fsc, prop))) + "Sources" |> bindArray (fun prop -> (^a: (member set_Sources: ITaskItemArray -> unit) (fsc, prop))) + "Tailcalls" |> bindBool (fun prop -> (^a: (member set_Tailcalls: bool -> unit) (fsc, prop))) + "TargetType" |> bind (fun prop -> (^a: (member set_TargetType: string -> unit) (fsc, prop))) + "TargetProfile" |> bind (fun prop -> (^a: (member set_TargetProfile: string -> unit) (fsc, prop))) + "ToolExe" |> bind (fun prop -> (^a: (member set_ToolExe: string -> unit) (fsc, prop))) + "ToolPath" |> bind (fun prop -> (^a: (member set_ToolPath: string -> unit) (fsc, prop))) + "TreatWarningsAsErrors" |> bindBool (fun prop -> (^a: (member set_TreatWarningsAsErrors: bool -> unit) (fsc, prop))) + "UseStandardResourceNames" |> bindBool (fun prop -> (^a: (member set_UseStandardResourceNames: bool -> unit) (fsc, prop))) + "Utf8Output" |> bindBool (fun prop -> (^a: (member set_Utf8Output: bool -> unit) (fsc, prop))) + "VersionFile" |> bind (fun prop -> (^a: (member set_VersionFile: string -> unit) (fsc, prop))) + "VisualStudioStyleErrors" |> bindBool (fun prop -> (^a: (member set_VisualStudioStyleErrors: bool -> unit) (fsc, prop))) + "WarningLevel" |> bind (fun prop -> (^a: (member set_WarningLevel: string -> unit) (fsc, prop))) + "WarningsAsErrors" |> bind (fun prop -> (^a: (member set_WarningsAsErrors: string -> unit) (fsc, prop))) + "Win32ManifestFile" |> bind (fun prop -> (^a: (member set_Win32ManifestFile: string -> unit) (fsc, prop))) + "Win32ResourceFile" |> bind (fun prop -> (^a: (member set_Win32ResourceFile: string -> unit) (fsc, prop))) + "SubsystemVersion" |> bind (fun prop -> (^a: (member set_SubsystemVersion: string -> unit) (fsc, prop))) + + //TODO force SkipCompilerExecution ? + + let responseFileText = (^a: (member GenerateResponseFileCommands: unit -> string) (fsc)) + + responseFileText.Split([| Environment.NewLine |], StringSplitOptions.RemoveEmptyEntries) + |> List.ofArray + +type internal Dummy() = inherit Object() + +open System.Reflection + +let getResourceFileAsString resourceName = + let assembly = typeof.GetTypeInfo().Assembly + + use stream = assembly.GetManifestResourceStream(resourceName) + match stream with + | null -> failwithf "Resource '%s' not found in assembly '%s'" resourceName (assembly.FullName) + | stream -> + use reader = new IO.StreamReader(stream) + + reader.ReadToEnd() + +let getFscTaskProperties () = + + let msFsharpTargetText = getResourceFileAsString "Microsoft.FSharp.Targets" + + let doc = + try + System.Xml.Linq.XDocument.Parse(msFsharpTargetText) + with ex -> + failwithf "Cannot parse xml embedded resource, %A" ex + + let xnNs name = System.Xml.Linq.XName.Get(name, doc.Root.GetDefaultNamespace().NamespaceName) + let xn name = System.Xml.Linq.XName.Get(name) + let attr name (x: Xml.Linq.XElement) = x.Attributes(xn name) |> Seq.map (fun a -> a.Value) |> Seq.tryHead + let els name (x: Xml.Linq.XElement) = x.Elements(xnNs name) + let el name (x: Xml.Linq.XElement) = x |> els name |> Seq.tryHead + + let targets = + doc.Root + |> els "Target" + + let coreCompile = + targets + |> Seq.tryFind (attr "Name" >> Option.exists ((=) "CoreCompile")) + + match coreCompile with + | None -> + failwithf "CoreCompile target not found from embedded resource" + | Some t -> + match t |> el "Fsc" with + | None -> + failwithf "FscTask not found from embedded resource" + | Some fscTask -> + fscTask.Attributes() + |> Seq.filter (fun a -> a.Name.LocalName <> "Condition") + |> Seq.map (fun a -> a.Name.LocalName, a.Value) + |> List.ofSeq diff --git a/src/Dotnet.ProjInfo/ExternalFSharp/MissingApi.fs b/src/Dotnet.ProjInfo/ExternalFSharp/MissingApi.fs new file mode 100644 index 00000000..505deaeb --- /dev/null +++ b/src/Dotnet.ProjInfo/ExternalFSharp/MissingApi.fs @@ -0,0 +1,57 @@ + +namespace Microsoft.Build.Framework + + type MessageImportance = + | Normal + + type TaskLoggingHelper () = + member __.LogMessageFromText(_message: string, _importance: MessageImportance) = + () + member __.LogError(_message: string, _: string array) = + () + + [] + type ToolTask () = + + member val YieldDuringToolExecution: bool = false with get, set + + abstract member GenerateCommandLineCommands : unit -> string + + abstract member GenerateResponseFileCommands : unit -> string + + abstract ToolName : string + abstract StandardErrorEncoding : System.Text.Encoding + default x.StandardErrorEncoding = System.Text.Encoding.UTF8 + + abstract StandardOutputEncoding : System.Text.Encoding + default x.StandardOutputEncoding = System.Text.Encoding.UTF8 + + abstract GenerateFullPathToTool : unit -> string + + abstract member ExecuteTool : pathToTool: string * responseFileCommands: string * commandLineCommands: string -> int + default x.ExecuteTool(_pathToTool: string, _responseFileCommands: string, _commandLineCommands: string) = + 0 + + abstract HostObject : obj + default x.HostObject = Unchecked.defaultof + + member val ToolExe: string = "" with get, set + member x.Log: TaskLoggingHelper = TaskLoggingHelper () + + type OutputAttribute () = + inherit System.Attribute() + +namespace Microsoft.Build.Exceptions + + exception BuildAbortedException + +namespace Internal.Utilities + + module FSBuild = + module SR = + + let toolpathUnknown () = "" + + + module FSharpEnvironment = + let BinFolderOfDefaultFSharpCompiler (_: string option) = Some "dummy path" diff --git a/src/dotnet-proj-info.sln b/src/dotnet-proj-info.sln new file mode 100644 index 00000000..0f022b15 --- /dev/null +++ b/src/dotnet-proj-info.sln @@ -0,0 +1,69 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B72D6D81-119E-482E-9306-E5E2189D1CB7}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "dotnet-proj-info", "..\src\dotnet-proj-info\dotnet-proj-info.fsproj", "{93CBD93B-3FA8-40BE-8C86-2E2A7B748545}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Dotnet.ProjInfo", "..\src\Dotnet.ProjInfo\Dotnet.ProjInfo.fsproj", "{6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dotnet.ProjInfo.Helpers", "..\src\Dotnet.ProjInfo.Helpers\Dotnet.ProjInfo.Helpers.csproj", "{9275507A-6FC6-46DC-B7CB-DF74D59A4345}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Debug|Any CPU.Build.0 = Debug|Any CPU + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Debug|x64.ActiveCfg = Debug|x64 + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Debug|x64.Build.0 = Debug|x64 + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Debug|x86.ActiveCfg = Debug|x86 + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Debug|x86.Build.0 = Debug|x86 + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Release|Any CPU.ActiveCfg = Release|Any CPU + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Release|Any CPU.Build.0 = Release|Any CPU + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Release|x64.ActiveCfg = Release|x64 + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Release|x64.Build.0 = Release|x64 + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Release|x86.ActiveCfg = Release|x86 + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545}.Release|x86.Build.0 = Release|x86 + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Debug|x64.ActiveCfg = Debug|x64 + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Debug|x64.Build.0 = Debug|x64 + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Debug|x86.ActiveCfg = Debug|x86 + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Debug|x86.Build.0 = Debug|x86 + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Release|Any CPU.Build.0 = Release|Any CPU + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Release|x64.ActiveCfg = Release|x64 + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Release|x64.Build.0 = Release|x64 + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Release|x86.ActiveCfg = Release|x86 + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574}.Release|x86.Build.0 = Release|x86 + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Debug|x64.ActiveCfg = Debug|x64 + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Debug|x64.Build.0 = Debug|x64 + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Debug|x86.ActiveCfg = Debug|x86 + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Debug|x86.Build.0 = Debug|x86 + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Release|Any CPU.Build.0 = Release|Any CPU + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Release|x64.ActiveCfg = Release|x64 + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Release|x64.Build.0 = Release|x64 + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Release|x86.ActiveCfg = Release|x86 + {9275507A-6FC6-46DC-B7CB-DF74D59A4345}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {93CBD93B-3FA8-40BE-8C86-2E2A7B748545} = {B72D6D81-119E-482E-9306-E5E2189D1CB7} + {6E5ECDBA-8C45-4079-B2E2-81DF3D0A5574} = {B72D6D81-119E-482E-9306-E5E2189D1CB7} + {9275507A-6FC6-46DC-B7CB-DF74D59A4345} = {B72D6D81-119E-482E-9306-E5E2189D1CB7} + EndGlobalSection +EndGlobal diff --git a/src/dotnet-proj-info/.vscode/tasks.json b/src/dotnet-proj-info/.vscode/tasks.json deleted file mode 100644 index 33256db7..00000000 --- a/src/dotnet-proj-info/.vscode/tasks.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "0.1.0", - "command": "dotnet", - "isShellCommand": true, - "args": [], - "tasks": [ - { - "taskName": "build", - "args": [ ], - "isBuildCommand": true, - "showOutput": "silent", - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/src/dotnet-proj-info/Inspect.fs b/src/dotnet-proj-info/Inspect.fs index bcb2571f..41e7bc15 100644 --- a/src/dotnet-proj-info/Inspect.fs +++ b/src/dotnet-proj-info/Inspect.fs @@ -1,5 +1,6 @@ module Dotnet.ProjInfo.Inspect +open System open System.IO #if NET45 @@ -54,20 +55,27 @@ type GetProjectInfoErrors<'T> = | MSBuildFailed of int * 'T | MSBuildSkippedTarget -let dotnetMsbuild run project args = - let dotnetExe = @"dotnet" +[] +type MSBuildExePath = + | Path of string + | DotnetMsbuild of dotnetExePath: string + +let msbuild msbuildExe run project args = + let exe, beforeArgs = + match msbuildExe with + | MSBuildExePath.Path path -> path, [] + | MSBuildExePath.DotnetMsbuild path -> path, ["msbuild"] let msbuildArgs = Project(project) :: args @ [ Switch "nologo"; Switch "verbosity:quiet"] |> List.map (MSBuild.sprintfMsbuildArg) - match run dotnetExe ("msbuild" :: msbuildArgs) with + match run exe (beforeArgs @ msbuildArgs) with | 0, x -> Ok x | n, x -> Error (MSBuildFailed (n,x)) -let install_target_file log templates projPath = - let projDir, projName = Path.GetDirectoryName(projPath), Path.GetFileName(projPath) - let objDir = Path.Combine(projDir, "obj") - let targetFileDestPath = Path.Combine(objDir, (sprintf "%s.proj-info.targets" projName)) +let dotnetMsbuild run project args = + msbuild (MSBuildExePath.DotnetMsbuild "dotnet") run project args +let writeTargetFile log templates targetFileDestPath = // https://github.com/dotnet/cli/issues/5650 let targetFileTemplate = @@ -89,6 +97,13 @@ let install_target_file log templates projPath = Ok targetFileDestPath +let install_target_file log templates projPath = + let projDir, projName = Path.GetDirectoryName(projPath), Path.GetFileName(projPath) + let objDir = Path.Combine(projDir, "obj") + let targetFileDestPath = Path.Combine(objDir, (sprintf "%s.proj-info.targets" projName)) + + writeTargetFile log templates targetFileDestPath + type GetResult = | FscArgs of string list | P2PRefs of string list @@ -189,7 +204,7 @@ let parsePropertiesOut outFile = | l, [] -> l |> List.choose (function Ok x -> Some x | Error _ -> None) - |> (fun x -> Ok (Properties x)) + |> (fun x -> Ok x) | _, err -> err |> List.choose (function Ok _ -> None | Error x -> Some x) @@ -246,7 +261,9 @@ let getProperties props = let args = [ Target "_Inspect_GetProperties" Property ("_Inspect_GetProperties_OutFile", outFile) ] - template, args, (fun () -> bindSkipped parsePropertiesOut outFile) + template, args, (fun () -> outFile + |> bindSkipped parsePropertiesOut + |> Result.map Properties) let parseResolvedP2PRefOut outFile = /// Example: @@ -338,10 +355,103 @@ let getProjectInfos log msbuildExec getters additionalArgs projPath = |> Result.map (fun _ -> parsers |> List.map (fun parse -> parse ())) let getProjectInfo log msbuildExec getArgs additionalArgs projPath = - + //TODO refactor to use getProjectInfos let template, args, parse = getArgs () projPath |> install_target_file log [template] |> Result.bind (fun _ -> msbuildExec projPath (args @ additionalArgs)) |> Result.bind (fun _ -> parse ()) + +#if !NETSTANDARD1_6 + +let getFscArgsOldSdk propsToFscArgs () = + + let props = FakeMsbuildTasks.getFscTaskProperties () + + let template = + """ + + + + """ + + ( + props + |> List.mapi (fun i (p,v) -> sprintf """ + <_Inspect_CoreCompilePropsOldSdk_OutLines Include="P%i"> + %s + %s + + """ i p v) + |> List.map (fun s -> s.TrimEnd()) + |> String.concat (System.Environment.NewLine) ) + + + """ + + + + + """.Trim() + let outFile = getNewTempFilePath "CoreCompilePropsOldSdk.txt" + let args = + [ Property ("CopyBuildOutputToOutputDirectory", "false") + Property ("UseCommonOutputDirectory", "true") + Property ("BuildingInsideVisualStudio", "true") + Property ("ShouldUnsetParentConfigurationAndPlatform", "true") + Target "Build" + Property ("_Inspect_CoreCompilePropsOldSdk_OutFile", outFile) ] + template, args, (fun () -> outFile + |> bindSkipped parsePropertiesOut + |> Result.bind propsToFscArgs + |> Result.map FscArgs) + + +let getProjectInfosOldSdk log msbuildExec getters additionalArgs (projPath: string) = + + let templates, argsList, parsers = + getters + |> List.map (fun getArgs -> getArgs ()) + |> List.unzip3 + + let args = argsList |> List.concat + + getNewTempFilePath "proj-info.oldsdk-hook.targets" + |> writeTargetFile log templates + |> Result.bind (fun targetPath -> msbuildExec projPath (args @ additionalArgs @ [ Property("CustomAfterMicrosoftCommonTargets", targetPath) ])) + |> Result.map (fun _ -> parsers |> List.map (fun parse -> parse ())) + +let getProjectInfoOldSdk log msbuildExec getArgs additionalArgs projPath = + //TODO refactor to use getProjectInfosOldSdk + let template, args, parse = getArgs () + + getNewTempFilePath "proj-info.oldsdk-hook.targets" + |> writeTargetFile log [template] + |> Result.bind (fun targetPath -> msbuildExec projPath (args @ additionalArgs @ [ Property("CustomAfterMicrosoftCommonTargets", targetPath) ])) + |> Result.bind (fun _ -> parse ()) + +#endif + +module ProjectRecognizer = + + let (|DotnetSdk|OldSdk|Unsupported|) file = + //Easy way to detect new fsproj is to check the msbuild version of .fsproj + //Post 1.0 has Sdk attribute (like `Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk"`), use that + //for checking .NET Core fsproj. + let rec getProjectType (sr:StreamReader) limit = + // post preview5 dropped this, check Sdk field + let isNetCore (line:string) = line.ToLower().Contains("sdk=") + if limit = 0 then + Unsupported // unsupported project type + else + let line = sr.ReadLine() + if not <| line.Contains("ToolsVersion") && not <| line.Contains("Sdk=") then + getProjectType sr (limit-1) + else + if isNetCore line then DotnetSdk else OldSdk + use sr = File.OpenText(file) + getProjectType sr 3 diff --git a/src/dotnet-proj-info/Program.fs b/src/dotnet-proj-info/Program.fs index 5b63ca08..5f120d9e 100644 --- a/src/dotnet-proj-info/Program.fs +++ b/src/dotnet-proj-info/Program.fs @@ -10,6 +10,9 @@ type CLIArguments = | [] Runtime of string | [] Configuration of string | [] Verbose + | MSBuild of string + | DotnetCli of string + | MSBuild_Host of MSBuildHostPicker with interface IArgParserTemplate with member s.Usage = @@ -22,6 +25,13 @@ with | Runtime _ -> "target runtime, the RuntimeIdentifier msbuild property" | Configuration _ -> "configuration to use (like Debug), the Configuration msbuild property" | Get_Property _ -> "msbuild property to get (allow multiple)" + | MSBuild _ -> "MSBuild path (default \"msbuild\")" + | DotnetCli _ -> "Dotnet CLI path (default \"dotnet\")" + | MSBuild_Host _ -> "the Msbuild host, if auto then oldsdk=MSBuild dotnetSdk=DotnetCLI" +and MSBuildHostPicker = + | Auto = 1 + | MSBuild = 2 + | DotnetMSBuild = 3 open Dotnet.ProjInfo.Inspect @@ -31,7 +41,8 @@ type Errors = | ProjectFileNotFound of string | GenericError of string | RaisedException of System.Exception * string - | ExecutionError of GetProjectInfoErrors + | ExecutionError of GetProjectInfoErrors +and ShellCommandResult = ShellCommandResult of workingDir: string * exePath: string * args: string let parseArgsCommandLine argv = try @@ -44,22 +55,63 @@ let parseArgsCommandLine argv = | _ -> reraise () -open Medallion.Shell open Railway open System.IO -let runCmd log exePath args = +let runCmd log workingDir exePath args = log (sprintf "running '%s %s'" exePath (args |> String.concat " ")) - let cmd = Command.Run(exePath, args |> List.map (fun s -> s.Trim('"')) |> Array.ofList |> Array.map box) - let result = cmd.Result + let logOut = System.Collections.Concurrent.ConcurrentQueue() + let logErr = System.Collections.Concurrent.ConcurrentQueue() + + let runProcess (workingDir: string) (exePath: string) (args: string) = + let psi = System.Diagnostics.ProcessStartInfo() + psi.FileName <- exePath + psi.WorkingDirectory <- workingDir + psi.RedirectStandardOutput <- true + psi.RedirectStandardError <- true + psi.Arguments <- args + psi.CreateNoWindow <- true + psi.UseShellExecute <- false + + //Some env var like `MSBUILD_EXE_PATH` override the msbuild used. + //The dotnet cli (`dotnet`) set these when calling child processes, and + //is wrong because these override some properties of the called msbuild + let msbuildEnvVars = + psi.Environment.Keys + |> Seq.filter (fun s -> s.StartsWith("msbuild", StringComparison.OrdinalIgnoreCase)) + |> Seq.toList + for msbuildEnvVar in msbuildEnvVars do + psi.Environment.Remove(msbuildEnvVar) |> ignore + + + use p = new System.Diagnostics.Process() + p.StartInfo <- psi + + p.OutputDataReceived.Add(fun ea -> logOut.Enqueue (ea.Data)) + + p.ErrorDataReceived.Add(fun ea -> logErr.Enqueue (ea.Data)) + + p.Start() |> ignore + p.BeginOutputReadLine() + p.BeginErrorReadLine() + p.WaitForExit() + + let exitCode = p.ExitCode + + exitCode, (workingDir, exePath, args) + + let exitCode, result = runProcess workingDir exePath (args |> String.concat " ") + log "output:" - cmd.StandardOutput.ReadToEnd() |> log + logOut.ToArray() + |> Array.iter log log "error:" - cmd.StandardError.ReadToEnd() |> log + logErr.ToArray() + |> Array.iter log - result.ExitCode, result + exitCode, (ShellCommandResult result) let realMain argv = attempt { @@ -90,6 +142,24 @@ let realMain argv = attempt { then Error (ProjectFileNotFound projPath) else Ok () + let! (isDotnetSdk, getProjectInfoBySdk, getFscArgsBySdk) = + match projPath with + | ProjectRecognizer.DotnetSdk -> + Ok (true, getProjectInfo, getFscArgs) + | ProjectRecognizer.OldSdk -> +#if NETCOREAPP1_0 + Errors.GenericError "unsupported project format on .net core 1.0, use at least .net core 2.0" + |> Result.Error +#else + let asFscArgs props = + let fsc = Microsoft.FSharp.Build.Fsc() + Dotnet.ProjInfo.FakeMsbuildTasks.getResponseFileFromTask props fsc + Ok (false, getProjectInfoOldSdk, getFscArgsOldSdk (asFscArgs >> Ok)) +#endif + | ProjectRecognizer.Unsupported -> + Errors.GenericError "unsupported project format" + |> Result.Error + let globalArgs = [ results.TryGetResult <@ Framework @>, "TargetFramework" results.TryGetResult <@ Runtime @>, "RuntimeIdentifier" @@ -98,10 +168,14 @@ let realMain argv = attempt { |> List.map (MSBuild.MSbuildCli.Property) let allCmds = - [ results.TryGetResult <@ Fsc_Args @> |> Option.map (fun _ -> getFscArgs) + [ results.TryGetResult <@ Fsc_Args @> |> Option.map (fun _ -> getFscArgsBySdk) results.TryGetResult <@ Project_Refs @> |> Option.map (fun _ -> getP2PRefs) results.TryGetResult <@ Get_Property @> |> Option.map (fun p -> (fun () -> getProperties p)) ] + let msbuildPath = results.GetResult(<@ MSBuild @>, defaultValue = "msbuild") + let dotnetPath = results.GetResult(<@ DotnetCli @>, defaultValue = "dotnet") + let dotnetHostPicker = results.GetResult(<@ MSBuild_Host @>, defaultValue = MSBuildHostPicker.Auto) + let cmds = allCmds |> List.choose id let! cmd = @@ -111,11 +185,26 @@ let realMain argv = attempt { | _ -> Error (InvalidArgsState "specify only one get argument") let exec getArgs additionalArgs = attempt { - let msbuildExec = dotnetMsbuild (runCmd log) + let msbuildExec = + let projDir = Path.GetDirectoryName(projPath) + let rec msbuildHost host = + match host with + | MSBuildHostPicker.MSBuild -> + MSBuildExePath.Path msbuildPath + | MSBuildHostPicker.DotnetMSBuild -> + MSBuildExePath.DotnetMsbuild dotnetPath + | MSBuildHostPicker.Auto -> + if isDotnetSdk then + msbuildHost MSBuildHostPicker.DotnetMSBuild + else + msbuildHost MSBuildHostPicker.MSBuild + | x -> + failwithf "Unexpected msbuild host '%A'" x + msbuild (msbuildHost dotnetHostPicker) (runCmd log projDir) let! r = projPath - |> getProjectInfo log msbuildExec getArgs additionalArgs + |> getProjectInfoBySdk log msbuildExec getArgs additionalArgs |> Result.mapError ExecutionError return r @@ -128,6 +217,7 @@ let realMain argv = attempt { | FscArgs args -> args | P2PRefs args -> args | Properties args -> args |> List.map (fun (x,y) -> sprintf "%s=%s" x y) + | ResolvedP2PRefs _ -> [] out |> List.iter (printfn "%s") @@ -169,3 +259,6 @@ let main argv = | ExecutionError (UnexpectedMSBuildResult r) -> printfn "%A" r 8 + | ExecutionError (MSBuildSkippedTarget) -> + printfn "internal error, target was skipped" + 9 diff --git a/src/dotnet-proj-info/dotnet-proj-info.fsproj b/src/dotnet-proj-info/dotnet-proj-info.fsproj index d4ec1f14..afa2c284 100644 --- a/src/dotnet-proj-info/dotnet-proj-info.fsproj +++ b/src/dotnet-proj-info/dotnet-proj-info.fsproj @@ -1,27 +1,25 @@ - + Exe - netcoreapp1.0 + netcoreapp2.0;netcoreapp1.0 Get msbuild info as cli tool + - - - - - + + diff --git a/test/Directory.Build.props b/test/Directory.Build.props new file mode 100644 index 00000000..cb883413 --- /dev/null +++ b/test/Directory.Build.props @@ -0,0 +1,4 @@ + + + + diff --git a/test/oldsdk/l1/AssemblyInfo.fs b/test/oldsdk/l1/AssemblyInfo.fs new file mode 100644 index 00000000..ce41b1fe --- /dev/null +++ b/test/oldsdk/l1/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace l1.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[] +[] +[] +[] +[] +[] +[] +[] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [] +[] +[] + +do + () \ No newline at end of file diff --git a/test/oldsdk/l1/Library.fs b/test/oldsdk/l1/Library.fs new file mode 100644 index 00000000..4a7cb2d7 --- /dev/null +++ b/test/oldsdk/l1/Library.fs @@ -0,0 +1,22 @@ +namespace l1 + +open Newtonsoft.Json + +type Movie = { + Name : string + Year: int +} + +module Say = + let hello name = + printfn "Hello %s" name + + let jsonstuff () = + + let movies = [ + { Name = "Bad Boys"; Year = 1995 }; + { Name = "Bad Boys 2"; Year = 2003 } + ] + + let json = JsonConvert.SerializeObject(movies) + printfn "%s" json diff --git a/test/oldsdk/l1/Script.fsx b/test/oldsdk/l1/Script.fsx new file mode 100644 index 00000000..94f7437f --- /dev/null +++ b/test/oldsdk/l1/Script.fsx @@ -0,0 +1,8 @@ +// Learn more about F# at http://fsharp.org. See the 'F# Tutorial' project +// for more guidance on F# programming. + +#load "Library1.fs" +open l1 + +// Define your library scripting code here + diff --git a/test/oldsdk/l1/l1.fsproj b/test/oldsdk/l1/l1.fsproj new file mode 100644 index 00000000..0e8756cd --- /dev/null +++ b/test/oldsdk/l1/l1.fsproj @@ -0,0 +1,82 @@ + + + + + Debug + AnyCPU + 2.0 + 07c5431b-f5e0-41c4-b7b3-05fb0d2d4b8b + Library + l1 + l1 + v4.6.1 + 4.4.1.0 + true + l1 + + + true + portable + false + false + bin\$(Configuration)\ + DEBUG;TRACE + 3 + bin\$(Configuration)\$(AssemblyName).XML + + + pdbonly + true + true + bin\$(Configuration)\ + TRACE + 3 + bin\$(Configuration)\$(AssemblyName).XML + + + 11 + + + + + $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets + + + + + + + + + + + + + + FSharp.Core + FSharp.Core.dll + $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll + + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + + + + ..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll + + + + \ No newline at end of file diff --git a/test/oldsdk/l1/packages.config b/test/oldsdk/l1/packages.config new file mode 100644 index 00000000..acaf4804 --- /dev/null +++ b/test/oldsdk/l1/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/app c1/Program.fs b/test/sdk1/app c1/Program.fs similarity index 100% rename from test/app c1/Program.fs rename to test/sdk1/app c1/Program.fs diff --git a/test/app c1/app c1.fsproj b/test/sdk1/app c1/app c1.fsproj similarity index 100% rename from test/app c1/app c1.fsproj rename to test/sdk1/app c1/app c1.fsproj diff --git a/test/tests.proj b/test/tests.proj new file mode 100644 index 00000000..f6e17881 --- /dev/null +++ b/test/tests.proj @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +