6 people like it.

Get Assemblies from NuGet

Given a NuGet package name, this code will download the package, extract it to a temp directory, and return a sequence of FileInfo objects representing assemblies from that package, with a preference for .NET 4.5 and 4.0 assemblies, if present. Requires the "DotNetZip" package.

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
#if INTERACTIVE
#r @"C:\SK\v9.2\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll"
#else
module FsSnip.NuGet
#endif

open System
open System.IO
open System.Net
open Ionic.Zip

let getPackageUrl = sprintf "http://packages.nuget.org/api/v1/package/%s/"

let getPackage name = async {
    let url = getPackageUrl name
    let req = WebRequest.Create(url)
    use! resp = req.AsyncGetResponse()
    use incoming = resp.GetResponseStream()
    
    // The response stream doesn't support Seek, and ZipFile needs it,
    // so read into a MemoryStream
    use ms = new MemoryStream()
    let buffer = Array.zeroCreate<byte> 0x1000
    let more = ref true
    while !more do
        let! read = incoming.AsyncRead(buffer, 0, buffer.Length)
        if read = 0 then
            more := false
        else
            ms.Write(buffer, 0, read)

    ms.Seek(0L, SeekOrigin.Begin) |> ignore
    use zip = ZipFile.Read(ms)
    let tempName = Path.GetTempFileName()
    File.Delete tempName // GetTempFileName creates a file, we want a folder
    let dir = Directory.CreateDirectory tempName
    zip.ExtractAll tempName
    return dir
}

let ensureDelete (dir:DirectoryInfo) =
    { new IDisposable with
        member x.Dispose() =
            dir.Delete(true) }

let findAssemblies (dir:DirectoryInfo) =
    let rec filterAssemblies (dir:DirectoryInfo) = seq {
        for item in dir.EnumerateFileSystemInfos() do
            match item with
            | :? DirectoryInfo as d ->
                match d.Name.ToLowerInvariant() with
                | "lib" | "net20" | "net35" | "net40" 
                | "net40-full" | "net40-client" | "net45" ->
                    yield! filterAssemblies d
                | _ -> ()
            | :? FileInfo as f ->
                if f.Extension = ".dll" then
                    yield f
            | _ -> ()
    }

    let getPlatform (f:FileInfo) =
        let idx = f.DirectoryName.LastIndexOf('\\')
        f.DirectoryName.[idx + 1 ..].ToLowerInvariant()

    let allAssemblies =
        filterAssemblies dir
        |> Seq.cache

    let platforms =
        allAssemblies
        |> Seq.map getPlatform
        |> Set.ofSeq

    let newestPlatforms =
        platforms
        |> Set.filter 
            (function
            | "lib" | "net45" -> true
            | "net20" -> 
                [ "net35"; "net40"; "net40-full"; "net40-client"; "net45" ] 
                |> Set.ofList 
                |> Set.intersect platforms 
                |> Set.isEmpty
            | "net35" ->
                [ "net40"; "net40-full"; "net40-client"; "net45" ] 
                |> Set.ofList 
                |> Set.intersect platforms 
                |> Set.isEmpty
            | "net40-client" ->
                [ "net40"; "net40-full"; "net45" ] 
                |> Set.ofList 
                |> Set.intersect platforms 
                |> Set.isEmpty
            | "net40" ->
                [ "net40-full"; "net45" ] 
                |> Set.ofList 
                |> Set.intersect platforms 
                |> Set.isEmpty
            | "net40-full" ->
                platforms.Contains "net45" |> not
            | _ -> false)

    allAssemblies
    |> Seq.filter (getPlatform >> newestPlatforms.Contains)

let printFiles name =
    printfn "Downloading %s..." name
    let packageDir =
        getPackage name
        |> Async.RunSynchronously

    use x = ensureDelete packageDir

    findAssemblies packageDir
    |> Seq.iter (fun f -> printfn "%s" f.FullName)

