mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-18 20:11:17 +00:00
#1302: Add new git_clone_missing rule
* Add git clone missing rule * Clean up tests and improve matching * Make rules behave correctly? * Improve tests and redo matcher * Remove unnecessary tests * Improvements as per code review * Remove dead tests * Improve match function for git clone missing * Improve tests * Fix more tests * Fix failing test * Add Macos's /bin/sh command output to match * Add output for lines uncovered by tests Co-authored-by: Pablo Santiago Blum de Aguiar <scorphus@gmail.com>
This commit is contained in:
parent
ed40463105
commit
f9768cf929
@ -234,6 +234,7 @@ following rules are enabled by default:
|
|||||||
* `git_branch_0flag` – fixes commands such as `git branch 0v` and `git branch 0r` removing the created branch;
|
* `git_branch_0flag` – fixes commands such as `git branch 0v` and `git branch 0r` removing the created branch;
|
||||||
* `git_checkout` – fixes branch name or creates new branch;
|
* `git_checkout` – fixes branch name or creates new branch;
|
||||||
* `git_clone_git_clone` – replaces `git clone git clone ...` with `git clone ...`
|
* `git_clone_git_clone` – replaces `git clone git clone ...` with `git clone ...`
|
||||||
|
* `git_clone_missing` – adds `git clone` to URLs that appear to link to a git repository.
|
||||||
* `git_commit_add` – offers `git commit -a ...` or `git commit -p ...` after previous commit if it failed because nothing was staged;
|
* `git_commit_add` – offers `git commit -a ...` or `git commit -p ...` after previous commit if it failed because nothing was staged;
|
||||||
* `git_commit_amend` – offers `git commit --amend` after previous commit;
|
* `git_commit_amend` – offers `git commit --amend` after previous commit;
|
||||||
* `git_commit_reset` – offers `git reset HEAD~` after previous commit;
|
* `git_commit_reset` – offers `git reset HEAD~` after previous commit;
|
||||||
|
50
tests/rules/test_git_clone_missing.py
Normal file
50
tests/rules/test_git_clone_missing.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import pytest
|
||||||
|
from thefuck.rules.git_clone_missing import match, get_new_command
|
||||||
|
from thefuck.types import Command
|
||||||
|
|
||||||
|
valid_urls = [
|
||||||
|
'https://github.com/nvbn/thefuck.git',
|
||||||
|
'https://github.com/nvbn/thefuck',
|
||||||
|
'http://github.com/nvbn/thefuck.git',
|
||||||
|
'git@github.com:nvbn/thefuck.git',
|
||||||
|
'git@github.com:nvbn/thefuck',
|
||||||
|
'ssh://git@github.com:nvbn/thefuck.git',
|
||||||
|
]
|
||||||
|
invalid_urls = [
|
||||||
|
'', # No command
|
||||||
|
'notacommand', # Command not found
|
||||||
|
'ssh git@github.com:nvbn/thefrick.git', # ssh command, not a git clone
|
||||||
|
'git clone foo', # Valid clone
|
||||||
|
'git clone https://github.com/nvbn/thefuck.git', # Full command
|
||||||
|
'github.com/nvbn/thefuck.git', # Missing protocol
|
||||||
|
'github.com:nvbn/thefuck.git', # SSH missing username
|
||||||
|
'git clone git clone ssh://git@github.com:nvbn/thefrick.git', # 2x clone
|
||||||
|
'https:/github.com/nvbn/thefuck.git' # Bad protocol
|
||||||
|
]
|
||||||
|
outputs = [
|
||||||
|
'No such file or directory',
|
||||||
|
'not found',
|
||||||
|
'is not recognised as',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('cmd', valid_urls)
|
||||||
|
@pytest.mark.parametrize('output', outputs)
|
||||||
|
def test_match(cmd, output):
|
||||||
|
c = Command(cmd, output)
|
||||||
|
assert match(c)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('cmd', invalid_urls)
|
||||||
|
@pytest.mark.parametrize('output', outputs + ["some other output"])
|
||||||
|
def test_not_match(cmd, output):
|
||||||
|
c = Command(cmd, output)
|
||||||
|
assert not match(c)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('script', valid_urls)
|
||||||
|
@pytest.mark.parametrize('output', outputs)
|
||||||
|
def test_get_new_command(script, output):
|
||||||
|
command = Command(script, output)
|
||||||
|
new_command = 'git clone ' + script
|
||||||
|
assert get_new_command(command) == new_command
|
42
thefuck/rules/git_clone_missing.py
Normal file
42
thefuck/rules/git_clone_missing.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
'''
|
||||||
|
Rule: git_clone_missing
|
||||||
|
|
||||||
|
Correct missing `git clone` command when pasting a git URL
|
||||||
|
|
||||||
|
```sh
|
||||||
|
>>> https://github.com/nvbn/thefuck.git
|
||||||
|
git clone https://github.com/nvbn/thefuck.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Author: Miguel Guthridge
|
||||||
|
'''
|
||||||
|
from six.moves.urllib import parse
|
||||||
|
from thefuck.utils import which
|
||||||
|
|
||||||
|
|
||||||
|
def match(command):
|
||||||
|
# We want it to be a URL by itself
|
||||||
|
if len(command.script_parts) != 1:
|
||||||
|
return False
|
||||||
|
# Ensure we got the error we expected
|
||||||
|
if which(command.script_parts[0]) or not (
|
||||||
|
'No such file or directory' in command.output
|
||||||
|
or 'not found' in command.output
|
||||||
|
or 'is not recognised as' in command.output
|
||||||
|
):
|
||||||
|
return False
|
||||||
|
url = parse.urlparse(command.script, scheme='ssh')
|
||||||
|
# HTTP URLs need a network address
|
||||||
|
if not url.netloc and url.scheme != 'ssh':
|
||||||
|
return False
|
||||||
|
# SSH needs a username and a splitter between the path
|
||||||
|
if url.scheme == 'ssh' and not (
|
||||||
|
'@' in command.script
|
||||||
|
and ':' in command.script
|
||||||
|
):
|
||||||
|
return False
|
||||||
|
return url.scheme in ['http', 'https', 'ssh']
|
||||||
|
|
||||||
|
|
||||||
|
def get_new_command(command):
|
||||||
|
return 'git clone ' + command.script
|
Loading…
x
Reference in New Issue
Block a user