summary refs log tree commit diff stats
path: root/tools/atlas/osutils.nim
blob: 6134830b50e7699852edf21f8c020d7ec0c25c74 (plain) (blame)
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
## OS utilities like 'withDir'.
## (c) 2021 Andreas Rumpf

import os, strutils, osproc

proc isUrl*(x: string): bool =
  x.startsWith("git://") or x.startsWith("https://") or x.startsWith("http://")

proc cloneUrl*(url, dest: string; cloneUsingHttps: bool): string =
  ## Returns an error message on error or else "".
  result = ""
  var modUrl =
    if url.startsWith("git://") and cloneUsingHttps:
      "https://" & url[6 .. ^1]
    else: url

  # github + https + trailing url slash causes a
  # checkout/ls-remote to fail with Repository not found
  var isGithub = false
  if modUrl.contains("github.com") and modUrl.endsWith("/"):
    modUrl = modUrl[0 .. ^2]
    isGithub = true

  let (_, exitCode) = execCmdEx("git ls-remote --quiet --tags " & modUrl)
  var xcode = exitCode
  if isGithub and exitCode != QuitSuccess:
    # retry multiple times to avoid annoying github timeouts:
    for i in 0..4:
      os.sleep(4000)
      xcode = execCmdEx("git ls-remote --quiet --tags " & modUrl)[1]
      if xcode == QuitSuccess: break

  if xcode == QuitSuccess:
    # retry multiple times to avoid annoying github timeouts:
    let cmd = "git clone " & modUrl & " " & dest
    for i in 0..4:
      if execShellCmd(cmd) == 0: return ""
      os.sleep(4000)
    result = "exernal program failed: " & cmd
  elif not isGithub:
    let (_, exitCode) = execCmdEx("hg identify " & modUrl)
    if exitCode == QuitSuccess:
      let cmd = "hg clone " & modUrl & " " & dest
      for i in 0..4:
        if execShellCmd(cmd) == 0: return ""
        os.sleep(4000)
      result = "exernal program failed: " & cmd
    else:
      result = "Unable to identify url: " & modUrl
  else:
    result = "Unable to identify url: " & modUrl