Exemplo n.º 1
0
def get_origin_wise_metadata(config):
    """Method responsible for extracting metadata based on package origin."""
    if config.repo_github and origin_is_github(config.repo_github):
        url = config.repo_github
        name = config.name
        version, version_tag = handle_gh_version(name=name,
                                                 version=config.version,
                                                 url=url)
        archive_url = generate_git_archive_tarball_url(git_url=url,
                                                       git_ref=version_tag)
        sdist_metadata = get_sdist_metadata(sdist_url=archive_url,
                                            config=config,
                                            with_source=True)
        sdist_metadata["version"] = version
        pypi_metadata = {}
    elif config.from_local_sdist:
        sdist_metadata = get_sdist_metadata(
            sdist_url="",
            config=config,
        )
        pypi_metadata = {}
    else:
        pypi_metadata = get_pypi_metadata(config)
        sdist_metadata = get_sdist_metadata(
            sdist_url=pypi_metadata["sdist_url"], config=config)
    return sdist_metadata, pypi_metadata
Exemplo n.º 2
0
def parse_pkg_name_version(pkg_name: str, ) -> Tuple[str, str, Optional[str]]:
    origin = ""
    if origin_is_local_sdist(pkg_name):
        # Try to get package name and version from sdist archive
        # If the version is normalized, there should be no dash in it
        # Will get them from PKG-INFO later
        filename = Path(pkg_name).stem
        if filename.endswith(".tar"):
            filename = filename[:-4]
        name, _, version = filename.rpartition("-")
        if name == "":
            name = filename
            version = ""
        return "", name, version
    if origin_is_github(pkg_name):
        origin, pkg_name = pkg_name.rsplit("/", 1)
        origin += "/"
        if pkg_name.endswith(".git"):
            pkg_name = pkg_name[:-4]
    pkg = re.match(r"([a-zA-Z0-9\-_\.]+)=+([a-zA-Z0-9\-_\.]+)", pkg_name)
    if pkg:
        pkg_name = origin + pkg.group(1)
        version = pkg.group(2)
        return "", pkg_name, version
    return origin, pkg_name, None
Exemplo n.º 3
0
    def generate_recipe(
        self,
        folder_path: Union[str, Path] = ".",
        mantainers: Optional[List] = None,
        disable_extra: bool = False,
    ):
        """Write the recipe in a location. It will create a folder with the
        package name and the recipe will be there.

        :param folder_path: Path to the folder
        """
        pkg_name = self.get_var_content(self["package"]["name"].values[0])
        if origin_is_github(pkg_name):
            pkg_name = pkg_name.split("/")[-1]
        recipe_dir = Path(folder_path) / pkg_name
        logging.debug(f"Generating recipe on folder: {recipe_dir}")
        if not recipe_dir.is_dir():
            recipe_dir.mkdir()
        recipe_path = recipe_dir / "meta.yaml"

        if not disable_extra:
            self._add_extra_section(mantainers)

        with recipe_path.open("w") as recipe:
            yaml.dump(self.get_clean_yaml(self._yaml), recipe)

        for file_to_recipe in self.files_to_copy:
            name = file_to_recipe.split(os.path.sep)[-1]
            if os.path.isfile(file_to_recipe):
                copyfile(file_to_recipe, os.path.join(recipe_dir, name))
Exemplo n.º 4
0
def parse_pkg_name_version(pkg_name: str) -> Tuple[str, Optional[str]]:
    origin = ""
    if origin_is_github(pkg_name):
        origin, pkg_name = pkg_name.rsplit("/", 1)
        origin += "/"
    pkg = re.match(r"([a-zA-Z0-9\-_\.]+)=+([a-zA-Z0-9\-_\.]+)", pkg_name)
    if pkg:
        pkg_name = origin + pkg.group(1)
        version = pkg.group(2)
        return pkg_name, version
    return origin + pkg_name, None
