hassle.hassle API documentation

# hassle.hassle

View Source

      1import argparse
      2import os
      3import shutil
      4from pathlib import Path
      5
      6import tomlkit
      7
      8from hassle import hassle_utilities
      9from hassle.generate_tests import generate_test_files
     10from hassle.run_tests import run_tests
     11
     12root = Path(__file__).parent
     13
     14
     15def get_args() -> argparse.Namespace:
     16    parser = argparse.ArgumentParser()
     17
     18    parser.add_argument(
     19        "package",
     20        type=str,
     21        default=".",
     22        nargs="?",
     23        help=""" The name of the package or project to use,
     24        assuming it's a subfolder of your current working directory.
     25        Can also be a full path to the package. If nothing is given,
     26        the current working directory will be used.""",
     27    )
     28
     29    parser.add_argument(
     30        "-b", "--build", action="store_true", help=""" Build the package. """
     31    )
     32
     33    parser.add_argument(
     34        "-t",
     35        "--tag_version",
     36        action="store_true",
     37        help=""" Add a git tag corresponding to the version in pyproject.toml. """,
     38    )
     39
     40    parser.add_argument(
     41        "-i",
     42        "--install",
     43        action="store_true",
     44        help=""" Install the package from source. """,
     45    )
     46
     47    parser.add_argument(
     48        "-iv",
     49        "--increment_version",
     50        type=str,
     51        default=None,
     52        help=""" Increment version in pyproject.toml.
     53        Can be one of "major", "minor", or "patch". """,
     54    )
     55
     56    parser.add_argument(
     57        "-p",
     58        "--publish",
     59        action="store_true",
     60        help=""" Publish package to PyPi.
     61        Note: You must have configured twine
     62        and registered a PyPi account/generated an API
     63        key to use this option.""",
     64    )
     65
     66    parser.add_argument(
     67        "-rt",
     68        "--run_tests",
     69        action="store_true",
     70        help=""" Run tests for the package. """,
     71    )
     72
     73    parser.add_argument(
     74        "-gt",
     75        "--generate_tests",
     76        action="store_true",
     77        help=""" Generate tests for the package. """,
     78    )
     79
     80    parser.add_argument(
     81        "-uc",
     82        "--update_changelog",
     83        action="store_true",
     84        help=""" Update changelog file. """,
     85    )
     86
     87    parser.add_argument(
     88        "-od",
     89        "--overwrite_dependencies",
     90        action="store_true",
     91        help=""" When building a package, packagelister will be used
     92        to update the dependencies list in pyproject.toml.
     93        The default behavior is to append any new dependencies to
     94        the current list so as not to erase any manually added dependencies
     95        that packagelister may not detect. If you don't have any manually
     96        added dependencies and want to remove any dependencies that your
     97        project no longer uses, pass this flag.""",
     98    )
     99
    100    parser.add_argument(
    101        "-ca",
    102        "--commit_all",
    103        type=str,
    104        default=None,
    105        help=""" Git stage and commit all tracked files
    106        with this supplied commit message.
    107        If 'build' is passed, all commits will have
    108        message: 'chore: build v{current_version}""",
    109    )
    110
    111    parser.add_argument(
    112        "-s",
    113        "--sync",
    114        action="store_true",
    115        help=""" Pull from github, then push current commit to repo. """,
    116    )
    117
    118    parser.add_argument(
    119        "-dv",
    120        "--dependency_versions",
    121        action="store_true",
    122        help=""" Include version specifiers for dependencies in
    123        pyproject.toml.""",
    124    )
    125
    126    parser.add_argument(
    127        "-up",
    128        "--update",
    129        type=str,
    130        default=None,
    131        help=""" Excpects one argument: "major", "minor", or "patch".
    132        Passing "-up minor" is equivalent to passing the cli string: "-b -t -i -iv minor -uc -ca build -s".
    133        To publish the updated package, the -p/--publish switch needs to be added to the cli input.""",
    134    )
    135
    136    args = parser.parse_args()
    137
    138    args.package = Path(args.package).resolve()
    139
    140    if args.update:
    141        args.build = True
    142        args.tag_version = True
    143        args.install = True
    144        args.increment_version = args.update
    145        args.update_changelog = True
    146        args.commit_all = "build"
    147        args.sync = True
    148
    149    if args.increment_version and args.increment_version not in [
    150        "major",
    151        "minor",
    152        "patch",
    153    ]:
    154        raise ValueError(
    155            f"Invalid option for -iv/--increment_version: {args.increment_version}"
    156        )
    157
    158    if args.commit_all == "":
    159        raise ValueError("Commit message for args.commit_all cannot be empty.")
    160
    161    return args
    162
    163
    164def main(args: argparse.Namespace = None):
    165    if not args:
    166        args = get_args()
    167
    168    pyproject_path = args.package / "pyproject.toml"
    169
    170    if not pyproject_path.exists():
    171        raise FileNotFoundError(f"Could not locate pyproject.toml for {args.package}")
    172
    173    if args.generate_tests:
    174        generate_test_files(args.package)
    175
    176    if args.run_tests:
    177        run_tests(args.package)
    178
    179    if args.increment_version:
    180        hassle_utilities.increment_version(pyproject_path, args.increment_version)
    181
    182    if args.build:
    183        try:
    184            shutil.rmtree(f"{args.package}/dist")
    185        except Exception as e:
    186            pass
    187        os.system(f"black {args.package}")
    188        os.system(f"isort {args.package}")
    189        hassle_utilities.update_dependencies(
    190            pyproject_path, args.overwrite_dependencies
    191        )
    192        hassle_utilities.update_minimum_python_version(pyproject_path)
    193        hassle_utilities.generate_docs(args.package)
    194        os.system(f"py -m build {args.package}")
    195
    196    if args.update_changelog:
    197        hassle_utilities.update_changelog(pyproject_path)
    198        # If we're going to add tag for current version
    199        # commit changelog first
    200        if args.tag_version:
    201            os.chdir(args.package)
    202            os.system("git add CHANGELOG.md")
    203            os.system('git commit CHANGELOG.md -m "chore: update changelog"')
    204
    205    if args.commit_all:
    206        os.chdir(args.package)
    207        if args.commit_all == "build":
    208            version = tomlkit.loads(pyproject_path.read_text())["project"]["version"]
    209            args.commit_all = f"chore: build v{version}"
    210        os.system("git add .")
    211        os.system(f'git commit -m "{args.commit_all}"')
    212
    213    if args.tag_version:
    214        hassle_utilities.tag_version(args.package)
    215
    216    if args.publish:
    217        os.system(f"twine upload {args.package / 'dist' / '*'}")
    218
    219    if args.install:
    220        os.system(f"pip install {args.package} --no-deps --upgrade --no-cache-dir")
    221
    222    if args.sync:
    223        os.chdir(args.package)
    224        os.system(f"git pull --tags origin main")
    225        os.system(f"git push origin main:main --tags")
    226
    227
    228if __name__ == "__main__":
    229    main(get_args())

