Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Make Paket runtimes aware
  • Loading branch information
forki committed Apr 19, 2016
commit f8d2805b8309a192152dd9bc44f3c9b1a4e66bbd
16 changes: 15 additions & 1 deletion src/Paket.Core/FrameworkHandling.fs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ type FrameworkIdentifier =
| MonoTouch
| MonoMac
| Native of string * string
| Runtimes of string
| XamariniOS
| XamarinMac
| Windows of string
Expand All @@ -130,6 +131,7 @@ type FrameworkIdentifier =
| MonoTouch -> "monotouch"
| MonoMac -> "monomac"
| Native(_) -> "native"
| Runtimes(_) -> "runtimes"
| XamariniOS -> "xamarinios"
| XamarinMac -> "xamarinmac"
| Windows v -> "win" + v
Expand All @@ -145,6 +147,7 @@ type FrameworkIdentifier =
| MonoTouch -> [ ]
| MonoMac -> [ ]
| Native(_) -> [ ]
| Runtimes(_) -> [ ]
| XamariniOS -> [ ]
| XamarinMac -> [ ]
| DotNetFramework FrameworkVersion.V1 -> [ ]
Expand Down Expand Up @@ -196,6 +199,7 @@ type FrameworkIdentifier =
| DNXCore _, DNXCore _ -> true
| MonoAndroid _, MonoAndroid _ -> true
| MonoMac _, MonoMac _ -> true
| Runtimes _, Runtimes _ -> true
| MonoTouch _, MonoTouch _ -> true
| Windows _, Windows _ -> true
| WindowsPhoneApp _, WindowsPhoneApp _ -> true
Expand Down Expand Up @@ -247,6 +251,9 @@ module FrameworkDetection =
| "native/arm/release" -> Some(Native("Release","arm"))
| "native/address-model-32" -> Some(Native("","Win32"))
| "native/address-model-64" -> Some(Native("","x64"))
| x when x.StartsWith "runtimes/" -> Some(Runtimes(x.Substring(9)))
| "runtimes/win7-x86" -> Some(Runtimes("Win32"))
| "runtimes/win7-arm" -> Some(Runtimes("arm"))
| "native" -> Some(Native("",""))
| "sl" | "sl3" | "sl30" -> Some (Silverlight "v3.0")
| "sl4" | "sl40" -> Some (Silverlight "v4.0")
Expand Down Expand Up @@ -453,7 +460,14 @@ module KnownTargetProfiles =
Native("Release","x64")
Native("Release","arm")]

let AllProfiles = (AllNativeProfiles |> List.map (fun p -> SinglePlatform p)) @ AllDotNetProfiles
let AllRuntimes =
[ Runtimes("win7-x64")
Runtimes("win7-x86")
Runtimes("win7-arm")
Runtimes("debian-x64")
Runtimes("osx") ]

let AllProfiles = (AllNativeProfiles |> List.map (fun p -> SinglePlatform p)) @ (AllRuntimes |> List.map (fun p -> SinglePlatform p)) @ AllDotNetProfiles

let FindPortableProfile name =
AllProfiles
Expand Down
7 changes: 5 additions & 2 deletions src/Paket.Core/InstallModel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ module InstallModel =
TargetsFileFolders = []
Analyzers = [] }

let extractLibFolder path = Utils.extractPath ("lib", path)
let extractLibFolder path =
match Utils.extractPath ("lib", path) with
| None when path.Contains "runtimes" -> Utils.extractPath ("runtimes", path)
| x -> x

let extractBuildFolder path = Utils.extractPath ("build", path)

Expand Down Expand Up @@ -184,7 +187,7 @@ module InstallModel =
this

let calcLibFolders libs =
libs
libs
|> Seq.choose extractLibFolder
|> Seq.distinct
|> PlatformMatching.getSupportedTargetProfiles
Expand Down
5 changes: 4 additions & 1 deletion src/Paket.Core/NuGetV2.fs
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,10 @@ let private getFiles targetFolder subFolderName filesDescriptionForVerbose =
files

/// Finds all libraries in a nuget package.
let GetLibFiles(targetFolder) = getFiles targetFolder "lib" "libraries"
let GetLibFiles(targetFolder) =
let libs = getFiles targetFolder "lib" "libraries"
let runtimeLibs = getFiles targetFolder "runtimes" "libraries"
Array.append libs runtimeLibs