Exemplo n.º 5
0
def generate_recipes_from_list(list_pkgs, args):
    for pkg_name in list_pkgs:
        logging.debug(f"Starting grayskull for pkg: {pkg_name}")
        from_local_sdist = origin_is_local_sdist(pkg_name)
        if origin_is_github(pkg_name):
            pypi_label = ""
        elif from_local_sdist:
            pypi_label = " (local)"
        else:
            pypi_label = " (pypi)"
        print_msg(f"{Fore.GREEN}\n\n"
                  f"#### Initializing recipe for "
                  f"{Fore.BLUE}{pkg_name}{pypi_label} {Fore.GREEN}####\n")
        is_pkg_file = Path(pkg_name).is_file() and (not from_local_sdist)
        if is_pkg_file:
            args.output = pkg_name
        try:
            recipe, config = create_python_recipe(
                pkg_name,
                is_strict_cf=args.is_strict_conda_forge,
                download=args.download,
                url_pypi_metadata=args.url_pypi_metadata,
                sections_populate=args.sections_populate,
                from_local_sdist=from_local_sdist,
                extras_require_test=args.extras_require_test,
            )
        except requests.exceptions.HTTPError as err:
            print_msg(
                f"{Fore.RED}Package seems to be missing.\nException: {err}\n\n"
            )
            continue

        if args.sections_populate is None or "extra" in args.sections_populate:
            add_extra_section(recipe, args.maintainers)

        generate_recipe(recipe, config, args.output)
        print_msg(f"\n{Fore.GREEN}#### Recipe generated on "
                  f"{os.path.realpath(args.output)} for {pkg_name} ####\n\n")

        if args.is_recursive and config.missing_deps:
            generate_recipes_from_list(config.missing_deps, args)
Exemplo n.º 6
0
def main(args=None):
    if not args:
        args = sys.argv[1:] if sys.argv[1:] else ["--help"]

    parser = argparse.ArgumentParser(
        description="Grayskull - Conda recipe generator")
    pypi_parser = parser.add_subparsers(
        help="Options to generate PyPI recipes")
    pypi_cmds = pypi_parser.add_parser("pypi",
                                       help="Generate recipes based on PyPI")
    pypi_cmds.add_argument("pypi_packages",
                           nargs="+",
                           help="Specify the PyPI packages name.",
                           default=[])
    pypi_cmds.add_argument(
        "--download",
        "-d",
        dest="download",
        action="store_true",
        default=False,
        help="Download the sdist package and PyPI information in the same folder"
        " the recipe is located.",
    )
    pypi_cmds.add_argument(
        "--maintainers",
        "-m",
        dest="maintainers",
        nargs="+",
        help="List of maintainers which will be added to the recipe.",
    )
    parser.add_argument(
        "--version",
        "-v",
        default=False,
        action="store_true",
        dest="version",
        help="Print Grayskull version and exit",
    )
    parser.add_argument(
        "--heman",
        "--shera",
        default=False,
        action="store_true",
        dest="grayskull_power",
        help=argparse.SUPPRESS,
    )
    pypi_cmds.add_argument(
        "--output",
        "-o",
        dest="output",
        default=".",
        help="Path to where the recipe will be created",
    )
    pypi_cmds.add_argument(
        "--stdout",
        dest="stdout",
        default=True,
        help="Disable or enable stdout, if it is False, Grayskull"
        " will disable the prints. Default is True",
    )
    pypi_cmds.add_argument(
        "--list-missing-deps",
        default=False,
        action="store_true",
        dest="list_missing_deps",
        help=
        "After the execution Grayskull will print all the missing dependencies.",
    )
    pypi_cmds.add_argument(
        "--strict-conda-forge",
        default=False,
        action="store_true",
        dest="is_strict_conda_forge",
        help="It will generate the recipes strict for the conda-forge channel.",
    )

    args = parser.parse_args(args)

    if args.version:
        print(grayskull.__version__)
        return

    logging.debug(f"All arguments received: args: {args}")

    if args.grayskull_power:
        print(f"{Fore.BLUE}By the power of Grayskull...\n"
              f"{Style.BRIGHT}I have the power!")
        return

    CLIConfig().stdout = args.stdout
    CLIConfig().list_missing_deps = args.list_missing_deps

    print_msg(Style.RESET_ALL)
    print_msg(clear_screen())

    for pkg_name in args.pypi_packages:
        logging.debug(f"Starting grayskull for pkg: {pkg_name}")
        pypi_label = "" if origin_is_github(pkg_name) else " (pypi)"
        print_msg(f"{Fore.GREEN}\n\n"
                  f"#### Initializing recipe for "
                  f"{Fore.BLUE}{pkg_name}{pypi_label} {Fore.GREEN}####\n")
        pkg_name, pkg_version = parse_pkg_name_version(pkg_name)
        try:
            recipe = GrayskullFactory.create_recipe(
                "pypi",
                pkg_name,
                pkg_version,
                download=args.download,
                is_strict_cf=args.is_strict_conda_forge,
            )
        except requests.exceptions.HTTPError as err:
            print_msg(
                f"{Fore.RED}Package seems to be missing on pypi.\nException: {err}\n\n"
            )
            continue
        recipe.generate_recipe(args.output, mantainers=args.maintainers)
        print_msg(f"\n{Fore.GREEN}#### Recipe generated on "
                  f"{os.path.realpath(args.output)} for {pkg_name} ####\n")