hassle.hassle_utilities

  1import os
  2
  3import packagelister
  4import vermin
  5from pathier import Pathier
  6
  7from hassle import hassle_config
  8
  9root = Pathier(__file__).parent
 10
 11
 12def increment_version(pyproject_path: Pathier, increment_type: str):
 13    """Increment the project.version field in pyproject.toml.
 14
 15    :param package_path: Path to the package/project directory.
 16
 17    :param increment_type: One from 'major', 'minor', or 'patch'."""
 18    meta = pyproject_path.loads()
 19    major, minor, patch = [int(num) for num in meta["project"]["version"].split(".")]
 20    if increment_type == "major":
 21        major += 1
 22        minor = 0
 23        patch = 0
 24    elif increment_type == "minor":
 25        minor += 1
 26        patch = 0
 27    elif increment_type == "patch":
 28        patch += 1
 29    incremented_version = ".".join(str(num) for num in [major, minor, patch])
 30    meta["project"]["version"] = incremented_version
 31    pyproject_path.dumps(meta)
 32
 33
 34def update_minimum_python_version(pyproject_path: Pathier):
 35    """Use vermin to determine the minimum compatible
 36    Python version and update the corresponding field
 37    in pyproject.toml."""
 38    project_code = "\n".join(
 39        file.read_text() for file in (pyproject_path.parent / "src").rglob("*.py")
 40    )
 41    meta = pyproject_path.loads()
 42    minimum_version = vermin.visit(project_code, vermin.Config()).minimum_versions()[1]
 43    minimum_version = f">={minimum_version[0]}.{minimum_version[1]}"
 44    meta["project"]["requires-python"] = minimum_version
 45    pyproject_path.dumps(meta)
 46
 47
 48def generate_docs(package_path: Pathier):
 49    """Generate project documentation using pdoc."""
 50    try:
 51        (package_path / "docs").delete()
 52    except Exception as e:
 53        pass
 54    os.system(
 55        f"pdoc -o {package_path / 'docs'} {package_path / 'src' / package_path.stem}"
 56    )
 57
 58
 59def update_dependencies(
 60    pyproject_path: Pathier, overwrite: bool, include_versions: bool = False
 61):
 62    """Update dependencies list in pyproject.toml.
 63
 64    :param overwrite: If True, replace the dependencies in pyproject.toml
 65    with the results of packagelister.scan() .
 66    If False, packages returned by packagelister are appended to
 67    the current dependencies in pyproject.toml if they don't already
 68    exist in the field."""
 69    packages = packagelister.scan(pyproject_path.parent)
 70
 71    packages = [
 72        f"{package}~={packages[package]['version']}"
 73        if packages[package]["version"] and include_versions
 74        else f"{package}"
 75        for package in packages
 76        if package != pyproject_path.parent.stem
 77    ]
 78    packages = [
 79        package.replace("speech_recognition", "speechRecognition")
 80        for package in packages
 81    ]
 82    meta = pyproject_path.loads()
 83    if overwrite:
 84        meta["project"]["dependencies"] = packages
 85    else:
 86        for package in packages:
 87            if "~" in package:
 88                name = package.split("~")[0]
 89            elif "=" in package:
 90                name = package.split("=")[0]
 91            else:
 92                name = package
 93            if all(
 94                name not in dependency for dependency in meta["project"]["dependencies"]
 95            ):
 96                meta["project"]["dependencies"].append(package)
 97    pyproject_path.dumps(meta)
 98
 99
100def update_changelog(pyproject_path: Pathier):
101    """Update project changelog."""
102    meta = pyproject_path.loads()
103    if hassle_config.config_exists():
104        config = hassle_config.load_config()
105    else:
106        hassle_config.warn()
107        print("Creating blank hassle_config.toml...")
108        config = hassle_config.load_config()
109    changelog_path = pyproject_path.parent / "CHANGELOG.md"
110    os.system(
111        f"auto-changelog -p {pyproject_path.parent} --tag-prefix {config['git']['tag_prefix']} --unreleased -v {meta['project']['version']} -o {changelog_path}"
112    )
113    changelog = changelog_path.read_text().splitlines()
114    changelog = [line for line in changelog if "Full set of changes:" not in line]
115    changelog_path.write_text("\n".join(changelog))
116
117
118def tag_version(package_path: Pathier):
119    """Add a git tag corresponding
120    to the version number in pyproject.toml."""
121    if hassle_config.config_exists():
122        tag_prefix = hassle_config.load_config()["git"]["tag_prefix"]
123    else:
124        hassle_config.warn()
125        tag_prefix = ""
126    version = (package_path / "pyproject.toml").loads()["project"]["version"]
127    os.chdir(package_path)
128    os.system(f"git tag {tag_prefix}{version}")
def increment_version(pyproject_path: pathier.pathier.Pathier, increment_type: str):
13def increment_version(pyproject_path: Pathier, increment_type: str):
14    """Increment the project.version field in pyproject.toml.
15
16    :param package_path: Path to the package/project directory.
17
18    :param increment_type: One from 'major', 'minor', or 'patch'."""
19    meta = pyproject_path.loads()
20    major, minor, patch = [int(num) for num in meta["project"]["version"].split(".")]
21    if increment_type == "major":
22        major += 1
23        minor = 0
24        patch = 0
25    elif increment_type == "minor":
26        minor += 1
27        patch = 0
28    elif increment_type == "patch":
29        patch += 1
30    incremented_version = ".".join(str(num) for num in [major, minor, patch])
31    meta["project"]["version"] = incremented_version
32    pyproject_path.dumps(meta)

