PageRenderTime 33ms CodeModel.GetById 13ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/src/etc/snapshot.py

http://github.com/jruderman/rust
Python | 214 lines | 166 code | 45 blank | 3 comment | 27 complexity | 9eab4e52dbe36492b2b910606566c7ab MD5 | raw file
  1import re, os, sys, glob, tarfile, shutil, subprocess, tempfile
  2
  3try:
  4  import hashlib
  5  sha_func = hashlib.sha1
  6except ImportError:
  7  import sha
  8  sha_func = sha.new
  9
 10def scrub(b):
 11  if sys.version_info >= (3,) and type(b) == bytes:
 12    return b.decode('ascii')
 13  else:
 14    return b
 15
 16src_dir = scrub(os.getenv("CFG_SRC_DIR"))
 17if not src_dir:
 18  raise Exception("missing env var CFG_SRC_DIR")
 19
 20snapshotfile = os.path.join(src_dir, "src", "snapshots.txt")
 21download_url_base = "http://dl.rust-lang.org/stage0-snapshots"
 22download_dir_base = "dl"
 23download_unpack_base = os.path.join(download_dir_base, "unpack")
 24
 25snapshot_files = {
 26    "linux": ["bin/rustc",
 27              "lib/libcore-*.so",
 28              "lib/libstd-*.so",
 29              "lib/librustc-*.so",
 30              "lib/libsyntax-*.so",
 31              "lib/librustrt.so",
 32              "lib/librustllvm.so"],
 33    "macos": ["bin/rustc",
 34              "lib/libcore-*.dylib",
 35              "lib/libstd-*.dylib",
 36              "lib/librustc-*.dylib",
 37              "lib/libsyntax-*.dylib",
 38              "lib/librustrt.dylib",
 39              "lib/librustllvm.dylib"],
 40    "winnt": ["bin/rustc.exe",
 41              "bin/core-*.dll",
 42              "bin/std-*.dll",
 43              "bin/rustc-*.dll",
 44              "bin/syntax-*.dll",
 45              "bin/rustrt.dll",
 46              "bin/rustllvm.dll"],
 47    "freebsd": ["bin/rustc",
 48                "lib/libcore-*.so",
 49                "lib/libstd-*.so",
 50                "lib/librustc-*.so",
 51                "lib/libsyntax-*.so",
 52                "lib/librustrt.so",
 53                "lib/librustllvm.so"]
 54    }
 55
 56def parse_line(n, line):
 57  global snapshotfile
 58
 59  if re.match(r"\s*$", line): return None
 60
 61  if re.match(r"^T\s*$", line): return None
 62
 63  match = re.match(r"\s+([\w_-]+) ([a-fA-F\d]{40})\s*$", line)
 64  if match:
 65    return { "type": "file",
 66             "platform": match.group(1),
 67             "hash": match.group(2).lower() }
 68
 69  match = re.match(r"([ST]) (\d{4}-\d{2}-\d{2}) ([a-fA-F\d]+)\s*$", line);
 70  if (not match):
 71    raise Exception("%s:%d:E syntax error" % (snapshotfile, n))
 72  return {"type": "snapshot",
 73          "date": match.group(2),
 74          "rev": match.group(3)}
 75
 76
 77def partial_snapshot_name(date, rev, platform):
 78  return ("rust-stage0-%s-%s-%s.tar.bz2"
 79          % (date, rev, platform))
 80
 81def full_snapshot_name(date, rev, platform, hsh):
 82  return ("rust-stage0-%s-%s-%s-%s.tar.bz2"
 83          % (date, rev, platform, hsh))
 84
 85
 86def get_kernel(triple):
 87    os_name = triple.split('-')[-1]
 88    #scrub(os.getenv("CFG_ENABLE_MINGW_CROSS")):
 89    if os_name == "nt" or os_name == "mingw32":
 90        return "winnt"
 91    if os_name == "darwin":
 92        return "macos"
 93    if os_name == "freebsd":
 94        return "freebsd"
 95    return "linux"
 96
 97def get_cpu(triple):
 98    arch = triple.split('-')[0]
 99    if arch == "i686":
