hassle.hassle

  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    args = parser.parse_args()
119
120    args.package = Path(args.package).resolve()
121
122    if args.increment_version and args.increment_version not in [
123        "major",
124        "minor",
125        "patch",
126    ]:
127        raise ValueError(
128            f"Invalid option for -iv/--increment_version: {args.increment_version}"
129        )
130
131    if args.commit_all == "":
132        raise ValueError("Commit message for args.commit_all cannot be empty.")
133
134    return args
135
136
137def main(args: argparse.Namespace = None):
138    if not args:
139        args = get_args()
140
141    pyproject_path = args.package / "pyproject.toml"
142
143    if not pyproject_path.exists():
144        raise FileNotFoundError(f"Could not locate pyproject.toml for {args.package}")
145
146    if args.generate_tests:
147        generate_test_files(args.package)
148
149    if args.run_tests:
150        run_tests(args.package)
151
152    if args.increment_version:
153        hassle_utilities.increment_version(pyproject_path, args.increment_version)
154
155    if args.build:
156        try:
157            shutil.rmtree(f"{args.package}/dist")
158        except Exception as e:
159            pass
160        os.system(f"black {args.package}")
161        os.system(f"isort {args.package}")
162        hassle_utilities.update_dependencies(
163            pyproject_path, args.overwrite_dependencies
164        )
165        hassle_utilities.update_minimum_python_version(pyproject_path)
166        hassle_utilities.generate_docs(args.package)
167        os.system(f"py -m build {args.package}")
168
169    if args.update_changelog:
170        hassle_utilities.update_changelog(pyproject_path)
171        # If we're going to add tag for current version
172        # commit changelog first
173        if args.tag_version:
174            os.chdir(args.package)
175            os.system("git add CHANGELOG.md")
176            os.system('git commit CHANGELOG.md -m "chore: update changelog"')
177
178    if args.commit_all:
179        os.chdir(args.package)
180        if args.commit_all == "build":
181            version = tomlkit.loads(pyproject_path.read_text())["project"]["version"]
182            args.commit_all = f"chore: build v{version}"
183        os.system(f"git add .")
184        os.system(f'git commit -a -m "{args.commit_all}"')
185
186    if args.tag_version:
187        hassle_utilities.tag_version(args.package)
188
189    if args.publish:
190        os.system(f"twine upload {args.package / 'dist' / '*'}")
191
192    if args.install:
193        os.system(
194            f"pip install --no-deps -U --no-cache-dir {args.package.stem if args.publish else args.package}"
195        )
196
197    if args.sync:
198        os.chdir(args.package)
199        os.system(f"git pull --tags origin main")
200        os.system(f"git push origin main:main --tags")
201
202
203if __name__ == "__main__":
204    main(get_args())
def get_args() -> argparse.Namespace:
 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    args = parser.parse_args()
120
121    args.package = Path(args.package).resolve()
122
123    if args.increment_version and args.increment_version not in [
124        "major",
125        "minor",
126        "patch",
127    ]:
128        raise ValueError(
129            f"Invalid option for -iv/--increment_version: {args.increment_version}"
130        )
131
132    if args.commit_all == "":
133        raise ValueError("Commit message for args.commit_all cannot be empty.")
134
135    return args
def main(args: argparse.Namespace = None):
138def main(args: argparse.Namespace = None):
139    if not args:
140        args = get_args()
141
142    pyproject_path = args.package / "pyproject.toml"
143
144    if not pyproject_path.exists():
145        raise FileNotFoundError(f"Could not locate pyproject.toml for {args.package}")
146
147    if args.generate_tests:
148        generate_test_files(args.package)
149
150    if args.run_tests:
151        run_tests(args.package)
152
153    if args.increment_version:
154        hassle_utilities.increment_version(pyproject_path, args.increment_version)
155
156    if args.build:
157        try:
158            shutil.rmtree(f"{args.package}/dist")
159        except Exception as e:
160            pass
161        os.system(f"black {args.package}")
162        os.system(f"isort {args.package}")
163        hassle_utilities.update_dependencies(
164            pyproject_path, args.overwrite_dependencies
165        )
166        hassle_utilities.update_minimum_python_version(pyproject_path)
167        hassle_utilities.generate_docs(args.package)
168        os.system(f"py -m build {args.package}")
169
170    if args.update_changelog:
171        hassle_utilities.update_changelog(pyproject_path)
172        # If we're going to add tag for current version
173        # commit changelog first
174        if args.tag_version:
175            os.chdir(args.package)
176            os.system("git add CHANGELOG.md")
177            os.system('git commit CHANGELOG.md -m "chore: update changelog"')
178
179    if args.commit_all:
180        os.chdir(args.package)
181        if args.commit_all == "build":
182            version = tomlkit.loads(pyproject_path.read_text())["project"]["version"]
183            args.commit_all = f"chore: build v{version}"
184        os.system(f"git add .")
185        os.system(f'git commit -a -m "{args.commit_all}"')
186
187    if args.tag_version:
188        hassle_utilities.tag_version(args.package)
189
190    if args.publish:
191        os.system(f"twine upload {args.package / 'dist' / '*'}")
192
193    if args.install:
194        os.system(
195            f"pip install --no-deps -U --no-cache-dir {args.package.stem if args.publish else args.package}"
196        )
197
198    if args.sync:
199        os.chdir(args.package)
200        os.system(f"git pull --tags origin main")
201        os.system(f"git push origin main:main --tags")