/// Finds all targets files in a nuget package.
let GetTargetsFiles(targetFolder) = getFiles targetFolder "build" ".targets files"
Expand Down
16 changes: 10 additions & 6 deletions src/Paket.Core/PlatformMatching.fs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ let getTargetCondition (target:TargetProfile) =
| XamarinMac -> "$(TargetFrameworkIdentifier) == 'Xamarin.Mac'", ""
| Native("","") -> "true", ""
| Native("",bits) -> (sprintf "'$(Platform)'=='%s'" bits), ""
| Runtimes(platform) -> failwithf "Runtime dependencies are unsupported in project files."
| Native(profile,bits) -> (sprintf "'$(Configuration)|$(Platform)'=='%s|%s'" profile bits), ""
| PortableProfile(name, _) -> sprintf "$(TargetFrameworkProfile) == '%O'" name,""

Expand All @@ -181,14 +182,17 @@ let getCondition (referenceCondition:string option) (targets : TargetProfile lis
|> CheckIfFullyInGroup "WindowsPhoneApp" (fun x -> match x with | SinglePlatform(WindowsPhoneApp(_)) -> true | _ -> false)
|> CheckIfFullyInGroup "WindowsPhone" (fun x -> match x with | SinglePlatform(WindowsPhoneSilverlight(_)) -> true | _ -> false)

let conditions =
if targets = [SinglePlatform(Native("",""))] then
targets
else
let conditions =
if targets = [ SinglePlatform(Native("", "")) ] then
targets
|> List.filter (fun x -> match x with | SinglePlatform(Native("","")) -> false | _ -> true )
else
targets
|> List.filter (function
| SinglePlatform(Native("", "")) -> false
| SinglePlatform(Runtimes(_)) -> false
| _ -> true)
|> List.map getTargetCondition
|> List.filter (fun (_,v) -> v <> "false")
|> List.filter (fun (_, v) -> v <> "false")
|> List.append grouped
|> List.groupBy fst

Expand Down
5 changes: 4 additions & 1 deletion src/Paket.Core/ProjectFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,10 @@ module ProjectFile =

let conditions =
model.ReferenceFileFolders
|> List.map (fun lib -> PlatformMatching.getCondition referenceCondition lib.Targets,createItemGroup lib.Files.References)
|> List.choose (fun lib ->
match lib with
| x when (match x.Targets with | [SinglePlatform(Runtimes(_))] -> true | _ -> false) -> None // TODO: Add reference to custom task instead
| _ -> Some (PlatformMatching.getCondition referenceCondition lib.Targets,createItemGroup lib.Files.References))
|> List.sortBy fst

let targetsFileConditions =
Expand Down
25 changes: 15 additions & 10 deletions src/Paket.Core/PublicAPI.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ open Chessie.ErrorHandling

/// Paket API which is optimized for F# Interactive use.
type Dependencies(dependenciesFileName: string) =
let getLockFile() =
let lockFileName = DependenciesFile.FindLockfile dependenciesFileName
LockFile.LoadFrom(lockFileName.FullName)

let listPackages (packages: System.Collections.Generic.KeyValuePair<GroupName*PackageName, PackageResolver.ResolvedPackage> seq) =
packages
Expand All @@ -34,6 +31,14 @@ type Dependencies(dependenciesFileName: string) =
/// Tries to locate the paket.dependencies file in the current folder or a parent folder.
static member Locate(): Dependencies = Dependencies.Locate(Environment.CurrentDirectory)

/// Returns an instance of the paket.lock file.
member this.GetLockFile() =
let lockFileName = DependenciesFile.FindLockfile dependenciesFileName
LockFile.LoadFrom(lockFileName.FullName)

/// Returns an instance of the paket.dependencies file.
member this.GetDependenciesFile() = DependenciesFile.ReadFromFile dependenciesFileName

/// Tries to locate the paket.dependencies file in the given folder or a parent folder.
static member Locate(path: string): Dependencies =
let rec findInPath(dir:DirectoryInfo,withError) =
Expand Down Expand Up @@ -311,15 +316,15 @@ type Dependencies(dependenciesFileName: string) =
| None -> Constants.MainDependencyGroup
| Some name -> GroupName name

match getLockFile().Groups |> Map.tryFind groupName with
match this.GetLockFile().Groups |> Map.tryFind groupName with
| None -> None
| Some group ->
group.Resolution.TryFind(PackageName packageName)
|> Option.map (fun package -> package.Version.ToString())

/// Returns the installed versions of all installed packages.
member this.GetInstalledPackages(): (string * string * string) list =
getLockFile().GetGroupedResolution()
this.GetLockFile().GetGroupedResolution()
|> listPackages

/// Returns all sources from the dependencies file.
Expand All @@ -340,7 +345,7 @@ type Dependencies(dependenciesFileName: string) =

/// Returns the installed versions of all installed packages which are referenced in the references file.
member this.GetInstalledPackages(referencesFile:ReferencesFile): (string * string * string) list =
let lockFile = getLockFile()
let lockFile = this.GetLockFile()
let resolved = lockFile.GetGroupedResolution()
referencesFile
|> lockFile.GetPackageHull
Expand Down Expand Up @@ -386,7 +391,7 @@ type Dependencies(dependenciesFileName: string) =
|> Seq.map (fun kv -> kv.Value.NugetPackages |> List.map (fun p -> kv.Key, p.Name))
|> List.concat

getLockFile().GetGroupedResolution()
this.GetLockFile().GetGroupedResolution()
|> Seq.filter (fun kv -> normalizedDependendenciesFromRefFile |> Seq.exists ((=) kv.Key))
|> Seq.filter (fun kv -> normalizedDependencies |> Seq.exists ((=) kv.Key))
|> listPackages
Expand All @@ -399,7 +404,7 @@ type Dependencies(dependenciesFileName: string) =
|> Seq.map (fun kv -> dependenciesFile.GetDependenciesInGroup(kv.Value.Name) |> Seq.map (fun kv' -> kv.Key, kv'.Key) |> Seq.toList)
|> List.concat

getLockFile().GetGroupedResolution()
this.GetLockFile().GetGroupedResolution()
|> Seq.filter (fun kv -> normalizedDependencies |> Seq.exists ((=) kv.Key))
|> listPackages

Expand All @@ -412,7 +417,7 @@ type Dependencies(dependenciesFileName: string) =

/// Returns the direct dependencies for the given package.
member this.GetDirectDependenciesForPackage(groupName,packageName:string): (string * string * string) list =
let resolvedPackages = getLockFile().GetGroupedResolution()
let resolvedPackages = this.GetLockFile().GetGroupedResolution()
let package = resolvedPackages.[groupName, (PackageName packageName)]
let normalizedDependencies = package.Dependencies |> Seq.map (fun (name,_,_) -> groupName, name) |> Seq.toList

Expand Down Expand Up @@ -560,7 +565,7 @@ type Dependencies(dependenciesFileName: string) =

/// Lists all paket.template files in the current solution.
member this.ListTemplateFiles() : TemplateFile list =
let lockFile = getLockFile()
let lockFile = this.GetLockFile()
ProjectFile.FindAllProjects(this.RootPath)
|> Array.choose (fun proj -> ProjectFile.FindTemplatesFile(FileInfo(proj.FileName)))
|> Array.choose (fun path ->
Expand Down
21 changes: 16 additions & 5 deletions src/Paket.Core/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ let inline createRelativePath root path =
uri.MakeRelativeUri(Uri path).ToString().Replace("/", "\\").Replace("%20", " ")

let getNative (path:string) =
if path.Contains "native" |> not then "" else
if path.Contains "/x86/debug" then "x86/debug" else
if path.Contains "/x86/release" then "/x86/release" else
if path.Contains "/arm/debug" then "/arm/debug" else
Expand All @@ -145,28 +146,38 @@ let getNative (path:string) =
if path.Contains "/x64/release" then "/x64/release" else
if path.Contains "/address-model-32" then "/address-model-32" else
if path.Contains "/address-model-64" then "/address-model-64" else
if path.Contains "/win7-x64" then "/win7-x64" else
if path.Contains "/win7-x86" then "/win7-x86" else
if path.Contains "/win7-arm" then "/win7-arm" else
if path.Contains "/debian-x64" then "/debian-x64" else
if path.Contains "/osx" then "/osx" else
""

let extractPath =
memoize <| fun (infix, fileName : string) ->
let path = fileName.Replace("\\", "/").ToLower()
let path = if path.StartsWith "lib/" then "/" + path else path
let needle = sprintf "/%s/" infix
if path.Contains needle |> not then None else
let fi = FileInfo path

let packagesPos = path.LastIndexOf "packages/"
let startPos =
if packagesPos >= 0 then
path.IndexOf(sprintf "/%s/" infix,packagesPos) + 1
path.IndexOf(needle,packagesPos) + 1
else
path.LastIndexOf(sprintf "/%s/" infix) + 1
path.LastIndexOf(needle) + 1

let endPos = path.IndexOf('/', startPos + infix.Length + 1)
if startPos < 0 then None
elif endPos < 0 then Some("")
else
let nativePart = getNative path
let libPart = path.Substring(startPos + infix.Length + 1, endPos - startPos - infix.Length - 1)
Some (libPart + nativePart)
if infix = "runtimes" then
Some("runtimes" + getNative path)
else
let nativePart = getNative path
let libPart = path.Substring(startPos + infix.Length + 1, endPos - startPos - infix.Length - 1)
Some (libPart + nativePart)

/// [omit]
let inline normalizeXml (doc:XmlDocument) =
Expand Down
4 changes: 4 additions & 0 deletions src/Paket/Paket.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,15 @@
<ItemGroup>
<Compile Include="AssemblyInfo.fs" />
<Compile Include="Commands.fs" />
<Compile Include="PlatformTask.fs" />
<Compile Include="Program.fs" />
<Content Include="App.config" />
<None Include="paket.references" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Build" />
<Reference Include="Microsoft.Build.Framework" />
<Reference Include="Microsoft.Build.Utilities.v4.0" />
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
80 changes: 80 additions & 0 deletions src/Paket/PlatformTask.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
namespace MSBuild.Tasks

open System
open System.IO
open Microsoft.Build.Utilities
open Microsoft.Build.Framework
open Paket
open Paket.Domain

type CopyRuntimeDependencies() =
inherit Task()

let mutable outputPath = ""
let mutable projectFile = ""
let mutable projectsWithRuntimeLibs = ""

[<Required>]
member this.OutputPath
with get() = outputPath
and set(v) = outputPath <- v

[<Required>]
member this.ProjectsWithRuntimeLibs
with get() = projectsWithRuntimeLibs
and set(v) = projectsWithRuntimeLibs <- v

member this.ProjectFile
with get() = outputPath
and set(v) = outputPath <- v

override this.Execute() =
let resultCode =
try
let currentRuntime = "win7-x64"
base.Log.LogMessage(MessageImportance.Normal, "Current runtime is {0}", currentRuntime)
let projectFile = FileInfo(if String.IsNullOrWhiteSpace this.ProjectFile then this.BuildEngine.ProjectFileOfTaskNode else this.ProjectFile)


let packagesToInstall =
projectsWithRuntimeLibs.Split([|';'|],StringSplitOptions.RemoveEmptyEntries)
|> Array.map (fun x ->
match x.Split('#') |> Array.toList with
| [name] -> Constants.MainDependencyGroup,PackageName (name.Trim())
| [group; name] -> GroupName (group.Trim()),PackageName (name.Trim())
| _ -> failwithf "Unknown package %s" x)

if Array.isEmpty packagesToInstall then true else

let referencesFile = ProjectFile.findReferencesFile projectFile

let dependencies = Dependencies.Locate projectFile.FullName
let lockFile = dependencies.GetLockFile()
let dependenciesFile = dependencies.GetDependenciesFile()

let root = Path.GetDirectoryName lockFile.FileName
let model = InstallProcess.CreateModel(root, false, dependenciesFile, lockFile, Set.ofSeq packagesToInstall) |> Map.ofArray
let projectDir = FileInfo(this.BuildEngine.ProjectFileOfTaskNode).Directory

for group,packageName in packagesToInstall do
match model |> Map.tryFind (group,packageName) with
| None -> failwithf "Package %O %O was not found in the install model" group packageName
| Some (package,model) ->
let files =
model.ReferenceFileFolders
|> List.choose (fun lib ->
match lib with
| x when (match x.Targets with | [SinglePlatform(Runtimes(x))] when x = currentRuntime -> true | _ -> false) -> Some lib.Files
| _ -> None)

for file in files do
for reference in file.References do
let sourceFile = FileInfo(reference.Path)
base.Log.LogMessage(MessageImportance.Normal, "Copying {0} to {1}", sourceFile, this.OutputPath)
let destFile = Path.Combine(this.OutputPath,sourceFile.Name)

File.Copy(sourceFile.FullName,destFile)
true
with
| _ as ex -> base.Log.LogErrorFromException(ex, false); false
resultCode
7 changes: 7 additions & 0 deletions tests/Paket.Tests/InstallModel/ProcessingSpecs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ let ``should understand lib in lib.dll``() =

model.GetLibReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) |> shouldContain @"..\FunScript.TypeScript\lib\net40\FunScript.TypeScript.Binding.lib.dll"

[<Test>]
let ``should understand libuv in runtimes``() =
let model = emptymodel.AddReferences [ @"..\Microsoft.AspNetCore.Server.Kestrel\runtimes\win7-x64\native\libuv.dll"; ]

model.GetLibReferences(SinglePlatform (Runtimes("win7-x64"))) |> shouldContain @"..\Microsoft.AspNetCore.Server.Kestrel\runtimes\win7-x64\native\libuv.dll"


[<Test>]
let ``should understand mylib in mylib.dll``() =
let model = emptymodel.AddReferences [ @"c:/users/username/workspace/myproject/packages/mylib.mylib/lib/net45/mylib.mylib.dll"; ]
Expand Down