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