def _py_import_impl(ctx): # Unpack the file somewhere, and present as a python library. We need to # know all the files in the zip, and that's problematic. For now, we might # be able to get away with just creating and declaring the directory. root = ctx.actions.declare_directory("%s-pyroot" % ctx.attr.name) args = ctx.actions.args() if ctx.file.wheel.path.endswith(".zip") or ctx.file.wheel.path.endswith(".whl"): args.add("x") args.add(ctx.file.wheel.path) args.add_all(["-d", root.path]) ctx.actions.run( outputs = [root], inputs = [ctx.file.wheel], arguments = [args], executable = ctx.executable._zip, ) elif ctx.file.wheel.path.endswith(".tar.gz"): args.add(ctx.file.wheel.path) args.add(root.path) ctx.actions.run( outputs = [root], inputs = [ctx.file.wheel], arguments = [args], executable = ctx.executable._untar, ) else: fail("Unrecognised file extension: %s" % ctx.attr.wheel) runfiles = ctx.runfiles(files = [root]) for dep in ctx.attr.deps: runfiles = runfiles.merge(dep[DefaultInfo].default_runfiles) imports = depset( [ "%s/%s/%s-pyroot" % (ctx.workspace_name, ctx.label.package, ctx.label.name), ], transitive = [dep[PyInfo].imports for dep in ctx.attr.deps], ) transitive_sources = depset( [], transitive = [dep[PyInfo].transitive_sources for dep in ctx.attr.deps], ) py_srcs = ctx.attr.srcs_version info = PyInfo( imports = imports, has_py2_only_sources = py_srcs == "PY2", has_py3_only_sources = py_srcs == "PY3", transitive_sources = transitive_sources, uses_shared_libraries = not ctx.attr.zip_safe, ) return [ DefaultInfo( files = depset([root]), default_runfiles = runfiles, ), info, ] py_import = rule( _py_import_impl, attrs = { "wheel": attr.label( allow_single_file = True, mandatory = True, ), "zip_safe": attr.bool( default = True, ), "python_version": attr.string( default = "PY3", values = ["PY2", "PY3"], ), "srcs_version": attr.string( default = "PY2AND3", values = ["PY2", "PY3", "PY2AND3"], ), "deps": attr.label_list( allow_empty = True, providers = [PyInfo], ), "_zip": attr.label( allow_single_file = True, cfg = "exec", default = "@bazel_tools//tools/zip:zipper", executable = True, ), "_untar": attr.label( cfg = "exec", default = "//py/private:untar", executable = True, ), }, )