comparison vext.sml @ 1747:ffe59b457557

Update vext
author Chris Cannam
date Mon, 09 Oct 2017 11:09:34 +0100
parents bf4a7015033e
children 716e13004b19
comparison
equal deleted inserted replaced
1746:bf4a7015033e 1747:ffe59b457557
36 shall not be used in advertising or otherwise to promote the sale, 36 shall not be used in advertising or otherwise to promote the sale,
37 use or other dealings in this Software without prior written 37 use or other dealings in this Software without prior written
38 authorization. 38 authorization.
39 *) 39 *)
40 40
41 val vext_version = "0.9.8" 41 val vext_version = "0.9.9"
42 42
43 43
44 datatype vcs = 44 datatype vcs =
45 HG | 45 HG |
46 GIT 46 GIT
366 (SOME home, _) => home 366 (SOME home, _) => home
367 | (NONE, SOME home) => home 367 | (NONE, SOME home) => home
368 | (NONE, NONE) => 368 | (NONE, NONE) =>
369 raise Fail "Failed to look up home directory from environment" 369 raise Fail "Failed to look up home directory from environment"
370 370
371 fun mkpath path = 371 fun mkpath' path =
372 if OS.FileSys.isDir path handle _ => false 372 if OS.FileSys.isDir path handle _ => false
373 then OK () 373 then OK ()
374 else case OS.Path.fromString path of 374 else case OS.Path.fromString path of
375 { arcs = nil, ... } => OK () 375 { arcs = nil, ... } => OK ()
376 | { isAbs = false, ... } => ERROR "mkpath requires absolute path" 376 | { isAbs = false, ... } => ERROR "mkpath requires absolute path"
377 | { isAbs, vol, arcs } => 377 | { isAbs, vol, arcs } =>
378 case mkpath (OS.Path.toString { (* parent *) 378 case mkpath' (OS.Path.toString { (* parent *)
379 isAbs = isAbs, 379 isAbs = isAbs,
380 vol = vol, 380 vol = vol,
381 arcs = rev (tl (rev arcs)) }) of 381 arcs = rev (tl (rev arcs)) }) of
382 ERROR e => ERROR e 382 ERROR e => ERROR e
383 | OK () => ((OS.FileSys.mkDir path; OK ()) 383 | OK () => ((OS.FileSys.mkDir path; OK ())
384 handle OS.SysErr (e, _) => 384 handle OS.SysErr (e, _) =>
385 ERROR ("Directory creation failed: " ^ e)) 385 ERROR ("Directory creation failed: " ^ e))
386
387 fun mkpath path =
388 (* strip any trailing '/', something isDir doesn't always handle *)
389 case rev (explode path) of
390 #"/"::rest => mkpath (implode (rev rest))
391 | _ => mkpath' path
386 392
387 fun rmpath path = 393 fun rmpath path =
388 let open OS 394 let open OS
389 fun files_from dirstream = 395 fun files_from dirstream =
390 case FileSys.readDir dirstream of 396 case FileSys.readDir dirstream of
1127 1133
1128 fun login_for ({ accounts, ... } : context) service = 1134 fun login_for ({ accounts, ... } : context) service =
1129 case List.find (fn a => service = #service a) accounts of 1135 case List.find (fn a => service = #service a) accounts of
1130 SOME { login, ... } => SOME login 1136 SOME { login, ... } => SOME login
1131 | NONE => NONE 1137 | NONE => NONE
1132 1138
1139 fun reponame_for path =
1140 case String.tokens (fn c => c = #"/") path of
1141 [] => raise Fail "Non-empty library path required"
1142 | toks => hd (rev toks)
1143
1133 fun remote_url (context : context) vcs source libname = 1144 fun remote_url (context : context) vcs source libname =
1134 case source of 1145 case source of
1135 URL_SOURCE u => u 1146 URL_SOURCE u => u
1136 | SERVICE_SOURCE { service, owner, repo } => 1147 | SERVICE_SOURCE { service, owner, repo } =>
1137 provider_url { vcs = vcs, 1148 provider_url { vcs = vcs,
1138 service = service, 1149 service = service,
1139 owner = owner, 1150 owner = owner,
1140 repo = case repo of 1151 repo = case repo of
1141 SOME r => r 1152 SOME r => r
1142 | NONE => libname } 1153 | NONE => reponame_for libname }
1143 (login_for context service) 1154 (login_for context service)
1144 (#providers context) 1155 (#providers context)
1145 end 1156 end
1146 1157
1147 structure HgControl :> VCS_CONTROL = struct 1158 structure HgControl :> VCS_CONTROL = struct
1246 | OK { modified, ... } => OK modified 1257 | OK { modified, ... } => OK modified
1247 1258
1248 fun checkout context (libname, source, branch) = 1259 fun checkout context (libname, source, branch) =
1249 let val url = remote_for context (libname, source) 1260 let val url = remote_for context (libname, source)
1250 in 1261 in
1251 case FileBits.mkpath (FileBits.extpath context) of 1262 (* make the lib dir rather than just the ext dir, since
1263 the lib dir might be nested and hg will happily check
1264 out into an existing empty dir anyway *)
1265 case FileBits.mkpath (FileBits.libpath context libname) of
1252 ERROR e => ERROR e 1266 ERROR e => ERROR e
1253 | _ => hg_command context "" 1267 | _ => hg_command context ""
1254 ["clone", "-u", branch_name branch, 1268 ["clone", "-u", branch_name branch,
1255 url, libname] 1269 url, libname]
1256 end 1270 end
1308 fun remote_branch_name branch = "origin/" ^ branch_name branch 1322 fun remote_branch_name branch = "origin/" ^ branch_name branch
1309 1323
1310 fun checkout context (libname, source, branch) = 1324 fun checkout context (libname, source, branch) =
1311 let val url = remote_for context (libname, source) 1325 let val url = remote_for context (libname, source)
1312 in 1326 in
1313 case FileBits.mkpath (FileBits.extpath context) of 1327 (* make the lib dir rather than just the ext dir, since
1328 the lib dir might be nested and git will happily check
1329 out into an existing empty dir anyway *)
1330 case FileBits.mkpath (FileBits.libpath context libname) of
1314 OK () => git_command context "" 1331 OK () => git_command context ""
1315 ["clone", "-b", 1332 ["clone", "-b",
1316 branch_name branch, 1333 branch_name branch,
1317 url, libname] 1334 url, libname]
1318 | ERROR e => ERROR e 1335 | ERROR e => ERROR e