From 6a0ebce349e99a9a4288f4b16fffc4a548526b7d Mon Sep 17 00:00:00 2001 From: Anthony Perez Date: Mon, 30 Nov 2015 19:11:43 +0000 Subject: [PATCH 1/4] Add buildPlatform param to ProjectFile.GetOutputDirectory Added it everywhere that the compiler complained about, and added a new `buildplatform` option to the `paket pack` command to supply the new value. --- src/Paket.Core/PackageMetaData.fs | 14 +++++++------- src/Paket.Core/PackageProcess.fs | 13 +++++++------ src/Paket.Core/ProjectFile.fs | 2 +- src/Paket.Core/PublicAPI.fs | 4 ++-- src/Paket/Commands.fs | 1 + src/Paket/Program.fs | 1 + tests/Paket.Tests/PackageProcessSpecs.fs | 2 +- tests/Paket.Tests/ProjectFile/OutputSpecs.fs | 2 +- 8 files changed, 21 insertions(+), 18 deletions(-) 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..275c28f31b 100644 --- a/src/Paket.Core/ProjectFile.fs +++ b/src/Paket.Core/ProjectFile.fs @@ -979,7 +979,7 @@ type ProjectFile = then "Compile" else "Content" - member this.GetOutputDirectory buildConfiguration = + member this.GetOutputDirectory buildConfiguration buildPlatform = let startingData = Map.empty.Add("Configuration", buildConfiguration) this.GetPropertyWithDefaults "OutputPath" startingData 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..27b68984a0 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 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) [] From 569408fc236436a1d6501480894031a9816ecfa0 Mon Sep 17 00:00:00 2001 From: Anthony Perez Date: Mon, 30 Nov 2015 19:18:04 +0000 Subject: [PATCH 2/4] Attempt specified platform(s) when getting project's output path If String.IsNullOrWhiteSpace returns true for the specified platform, then all of the platforms specified at the following MSDN article (as of now) are tested: https://msdn.microsoft.com/en-us/library/zekwfyz4.aspx If a platform is specified, that platform is tested. --- src/Paket.Core/ProjectFile.fs | 37 ++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/Paket.Core/ProjectFile.fs b/src/Paket.Core/ProjectFile.fs index 275c28f31b..4480d6a446 100644 --- a/src/Paket.Core/ProjectFile.fs +++ b/src/Paket.Core/ProjectFile.fs @@ -980,12 +980,39 @@ type ProjectFile = else "Content" member this.GetOutputDirectory buildConfiguration buildPlatform = - let startingData = Map.empty.Add("Configuration", buildConfiguration) + 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 = From cb65d7a867f569c6ef4121a8549626161de9aaf5 Mon Sep 17 00:00:00 2001 From: Anthony Perez Date: Mon, 30 Nov 2015 19:22:29 +0000 Subject: [PATCH 3/4] Add description for new `buildplatform` option on `paket pack` --- src/Paket/Commands.fs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Paket/Commands.fs b/src/Paket/Commands.fs index 27b68984a0..6321f7a340 100644 --- a/src/Paket/Commands.fs +++ b/src/Paket/Commands.fs @@ -303,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." From 1ce770f4c213b1c5054fe930d81542bb275e283c Mon Sep 17 00:00:00 2001 From: Anthony Perez Date: Tue, 1 Dec 2015 12:37:24 +0000 Subject: [PATCH 4/4] Add forgotten param to ProjectFile.GetOutputDirectory Forgot to specify an value when I added the `attempted` param to the `tryNextPlat` helper function. --- src/Paket.Core/ProjectFile.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Paket.Core/ProjectFile.fs b/src/Paket.Core/ProjectFile.fs index 4480d6a446..ffa2cd543a 100644 --- a/src/Paket.Core/ProjectFile.fs +++ b/src/Paket.Core/ProjectFile.fs @@ -1012,7 +1012,7 @@ type ProjectFile = 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 - tryNextPlat platforms + tryNextPlat platforms [] member this.GetAssemblyName () = let assemblyName =