Skip to content

Commit

Permalink
Use AssemblyReader from FSharp.Data
Browse files Browse the repository at this point in the history
  • Loading branch information
forki committed Dec 9, 2015
1 parent 798aeea commit 9d5b63e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 94 deletions.
104 changes: 38 additions & 66 deletions src/Paket.Core/PackageMetaData.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,55 +13,21 @@ let (|CompleteTemplate|IncompleteTemplate|) templateFile =
| { Contents = (CompleteInfo(core, optional)) } -> CompleteTemplate(core, optional)
| _ -> IncompleteTemplate

let (|Title|Description|Version|InformationalVersion|Company|Ignore|) (attribute : obj) =
match attribute with
| :? AssemblyTitleAttribute as title ->
match title.Title with
| x when String.IsNullOrWhiteSpace x ->
Ignore
| x ->
Title x
| :? AssemblyDescriptionAttribute as description ->
match description.Description with
| x when String.IsNullOrWhiteSpace x ->
Ignore
| x ->
Description x
| :? AssemblyVersionAttribute as version ->
match version.Version with
| x when String.IsNullOrWhiteSpace x ->
Ignore
| x -> Version(SemVer.Parse x)
| :? AssemblyInformationalVersionAttribute as version ->
match version.InformationalVersion with
| x when String.IsNullOrWhiteSpace x ->
Ignore
| x ->
try
InformationalVersion(SemVer.Parse x)
with
| _ -> Ignore
| :? System.Reflection.AssemblyCompanyAttribute as company ->
match company.Company with
| x when String.IsNullOrWhiteSpace x ->
Ignore
| x -> Company x
| :? System.Reflection.CustomAttributeData as attr ->
try
match attr.AttributeType.FullName with
| "System.Reflection.AssemblyCompanyAttribute" -> Company(attr.ConstructorArguments.Item(0).Value.ToString())
| "System.Reflection.AssemblyDescriptionAttribute" -> Description(attr.ConstructorArguments.Item(0).Value.ToString())
| "System.Reflection.AssemblyTitleAttribute" -> Title(attr.ConstructorArguments.Item(0).Value.ToString())
| "System.Reflection.AssemblyVersionAttribute" -> Version(attr.ConstructorArguments.Item(0).Value.ToString() |> SemVer.Parse)
| "System.Reflection.AssemblyInformationalVersionAttribute" -> InformationalVersion(attr.ConstructorArguments.Item(0).Value.ToString() |> SemVer.Parse)
| _ -> Ignore
with
let (|Title|Description|Version|InformationalVersion|Company|Ignore|) (attributeName:string,attributeValue:string) =
try
match attributeName with
| "AssemblyCompanyAttribute" -> Company(attributeValue)
| "AssemblyDescriptionAttribute" -> Description(attributeValue)
| "AssemblyTitleAttribute" -> Title(attributeValue)
| "AssemblyVersionAttribute" -> Version(attributeValue |> SemVer.Parse)
| "AssemblyInformationalVersionAttribute" -> InformationalVersion(attributeValue|> SemVer.Parse)
| _ -> Ignore
with
| _ -> Ignore

let getId (assembly : Assembly) (md : ProjectCoreInfo) = { md with Id = Some(assembly.GetName().Name) }

let getVersion (assembly : Assembly) attributes =
let getVersion versionFromAssembly attributes =
let informational =
attributes |> Seq.tryPick (function
| InformationalVersion v -> Some v
Expand All @@ -70,9 +36,9 @@ let getVersion (assembly : Assembly) attributes =
| Some v -> informational
| None ->
let fromAssembly =
match assembly.GetName().Version with
| null -> None
| v -> Some(SemVer.Parse(v.ToString()))
match versionFromAssembly with
| None -> None
| Some v -> Some(SemVer.Parse(v.ToString()))
match fromAssembly with
| Some v -> fromAssembly
| None ->
Expand Down Expand Up @@ -101,29 +67,35 @@ let getDescription attributes =
| Description d -> Some d
| _ -> None)

let loadAssemblyId buildConfig buildPlatform (projectFile : ProjectFile) =
let readAssembly buildConfig buildPlatform (projectFile : ProjectFile) =
let fileName =
Path.Combine
(Path.GetDirectoryName projectFile.FileName, projectFile.GetOutputDirectory buildConfig buildPlatform,
projectFile.GetAssemblyName()) |> normalizePath
FileInfo(
Path.Combine
(Path.GetDirectoryName projectFile.FileName, projectFile.GetOutputDirectory buildConfig buildPlatform,
projectFile.GetAssemblyName())
|> normalizePath)

traceVerbose <| sprintf "Loading assembly metadata for %s" fileName
let bytes = File.ReadAllBytes fileName
let assembly = Assembly.Load bytes
traceVerbose <| sprintf "Loading assembly metadata for %s" fileName.FullName
let assemblyReader =
ProviderImplementation.AssemblyReader.ILModuleReaderAfterReadingAllBytes(
fileName.FullName,
ProviderImplementation.AssemblyReader.mkILGlobals ProviderImplementation.AssemblyReader.ecmaMscorlibScopeRef,
true)

