Skip to content

Commit

Permalink
Merge pull request #773 from Stift/LocalRelativePathDetection
Browse files Browse the repository at this point in the history
Fixing wrong local path detection with 'paket install'
  • Loading branch information
forki committed Apr 14, 2015
2 parents 020ab86 + d4da28d commit da29e78
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 22 deletions.
4 changes: 4 additions & 0 deletions docs/content/nuget-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Paket also supports file paths such as local directories or references to UNC sh

source C:\Nugets
source ~/project/nugets

As well Paket supports the source directory to be specified relative to the `paket.dependencies` file:

source ext/nugets

## Dependencies

Expand Down
3 changes: 2 additions & 1 deletion src/Paket.Core/DependenciesFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ type DependenciesFile(fileName,options,sources,packages : PackageRequirement lis
member __.Sources = sources
member this.Resolve(force) =
let getSha1 origin owner repo branch = RemoteDownload.getSHA1OfBranch origin owner repo branch |> Async.RunSynchronously
this.Resolve(getSha1,NuGetV2.GetVersions,NuGetV2.GetPackageDetails force)
let root = Path.GetDirectoryName this.FileName
this.Resolve(getSha1,NuGetV2.GetVersions root,NuGetV2.GetPackageDetails root force)

member __.Resolve(getSha1,getVersionF, getPackageDetailsF) =
let resolveSourceFile(file:ResolvedSourceFile) : PackageRequirement list =
Expand Down
25 changes: 13 additions & 12 deletions src/Paket.Core/NuGetV2.fs
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,12 @@ let getAllVersions(auth, nugetURL, package) = async {
// }

/// Gets versions of the given package from local Nuget feed.
let getAllVersionsFromLocalPath (localNugetPath, package) =
let getAllVersionsFromLocalPath (localNugetPath, package, root) =
async {
let localNugetPath = Utils.normalizeLocalPath localNugetPath
let di = DirectoryInfo(localNugetPath)
let di = getDirectoryInfo localNugetPath root
if not di.Exists then
failwithf "The directory %s doesn't exist.%sPlease check the NuGet source feed definition in your paket.dependencies file." localNugetPath Environment.NewLine
failwithf "The directory %s doesn't exist.%sPlease check the NuGet source feed definition in your paket.dependencies file." di.FullName Environment.NewLine

let versions=
Directory.EnumerateFiles(di.FullName,"*.nupkg",SearchOption.AllDirectories)
Expand Down Expand Up @@ -293,17 +293,18 @@ let getDetailsFromNuget force auth nugetURL package (version:SemVerInfo) =
}

/// Reads direct dependencies from a nupkg file
let getDetailsFromLocalFile localNugetPath package (version:SemVerInfo) =
let getDetailsFromLocalFile root localNugetPath package (version:SemVerInfo) =
async {
let localNugetPath = Utils.normalizeLocalPath localNugetPath
let di = getDirectoryInfo localNugetPath root
let nupkg =
let v1 = FileInfo(Path.Combine(localNugetPath, sprintf "%s.%s.nupkg" package (version.ToString())))
let v1 = FileInfo(Path.Combine(di.FullName, sprintf "%s.%s.nupkg" package (version.ToString())))
if v1.Exists then v1 else
let version = version.Normalize()
FileInfo(Path.Combine(localNugetPath, sprintf "%s.%s.nupkg" package version))
FileInfo(Path.Combine(di.FullName, sprintf "%s.%s.nupkg" package version))

if not nupkg.Exists then
failwithf "The package %s %s can't be found in %s.%sPlease check the feed definition in your paket.dependencies file." package (version.ToString()) localNugetPath Environment.NewLine
failwithf "The package %s %s can't be found in %s.%sPlease check the feed definition in your paket.dependencies file." package (version.ToString()) di.FullName Environment.NewLine
let zip = ZipFile.OpenRead(nupkg.FullName)
let zippedNuspec = zip.Entries |> Seq.find (fun f -> f.FullName.EndsWith ".nuspec")
let fileName = FileInfo(Path.Combine(Path.GetTempPath(), zippedNuspec.Name)).FullName
Expand All @@ -318,7 +319,7 @@ let getDetailsFromLocalFile localNugetPath package (version:SemVerInfo) =
{ PackageName = nuspec.OfficialName
DownloadUrl = package
Dependencies = Requirements.optimizeRestrictions nuspec.Dependencies
SourceUrl = localNugetPath
SourceUrl = di.FullName
CacheVersion = NugetPackageCache.CurrentCacheVersion
LicenseUrl = nuspec.LicenseUrl
Unlisted = false }
Expand Down Expand Up @@ -548,7 +549,7 @@ let GetTargetsFiles(targetFolder) =

targetsFiles

let GetPackageDetails force sources (PackageName package) (version:SemVerInfo) : PackageResolver.PackageDetails =
let GetPackageDetails root force sources (PackageName package) (version:SemVerInfo) : PackageResolver.PackageDetails =
let rec tryNext xs =
match xs with
| source :: rest ->
Expand All @@ -564,7 +565,7 @@ let GetPackageDetails force sources (PackageName package) (version:SemVerInfo) :
version
|> Async.RunSynchronously
| LocalNuget path ->
getDetailsFromLocalFile path package version
getDetailsFromLocalFile root path package version
|> Async.RunSynchronously
|> fun x -> source,x
with e ->
Expand All @@ -584,7 +585,7 @@ let GetPackageDetails force sources (PackageName package) (version:SemVerInfo) :
|> Set.ofList }

/// Allows to retrieve all version no. for a package from the given sources.
let GetVersions(sources, PackageName packageName) =
let GetVersions root (sources, PackageName packageName) =
let versions =
sources
|> Seq.map (fun source ->
Expand All @@ -593,7 +594,7 @@ let GetVersions(sources, PackageName packageName) =
source.Authentication |> Option.map toBasicAuth,
source.Url,
packageName)
| LocalNuget path -> getAllVersionsFromLocalPath (path, packageName))
| LocalNuget path -> getAllVersionsFromLocalPath (path, packageName, root))
|> Async.Parallel
|> Async.RunSynchronously
|> Seq.choose id
Expand Down
3 changes: 2 additions & 1 deletion src/Paket.Core/RestoreProcess.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ let ExtractPackage(root, sources, force, package : ResolvedPackage) =
return package, NuGetV2.GetLibFiles folder, NuGetV2.GetTargetsFiles folder
| LocalNuget path ->
let path = Utils.normalizeLocalPath path
let packageFile = Path.Combine(root, path, sprintf "%s.%A.nupkg" name v)
let di = Utils.getDirectoryInfo path root
let packageFile = Path.Combine(di.FullName, sprintf "%s.%A.nupkg" name v)
let! folder = NuGetV2.CopyFromCache(root, packageFile, "", name, v, force) // TODO: Restore license
return package, NuGetV2.GetLibFiles folder, NuGetV2.GetTargetsFiles folder
}
Expand Down
21 changes: 16 additions & 5 deletions src/Paket.Core/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,22 @@ let GetHomeDirectory() =
else
Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%")

