Skip to content

Commit

Permalink
Add support for overriden BaseIntermediateOutputPath (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
Krzysztof-Cieslak authored Mar 25, 2020
1 parent e6d0f77 commit 42ddee9
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 36 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
Expand Down Expand Up @@ -241,3 +241,7 @@ _Pvt_Extensions
msbuild.binlog
/test/testrun_ws_fcs/
/.ionide/

.fake
.ionide
obj2
6 changes: 3 additions & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<Project ToolsVersion="15.0">

<PropertyGroup>
<Version Condition=" '$(Version)' == '' ">0.38.0$(VersionSuffix)</Version>
<Version Condition=" '$(Version)' == '' ">0.39.0$(VersionSuffix)</Version>
</PropertyGroup>

<PropertyGroup>
<Authors>enricosada</Authors>
<PackageProjectUrl>https://github.com/enricosada/dotnet-proj-info/</PackageProjectUrl>
<PackageProjectUrl>https://github.com/IonideProject/dotnet-proj-info/</PackageProjectUrl>
<PackageTags>msbuild;dotnet;sdk;csproj;fsproj</PackageTags>
<RepositoryUrl>https://github.com/enricosada/dotnet-proj-info.git</RepositoryUrl>
<RepositoryUrl>https://github.com/IonideProject/dotnet-proj-info.git</RepositoryUrl>
<PackageLicenseUrl>https://github.com/enricosada/dotnet-proj-info/blob/master/LICENSE</PackageLicenseUrl>
</PropertyGroup>

Expand Down
12 changes: 6 additions & 6 deletions src/Dotnet.ProjInfo.Workspace/NETFrameworkInfoProvider.fs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ module internal NETFrameworkInfoProvider =
let private defaultReferencesForNonProjectFiles () =
// ref https://github.com/fsharp/FSharp.Compiler.Service/blob/1f497ef86fd5d0a18e5a935f3d16984fda91f1de/src/fsharp/CompileOps.fs#L1801
// This list is the default set of references for "non-project" files

// TODO make somehow this list public on FCS and use that directly instead of hardcode it in FSAC

let GetDefaultSystemValueTupleReference () =
Expand All @@ -75,17 +75,17 @@ module internal NETFrameworkInfoProvider =
// from https://github.com/fsharp/FSharp.Compiler.Service/blob/1f497ef86fd5d0a18e5a935f3d16984fda91f1de/src/fsharp/CompileOps.fs#L1803-L1832
[
yield "System"
yield "System.Xml"
yield "System.Xml"
yield "System.Runtime.Remoting"
yield "System.Runtime.Serialization.Formatters.Soap"
yield "System.Data"
yield "System.Drawing"
yield "System.Core"
// These are the Portable-profile and .NET Standard 1.6 dependencies of FSharp.Core.dll. These are needed
// when an F# sript references an F# profile 7, 78, 259 or .NET Standard 1.6 component which in turn refers
// when an F# sript references an F# profile 7, 78, 259 or .NET Standard 1.6 component which in turn refers
// to FSharp.Core for profile 7, 78, 259 or .NET Standard.
yield "System.Runtime" // lots of types
yield "System.Linq" // System.Linq.Expressions.Expression<T>
yield "System.Linq" // System.Linq.Expressions.Expression<T>
yield "System.Reflection" // System.Reflection.ParameterInfo
yield "System.Linq.Expressions" // System.Linq.IQueryable<T>
yield "System.Threading.Tasks" // valuetype [System.Threading.Tasks]System.Threading.CancellationToken
Expand All @@ -96,14 +96,14 @@ module internal NETFrameworkInfoProvider =
yield "System.Runtime.Numerics" // BigInteger
yield "System.Threading" // OperationCanceledException
// always include a default reference to System.ValueTuple.dll in scripts and out-of-project sources
match GetDefaultSystemValueTupleReference() with
match GetDefaultSystemValueTupleReference() with
| None -> ()
| Some v -> yield v

yield "System.Web"
yield "System.Web.Services"
yield "System.Windows.Forms"
yield "System.Numerics"
yield "System.Numerics"
]

let getAdditionalArgumentsBy (msbuildHost: MSBuildExePath) (targetFramework: string) =
Expand Down
63 changes: 50 additions & 13 deletions src/Dotnet.ProjInfo.Workspace/ProjectCrackerDotnetSdk.fs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,58 @@ module internal ProjectCrackerDotnetSdk =
type ParsedProjectCache = Collections.Concurrent.ConcurrentDictionary<string, ParsedProject>

let private execProjInfoFromMsbuild msbuildPath notifyState parseAsSdk additionalMSBuildProps (file: string) =
let inspect =
match parseAsSdk with
| ProjectParsingSdk.DotnetSdk ->
Dotnet.ProjInfo.Inspect.getProjectInfos
| ProjectParsingSdk.VerboseSdk ->
Dotnet.ProjInfo.Inspect.getProjectInfos // getProjectInfosOldSdk

let globalArgs =
match Environment.GetEnvironmentVariable("DOTNET_PROJ_INFO_MSBUILD_BL") with
| "1" -> Dotnet.ProjInfo.Inspect.MSBuild.MSbuildCli.Switch("bl") :: []
| _ -> []

let projDir = Path.GetDirectoryName file

let loggedMessages = System.Collections.Concurrent.ConcurrentQueue<string>()

let runCmd exePath args = Utils.runProcess loggedMessages.Enqueue projDir exePath (args |> String.concat " ")

let msbuildExec =
Dotnet.ProjInfo.Inspect.msbuild msbuildPath runCmd

notifyState (WorkspaceProjectState.Loading (file, additionalMSBuildProps))

let objRes =
let r =
file
|> inspect loggedMessages.Enqueue msbuildExec [fun () -> Dotnet.ProjInfo.Inspect.getProperties ["BaseIntermediateOutputPath"] ] globalArgs
|> Result.bind (fun n ->
match List.tryHead n with
| Some n -> n
| None -> Error (GetProjectInfoErrors.UnexpectedMSBuildResult "Couldn't find BaseIntermediateOutputPath"))
|> Result.map (fun n ->
match n with
| Properties lst -> List.tryHead lst |> Option.map snd
| _ -> None
)
match r with
| Ok r -> r
| _ -> None


match parseAsSdk with
| ProjectParsingSdk.DotnetSdk ->
let projectAssetsJsonPath = Path.Combine(projDir, "obj", "project.assets.json")
let projectAssetsJsonPath =
match objRes with
| Some r ->
if Path.IsPathRooted r then
Path.Combine(r, "project.assets.json")
else
Path.Combine(projDir, r, "project.assets.json")
| None ->
Path.Combine(projDir, "obj", "project.assets.json")
if not(File.Exists(projectAssetsJsonPath)) then
raise (ProjectInspectException (ProjectNotRestored file))
| ProjectParsingSdk.VerboseSdk ->
Expand Down Expand Up @@ -117,21 +162,13 @@ module internal ProjectCrackerDotnetSdk =

let getItems () = Dotnet.ProjInfo.Inspect.getItems [("Compile", GetItemsModifier.FullPath); ("Compile", GetItemsModifier.Custom("Link"))] []

let loggedMessages = System.Collections.Concurrent.ConcurrentQueue<string>()

let runCmd exePath args = Utils.runProcess loggedMessages.Enqueue projDir exePath (args |> String.concat " ")

let msbuildExec =
Dotnet.ProjInfo.Inspect.msbuild msbuildPath runCmd


let additionalArgs = additionalMSBuildProps |> List.map (Dotnet.ProjInfo.Inspect.MSBuild.MSbuildCli.Property)

let inspect =
match parseAsSdk with
| ProjectParsingSdk.DotnetSdk ->
Dotnet.ProjInfo.Inspect.getProjectInfos
| ProjectParsingSdk.VerboseSdk ->
Dotnet.ProjInfo.Inspect.getProjectInfos // getProjectInfosOldSdk


let globalArgs =
match Environment.GetEnvironmentVariable("DOTNET_PROJ_INFO_MSBUILD_BL") with
Expand Down Expand Up @@ -231,7 +268,7 @@ module internal ProjectCrackerDotnetSdk =
let mergedLog =
[ yield (file, "")
yield! p2pProjects |> List.collect (fun (_,_,x,_) -> x) ]

let extraInfo = getExtraInfoVerboseSdk props
ProjectSdkType.Verbose(extraInfo), mergedLog

Expand All @@ -253,7 +290,7 @@ module internal ProjectCrackerDotnetSdk =
{
ProjectId = Some file
ProjectFileName = file
TargetFramework =
TargetFramework =
match sdkTypeData with
| ProjectSdkType.DotnetSdk t ->
t.TargetFramework
Expand Down
4 changes: 2 additions & 2 deletions src/Dotnet.ProjInfo.Workspace/VisualTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ module VisualTree =

let item = projItems |> List.tryFind (isCompileItemWithFullpath sourceFile)
match item with
| None ->
| None ->
let (name, fullpath) = projPath |> getVisualPath None (Some sourceFile) sourceFile

ProjectItem.Compile (name, fullpath)
| Some p ->
let linkMetadata = p |> tryFindMetadata (GetItemsModifier.Custom("Link"))
let fullpathMetadata = p |> tryFindMetadata (GetItemsModifier.FullPath)

let (name, fullpath) = projPath |> getVisualPath linkMetadata fullpathMetadata p.Identity
let (name, fullpath) = projPath |> getVisualPath linkMetadata fullpathMetadata p.Identity

ProjectItem.Compile (name, fullpath)
62 changes: 51 additions & 11 deletions test/Dotnet.ProjInfo.Workspace.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ module ExpectNotification =

member __.Notifications
with get () = notifications |> List.ofSeq

let findByPath path parsed =
parsed
|> Array.tryPick (fun (kv: KeyValuePair<ProjectKey, ProjectOptions>) ->
Expand All @@ -156,7 +156,7 @@ let isOSX () =
open TestsConfig

let tests (suiteConfig: TestSuiteConfig) =

let prepareTestsAssets = lazy(
let logger = Log.create "Tests Assets"
let fs = FileUtils(logger)
Expand Down Expand Up @@ -253,13 +253,13 @@ let tests (suiteConfig: TestSuiteConfig) =
let parsed = loader.Projects

Expect.equal parsed.Length 1 "lib"

let l1Parsed =
parsed
|> expectFind projPath { ProjectKey.ProjectPath = projPath; TargetFramework = "net461" } "a lib"

let expectedSources =
let sourceFiles =
let sourceFiles =
[ projDir / "AssemblyInfo.fs"
projDir / "Library.fs" ]

Expand Down Expand Up @@ -296,7 +296,7 @@ let tests (suiteConfig: TestSuiteConfig) =
let parsed = loader.Projects

Expect.equal parsed.Length 1 "console and lib"

let n1Parsed =
parsed
|> expectFind projPath { ProjectKey.ProjectPath = projPath; TargetFramework = "netstandard2.0" } "first is a lib"
Expand Down Expand Up @@ -503,7 +503,7 @@ let tests (suiteConfig: TestSuiteConfig) =
let parsed = loader.Projects

Expect.equal parsed.Length 3 "c1, l1, l2"

let c1 = testDir/ (``sample6 Netsdk Sparse/1``.ProjectFile)
let c1Dir = Path.GetDirectoryName c1

Expand Down Expand Up @@ -569,6 +569,46 @@ let tests (suiteConfig: TestSuiteConfig) =
Expect.isTrue (File.Exists outputPath) (sprintf "output assembly '%s' not found" outputPath)
)

testCase |> withLog "can load sample9" (fun logger fs ->
let testDir = inDir fs "load_sample9"
copyDirFromAssets fs ``sample9 NetSdk library``.ProjDir testDir
// fs.cp (``sample9 NetSdk library``.ProjDir/"Directory.Build.props") testDir

let projPath = testDir/ (``sample9 NetSdk library``.ProjectFile)
let projDir = Path.GetDirectoryName projPath

dotnet fs ["restore"; projPath]
|> checkExitCodeZero

let loader = createLoader logger

let watcher = watchNotifications logger loader

loader.LoadProjects [projPath]

[ loading "n1.fsproj"; loaded "n1.fsproj" ]
|> expectNotifications (watcher.Notifications)

let [_; WorkspaceProjectState.Loaded(n1Loaded,_)] = watcher.Notifications

let parsed = loader.Projects

Expect.equal parsed.Length 1 "console and lib"

let n1Parsed =
parsed
|> expectFind projPath { ProjectKey.ProjectPath = projPath; TargetFramework = "netstandard2.0" } "first is a lib"

let expectedSources =
[ projDir / "obj2/Debug/netstandard2.0/n1.AssemblyInfo.fs"
projDir / "Library.fs" ]
|> List.map Path.GetFullPath

Expect.equal n1Parsed.SourceFiles expectedSources "check sources"

Expect.equal n1Parsed n1Loaded "notificaton and parsed should be the same"
)

]

let invalid =
Expand Down Expand Up @@ -607,7 +647,7 @@ let tests (suiteConfig: TestSuiteConfig) =
let parsed = loader.Projects

Expect.equal parsed.Length 0 "no project loaded"

Expect.equal (watcher.Notifications |> List.item 1) (WorkspaceProjectState.Failed(wrongPath, (GetProjectOptionsErrors.GenericError(wrongPath, "not found")))) "check error type"
)

Expand All @@ -632,7 +672,7 @@ let tests (suiteConfig: TestSuiteConfig) =
let parsed = loader.Projects

Expect.equal parsed.Length 0 "no project loaded"

Expect.equal (watcher.Notifications |> List.item 1) (WorkspaceProjectState.Failed(projPath, (GetProjectOptionsErrors.ProjectNotRestored projPath))) "check error type"
)