let versionFromAssembly = assemblyReader.ILModuleDef.ManifestOfAssembly.Version
let id = assemblyReader.ILModuleDef.ManifestOfAssembly.Name
assemblyReader,id,versionFromAssembly,fileName.FullName

assembly,assembly.GetName().Name,fileName
let loadAssemblyAttributes (assemblyReader:ProviderImplementation.AssemblyReader.CacheValue) =

let extractAttr (inp: ProviderImplementation.AssemblyReader.ILCustomAttr) =
let args = ProviderImplementation.AssemblyReader.decodeILCustomAttribData assemblyReader.ILGlobals inp

inp.Method.EnclosingType.BasicQualifiedName, Seq.head [ for (_,arg) in args -> arg.ToString() ]

[| for a in assemblyReader.ILModuleDef.ManifestOfAssembly.CustomAttrs.Elements do
yield extractAttr a |]

let loadAssemblyAttributes fileName (assembly:Assembly) =
try
assembly.GetCustomAttributesData()
with
| :? FileNotFoundException ->
// retrieving via path
let assembly = Assembly.LoadFrom fileName
assembly.GetCustomAttributesData()
| exn ->
traceWarnfn "Loading custom attributes failed for %s.%sMessage: %s" fileName Environment.NewLine exn.Message
assembly.GetCustomAttributesData()

let (|Valid|Invalid|) md =
match md with
Expand Down
6 changes: 3 additions & 3 deletions src/Paket.Core/PackageProcess.fs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ let private merge buildConfig buildPlatform version projectFile templateFile =

match withVersion with
| { Contents = ProjectInfo(md, opt) } ->
let assembly,id,assemblyFileName = loadAssemblyId buildConfig buildPlatform projectFile
let attribs = loadAssemblyAttributes assemblyFileName assembly
let assemblyReader,id,versionFromAssembly,assemblyFileName = readAssembly buildConfig buildPlatform projectFile
let attribs = loadAssemblyAttributes assemblyReader

let mergedOpt =
match opt.Title with
Expand All @@ -37,7 +37,7 @@ let private merge buildConfig buildPlatform version projectFile templateFile =

let merged =
{ Id = md.Id
Version = md.Version ++ getVersion assembly attribs
Version = md.Version ++ getVersion version attribs
Authors = md.Authors ++ getAuthors attribs
Description = md.Description ++ getDescription attribs
Symbols = md.Symbols }
Expand Down
28 changes: 3 additions & 25 deletions tests/Paket.Tests/PackageProcessSpecs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,6 @@ open Paket
open FsUnit
open NUnit.Framework

let assembly = Assembly.GetExecutingAssembly()

[<Test>]
let ``Loading description from assembly works``() =
let sut = PackageMetaData.getDescription (assembly.GetCustomAttributesData())
sut.Value |> shouldEqual "A description"

[<Test>]
let ``Loading version from assembly works``() =
let sut = PackageMetaData.getVersion assembly (assembly.GetCustomAttributesData())
sut.Value |> shouldEqual (SemVer.Parse "1.0.0.0")

[<Test>]
let ``Loading authors from assembly works with GetCustomAttributesData``() =
let sut = PackageMetaData.getAuthors (assembly.GetCustomAttributesData())
sut.Value |> shouldEqual [ "Two"; "Authors" ]

[<Test>]
let ``Loading id from assembly works``() =
let sut = PackageMetaData.getId assembly ProjectCoreInfo.Empty
sut.Id.Value |> shouldEqual "Paket.Tests"

[<Test>]
let ``Loading assembly metadata works``() =
let workingDir = Path.GetFullPath(".")
Expand All @@ -48,11 +26,11 @@ let ``Loading assembly metadata works``() =
if workingDir.Contains "Debug" then "Debug"
else "Release"

let assembly,id,fileName = PackageMetaData.loadAssemblyId config "" projFile
let assemblyReader,id,versionFromAssembly,fileName = PackageMetaData.readAssembly config "" projFile
id |> shouldEqual "Paket.Tests"

let attribs = PackageMetaData.loadAssemblyAttributes fileName assembly
PackageMetaData.getVersion assembly attribs |> shouldEqual <| Some(SemVer.Parse "1.0.0.0")
let attribs = PackageMetaData.loadAssemblyAttributes assemblyReader
PackageMetaData.getVersion versionFromAssembly attribs |> shouldEqual <| Some(SemVer.Parse "1.0.0.0")
let authors = PackageMetaData.getAuthors attribs
authors.Value |> shouldEqual ["Two"; "Authors" ]
PackageMetaData.getDescription attribs |> shouldEqual <| Some("A description")

0 comments on commit 9d5b63e

Please sign in to comment.