def get_args() -> argparse.Namespace: View Source

     16def get_args() -> argparse.Namespace:
     17    parser = argparse.ArgumentParser()
     18
     19    parser.add_argument(
     20        "package",
     21        type=str,
     22        default=".",
     23        nargs="?",
     24        help=""" The name of the package or project to use,
     25        assuming it's a subfolder of your current working directory.
     26        Can also be a full path to the package. If nothing is given,
     27        the current working directory will be used.""",
     28    )
     29
     30    parser.add_argument(
     31        "-b", "--build", action="store_true", help=""" Build the package. """
     32    )
     33
     34    parser.add_argument(
     35        "-t",
     36        "--tag_version",
     37        action="store_true",
     38        help=""" Add a git tag corresponding to the version in pyproject.toml. """,
     39    )
     40
     41    parser.add_argument(
     42        "-i",
     43        "--install",
     44        action="store_true",
     45        help=""" Install the package from source. """,
     46    )
     47
     48    parser.add_argument(
     49        "-iv",
     50        "--increment_version",
     51        type=str,
     52        default=None,
     53        help=""" Increment version in pyproject.toml.
     54        Can be one of "major", "minor", or "patch". """,
     55    )
     56
     57    parser.add_argument(
     58        "-p",
     59        "--publish",
     60        action="store_true",
     61        help=""" Publish package to PyPi.
     62        Note: You must have configured twine
     63        and registered a PyPi account/generated an API
     64        key to use this option.""",
     65    )
     66
     67    parser.add_argument(
     68        "-rt",
     69        "--run_tests",
     70        action="store_true",
     71        help=""" Run tests for the package. """,
     72    )
     73
     74    parser.add_argument(
     75        "-gt",
     76        "--generate_tests",
     77        action="store_true",
     78        help=""" Generate tests for the package. """,
     79    )
     80
     81    parser.add_argument(
     82        "-uc",
     83        "--update_changelog",
     84        action="store_true",
     85        help=""" Update changelog file. """,
     86    )
     87
     88    parser.add_argument(
     89        "-od",
     90        "--overwrite_dependencies",
     91        action="store_true",
     92        help=""" When building a package, packagelister will be used
     93        to update the dependencies list in pyproject.toml.
     94        The default behavior is to append any new dependencies to
     95        the current list so as not to erase any manually added dependencies
     96        that packagelister may not detect. If you don't have any manually
     97        added dependencies and want to remove any dependencies that your
     98        project no longer uses, pass this flag.""",
     99    )
    100
    101    parser.add_argument(
    102        "-ca",
    103        "--commit_all",
    104        type=str,
    105        default=None,
    106        help=""" Git stage and commit all tracked files
    107        with this supplied commit message.
    108        If 'build' is passed, all commits will have
    109        message: 'chore: build v{current_version}""",
    110    )
    111
    112    parser.add_argument(
    113        "-s",
    114        "--sync",
    115        action="store_true",
    116        help=""" Pull from github, then push current commit to repo. """,
    117    )
    118
    119    parser.add_argument(
    120        "-dv",
    121        "--dependency_versions",
    122        action="store_true",
    123        help=""" Include version specifiers for dependencies in
    124        pyproject.toml.""",
    125    )
    126
    127    parser.add_argument(
    128        "-up",
    129        "--update",
    130        type=str,
    131        default=None,
    132        help=""" Excpects one argument: "major", "minor", or "patch".
    133        Passing "-up minor" is equivalent to passing the cli string: "-b -t -i -iv minor -uc -ca build -s".
    134        To publish the updated package, the -p/--publish switch needs to be added to the cli input.""",
    135    )
    136
    137    args = parser.parse_args()
    138
    139    args.package = Path(args.package).resolve()
    140
    141    if args.update:
    142        args.build = True
    143        args.tag_version = True
    144        args.install = True
    145        args.increment_version = args.update
    146        args.update_changelog = True
    147        args.commit_all = "build"
    148        args.sync = True
    149
    150    if args.increment_version and args.increment_version not in [
    151        "major",
    152        "minor",
    153        "patch",
    154    ]:
    155        raise ValueError(
    156            f"Invalid option for -iv/--increment_version: {args.increment_version}"
    157        )
    158
    159    if args.commit_all == "":
    160        raise ValueError("Commit message for args.commit_all cannot be empty.")
    161
    162    return args

