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 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( 221 f"pip install {args.package.stem if args.publish else args.package} --no-deps --upgrade --no-cache-dir" 222 ) 223 224 if args.sync: 225 os.chdir(args.package) 226 os.system(f"git pull --tags origin main") 227 os.system(f"git push origin main:main --tags") 228 229 230if __name__ == "__main__": 231 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 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):
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( 222 f"pip install {args.package.stem if args.publish else args.package} --no-deps --upgrade --no-cache-dir" 223 ) 224 225 if args.sync: 226 os.chdir(args.package) 227 os.system(f"git pull --tags origin main") 228 os.system(f"git push origin main:main --tags")