Skip to content

Commit

Permalink
Merge rest of #1785
Browse files Browse the repository at this point in the history
  • Loading branch information
forki committed Jul 12, 2016
1 parent be54599 commit f3cd126
Show file tree
Hide file tree
Showing 15 changed files with 55 additions and 64 deletions.
11 changes: 5 additions & 6 deletions src/Paket.Core/BindingRedirects.fs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,9 @@ let internal indentAssemblyBindings config =
let sb = StringBuilder()
let xmlWriterSettings = XmlWriterSettings()
xmlWriterSettings.Indent <- true
use writer = XmlWriter.Create(sb, xmlWriterSettings)
let tempAssemblyBindingNode = XElement.Parse(assemblyBinding.ToString())
tempAssemblyBindingNode.WriteTo writer
writer.Close()
( use writer = XmlWriter.Create(sb, xmlWriterSettings)
let tempAssemblyBindingNode = XElement.Parse(assemblyBinding.ToString())
tempAssemblyBindingNode.WriteTo writer)

let parent = assemblyBinding.Parent
assemblyBinding.Remove()
Expand Down Expand Up @@ -184,8 +183,8 @@ let applyBindingRedirectsToFolder isFirstGroup createNewBindingFiles cleanBindin
|> Seq.iter applyBindingRedirects

/// Calculates the short form of the public key token for use with binding redirects, if it exists.
let getPublicKeyToken (assembly:Assembly) =
("", assembly.GetName().GetPublicKeyToken())
let getPublicKeyToken (assembly:Mono.Cecil.AssemblyDefinition) =
("", assembly.Name.PublicKeyToken)
||> Array.fold(fun state b -> state + b.ToString("X2"))
|> function
| "" -> None
Expand Down
10 changes: 7 additions & 3 deletions src/Paket.Core/ConfigFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ let private getConfigNode (nodeName : string) =
let doc = XmlDocument ()
if File.Exists Constants.PaketConfigFile then
try
doc.Load Constants.PaketConfigFile
use f = File.OpenRead(Constants.PaketConfigFile)
doc.Load f
ok doc.DocumentElement
with _ -> fail ConfigFileParseError
else
Expand All @@ -44,12 +45,15 @@ let private saveConfigNode (node : XmlNode) =
do! saveFile Constants.PaketConfigFile (node.OwnerDocument.OuterXml)
}

let private cryptoServiceProvider = new RNGCryptoServiceProvider()

let private fillRandomBytes =
let provider = RandomNumberGenerator.Create()
(fun (b:byte[]) -> provider.GetBytes(b))

let private getRandomSalt() =
let saltSize = 8
let saltBytes = Array.create saltSize ( new Byte() )
cryptoServiceProvider.GetNonZeroBytes(saltBytes)
fillRandomBytes(saltBytes)
saltBytes

/// Encrypts a string with a user specific keys
Expand Down
2 changes: 1 addition & 1 deletion src/Paket.Core/Constants.fs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ let AppDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.Ap
let PaketConfigFolder = Path.Combine(AppDataFolder, "Paket")
let PaketConfigFile = Path.Combine(PaketConfigFolder, "paket.config")

let UserProfile = System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile)
let UserProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
let GitRepoCacheFolder = Path.Combine(UserProfile,".paket","git","db")