def main(args: argparse.Namespace = None): View Source

    165def main(args: argparse.Namespace = None):
    166    if not args:
    167        args = get_args()
    168
    169    pyproject_path = args.package / "pyproject.toml"
    170
    171    if not pyproject_path.exists():
    172        raise FileNotFoundError(f"Could not locate pyproject.toml for {args.package}")
    173
    174    if args.generate_tests:
    175        generate_test_files(args.package)
    176
    177    if args.run_tests:
    178        run_tests(args.package)
    179
    180    if args.increment_version:
    181        hassle_utilities.increment_version(pyproject_path, args.increment_version)
    182
    183    if args.build:
    184        try:
    185            shutil.rmtree(f"{args.package}/dist")
    186        except Exception as e:
    187            pass
    188        os.system(f"black {args.package}")
    189        os.system(f"isort {args.package}")
    190        hassle_utilities.update_dependencies(
    191            pyproject_path, args.overwrite_dependencies
    192        )
    193        hassle_utilities.update_minimum_python_version(pyproject_path)
    194        hassle_utilities.generate_docs(args.package)
    195        os.system(f"py -m build {args.package}")
    196
    197    if args.update_changelog:
    198        hassle_utilities.update_changelog(pyproject_path)
    199        # If we're going to add tag for current version
    200        # commit changelog first
    201        if args.tag_version:
    202            os.chdir(args.package)
    203            os.system("git add CHANGELOG.md")
    204            os.system('git commit CHANGELOG.md -m "chore: update changelog"')
    205
    206    if args.commit_all:
    207        os.chdir(args.package)
    208        if args.commit_all == "build":
    209            version = tomlkit.loads(pyproject_path.read_text())["project"]["version"]
    210            args.commit_all = f"chore: build v{version}"
    211        os.system("git add .")
    212        os.system(f'git commit -m "{args.commit_all}"')
    213
    214    if args.tag_version:
    215        hassle_utilities.tag_version(args.package)
    216
    217    if args.publish:
    218        os.system(f"twine upload {args.package / 'dist' / '*'}")
    219
    220    if args.install:
    221        os.system(f"pip install {args.package} --no-deps --upgrade --no-cache-dir")
    222
    223    if args.sync:
    224        os.chdir(args.package)
    225        os.system(f"git pull --tags origin main")
    226        os.system(f"git push origin main:main --tags")