mirror of
https://github.com/nvbn/thefuck.git
synced 2025-11-05 09:32:09 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c534c52bc | ||
|
|
b4392ba706 | ||
|
|
46f918718f | ||
|
|
d71ce76ae4 | ||
|
|
355505a0a8 | ||
|
|
3d425ce831 | ||
|
|
98a9fb3d7d | ||
|
|
c8d748e095 | ||
|
|
e0af35819d | ||
|
|
9e4c250e4e | ||
|
|
8c395377f8 | ||
|
|
f165523247 | ||
|
|
903abff77e | ||
|
|
6d39b78824 | ||
|
|
1285303363 | ||
|
|
66e2ec7e3f | ||
|
|
92cca7b641 | ||
|
|
e572cab1f3 | ||
|
|
33b1536c28 | ||
|
|
d4fada8e4c | ||
|
|
afc089bc3c | ||
|
|
300c8f528a | ||
|
|
7b011a504d |
@@ -7,6 +7,7 @@ install:
|
|||||||
- pip install -r requirements.txt
|
- pip install -r requirements.txt
|
||||||
- python setup.py develop
|
- python setup.py develop
|
||||||
- pip install coveralls
|
- pip install coveralls
|
||||||
|
- rm -rf build
|
||||||
script:
|
script:
|
||||||
- export COVERAGE_PYTHON_VERSION=python-${TRAVIS_PYTHON_VERSION:0:1}
|
- export COVERAGE_PYTHON_VERSION=python-${TRAVIS_PYTHON_VERSION:0:1}
|
||||||
- coverage run --source=thefuck,tests -m py.test -v
|
- coverage run --source=thefuck,tests -m py.test -v
|
||||||
|
|||||||
46
README.md
46
README.md
@@ -14,7 +14,7 @@ E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
|
|||||||
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
|
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
|
||||||
|
|
||||||
➜ fuck
|
➜ fuck
|
||||||
sudo apt-get install vim
|
sudo apt-get install vim [enter/ctrl+c]
|
||||||
[sudo] password for nvbn:
|
[sudo] password for nvbn:
|
||||||
Reading package lists... Done
|
Reading package lists... Done
|
||||||
...
|
...
|
||||||
@@ -29,7 +29,7 @@ To push the current branch and set the remote as upstream, use
|
|||||||
|
|
||||||
|
|
||||||
➜ fuck
|
➜ fuck
|
||||||
git push --set-upstream origin master
|
git push --set-upstream origin master [enter/ctrl+c]
|
||||||
Counting objects: 9, done.
|
Counting objects: 9, done.
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
@@ -42,7 +42,7 @@ No command 'puthon' found, did you mean:
|
|||||||
zsh: command not found: puthon
|
zsh: command not found: puthon
|
||||||
|
|
||||||
➜ fuck
|
➜ fuck
|
||||||
python
|
python [enter/ctrl+c]
|
||||||
Python 3.4.2 (default, Oct 8 2014, 13:08:17)
|
Python 3.4.2 (default, Oct 8 2014, 13:08:17)
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
@@ -55,7 +55,7 @@ Did you mean this?
|
|||||||
branch
|
branch
|
||||||
|
|
||||||
➜ fuck
|
➜ fuck
|
||||||
git branch
|
git branch [enter/ctrl+c]
|
||||||
* master
|
* master
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -67,13 +67,13 @@ Did you mean this?
|
|||||||
repl
|
repl
|
||||||
|
|
||||||
➜ fuck
|
➜ fuck
|
||||||
lein repl
|
lein repl [enter/ctrl+c]
|
||||||
nREPL server started on port 54848 on host 127.0.0.1 - nrepl://127.0.0.1:54848
|
nREPL server started on port 54848 on host 127.0.0.1 - nrepl://127.0.0.1:54848
|
||||||
REPL-y 0.3.1
|
REPL-y 0.3.1
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are scared to blindly run the changed command, there is a `require_confirmation`
|
If you are not scared to blindly run the changed command, there is a `require_confirmation`
|
||||||
[settings](#settings) option:
|
[settings](#settings) option:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -82,7 +82,7 @@ E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
|
|||||||
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
|
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
|
||||||
|
|
||||||
➜ fuck
|
➜ fuck
|
||||||
sudo apt-get install vim [Enter/Ctrl+C]
|
sudo apt-get install vim
|
||||||
[sudo] password for nvbn:
|
[sudo] password for nvbn:
|
||||||
Reading package lists... Done
|
Reading package lists... Done
|
||||||
...
|
...
|
||||||
@@ -112,7 +112,7 @@ eval "$(thefuck-alias)"
|
|||||||
eval "$(thefuck-alias FUCK)"
|
eval "$(thefuck-alias FUCK)"
|
||||||
```
|
```
|
||||||
|
|
||||||
[Or in your shell config (Bash, Zsh, Fish, Powershell).](https://github.com/nvbn/thefuck/wiki/Shell-aliases)
|
[Or in your shell config (Bash, Zsh, Fish, Powershell, tcsh).](https://github.com/nvbn/thefuck/wiki/Shell-aliases)
|
||||||
|
|
||||||
Changes will be available only in a new shell session.
|
Changes will be available only in a new shell session.
|
||||||
To make them available immediately, run `source ~/.bashrc` (or your shell config file like `.zshrc`).
|
To make them available immediately, run `source ~/.bashrc` (or your shell config file like `.zshrc`).
|
||||||
@@ -138,17 +138,17 @@ using the matched rule and runs it. Rules enabled by default are as follows:
|
|||||||
* `cd_parent` – changes `cd..` to `cd ..`;
|
* `cd_parent` – changes `cd..` to `cd ..`;
|
||||||
* `composer_not_command` – fixes composer command name;
|
* `composer_not_command` – fixes composer command name;
|
||||||
* `cp_omitting_directory` – adds `-a` when you `cp` directory;
|
* `cp_omitting_directory` – adds `-a` when you `cp` directory;
|
||||||
* `cpp11` – add missing `-std=c++11` to `g++` or `clang++`;
|
* `cpp11` – adds missing `-std=c++11` to `g++` or `clang++`;
|
||||||
* `django_south_ghost` – adds `--delete-ghost-migrations` to failed because ghosts django south migration;
|
* `django_south_ghost` – adds `--delete-ghost-migrations` to failed because ghosts django south migration;
|
||||||
* `django_south_merge` – adds `--merge` to inconsistent django south migration;
|
* `django_south_merge` – adds `--merge` to inconsistent django south migration;
|
||||||
* `dry` – fix repetitions like "git git push";
|
* `dry` – fixes repetitions like "git git push";
|
||||||
* `fix_alt_space` – replaces Alt+Space with Space character;
|
* `fix_alt_space` – replaces Alt+Space with Space character;
|
||||||
* `git_add` – fix *"Did you forget to 'git add'?"*;
|
* `git_add` – fixes *"Did you forget to 'git add'?"*;
|
||||||
* `git_branch_delete` – changes `git branch -d` to `git branch -D`;
|
* `git_branch_delete` – changes `git branch -d` to `git branch -D`;
|
||||||
* `git_branch_list` – catches `git branch list` in place of `git branch` and removes created branch;
|
* `git_branch_list` – catches `git branch list` in place of `git branch` and removes created branch;
|
||||||
* `git_checkout` – fixes branch name or creates new branch;
|
* `git_checkout` – fixes branch name or creates new branch;
|
||||||
* `git_diff_staged` – adds `--staged` to previous `git diff` with unexpected output;
|
* `git_diff_staged` – adds `--staged` to previous `git diff` with unexpected output;
|
||||||
* `git_no_command` – fixes wrong git commands like `git brnch`;
|
* `git_not_command` – fixes wrong git commands like `git brnch`;
|
||||||
* `git_pull` – sets upstream before executing previous `git pull`;
|
* `git_pull` – sets upstream before executing previous `git pull`;
|
||||||
* `git_pull_clone` – clones instead of pulling when the repo does not exist;
|
* `git_pull_clone` – clones instead of pulling when the repo does not exist;
|
||||||
* `git_push` – adds `--set-upstream origin $branch` to previous failed `git push`;
|
* `git_push` – adds `--set-upstream origin $branch` to previous failed `git push`;
|
||||||
@@ -157,12 +157,13 @@ using the matched rule and runs it. Rules enabled by default are as follows:
|
|||||||
* `go_run` – appends `.go` extension when compiling/running Go programs
|
* `go_run` – appends `.go` extension when compiling/running Go programs
|
||||||
* `grep_recursive` – adds `-r` when you trying to grep directory;
|
* `grep_recursive` – adds `-r` when you trying to grep directory;
|
||||||
* `has_exists_script` – prepends `./` when script/binary exists;
|
* `has_exists_script` – prepends `./` when script/binary exists;
|
||||||
|
* `heroku_no_command` – fixes wrong heroku commands like `heroku log`;
|
||||||
* `history` – tries to replace command with most similar command from history;
|
* `history` – tries to replace command with most similar command from history;
|
||||||
* `java` – removes `.java` extension when running Java programs;
|
* `java` – removes `.java` extension when running Java programs;
|
||||||
* `javac` – appends missing `.java` when compiling Java files;
|
* `javac` – appends missing `.java` when compiling Java files;
|
||||||
* `lein_not_task` – fixes wrong `lein` tasks like `lein rpl`;
|
* `lein_not_task` – fixes wrong `lein` tasks like `lein rpl`;
|
||||||
* `ls_lah` – adds -lah to ls;
|
* `ls_lah` – adds -lah to ls;
|
||||||
* `man` – change manual section;
|
* `man` – changes manual section;
|
||||||
* `man_no_space` – fixes man commands without spaces, for example `mandiff`;
|
* `man_no_space` – fixes man commands without spaces, for example `mandiff`;
|
||||||
* `mercurial` – fixes wrong `hg` commands;
|
* `mercurial` – fixes wrong `hg` commands;
|
||||||
* `mkdir_p` – adds `-p` when you trying to create directory without parent;
|
* `mkdir_p` – adds `-p` when you trying to create directory without parent;
|
||||||
@@ -190,26 +191,29 @@ Enabled by default only on specific platforms:
|
|||||||
* `brew_install` – fixes formula name for `brew install`;
|
* `brew_install` – fixes formula name for `brew install`;
|
||||||
* `brew_unknown_command` – fixes wrong brew commands, for example `brew docto/brew doctor`;
|
* `brew_unknown_command` – fixes wrong brew commands, for example `brew docto/brew doctor`;
|
||||||
* `brew_upgrade` – appends `--all` to `brew upgrade` as per Homebrew's new behaviour;
|
* `brew_upgrade` – appends `--all` to `brew upgrade` as per Homebrew's new behaviour;
|
||||||
* `git_push_force` – adds `--force` to a `git push` (may conflict with `git_push_pull`);
|
|
||||||
* `pacman` – installs app with `pacman` or `yaourt` if it is not installed.
|
* `pacman` – installs app with `pacman` or `yaourt` if it is not installed.
|
||||||
|
|
||||||
Bundled, but not enabled by default:
|
Bundled, but not enabled by default:
|
||||||
|
|
||||||
|
* `git_push_force` – adds `--force` to a `git push` (may conflict with `git_push_pull`);
|
||||||
* `rm_root` – adds `--no-preserve-root` to `rm -rf /` command.
|
* `rm_root` – adds `--no-preserve-root` to `rm -rf /` command.
|
||||||
|
|
||||||
## Creating your own rules
|
## Creating your own rules
|
||||||
|
|
||||||
For adding your own rule you should create `your-rule-name.py`
|
For adding your own rule you should create `your-rule-name.py`
|
||||||
in `~/.thefuck/rules`. Rule should contain two functions:
|
in `~/.thefuck/rules`. The rule should contain two functions:
|
||||||
`match(command: Command, settings: Settings) -> bool`
|
```python
|
||||||
and `get_new_command(command: Command, settings: Settings) -> str`.
|
match(command: Command, settings: Settings) -> bool
|
||||||
Also the rule can contain optional function
|
get_new_command(command: Command, settings: Settings) -> str
|
||||||
`side_effect(command: Command, settings: Settings) -> None` and
|
```
|
||||||
|
|
||||||
|
Also the rule can contain an optional function
|
||||||
|
`side_effect(command: Command, settings: Settings) -> None` and an
|
||||||
optional boolean `enabled_by_default`.
|
optional boolean `enabled_by_default`.
|
||||||
|
|
||||||
`Command` has three attributes: `script`, `stdout` and `stderr`.
|
`Command` has three attributes: `script`, `stdout` and `stderr`.
|
||||||
|
|
||||||
`Settings` is a special object filled with `~/.thefuck/settings.py` and values from env, [more](#settings).
|
`Settings` is a special object filled with `~/.thefuck/settings.py` and values from env ([see more below](#settings)).
|
||||||
|
|
||||||
Simple example of the rule for running script with `sudo`:
|
Simple example of the rule for running script with `sudo`:
|
||||||
|
|
||||||
@@ -243,7 +247,7 @@ The Fuck has a few settings parameters which can be changed in `~/.thefuck/setti
|
|||||||
* `wait_command` – max amount of time in seconds for getting previous command output;
|
* `wait_command` – max amount of time in seconds for getting previous command output;
|
||||||
* `no_colors` – disable colored output;
|
* `no_colors` – disable colored output;
|
||||||
* `priority` – dict with rules priorities, rule with lower `priority` will be matched first;
|
* `priority` – dict with rules priorities, rule with lower `priority` will be matched first;
|
||||||
* `debug` – enables debug output, by default `False`;
|
* `debug` – enables debug output, by default `False`.
|
||||||
|
|
||||||
Example of `settings.py`:
|
Example of `settings.py`:
|
||||||
|
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -11,7 +11,7 @@ elif (3, 0) < sys.version_info < (3, 3):
|
|||||||
' ({}.{} detected).'.format(*sys.version_info[:2]))
|
' ({}.{} detected).'.format(*sys.version_info[:2]))
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
VERSION = '2.1'
|
VERSION = '2.3'
|
||||||
|
|
||||||
install_requires = ['psutil', 'colorama', 'six']
|
install_requires = ['psutil', 'colorama', 'six']
|
||||||
extras_require = {':python_version<"3.4"': ['pathlib']}
|
extras_require = {':python_version<"3.4"': ['pathlib']}
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ def test_not_match(command):
|
|||||||
Command('git commit unknown', stderr=did_not_match('unknown')),
|
Command('git commit unknown', stderr=did_not_match('unknown')),
|
||||||
'git branch unknown && git commit unknown'),
|
'git branch unknown && git commit unknown'),
|
||||||
(['master'],
|
(['master'],
|
||||||
Command(script='git checkout amster', stderr=did_not_match('amster')),
|
Command(script='git checkout mster', stderr=did_not_match('mster')),
|
||||||
'git checkout master'),
|
'git checkout master'),
|
||||||
(['master'],
|
(['master'],
|
||||||
Command(script='git commit amster', stderr=did_not_match('amster')),
|
Command(script='git commit mster', stderr=did_not_match('mster')),
|
||||||
'git commit master')])
|
'git commit master')])
|
||||||
def test_get_new_command(branches, command, new_command, get_branches):
|
def test_get_new_command(branches, command, new_command, get_branches):
|
||||||
get_branches.return_value = branches
|
get_branches.return_value = branches
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ from thefuck.rules.git_diff_staged import match, get_new_command
|
|||||||
from tests.utils import Command
|
from tests.utils import Command
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('command', [Command(script='git diff')])
|
@pytest.mark.parametrize('command', [
|
||||||
|
Command(script='git diff foo'),
|
||||||
|
Command(script='git diff')])
|
||||||
def test_match(command):
|
def test_match(command):
|
||||||
assert match(command, None)
|
assert match(command, None)
|
||||||
|
|
||||||
@@ -18,6 +20,7 @@ def test_not_match(command):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('command, new_command', [
|
@pytest.mark.parametrize('command, new_command', [
|
||||||
(Command('git diff'), 'git diff --staged')])
|
(Command('git diff'), 'git diff --staged'),
|
||||||
|
(Command('git diff foo'), 'git diff --staged foo')])
|
||||||
def test_get_new_command(command, new_command):
|
def test_get_new_command(command, new_command):
|
||||||
assert get_new_command(command, None) == new_command
|
assert get_new_command(command, None) == new_command
|
||||||
|
|||||||
@@ -20,5 +20,5 @@ def test_match(stderr):
|
|||||||
|
|
||||||
|
|
||||||
def test_get_new_command(stderr):
|
def test_get_new_command(stderr):
|
||||||
assert get_new_command(Command(stderr=stderr), None)\
|
assert get_new_command(Command('git push', stderr=stderr), None)\
|
||||||
== "git push --set-upstream origin master"
|
== "git push --set-upstream origin master"
|
||||||
|
|||||||
34
tests/rules/test_heroku_not_command.py
Normal file
34
tests/rules/test_heroku_not_command.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import pytest
|
||||||
|
from tests.utils import Command
|
||||||
|
from thefuck.rules.heroku_not_command import match, get_new_command
|
||||||
|
|
||||||
|
|
||||||
|
def suggest_stderr(cmd):
|
||||||
|
return ''' ! `{}` is not a heroku command.
|
||||||
|
! Perhaps you meant `logs`, `pg`.
|
||||||
|
! See `heroku help` for a list of available commands.'''.format(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
no_suggest_stderr = ''' ! `aaaaa` is not a heroku command.
|
||||||
|
! See `heroku help` for a list of available commands.'''
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('cmd', ['log', 'pge'])
|
||||||
|
def test_match(cmd):
|
||||||
|
assert match(
|
||||||
|
Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd)), None)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('script, stderr', [
|
||||||
|
('cat log', suggest_stderr('log')),
|
||||||
|
('heroku aaa', no_suggest_stderr)])
|
||||||
|
def test_not_match(script, stderr):
|
||||||
|
assert not match(Command(script, stderr=stderr), None)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('cmd, result', [
|
||||||
|
('log', 'heroku logs'),
|
||||||
|
('pge', 'heroku pg')])
|
||||||
|
def test_get_new_command(cmd, result):
|
||||||
|
command = Command('heroku {}'.format(cmd), stderr=suggest_stderr(cmd))
|
||||||
|
assert get_new_command(command, None) == result
|
||||||
@@ -11,6 +11,7 @@ from tests.utils import Command
|
|||||||
('need to be root', ''),
|
('need to be root', ''),
|
||||||
('need root', ''),
|
('need root', ''),
|
||||||
('must be root', ''),
|
('must be root', ''),
|
||||||
|
('You don\'t have access to the history DB.', ''),
|
||||||
('', "error: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/ipaddr.py'")])
|
('', "error: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/ipaddr.py'")])
|
||||||
def test_match(stderr, stdout):
|
def test_match(stderr, stdout):
|
||||||
assert match(Command(stderr=stderr, stdout=stdout), None)
|
assert match(Command(stderr=stderr, stdout=stdout), None)
|
||||||
|
|||||||
@@ -36,6 +36,20 @@ def test_git_support(called, command, stderr):
|
|||||||
assert fn(Command(script=called, stderr=stderr), None) == command
|
assert fn(Command(script=called, stderr=stderr), None) == command
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('command, is_git', [
|
||||||
|
('git pull', True),
|
||||||
|
('hub pull', True),
|
||||||
|
('git push --set-upstream origin foo', True),
|
||||||
|
('hub push --set-upstream origin foo', True),
|
||||||
|
('ls', False),
|
||||||
|
('cat git', False),
|
||||||
|
('cat hub', False)])
|
||||||
|
def test_git_support_match(command, is_git):
|
||||||
|
@git_support
|
||||||
|
def fn(command, settings): return True
|
||||||
|
assert fn(Command(script=command), None) == is_git
|
||||||
|
|
||||||
|
|
||||||
def test_memoize():
|
def test_memoize():
|
||||||
fn = Mock(__name__='fn')
|
fn = Mock(__name__='fn')
|
||||||
memoized = memoize(fn)
|
memoized = memoize(fn)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
|
|||||||
'no_colors': False,
|
'no_colors': False,
|
||||||
'debug': False,
|
'debug': False,
|
||||||
'priority': {},
|
'priority': {},
|
||||||
'env': {'LANG': 'C', 'GIT_TRACE': '1'}}
|
'env': {'LC_ALL': 'C', 'LANG': 'C', 'GIT_TRACE': '1'}}
|
||||||
|
|
||||||
ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
|
ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
|
||||||
'THEFUCK_WAIT_COMMAND': 'wait_command',
|
'THEFUCK_WAIT_COMMAND': 'wait_command',
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ from thefuck import utils, shells
|
|||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('did not match any file(s) known to git.' in command.stderr
|
||||||
and 'did not match any file(s) known to git.' in command.stderr
|
|
||||||
and "Did you forget to 'git add'?" in command.stderr)
|
and "Did you forget to 'git add'?" in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from thefuck import utils
|
|||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git branch -d' in command.script
|
return ('branch -d' in command.script
|
||||||
and 'If you are sure you want to delete it' in command.stderr)
|
and 'If you are sure you want to delete it' in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from thefuck import utils, shells
|
|||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
# catches "git branch list" in place of "git branch"
|
# catches "git branch list" in place of "git branch"
|
||||||
return command.script.split() == 'git branch list'.split()
|
return command.script.split()[1:] == 'branch list'.split()
|
||||||
|
|
||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ from thefuck import shells, utils
|
|||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('did not match any file(s) known to git.' in command.stderr
|
||||||
and 'did not match any file(s) known to git.' in command.stderr
|
|
||||||
and "Did you forget to 'git add'?" not in command.stderr)
|
and "Did you forget to 'git add'?" not in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,10 @@ from thefuck import utils
|
|||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script and
|
return ('diff' in command.script and
|
||||||
'diff' in command.script and
|
|
||||||
'--staged' not in command.script)
|
'--staged' not in command.script)
|
||||||
|
|
||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def get_new_command(command, settings):
|
def get_new_command(command, settings):
|
||||||
return '{} --staged'.format(command.script)
|
return command.script.replace(' diff', ' diff --staged')
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ from thefuck.utils import get_closest, git_support
|
|||||||
|
|
||||||
@git_support
|
@git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return (" is not a git command. See 'git --help'." in command.stderr
|
||||||
and " is not a git command. See 'git --help'." in command.stderr
|
|
||||||
and 'Did you mean' in command.stderr)
|
and 'Did you mean' in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ from thefuck import shells, utils
|
|||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('pull' in command.script
|
||||||
and 'pull' in command.script
|
|
||||||
and 'set-upstream' in command.stderr)
|
and 'set-upstream' in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import re
|
from thefuck import utils
|
||||||
from thefuck import utils, shells
|
|
||||||
|
|
||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git pull' in command.script
|
return ('fatal: Not a git repository' in command.stderr
|
||||||
and 'fatal: Not a git repository' in command.stderr
|
|
||||||
and "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)." in command.stderr)
|
and "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)." in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ from thefuck import utils
|
|||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('push' in command.script
|
||||||
and 'push' in command.script
|
|
||||||
and 'set-upstream' in command.stderr)
|
and 'set-upstream' in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ from thefuck import utils
|
|||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('push' in command.script
|
||||||
and 'push' in command.script
|
|
||||||
and '! [rejected]' in command.stderr
|
and '! [rejected]' in command.stderr
|
||||||
and 'failed to push some refs to' in command.stderr
|
and 'failed to push some refs to' in command.stderr
|
||||||
and 'Updates were rejected because the tip of your current branch is behind' in command.stderr)
|
and 'Updates were rejected because the tip of your current branch is behind' in command.stderr)
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ from thefuck.shells import and_
|
|||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('push' in command.script
|
||||||
and 'push' in command.script
|
|
||||||
and '! [rejected]' in command.stderr
|
and '! [rejected]' in command.stderr
|
||||||
and 'failed to push some refs to' in command.stderr
|
and 'failed to push some refs to' in command.stderr
|
||||||
and 'Updates were rejected because the tip of your current branch is behind' in command.stderr)
|
and 'Updates were rejected because the tip of your current branch is behind' in command.stderr)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from thefuck import shells, utils
|
|||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
# catches "Please commit or stash them" and "Please, commit your changes or
|
# catches "Please commit or stash them" and "Please, commit your changes or
|
||||||
# stash them before you can switch branches."
|
# stash them before you can switch branches."
|
||||||
return 'git' in command.script and 'or stash them' in command.stderr
|
return 'or stash them' in command.stderr
|
||||||
|
|
||||||
|
|
||||||
@utils.git_support
|
@utils.git_support
|
||||||
|
|||||||
20
thefuck/rules/heroku_not_command.py
Normal file
20
thefuck/rules/heroku_not_command.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import re
|
||||||
|
from thefuck.utils import get_closest
|
||||||
|
|
||||||
|
|
||||||
|
def match(command, settings):
|
||||||
|
return command.script.startswith('heroku') and \
|
||||||
|
'is not a heroku command' in command.stderr and \
|
||||||
|
'Perhaps you meant' in command.stderr
|
||||||
|
|
||||||
|
|
||||||
|
def _get_suggests(stderr):
|
||||||
|
for line in stderr.split('\n'):
|
||||||
|
if 'Perhaps you meant' in line:
|
||||||
|
return re.findall(r'`([^`]+)`', line)
|
||||||
|
|
||||||
|
|
||||||
|
def get_new_command(command, settings):
|
||||||
|
wrong = re.findall(r'`(\w+)` is not a heroku command', command.stderr)[0]
|
||||||
|
correct = get_closest(wrong, _get_suggests(command.stderr))
|
||||||
|
return command.script.replace(' {}'.format(wrong), ' {}'.format(correct), 1)
|
||||||
@@ -14,6 +14,7 @@ patterns = ['permission denied',
|
|||||||
'need to be root',
|
'need to be root',
|
||||||
'need root',
|
'need root',
|
||||||
'only root can do that',
|
'only root can do that',
|
||||||
|
'You don\'t have access to the history DB.',
|
||||||
'authentication is required']
|
'authentication is required']
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ class Bash(Generic):
|
|||||||
return u'{}\n'.format(command_script)
|
return u'{}\n'.format(command_script)
|
||||||
|
|
||||||
def _script_from_history(self, line):
|
def _script_from_history(self, line):
|
||||||
print(line)
|
|
||||||
return line
|
return line
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -75,12 +75,19 @@ def sudo_support(fn):
|
|||||||
|
|
||||||
|
|
||||||
def git_support(fn):
|
def git_support(fn):
|
||||||
"""Resolve git aliases."""
|
"""Resolves git aliases and supports testing for both git and hub."""
|
||||||
@wraps(fn)
|
@wraps(fn)
|
||||||
def wrapper(command, settings):
|
def wrapper(command, settings):
|
||||||
if (command.script.startswith('git') and
|
# supports GitHub's `hub` command
|
||||||
'trace: alias expansion:' in command.stderr):
|
# which is recommended to be used with `alias git=hub`
|
||||||
|
# but at this point, shell aliases have already been resolved
|
||||||
|
is_git_cmd = command.script.startswith(('git', 'hub'))
|
||||||
|
|
||||||
|
if not is_git_cmd:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# perform git aliases expansion
|
||||||
|
if 'trace: alias expansion:' in command.stderr:
|
||||||
search = re.search("trace: alias expansion: ([^ ]*) => ([^\n]*)",
|
search = re.search("trace: alias expansion: ([^ ]*) => ([^\n]*)",
|
||||||
command.stderr)
|
command.stderr)
|
||||||
alias = search.group(1)
|
alias = search.group(1)
|
||||||
@@ -93,6 +100,7 @@ def git_support(fn):
|
|||||||
new_script = command.script.replace(alias, expansion)
|
new_script = command.script.replace(alias, expansion)
|
||||||
|
|
||||||
command = Command._replace(command, script=new_script)
|
command = Command._replace(command, script=new_script)
|
||||||
|
|
||||||
return fn(command, settings)
|
return fn(command, settings)
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|||||||
Reference in New Issue
Block a user