rust/src/etc/snapshot.py

304 lines
7.9 KiB
Python
Raw Normal View History

2015-01-29 01:19:28 -06:00
# Copyright 2011-2015 The Rust Project Developers. See the COPYRIGHT
2014-02-02 04:47:02 -06:00
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
2013-01-18 01:28:42 -06:00
2015-01-27 02:22:24 -06:00
import re
import os
import sys
import glob
import tarfile
import shutil
import subprocess
import distutils.spawn
try:
2015-01-27 02:22:24 -06:00
import hashlib
sha_func = hashlib.sha1
except ImportError:
2015-01-27 02:22:24 -06:00
import sha
sha_func = sha.new
2011-05-03 11:25:59 -05:00
def scrub(b):
2015-01-27 02:22:24 -06:00
if sys.version_info >= (3,) and type(b) == bytes:
return b.decode('ascii')
else:
return b
2011-05-03 11:25:59 -05:00
src_dir = scrub(os.getenv("CFG_SRC_DIR"))
2011-05-03 01:37:52 -05:00
if not src_dir:
2015-01-27 02:22:24 -06:00
raise Exception("missing env var CFG_SRC_DIR")
2011-05-03 01:37:52 -05:00
snapshotfile = os.path.join(src_dir, "src", "snapshots.txt")
download_url_base = "https://static.rust-lang.org/stage0-snapshots"
download_dir_base = "dl"
download_unpack_base = os.path.join(download_dir_base, "unpack")
snapshot_files = {
2015-06-30 22:37:11 -05:00
"bitrig": ["bin/rustc"],
"dragonfly": ["bin/rustc"],
"freebsd": ["bin/rustc"],
2015-01-27 02:22:24 -06:00
"linux": ["bin/rustc"],
"macos": ["bin/rustc"],
2015-06-30 22:37:11 -05:00
"netbsd": ["bin/rustc"],
2015-01-29 01:19:28 -06:00
"openbsd": ["bin/rustc"],
2015-06-30 22:37:11 -05:00
"winnt": ["bin/rustc.exe"],
2015-01-27 02:22:24 -06:00
}
winnt_runtime_deps_32 = ["libgcc_s_dw2-1.dll", "libstdc++-6.dll"]
winnt_runtime_deps_64 = ["libgcc_s_seh-1.dll", "libstdc++-6.dll"]
def parse_line(n, line):
2015-01-27 02:22:24 -06:00
global snapshotfile
2015-01-27 02:22:24 -06:00
if re.match(r"\s*$", line):
return None
2015-01-27 02:22:24 -06:00
if re.match(r"^T\s*$", line):
return None
2015-01-27 02:22:24 -06:00
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()}
2015-01-27 02:22:24 -06:00
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)}
2011-05-03 09:23:05 -05:00
def partial_snapshot_name(date, rev, platform):
2015-01-27 02:22:24 -06:00
return ("rust-stage0-%s-%s-%s.tar.bz2" %
(date, rev, platform))
2011-05-03 09:23:05 -05:00
def full_snapshot_name(date, rev, platform, hsh):
2015-01-27 02:22:24 -06:00
return ("rust-stage0-%s-%s-%s-%s.tar.bz2" %
(date, rev, platform, hsh))
2011-11-28 08:06:32 -06:00
def get_kernel(triple):
t = triple.split('-')
if len(t) == 2:
2015-01-27 02:22:24 -06:00
os_name = t[1]
else:
2015-01-27 02:22:24 -06:00
os_name = t[2]
if os_name == "windows":
return "winnt"
2011-11-28 08:06:32 -06:00
if os_name == "darwin":
return "macos"
2012-01-01 11:24:07 -06:00
if os_name == "freebsd":
return "freebsd"
2014-12-19 06:05:06 -06:00
if os_name == "dragonfly":
return "dragonfly"
2015-01-17 01:51:04 -06:00
if os_name == "bitrig":
return "bitrig"
2015-06-30 22:37:11 -05:00
if os_name == "netbsd":
return "netbsd"
2015-01-29 01:19:28 -06:00
if os_name == "openbsd":
return "openbsd"
2011-11-28 08:06:32 -06:00
return "linux"
2015-01-27 02:22:24 -06:00
2011-11-28 08:06:32 -06:00
def get_cpu(triple):
arch = triple.split('-')[0]
if arch == "i686":
2015-01-27 02:22:24 -06:00
return "i386"
2011-11-28 08:06:32 -06:00
return arch
2015-01-27 02:22:24 -06:00
2011-11-28 08:06:32 -06:00
def get_platform(triple):
2015-01-27 02:22:24 -06:00
return "%s-%s" % (get_kernel(triple), get_cpu(triple))
def cmd_out(cmdline):
2015-01-27 02:22:24 -06:00
p = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
2011-05-03 01:37:52 -05:00
return scrub(p.communicate()[0].strip())
def local_rev_info(field):
2011-05-03 11:25:59 -05:00
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")
2015-01-27 02:22:24 -06:00
def get_url_to_file(u, f):
2012-01-17 14:51:31 -06:00
# no security issue, just to stop partial download leaving a stale file
2012-01-17 14:54:23 -06:00
tmpf = f + '.tmp'
returncode = -1
if distutils.spawn.find_executable("curl"):
returncode = subprocess.call(["curl", "-o", tmpf, u])
elif distutils.spawn.find_executable("wget"):
returncode = subprocess.call(["wget", "-O", tmpf, u])
if returncode != 0:
try:
os.unlink(tmpf)
2015-01-27 02:22:24 -06:00
except OSError:
pass
raise Exception("failed to fetch url")
os.rename(tmpf, f)
2015-01-27 02:22:24 -06:00
def snap_filename_hash_part(snap):
2015-01-27 02:22:24 -06:00
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()
2011-05-03 01:37:52 -05:00
h.update(open(x, "rb").read())
return scrub(h.hexdigest())
2011-05-03 09:23:05 -05:00
2015-01-27 02:22:24 -06:00
2014-09-08 18:38:05 -05:00
def get_winnt_runtime_deps(platform):
2015-01-27 02:22:24 -06:00
"""Returns a list of paths of Rust's system runtime dependencies"""
2014-09-08 18:38:05 -05:00
if platform == "winnt-x86_64":
2015-01-27 02:22:24 -06:00
deps = winnt_runtime_deps_64
2014-09-08 18:38:05 -05:00
else:
2015-01-27 02:22:24 -06:00
deps = winnt_runtime_deps_32
runtime_deps = []
2014-09-08 18:38:05 -05:00
path_dirs = os.environ["PATH"].split(os.pathsep)
for name in deps:
2015-01-27 02:22:24 -06:00
for dir in path_dirs:
filepath = os.path.join(dir, name)
if os.path.isfile(filepath):
runtime_deps.append(filepath)
break
else:
raise Exception("Could not find runtime dependency: %s" % name)
return runtime_deps
2011-05-03 09:23:05 -05:00
2015-01-27 02:22:24 -06:00
def make_snapshot(stage, triple):
2011-11-28 08:06:32 -06:00
kernel = get_kernel(triple)
platform = get_platform(triple)
2011-05-03 09:23:05 -05:00
rev = local_rev_short_sha()
date = local_rev_committer_date().split()[0]
file0 = partial_snapshot_name(date, rev, platform)
def in_tar_name(fn):
2015-01-27 02:22:24 -06:00
cs = re.split(r"[\\/]", fn)
if len(cs) >= 2:
return os.sep.join(cs[-2:])
2011-05-03 09:23:05 -05:00
tar = tarfile.open(file0, "w:bz2")
2011-05-03 09:23:05 -05:00
for name in snapshot_files[kernel]:
2015-01-27 02:22:24 -06:00
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))
if kernel == "winnt":
for path in get_winnt_runtime_deps(platform):
tar.add(path, "rust-stage0/bin/" + os.path.basename(path))
tar.add(os.path.join(os.path.dirname(__file__), "third-party"),
"rust-stage0/bin/third-party")
2011-05-03 09:23:05 -05:00
tar.close()
h = hash_file(file0)
file1 = full_snapshot_name(date, rev, platform, h)
shutil.move(file0, file1)
2011-05-03 09:23:05 -05:00
return file1
2015-01-27 02:22:24 -06:00
def curr_snapshot_rev():
2015-01-27 02:22:24 -06:00
i = 0
found_snap = False
date = None
rev = None
f = open(snapshotfile)
for line in f.readlines():
i += 1
parsed = parse_line(i, line)
if not parsed:
continue
2015-01-27 02:22:24 -06:00
if parsed["type"] == "snapshot":
date = parsed["date"]
rev = parsed["rev"]
found_snap = True
break
2015-01-27 02:22:24 -06:00
if not found_snap:
raise Exception("no snapshot entries in file")
2015-01-27 02:22:24 -06:00
return (date, rev)
def determine_curr_snapshot(triple):
2015-01-27 02:22:24 -06:00
i = 0
platform = get_platform(triple)
found_file = False
found_snap = False
hsh = None
date = None
rev = None
f = open(snapshotfile)
for line in f.readlines():
i += 1
parsed = parse_line(i, line)
if not parsed:
continue
if found_snap and parsed["type"] == "file":
if parsed["platform"] == platform:
hsh = parsed["hash"]
found_file = True
break
elif parsed["type"] == "snapshot":
date = parsed["date"]
rev = parsed["rev"]
found_snap = True
if not found_snap:
raise Exception("no snapshot entries in file")
if not found_file:
raise Exception("no snapshot file found for platform %s, rev %s" %
(platform, rev))
return full_snapshot_name(date, rev, platform, hsh)