Expand Down Expand Up @@ -801,7 +841,7 @@ let tests (suiteConfig: TestSuiteConfig) =
loader.LoadProjects [projPath]

let parsed = loader.Projects

let l1Parsed =
parsed
|> expectFind projPath { ProjectKey.ProjectPath = projPath; TargetFramework = "net461" } "a lib"
Expand Down Expand Up @@ -834,7 +874,7 @@ let tests (suiteConfig: TestSuiteConfig) =
loader.LoadProjects [projPath]

let parsed = loader.Projects

let n1Parsed =
parsed
|> expectFind projPath { ProjectKey.ProjectPath = projPath; TargetFramework = "netstandard2.0" } "first is a lib"
Expand Down Expand Up @@ -1000,7 +1040,7 @@ let tests (suiteConfig: TestSuiteConfig) =
loader.LoadProjects [projPath]

let parsed = loader.Projects

let n1Parsed =
parsed
|> expectFind projPath { ProjectKey.ProjectPath = projPath; TargetFramework = "netstandard2.0" } "first is a lib"
Expand Down
10 changes: 10 additions & 0 deletions test/dotnet-proj.Tests/TestAssets.fs
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,13 @@ let ``sample8 NetSdk Explorer`` =
"netstandard2.0", sourceFiles ["LibraryA.fs"; "LibraryC.fs"; "LibraryB.fs"]
]
ProjectReferences = [] }

/// dotnet sdk, one netstandard2.0 lib n1, nonstandard obj
let ``sample9 NetSdk library`` =
{ ProjDir = "sample9-netsdk-changed-obj"
AssemblyName = "n1"
ProjectFile = "n1"/"n1.fsproj"
TargetFrameworks = Map.ofList [
"netstandard2.0", sourceFiles ["Library.fs"]
]
ProjectReferences = [] }
1 change: 1 addition & 0 deletions test/examples/sample9-netsdk-changed-obj/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a simple library (.net sdk) targeting `netstandard2.0`
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project ToolsVersion="15.0">
<PropertyGroup>
<BaseIntermediateOutputPath>obj2\</BaseIntermediateOutputPath>
</PropertyGroup>
</Project>
5 changes: 5 additions & 0 deletions test/examples/sample9-netsdk-changed-obj/n1/Library.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace n1

module Say =
let hello name =
printfn "Hello %s" name
11 changes: 11 additions & 0 deletions test/examples/sample9-netsdk-changed-obj/n1/n1.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="Library.fs" />
</ItemGroup>

</Project>

0 comments on commit 42ddee9

Please sign in to comment.