diff --git a/.travis.yml b/.travis.yml index 97296634..f1d8b83f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,21 +60,6 @@ matrix: env: TEST=bench script: python -m unittest -v bench.tests.test_utils && python -m unittest -v bench.tests.test_init - - name: "Python 3.7 Easy Install" - python: 3.7 - env: TEST=easy_install - script: sudo python $TRAVIS_BUILD_DIR/install.py --user travis --run-travis --production --verbose - - - name: "Python 3.8 Easy Install" - python: 3.8 - env: TEST=easy_install - script: sudo python $TRAVIS_BUILD_DIR/install.py --user travis --run-travis --production --verbose - - - name: "Python 3.9 Easy Install" - python: 3.9 - env: TEST=easy_install - script: sudo python $TRAVIS_BUILD_DIR/install.py --user travis --run-travis --production --verbose - install: - pip3 install urllib3 pyOpenSSL ndg-httpsclient pyasn1 diff --git a/bench/app.py b/bench/app.py index 1acb8b65..315eec6c 100755 --- a/bench/app.py +++ b/bench/app.py @@ -115,7 +115,7 @@ class AppMeta: name = url if url else self.name if name.startswith("git@") or name.startswith("ssh://"): self.use_ssh = True - _first_part, _second_part = name.split(":") + _first_part, _second_part = self.name.rsplit(":", 1) self.remote_server = _first_part.split("@")[-1] self.org, _repo = _second_part.rsplit("/", 1) else: @@ -485,6 +485,13 @@ def new_app(app, no_git=None, bench_path="."): # For backwards compatibility app = app.lower().replace(" ", "_").replace("-", "_") + if app[0].isdigit() or "." in app: + click.secho( + "App names cannot start with numbers(digits) or have dot(.) in them", + fg="red" + ) + return + apps = os.path.abspath(os.path.join(bench_path, "apps")) args = ["make-app", apps, app] if no_git: diff --git a/bench/tests/test_utils.py b/bench/tests/test_utils.py index 3c2b3307..f91e8785 100644 --- a/bench/tests/test_utils.py +++ b/bench/tests/test_utils.py @@ -73,3 +73,7 @@ class TestUtils(unittest.TestCase): self.assertEqual("11.0", fake_bench.apps.states["frappe"]["version"]) shutil.rmtree(bench_dir) + + def test_ssh_ports(self): + app = App("git@github.com:22:frappe/frappe") + self.assertEqual((app.use_ssh, app.org, app.repo), (True, "frappe", "frappe")) \ No newline at end of file diff --git a/bench/utils/__init__.py b/bench/utils/__init__.py index 45cd1dce..d0bb0383 100644 --- a/bench/utils/__init__.py +++ b/bench/utils/__init__.py @@ -51,10 +51,9 @@ def is_frappe_app(directory: str) -> bool: def is_valid_frappe_branch(frappe_path:str, frappe_branch:str): - """ Check if a branch exists in a repo. Throws InvalidRemoteException if branch is not found + """Check if a branch exists in a repo. Throws InvalidRemoteException if branch is not found - Uses github's api without auth to query branch. - If rate limited by gitapi, requests are sent to github.com + Uses native git command to check for branches on a remote. :param frappe_path: git url :type frappe_path: str @@ -62,23 +61,26 @@ def is_valid_frappe_branch(frappe_path:str, frappe_branch:str): :type frappe_branch: str :raises InvalidRemoteException: branch for this repo doesn't exist """ - if "http" in frappe_path and frappe_branch: - frappe_path = frappe_path.replace(".git", "") + import subprocess + + if frappe_branch: try: - owner, repo = frappe_path.split("/")[3], frappe_path.split("/")[4] - except IndexError: - raise InvalidRemoteException("Invalid git url") - git_api_req = f"https://api.github.com/repos/{owner}/{repo}/branches" - res = requests.get(git_api_req).json() - - if "message" in res: - # slower alternative with no rate limit - github_req = f'https://github.com/{owner}/{repo}/tree/{frappe_branch}' - if requests.get(github_req).status_code != 200: - raise InvalidRemoteException("Invalid git url") - - elif frappe_branch not in [x["name"] for x in res]: - raise InvalidRemoteException("Frappe branch does not exist") + ret = subprocess.check_output( + ( + "git", + "ls-remote", + "--heads", + frappe_path, + frappe_branch, + ), + encoding="UTF-8", + ) + if not ret: + raise InvalidRemoteException( + f"Invalid {frappe_branch} for the remote {frappe_path}" + ) + except subprocess.CalledProcessError: + raise InvalidRemoteException(f"Invalid frappe path {frappe_path}") def log(message, level=0, no_log=False):