Increment the project.version field in pyproject.toml.

Parameters
  • package_path: Path to the package/project directory.

  • increment_type: One from 'major', 'minor', or 'patch'.

def update_minimum_python_version(pyproject_path: pathier.pathier.Pathier):
35def update_minimum_python_version(pyproject_path: Pathier):
36    """Use vermin to determine the minimum compatible
37    Python version and update the corresponding field
38    in pyproject.toml."""
39    project_code = "\n".join(
40        file.read_text() for file in (pyproject_path.parent / "src").rglob("*.py")
41    )
42    meta = pyproject_path.loads()
43    minimum_version = vermin.visit(project_code, vermin.Config()).minimum_versions()[1]
44    minimum_version = f">={minimum_version[0]}.{minimum_version[1]}"
45    meta["project"]["requires-python"] = minimum_version
46    pyproject_path.dumps(meta)

Use vermin to determine the minimum compatible Python version and update the corresponding field in pyproject.toml.

def generate_docs(package_path: pathier.pathier.Pathier):
49def generate_docs(package_path: Pathier):
50    """Generate project documentation using pdoc."""
51    try:
52        (package_path / "docs").delete()
53    except Exception as e:
54        pass
55    os.system(
56        f"pdoc -o {package_path / 'docs'} {package_path / 'src' / package_path.stem}"
57    )

Generate project documentation using pdoc.

def update_dependencies( pyproject_path: pathier.pathier.Pathier, overwrite: bool, include_versions: bool = False):
60def update_dependencies(
61    pyproject_path: Pathier, overwrite: bool, include_versions: bool = False
62):
63    """Update dependencies list in pyproject.toml.
64
65    :param overwrite: If True, replace the dependencies in pyproject.toml
66    with the results of packagelister.scan() .
67    If False, packages returned by packagelister are appended to
68    the current dependencies in pyproject.toml if they don't already
69    exist in the field."""
70    packages = packagelister.scan(pyproject_path.parent)
71
72    packages = [
73        f"{package}~={packages[package]['version']}"
74        if packages[package]["version"] and include_versions
75        else f"{package}"
76        for package in packages
77        if package != pyproject_path.parent.stem
78    ]
79    packages = [
80        package.replace("speech_recognition", "speechRecognition")
81        for package in packages
82    ]
83    meta = pyproject_path.loads()
84    if overwrite:
85        meta["project"]["dependencies"] = packages
86    else:
87        for package in packages:
88            if "~" in package:
89                name = package.split("~")[0]
90            elif "=" in package:
91                name = package.split("=")[0]
92            else:
93                name = package
94            if all(
95                name not in dependency for dependency in meta["project"]["dependencies"]
96            ):
97                meta["project"]["dependencies"].append(package)
98    pyproject_path.dumps(meta)

Update dependencies list in pyproject.toml.

Parameters
  • overwrite: If True, replace the dependencies in pyproject.toml with the results of packagelister.scan() . If False, packages returned by packagelister are appended to the current dependencies in pyproject.toml if they don't already exist in the field.
def update_changelog(pyproject_path: pathier.pathier.Pathier):
101def update_changelog(pyproject_path: Pathier):
102    """Update project changelog."""
103    meta = pyproject_path.loads()
104    if hassle_config.config_exists():
105        config = hassle_config.load_config()
106    else:
107        hassle_config.warn()
108        print("Creating blank hassle_config.toml...")
109        config = hassle_config.load_config()
110    changelog_path = pyproject_path.parent / "CHANGELOG.md"
111    os.system(
112        f"auto-changelog -p {pyproject_path.parent} --tag-prefix {config['git']['tag_prefix']} --unreleased -v {meta['project']['version']} -o {changelog_path}"
113    )
114    changelog = changelog_path.read_text().splitlines()
115    changelog = [line for line in changelog if "Full set of changes:" not in line]
116    changelog_path.write_text("\n".join(changelog))

Update project changelog.

def tag_version(package_path: pathier.pathier.Pathier):
119def tag_version(package_path: Pathier):
120    """Add a git tag corresponding
121    to the version number in pyproject.toml."""
122    if hassle_config.config_exists():
123        tag_prefix = hassle_config.load_config()["git"]["tag_prefix"]
124    else:
125        hassle_config.warn()
126        tag_prefix = ""
127    version = (package_path / "pyproject.toml").loads()["project"]["version"]
128    os.chdir(package_path)
129    os.system(f"git tag {tag_prefix}{version}")

Add a git tag corresponding to the version number in pyproject.toml.