(*
printFiles "Castle.Core"
printFiles "DotNetZip"
printFiles "RavenDB.Client"
printFiles "xunit"
printFiles "AutoMapper"
printFiles "EntityFramework"
printFiles "Newtonsoft.Json"
*)
namespace System
namespace System.IO
namespace System.Net
namespace Ionic
namespace Ionic.Zip
val getPackageUrl : (string -> string)

Full name: Script.getPackageUrl
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val getPackage : name:string -> Async<DirectoryInfo>

Full name: Script.getPackage
val name : string
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
val url : string
val req : WebRequest
type WebRequest =
  inherit MarshalByRefObject
  member Abort : unit -> unit
  member AuthenticationLevel : AuthenticationLevel with get, set
  member BeginGetRequestStream : callback:AsyncCallback * state:obj -> IAsyncResult
  member BeginGetResponse : callback:AsyncCallback * state:obj -> IAsyncResult
  member CachePolicy : RequestCachePolicy with get, set
  member ConnectionGroupName : string with get, set
  member ContentLength : int64 with get, set
  member ContentType : string with get, set
  member Credentials : ICredentials with get, set
  member EndGetRequestStream : asyncResult:IAsyncResult -> Stream
  ...

Full name: System.Net.WebRequest
WebRequest.Create(requestUri: Uri) : WebRequest
WebRequest.Create(requestUriString: string) : WebRequest
val resp : WebResponse
member WebRequest.AsyncGetResponse : unit -> Async<WebResponse>
val incoming : Stream
WebResponse.GetResponseStream() : Stream
val ms : MemoryStream
Multiple items
type MemoryStream =
  inherit Stream
  new : unit -> MemoryStream + 6 overloads
  member CanRead : bool
  member CanSeek : bool
  member CanWrite : bool
  member Capacity : int with get, set
  member Flush : unit -> unit
  member GetBuffer : unit -> byte[]
  member Length : int64
  member Position : int64 with get, set
  member Read : buffer:byte[] * offset:int * count:int -> int
  ...

Full name: System.IO.MemoryStream

--------------------
MemoryStream() : unit
MemoryStream(capacity: int) : unit
MemoryStream(buffer: byte []) : unit
MemoryStream(buffer: byte [], writable: bool) : unit
MemoryStream(buffer: byte [], index: int, count: int) : unit
MemoryStream(buffer: byte [], index: int, count: int, writable: bool) : unit
MemoryStream(buffer: byte [], index: int, count: int, writable: bool, publiclyVisible: bool) : unit
val buffer : byte []
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...

Full name: System.Array
val zeroCreate : count:int -> 'T []

Full name: Microsoft.FSharp.Collections.Array.zeroCreate
Multiple items
val byte : value:'T -> byte (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.byte

--------------------
type byte = Byte

Full name: Microsoft.FSharp.Core.byte
val more : bool ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val read : int
member Stream.AsyncRead : count:int -> Async<byte []>
member Stream.AsyncRead : buffer:byte [] * ?offset:int * ?count:int -> Async<int>
property Array.Length: int
MemoryStream.Write(buffer: byte [], offset: int, count: int) : unit
MemoryStream.Seek(offset: int64, loc: SeekOrigin) : int64
type SeekOrigin =
  | Begin = 0
  | Current = 1
  | End = 2

Full name: System.IO.SeekOrigin
field SeekOrigin.Begin = 0
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val zip : ZipFile
Multiple items
type ZipFile =
  new : unit -> ZipFile + 5 overloads
  member AddDirectory : directoryName:string -> ZipEntry + 1 overload
  member AddDirectoryByName : directoryNameInArchive:string -> ZipEntry
  member AddDirectoryWillTraverseReparsePoints : bool with get, set
  member AddEntry : entryName:string * content:string -> ZipEntry + 5 overloads
  member AddFile : fileName:string -> ZipEntry + 1 overload
  member AddFiles : fileNames:IEnumerable<string> -> unit + 2 overloads
  member AddItem : fileOrDirectoryName:string -> ZipEntry + 1 overload
  member AddSelectedFiles : selectionCriteria:string -> unit + 5 overloads
  member AlternateEncoding : Encoding with get, set
  ...

