From edd4c0e8c726cbb2eea8603220d088ffc0f2bb0f Mon Sep 17 00:00:00 2001 From: bhugot Date: Fri, 16 Jun 2017 04:32:04 +0200 Subject: [PATCH 1/4] #913 Implementation for multiple targetFramework --- src/Paket.Core/Packaging/NupkgWriter.fs | 41 +++++-- src/Paket.Core/Packaging/PackageMetaData.fs | 19 +-- .../PaketConfigFiles/TemplateFile.fs | 108 ++++++++++++------ .../Versioning/FrameworkHandling.fs | 1 - .../Packaging/NuspecWriterSpecs.fs | 86 +++++++++++++- .../Packaging/TemplateFileParsing.fs | 47 +++++++- 6 files changed, 243 insertions(+), 59 deletions(-) diff --git a/src/Paket.Core/Packaging/NupkgWriter.fs b/src/Paket.Core/Packaging/NupkgWriter.fs index 2d34941274..fea89b1090 100644 --- a/src/Paket.Core/Packaging/NupkgWriter.fs +++ b/src/Paket.Core/Packaging/NupkgWriter.fs @@ -8,6 +8,7 @@ open Paket.Xml open System.Text open System.Text.RegularExpressions open System.Xml +open Paket.Requirements module internal NupkgWriter = @@ -83,9 +84,9 @@ module internal NupkgWriter = frameworkAssembliesList |> List.iter (buildFrameworkReferencesNode >> d.Add) metadataNode.Add d - let buildDependencyNode (Id, requirement:VersionRequirement) = + let buildDependencyNode (id, requirement:VersionRequirement) = let dep = XElement(ns + "dependency") - dep.SetAttributeValue(XName.Get "id", Id) + dep.SetAttributeValue(XName.Get "id", id) let version = requirement.FormatInNuGetSyntax() if String.IsNullOrEmpty version then dep.SetAttributeValue(XName.Get "version", "0.0") @@ -93,13 +94,39 @@ module internal NupkgWriter = dep.SetAttributeValue(XName.Get "version", version) dep + let last3(_,_,c) = c; + let last2(_,b) = b; + let fst3 (a, _, _) = a + let second (a, b, _) = (a,b) + + let buildGroupNode (framework:FrameworkIdentifier, add) = + let g = XElement(ns + "group") + g.SetAttributeValue(XName.Get "targetFramework", framework.ToString()) + add g + g + + + let buildDependencyNodes (excludedDependencies, add, dependencyList) = + dependencyList + |> List.filter (fun d -> Set.contains (fst3 d) excludedDependencies |> not) + |> List.map second + |> List.iter (buildDependencyNode >> add) + + let buildDependencyNodesByGroup excludedDependencies add dependencyList framework = + let node = buildGroupNode(framework, add) + buildDependencyNodes(excludedDependencies, node.Add, dependencyList) + let buildDependenciesNode excludedDependencies dependencyList = if List.isEmpty dependencyList then () else let d = XElement(ns + "dependencies") - dependencyList - |> List.filter (fun d -> Set.contains (fst d) excludedDependencies |> not) - |> List.iter (buildDependencyNode >> d.Add) - metadataNode.Add d + + let groups = List.groupBy last3 dependencyList + if groups.Length = 1 && fst groups.Head = None then + buildDependencyNodes(excludedDependencies, d.Add, dependencyList) + else + groups + |> List.iter (fun a -> buildDependencyNodesByGroup excludedDependencies d.Add (last2 a) (fst a).Value) + metadataNode.Add d let buildReferenceNode (fileName) = let dep = XElement(ns + "reference") @@ -369,7 +396,7 @@ module NuspecExtensions = references.Groups |> Seq.collect (fun kvp -> kvp.Value.NugetPackages |> List.choose (fun pkg -> dependencies.TryGetPackage(kvp.Key,pkg.Name) - |> Option.map (fun verreq -> pkg.Name,verreq.VersionRequirement))) + |> Option.map (fun verreq -> pkg.Name,verreq.VersionRequirement, None))) |> List.ofSeq ) |> Option.defaultValue [] let projectInfo, optionalInfo = project.GetTemplateMetadata () diff --git a/src/Paket.Core/Packaging/PackageMetaData.fs b/src/Paket.Core/Packaging/PackageMetaData.fs index 32101049f9..2c17e65992 100644 --- a/src/Paket.Core/Packaging/PackageMetaData.fs +++ b/src/Paket.Core/Packaging/PackageMetaData.fs @@ -107,11 +107,13 @@ let (|Valid|Invalid|) md = Symbols = s } | _ -> Invalid -let addDependency (templateFile : TemplateFile) (dependency : PackageName * VersionRequirement) = +let firstOf3 (a, _, _) = a + +let addDependency (templateFile : TemplateFile) (dependency : PackageName * VersionRequirement * FrameworkIdentifier option) = match templateFile with | CompleteTemplate(core, opt) -> let newDeps = - match opt.Dependencies |> List.tryFind (fun (n,_) -> n = fst dependency) with + match opt.Dependencies |> List.tryFind (fun (n,_,_) -> n = firstOf3 dependency) with | None -> dependency :: opt.Dependencies | _ -> opt.Dependencies { FileName = templateFile.FileName @@ -253,7 +255,7 @@ let findDependencies (dependenciesFile : DependenciesFile) config platform (temp match core.Version with | Some v -> let versionConstraint = if lockDependencies || pinProjectReferences then Specific v else Minimum v - PackageName core.Id, VersionRequirement(versionConstraint, getPreReleaseStatus v) + PackageName core.Id, VersionRequirement(versionConstraint, getPreReleaseStatus v), None | None -> failwithf "There was no version given for %s." templateFile.FileName | IncompleteTemplate -> failwithf "You cannot create a dependency on a template file (%s) with incomplete metadata." templateFile.FileName) @@ -357,7 +359,7 @@ let findDependencies (dependenciesFile : DependenciesFile) config platform (temp | None -> match version with | Some v -> - np.Name,VersionRequirement.Parse (v.ToString()) + np.Name,VersionRequirement.Parse (v.ToString()) , None | None -> if minimumFromLockFile then let groupName = @@ -368,7 +370,7 @@ let findDependencies (dependenciesFile : DependenciesFile) config platform (temp |> Option.map fst match groupName with - | None -> np.Name,specificVersionRequirement + | None -> np.Name,specificVersionRequirement, None | Some groupName -> let group = lockFile.GetGroup groupName @@ -377,9 +379,9 @@ let findDependencies (dependenciesFile : DependenciesFile) config platform (temp | Some resolvedPackage -> VersionRequirement(GreaterThan resolvedPackage.Version, getPreReleaseStatus resolvedPackage.Version) | None -> specificVersionRequirement - np.Name,lockedVersion + np.Name,lockedVersion, None else - np.Name,specificVersionRequirement + np.Name,specificVersionRequirement, None | Some groupName -> let dependencyVersionRequirement = if not lockDependencies then @@ -437,7 +439,8 @@ let findDependencies (dependenciesFile : DependenciesFile) config platform (temp match dependencyVersionRequirement with | Some installed -> installed | None -> failwithf "No package with id '%O' installed in group %O." np.Name groupName - np.Name, dep) + + np.Name, dep, None) deps |> List.fold addDependency withDepsAndIncluded diff --git a/src/Paket.Core/PaketConfigFiles/TemplateFile.fs b/src/Paket.Core/PaketConfigFiles/TemplateFile.fs index 31a6522487..d4d6c6e49e 100644 --- a/src/Paket.Core/PaketConfigFiles/TemplateFile.fs +++ b/src/Paket.Core/PaketConfigFiles/TemplateFile.fs @@ -6,6 +6,7 @@ open System.IO open System.Text.RegularExpressions open Chessie.ErrorHandling open Paket.Domain +open Paket.Requirements module private TemplateParser = type private ParserState = @@ -141,7 +142,7 @@ type OptionalPackagingInfo = RequireLicenseAcceptance : bool Tags : string list DevelopmentDependency : bool - Dependencies : (PackageName * VersionRequirement) list + Dependencies : (PackageName * VersionRequirement * FrameworkIdentifier option) list ExcludedDependencies : Set ExcludedGroups : Set References : string list @@ -261,45 +262,80 @@ module internal TemplateFile = | Some m -> ok m | None -> failP file "No description line in paket.template file." + let private (|Framework|_|) (line:string) = + match line.Trim() with + | String.RemovePrefix "framework:" _ as trimmed -> Some (FrameworkDetection.Extract(trimmed.Replace("framework: ",""))) + | _ -> None + + let private (|Empty|_|) (line:string) = + match line.Trim() with + | _ when String.IsNullOrWhiteSpace line -> Some (Empty line) + | String.RemovePrefix "//" _ -> Some (Empty line) + | String.RemovePrefix "#" _ -> Some (Empty line) + | _ -> None + type TargetFrameworkGroup = + { + Framework : FrameworkIdentifier option + Dependencies : (PackageName * VersionRequirement * FrameworkIdentifier option) List} + static member ForNone = { Framework = None ; Dependencies = [] } + static member ForFramework framework = { Framework = framework ; Dependencies = [] } + + let private getDependencieByLine (fileName, lockFile:LockFile,currentVersion:SemVerInfo option, specificVersions:Map, line:string, framework:FrameworkIdentifier option)= + let reg = Regex(@"(?\S+)(?.*)").Match line + let name = PackageName reg.Groups.["id"].Value + let versionRequirement = + let versionString = + let s = reg.Groups.["version"].Value.Trim() + if s.Contains "CURRENTVERSION" then + match specificVersions.TryFind (string name) with + | Some v -> s.Replace("CURRENTVERSION", string v) + | None -> + match currentVersion with + | Some v -> s.Replace("CURRENTVERSION", string v) + | None -> failwithf "The template file %s contains the placeholder CURRENTVERSION, but no version was given." fileName + + elif s.Contains "LOCKEDVERSION" then + match lockFile.Groups.[Constants.MainDependencyGroup].Resolution |> Map.tryFind name with + | Some p -> s.Replace("LOCKEDVERSION", string p.Version) + | None -> + let packages = + lockFile.GetGroupedResolution() + |> Seq.filter (fun kv -> snd kv.Key = name) + |> Seq.toList + + match packages with + | [] -> failwithf "The template file %s contains the placeholder LOCKEDVERSION, but no version was given for package %O in paket.lock." fileName name + | [kv] -> s.Replace("LOCKEDVERSION", string kv.Value.Version) + | _ -> failwithf "The template file %s contains the placeholder LOCKEDVERSION, but more than one group contains package %O in paket.lock." fileName name + + else s + + DependenciesFileParser.parseVersionRequirement versionString + name, versionRequirement, framework + + let private getDependenciesByTargetFramework fileName lockFile currentVersion specificVersions (lineNo, state: TargetFrameworkGroup list) line= + match state with + | current::other -> + let lineNo = lineNo + 1 + match line with + | Framework framework -> + let group = TargetFrameworkGroup.ForFramework framework::current::other + lineNo, group + | Empty _ -> lineNo, current::other + | _ -> + let dependency = getDependencieByLine(fileName, lockFile, currentVersion, specificVersions, line, current.Framework) + lineNo ,{ current with Dependencies = current.Dependencies @ [dependency] }::other + | [] -> failwithf "Error in paket.dependencies line %d" lineNo + let private getDependencies (fileName, lockFile:LockFile, info : Map,currentVersion:SemVerInfo option, specificVersions:Map) = match Map.tryFind "dependencies" info with | None -> [] | Some d -> - d.Split '\n' - |> Array.map (fun d -> - let reg = Regex(@"(?\S+)(?.*)").Match d - let name = PackageName reg.Groups.["id"].Value - let versionRequirement = - let versionString = - let s = reg.Groups.["version"].Value.Trim() - if s.Contains "CURRENTVERSION" then - match specificVersions.TryFind (string name) with - | Some v -> s.Replace("CURRENTVERSION", string v) - | None -> - match currentVersion with - | Some v -> s.Replace("CURRENTVERSION", string v) - | None -> failwithf "The template file %s contains the placeholder CURRENTVERSION, but no version was given." fileName - - elif s.Contains "LOCKEDVERSION" then - match lockFile.Groups.[Constants.MainDependencyGroup].Resolution |> Map.tryFind name with - | Some p -> s.Replace("LOCKEDVERSION", string p.Version) - | None -> - let packages = - lockFile.GetGroupedResolution() - |> Seq.filter (fun kv -> snd kv.Key = name) - |> Seq.toList - - match packages with - | [] -> failwithf "The template file %s contains the placeholder LOCKEDVERSION, but no version was given for package %O in paket.lock." fileName name - | [kv] -> s.Replace("LOCKEDVERSION", string kv.Value.Version) - | _ -> failwithf "The template file %s contains the placeholder LOCKEDVERSION, but more than one group contains package %O in paket.lock." fileName name - - else s - - DependenciesFileParser.parseVersionRequirement versionString - - name, versionRequirement) - |> Array.toList + d.Split '\n' + |> Array.fold (getDependenciesByTargetFramework fileName lockFile currentVersion specificVersions) (0, [TargetFrameworkGroup.ForNone]) + |> snd + |> List.rev + |> List.collect (fun a -> a.Dependencies) let private getExcludedDependencies (info : Map) = diff --git a/src/Paket.Core/Versioning/FrameworkHandling.fs b/src/Paket.Core/Versioning/FrameworkHandling.fs index 7ec1101686..37d3288fc6 100644 --- a/src/Paket.Core/Versioning/FrameworkHandling.fs +++ b/src/Paket.Core/Versioning/FrameworkHandling.fs @@ -439,7 +439,6 @@ module FrameworkDetection = open Logging /// parse a string to construct a Netframework, NetCore, NetStandard, or other dotnet identifier - [] let Extract = memoize (fun (path:string) -> diff --git a/tests/Paket.Tests/Packaging/NuspecWriterSpecs.fs b/tests/Paket.Tests/Packaging/NuspecWriterSpecs.fs index c2a3cfcd8c..b4d5aee1b9 100644 --- a/tests/Paket.Tests/Packaging/NuspecWriterSpecs.fs +++ b/tests/Paket.Tests/Packaging/NuspecWriterSpecs.fs @@ -7,6 +7,7 @@ open FsUnit open NUnit.Framework open TestHelpers open Paket.Domain +open Paket.Requirements [] let ``should serialize core info``() = @@ -58,8 +59,89 @@ let ``should serialize dependencies``() = { OptionalPackagingInfo.Epmty with Tags = [ "f#"; "rules" ] Dependencies = - [ PackageName "Paket.Core", VersionRequirement.Parse "[3.1]" - PackageName "xUnit", VersionRequirement.Parse "2.0" ] } + [ PackageName "Paket.Core", VersionRequirement.Parse "[3.1]", None + PackageName "xUnit", VersionRequirement.Parse "2.0", None ] } + + let doc = NupkgWriter.nuspecDoc (core, optional) + doc.ToString() + |> normalizeLineEndings + |> shouldEqual (normalizeLineEndings result) + + +[] +let ``#913 should serialize dependencies by group``() = + let result = """ + + Paket.Tests + 1.0.0.0 + Two, Authors + A description + f# rules + + + + + + + +""" + + let core : CompleteCoreInfo = + { Id = "Paket.Tests" + Version = SemVer.Parse "1.0.0.0" |> Some + Authors = [ "Two"; "Authors" ] + Description = "A description" + Symbols = false } + + let optional = + { OptionalPackagingInfo.Epmty with + Tags = [ "f#"; "rules" ] + Dependencies = + [ PackageName "Paket.Core", VersionRequirement.Parse "[3.1]", Some(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5)) + PackageName "xUnit", VersionRequirement.Parse "2.0", Some(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5)) ] } + + let doc = NupkgWriter.nuspecDoc (core, optional) + doc.ToString() + |> normalizeLineEndings + |> shouldEqual (normalizeLineEndings result) + +[] +let ``#913 should serialize dependencies by group with 2 group``() = + let result = """ + + Paket.Tests + 1.0.0.0 + Two, Authors + A description + f# rules + + + + + + + + + + + +""" + + let core : CompleteCoreInfo = + { Id = "Paket.Tests" + Version = SemVer.Parse "1.0.0.0" |> Some + Authors = [ "Two"; "Authors" ] + Description = "A description" + Symbols = false } + + let optional = + { OptionalPackagingInfo.Epmty with + Tags = [ "f#"; "rules" ] + Dependencies = + [ PackageName "Paket.Core", VersionRequirement.Parse "[3.1]", Some(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5)) + PackageName "xUnit", VersionRequirement.Parse "2.0", Some(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5)) + PackageName "Paket.Core", VersionRequirement.Parse "[3.1]", Some(FrameworkIdentifier.DotNetStandard(DotNetStandardVersion.V1_3)) + PackageName "xUnit", VersionRequirement.Parse "2.0", Some(FrameworkIdentifier.DotNetStandard(DotNetStandardVersion.V1_3)) ] } let doc = NupkgWriter.nuspecDoc (core, optional) doc.ToString() diff --git a/tests/Paket.Tests/Packaging/TemplateFileParsing.fs b/tests/Paket.Tests/Packaging/TemplateFileParsing.fs index c9195eec1b..e3f0161c38 100644 --- a/tests/Paket.Tests/Packaging/TemplateFileParsing.fs +++ b/tests/Paket.Tests/Packaging/TemplateFileParsing.fs @@ -202,7 +202,7 @@ let ``Optional fields are read`` (fileContent : string) = sut.RequireLicenseAcceptance |> shouldEqual false sut.DevelopmentDependency |> shouldEqual false sut.Language |> shouldEqual (Some "en-gb") - sut.Dependencies |> shouldContain (PackageName "FSharp.Core",VersionRequirement.Parse("[4.3.1]")) + sut.Dependencies |> shouldContain (PackageName "FSharp.Core",VersionRequirement.Parse("[4.3.1]"), None) sut.ExcludedDependencies |> shouldContain (PackageName "Newtonsoft.Json") sut.ExcludedDependencies |> shouldContain (PackageName "Chessie") sut.ExcludedGroups |> shouldContain (GroupName "build") @@ -230,13 +230,50 @@ let ``Detect dependencies correctly`` fileContent = | CompleteInfo (_, opt) | ProjectInfo (_, opt) -> opt match sut.Dependencies with - | [name1,range1;name2,range2] -> + | [name1,range1,framework1;name2,range2,framework2] -> name1 |> shouldEqual (PackageName "FSharp.Core") range1.Range |> shouldEqual (Specific (SemVer.Parse "4.3.1")) name2 |> shouldEqual (PackageName "My.OtherThing") range2.Range |> shouldEqual (Minimum (SemVer.Parse "0")) | _ -> Assert.Fail() +[] +let ``Detect dependencies with targetFramework correctly`` () = + let fileContent = """type file +id My.Thing +authors Bob McBob +description + A longer description + on two lines. +version + 1.0 +dependencies + framework: net45 + FSharp.Core 4.3.1 + My.OtherThing + framework: netstandard11 + FSharp.Core 4.3.1 +""" + + let sut = + TemplateFile.Parse("file1.template", LockFile.Parse("",[||]), None, Map.empty, strToStream fileContent) + |> returnOrFail + |> function + | CompleteInfo (_, opt) + | ProjectInfo (_, opt) -> opt + match sut.Dependencies with + | [name1,range1,framework1;name2,range2,framework2;name3,range3,framework3] -> + name1 |> shouldEqual (PackageName "FSharp.Core") + range1.Range |> shouldEqual (Specific (SemVer.Parse "4.3.1")) + framework1 |> shouldEqual (Some(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_5))) + name2 |> shouldEqual (PackageName "My.OtherThing") + range2.Range |> shouldEqual (Minimum (SemVer.Parse "0")) + framework2 |> shouldEqual (Some(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_5))) + name3 |> shouldEqual (PackageName "FSharp.Core") + range3.Range |> shouldEqual (Specific (SemVer.Parse "4.3.1")) + framework3 |> shouldEqual (Some(FrameworkIdentifier.DotNetStandard(DotNetStandardVersion.V1_1))) + | _ -> Assert.Fail() + [] let ``Detect dependencies with CURRENTVERSION correctly`` () = @@ -260,7 +297,7 @@ dependencies | CompleteInfo (_, opt) | ProjectInfo (_, opt) -> opt match sut.Dependencies with - | [name1,range1;name2,range2] -> + | [name1,range1,_;name2,range2,_] -> name1 |> shouldEqual (PackageName "FSharp.Core") range1.Range |> shouldEqual (Specific (SemVer.Parse "4.3.1")) name2 |> shouldEqual (PackageName "My.OtherThing") @@ -296,7 +333,7 @@ dependencies version |> shouldEqual (Some specificVersion) match sut.Dependencies with - | [name1,range1;name2,range2;name3,range3] -> + | [name1,range1,_;name2,range2,_;name3,range3,_] -> name1 |> shouldEqual (PackageName "FSharp.Core") range1.Range |> shouldEqual (Specific (SemVer.Parse "4.3.1")) name2 |> shouldEqual (PackageName "Project.A") @@ -367,7 +404,7 @@ GITHUB | CompleteInfo (_, opt) | ProjectInfo (_, opt) -> opt match sut.Dependencies with - | [name1,range1;name2,range2] -> + | [name1,range1,_;name2,range2,_] -> name1 |> shouldEqual (PackageName "FSharp.Core") range1.Range |> shouldEqual (Specific (SemVer.Parse "4.3.1")) name2 |> shouldEqual (PackageName "My.OtherThing") From bdfeef417dddebfcb4a07776dc5ccfab6ecdd793 Mon Sep 17 00:00:00 2001 From: Benjamin Hugot Date: Fri, 16 Jun 2017 11:47:41 +0200 Subject: [PATCH 2/4] clean up a bit --- src/Paket.Core/Packaging/NupkgWriter.fs | 16 ++++++---------- src/Paket.Core/Packaging/PackageMetaData.fs | 3 ++- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Paket.Core/Packaging/NupkgWriter.fs b/src/Paket.Core/Packaging/NupkgWriter.fs index fea89b1090..d609514be1 100644 --- a/src/Paket.Core/Packaging/NupkgWriter.fs +++ b/src/Paket.Core/Packaging/NupkgWriter.fs @@ -94,11 +94,6 @@ module internal NupkgWriter = dep.SetAttributeValue(XName.Get "version", version) dep - let last3(_,_,c) = c; - let last2(_,b) = b; - let fst3 (a, _, _) = a - let second (a, b, _) = (a,b) - let buildGroupNode (framework:FrameworkIdentifier, add) = let g = XElement(ns + "group") g.SetAttributeValue(XName.Get "targetFramework", framework.ToString()) @@ -107,9 +102,11 @@ module internal NupkgWriter = let buildDependencyNodes (excludedDependencies, add, dependencyList) = + let takeFirstOfThree (a,_,_) = a + let takeFirstTwoOfThree (a,b,_) = a,b dependencyList - |> List.filter (fun d -> Set.contains (fst3 d) excludedDependencies |> not) - |> List.map second + |> List.filter (fun d -> Set.contains (takeFirstOfThree d) excludedDependencies |> not) + |> List.map takeFirstTwoOfThree |> List.iter (buildDependencyNode >> add) let buildDependencyNodesByGroup excludedDependencies add dependencyList framework = @@ -119,13 +116,12 @@ module internal NupkgWriter = let buildDependenciesNode excludedDependencies dependencyList = if List.isEmpty dependencyList then () else let d = XElement(ns + "dependencies") - - let groups = List.groupBy last3 dependencyList + let groups = List.groupBy thirdOf3 dependencyList if groups.Length = 1 && fst groups.Head = None then buildDependencyNodes(excludedDependencies, d.Add, dependencyList) else groups - |> List.iter (fun a -> buildDependencyNodesByGroup excludedDependencies d.Add (last2 a) (fst a).Value) + |> List.iter (fun a -> buildDependencyNodesByGroup excludedDependencies d.Add (snd a) (fst a).Value) metadataNode.Add d let buildReferenceNode (fileName) = diff --git a/src/Paket.Core/Packaging/PackageMetaData.fs b/src/Paket.Core/Packaging/PackageMetaData.fs index 2c17e65992..7bd7bf820e 100644 --- a/src/Paket.Core/Packaging/PackageMetaData.fs +++ b/src/Paket.Core/Packaging/PackageMetaData.fs @@ -107,11 +107,12 @@ let (|Valid|Invalid|) md = Symbols = s } | _ -> Invalid -let firstOf3 (a, _, _) = a + let addDependency (templateFile : TemplateFile) (dependency : PackageName * VersionRequirement * FrameworkIdentifier option) = match templateFile with | CompleteTemplate(core, opt) -> + let firstOf3 (a, _, _) = a let newDeps = match opt.Dependencies |> List.tryFind (fun (n,_,_) -> n = firstOf3 dependency) with | None -> dependency :: opt.Dependencies From 86e5e3a1a816e566cf84a11508d91eb3b1fdca89 Mon Sep 17 00:00:00 2001 From: bhugot Date: Sun, 18 Jun 2017 14:40:40 +0200 Subject: [PATCH 3/4] Refactoring --- src/Paket.Core/Packaging/NupkgWriter.fs | 15 +++++++-------- src/Paket.Core/Packaging/PackageMetaData.fs | 4 ++-- src/Paket.Core/PaketConfigFiles/TemplateFile.fs | 4 ++-- src/Paket.Core/Versioning/FrameworkHandling.fs | 1 + 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Paket.Core/Packaging/NupkgWriter.fs b/src/Paket.Core/Packaging/NupkgWriter.fs index d609514be1..e89675a2e8 100644 --- a/src/Paket.Core/Packaging/NupkgWriter.fs +++ b/src/Paket.Core/Packaging/NupkgWriter.fs @@ -84,9 +84,9 @@ module internal NupkgWriter = frameworkAssembliesList |> List.iter (buildFrameworkReferencesNode >> d.Add) metadataNode.Add d - let buildDependencyNode (id, requirement:VersionRequirement) = + let buildDependencyNode (Id, requirement:VersionRequirement) = let dep = XElement(ns + "dependency") - dep.SetAttributeValue(XName.Get "id", id) + dep.SetAttributeValue(XName.Get "id", Id) let version = requirement.FormatInNuGetSyntax() if String.IsNullOrEmpty version then dep.SetAttributeValue(XName.Get "version", "0.0") @@ -102,11 +102,9 @@ module internal NupkgWriter = let buildDependencyNodes (excludedDependencies, add, dependencyList) = - let takeFirstOfThree (a,_,_) = a - let takeFirstTwoOfThree (a,b,_) = a,b dependencyList - |> List.filter (fun d -> Set.contains (takeFirstOfThree d) excludedDependencies |> not) - |> List.map takeFirstTwoOfThree + |> List.filter (fun (a, _, _) -> Set.contains a excludedDependencies |> not) + |> List.map (fun (a,b,_) -> a,b) |> List.iter (buildDependencyNode >> add) let buildDependencyNodesByGroup excludedDependencies add dependencyList framework = @@ -117,9 +115,10 @@ module internal NupkgWriter = if List.isEmpty dependencyList then () else let d = XElement(ns + "dependencies") let groups = List.groupBy thirdOf3 dependencyList - if groups.Length = 1 && fst groups.Head = None then + match groups.Length, fst groups.Head with + | (1, None) -> buildDependencyNodes(excludedDependencies, d.Add, dependencyList) - else + | _ -> groups |> List.iter (fun a -> buildDependencyNodesByGroup excludedDependencies d.Add (snd a) (fst a).Value) metadataNode.Add d diff --git a/src/Paket.Core/Packaging/PackageMetaData.fs b/src/Paket.Core/Packaging/PackageMetaData.fs index 7bd7bf820e..d0672ab494 100644 --- a/src/Paket.Core/Packaging/PackageMetaData.fs +++ b/src/Paket.Core/Packaging/PackageMetaData.fs @@ -112,9 +112,9 @@ let (|Valid|Invalid|) md = let addDependency (templateFile : TemplateFile) (dependency : PackageName * VersionRequirement * FrameworkIdentifier option) = match templateFile with | CompleteTemplate(core, opt) -> - let firstOf3 (a, _, _) = a + let packageName = dependency |> (fun (n,_,_) -> n) let newDeps = - match opt.Dependencies |> List.tryFind (fun (n,_,_) -> n = firstOf3 dependency) with + match opt.Dependencies |> List.tryFind (fun (n,_,_) -> n = packageName) with | None -> dependency :: opt.Dependencies | _ -> opt.Dependencies { FileName = templateFile.FileName diff --git a/src/Paket.Core/PaketConfigFiles/TemplateFile.fs b/src/Paket.Core/PaketConfigFiles/TemplateFile.fs index d4d6c6e49e..ac30d55aa7 100644 --- a/src/Paket.Core/PaketConfigFiles/TemplateFile.fs +++ b/src/Paket.Core/PaketConfigFiles/TemplateFile.fs @@ -280,7 +280,7 @@ module internal TemplateFile = static member ForNone = { Framework = None ; Dependencies = [] } static member ForFramework framework = { Framework = framework ; Dependencies = [] } - let private getDependencieByLine (fileName, lockFile:LockFile,currentVersion:SemVerInfo option, specificVersions:Map, line:string, framework:FrameworkIdentifier option)= + let private getDependencyByLine (fileName, lockFile:LockFile,currentVersion:SemVerInfo option, specificVersions:Map, line:string, framework:FrameworkIdentifier option)= let reg = Regex(@"(?\S+)(?.*)").Match line let name = PackageName reg.Groups.["id"].Value let versionRequirement = @@ -323,7 +323,7 @@ module internal TemplateFile = lineNo, group | Empty _ -> lineNo, current::other | _ -> - let dependency = getDependencieByLine(fileName, lockFile, currentVersion, specificVersions, line, current.Framework) + let dependency = getDependencyByLine(fileName, lockFile, currentVersion, specificVersions, line, current.Framework) lineNo ,{ current with Dependencies = current.Dependencies @ [dependency] }::other | [] -> failwithf "Error in paket.dependencies line %d" lineNo diff --git a/src/Paket.Core/Versioning/FrameworkHandling.fs b/src/Paket.Core/Versioning/FrameworkHandling.fs index 37d3288fc6..7ec1101686 100644 --- a/src/Paket.Core/Versioning/FrameworkHandling.fs +++ b/src/Paket.Core/Versioning/FrameworkHandling.fs @@ -439,6 +439,7 @@ module FrameworkDetection = open Logging /// parse a string to construct a Netframework, NetCore, NetStandard, or other dotnet identifier + [] let Extract = memoize (fun (path:string) -> From b6a742b397e82c3d04595645bac451004c2a4978 Mon Sep 17 00:00:00 2001 From: bhugot Date: Sun, 18 Jun 2017 15:40:29 +0200 Subject: [PATCH 4/4] Add documentation --- docs/content/template-files.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/content/template-files.md b/docs/content/template-files.md index cae85b41b8..2005e7fcc5 100644 --- a/docs/content/template-files.md +++ b/docs/content/template-files.md @@ -179,6 +179,17 @@ The `LOCKEDVERSION` placeholder allows to reference the currently used dependenc FSharp.Core >= 4.3.1 Other.Dep ~> LOCKEDVERSION +It's possible to add a line to constrain the targetFramework: + + dependencies + framework: net45 + FSharp.Core 4.3.1 + My.OtherThing + framework: netstandard11 + FSharp.Core 4.3.1 + +Like that the package is only going to be used by a project >= net45 and for >= netstandard11 it will not use My.OtherThing package. + In a project file, the following dependencies will be added: * any Paket dependency with the range specified in the [`paket.dependencies` file](dependencies-file.html).