/src/etc/snapshot.py
http://github.com/jruderman/rust · Python · 214 lines · 166 code · 45 blank · 3 comment · 29 complexity · 9eab4e52dbe36492b2b910606566c7ab MD5 · raw file
- import re, os, sys, glob, tarfile, shutil, subprocess, tempfile
- try:
- import hashlib
- sha_func = hashlib.sha1
- except ImportError:
- import sha
- sha_func = sha.new
- def scrub(b):
- if sys.version_info >= (3,) and type(b) == bytes:
- return b.decode('ascii')
- else:
- return b
- src_dir = scrub(os.getenv("CFG_SRC_DIR"))
- if not src_dir:
- raise Exception("missing env var CFG_SRC_DIR")
- snapshotfile = os.path.join(src_dir, "src", "snapshots.txt")
- download_url_base = "http://dl.rust-lang.org/stage0-snapshots"
- download_dir_base = "dl"
- download_unpack_base = os.path.join(download_dir_base, "unpack")
- snapshot_files = {
- "linux": ["bin/rustc",
- "lib/libcore-*.so",
- "lib/libstd-*.so",
- "lib/librustc-*.so",
- "lib/libsyntax-*.so",
- "lib/librustrt.so",
- "lib/librustllvm.so"],
- "macos": ["bin/rustc",
- "lib/libcore-*.dylib",
- "lib/libstd-*.dylib",
- "lib/librustc-*.dylib",
- "lib/libsyntax-*.dylib",
- "lib/librustrt.dylib",
- "lib/librustllvm.dylib"],
- "winnt": ["bin/rustc.exe",
- "bin/core-*.dll",
- "bin/std-*.dll",
- "bin/rustc-*.dll",
- "bin/syntax-*.dll",
- "bin/rustrt.dll",
- "bin/rustllvm.dll"],
- "freebsd": ["bin/rustc",
- "lib/libcore-*.so",
- "lib/libstd-*.so",
- "lib/librustc-*.so",
- "lib/libsyntax-*.so",
- "lib/librustrt.so",
- "lib/librustllvm.so"]
- }
- def parse_line(n, line):
- global snapshotfile
- if re.match(r"\s*$", line): return None
- if re.match(r"^T\s*$", line): return None
- match = re.match(r"\s+([\w_-]+) ([a-fA-F\d]{40})\s*$", line)
- if match:
- return { "type": "file",
- "platform": match.group(1),
- "hash": match.group(2).lower() }
- match = re.match(r"([ST]) (\d{4}-\d{2}-\d{2}) ([a-fA-F\d]+)\s*$", line);
- if (not match):
- raise Exception("%s:%d:E syntax error" % (snapshotfile, n))
- return {"type": "snapshot",
- "date": match.group(2),
- "rev": match.group(3)}
- def partial_snapshot_name(date, rev, platform):
- return ("rust-stage0-%s-%s-%s.tar.bz2"
- % (date, rev, platform))
- def full_snapshot_name(date, rev, platform, hsh):
- return ("rust-stage0-%s-%s-%s-%s.tar.bz2"
- % (date, rev, platform, hsh))
- def get_kernel(triple):
- os_name = triple.split('-')[-1]
- #scrub(os.getenv("CFG_ENABLE_MINGW_CROSS")):
- if os_name == "nt" or os_name == "mingw32":
- return "winnt"
- if os_name == "darwin":
- return "macos"
- if os_name == "freebsd":
- return "freebsd"
- return "linux"
- def get_cpu(triple):
- arch = triple.split('-')[0]
- if arch == "i686":
- return "i386"
- return arch
- def get_platform(triple):
- return "%s-%s" % (get_kernel(triple), get_cpu(triple))
- def cmd_out(cmdline):
- p = subprocess.Popen(cmdline,
- stdout=subprocess.PIPE)
- return scrub(p.communicate()[0].strip())
- def local_rev_info(field):
- return cmd_out(["git", "--git-dir=" + os.path.join(src_dir, ".git"),
- "log", "-n", "1",
- "--format=%%%s" % field, "HEAD"])
- def local_rev_full_sha():
- return local_rev_info("H").split()[0]
- def local_rev_short_sha():
- return local_rev_info("h").split()[0]
- def local_rev_committer_date():
- return local_rev_info("ci")
- def get_url_to_file(u,f):
- # no security issue, just to stop partial download leaving a stale file
- tmpf = f + '.tmp'
- returncode = subprocess.call(["curl", "-o", tmpf, u])
- if returncode != 0:
- os.unlink(tmpf)
- raise
- os.rename(tmpf, f)
- def snap_filename_hash_part(snap):
- match = re.match(r".*([a-fA-F\d]{40}).tar.bz2$", snap)
- if not match:
- raise Exception("unable to find hash in filename: " + snap)
- return match.group(1)
- def hash_file(x):
- h = sha_func()
- h.update(open(x, "rb").read())
- return scrub(h.hexdigest())
- def make_snapshot(stage, triple, flag):
- kernel = get_kernel(triple)
- platform = get_platform(triple)
- rev = local_rev_short_sha()
- date = local_rev_committer_date().split()[0]
- file0 = partial_snapshot_name(date, rev, platform)
- def in_tar_name(fn):
- cs = re.split(r"[\\/]", fn)
- if len(cs) >= 2:
- return os.sep.join(cs[-2:])
- tar = tarfile.open(file0, "w:bz2")
- for name in snapshot_files[kernel]:
- dir = stage
- if stage == "stage1" and re.match(r"^lib/(lib)?std.*", name):
- dir = "stage0"
- fn_glob = os.path.join(triple, dir, name)
- matches = glob.glob(fn_glob)
- if not matches:
- raise Exception("Not found file with name like " + fn_glob)
- if len(matches) == 1:
- tar.add(matches[0], "rust-stage0/" + in_tar_name(matches[0]))
- else:
- raise Exception("Found stale files: \n %s\n\
- Please make a clean build." % "\n ".join(matches))
- tar.close()
- h = hash_file(file0)
- file1 = full_snapshot_name(date, rev, platform, h)
- shutil.move(file0, file1)
- if flag == "install":
- # FIXME (#2664): this is an ugly quick hack; pls make it better
- path = file1
- comps = path.split("-")
- parts = { 'year': comps[2], \
- 'month': comps[3], \
- 'date': comps[4], \
- 'check': comps[5], \
- 'plat': comps[6], \
- 'arch': comps[7], \
- 'sha': comps[8].split(".")[0] }
- shutil.move(path, "dl/" + path)
- shutil.move('src/snapshots.txt', 'src/snapshots-old.txt')
- newf = open('src/snapshots.txt', 'w')
- newf.write("T %(year)s-%(month)s-%(date)s %(check)s\n" % parts)
- newf.write(" %(plat)s-%(arch)s %(sha)s\n\n" % parts)
- oldf = open('src/snapshots-old.txt', 'r')
- for line in oldf:
- newf.write(line)
- oldf.close()
- newf.close()
- os.remove('src/snapshots-old.txt')
- return file1