diff --git a/pex/BUILD b/pex/BUILD index fff2cd86..dce57010 100644 --- a/pex/BUILD +++ b/pex/BUILD @@ -22,7 +22,8 @@ genrule( # Workaround really long shebang lines breaking on linux: # Use a /tmp path, but keep the actual venv inside the bazel outdir. # Avoids having to worry about cleanup, even if sandboxing is off. - TMPF=$$(mktemp) + # `mktemp -t tmp` is used for older OS X versions. + TMPF=$$(mktemp 2>/dev/null || mktemp -t tmp) ln -sf "$$OUTDIR" "$$TMPF" VENV="$${TMPF}/venv" diff --git a/pex/pex_rules.bzl b/pex/pex_rules.bzl index 8e15ea9a..947fb373 100644 --- a/pex/pex_rules.bzl +++ b/pex/pex_rules.bzl @@ -48,6 +48,21 @@ so that Bazel can find your `prelude_bazel` file. pex_file_types = FileType([".py"]) egg_file_types = FileType([".egg", ".whl"]) +req_file_types = FileType([".txt"]) + +# Repos file types according to: https://www.python.org/dev/peps/pep-0527/ +repo_file_types = FileType([ + ".egg", + ".whl", + ".tar.gz", + ".zip", + ".tar", + ".tar.bz2", + ".tar.xz", + ".tar.Z", + ".tgz", + ".tbz" +]) # As much as I think this test file naming convention is a good thing, it's # probably a bad idea to impose it as a policy to all OSS users of these rules, @@ -82,6 +97,16 @@ def _collect_transitive_reqs(ctx): return transitive_reqs +def _collect_repos(ctx): + repos = {} + for dep in ctx.attr.deps: + if hasattr(dep.py, "repos"): + repos += dep.py.repos + for file in repo_file_types.filter(ctx.files.repos): + repos.update({file.dirname : True}) + return repos.keys() + + def _collect_transitive(ctx): return struct( # These rules don't use transitive_sources internally; it's just here for @@ -159,6 +184,7 @@ def _pex_binary_impl(ctx): ctx.configuration.bin_dir, ctx.outputs.executable, '.pex') py = _collect_transitive(ctx) + repos = _collect_repos(ctx) for dep in ctx.attr.deps: transitive_files += dep.default_runfiles.files @@ -184,6 +210,14 @@ def _pex_binary_impl(ctx): arguments += [] if ctx.attr.pex_use_wheels else ["--no-use-wheel"] if ctx.attr.interpreter: arguments += ["--python", ctx.attr.interpreter] + if ctx.attr.no_index: + arguments += ["--no-index"] + if ctx.attr.disable_cache: + arguments += ["--disable-cache"] + for req_file in ctx.files.req_files: + arguments += ["--requirement", req_file.path] + for repo in repos: + arguments += ["--repo", repo] for egg in py.transitive_eggs: arguments += ["--find-links", egg.dirname] arguments += [ @@ -286,6 +320,12 @@ pex_attrs = { "eggs": attr.label_list(flags = ["DIRECT_COMPILE_TIME_INPUT"], allow_files = egg_file_types), "reqs": attr.string_list(), + "req_files": attr.label_list(flags = ["DIRECT_COMPILE_TIME_INPUT"], + allow_files = req_file_types), + "no_index": attr.bool(default=False), + "disable_cache": attr.bool(default=False), + "repos": attr.label_list(flags = ["DIRECT_COMPILE_TIME_INPUT"], + allow_files = repo_file_types), "data": attr.label_list(allow_files = True, cfg = "data"), @@ -350,6 +390,19 @@ Args: It is recommended that you use `eggs` instead where possible. + req_files: Add requirements from the given requirements files. Must be provided as labels. + + This feature will reduce build determinism! It tells pex to resolve all + the transitive python dependencies and fetch them from pypi. + + It is recommended that you use `eggs` or specify `no_index` instead where possible. + + no_index: If True, don't use pypi to resolve dependencies for `reqs` and `req_files`; Default: False + + disable_cache: Disable caching in the pex tool entirely. Default: False + + repos: Additional repository labels (filegroups of wheel/egg files) to look for requirements. + data: Files to include as resources in the final pex binary. Putting other rules here will cause the *outputs* of those rules to be