let normalizeLocalPath(path:string)=
type PathReference =
| AbsolutePath of string
| RelativePath of string

let normalizeLocalPath(path:string) =
if path.StartsWith("~/") then
Path.Combine(GetHomeDirectory(), path.Substring(2))
else
path
AbsolutePath (Path.Combine(GetHomeDirectory(), path.Substring(2)))
else if Path.IsPathRooted(path) then
AbsolutePath path
else
RelativePath path

let getDirectoryInfo pathInfo root =
match pathInfo with
| AbsolutePath s -> DirectoryInfo(s)
| RelativePath s -> DirectoryInfo(Path.Combine(root, s))

/// Creates a directory if it does not exist.
let createDir path =
Expand Down Expand Up @@ -373,4 +384,4 @@ module ObservableExtensions =
{ new IDisposable with
member this.Dispose() = cts.Cancel()
}
}
}
52 changes: 49 additions & 3 deletions tests/Paket.Tests/UtilsSpecs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,56 @@ let ``createRelativePath should handle spaces``() =
"C:/some file"
|> createRelativePath "C:/a/b"
|> shouldEqual "..\\some file"



[<Test>]
let ``normalize path with home directory``() =
"~/data"
|> Utils.normalizeLocalPath
|> shouldEqual (GetHomeDirectory() + Path.DirectorySeparatorChar.ToString() + "data")
|> shouldEqual (AbsolutePath (GetHomeDirectory() + Path.DirectorySeparatorChar.ToString() + "data"))

[<Test>]
let ``relative local path is returned as is``() =
"Externals/NugetStore"
|> normalizeLocalPath
|> shouldEqual (RelativePath "Externals/NugetStore")

[<Test>]
let ``absolute path with drive letter``() =
"c:\\Store"
|> normalizeLocalPath
|> match System.Environment.OSVersion.Platform with
| System.PlatformID.Win32NT -> shouldEqual (AbsolutePath "c:\\Store")
| _ -> shouldEqual (RelativePath "c:\\Store")

[<Test>]
let ``relative path with drive letter``() =
"..\\Store"
|> normalizeLocalPath
|> shouldEqual (RelativePath "..\\Store")

[<Test>]
let ``relative path with local identifier``() =
".\\Store"
|> normalizeLocalPath
|> shouldEqual (RelativePath ".\\Store")

[<Test>]
let ``SMB path is returned as absolute path``() =
"\\\\server\\Store"
|> normalizeLocalPath
|> match System.Environment.OSVersion.Platform with
| System.PlatformID.Win32NT | System.PlatformID.Win32S -> shouldEqual (AbsolutePath "\\\\server\\Store")
| _ -> shouldEqual (RelativePath "\\\\server\\Store")

[<Test>]
let ``absolute path on unixoid systems``() =
"/server/Store"
|> normalizeLocalPath
|> shouldEqual (AbsolutePath "/server/Store")

[<Test>]
let ``relative path with local identifier on unxoid systems``() =
"./Store"
|> normalizeLocalPath
|> shouldEqual (RelativePath "./Store")

0 comments on commit da29e78

Please sign in to comment.