def process_wheel(path, l_name): # there will be multiple wheel files res = [] all_file_names = os.listdir(path) whl_final = '' max_py_ver = '' for fn in all_file_names: if fn.endswith('.whl') and (fn.find('linux')>=0 or fn.find('any')>=0): # this is a wheel whl_path = os.path.join(path, fn) try: output = inspect_wheel(whl_path) if output['pyver'][-1]> max_py_ver: # -1 means the last one. Use the biggest version number max_py_ver = output['pyver'][-1] whl_final = fn except Exception as e: print("failed to handle {}".format(whl_path)) print(e) if whl_final != '': whl_path = os.path.join(path, whl_final) output = inspect_wheel(whl_path) #print(output.keys()) if 'top_level' not in output['dist_info']: top_levels = [l_name] else: top_levels = output['dist_info']['top_level'] with ZipFile(whl_path, 'r') as zipObj: # Extract all the contents of zip file in current directory source_dir = os.path.join(path, 'tmp') if not os.path.exists(source_dir): zipObj.extractall(source_dir) entry_points = search_targets(source_dir, top_levels) return entry_points return None
def _get_wheel_version(wheel_path: str): version = inspect_wheel(wheel_path)["version"].split(".") if len(version) > 3: dev = int(version[3].replace("dev", "")) else: dev = 0 name = inspect_wheel(wheel_path)["project"] wheel = Wheel(wheel_path, name, version[0], version[1], version[2], dev) return wheel
def is_pure(wheel): """ Check whether wheel given by the passed path is pure. Pure wheels operate independent of the specific Python version and platform. :param wheel: The path to the wheel to inspect :return: True if the wheel is pure """ return (inspect_wheel(wheel).get("dist_info", {}).get("wheel", {}).get("root_is_purelib"))
def get_project_name_and_version(folder_or_wheel: str) -> Tuple[str, str]: """Returns project name for a given project folder (with setup.py) or wheel file. Args: folder_or_wheel: path to the folder or wheel of textx language project Returns: Project name and version Raises: None """ project_metadata = {} # Folder with setup.py inside (project) ... setuppy = join(folder_or_wheel, "setup.py") if isfile(setuppy): from unittest import mock import setuptools with mock.patch.object(setuptools, "setup") as mock_setup: with open(setuppy, "r") as f: exec(f.read()) project_metadata.update(mock_setup.call_args[1]) # ... or setup.cfg setupcfg = join(folder_or_wheel, "setup.cfg") if isfile(setupcfg): try: from configparser import ConfigParser cfg_parser = ConfigParser() cfg_parser.read(setupcfg) project_metadata.update(dict(cfg_parser.items("metadata"))) except Exception: pass # installed from wheel if isfile(folder_or_wheel) and folder_or_wheel.endswith(".whl"): from wheel_inspect import inspect_wheel project_metadata.update(inspect_wheel(folder_or_wheel)) project_metadata.update({"name": project_metadata.get("project")}) return project_metadata.get("name", None), project_metadata.get("version", None)
def process_wheel(filename, url, size, md5, sha256, tmpdir): """ Process an individual wheel. The wheel is downloaded from ``url`` to the directory ``tmpdir``, analyzed with `inspect_wheel()`, and then deleted. The wheel's size and digests are also checked against ``size``, ``md5``, and ``sha256`` (provided by PyPI) to verify download integrity. :return: the results of the call to `inspect_wheel()` """ fpath = join(tmpdir, filename) log.info("Downloading %s from %s ...", filename, url) # Write "user-agent" in lowercase so it overrides requests_download's # header correctly: download(url, fpath, headers={"user-agent": USER_AGENT}) log.info("Inspecting %s ...", filename) try: about = inspect_wheel(fpath) finally: os.remove(fpath) if about["file"]["size"] != size: log.error( "Wheel %s: size mismatch: PyPI reports %d, got %d", size, about["file"]["size"], ) raise ValueError( f'Size mismatch: PyPI reports {size}, got {about["file"]["size"]}') for alg, expected in [("md5", md5), ("sha256", sha256)]: if expected is not None and expected != about["file"]["digests"][alg]: log.error( "Wheel %s: %s hash mismatch: PyPI reports %s, got %s", alg, expected, about["file"]["digests"][alg], ) raise ValueError(f"{alg} hash mismatch: PyPI reports {expected}," f' got {about["file"]["digests"][alg]}') log.info("Finished inspecting %s", filename) return about
def installWhl(self, filePath): filename = filePath.split("/")[-1] try: # validate filename if not self.validate_filename(filename): raise Exception("Invalide filename") package_info = inspect_wheel(filePath)['dist_info']['metadata'] p = Popen(self.command("install")+[filePath], stdin=PIPE, stdout=PIPE, stderr=PIPE) output, err = p.communicate(b"input data that is passed to subprocess' stdin") #(output if p.returncode == 0 else err).decode("utf-8") if p.returncode == 0: output = {**{"message": output.decode("utf-8")}, **{"name": package_info['name'], "version": package_info['version'], "author": package_info['author']}, **{"installed": True}} else: output = {**{"message": err.decode("utf-8")}, **{"filename": filename}, **{"installed": False}} except: output = {"filename": filename, "installed": False, "message": "Invalid File"} return [output]
choices=['project', 'version', 'requirements'], help='Type of information to extract from wheel.') parser.add_argument('wheel_file', action=ActionPath(mode='fr'), help='Path to wheel file.') parser.add_argument('--extras_require', default=[], nargs='+', help='Names of extras_requires to include in requirements list.') return parser if __name__ == '__main__': parser = get_parser() cfg = parser.parse_args() wheel_info = inspect_wheel(cfg.wheel_file()) if cfg.action == 'project': print(wheel_info['project']) elif cfg.action == 'version': print(wheel_info['version'].replace('_', '-')) elif cfg.action == 'requirements': reqs = {} # type: ignore for v in cfg.extras_require: if v not in wheel_info['dist_info']['metadata']['provides_extra']: parser.logger.warning('extras_require "'+v+'" not defined in wheel package.') continue re_extra = re.compile('^extra == "(.+)"$') for require_info in wheel_info['dist_info']['metadata']['requires_dist']: if require_info['marker'] is None or re_extra.sub('\\1', require_info['marker']) in cfg.extras_require: if require_info['name'] not in reqs: print(require_info['name']+require_info['specifier'])
def test_inspect_wheel(whlfile): with open(str(whlfile.with_suffix('.json'))) as fp: expected = json.load(fp) inspection = inspect_wheel(str(whlfile)) assert inspection == expected validate(inspection, SCHEMA)
def main(): fname = sys.argv[1] output = inspect_wheel(fname) print(output['dist_info']['top_level']) print(output['derived']['modules']) return 0
def fetch_metadata(): for file in listdir(DIST): if file.endswith(".whl"): path = Path(DIST, file) return inspect_wheel(path)
def test_inspect_wheel(whlfile, expected): inspection = inspect_wheel(whlfile) assert inspection == expected validate(inspection, WHEEL_SCHEMA)