distutils_rust: download vendored crates from LFS

Summary: Switch from dewey to in-repo LFS utility.

Test Plan:
Run `make local` on my Arch Linux. Check `hg-vendored-crates.tar.gz` was
downloaded and stored in `build/`. Run `make local` again and make sure it
says:

  hg-vendored-crates.tar.gz was already downloaded and up-to-date

Reviewers: mbthomas, #mercurial

Reviewed By: mbthomas

Differential Revision: https://phabricator.intern.facebook.com/D6706906

Signature: 6706906:1515723430:233ccbb47286dbc4e5d856ff4b20c848b281928c
This commit is contained in:
Jun Wu 2018-01-11 17:16:44 -08:00
parent e53b0261c1
commit 32d36d135d
2 changed files with 31 additions and 42 deletions

View File

@ -3,6 +3,7 @@
# Copyright 2017 Facebook, Inc. # Copyright 2017 Facebook, Inc.
from __future__ import absolute_import from __future__ import absolute_import
import contextlib
import distutils import distutils
import distutils.command.build import distutils.command.build
import distutils.core import distutils.core
@ -13,6 +14,18 @@ import shutil
import subprocess import subprocess
import tarfile import tarfile
SCRIPT_ROOT = os.path.realpath(os.path.join(__file__, '../..'))
LFS_SCRIPT_PATH = os.path.join(SCRIPT_ROOT, 'fb/tools/lfs.py')
@contextlib.contextmanager
def chdir(path):
cwd = os.getcwd()
try:
os.chdir(path)
yield
finally:
os.chdir(cwd)
class RustExtension(object): class RustExtension(object):
"""Data for a Rust extension. """Data for a Rust extension.
@ -32,25 +45,20 @@ class RustExtension(object):
self.manifest = manifest or 'Cargo.toml' self.manifest = manifest or 'Cargo.toml'
class RustVendoredCrates(object): class RustVendoredCrates(object):
"""Data for Rust vendored crates stored in Dewey. """Data for Rust vendored crates stored in LFS.
'name' is the name of the vendoring set, and is also the Dewey tag. 'name' is the name of the vendoring set, and is also the LFS name (with
".tar.gz" appended) to download.
'project' is the Dewey project the vendored crates are stored in.
'hashfile' is the filename that stores the Dewey hash that should be
downloaded.
'path' is the path in Dewey of the file to download.
'dest' is the directory into which the archive should be extracted. 'dest' is the directory into which the archive should be extracted.
""" """
def __init__(self, name, project=None, hashfile=None, path=None, dest=None): def __init__(self, name, dest=None):
self.name = name self.name = name
self.project = project self.dest = dest or os.getcwd()
self.hashfile = hashfile or '.' + name
self.path = path or name + '.tar.gz' @property
self.dest = dest or '.' def filename(self):
return '%s.tar.gz' % self.name
class BuildRustExt(distutils.core.Command): class BuildRustExt(distutils.core.Command):
@ -126,40 +134,21 @@ class BuildRustExt(distutils.core.Command):
return os.path.join(package_dir, name) return os.path.join(package_dir, name)
def download_vendored_crates(self, ven): def download_vendored_crates(self, ven):
commit = open(ven.hashfile).read()
desttarfile = os.path.join(ven.dest, ven.path)
desthashfile = desttarfile + ".hash"
if (os.path.exists(ven.dest) and
os.path.exists(desthashfile) and
commit == open(desthashfile).read()):
# Already downloaded, nothing to do.
return
try: try:
os.makedirs(ven.dest) os.makedirs(ven.dest)
except OSError: except OSError:
pass pass
distutils.log.info("downloading vendored crates '%s'", ven.name) distutils.log.info("downloading vendored crates '%s'", ven.name)
cmd = ["dewey", "cat"] cmd = [LFS_SCRIPT_PATH, 'download', ven.filename]
if ven.project is not None: with chdir(ven.dest):
cmd += ["--project", ven.project] rc = subprocess.call(cmd)
cmd += [ if rc:
"--commit", commit, raise distutils.errors.CompileError(
"--tag", ven.name, "download of Rust vendored crates '%s' failed" % ven.name)
"--path", ven.path,
"--dest", desttarfile]
rc = subprocess.call(cmd) with tarfile.open(ven.filename, 'r:gz') as tar:
if rc: tar.extractall(ven.dest)
raise distutils.errors.CompileError(
"download of Rust vendored crates '%s' failed" % ven.name)
with tarfile.open(desttarfile, 'r:gz') as tar:
tar.extractall(ven.dest)
os.remove(desttarfile)
with open(desthashfile, 'w') as f:
f.write(commit)
def build_ext(self, ext): def build_ext(self, ext):
distutils.log.info("building '%s' extension", ext.name) distutils.log.info("building '%s' extension", ext.name)

View File

@ -1285,7 +1285,7 @@ def build_libraries(self, libraries):
distutils.command.build_clib.build_clib.build_libraries = build_libraries distutils.command.build_clib.build_clib.build_libraries = build_libraries
rustvendoredcrates = [ rustvendoredcrates = [
RustVendoredCrates('hg-vendored-crates', project='fbsource', dest='build'), RustVendoredCrates('hg-vendored-crates', dest='build'),
] ]
rustextmodules = [ rustextmodules = [