Full name: Ionic.Zip.ZipFile

--------------------
ZipFile() : unit
ZipFile(fileName: string) : unit
ZipFile(encoding: Text.Encoding) : unit
ZipFile(fileName: string, encoding: Text.Encoding) : unit
ZipFile(fileName: string, statusMessageWriter: TextWriter) : unit
ZipFile(fileName: string, statusMessageWriter: TextWriter, encoding: Text.Encoding) : unit
ZipFile.Read(zipStream: Stream) : ZipFile
ZipFile.Read(fileName: string) : ZipFile
ZipFile.Read(zipStream: Stream, options: ReadOptions) : ZipFile
ZipFile.Read(fileName: string, options: ReadOptions) : ZipFile
val tempName : string
type Path =
  static val DirectorySeparatorChar : char
  static val AltDirectorySeparatorChar : char
  static val VolumeSeparatorChar : char
  static val InvalidPathChars : char[]
  static val PathSeparator : char
  static member ChangeExtension : path:string * extension:string -> string
  static member Combine : [<ParamArray>] paths:string[] -> string + 3 overloads
  static member GetDirectoryName : path:string -> string
  static member GetExtension : path:string -> string
  static member GetFileName : path:string -> string
  ...

Full name: System.IO.Path
Path.GetTempFileName() : string
type File =
  static member AppendAllLines : path:string * contents:IEnumerable<string> -> unit + 1 overload
  static member AppendAllText : path:string * contents:string -> unit + 1 overload
  static member AppendText : path:string -> StreamWriter
  static member Copy : sourceFileName:string * destFileName:string -> unit + 1 overload
  static member Create : path:string -> FileStream + 3 overloads
  static member CreateText : path:string -> StreamWriter
  static member Decrypt : path:string -> unit
  static member Delete : path:string -> unit
  static member Encrypt : path:string -> unit
  static member Exists : path:string -> bool
  ...

Full name: System.IO.File
File.Delete(path: string) : unit
val dir : DirectoryInfo
type Directory =
  static member CreateDirectory : path:string -> DirectoryInfo + 1 overload
  static member Delete : path:string -> unit + 1 overload
  static member EnumerateDirectories : path:string -> IEnumerable<string> + 2 overloads
  static member EnumerateFileSystemEntries : path:string -> IEnumerable<string> + 2 overloads
  static member EnumerateFiles : path:string -> IEnumerable<string> + 2 overloads
  static member Exists : path:string -> bool
  static member GetAccessControl : path:string -> DirectorySecurity + 1 overload
  static member GetCreationTime : path:string -> DateTime
  static member GetCreationTimeUtc : path:string -> DateTime
  static member GetCurrentDirectory : unit -> string
  ...

Full name: System.IO.Directory
Directory.CreateDirectory(path: string) : DirectoryInfo
Directory.CreateDirectory(path: string, directorySecurity: Security.AccessControl.DirectorySecurity) : DirectoryInfo
ZipFile.ExtractAll(path: string) : unit
ZipFile.ExtractAll(path: string, extractExistingFile: ExtractExistingFileAction) : unit
val ensureDelete : dir:DirectoryInfo -> IDisposable

Full name: Script.ensureDelete
Multiple items
type DirectoryInfo =
  inherit FileSystemInfo
  new : path:string -> DirectoryInfo
  member Create : unit -> unit + 1 overload
  member CreateSubdirectory : path:string -> DirectoryInfo + 1 overload
  member Delete : unit -> unit + 1 overload
  member EnumerateDirectories : unit -> IEnumerable<DirectoryInfo> + 2 overloads
  member EnumerateFileSystemInfos : unit -> IEnumerable<FileSystemInfo> + 2 overloads
  member EnumerateFiles : unit -> IEnumerable<FileInfo> + 2 overloads
  member Exists : bool
  member GetAccessControl : unit -> DirectorySecurity + 1 overload
  member GetDirectories : unit -> DirectoryInfo[] + 2 overloads
  ...

Full name: System.IO.DirectoryInfo

--------------------
DirectoryInfo(path: string) : unit
type IDisposable =
  member Dispose : unit -> unit

