Skip to content

Commit 4e24d35

Browse files
Check define condition when parsing pkg projects
1 parent 9897f13 commit 4e24d35

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

src/Fable.Cli/ProjectCracker.fs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Fable.Cli.ProjectCracker
44

55
open System
66
open System.Xml.Linq
7+
open System.Text.RegularExpressions
78
open System.Collections.Generic
89
open FSharp.Compiler.CodeAnalysis
910
open FSharp.Compiler.Text
@@ -248,11 +249,6 @@ let private getDllName (dllFullPath: string) =
248249
let i = dllFullPath.LastIndexOf('/')
249250
dllFullPath[(i + 1) .. (dllFullPath.Length - 5)] // -5 removes the .dll extension
250251

251-
let (|Regex|_|) (pattern: string) (input: string) =
252-
let m = Text.RegularExpressions.Regex.Match(input, pattern)
253-
if m.Success then Some [for x in m.Groups -> x.Value]
254-
else None
255-
256252
let getBasicCompilerArgs () =
257253
[|
258254
// "--debug"
@@ -271,12 +267,32 @@ let getBasicCompilerArgs () =
271267
// yield "--target:library"
272268
|]
273269

270+
let MSBUILD_CONDITION = Regex(@"^\s*'\$\((\w+)\)'\s*([!=]=)\s*'(true|false)'\s*$", RegexOptions.IgnoreCase)
271+
274272
/// Simplistic XML-parsing of .fsproj to get source files, as we cannot
275273
/// run `dotnet restore` on .fsproj files embedded in Nuget packages.
276-
let getSourcesFromFablePkg (projFile: string) =
274+
let getSourcesFromFablePkg (opts: CrackerOptions) (projFile: string) =
277275
let withName s (xs: XElement seq) =
278276
xs |> Seq.filter (fun x -> x.Name.LocalName = s)
279277

278+
let checkCondition (el: XElement) =
279+
match el.Attribute(XName.Get "Condition") with
280+
| null -> true
281+
| attr ->
282+
match attr.Value with
283+
| Naming.Regex MSBUILD_CONDITION [_; prop; op; bval] ->
284+
let bval = Boolean.Parse bval
285+
let isTrue = (op = "==") = bval // (op = "==" && bval) || (op = "!=" && not bval)
286+
let isDefined =
287+
opts.FableOptions.Define
288+
|> List.exists (fun d -> String.Equals(d, prop, StringComparison.InvariantCultureIgnoreCase))
289+
// printfn $"CONDITION: {prop} ({isDefined}) {op} {bval} ({isTrue})"
290+
isTrue = isDefined
291+
| _ -> false
292+
293+
let withNameAndCondition s (xs: XElement seq) =
294+
xs |> Seq.filter (fun el -> el.Name.LocalName = s && checkCondition el)
295+
280296
let xmlDoc = XDocument.Load(projFile)
281297
let projDir = Path.GetDirectoryName(projFile)
282298

@@ -290,11 +306,11 @@ let getSourcesFromFablePkg (projFile: string) =
290306
|> not))
291307

292308
xmlDoc.Root.Elements()
293-
|> withName "ItemGroup"
309+
|> withNameAndCondition "ItemGroup"
294310
|> Seq.map (fun item ->
295311
(item.Elements(), [])
296312
||> Seq.foldBack (fun el src ->
297-
if el.Name.LocalName = "Compile" then
313+
if el.Name.LocalName = "Compile" && checkCondition el then
298314
el.Elements() |> withName "Link"
299315
|> Seq.tryHead |> function
300316
| Some link when Path.isRelativePath link.Value ->
@@ -445,7 +461,7 @@ let getProjectOptionsFromProjectFile =
445461
tryGetResult isMain opts manager csprojFile
446462
|> Option.map (fun (r: IAnalyzerResult) ->
447463
// Careful, options for .csproj start with / but so do root paths in unix
448-
let reg = System.Text.RegularExpressions.Regex(@"^\/[^\/]+?(:?:|$)")
464+
let reg = Regex(@"^\/[^\/]+?(:?:|$)")
449465
let comArgs =
450466
r.CompilerArguments
451467
|> Array.map (fun line ->
@@ -469,7 +485,7 @@ let getProjectOptionsFromProjectFile =
469485
tryGetResult isMain opts manager projFile
470486
|> Option.map (fun r ->
471487
// result.CompilerArguments doesn't seem to work well in Linux
472-
let comArgs = Text.RegularExpressions.Regex.Split(r.Command, @"\r?\n")
488+
let comArgs = Regex.Split(r.Command, @"\r?\n")
473489
comArgs, r))
474490
|> function
475491
| Some result -> result
@@ -631,7 +647,7 @@ let copyFableLibraryAndPackageSourcesPy (opts: CrackerOptions) (pkgs: FablePacka
631647

632648
// See #1455: F# compiler generates *.AssemblyInfo.fs in obj folder, but we don't need it
633649
let removeFilesInObjFolder sourceFiles =
634-
let reg = System.Text.RegularExpressions.Regex(@"[\\\/]obj[\\\/]")
650+
let reg = Regex(@"[\\\/]obj[\\\/]")
635651
sourceFiles |> Array.filter (reg.IsMatch >> not)
636652

637653
let loadPrecompiledInfo (opts: CrackerOptions) otherOptions sourceFiles =
@@ -775,7 +791,7 @@ let getFullProjectOpts (opts: CrackerOptions) =
775791

776792
let pkgRefs =
777793
pkgRefs |> List.map (fun pkg ->
778-
{ pkg with SourcePaths = getSourcesFromFablePkg pkg.FsprojPath })
794+
{ pkg with SourcePaths = getSourcesFromFablePkg opts pkg.FsprojPath })
779795

780796
let sourcePaths =
781797
let pkgSources = pkgRefs |> List.collect (fun x -> x.SourcePaths)

0 commit comments

Comments
 (0)