diff --git a/src/Paket.Core/PackageMetaData.fs b/src/Paket.Core/PackageMetaData.fs index 74d4f79cac..5034fd2c23 100644 --- a/src/Paket.Core/PackageMetaData.fs +++ b/src/Paket.Core/PackageMetaData.fs @@ -84,10 +84,10 @@ let getDescription attributes = | Description d -> Some d | _ -> None) -let loadAssemblyId buildConfig (projectFile : ProjectFile) = +let loadAssemblyId buildConfig buildPlatform (projectFile : ProjectFile) = let fileName = Path.Combine - (Path.GetDirectoryName projectFile.FileName, projectFile.GetOutputDirectory buildConfig, + (Path.GetDirectoryName projectFile.FileName, projectFile.GetOutputDirectory buildConfig buildPlatform, projectFile.GetAssemblyName()) |> normalizePath traceVerbose <| sprintf "Loading assembly metadata for %s" fileName @@ -129,8 +129,8 @@ let addDependency (templateFile : TemplateFile) (dependency : PackageName * Vers | IncompleteTemplate -> failwith "You should only try and add dependencies to template files with complete metadata." -let toFile config (p : ProjectFile) = - Path.Combine(Path.GetDirectoryName p.FileName, p.GetOutputDirectory(config), p.GetAssemblyName()) +let toFile config platform (p : ProjectFile) = + Path.Combine(Path.GetDirectoryName p.FileName, p.GetOutputDirectory config platform, p.GetAssemblyName()) let addFile (source : string) (target : string) (templateFile : TemplateFile) = match templateFile with @@ -140,7 +140,7 @@ let addFile (source : string) (target : string) (templateFile : TemplateFile) = | IncompleteTemplate -> failwith "You should only try and add files to template files with complete metadata." -let findDependencies (dependencies : DependenciesFile) config (template : TemplateFile) (project : ProjectFile) lockDependencies (map : Map) = +let findDependencies (dependencies : DependenciesFile) config platform (template : TemplateFile) (project : ProjectFile) lockDependencies (map : Map) = let targetDir = match project.OutputType with | ProjectOutputType.Exe -> "tools/" @@ -163,7 +163,7 @@ let findDependencies (dependencies : DependenciesFile) config (template : Templa // Add the assembly + pdb + dll from this project let templateWithOutput = - let assemblyFileName = toFile config project + let assemblyFileName = toFile config platform project let fi = FileInfo(assemblyFileName) let name = Path.GetFileNameWithoutExtension fi.Name @@ -199,7 +199,7 @@ let findDependencies (dependencies : DependenciesFile) config (template : Templa // If project refs will not be packaged, add the assembly to the package let withDepsAndIncluded = files - |> List.fold (fun templatefile file -> addFile (toFile config file) targetDir templatefile) withDeps + |> List.fold (fun templatefile file -> addFile (toFile config platform file) targetDir templatefile) withDeps let lockFile = dependencies.FindLockfile().FullName diff --git a/src/Paket.Core/PackageProcess.fs b/src/Paket.Core/PackageProcess.fs index 859e6e6643..55c427c801 100644 --- a/src/Paket.Core/PackageProcess.fs +++ b/src/Paket.Core/PackageProcess.fs @@ -10,7 +10,7 @@ open System.Collections.Generic open Paket.PackageMetaData open Chessie.ErrorHandling -let private merge buildConfig version projectFile templateFile = +let private merge buildConfig buildPlatform version projectFile templateFile = let withVersion = match version with | None -> templateFile @@ -21,7 +21,7 @@ let private merge buildConfig version projectFile templateFile = match md with | Valid completeCore -> { templateFile with Contents = CompleteInfo(completeCore, opt) } | _ -> - let assembly,id,assemblyFileName = loadAssemblyId buildConfig projectFile + let assembly,id,assemblyFileName = loadAssemblyId buildConfig buildPlatform projectFile let md = { md with Id = md.Id ++ Some id } match md with @@ -53,8 +53,9 @@ let private merge buildConfig version projectFile templateFile = | Valid completeCore -> { templateFile with Contents = CompleteInfo(completeCore, opt) } | _ -> templateFile -let Pack(workingDir,dependencies : DependenciesFile, packageOutputPath, buildConfig, version, releaseNotes, templateFile, lockDependencies) = +let Pack(workingDir,dependencies : DependenciesFile, packageOutputPath, buildConfig, buildPlatform, version, releaseNotes, templateFile, lockDependencies) = let buildConfig = defaultArg buildConfig "Release" + let buildPlatform = defaultArg buildPlatform "" let packageOutputPath = if Path.IsPathRooted(packageOutputPath) then packageOutputPath else Path.Combine(workingDir,packageOutputPath) Utils.createDir packageOutputPath |> returnOrFail @@ -93,14 +94,14 @@ let Pack(workingDir,dependencies : DependenciesFile, packageOutputPath, buildCon |> Array.map (fun (projectFile,templateFile) -> allTemplateFiles.Remove(templateFile.FileName) |> ignore - let merged = merge buildConfig version projectFile templateFile + let merged = merge buildConfig buildPlatform version projectFile templateFile Path.GetFullPath projectFile.FileName |> normalizePath,(merged,projectFile)) |> Map.ofArray // add dependencies let allTemplates = projectTemplates - |> Map.map (fun _ (t, p) -> p,findDependencies dependencies buildConfig t p lockDependencies projectTemplates) + |> Map.map (fun _ (t, p) -> p,findDependencies dependencies buildConfig buildPlatform t p lockDependencies projectTemplates) |> Map.toList |> List.map (fun (_,(_,x)) -> x) |> List.append [for fileName in allTemplateFiles -> @@ -111,7 +112,7 @@ let Pack(workingDir,dependencies : DependenciesFile, packageOutputPath, buildCon let allProjectFiles = ProjectFile.FindAllProjects(fi.Directory.FullName) |> Array.toList match allProjectFiles with - | [ projectFile ] -> merge buildConfig version projectFile templateFile + | [ projectFile ] -> merge buildConfig buildPlatform version projectFile templateFile | [] -> failwithf "There was no project file found for template file %s" fileName | _ -> failwithf "There was more than one project file found for template file %s" fileName | _ -> templateFile ] diff --git a/src/Paket.Core/ProjectFile.fs b/src/Paket.Core/ProjectFile.fs index 206815a9f8..ffa2cd543a 100644 --- a/src/Paket.Core/ProjectFile.fs +++ b/src/Paket.Core/ProjectFile.fs @@ -979,13 +979,40 @@ type ProjectFile = then "Compile" else "Content" - member this.GetOutputDirectory buildConfiguration = - let startingData = Map.empty.Add("Configuration", buildConfiguration) + member this.GetOutputDirectory buildConfiguration buildPlatform = + let platforms = + if not <| String.IsNullOrWhiteSpace(buildPlatform) + then [buildPlatform] + else + [ + "AnyCPU"; + "AnyCPU32BitPreferred"; + "x86"; + "x64"; + "ARM"; + "Itanium"; + ] + + let rec tryNextPlat platforms attempted = + match platforms with + | [] -> + if String.IsNullOrWhiteSpace(buildPlatform) + then + failwithf "Unable to find %s output path node in file %s for any known platforms" buildConfiguration this.FileName + else + failwithf "Unable to find %s output path node in file %s targeting the %s platform" buildConfiguration this.FileName buildPlatform + | x::xs -> + let startingData = Map.ofList [("Configuration", buildConfiguration); ("Platform", x)] + this.GetPropertyWithDefaults "OutputPath" startingData + |> function + | None -> tryNextPlat xs (x::attempted) + | Some s -> + if String.IsNullOrWhiteSpace(buildPlatform) then + let tested = String.Join(", ", Array.ofList attempted) + traceWarnfn "No platform specified; found output path node for the %s platform after failing to find one for the following: %s" x tested + s.TrimEnd [|'\\'|] |> normalizePath - this.GetPropertyWithDefaults "OutputPath" startingData - |> function - | None -> failwithf "Unable to find %s output path node in file %s" buildConfiguration this.FileName - | Some s -> s.TrimEnd [|'\\'|] |> normalizePath + tryNextPlat platforms [] member this.GetAssemblyName () = let assemblyName = diff --git a/src/Paket.Core/PublicAPI.fs b/src/Paket.Core/PublicAPI.fs index e972c321df..960e58f421 100644 --- a/src/Paket.Core/PublicAPI.fs +++ b/src/Paket.Core/PublicAPI.fs @@ -456,11 +456,11 @@ type Dependencies(dependenciesFileName: string) = FindReferences.FindReferencesForPackage (GroupName group) (PackageName package) |> this.Process // Packs all paket.template files. - member this.Pack(outputPath, ?buildConfig, ?version, ?releaseNotes, ?templateFile, ?workingDir, ?lockDependencies) = + member this.Pack(outputPath, ?buildConfig, ?buildPlatform, ?version, ?releaseNotes, ?templateFile, ?workingDir, ?lockDependencies) = let dependenciesFile = DependenciesFile.ReadFromFile dependenciesFileName let workingDir = defaultArg workingDir (dependenciesFile.FileName |> Path.GetDirectoryName) let lockDependencies = defaultArg lockDependencies false - PackageProcess.Pack(workingDir, dependenciesFile, outputPath, buildConfig, version, releaseNotes, templateFile, lockDependencies) + PackageProcess.Pack(workingDir, dependenciesFile, outputPath, buildConfig, buildPlatform, version, releaseNotes, templateFile, lockDependencies) /// Pushes a nupkg file. static member Push(packageFileName, ?url, ?apiKey, (?endPoint: string), ?maxTrials) = diff --git a/src/Paket/Commands.fs b/src/Paket/Commands.fs index a10451dcc6..6321f7a340 100644 --- a/src/Paket/Commands.fs +++ b/src/Paket/Commands.fs @@ -292,6 +292,7 @@ with type PackArgs = | [][] Output of string | [] BuildConfig of string + | [] BuildPlatform of string | [] Version of string | [] TemplateFile of string | [] ReleaseNotes of string @@ -302,6 +303,7 @@ with match this with | Output(_) -> "Output directory to put .nupkg files." | BuildConfig(_) -> "Optionally specify build configuration that should be packaged (defaults to Release)." + | BuildPlatform(_) -> "Optionally specify build platform that should be packaged (if not provided or empty, checks all known platform targets)." | Version(_) -> "Specify version of the package." | TemplateFile(_) -> "Allows to specify a single template file." | ReleaseNotes(_) -> "Specify relase notes for the package." diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index 16b1ac9e6d..ab494932d9 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -215,6 +215,7 @@ let pack (results : ParseResults<_>) = Dependencies.Locate() .Pack(outputPath, ?buildConfig = results.TryGetResult <@ PackArgs.BuildConfig @>, + ?buildPlatform = results.TryGetResult <@ PackArgs.BuildPlatform @>, ?version = results.TryGetResult <@ PackArgs.Version @>, ?releaseNotes = results.TryGetResult <@ PackArgs.ReleaseNotes @>, ?templateFile = results.TryGetResult <@ PackArgs.TemplateFile @>, diff --git a/tests/Paket.Tests/PackageProcessSpecs.fs b/tests/Paket.Tests/PackageProcessSpecs.fs index ffb1eaf84a..dbc54b4a70 100644 --- a/tests/Paket.Tests/PackageProcessSpecs.fs +++ b/tests/Paket.Tests/PackageProcessSpecs.fs @@ -48,7 +48,7 @@ let ``Loading assembly metadata works``() = if workingDir.Contains "Debug" then "Debug" else "Release" - let assembly,id,fileName = PackageMetaData.loadAssemblyId config projFile + let assembly,id,fileName = PackageMetaData.loadAssemblyId config "" projFile id |> shouldEqual "Paket.Tests" let attribs = PackageMetaData.loadAssemblyAttributes fileName assembly diff --git a/tests/Paket.Tests/ProjectFile/OutputSpecs.fs b/tests/Paket.Tests/ProjectFile/OutputSpecs.fs index ca60736cfb..5fbcecc82d 100644 --- a/tests/Paket.Tests/ProjectFile/OutputSpecs.fs +++ b/tests/Paket.Tests/ProjectFile/OutputSpecs.fs @@ -35,7 +35,7 @@ let ``should detect target framework for Project2 proj file``() = let ``should detect output path for proj file`` ([] project) ([] configuration) = - ProjectFile.TryLoad(sprintf "./ProjectFile/TestData/%s.fsprojtest" project).Value.GetOutputDirectory configuration + ProjectFile.TryLoad(sprintf "./ProjectFile/TestData/%s.fsprojtest" project).Value.GetOutputDirectory configuration "" |> shouldEqual (System.IO.Path.Combine(@"bin", configuration) |> normalizePath) []