From 8a6e19fb3256a50ffe531416b83ba9f2261dc103 Mon Sep 17 00:00:00 2001 From: psadi Date: Thu, 10 Nov 2022 00:02:57 +0530 Subject: [PATCH] feat(better prompts for mainstream commands): user will be prompted for mandatory inputs if none --- .gitignore | 2 ++ bb/__init__.py | 2 +- bb/main.py | 58 +++++++++++++++++++++++++++++++++-------------- bb/pr/copy.py | 0 bb/pr/create.py | 8 +------ bb/utils/cmnd.py | 16 +++++++++---- bb/utils/cp.py | 0 img/bb.png | Bin poetry.lock | 49 ++++++++++++++++++++------------------- pyproject.toml | 8 +++---- 10 files changed, 84 insertions(+), 59 deletions(-) mode change 100644 => 100755 bb/pr/copy.py mode change 100644 => 100755 bb/utils/cp.py mode change 100644 => 100755 img/bb.png diff --git a/.gitignore b/.gitignore index 1365913..0b7a238 100644 --- a/.gitignore +++ b/.gitignore @@ -152,3 +152,5 @@ cython_debug/ .idea/ __pycache__ __PYCACHE__ +node_modules +package*.json diff --git a/bb/__init__.py b/bb/__init__.py index e299f02..824c16e 100755 --- a/bb/__init__.py +++ b/bb/__init__.py @@ -2,7 +2,7 @@ """ bb: A command line utility to manage pull requests in bitbucket """ -__version__ = "0.4.4" +__version__ = "0.4.5" __author__ = "P S, Adithya (psadi) (adithya3494@gmail.com)" __license__ = "MIT" __doc__ = f"VERSION: {__version__} \nAUTHOR: {__author__} \nLICENSE: {__license__}" diff --git a/bb/main.py b/bb/main.py index 4160459..3802448 100755 --- a/bb/main.py +++ b/bb/main.py @@ -38,11 +38,22 @@ def version_callback(value: bool): def error_tip(): console.print( - f"šŸ’» Try running 'bb --verbose [OPTIONS] COMMAND [ARGS]' to debug", + f"\nšŸ’» Try running 'bb --verbose [OPTIONS] COMMAND [ARGS]' to debug", style="dim white", ) +def validate_input(input: any, expected: str, error: str) -> str: + if not input: + input: str = typer.prompt(f"? {expected}") + + if input == None or input.lower() == "none": + console.print(f"{error}", style="red") + raise (typer.Exit(code=1)) + + return input + + @app.callback() def callback( verbose: bool = False, @@ -68,14 +79,14 @@ def create( ): """- create new pull request""" try: - if is_git_repo() is not True: + if not is_git_repo(): console.print("Not a git repository", style="red") raise typer.Exit(code=1) - if not target: - target = typer.prompt("Target Branch") + target = validate_input(target, "Target branch", "Target branch cannot be none") create_pull_request(target, yes, diff, rebase) + except Exception: error_tip() if state["verbose"]: @@ -84,20 +95,24 @@ def create( @app.command() def delete( - id: Optional[List[int]] = typer.Option( - None, help="pull request number(s) to delete" - ), + id: str = typer.Option("", help="pull request number(s) to delete"), yes: bool = typer.Option(False, help="skip confirmation prompt"), diff: bool = typer.Option(False, help="show diff before deleting pull request"), ): """- delete pull request's by id's""" try: - if is_git_repo() is not True: + if not is_git_repo(): console.print("Not a git repository", style="red") raise typer.Exit(code=1) - if not id: - id = typer.prompt("Pull request number(s)").split(",") + + id = validate_input( + False, + "Pull request id(s) to delete\n? ex: id (or) id1, id2", + "Id's cannot be empty", + ).split(",") + delete_pull_request(id, yes, diff) + except Exception: error_tip() if state["verbose"]: @@ -120,11 +135,12 @@ def show( ): """- show pull request's authored & reviewing""" try: - if is_git_repo() is not True: + if not is_git_repo(): console.print("Not a git repository", style="red") raise typer.Exit(code=1) show_pull_request(role.value, all) + except Exception: error_tip() if state["verbose"]: @@ -154,16 +170,21 @@ class Action(str, Enum): @app.command() def review( - id: int = typer.Option("", help="pull request number to review"), + id: str = typer.Option("", help="pull request number to review"), action: Action = Action.none.value, ): """- review Pull Request by ID""" try: - if action.value == "none": - console.print("Action cannot be none", style="red") - raise (typer.Exit(code=1)) - review_pull_request(id, action.value) + id = validate_input(id, "Pull request id to review", "id cannot be none") + action = validate_input( + False if action.value is "none" else action.value, + "Action [approve|unapprove|needs_work]", + "action cannot be none", + ) + + review_pull_request(id, action) + except Exception: error_tip() if state["verbose"]: @@ -172,7 +193,7 @@ def review( @app.command() def merge( - id: int = typer.Option("", help="pull request number to merge"), + id: str = typer.Option("", help="pull request number to merge"), delete_source_branch: bool = typer.Option( False, help="deletes source branch after merge" ), @@ -183,6 +204,8 @@ def merge( ): """- merge pull request by id""" try: + + id = validate_input(id, "Pull request id to merge", "id cannot be none") merge_pull_request(id, delete_source_branch, rebase, yes) except Exception: error_tip() @@ -196,6 +219,7 @@ def diff( ): """- view diff in pull request (file only)""" try: + id = validate_input(id, "Pull request number to show diff", "id cannot be none") show_diff(id) except Exception: error_tip() diff --git a/bb/pr/copy.py b/bb/pr/copy.py old mode 100644 new mode 100755 diff --git a/bb/pr/create.py b/bb/pr/create.py index ab621c8..6a2b8d1 100755 --- a/bb/pr/create.py +++ b/bb/pr/create.py @@ -67,13 +67,7 @@ def create_pull_request(target: str, yes: bool, diff: bool, rebase: bool) -> Non richprint.console.print("Source & target cannot be the same", style="bold red") raise Exit(code=1) - if ( - rebase - or prompt(f"? Do you want rebase '{from_branch}' branch from '{target}' [y/n]") - .lower() - .strip() - == "y" - ): + if rebase: with richprint.live_progress( f"Rebasing {from_branch} with {target} ... " ) as live: diff --git a/bb/utils/cmnd.py b/bb/utils/cmnd.py index 68bbcb9..c181d93 100755 --- a/bb/utils/cmnd.py +++ b/bb/utils/cmnd.py @@ -70,9 +70,15 @@ def git_rebase(target_branch: str) -> None: try: subprocess_run(f"git pull --rebase origin {target_branch}") subprocess_run(f"git push --force-with-lease") - except Exception: - str_print( - "Try running `git diff --diff-filter=U --relative` to know more on local conflicts", - "dim white", - ) + except Exception as ex: + error_code = int(str(ex).split(" ")[-1].replace(".", "")) + error_message = { + 128: "cannot pull with rebase, you have unstaged/uncommitted changes\nplease commit or stash them.", + 1: "Try running `git diff --diff-filter=U --relative` to know more on local conflicts", + } + if error_code in error_message.keys(): + str_print( + error_message[error_code], + "dim white", + ) raise Exit(code=1) diff --git a/bb/utils/cp.py b/bb/utils/cp.py old mode 100644 new mode 100755 diff --git a/img/bb.png b/img/bb.png old mode 100644 new mode 100755 diff --git a/poetry.lock b/poetry.lock index 784dfa4..a81dc12 100755 --- a/poetry.lock +++ b/poetry.lock @@ -18,7 +18,7 @@ python-versions = ">=3.5" dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] -tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] name = "certifi" @@ -37,7 +37,7 @@ optional = false python-versions = ">=3.6.0" [package.extras] -unicode_backport = ["unicodedata2"] +unicode-backport = ["unicodedata2"] [[package]] name = "click" @@ -53,11 +53,11 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" -version = "0.4.5" +version = "0.4.6" description = "Cross-platform colored terminal text." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" [[package]] name = "commonmark" @@ -97,11 +97,11 @@ testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packag [[package]] name = "more-itertools" -version = "8.14.0" +version = "9.0.0" description = "More routines for operating on iterables, beyond itertools" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" [[package]] name = "packaging" @@ -137,7 +137,7 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] -name = "Pygments" +name = "pygments" version = "2.13.0" description = "Pygments is a syntax highlighting package written in Python." category = "main" @@ -205,21 +205,20 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "11.2.0" +version = "12.6.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "main" optional = false -python-versions = ">=3.6.2,<4.0.0" +python-versions = ">=3.6.3,<4.0.0" [package.dependencies] -colorama = ">=0.4.0,<0.5.0" commonmark = ">=0.9.0,<0.10.0" pygments = ">=2.6.0,<3.0.0" -typing-extensions = {version = ">=3.7.4,<5.0", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} [package.extras] jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] @@ -282,20 +281,20 @@ python-versions = "*" [[package]] name = "zipp" -version = "3.8.1" +version = "3.10.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"] -testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = ">=3.7,<4.0.0" -content-hash = "e281849da9144dc385bab012844c7d9b44b580ab58715cad7c8d4642e1130089" +content-hash = "a3dcb43e08a56912916ac69bfe85f8643c5d885a2098058c08294a5a5d579b49" [metadata.files] atomicwrites = [ @@ -318,8 +317,8 @@ click = [ {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] colorama = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] commonmark = [ {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, @@ -334,8 +333,8 @@ importlib-metadata = [ {file = "importlib_metadata-5.0.0.tar.gz", hash = "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab"}, ] more-itertools = [ - {file = "more-itertools-8.14.0.tar.gz", hash = "sha256:c09443cd3d5438b8dafccd867a6bc1cb0894389e90cb53d227456b0b0bccb750"}, - {file = "more_itertools-8.14.0-py3-none-any.whl", hash = "sha256:1bc4f91ee5b1b31ac7ceacc17c09befe6a40a503907baf9c839c229b5095cfd2"}, + {file = "more-itertools-9.0.0.tar.gz", hash = "sha256:5a6257e40878ef0520b1803990e3e22303a41b5714006c32a3fd8304b26ea1ab"}, + {file = "more_itertools-9.0.0-py3-none-any.whl", hash = "sha256:250e83d7e81d0c87ca6bd942e6aeab8cc9daa6096d12c5308f3f92fa5e5c1f41"}, ] packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, @@ -349,7 +348,7 @@ py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] -Pygments = [ +pygments = [ {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, ] @@ -369,8 +368,8 @@ requests = [ {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, ] rich = [ - {file = "rich-11.2.0-py3-none-any.whl", hash = "sha256:d5f49ad91fb343efcae45a2b2df04a9755e863e50413623ab8c9e74f05aee52b"}, - {file = "rich-11.2.0.tar.gz", hash = "sha256:1a6266a5738115017bb64a66c59c717e7aa047b3ae49a011ede4abdeffc6536e"}, + {file = "rich-12.6.0-py3-none-any.whl", hash = "sha256:a4eb26484f2c82589bd9a17c73d32a010b1e29d89f1604cd9bf3a2097b81bb5e"}, + {file = "rich-12.6.0.tar.gz", hash = "sha256:ba3a3775974105c221d31141f2c116f4fd65c5ceb0698657a11e9f295ec93fd0"}, ] shellingham = [ {file = "shellingham-1.5.0-py2.py3-none-any.whl", hash = "sha256:a8f02ba61b69baaa13facdba62908ca8690a94b8119b69f5ec5873ea85f7391b"}, @@ -393,6 +392,6 @@ wcwidth = [ {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] zipp = [ - {file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"}, - {file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"}, + {file = "zipp-3.10.0-py3-none-any.whl", hash = "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1"}, + {file = "zipp-3.10.0.tar.gz", hash = "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8"}, ] diff --git a/pyproject.toml b/pyproject.toml index a9f978a..9bc41e5 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "bb" -version = "0.4.4" +version = "0.4.5" description = "cli to manage bitbucket pull requests" authors = ["psadi "] readme = "README.md" @@ -19,9 +19,9 @@ bb = "bb.main:app" [tool.poetry.dependencies] python = ">=3.7,<4.0.0" typer = {extras = ["all"], version = "^0.4.0"} -requests = "^2.27.1" -rich = "^11.1.0" -pyperclip = "^1.8.2" +requests = ">=2.27.1" +rich = ">=11.1.0" +pyperclip = ">=1.8.2" [tool.poetry.dev-dependencies] pytest = "^5.2"