/
LocalFile.fs
163 lines (142 loc) · 6.24 KB
/
LocalFile.fs
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
namespace Paket
open Paket.Domain
open Paket.ModuleResolver
open Paket.PackageSources
type OverriddenPackage = {
Name : PackageName
Group : GroupName
}
type LocalOverride =
| LocalSourceOverride of package: OverriddenPackage * devSource: PackageSource * version: Option<SemVerInfo>
| LocalGitOverride of package: OverriddenPackage * gitSource: string
type LocalFile = LocalFile of devSourceOverrides: LocalOverride list
module LocalFile =
open System
open Chessie.ErrorHandling
open Logging
let private (|Regex|_|) pattern input =
let m = System.Text.RegularExpressions.Regex(pattern).Match(input)
if m.Success then
Some(List.tail [ for g in m.Groups -> g.Value ])
else
None
let nameGroup (name, group) =
let group =
if group = "" then
Constants.MainDependencyGroup
else
GroupName group
{ Name = PackageName name
Group = group }
let private parseLine = function
| Regex
"^nuget[ ]+(.*?)([ ]+group[ ]+(.*))?[ ]+->[ ]+(source[ ]+.*?)([ ]+version[ ]+(.*))?$"
[package; _; group; source; _; version] ->
let v =
if String.IsNullOrWhiteSpace version then None
else
try SemVer.Parse version |> Some
with exn ->
traceWarnfn "Could not parse version '%s': %s" version exn.Message
if verbose then
traceWarnfn "Exception: %O" exn
None
source
|> Trial.Catch PackageSource.Parse
|> Trial.mapFailure (fun _ -> [sprintf "Cannot parse source '%s'" source])
|> Trial.lift (fun s -> LocalSourceOverride (nameGroup(package, group), s, v))
| Regex
"nuget[ ]+(.*?)([ ]+group[ ]+(.*))?[ ]+->[ ]+git[ ]+(.*)"
[package; _; group; gitSource] ->
LocalGitOverride (nameGroup(package, group), gitSource)
|> Trial.ok
| line ->
Trial.fail (sprintf "Cannot parse line '%s'" line)
let parse =
List.map String.trim
>> List.filter (not << String.IsNullOrWhiteSpace)
>> List.filter (not << String.startsWithIgnoreCase @"//")
>> List.filter (not << String.startsWithIgnoreCase @"#")
>> List.map parseLine
>> Trial.collect
>> Trial.lift LocalFile
let readFile =
IO.File.ReadAllLines
>> Array.toList
>> parse
let empty = LocalFile []
let private overrideResolution (p, v, source) resolution =
resolution
|> Map.map (fun name original ->
if name = p then
{ original with PackageResolver.ResolvedPackage.Source = source
PackageResolver.ResolvedPackage.Version =
defaultArg v original.Version }
else
original)
let private warning x =
match x with
| LocalSourceOverride ({ Name = p; Group = g},s, Some v) ->
sprintf "nuget %s group %s -> %s version %s" (p.ToString()) (g.ToString()) (s.ToString()) (v.ToString())
| LocalSourceOverride ({ Name = p; Group = g},s, None) ->
sprintf "nuget %s group %s -> %s" (p.ToString()) (g.ToString()) (s.ToString())
| LocalGitOverride ({ Name = p; Group = g},s) ->
sprintf "nuget %s group %s -> %s" (p.ToString()) (g.ToString()) s
|> (+) "paket.local override: "
|> Logging.traceWarn
x
let overrideDependency (lockFile: LockFile) = warning >> function
| LocalSourceOverride ({ Name = p; Group = group },s,v) ->
let groups =
lockFile.Groups
|> Map.map (fun name g ->
if name = group then
{ g with Resolution = overrideResolution (p,v,s) g.Resolution }
else
g )
LockFile(lockFile.FileName, groups)
| LocalGitOverride ({ Name = p; Group = group},s) ->
let owner,branch,project,cloneUrl,buildCommand,operatingSystemRestriction,packagePath =
Git.Handling.extractUrlParts s
let restriction = VersionRestriction.Concrete (defaultArg branch "master")
let sha =
RemoteDownload.getSHA1OfBranch (GitLink cloneUrl) owner project restriction None
|> Async.RunSynchronously
let remoteFile = {
ResolvedSourceFile.Commit = sha
Owner = owner
Origin = GitLink cloneUrl
Project = project
Dependencies = Set.empty
Command = buildCommand
OperatingSystemRestriction = operatingSystemRestriction
PackagePath = packagePath
Name = ""
AuthKey = None
}
let packagesPath =
match packagePath with
| Some p -> p
| None ->
failwith "paket.local: only git repositories as NuGet source (with 'Packages: ...') are currently supported"
let source groupName =
let root = ""
let fullPath = remoteFile.ComputeFilePath(root,groupName, packagesPath)
let relative = (createRelativePath root fullPath).Replace("\\","/")
LocalNuGet(relative, None)
let groups =
lockFile.Groups
|> Map.map (fun name g ->
if name = group then
{ g with Resolution = overrideResolution (p,None,source g.Name) g.Resolution
RemoteFiles = remoteFile :: g.RemoteFiles }
else
g)
LockFile(lockFile.FileName, groups)
let overrideLockFile (LocalFile overrides) lockFile =
List.fold overrideDependency lockFile overrides
let overrides (LocalFile xs) (package, group) =
xs
|> List.exists (function | LocalSourceOverride ({ Name = p; Group = g}, _, _)
| LocalGitOverride ({ Name = p; Group = g}, _)
-> p = package && g = group)