Full name: System.IDisposable
val x : IDisposable
IDisposable.Dispose() : unit
DirectoryInfo.Delete() : unit
DirectoryInfo.Delete(recursive: bool) : unit
val findAssemblies : dir:DirectoryInfo -> seq<FileInfo>

Full name: Script.findAssemblies
val filterAssemblies : (DirectoryInfo -> seq<FileInfo>)
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val item : FileSystemInfo
DirectoryInfo.EnumerateFileSystemInfos() : Collections.Generic.IEnumerable<FileSystemInfo>
DirectoryInfo.EnumerateFileSystemInfos(searchPattern: string) : Collections.Generic.IEnumerable<FileSystemInfo>
DirectoryInfo.EnumerateFileSystemInfos(searchPattern: string, searchOption: SearchOption) : Collections.Generic.IEnumerable<FileSystemInfo>
val d : DirectoryInfo
property DirectoryInfo.Name: string
String.ToLowerInvariant() : string
Multiple items
type FileInfo =
  inherit FileSystemInfo
  new : fileName:string -> FileInfo
  member AppendText : unit -> StreamWriter
  member CopyTo : destFileName:string -> FileInfo + 1 overload
  member Create : unit -> FileStream
  member CreateText : unit -> StreamWriter
  member Decrypt : unit -> unit
  member Delete : unit -> unit
  member Directory : DirectoryInfo
  member DirectoryName : string
  member Encrypt : unit -> unit
  ...

Full name: System.IO.FileInfo

--------------------
FileInfo(fileName: string) : unit
val f : FileInfo
property FileSystemInfo.Extension: string
val getPlatform : (FileInfo -> string)
val idx : int
property FileInfo.DirectoryName: string
String.LastIndexOf(value: string) : int
String.LastIndexOf(value: char) : int
String.LastIndexOf(value: string, comparisonType: StringComparison) : int
String.LastIndexOf(value: string, startIndex: int) : int
String.LastIndexOf(value: char, startIndex: int) : int
String.LastIndexOf(value: string, startIndex: int, comparisonType: StringComparison) : int
String.LastIndexOf(value: string, startIndex: int, count: int) : int
String.LastIndexOf(value: char, startIndex: int, count: int) : int
String.LastIndexOf(value: string, startIndex: int, count: int, comparisonType: StringComparison) : int
val allAssemblies : seq<FileInfo>
module Seq

from Microsoft.FSharp.Collections
val cache : source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.cache
val platforms : Set<string>
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
Multiple items
module Set

from Microsoft.FSharp.Collections

--------------------
type Set<'T (requires comparison)> =
  interface IComparable
  interface IEnumerable
  interface IEnumerable<'T>
  interface ICollection<'T>
  new : elements:seq<'T> -> Set<'T>
  member Add : value:'T -> Set<'T>
  member Contains : value:'T -> bool
  override Equals : obj -> bool
  member IsProperSubsetOf : otherSet:Set<'T> -> bool
  member IsProperSupersetOf : otherSet:Set<'T> -> bool
  ...

Full name: Microsoft.FSharp.Collections.Set<_>

--------------------
new : elements:seq<'T> -> Set<'T>
val ofSeq : elements:seq<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Set.ofSeq
val newestPlatforms : Set<string>
val filter : predicate:('T -> bool) -> set:Set<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Set.filter
val ofList : elements:'T list -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Set.ofList
val intersect : set1:Set<'T> -> set2:Set<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Set.intersect
val isEmpty : set:Set<'T> -> bool (requires comparison)

Full name: Microsoft.FSharp.Collections.Set.isEmpty
member Set.Contains : value:'T -> bool
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.filter
val printFiles : name:string -> unit

Full name: Script.printFiles
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val packageDir : DirectoryInfo
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken

Full name: Microsoft.FSharp.Control.Async

--------------------
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
property FileSystemInfo.FullName: string

More information

Link:http://fssnip.net/cd
Posted:5 years ago
Author:Joel Mueller
Tags: nuget , async , zip