Expand Down
2 changes: 1 addition & 1 deletion src/Paket.Core/DependenciesFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ type DependenciesFile(fileName,groups:Map<GroupName,DependenciesGroup>, textRepr
let getRestrictionList =
let projectFrameworks = lazy (
let lockFile = dependenciesFile.FindLockfile()
let dir = (lockFile :> FileInfo).DirectoryName // wtf have to have the cast here so that the compiler doesn't coerce the lockFile to an obj
let dir = (lockFile : FileInfo).DirectoryName // wtf have to have the cast here so that the compiler doesn't coerce the lockFile to an obj
let projects = ProjectFile.FindAllProjects dir
let frameworks = projects |> Array.choose ProjectFile.getTargetFramework |> Array.distinct
frameworks |> Array.map FrameworkRestriction.Exactly |> List.ofArray
Expand Down
34 changes: 8 additions & 26 deletions src/Paket.Core/InstallProcess.fs
Original file line number Diff line number Diff line change
Expand Up @@ -169,24 +169,6 @@ let CreateModel(root, force, dependenciesFile:DependenciesFile, lockFile : LockF
|> Seq.concat
|> Seq.toArray

/// Since Assembly.ReflectionOnlyLoadFrom holds on to file handles indefintely, we use
/// ReflectionOnlyLoad(bytes[]) instead. However, in order to prevent
/// CLR from loading same assemblies multiple times (results in exn), we use a static
/// dictionary for caching assemblies, based on their filename.
module private LoadAssembliesSafe =

let loadedLibs = new Dictionary<_,_>()

let reflectionOnlyLoadFrom library =
let key = FileInfo(library).FullName.ToLowerInvariant()
match loadedLibs.TryGetValue key with
| (true,v) -> v
| _ ->
let assemblyAsBytes = File.ReadAllBytes library
let v = Assembly.ReflectionOnlyLoad assemblyAsBytes
loadedLibs.[key] <- v
v

let inline private getOrAdd (key: 'key) (getValue: 'key -> 'value) (d: Dictionary<'key, 'value>) : 'value =
let value: 'value ref = ref Unchecked.defaultof<_>
if d.TryGetValue(key, value) then !value
Expand Down Expand Up @@ -254,37 +236,37 @@ let private applyBindingRedirects isFirstGroup createNewBindingFiles redirects c
librariesForPackage
|> Seq.choose(fun (library,redirects,profile) ->
try
let assembly = LoadAssembliesSafe.reflectionOnlyLoadFrom library
Some (assembly, BindingRedirects.getPublicKeyToken assembly, assembly.GetReferencedAssemblies(), redirects, profile)
let assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(library)
Some (assembly, BindingRedirects.getPublicKeyToken assembly, assembly.MainModule.AssemblyReferences, redirects, profile)
with _ -> None)
|> Seq.sortBy(fun (assembly,_,_,_,_) -> assembly.GetName().Version)
|> Seq.sortBy(fun (assembly,_,_,_,_) -> assembly.Name.Version)
|> Seq.toList
|> List.rev
|> function | head :: _ -> Some head | _ -> None)
|> Seq.cache

let referencesDifferentProfiles (assemblyName : AssemblyName) profile =
let referencesDifferentProfiles (assemblyName : Mono.Cecil.AssemblyNameDefinition) profile =
profile = targetProfile
&& assemblies
|> Seq.filter (fun (_,_,_,_,p) -> p <> profile)
|> Seq.map (fun (a,_,_,_,_) -> a.GetName())
|> Seq.map (fun (a,_,_,_,_) -> a.Name)
|> Seq.filter (fun a -> a.Name = assemblyName.Name)
|> Seq.exists (fun a -> a.Version <> assemblyName.Version)

assemblies
|> Seq.choose (fun (assembly,token,refs,redirects,profile) -> token |> Option.map (fun token -> (assembly,token,refs,redirects,profile)))
|> Seq.filter (fun (_,_,_,packageRedirects,_) -> defaultArg ((packageRedirects |> Option.map ((<>) Off)) ++ redirects) false)
|> Seq.filter (fun (assembly,_,_,redirects,profile) ->
let assemblyName = assembly.GetName()
let assemblyName = assembly.Name
redirects = Some Force
|| referencesDifferentProfiles assemblyName profile
|| assemblies
|> Seq.collect (fun (_,_,refs,_,_) -> refs)
|> Seq.filter (fun a -> assemblyName.Name = a.Name)
|> Seq.exists (fun a -> assemblyName.Version > a.Version))
|> Seq.map(fun (assembly, token,_,_,_) ->
{ BindingRedirect.AssemblyName = assembly.GetName().Name
Version = assembly.GetName().Version.ToString()
{ BindingRedirect.AssemblyName = assembly.Name.Name
Version = assembly.Name.Version.ToString()
PublicKeyToken = token
Culture = None })
|> Seq.sort
Expand Down
2 changes: 1 addition & 1 deletion src/Paket.Core/NuGetV2.fs
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ let ExtractPackageToUserFolder(fileName:string, packageName:PackageName, version
if not <| File.Exists cachedHashFile then
use stream = File.OpenRead(fileName)
let packageSize = stream.Length
use hasher = new System.Security.Cryptography.SHA512CryptoServiceProvider() :> System.Security.Cryptography.HashAlgorithm
use hasher = System.Security.Cryptography.SHA512.Create() :> System.Security.Cryptography.HashAlgorithm
let packageHash = Convert.ToBase64String(hasher.ComputeHash(stream))
File.WriteAllText(cachedHashFile,packageHash)

Expand Down
3 changes: 2 additions & 1 deletion src/Paket.Core/NugetConvert.fs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ type NugetConfig =
static member GetConfigNode (file : FileInfo) =
try
let doc = XmlDocument()
doc.Load(file.FullName)
( use f = File.OpenRead file.FullName
doc.Load(f))
(doc |> getNode "configuration").Value |> ok
with _ ->
file
Expand Down
1 change: 0 additions & 1 deletion src/Paket.Core/NupkgWriter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ let Write (core : CompleteCoreInfo) optional workingDir outputDir =
let entry = zipFile.CreateEntry(path)
use stream = entry.Open()
writerF stream
stream.Close()

let addEntryFromFile path source =
if entries.Contains(path) then () else
Expand Down
3 changes: 2 additions & 1 deletion src/Paket.Core/Nuspec.fs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ type Nuspec =
else
let doc = new XmlDocument()
try
doc.Load fi.FullName
use f = File.OpenRead(fi.FullName)
doc.Load f
with
| exn ->
let text = File.ReadAllText(fi.FullName) // work around mono bug https://github.com/fsprojects/Paket/issues/1189
Expand Down
7 changes: 3 additions & 4 deletions src/Paket.Core/PackageSources.fs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ let toBasicAuth = function

let tryParseWindowsStyleNetworkPath (path : string) =
let trimmed = path.TrimStart()
match Environment.OSVersion.Platform with
| PlatformID.Unix | PlatformID.MacOSX when trimmed.StartsWith @"\\" ->
trimmed.Replace('\\', '/') |> sprintf "smb:%s" |> Some
| _ -> None
if (isUnix || isMacOS) && trimmed.StartsWith @"\\" then
trimmed.Replace('\\', '/') |> sprintf "smb:%s" |> Some
else None

type NugetSource =
{ Url : string
Expand Down
3 changes: 2 additions & 1 deletion src/Paket.Core/PackagesConfigFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ let Read fileName =
let file = FileInfo fileName
if file.Exists |> not then [] else
let doc = XmlDocument()
doc.Load file.FullName
( use f = File.OpenRead(file.FullName)
doc.Load f)

[for node in doc.SelectNodes("//package") ->
{ Id = node.Attributes.["id"].Value
Expand Down
8 changes: 3 additions & 5 deletions src/Paket.Core/PlatformMatching.fs
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,13 @@ let getCondition (referenceCondition:string option) (targets : TargetProfile lis
let andString =
conditions
|> List.map (fun (group,conditions) ->
match List.ofSeq conditions with
| [ _,"" ] -> group
| [ _,detail ] -> sprintf "%s And %s" group detail
match List.ofSeq (conditions |> Seq.map snd |> Set.ofSeq) with
| [ "" ] -> group
| [ detail ] -> sprintf "%s And %s" group detail
| [] -> "false"
| conditions ->
let detail =
conditions
|> List.map snd
|> Set.ofSeq
|> fun cs -> String.Join(" Or ",cs)
sprintf "%s And (%s)" group detail)

Expand Down
4 changes: 2 additions & 2 deletions src/Paket.Core/ProjectFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ module ProjectFile =
if normalizedPath.Contains "$(SolutionDir)" then
match getProperty "SolutionDir" project with
| Some slnDir -> normalizedPath.Replace("$(SolutionDir)",slnDir)
| None -> normalizedPath.Replace("$(SolutionDir)", Environment.CurrentDirectory + Path.DirectorySeparatorChar.ToString())
| None -> normalizedPath.Replace("$(SolutionDir)", Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar.ToString())
else normalizedPath

{ Path =
Expand Down Expand Up @@ -1104,7 +1104,7 @@ module ProjectFile =
|> List.tryFind (fun n ->
match n |> getAttribute "Project" with
| Some p -> p.Equals("$(SolutionDir)\\.nuget\\nuget.targets",
StringComparison.InvariantCultureIgnoreCase)
StringComparison.OrdinalIgnoreCase)
| None -> false)
project.Document
|> getDescendants "Target"
Expand Down
8 changes: 4 additions & 4 deletions src/Paket.Core/PublicAPI.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Dependencies(dependenciesFileName: string) =
Utils.emptyDir (DirectoryInfo Constants.GitRepoCacheFolder)

/// Tries to locate the paket.dependencies file in the current folder or a parent folder.
static member Locate(): Dependencies = Dependencies.Locate(Environment.CurrentDirectory)
static member Locate(): Dependencies = Dependencies.Locate(Directory.GetCurrentDirectory())

/// Returns an instance of the paket.lock file.
member this.GetLockFile() =
Expand Down Expand Up @@ -58,7 +58,7 @@ type Dependencies(dependenciesFileName: string) =
Dependencies(dependenciesFileName)

/// Initialize paket.dependencies file in current directory
static member Init() = Dependencies.Init(Environment.CurrentDirectory)
static member Init() = Dependencies.Init(Directory.GetCurrentDirectory())

/// Initialize paket.dependencies file in the given directory
static member Init(directory) =
Expand All @@ -73,7 +73,7 @@ type Dependencies(dependenciesFileName: string) =

/// Converts the solution from NuGet to Paket.
static member ConvertFromNuget(force: bool,installAfter: bool, initAutoRestore: bool,credsMigrationMode: string option, ?directory) : unit =
let dir = defaultArg directory (DirectoryInfo(Environment.CurrentDirectory))
let dir = defaultArg directory (DirectoryInfo(Directory.GetCurrentDirectory()))
let rootDirectory = dir

Utils.RunInLockedAccessMode(
Expand Down Expand Up @@ -167,7 +167,7 @@ type Dependencies(dependenciesFileName: string) =

/// Creates a paket.dependencies file with the given text in the current directory and installs it.
static member Install(dependencies, ?path: string, ?force, ?withBindingRedirects, ?cleanBindingRedirects, ?createNewBindingFiles, ?onlyReferenced, ?semVerUpdateMode, ?touchAffectedRefs) =
let path = defaultArg path Environment.CurrentDirectory
let path = defaultArg path (Directory.GetCurrentDirectory())
let fileName = Path.Combine(path, Constants.DependenciesFileName)
File.WriteAllText(fileName, dependencies)
let dependencies = Dependencies.Locate(path)
Expand Down
21 changes: 14 additions & 7 deletions src/Paket.Core/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ let getFileEncoding path =
/// [omit]
let inline createRelativePath root path =
let basePath =
if String.IsNullOrEmpty root then Environment.CurrentDirectory + string Path.DirectorySeparatorChar
if String.IsNullOrEmpty root then Directory.GetCurrentDirectory() + string Path.DirectorySeparatorChar
else root

let uri = Uri basePath
Expand Down Expand Up @@ -423,10 +423,17 @@ let safeGetFromUrl (auth:Auth option, url : string, contentType : string) =
client.Encoding <- Encoding.UTF8
let! raw = client.DownloadStringTaskAsync(uri) |> Async.AwaitTask
return Some raw
with _ -> return None
with e ->
Logging.verbosefn "Error while retrieving '%s': %O" url e
return None
}

let readAnswer() = System.Console.ReadLine().Trim()
let mutable autoAnswer = None
let readAnswer() =
match autoAnswer with
| Some true -> "y"
| Some false -> "n"
| None -> System.Console.ReadLine().Trim()

/// If the guard is true then a [Y]es / [N]o question will be ask.
/// Until the user pressed y or n.
Expand Down Expand Up @@ -460,7 +467,7 @@ let RunInLockedAccessMode(rootFolder,action) =
if Directory.Exists packagesFolder |> not then
Directory.CreateDirectory packagesFolder |> ignore

let p = Process.GetCurrentProcess()
let p = System.Diagnostics.Process.GetCurrentProcess()
let fileName = Path.Combine(packagesFolder,Constants.AccessLockFileName)

// Checks the packagesFolder for a paket.locked file or waits until it get access to it.
Expand All @@ -470,7 +477,7 @@ let RunInLockedAccessMode(rootFolder,action) =
if File.Exists fileName then
let content = File.ReadAllText fileName
if content <> string p.Id then
let currentProcess = Process.GetCurrentProcess()
let currentProcess = System.Diagnostics.Process.GetCurrentProcess()
let hasRunningPaketProcess =
Process.GetProcessesByName p.ProcessName
|> Array.filter (fun p -> p.Id <> currentProcess.Id)
Expand Down Expand Up @@ -603,13 +610,13 @@ let parseKeyValuePairs (s:string) : Dictionary<string,string> =
| exn ->
failwithf "Could not parse %s as key/value pairs.%s%s" s Environment.NewLine exn.Message

let downloadStringSync (url : string) (client : System.Net.WebClient) =
let downloadStringSync (url : string) (client : WebClient) =
try
client.DownloadString url |> ok
with _ ->
DownloadError url |> fail

let downloadFileSync (url : string) (fileName : string) (client : System.Net.WebClient) =
let downloadFileSync (url : string) (fileName : string) (client : WebClient) =
tracefn "Downloading file from %s to %s" url fileName
try
client.DownloadFile(url, fileName) |> ok
Expand Down

0 comments on commit f3cd126

Please sign in to comment.