mirror of
https://github.com/nvbn/thefuck.git
synced 2025-10-31 23:22:10 +00:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7e7e1d884 | ||
|
|
62e0767c50 | ||
|
|
3cd187a3bb | ||
|
|
0420442e77 | ||
|
|
617aaa1fd0 | ||
|
|
cf0921be4a | ||
|
|
ef1ea4b4dd | ||
|
|
2cadcca904 | ||
|
|
d81929f294 | ||
|
|
b03e0913d3 | ||
|
|
b79e104df8 | ||
|
|
3f71959b1b | ||
|
|
51b82c5377 | ||
|
|
5f562a185c | ||
|
|
1a242c7daa | ||
|
|
ceeaeab94b | ||
|
|
77627a3140 | ||
|
|
03a032295d | ||
|
|
56c16b737f | ||
|
|
f9768cf929 | ||
|
|
ed40463105 | ||
|
|
f1b7d879bd | ||
|
|
5198b34f24 | ||
|
|
1a1b5200a9 | ||
|
|
06cb50b1e3 | ||
|
|
16eb823066 | ||
|
|
d8ddf5a2be | ||
|
|
cf1beb6b89 | ||
|
|
925e562d96 |
25
.github/workflows/test.yml
vendored
25
.github/workflows/test.yml
vendored
@@ -3,14 +3,14 @@ name: Tests
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
PYTHON_LATEST: 3.9
|
||||
PYTHON_LATEST: "3.11"
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10-dev]
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12-dev"]
|
||||
fail-fast: false
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
@@ -41,9 +41,28 @@ jobs:
|
||||
run: coverage run --source=thefuck,tests -m pytest -v --capture=sys tests
|
||||
- name: Run tests (including functional)
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.python-version == env.PYTHON_LATEST
|
||||
run: coverage run --source=thefuck,tests -m pytest -v --capture=sys tests --enable-functional
|
||||
run: |
|
||||
docker build -t thefuck/python3 -f tests/Dockerfile --build-arg PYTHON_VERSION=3 .
|
||||
docker build -t thefuck/python2 -f tests/Dockerfile --build-arg PYTHON_VERSION=2 .
|
||||
coverage run --source=thefuck,tests -m pytest -v --capture=sys tests --enable-functional
|
||||
- name: Post coverage results
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.python-version == env.PYTHON_LATEST
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: coveralls --service=github
|
||||
test-deprecated:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["2.7", "3.6"]
|
||||
runs-on: ubuntu-latest
|
||||
container: python:${{ matrix.python-version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install The Fuck with all dependencies
|
||||
run: |
|
||||
pip install -Ur requirements.txt coveralls
|
||||
python setup.py develop
|
||||
- name: Lint
|
||||
run: flake8
|
||||
- name: Run tests
|
||||
run: coverage run --source=thefuck,tests -m pytest -v --capture=sys tests
|
||||
|
||||
@@ -51,13 +51,13 @@ flake8
|
||||
Run unit tests:
|
||||
|
||||
```bash
|
||||
py.test
|
||||
pytest
|
||||
```
|
||||
|
||||
Run unit and functional tests (requires docker):
|
||||
|
||||
```bash
|
||||
py.test --enable-functional
|
||||
pytest --enable-functional
|
||||
```
|
||||
|
||||
For sending package to pypi:
|
||||
@@ -89,4 +89,4 @@ Assuming you have the prerequisites:
|
||||
1. Open command palette (CMD+SHIFT+P (mac) or CTRL+SHIFT+P (windows))
|
||||
1. Select `Remote-Containers: Reopen in Container`.
|
||||
1. Container will be built, install all pip requirements and your VSCode will mount into it automagically.
|
||||
1. Your VSCode and container now essentially become a throw away environment.
|
||||
1. Your VSCode and container now essentially become a throw away environment.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
The MIT License (MIT)
|
||||
=====================
|
||||
|
||||
Copyright (c) 2015-2021 Vladimir Iakovlev
|
||||
Copyright (c) 2015-2022 Vladimir Iakovlev
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
41
README.md
41
README.md
@@ -106,7 +106,7 @@ Reading package lists... Done
|
||||
|
||||
## Requirements
|
||||
|
||||
- python (3.4+)
|
||||
- python (3.5+)
|
||||
- pip
|
||||
- python-dev
|
||||
|
||||
@@ -137,6 +137,11 @@ On ChromeOS, install *The Fuck* using [chromebrew](https://github.com/skycocker/
|
||||
crew install thefuck
|
||||
```
|
||||
|
||||
On Arch based systems, install *The Fuck* with the following command:
|
||||
```
|
||||
sudo pacman -S thefuck
|
||||
```
|
||||
|
||||
On other systems, install *The Fuck* by using `pip`:
|
||||
|
||||
```bash
|
||||
@@ -199,17 +204,17 @@ following rules are enabled by default:
|
||||
* `aws_cli` – fixes misspelled commands like `aws dynamdb scan`;
|
||||
* `az_cli` – fixes misspelled commands like `az providers`;
|
||||
* `cargo` – runs `cargo build` instead of `cargo`;
|
||||
* `cargo_no_command` – fixes wrongs commands like `cargo buid`;
|
||||
* `cargo_no_command` – fixes wrong commands like `cargo buid`;
|
||||
* `cat_dir` – replaces `cat` with `ls` when you try to `cat` a directory;
|
||||
* `cd_correction` – spellchecks and correct failed cd commands;
|
||||
* `cd_correction` – spellchecks and corrects failed cd commands;
|
||||
* `cd_cs` – changes `cs` to `cd`;
|
||||
* `cd_mkdir` – creates directories before cd'ing into them;
|
||||
* `cd_parent` – changes `cd..` to `cd ..`;
|
||||
* `chmod_x` – add execution bit;
|
||||
* `choco_install` – append common suffixes for chocolatey packages;
|
||||
* `chmod_x` – adds execution bit;
|
||||
* `choco_install` – appends common suffixes for chocolatey packages;
|
||||
* `composer_not_command` – fixes composer command name;
|
||||
* `conda_mistype` – fixes conda commands;
|
||||
* `cp_create_destination` – creates a new directory when you attempt to `cp` or `mv` to a non existent one
|
||||
* `cp_create_destination` – creates a new directory when you attempt to `cp` or `mv` to a non-existent one
|
||||
* `cp_omitting_directory` – adds `-a` when you `cp` directory;
|
||||
* `cpp11` – adds missing `-std=c++11` to `g++` or `clang++`;
|
||||
* `dirty_untar` – fixes `tar x` command that untarred in the current directory;
|
||||
@@ -220,7 +225,7 @@ following rules are enabled by default:
|
||||
* `docker_not_command` – fixes wrong docker commands like `docker tags`;
|
||||
* `docker_image_being_used_by_container` ‐ removes the container that is using the image before removing the image;
|
||||
* `dry` – fixes repetitions like `git git push`;
|
||||
* `fab_command_not_found` – fix misspelled fabric commands;
|
||||
* `fab_command_not_found` – fixes misspelled fabric commands;
|
||||
* `fix_alt_space` – replaces Alt+Space with Space character;
|
||||
* `fix_file` – opens a file with an error in your `$EDITOR`;
|
||||
* `gem_unknown_command` – fixes wrong `gem` commands;
|
||||
@@ -234,6 +239,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_checkout` – fixes branch name or creates new branch;
|
||||
* `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_amend` – offers `git commit --amend` after previous commit;
|
||||
* `git_commit_reset` – offers `git reset HEAD~` after previous commit;
|
||||
@@ -254,10 +260,10 @@ following rules are enabled by default:
|
||||
* `git_push` – adds `--set-upstream origin $branch` to previous failed `git push`;
|
||||
* `git_push_different_branch_names` – fixes pushes when local branch name does not match remote branch name;
|
||||
* `git_push_pull` – runs `git pull` when `push` was rejected;
|
||||
* `git_push_without_commits` – Creates an initial commit if you forget and only `git add .`, when setting up a new project;
|
||||
* `git_push_without_commits` – creates an initial commit if you forget and only `git add .`, when setting up a new project;
|
||||
* `git_rebase_no_changes` – runs `git rebase --skip` instead of `git rebase --continue` when there are no changes;
|
||||
* `git_remote_delete` – replaces `git remote delete remote_name` with `git remote remove remote_name`;
|
||||
* `git_rm_local_modifications` – adds `-f` or `--cached` when you try to `rm` a locally modified file;
|
||||
* `git_rm_local_modifications` – adds `-f` or `--cached` when you try to `rm` a locally modified file;
|
||||
* `git_rm_recursive` – adds `-r` when you try to `rm` a directory;
|
||||
* `git_rm_staged` – adds `-f` or `--cached` when you try to `rm` a file with staged changes
|
||||
* `git_rebase_merge_dir` – offers `git rebase (--continue | --abort | --skip)` or removing the `.git/rebase-merge` dir when a rebase is in progress;
|
||||
@@ -275,7 +281,7 @@ following rules are enabled by default:
|
||||
* `grunt_task_not_found` – fixes misspelled `grunt` commands;
|
||||
* `gulp_not_task` – fixes misspelled `gulp` tasks;
|
||||
* `has_exists_script` – prepends `./` when script/binary exists;
|
||||
* `heroku_multiple_apps` – add `--app <app>` to `heroku` commands like `heroku pg`;
|
||||
* `heroku_multiple_apps` – adds `--app <app>` to `heroku` commands like `heroku pg`;
|
||||
* `heroku_not_command` – fixes wrong `heroku` commands like `heroku log`;
|
||||
* `history` – tries to replace command with the most similar command from history;
|
||||
* `hostscli` – tries to fix `hostscli` usage;
|
||||
@@ -301,7 +307,7 @@ following rules are enabled by default:
|
||||
* `no_command` – fixes wrong console commands, for example `vom/vim`;
|
||||
* `no_such_file` – creates missing directories with `mv` and `cp` commands;
|
||||
* `omnienv_no_such_command` – fixes wrong commands for `goenv`, `nodenv`, `pyenv` and `rbenv` (eg.: `pyenv isntall` or `goenv list`);
|
||||
* `open` – either prepends `http://` to address passed to `open` or create a new file or directory and passes it to `open`;
|
||||
* `open` – either prepends `http://` to address passed to `open` or creates a new file or directory and passes it to `open`;
|
||||
* `pip_install` – fixes permission issues with `pip install` commands by adding `--user` or prepending `sudo` if necessary;
|
||||
* `pip_unknown_command` – fixes wrong `pip` commands, for example `pip instatl/pip install`;
|
||||
* `php_s` – replaces `-s` by `-S` when trying to run a local php server;
|
||||
@@ -314,8 +320,8 @@ following rules are enabled by default:
|
||||
* `path_from_history` – replaces not found path with a similar absolute path from history;
|
||||
* `rails_migrations_pending` – runs pending migrations;
|
||||
* `react_native_command_unrecognized` – fixes unrecognized `react-native` commands;
|
||||
* `remove_shell_prompt_literal` – remove leading shell prompt symbol `$`, common when copying commands from documentations;
|
||||
* `remove_trailing_cedilla` – remove trailing cedillas `ç`, a common typo for European keyboard layouts;
|
||||
* `remove_shell_prompt_literal` – removes leading shell prompt symbol `$`, common when copying commands from documentations;
|
||||
* `remove_trailing_cedilla` – removes trailing cedillas `ç`, a common typo for European keyboard layouts;
|
||||
* `rm_dir` – adds `-rf` when you try to remove a directory;
|
||||
* `scm_correction` – corrects wrong scm like `hg log` to `git log`;
|
||||
* `sed_unterminated_s` – adds missing '/' to `sed`'s `s` commands;
|
||||
@@ -325,8 +331,9 @@ following rules are enabled by default:
|
||||
* `sudo_command_from_user_path` – runs commands from users `$PATH` with `sudo`;
|
||||
* `switch_lang` – switches command from your local layout to en;
|
||||
* `systemctl` – correctly orders parameters of confusing `systemctl`;
|
||||
* `terraform_init.py` – run `terraform init` before plan or apply;
|
||||
* `test.py` – runs `py.test` instead of `test.py`;
|
||||
* `terraform_init.py` – runs `terraform init` before plan or apply;
|
||||
* `terraform_no_command.py` – fixes unrecognized `terraform` commands;
|
||||
* `test.py` – runs `pytest` instead of `test.py`;
|
||||
* `touch` – creates missing directories before "touching";
|
||||
* `tsuru_login` – runs `tsuru login` if not authenticated or session expired;
|
||||
* `tsuru_not_command` – fixes wrong `tsuru` commands like `tsuru shell`;
|
||||
@@ -360,9 +367,9 @@ The following rules are enabled by default on specific platforms only:
|
||||
* `brew_update_formula` – turns `brew update <formula>` into `brew upgrade <formula>`;
|
||||
* `dnf_no_such_command` – fixes mistyped DNF commands;
|
||||
* `nixos_cmd_not_found` – installs apps on NixOS;
|
||||
* `pacman` – installs app with `pacman` if it is not installed (uses `yay` or `yaourt` if available);
|
||||
* `pacman` – installs app with `pacman` if it is not installed (uses `yay`, `pikaur` or `yaourt` if available);
|
||||
* `pacman_invalid_option` – replaces lowercase `pacman` options with uppercase.
|
||||
* `pacman_not_found` – fixes package name with `pacman`, `yay` or `yaourt`.
|
||||
* `pacman_not_found` – fixes package name with `pacman`, `yay`, `pikaur` or `yaourt`.
|
||||
* `yum_invalid_operation` – fixes invalid `yum` calls, like `yum isntall vim`;
|
||||
|
||||
The following commands are bundled with *The Fuck*, but are not enabled by
|
||||
|
||||
2
scripts/fuck.bat
Normal file
2
scripts/fuck.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
@set PYTHONIOENCODING=utf-8
|
||||
@powershell -noprofile -c "cmd /c \"$(thefuck %* $(doskey /history)[-2])\"; [Console]::ResetColor();"
|
||||
22
scripts/fuck.ps1
Normal file
22
scripts/fuck.ps1
Normal file
@@ -0,0 +1,22 @@
|
||||
if ((Get-Command "fuck").CommandType -eq "Function") {
|
||||
fuck @args;
|
||||
[Console]::ResetColor()
|
||||
exit
|
||||
}
|
||||
|
||||
"First time use of thefuck detected. "
|
||||
|
||||
if ((Get-Content $PROFILE -Raw -ErrorAction Ignore) -like "*thefuck*") {
|
||||
} else {
|
||||
" - Adding thefuck intialization to user `$PROFILE"
|
||||
$script = "`n`$env:PYTHONIOENCODING='utf-8' `niex `"`$(thefuck --alias)`"";
|
||||
Write-Output $script | Add-Content $PROFILE
|
||||
}
|
||||
|
||||
" - Adding fuck() function to current session..."
|
||||
$env:PYTHONIOENCODING='utf-8'
|
||||
iex "$($(thefuck --alias).Replace("function fuck", "function global:fuck"))"
|
||||
|
||||
" - Invoking fuck()`n"
|
||||
fuck @args;
|
||||
[Console]::ResetColor()
|
||||
22
setup.py
22
setup.py
@@ -33,12 +33,24 @@ elif (3, 0) < version < (3, 5):
|
||||
|
||||
VERSION = '3.32'
|
||||
|
||||
install_requires = ['psutil', 'colorama', 'six', 'decorator', 'pyte']
|
||||
install_requires = ['psutil', 'colorama', 'six']
|
||||
extras_require = {':python_version<"3.4"': ['pathlib2'],
|
||||
':python_version<"3.3"': ['backports.shutil_get_terminal_size'],
|
||||
':python_version<="2.7"': ['decorator<5'],
|
||||
':python_version<="2.7"': ['decorator<5', 'pyte<0.8.1'],
|
||||
':python_version>"2.7"': ['decorator', 'pyte'],
|
||||
":sys_platform=='win32'": ['win_unicode_console']}
|
||||
|
||||
if sys.platform == "win32":
|
||||
scripts = ['scripts\\fuck.bat', 'scripts\\fuck.ps1']
|
||||
entry_points = {'console_scripts': [
|
||||
'thefuck = thefuck.entrypoints.main:main',
|
||||
'thefuck_firstuse = thefuck.entrypoints.not_configured:main']}
|
||||
else:
|
||||
scripts = []
|
||||
entry_points = {'console_scripts': [
|
||||
'thefuck = thefuck.entrypoints.main:main',
|
||||
'fuck = thefuck.entrypoints.not_configured:main']}
|
||||
|
||||
setup(name='thefuck',
|
||||
version=VERSION,
|
||||
description="Magnificent app which corrects your previous console command",
|
||||
@@ -51,8 +63,8 @@ setup(name='thefuck',
|
||||
'tests', 'tests.*', 'release']),
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
install_requires=install_requires,
|
||||
extras_require=extras_require,
|
||||
entry_points={'console_scripts': [
|
||||
'thefuck = thefuck.entrypoints.main:main',
|
||||
'fuck = thefuck.entrypoints.not_configured:main']})
|
||||
scripts=scripts,
|
||||
entry_points=entry_points)
|
||||
|
||||
7
tests/Dockerfile
Normal file
7
tests/Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
||||
ARG PYTHON_VERSION
|
||||
FROM python:${PYTHON_VERSION}
|
||||
RUN apt-get update -y
|
||||
RUN apt-get install -yy --no-install-recommends --no-install-suggests fish tcsh zsh
|
||||
RUN pip install --upgrade pip
|
||||
COPY . /src
|
||||
RUN pip install /src
|
||||
20
tests/functional/conftest.py
Normal file
20
tests/functional/conftest.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import pytest
|
||||
|
||||
from pytest_docker_pexpect.docker import run as pexpect_docker_run, \
|
||||
stats as pexpect_docker_stats
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def build_container_mock(mocker):
|
||||
return mocker.patch('pytest_docker_pexpect.docker.build_container')
|
||||
|
||||
|
||||
def run_side_effect(*args, **kwargs):
|
||||
container_id = pexpect_docker_run(*args, **kwargs)
|
||||
pexpect_docker_stats(container_id)
|
||||
return container_id
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def run_mock(mocker):
|
||||
return mocker.patch('pytest_docker_pexpect.docker.run', side_effect=run_side_effect)
|
||||
@@ -20,10 +20,12 @@ def with_confirmation(proc, TIMEOUT):
|
||||
assert proc.expect([TIMEOUT, u'test'])
|
||||
|
||||
|
||||
def history_changed(proc, TIMEOUT, to):
|
||||
def history_changed(proc, TIMEOUT, *to):
|
||||
"""Ensures that history changed."""
|
||||
proc.send('\033[A')
|
||||
assert proc.expect([TIMEOUT, to])
|
||||
pattern = [TIMEOUT]
|
||||
pattern.extend(to)
|
||||
assert proc.expect(pattern)
|
||||
|
||||
|
||||
def history_not_changed(proc, TIMEOUT):
|
||||
@@ -44,14 +46,14 @@ def select_command_with_arrows(proc, TIMEOUT):
|
||||
proc.send('\033[B')
|
||||
assert proc.expect([TIMEOUT, u'git push'])
|
||||
proc.send('\033[B')
|
||||
assert proc.expect([TIMEOUT, u'git help'])
|
||||
assert proc.expect([TIMEOUT, u'git help', u'git hook'])
|
||||
proc.send('\033[A')
|
||||
assert proc.expect([TIMEOUT, u'git push'])
|
||||
proc.send('\033[B')
|
||||
assert proc.expect([TIMEOUT, u'git help'])
|
||||
assert proc.expect([TIMEOUT, u'git help', u'git hook'])
|
||||
proc.send('\n')
|
||||
|
||||
assert proc.expect([TIMEOUT, u'usage'])
|
||||
assert proc.expect([TIMEOUT, u'usage', u'fatal: not a git repository'])
|
||||
|
||||
|
||||
def refuse_with_confirmation(proc, TIMEOUT):
|
||||
|
||||
@@ -4,12 +4,12 @@ from tests.functional.plots import with_confirmation, without_confirmation, \
|
||||
select_command_with_arrows, how_to_configure
|
||||
|
||||
|
||||
python_3 = (u'thefuck/python3-bash',
|
||||
u'FROM python:3',
|
||||
python_3 = (u'thefuck/python3',
|
||||
u'',
|
||||
u'sh')
|
||||
|
||||
python_2 = (u'thefuck/python2-bash',
|
||||
u'FROM python:2',
|
||||
python_2 = (u'thefuck/python2',
|
||||
u'',
|
||||
u'sh')
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ echo "instant mode ready: $THEFUCK_INSTANT_MODE"
|
||||
def proc(request, spawnu, TIMEOUT):
|
||||
container, instant_mode = request.param
|
||||
proc = spawnu(*container)
|
||||
proc.sendline(u"pip install /src")
|
||||
assert proc.expect([TIMEOUT, u'Successfully installed'])
|
||||
proc.sendline(init_bashrc.format(
|
||||
u'--enable-experimental-instant-mode' if instant_mode else ''))
|
||||
proc.sendline(u"bash")
|
||||
@@ -47,7 +45,7 @@ def test_with_confirmation(proc, TIMEOUT):
|
||||
@pytest.mark.functional
|
||||
def test_select_command_with_arrows(proc, TIMEOUT):
|
||||
select_command_with_arrows(proc, TIMEOUT)
|
||||
history_changed(proc, TIMEOUT, u'git help')
|
||||
history_changed(proc, TIMEOUT, u'git help', u'git hook')
|
||||
|
||||
|
||||
@pytest.mark.functional
|
||||
|
||||
@@ -2,29 +2,13 @@ import pytest
|
||||
from tests.functional.plots import with_confirmation, without_confirmation, \
|
||||
refuse_with_confirmation, select_command_with_arrows
|
||||
|
||||
containers = (('thefuck/python3-fish',
|
||||
u'''FROM python:3
|
||||
# Use jessie-backports since it has the fish package. See here for details:
|
||||
# https://github.com/tianon/docker-brew-debian/blob/88ae21052affd8a14553bb969f9d41c464032122/jessie/backports/Dockerfile
|
||||
RUN awk '$1 ~ "^deb" { $3 = $3 "-backports"; print; exit }' /etc/apt/sources.list > /etc/apt/sources.list.d/backports.list
|
||||
RUN apt-get update
|
||||
RUN apt-get install -yy fish''',
|
||||
u'fish'),
|
||||
('thefuck/python2-fish',
|
||||
u'''FROM python:2
|
||||
# Use jessie-backports since it has the fish package. See here for details:
|
||||
# https://github.com/tianon/docker-brew-debian/blob/88ae21052affd8a14553bb969f9d41c464032122/jessie/backports/Dockerfile
|
||||
RUN awk '$1 ~ "^deb" { $3 = $3 "-backports"; print; exit }' /etc/apt/sources.list > /etc/apt/sources.list.d/backports.list
|
||||
RUN apt-get update
|
||||
RUN apt-get install -yy fish''',
|
||||
u'fish'))
|
||||
containers = ((u'thefuck/python3', u'', u'fish'),
|
||||
(u'thefuck/python2', u'', u'fish'))
|
||||
|
||||
|
||||
@pytest.fixture(params=containers)
|
||||
def proc(request, spawnu, TIMEOUT):
|
||||
proc = spawnu(*request.param)
|
||||
proc.sendline(u"pip install /src")
|
||||
assert proc.expect([TIMEOUT, u'Successfully installed'])
|
||||
proc.sendline(u'thefuck --alias > ~/.config/fish/config.fish')
|
||||
proc.sendline(u'fish')
|
||||
return proc
|
||||
|
||||
@@ -2,23 +2,13 @@ import pytest
|
||||
from tests.functional.plots import with_confirmation, without_confirmation, \
|
||||
refuse_with_confirmation, select_command_with_arrows
|
||||
|
||||
containers = (('thefuck/python3-tcsh',
|
||||
u'''FROM python:3
|
||||
RUN apt-get update
|
||||
RUN apt-get install -yy tcsh''',
|
||||
u'tcsh'),
|
||||
('thefuck/python2-tcsh',
|
||||
u'''FROM python:2
|
||||
RUN apt-get update
|
||||
RUN apt-get install -yy tcsh''',
|
||||
u'tcsh'))
|
||||
containers = ((u'thefuck/python3', u'', u'tcsh'),
|
||||
(u'thefuck/python2', u'', u'tcsh'))
|
||||
|
||||
|
||||
@pytest.fixture(params=containers)
|
||||
def proc(request, spawnu, TIMEOUT):
|
||||
proc = spawnu(*request.param)
|
||||
proc.sendline(u'pip install /src')
|
||||
assert proc.expect([TIMEOUT, u'Successfully installed'])
|
||||
proc.sendline(u'tcsh')
|
||||
proc.sendline(u'setenv PYTHONIOENCODING utf8')
|
||||
proc.sendline(u'eval `thefuck --alias`')
|
||||
|
||||
@@ -4,17 +4,8 @@ from tests.functional.plots import with_confirmation, without_confirmation, \
|
||||
select_command_with_arrows, how_to_configure
|
||||
|
||||
|
||||
python_3 = ('thefuck/python3-zsh',
|
||||
u'''FROM python:3
|
||||
RUN apt-get update
|
||||
RUN apt-get install -yy zsh''',
|
||||
u'sh')
|
||||
|
||||
python_2 = ('thefuck/python2-zsh',
|
||||
u'''FROM python:2
|
||||
RUN apt-get update
|
||||
RUN apt-get install -yy zsh''',
|
||||
u'sh')
|
||||
python_3 = (u'thefuck/python3', u'', u'sh')
|
||||
python_2 = (u'thefuck/python2', u'', u'sh')
|
||||
|
||||
|
||||
init_zshrc = u'''echo '
|
||||
@@ -35,8 +26,6 @@ echo "instant mode ready: $THEFUCK_INSTANT_MODE"
|
||||
def proc(request, spawnu, TIMEOUT):
|
||||
container, instant_mode = request.param
|
||||
proc = spawnu(*container)
|
||||
proc.sendline(u'pip install /src')
|
||||
assert proc.expect([TIMEOUT, u'Successfully installed'])
|
||||
proc.sendline(init_zshrc.format(
|
||||
u'--enable-experimental-instant-mode' if instant_mode else ''))
|
||||
proc.sendline(u"zsh")
|
||||
@@ -54,7 +43,7 @@ def test_with_confirmation(proc, TIMEOUT):
|
||||
@pytest.mark.functional
|
||||
def test_select_command_with_arrows(proc, TIMEOUT):
|
||||
select_command_with_arrows(proc, TIMEOUT)
|
||||
history_changed(proc, TIMEOUT, u'git help')
|
||||
history_changed(proc, TIMEOUT, u'git help', u'git hook')
|
||||
|
||||
|
||||
@pytest.mark.functional
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
from mock import Mock, patch
|
||||
from psutil import AccessDenied, TimeoutExpired
|
||||
|
||||
@@ -30,6 +32,7 @@ class TestRerun(object):
|
||||
actual = rerun.get_output('', '')
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.skipif(sys.platform == 'win32', reason="skip when running on Windows")
|
||||
@patch('thefuck.output_readers.rerun._wait_output')
|
||||
def test_get_output_unicode_misspell(self, wait_output_mock):
|
||||
rerun.get_output(u'pácman', u'pácman')
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
import pytest
|
||||
from thefuck.rules.brew_install import match, get_new_command
|
||||
from thefuck.rules.brew_install import _get_formulas
|
||||
from thefuck.rules.brew_install import match, get_new_command, _get_suggestions
|
||||
from thefuck.types import Command
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def brew_no_available_formula():
|
||||
return '''Error: No available formula for elsticsearch '''
|
||||
def brew_no_available_formula_one():
|
||||
return '''Warning: No available formula with the name "giss". Did you mean gist?'''
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def brew_no_available_formula_two():
|
||||
return '''Warning: No available formula with the name "elasticserar". Did you mean elasticsearch or elasticsearch@6?'''
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def brew_no_available_formula_three():
|
||||
return '''Warning: No available formula with the name "gitt". Did you mean git, gitg or gist?'''
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def brew_install_no_argument():
|
||||
return '''This command requires a formula argument'''
|
||||
return '''Install a formula or cask. Additional options specific to a formula may be'''
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -19,28 +28,38 @@ def brew_already_installed():
|
||||
return '''Warning: git-2.3.5 already installed'''
|
||||
|
||||
|
||||
def _is_not_okay_to_test():
|
||||
return 'elasticsearch' not in _get_formulas()
|
||||
def test_suggestions():
|
||||
assert _get_suggestions("one") == ['one']
|
||||
assert _get_suggestions("one or two") == ['one', 'two']
|
||||
assert _get_suggestions("one, two or three") == ['one', 'two', 'three']
|
||||
|
||||
|
||||
@pytest.mark.skipif(_is_not_okay_to_test(),
|
||||
reason='No need to run if there\'s no formula')
|
||||
def test_match(brew_no_available_formula, brew_already_installed,
|
||||
def test_match(brew_no_available_formula_one, brew_no_available_formula_two,
|
||||
brew_no_available_formula_three, brew_already_installed,
|
||||
brew_install_no_argument):
|
||||
assert match(Command('brew install elsticsearch',
|
||||
brew_no_available_formula))
|
||||
assert match(Command('brew install giss',
|
||||
brew_no_available_formula_one))
|
||||
assert match(Command('brew install elasticserar',
|
||||
brew_no_available_formula_two))
|
||||
assert match(Command('brew install gitt',
|
||||
brew_no_available_formula_three))
|
||||
assert not match(Command('brew install git',
|
||||
brew_already_installed))
|
||||
assert not match(Command('brew install', brew_install_no_argument))
|
||||
|
||||
|
||||
@pytest.mark.skipif(_is_not_okay_to_test(),
|
||||
reason='No need to run if there\'s no formula')
|
||||
def test_get_new_command(brew_no_available_formula):
|
||||
assert get_new_command(Command('brew install elsticsearch',
|
||||
brew_no_available_formula))\
|
||||
== 'brew install elasticsearch'
|
||||
def test_get_new_command(brew_no_available_formula_one, brew_no_available_formula_two,
|
||||
brew_no_available_formula_three):
|
||||
assert get_new_command(Command('brew install giss',
|
||||
brew_no_available_formula_one))\
|
||||
== ['brew install gist']
|
||||
assert get_new_command(Command('brew install elasticsear',
|
||||
brew_no_available_formula_two))\
|
||||
== ['brew install elasticsearch', 'brew install elasticsearch@6']
|
||||
assert get_new_command(Command('brew install gitt',
|
||||
brew_no_available_formula_three))\
|
||||
== ['brew install git', 'brew install gitg', 'brew install gist']
|
||||
|
||||
assert get_new_command(Command('brew install aa',
|
||||
brew_no_available_formula))\
|
||||
brew_no_available_formula_one))\
|
||||
!= 'brew install aha'
|
||||
|
||||
@@ -4,7 +4,7 @@ from thefuck.rules.brew_update_formula import get_new_command, match
|
||||
|
||||
|
||||
output = ("Error: This command updates brew itself, and does not take formula"
|
||||
" names.\nUse 'brew upgrade thefuck'.")
|
||||
" names.\nUse `brew upgrade thefuck`.")
|
||||
|
||||
|
||||
def test_match():
|
||||
|
||||
@@ -157,7 +157,7 @@ ReferenceError: conole is not defined
|
||||
./tests/rules/test_whois.py:22:80: E501 line too long (83 > 79 characters)
|
||||
"""),
|
||||
|
||||
FixFileTest('py.test', '/home/thefuck/tests/rules/test_fix_file.py', 218, None, """
|
||||
FixFileTest('pytest', '/home/thefuck/tests/rules/test_fix_file.py', 218, None, """
|
||||
monkeypatch = <_pytest.monkeypatch.monkeypatch object at 0x7fdb76a25b38>
|
||||
test = ('fish a.sh', '/tmp/fix-error/a.sh', 2, None, '', "\\nfish: Unknown command 'foo'\\n/tmp/fix-error/a.sh (line 2): foo\\n ^\\n")
|
||||
|
||||
|
||||
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
|
||||
@@ -21,7 +21,8 @@ def history_without_current(mocker):
|
||||
('vom file.py', 'vom: not found'),
|
||||
('fucck', 'fucck: not found'),
|
||||
('puthon', "'puthon' is not recognized as an internal or external command"),
|
||||
('got commit', 'got: command not found')])
|
||||
('got commit', 'got: command not found'),
|
||||
('gti commit -m "new commit"', 'gti: command not found')])
|
||||
def test_match(mocker, script, output):
|
||||
mocker.patch('thefuck.rules.no_command.which', return_value=None)
|
||||
|
||||
@@ -43,6 +44,7 @@ def test_not_match(mocker, script, output, which):
|
||||
@pytest.mark.parametrize('script, result', [
|
||||
('vom file.py', ['vim file.py']),
|
||||
('fucck', ['fsck']),
|
||||
('got commit', ['git commit', 'go commit'])])
|
||||
('got commit', ['git commit', 'go commit']),
|
||||
('gti commit -m "new commit"', ['git commit -m "new commit"'])])
|
||||
def test_get_new_command(script, result):
|
||||
assert get_new_command(Command(script, '')) == result
|
||||
|
||||
@@ -12,6 +12,7 @@ extra/llvm35 3.5.2-13/usr/bin/llc'''
|
||||
reason='Skip if pacman is not available')
|
||||
@pytest.mark.parametrize('command', [
|
||||
Command('yay -S llc', 'error: target not found: llc'),
|
||||
Command('pikaur -S llc', 'error: target not found: llc'),
|
||||
Command('yaourt -S llc', 'error: target not found: llc'),
|
||||
Command('pacman llc', 'error: target not found: llc'),
|
||||
Command('sudo pacman llc', 'error: target not found: llc')])
|
||||
@@ -21,6 +22,7 @@ def test_match(command):
|
||||
|
||||
@pytest.mark.parametrize('command', [
|
||||
Command('yay -S llc', 'error: target not found: llc'),
|
||||
Command('pikaur -S llc', 'error: target not found: llc'),
|
||||
Command('yaourt -S llc', 'error: target not found: llc'),
|
||||
Command('pacman llc', 'error: target not found: llc'),
|
||||
Command('sudo pacman llc', 'error: target not found: llc')])
|
||||
@@ -34,6 +36,7 @@ def test_match_mocked(subp_mock, command):
|
||||
reason='Skip if pacman is not available')
|
||||
@pytest.mark.parametrize('command, fixed', [
|
||||
(Command('yay -S llc', 'error: target not found: llc'), ['yay -S extra/llvm', 'yay -S extra/llvm35']),
|
||||
(Command('pikaur -S llc', 'error: target not found: llc'), ['pikaur -S extra/llvm', 'pikaur -S extra/llvm35']),
|
||||
(Command('yaourt -S llc', 'error: target not found: llc'), ['yaourt -S extra/llvm', 'yaourt -S extra/llvm35']),
|
||||
(Command('pacman -S llc', 'error: target not found: llc'), ['pacman -S extra/llvm', 'pacman -S extra/llvm35']),
|
||||
(Command('sudo pacman -S llc', 'error: target not found: llc'), ['sudo pacman -S extra/llvm', 'sudo pacman -S extra/llvm35'])])
|
||||
@@ -43,6 +46,7 @@ def test_get_new_command(command, fixed):
|
||||
|
||||
@pytest.mark.parametrize('command, fixed', [
|
||||
(Command('yay -S llc', 'error: target not found: llc'), ['yay -S extra/llvm', 'yay -S extra/llvm35']),
|
||||
(Command('pikaur -S llc', 'error: target not found: llc'), ['pikaur -S extra/llvm', 'pikaur -S extra/llvm35']),
|
||||
(Command('yaourt -S llc', 'error: target not found: llc'), ['yaourt -S extra/llvm', 'yaourt -S extra/llvm35']),
|
||||
(Command('pacman -S llc', 'error: target not found: llc'), ['pacman -S extra/llvm', 'pacman -S extra/llvm35']),
|
||||
(Command('sudo pacman -S llc', 'error: target not found: llc'), ['sudo pacman -S extra/llvm', 'sudo pacman -S extra/llvm35'])])
|
||||
|
||||
@@ -13,7 +13,7 @@ def output():
|
||||
[
|
||||
"$ cd newdir",
|
||||
" $ cd newdir",
|
||||
"$ $ cd newdir"
|
||||
"$ $ cd newdir",
|
||||
" $ $ cd newdir",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
import pytest
|
||||
from thefuck.rules.ssh_known_hosts import match, get_new_command,\
|
||||
from thefuck.rules.ssh_known_hosts import match, get_new_command, \
|
||||
side_effect
|
||||
from thefuck.types import Command
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ from thefuck.types import Command
|
||||
'requested operation requires superuser privilege',
|
||||
'need to be root',
|
||||
'need root',
|
||||
'shutdown: NOT super-user',
|
||||
'Error: This command has to be run with superuser privileges (under the root user on most systems).',
|
||||
'updatedb: can not open a temporary file for `/var/lib/mlocate/mlocate.db',
|
||||
'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'"])
|
||||
|
||||
27
tests/rules/test_terraform_no_command.py
Normal file
27
tests/rules/test_terraform_no_command.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import pytest
|
||||
from thefuck.rules.terraform_no_command import match, get_new_command
|
||||
from thefuck.types import Command
|
||||
|
||||
|
||||
@pytest.mark.parametrize('script, output', [
|
||||
('terraform appyl', 'Terraform has no command named "appyl". Did you mean "apply"?'),
|
||||
('terraform destory', 'Terraform has no command named "destory". Did you mean "destroy"?')])
|
||||
def test_match(script, output):
|
||||
assert match(Command(script, output))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('script, output', [
|
||||
('terraform --version', 'Terraform v0.12.2'),
|
||||
('terraform plan', 'No changes. Infrastructure is up-to-date.'),
|
||||
('terraform apply', 'Apply complete! Resources: 0 added, 0 changed, 0 destroyed.'),
|
||||
])
|
||||
def test_not_match(script, output):
|
||||
assert not match(Command(script, output))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('script, output, new_command', [
|
||||
('terraform appyl', 'Terraform has no command named "appyl". Did you mean "apply"?', 'terraform apply',),
|
||||
('terraform destory --some-other-option', 'Terraform has no command named "destory". Did you mean "destroy"?', 'terraform destroy --some-other-option',),
|
||||
])
|
||||
def test_get_new_command(script, output, new_command):
|
||||
assert get_new_command(Command(script, output)) == new_command
|
||||
@@ -8,5 +8,5 @@ def test_readme(source_root):
|
||||
|
||||
for rule in bundled:
|
||||
if rule.stem != '__init__':
|
||||
assert rule.stem in readme,\
|
||||
assert rule.stem in readme, \
|
||||
'Missing rule "{}" in README.md'.format(rule.stem)
|
||||
|
||||
@@ -245,7 +245,7 @@ class TestGetValidHistoryWithoutCurrent(object):
|
||||
def history(self, mocker):
|
||||
mock = mocker.patch('thefuck.shells.shell.get_history')
|
||||
# Passing as an argument causes `UnicodeDecodeError`
|
||||
# with newer py.test and python 2.7
|
||||
# with newer pytest and python 2.7
|
||||
mock.return_value = ['le cat', 'fuck', 'ls cat',
|
||||
'diff x', 'nocommand x', u'café ô']
|
||||
return mock
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from imp import load_source
|
||||
import os
|
||||
import sys
|
||||
from warnings import warn
|
||||
@@ -6,6 +5,17 @@ from six import text_type
|
||||
from . import const
|
||||
from .system import Path
|
||||
|
||||
try:
|
||||
import importlib.util
|
||||
|
||||
def load_source(name, pathname, _file=None):
|
||||
module_spec = importlib.util.spec_from_file_location(name, pathname)
|
||||
module = importlib.util.module_from_spec(module_spec)
|
||||
module_spec.loader.exec_module(module)
|
||||
return module
|
||||
except ImportError:
|
||||
from imp import load_source
|
||||
|
||||
|
||||
class Settings(dict):
|
||||
def __getattr__(self, item):
|
||||
|
||||
@@ -1,42 +1,24 @@
|
||||
import os
|
||||
import re
|
||||
from thefuck.utils import get_closest, replace_argument
|
||||
from thefuck.specific.brew import get_brew_path_prefix, brew_available
|
||||
from thefuck.utils import for_app
|
||||
from thefuck.specific.brew import brew_available
|
||||
|
||||
enabled_by_default = brew_available
|
||||
|
||||
|
||||
def _get_formulas():
|
||||
# Formulas are based on each local system's status
|
||||
try:
|
||||
brew_path_prefix = get_brew_path_prefix()
|
||||
brew_formula_path = brew_path_prefix + '/Library/Formula'
|
||||
|
||||
for file_name in os.listdir(brew_formula_path):
|
||||
if file_name.endswith('.rb'):
|
||||
yield file_name[:-3]
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _get_similar_formula(formula_name):
|
||||
return get_closest(formula_name, _get_formulas(), cutoff=0.85)
|
||||
def _get_suggestions(str):
|
||||
suggestions = str.replace(" or ", ", ").split(", ")
|
||||
return suggestions
|
||||
|
||||
|
||||
@for_app('brew', at_least=2)
|
||||
def match(command):
|
||||
is_proper_command = ('brew install' in command.script and
|
||||
'No available formula' in command.output)
|
||||
|
||||
if is_proper_command:
|
||||
formula = re.findall(r'Error: No available formula for ([a-z]+)',
|
||||
command.output)[0]
|
||||
return bool(_get_similar_formula(formula))
|
||||
return False
|
||||
is_proper_command = ('install' in command.script and
|
||||
'No available formula' in command.output and
|
||||
'Did you mean' in command.output)
|
||||
return is_proper_command
|
||||
|
||||
|
||||
def get_new_command(command):
|
||||
not_exist_formula = re.findall(r'Error: No available formula for ([a-z]+)',
|
||||
command.output)[0]
|
||||
exist_formula = _get_similar_formula(not_exist_formula)
|
||||
|
||||
return replace_argument(command.script, not_exist_formula, exist_formula)
|
||||
matcher = re.search('Warning: No available formula with the name "(?:[^"]+)". Did you mean (.+)\\?', command.output)
|
||||
suggestions = _get_suggestions(matcher.group(1))
|
||||
return ["brew install " + formula for formula in suggestions]
|
||||
|
||||
@@ -5,7 +5,7 @@ from thefuck.utils import for_app
|
||||
def match(command):
|
||||
return ('update' in command.script
|
||||
and "Error: This command updates brew itself" in command.output
|
||||
and "Use 'brew upgrade" in command.output)
|
||||
and "Use `brew upgrade" in command.output)
|
||||
|
||||
|
||||
def get_new_command(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
|
||||
@@ -35,8 +35,7 @@ def get_new_command(command):
|
||||
get_all_executables())
|
||||
if cmd not in new_cmds]
|
||||
|
||||
return [' '.join([new_command] + command.script_parts[1:])
|
||||
for new_command in new_cmds]
|
||||
return [command.script.replace(old_command, cmd, 1) for cmd in new_cmds]
|
||||
|
||||
|
||||
priority = 3000
|
||||
|
||||
@@ -12,7 +12,7 @@ from thefuck.specific.archlinux import get_pkgfile, archlinux_env
|
||||
|
||||
def match(command):
|
||||
return (command.script_parts
|
||||
and (command.script_parts[0] in ('pacman', 'yay', 'yaourt')
|
||||
and (command.script_parts[0] in ('pacman', 'yay', 'pikaur', 'yaourt')
|
||||
or command.script_parts[0:2] == ['sudo', 'pacman'])
|
||||
and 'error: target not found:' in command.output)
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ patterns = ['permission denied',
|
||||
'you cannot perform this operation unless you are root',
|
||||
'non-root users cannot',
|
||||
'operation not permitted',
|
||||
'not super-user',
|
||||
'superuser privilege',
|
||||
'root privilege',
|
||||
'this command has to be run under the root user.',
|
||||
'this operation requires root.',
|
||||
@@ -22,7 +24,8 @@ patterns = ['permission denied',
|
||||
'you don\'t have write permissions',
|
||||
'use `sudo`',
|
||||
'sudorequirederror',
|
||||
'error: insufficient privileges']
|
||||
'error: insufficient privileges',
|
||||
'updatedb: can not open a temporary file']
|
||||
|
||||
|
||||
def match(command):
|
||||
|
||||
16
thefuck/rules/terraform_no_command.py
Normal file
16
thefuck/rules/terraform_no_command.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import re
|
||||
from thefuck.utils import for_app
|
||||
|
||||
MISTAKE = r'(?<=Terraform has no command named ")([^"]+)(?="\.)'
|
||||
FIX = r'(?<=Did you mean ")([^"]+)(?="\?)'
|
||||
|
||||
|
||||
@for_app('terraform')
|
||||
def match(command):
|
||||
return re.search(MISTAKE, command.output) and re.search(FIX, command.output)
|
||||
|
||||
|
||||
def get_new_command(command):
|
||||
mistake = re.search(MISTAKE, command.output).group(0)
|
||||
fix = re.search(FIX, command.output).group(0)
|
||||
return command.script.replace(mistake, fix)
|
||||
@@ -3,7 +3,7 @@ def match(command):
|
||||
|
||||
|
||||
def get_new_command(command):
|
||||
return 'py.test'
|
||||
return 'pytest'
|
||||
|
||||
|
||||
# make it come before the python_command rule
|
||||
|
||||
@@ -34,6 +34,8 @@ def get_pkgfile(command):
|
||||
def archlinux_env():
|
||||
if utils.which('yay'):
|
||||
pacman = 'yay'
|
||||
elif utils.which('pikaur'):
|
||||
pacman = 'pikaur'
|
||||
elif utils.which('yaourt'):
|
||||
pacman = 'yaourt'
|
||||
elif utils.which('pacman'):
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
from imp import load_source
|
||||
import os
|
||||
import sys
|
||||
from . import logs
|
||||
from .shells import shell
|
||||
from .conf import settings
|
||||
from .conf import settings, load_source
|
||||
from .const import DEFAULT_PRIORITY, ALL_ENABLED
|
||||
from .exceptions import EmptyCommand
|
||||
from .utils import get_alias, format_raw_script
|
||||
|
||||
Reference in New Issue
Block a user