Beispiel #1
0
def make_recipe(out_dir: str = "./conda/"):
    """
	Make a Conda ``meta.yaml`` recipe.
	"""

    # stdlib
    import warnings

    # 3rd party
    from consolekit.terminal_colours import Fore, resolve_color_default
    from domdf_python_tools.paths import PathPlus, traverse_to_file

    # this package
    from repo_helper import conda

    warnings.warn(
        "'repo-helper make-recipe' is deprecated. "
        "Please use 'mkrecipe' instead: https://mkrecipe.readthedocs.io/",
        DeprecationWarning,
    )

    repo_dir = traverse_to_file(PathPlus.cwd(), "repo_helper.yml")

    recipe_file = PathPlus(out_dir).resolve() / "meta.yaml"
    recipe_file.parent.maybe_make()

    conda.make_recipe(repo_dir, recipe_file)

    click.echo(Fore.GREEN(f"Wrote recipe to {recipe_file!s}"),
               color=resolve_color_default())
Beispiel #2
0
def requirement(requirement: str, file: Optional[str] = None) -> int:
    """
	Add a requirement.
	"""

    # 3rd party
    from consolekit.utils import abort
    from domdf_python_tools.paths import PathPlus, traverse_to_file
    from domdf_python_tools.stringlist import StringList
    from packaging.requirements import InvalidRequirement
    from packaging.specifiers import SpecifierSet
    from shippinglabel import normalize_keep_dot
    from shippinglabel.requirements import ComparableRequirement, combine_requirements, read_requirements

    repo_dir: PathPlus = traverse_to_file(PathPlus.cwd(), "repo_helper.yml",
                                          "git_helper.yml")

    if file is None:
        requirements_file = repo_dir / "requirements.txt"

        if not requirements_file.is_file():
            raise abort(f"'{file}' not found.")

    else:
        requirements_file = PathPlus(file)

        if not requirements_file.is_file():
            raise abort("'requirements.txt' not found.")

    try:
        req = ComparableRequirement(requirement)
    except InvalidRequirement as e:
        raise BadRequirement(requirement, e)

    response = (PYPI_API / req.name / "json/").get()
    if response.status_code != 200:
        raise click.BadParameter(f"No such project {req.name}")
    else:
        req.name = normalize(response.json()["info"]["name"])
        if not req.specifier:
            req.specifier = SpecifierSet(
                f">={response.json()['info']['version']}")

        click.echo(f"Adding requirement '{req}'")

    requirements, comments, invalid_lines = read_requirements(
        req_file=requirements_file,
        include_invalid=True,
        normalize_func=normalize_keep_dot,
    )

    requirements.add(req)

    buf = StringList([*comments, *invalid_lines])
    buf.extend(str(req) for req in sorted(combine_requirements(requirements)))
    requirements_file.write_lines(buf)

    return 0
Beispiel #3
0
    def determine_project_dir(project_dir: PathLike) -> PathPlus:
        """
		Determine the project base directory.

		Subclasses may override this method to customise the behaviour.

		:param project_dir:
		"""

        return traverse_to_file(PathPlus(project_dir), "pyproject.toml")
Beispiel #4
0
	def __init__(self, repo_path: PathPlus, force: bool = False):
		#:
		self.repo = RepoHelper(traverse_to_file(PathPlus(repo_path), "repo_helper.yml"))

		self.repo.load_settings()

		if not assert_clean(self.repo.target_repo):
			if force:
				click.echo(Fore.RED("Proceeding anyway"), err=True)
			else:
				raise click.Abort

		# pypi_secure_key = "travis_pypi_secure"
		# if self.repo.templates.globals["on_pypi"] and not self.repo.templates.globals[pypi_secure_key]:
		# 	raise abort(f"Cowardly refusing to bump the version when {pypi_secure_key!r} is unset.")
		# TODO: Handle this wrt github actions

		#:
		self.current_version = self.get_current_version()

		#: The path to the bumpversion configuration file.
		self.bumpversion_file = self.repo.target_repo / ".bumpversion.cfg"
Beispiel #5
0
    def __init__(
        self,
        target_repo: PathLike,
        managed_message="This file is managed by 'repo_helper'. Don't edit it directly."
    ):
        import_registered_functions()

        # Walk up the tree until a "repo_helper.yml" or "git_helper.yml" (old name) file is found.
        self.target_repo = traverse_to_file(PathPlus(target_repo),
                                            "repo_helper.yml",
                                            "git_helper.yml")

        self.templates = Environment(  # nosec: B701
            loader=jinja2.FileSystemLoader(str(template_dir)),
            undefined=jinja2.StrictUndefined,
        )
        self.templates.globals["managed_message"] = managed_message
        self.templates.globals["brace"] = brace

        # isort and formate.toml must always run last
        self.files = management + [(make_isort, "isort", [])]
        self.files = management + [(make_formate_toml, "formate", [])]
Beispiel #6
0
def test_traverse_to_file_errors(tmp_pathplus: PathPlus):
    (tmp_pathplus / "foo/bar/baz").parent.maybe_make(parents=True)
    if os.sep == '/':
        with pytest.raises(FileNotFoundError,
                           match="'foo.yml' not found in .*/foo/bar/baz"):
            traverse_to_file(tmp_pathplus / "foo" / "bar" / "baz", "foo.yml")
    elif os.sep == '\\':
        with pytest.raises(FileNotFoundError,
                           match=r"'foo.yml' not found in .*\\foo\\bar\\baz"):
            traverse_to_file(tmp_pathplus / "foo" / "bar" / "baz", "foo.yml")
    else:
        raise NotImplementedError

    with pytest.raises(
            TypeError,
            match="traverse_to_file expected 2 or more arguments, got 1"):
        traverse_to_file(tmp_pathplus)
Beispiel #7
0
def test_traverse_to_file(tmp_pathplus: PathPlus, location: str,
                          expected: str):
    (tmp_pathplus / location).parent.maybe_make(parents=True)
    (tmp_pathplus / location).touch()
    assert traverse_to_file(tmp_pathplus / "foo" / "bar" / "baz",
                            "foo.yml") == tmp_pathplus / expected