100      return "i386"
101    return arch
102
103def get_platform(triple):
104  return "%s-%s" % (get_kernel(triple), get_cpu(triple))
105
106
107def cmd_out(cmdline):
108    p = subprocess.Popen(cmdline,
109                         stdout=subprocess.PIPE)
110    return scrub(p.communicate()[0].strip())
111
112
113def local_rev_info(field):
114    return cmd_out(["git", "--git-dir=" + os.path.join(src_dir, ".git"),
115                    "log", "-n", "1",
116                    "--format=%%%s" % field, "HEAD"])
117
118
119def local_rev_full_sha():
120    return local_rev_info("H").split()[0]
121
122
123def local_rev_short_sha():
124    return local_rev_info("h").split()[0]
125
126
127def local_rev_committer_date():
128    return local_rev_info("ci")
129
130def get_url_to_file(u,f):
131    # no security issue, just to stop partial download leaving a stale file
132    tmpf = f + '.tmp'
133    returncode = subprocess.call(["curl", "-o", tmpf, u])
134    if returncode != 0:
135        os.unlink(tmpf)
136        raise
137    os.rename(tmpf, f)
138
139def snap_filename_hash_part(snap):
140  match = re.match(r".*([a-fA-F\d]{40}).tar.bz2$", snap)
141  if not match:
142    raise Exception("unable to find hash in filename: " + snap)
143  return match.group(1)
144
145def hash_file(x):
146    h = sha_func()
147    h.update(open(x, "rb").read())
148    return scrub(h.hexdigest())
149
150
151def make_snapshot(stage, triple, flag):
152    kernel = get_kernel(triple)
153    platform = get_platform(triple)
154    rev = local_rev_short_sha()
155    date = local_rev_committer_date().split()[0]
156
157    file0 = partial_snapshot_name(date, rev, platform)
158
159    def in_tar_name(fn):
160      cs = re.split(r"[\\/]", fn)
161      if len(cs) >= 2:
162        return os.sep.join(cs[-2:])
163
164    tar = tarfile.open(file0, "w:bz2")
165    for name in snapshot_files[kernel]:
166      dir = stage
167      if stage == "stage1" and re.match(r"^lib/(lib)?std.*", name):
168        dir = "stage0"
169      fn_glob = os.path.join(triple, dir, name)
170      matches = glob.glob(fn_glob)
171      if not matches:
172        raise Exception("Not found file with name like " + fn_glob)
173      if len(matches) == 1:
174        tar.add(matches[0], "rust-stage0/" + in_tar_name(matches[0]))
175      else:
176        raise Exception("Found stale files: \n  %s\n\
177Please make a clean build." % "\n  ".join(matches))
178    tar.close()
179
180    h = hash_file(file0)
181    file1 = full_snapshot_name(date, rev, platform, h)
182
183    shutil.move(file0, file1)
184
185    if flag == "install":
186      # FIXME (#2664): this is an ugly quick hack; pls make it better
187      path  = file1
188      comps = path.split("-")
189      parts = { 'year': comps[2], \
190                'month': comps[3], \
191                'date': comps[4], \
192                'check': comps[5], \
193                'plat': comps[6], \
194                'arch': comps[7], \
195                'sha': comps[8].split(".")[0] }
196
197      shutil.move(path, "dl/" + path)
198      shutil.move('src/snapshots.txt', 'src/snapshots-old.txt')
199
200      newf = open('src/snapshots.txt', 'w')
201      newf.write("T %(year)s-%(month)s-%(date)s %(check)s\n" % parts)
202      newf.write("  %(plat)s-%(arch)s %(sha)s\n\n" % parts)
203
204      oldf = open('src/snapshots-old.txt', 'r')
205      for line in oldf:
206        newf.write(line)
207      oldf.close()
208
209      newf.close()
210
211      os.remove('src/snapshots-old.txt')
212
213
214    return file1