Full Code of nvbn/thefuck for AI

master c7e7e1d884d3 cached
434 files
568.5 KB
153.3k tokens
1470 symbols
2 requests
Download .txt
Showing preview only (656K chars total). Download the full file or copy to clipboard to get everything.
Repository: nvbn/thefuck
Branch: master
Commit: c7e7e1d884d3
Files: 434
Total size: 568.5 KB

Directory structure:
gitextract_9f8tmqdi/

├── .devcontainer/
│   ├── Dockerfile
│   └── devcontainer.json
├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   └── workflows/
│       └── test.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.md
├── MANIFEST.in
├── README.md
├── fastentrypoints.py
├── install.sh
├── release.py
├── requirements.txt
├── scripts/
│   ├── fuck.bat
│   └── fuck.ps1
├── setup.cfg
├── setup.py
├── snapcraft.yaml
├── tests/
│   ├── Dockerfile
│   ├── __init__.py
│   ├── conftest.py
│   ├── entrypoints/
│   │   ├── __init__.py
│   │   ├── test_alias.py
│   │   ├── test_fix_command.py
│   │   └── test_not_configured.py
│   ├── functional/
│   │   ├── __init__.py
│   │   ├── conftest.py
│   │   ├── plots.py
│   │   ├── test_bash.py
│   │   ├── test_fish.py
│   │   ├── test_tcsh.py
│   │   └── test_zsh.py
│   ├── output_readers/
│   │   └── test_rerun.py
│   ├── rules/
│   │   ├── __init__.py
│   │   ├── test_adb_unknown_command.py
│   │   ├── test_ag_literal.py
│   │   ├── test_apt_get.py
│   │   ├── test_apt_get_search.py
│   │   ├── test_apt_invalid_operation.py
│   │   ├── test_apt_list_upgradable.py
│   │   ├── test_apt_upgrade.py
│   │   ├── test_aws_cli.py
│   │   ├── test_az_cli.py
│   │   ├── test_brew_cask_dependency.py
│   │   ├── test_brew_install.py
│   │   ├── test_brew_link.py
│   │   ├── test_brew_reinstall.py
│   │   ├── test_brew_uninstall.py
│   │   ├── test_brew_unknown_command.py
│   │   ├── test_brew_update_formula.py
│   │   ├── test_cargo_no_command.py
│   │   ├── test_cat_dir.py
│   │   ├── test_cd_correction.py
│   │   ├── test_cd_cs.py
│   │   ├── test_cd_mkdir.py
│   │   ├── test_cd_parent.py
│   │   ├── test_chmod_x.py
│   │   ├── test_choco_install.py
│   │   ├── test_composer_not_command.py
│   │   ├── test_conda_mistype.py
│   │   ├── test_cp_create_destination.py
│   │   ├── test_cp_omitting_directory.py
│   │   ├── test_dirty_untar.py
│   │   ├── test_dirty_unzip.py
│   │   ├── test_django_south_ghost.py
│   │   ├── test_django_south_merge.py
│   │   ├── test_dnf_no_such_command.py
│   │   ├── test_docker_image_being_used_by_container.py
│   │   ├── test_docker_login.py
│   │   ├── test_docker_not_command.py
│   │   ├── test_dry.py
│   │   ├── test_fab_command_not_found.py
│   │   ├── test_fix_alt_space.py
│   │   ├── test_fix_file.py
│   │   ├── test_gem_unknown_command.py
│   │   ├── test_git_add.py
│   │   ├── test_git_add_force.py
│   │   ├── test_git_bisect_usage.py
│   │   ├── test_git_branch_0flag.py
│   │   ├── test_git_branch_delete.py
│   │   ├── test_git_branch_delete_checked_out.py
│   │   ├── test_git_branch_exists.py
│   │   ├── test_git_branch_list.py
│   │   ├── test_git_checkout.py
│   │   ├── test_git_clone_git_clone.py
│   │   ├── test_git_clone_missing.py
│   │   ├── test_git_commit_add.py
│   │   ├── test_git_commit_amend.py
│   │   ├── test_git_commit_reset.py
│   │   ├── test_git_diff_no_index.py
│   │   ├── test_git_diff_staged.py
│   │   ├── test_git_fix_stash.py
│   │   ├── test_git_flag_after_filename.py
│   │   ├── test_git_help_aliased.py
│   │   ├── test_git_hook_bypass.py
│   │   ├── test_git_lfs_mistype.py
│   │   ├── test_git_main_master.py
│   │   ├── test_git_merge.py
│   │   ├── test_git_merge_unrelated.py
│   │   ├── test_git_not_command.py
│   │   ├── test_git_pull.py
│   │   ├── test_git_pull_clone.py
│   │   ├── test_git_pull_uncommitted_changes.py
│   │   ├── test_git_pull_unstaged_changes.py
│   │   ├── test_git_push.py
│   │   ├── test_git_push_different_branch_names.py
│   │   ├── test_git_push_force.py
│   │   ├── test_git_push_pull.py
│   │   ├── test_git_push_without_commits.py
│   │   ├── test_git_rebase_merge_dir.py
│   │   ├── test_git_rebase_no_changes.py
│   │   ├── test_git_remote_delete.py
│   │   ├── test_git_remote_seturl_add.py
│   │   ├── test_git_rm_local_modifications.py
│   │   ├── test_git_rm_recursive.py
│   │   ├── test_git_rm_staged.py
│   │   ├── test_git_stash.py
│   │   ├── test_git_stash_pop.py
│   │   ├── test_git_tag_force.py
│   │   ├── test_git_two_dashes.py
│   │   ├── test_go_run.py
│   │   ├── test_go_unknown_command.py
│   │   ├── test_gradle_not_task.py
│   │   ├── test_gradle_wrapper.py
│   │   ├── test_grep_arguments_order.py
│   │   ├── test_grep_recursive.py
│   │   ├── test_grunt_task_not_found.py
│   │   ├── test_gulp_not_task.py
│   │   ├── test_has_exists_script.py
│   │   ├── test_heroku_multiple_apps.py
│   │   ├── test_heroku_not_command.py
│   │   ├── test_history.py
│   │   ├── test_hostscli.py
│   │   ├── test_ifconfig_device_not_found.py
│   │   ├── test_java.py
│   │   ├── test_javac.py
│   │   ├── test_lein_not_task.py
│   │   ├── test_ln_no_hard_link.py
│   │   ├── test_ln_s_order.py
│   │   ├── test_long_form_help.py
│   │   ├── test_ls_all.py
│   │   ├── test_ls_lah.py
│   │   ├── test_man.py
│   │   ├── test_man_no_space.py
│   │   ├── test_mercurial.py
│   │   ├── test_missing_space_before_subcommand.py
│   │   ├── test_mkdir_p.py
│   │   ├── test_mvn_no_command.py
│   │   ├── test_mvn_unknown_lifecycle_phase.py
│   │   ├── test_nixos_cmd_not_found.py
│   │   ├── test_no_command.py
│   │   ├── test_no_such_file.py
│   │   ├── test_npm_missing_script.py
│   │   ├── test_npm_run_script.py
│   │   ├── test_npm_wrong_command.py
│   │   ├── test_omnienv_no_such_command.py
│   │   ├── test_open.py
│   │   ├── test_pacman.py
│   │   ├── test_pacman_invalid_option.py
│   │   ├── test_pacman_not_found.py
│   │   ├── test_path_from_history.py
│   │   ├── test_php_s.py
│   │   ├── test_pip_install.py
│   │   ├── test_pip_unknown_command.py
│   │   ├── test_port_already_in_use.py
│   │   ├── test_prove_recursively.py
│   │   ├── test_python_command.py
│   │   ├── test_python_execute.py
│   │   ├── test_python_module_error.py
│   │   ├── test_quotation_marks.py
│   │   ├── test_rails_migrations_pending.py
│   │   ├── test_react_native_command_unrecognized.py
│   │   ├── test_remove_shell_prompt_literal.py
│   │   ├── test_remove_trailing_cedilla.py
│   │   ├── test_rm_dir.py
│   │   ├── test_rm_root.py
│   │   ├── test_scm_correction.py
│   │   ├── test_sed_unterminated_s.py
│   │   ├── test_sl_ls.py
│   │   ├── test_ssh_known_host.py
│   │   ├── test_sudo.py
│   │   ├── test_sudo_command_from_user_path.py
│   │   ├── test_switch_lang.py
│   │   ├── test_systemctl.py
│   │   ├── test_terraform_init.py
│   │   ├── test_terraform_no_command.py
│   │   ├── test_tmux.py
│   │   ├── test_touch.py
│   │   ├── test_tsuru_login.py
│   │   ├── test_tsuru_not_command.py
│   │   ├── test_unknown_command.py
│   │   ├── test_unsudo.py
│   │   ├── test_vagrant_up.py
│   │   ├── test_whois.py
│   │   ├── test_workon_doesnt_exists.py
│   │   ├── test_wrong_hyphen_before_subcommand.py
│   │   ├── test_yarn_alias.py
│   │   ├── test_yarn_command_not_found.py
│   │   ├── test_yarn_command_replaced.py
│   │   ├── test_yarn_help.py
│   │   └── test_yum_invalid_operation.py
│   ├── shells/
│   │   ├── __init__.py
│   │   ├── conftest.py
│   │   ├── test_bash.py
│   │   ├── test_fish.py
│   │   ├── test_generic.py
│   │   ├── test_powershell.py
│   │   ├── test_tcsh.py
│   │   └── test_zsh.py
│   ├── specific/
│   │   ├── __init__.py
│   │   ├── test_git.py
│   │   ├── test_npm.py
│   │   └── test_sudo.py
│   ├── test_argument_parser.py
│   ├── test_conf.py
│   ├── test_corrector.py
│   ├── test_logs.py
│   ├── test_readme.py
│   ├── test_types.py
│   ├── test_ui.py
│   ├── test_utils.py
│   └── utils.py
├── thefuck/
│   ├── __init__.py
│   ├── argument_parser.py
│   ├── conf.py
│   ├── const.py
│   ├── corrector.py
│   ├── entrypoints/
│   │   ├── __init__.py
│   │   ├── alias.py
│   │   ├── fix_command.py
│   │   ├── main.py
│   │   ├── not_configured.py
│   │   └── shell_logger.py
│   ├── exceptions.py
│   ├── logs.py
│   ├── output_readers/
│   │   ├── __init__.py
│   │   ├── read_log.py
│   │   ├── rerun.py
│   │   └── shell_logger.py
│   ├── rules/
│   │   ├── __init__.py
│   │   ├── adb_unknown_command.py
│   │   ├── ag_literal.py
│   │   ├── apt_get.py
│   │   ├── apt_get_search.py
│   │   ├── apt_invalid_operation.py
│   │   ├── apt_list_upgradable.py
│   │   ├── apt_upgrade.py
│   │   ├── aws_cli.py
│   │   ├── az_cli.py
│   │   ├── brew_cask_dependency.py
│   │   ├── brew_install.py
│   │   ├── brew_link.py
│   │   ├── brew_reinstall.py
│   │   ├── brew_uninstall.py
│   │   ├── brew_unknown_command.py
│   │   ├── brew_update_formula.py
│   │   ├── cargo.py
│   │   ├── cargo_no_command.py
│   │   ├── cat_dir.py
│   │   ├── cd_correction.py
│   │   ├── cd_cs.py
│   │   ├── cd_mkdir.py
│   │   ├── cd_parent.py
│   │   ├── chmod_x.py
│   │   ├── choco_install.py
│   │   ├── composer_not_command.py
│   │   ├── conda_mistype.py
│   │   ├── cp_create_destination.py
│   │   ├── cp_omitting_directory.py
│   │   ├── cpp11.py
│   │   ├── dirty_untar.py
│   │   ├── dirty_unzip.py
│   │   ├── django_south_ghost.py
│   │   ├── django_south_merge.py
│   │   ├── dnf_no_such_command.py
│   │   ├── docker_image_being_used_by_container.py
│   │   ├── docker_login.py
│   │   ├── docker_not_command.py
│   │   ├── dry.py
│   │   ├── fab_command_not_found.py
│   │   ├── fix_alt_space.py
│   │   ├── fix_file.py
│   │   ├── gem_unknown_command.py
│   │   ├── git_add.py
│   │   ├── git_add_force.py
│   │   ├── git_bisect_usage.py
│   │   ├── git_branch_0flag.py
│   │   ├── git_branch_delete.py
│   │   ├── git_branch_delete_checked_out.py
│   │   ├── git_branch_exists.py
│   │   ├── git_branch_list.py
│   │   ├── git_checkout.py
│   │   ├── git_clone_git_clone.py
│   │   ├── git_clone_missing.py
│   │   ├── git_commit_add.py
│   │   ├── git_commit_amend.py
│   │   ├── git_commit_reset.py
│   │   ├── git_diff_no_index.py
│   │   ├── git_diff_staged.py
│   │   ├── git_fix_stash.py
│   │   ├── git_flag_after_filename.py
│   │   ├── git_help_aliased.py
│   │   ├── git_hook_bypass.py
│   │   ├── git_lfs_mistype.py
│   │   ├── git_main_master.py
│   │   ├── git_merge.py
│   │   ├── git_merge_unrelated.py
│   │   ├── git_not_command.py
│   │   ├── git_pull.py
│   │   ├── git_pull_clone.py
│   │   ├── git_pull_uncommitted_changes.py
│   │   ├── git_push.py
│   │   ├── git_push_different_branch_names.py
│   │   ├── git_push_force.py
│   │   ├── git_push_pull.py
│   │   ├── git_push_without_commits.py
│   │   ├── git_rebase_merge_dir.py
│   │   ├── git_rebase_no_changes.py
│   │   ├── git_remote_delete.py
│   │   ├── git_remote_seturl_add.py
│   │   ├── git_rm_local_modifications.py
│   │   ├── git_rm_recursive.py
│   │   ├── git_rm_staged.py
│   │   ├── git_stash.py
│   │   ├── git_stash_pop.py
│   │   ├── git_tag_force.py
│   │   ├── git_two_dashes.py
│   │   ├── go_run.py
│   │   ├── go_unknown_command.py
│   │   ├── gradle_no_task.py
│   │   ├── gradle_wrapper.py
│   │   ├── grep_arguments_order.py
│   │   ├── grep_recursive.py
│   │   ├── grunt_task_not_found.py
│   │   ├── gulp_not_task.py
│   │   ├── has_exists_script.py
│   │   ├── heroku_multiple_apps.py
│   │   ├── heroku_not_command.py
│   │   ├── history.py
│   │   ├── hostscli.py
│   │   ├── ifconfig_device_not_found.py
│   │   ├── java.py
│   │   ├── javac.py
│   │   ├── lein_not_task.py
│   │   ├── ln_no_hard_link.py
│   │   ├── ln_s_order.py
│   │   ├── long_form_help.py
│   │   ├── ls_all.py
│   │   ├── ls_lah.py
│   │   ├── man.py
│   │   ├── man_no_space.py
│   │   ├── mercurial.py
│   │   ├── missing_space_before_subcommand.py
│   │   ├── mkdir_p.py
│   │   ├── mvn_no_command.py
│   │   ├── mvn_unknown_lifecycle_phase.py
│   │   ├── nixos_cmd_not_found.py
│   │   ├── no_command.py
│   │   ├── no_such_file.py
│   │   ├── npm_missing_script.py
│   │   ├── npm_run_script.py
│   │   ├── npm_wrong_command.py
│   │   ├── omnienv_no_such_command.py
│   │   ├── open.py
│   │   ├── pacman.py
│   │   ├── pacman_invalid_option.py
│   │   ├── pacman_not_found.py
│   │   ├── path_from_history.py
│   │   ├── php_s.py
│   │   ├── pip_install.py
│   │   ├── pip_unknown_command.py
│   │   ├── port_already_in_use.py
│   │   ├── prove_recursively.py
│   │   ├── python_command.py
│   │   ├── python_execute.py
│   │   ├── python_module_error.py
│   │   ├── quotation_marks.py
│   │   ├── rails_migrations_pending.py
│   │   ├── react_native_command_unrecognized.py
│   │   ├── remove_shell_prompt_literal.py
│   │   ├── remove_trailing_cedilla.py
│   │   ├── rm_dir.py
│   │   ├── rm_root.py
│   │   ├── scm_correction.py
│   │   ├── sed_unterminated_s.py
│   │   ├── sl_ls.py
│   │   ├── ssh_known_hosts.py
│   │   ├── sudo.py
│   │   ├── sudo_command_from_user_path.py
│   │   ├── switch_lang.py
│   │   ├── systemctl.py
│   │   ├── terraform_init.py
│   │   ├── terraform_no_command.py
│   │   ├── test.py.py
│   │   ├── tmux.py
│   │   ├── touch.py
│   │   ├── tsuru_login.py
│   │   ├── tsuru_not_command.py
│   │   ├── unknown_command.py
│   │   ├── unsudo.py
│   │   ├── vagrant_up.py
│   │   ├── whois.py
│   │   ├── workon_doesnt_exists.py
│   │   ├── wrong_hyphen_before_subcommand.py
│   │   ├── yarn_alias.py
│   │   ├── yarn_command_not_found.py
│   │   ├── yarn_command_replaced.py
│   │   ├── yarn_help.py
│   │   └── yum_invalid_operation.py
│   ├── shells/
│   │   ├── __init__.py
│   │   ├── bash.py
│   │   ├── fish.py
│   │   ├── generic.py
│   │   ├── powershell.py
│   │   ├── tcsh.py
│   │   └── zsh.py
│   ├── specific/
│   │   ├── __init__.py
│   │   ├── apt.py
│   │   ├── archlinux.py
│   │   ├── brew.py
│   │   ├── dnf.py
│   │   ├── git.py
│   │   ├── nix.py
│   │   ├── npm.py
│   │   ├── sudo.py
│   │   └── yum.py
│   ├── system/
│   │   ├── __init__.py
│   │   ├── unix.py
│   │   └── win32.py
│   ├── types.py
│   ├── ui.py
│   └── utils.py
└── tox.ini

================================================
FILE CONTENTS
================================================

================================================
FILE: .devcontainer/Dockerfile
================================================
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.163.1/containers/python-3/.devcontainer/base.Dockerfile

# [Choice] Python version: 3, 3.9, 3.8, 3.7, 3.6
ARG VARIANT="3"
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}

# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
COPY requirements.txt /tmp/pip-tmp/
RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
   && rm -rf /tmp/pip-tmp


================================================
FILE: .devcontainer/devcontainer.json
================================================
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.163.1/containers/python-3
{
	"name": "Python 3",
	"build": {
		"dockerfile": "Dockerfile",
		"context": ".."
	},

	// Set *default* container specific settings.json values on container create.
	"settings": {
		"terminal.integrated.profiles.linux": {
			"bash (login)": {
				"path": "bash",
				"args": ["-l"]
			}
		},
		"python.pythonPath": "/usr/local/bin/python",
		"python.linting.enabled": true,
		"python.linting.pylintEnabled": true,
		"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
		"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
		"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
		"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
		"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
		"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
		"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
		"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
		"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint"
	},

	// Add the IDs of extensions you want installed when the container is created.
	"extensions": [
		"ms-python.python"
	],

	// Use 'postCreateCommand' to run commands after the container is created.
	"postCreateCommand": "pip3 install -r requirements.txt && python3 setup.py develop"
}


================================================
FILE: .editorconfig
================================================
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4

[*.py]
max_line_length = 119


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
<!-- If you have any issue with The Fuck, sorry about that, but we will do what we
can to fix that. Actually, maybe we already have, so first thing to do is to
update The Fuck and see if the bug is still there. -->

<!-- If it is (sorry again), check if the problem has not already been reported and
if not, just open an issue on [GitHub](https://github.com/nvbn/thefuck) with
the following basic information: -->

The output of `thefuck --version` (something like `The Fuck 3.1 using Python
3.5.0 and Bash 4.4.12(1)-release`):

    FILL THIS IN

Your system (Debian 7, ArchLinux, Windows, etc.):

    FILL THIS IN

How to reproduce the bug:

    FILL THIS IN

The output of The Fuck with `THEFUCK_DEBUG=true` exported (typically execute `export THEFUCK_DEBUG=true` in your shell before The Fuck):

    FILL THIS IN

If the bug only appears with a specific application, the output of that application and its version:

    FILL THIS IN

Anything else you think is relevant:

    FILL THIS IN

<!-- It's only with enough information that we can do something to fix the problem. -->


================================================
FILE: .github/workflows/test.yml
================================================
name: Tests

on: [push, pull_request]

env:
  PYTHON_LATEST: "3.11"

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12-dev"]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Cache dependencies
        id: cache-deps
        uses: actions/cache@v2
        with:
          path: |
            ${{ env.pythonLocation }}/bin/*
            ${{ env.pythonLocation }}/lib/*
            ${{ env.pythonLocation }}/scripts/*
          key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('setup.py', 'requirements.txt') }}
      - name: Install The Fuck with all dependencies
        if: steps.cache-deps.outputs.cache-hit != 'true'
        run: |
          pip install -Ur requirements.txt coveralls
          python setup.py develop
      - name: Lint
        if: matrix.os == 'ubuntu-latest' && matrix.python-version == env.PYTHON_LATEST
        run: flake8
      - name: Run tests
        if: matrix.os != 'ubuntu-latest' || matrix.python-version != env.PYTHON_LATEST
        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: |
          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


================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build/

# PyBuilder
target/

.env
.idea

# vim temporary files
.*.swp


================================================
FILE: CONTRIBUTING.md
================================================
# Report issues
If you have any issue with The Fuck, sorry about that, but we will do what we
can to fix that. Actually, maybe we already have, so first thing to do is to
update The Fuck and see if the bug is still there.

If it is (sorry again), check if the problem has not already been reported and
if not, just open an issue on [GitHub](https://github.com/nvbn/thefuck) with
the following basic information:
  - the output of `thefuck --version` (something like `The Fuck 3.1 using
    Python 3.5.0`);
  - your shell and its version (`bash`, `zsh`, *Windows PowerShell*, etc.);
  - your system (Debian 7, ArchLinux, Windows, etc.);
  - how to reproduce the bug;
  - the output of The Fuck with `THEFUCK_DEBUG=true` exported (typically execute
    `export THEFUCK_DEBUG=true` in your shell before The Fuck);
  - if the bug only appears with a specific application, the output of that
    application and its version;
  - anything else you think is relevant.

It's only with enough information that we can do something to fix the problem.

# Make a pull request
We gladly accept pull request on the [official
repository](https://github.com/nvbn/thefuck) for new rules, new features, bug
fixes, etc.

# Developing

In order to develop locally, there are two options:

- Develop using a local installation of Python 3 and setting up a virtual environment
- Develop using an automated VSCode Dev Container.

## Develop using local Python installation

[Create and activate a Python 3 virtual environment.](https://docs.python.org/3/tutorial/venv.html)

Install `The Fuck` for development:

```bash
pip install -r requirements.txt
python setup.py develop
```

Run code style checks:

```bash
flake8
```

Run unit tests:

```bash
pytest
```

Run unit and functional tests (requires docker):

```bash
pytest --enable-functional
```

For sending package to pypi:

```bash
sudo apt-get install pandoc
./release.py
```

## Develop using Dev Container

To make local development easier a [VSCode Devcontainer](https://code.visualstudio.com/docs/remote/remote-overview) is included with this repository. This will allows you to spin up a Docker container with all the necessary prerequisites for this project pre-installed ready to go, no local Python install/setup required.

### Prerequisites

To use the container you require:
- [Docker](https://www.docker.com/products/docker-desktop)
- [VSCode](https://code.visualstudio.com/)
- [VSCode Remote Development Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
- [Windows Users Only]: [Installation of WSL2 and configuration of Docker to use it](https://docs.docker.com/docker-for-windows/wsl/)

Full notes about [installation are here](https://code.visualstudio.com/docs/remote/containers#_installation)

### Running the container

Assuming you have the prerequisites:

1. Open VSCode
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.


================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)
=====================

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
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: MANIFEST.in
================================================
include LICENSE.md
include fastentrypoints.py


================================================
FILE: README.md
================================================
# The Fuck [![Version][version-badge]][version-link] [![Build Status][workflow-badge]][workflow-link] [![Coverage][coverage-badge]][coverage-link] [![MIT License][license-badge]](LICENSE.md)

*The Fuck* is a magnificent app, inspired by a [@liamosaur](https://twitter.com/liamosaur/)
[tweet](https://twitter.com/liamosaur/status/506975850596536320),
that corrects errors in previous console commands.


Is *The Fuck* too slow? [Try the experimental instant mode!](#experimental-instant-mode)

[![gif with examples][examples-link]][examples-link]

More examples:

```bash
➜ apt-get install vim
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?

➜ fuck
sudo apt-get install vim [enter/↑/↓/ctrl+c]
[sudo] password for nvbn:
Reading package lists... Done
...
```

```bash
➜ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin master


➜ fuck
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...
```

```bash
➜ puthon
No command 'puthon' found, did you mean:
 Command 'python' from package 'python-minimal' (main)
 Command 'python' from package 'python3' (main)
zsh: command not found: puthon

➜ fuck
python [enter/↑/↓/ctrl+c]
Python 3.4.2 (default, Oct  8 2014, 13:08:17)
...
```

```bash
➜ git brnch
git: 'brnch' is not a git command. See 'git --help'.

Did you mean this?
    branch

➜ fuck
git branch [enter/↑/↓/ctrl+c]
* master
```

```bash
➜ lein rpl
'rpl' is not a task. See 'lein help'.

Did you mean this?
         repl

➜ fuck
lein repl [enter/↑/↓/ctrl+c]
nREPL server started on port 54848 on host 127.0.0.1 - nrepl://127.0.0.1:54848
REPL-y 0.3.1
...
```

If you're not afraid of blindly running corrected commands, the
`require_confirmation` [settings](#settings) option can be disabled:

```bash
➜ apt-get install vim
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?

➜ fuck
sudo apt-get install vim
[sudo] password for nvbn:
Reading package lists... Done
...
```

## Contents

1. [Requirements](#requirements)
2. [Installations](#installation)
3. [Updating](#updating)
4. [How it works](#how-it-works)
5. [Creating your own rules](#creating-your-own-rules)
6. [Settings](#settings)
7. [Third party packages with rules](#third-party-packages-with-rules)
8. [Experimental instant mode](#experimental-instant-mode)
9. [Developing](#developing)
10. [License](#license-mit)

## Requirements

- python (3.5+)
- pip
- python-dev

##### [Back to Contents](#contents)

## Installation

On macOS or Linux, you can install *The Fuck* via [Homebrew][homebrew]:

```bash
brew install thefuck
```

On Ubuntu / Mint, install *The Fuck* with the following commands:
```bash
sudo apt update
sudo apt install python3-dev python3-pip python3-setuptools
pip3 install thefuck --user
```

On FreeBSD, install *The Fuck* with the following commands:
```bash
pkg install thefuck
```

On ChromeOS, install *The Fuck* using [chromebrew](https://github.com/skycocker/chromebrew) with the following command:
```bash
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
pip install thefuck
```

[Alternatively, you may use an OS package manager (OS X, Ubuntu, Arch).](https://github.com/nvbn/thefuck/wiki/Installation)

<a href='#manual-installation' name='manual-installation'>#</a>
It is recommended that you place this command in your `.bash_profile`,
`.bashrc`, `.zshrc` or other startup script:

```bash
eval $(thefuck --alias)
# You can use whatever you want as an alias, like for Mondays:
eval $(thefuck --alias FUCK)
```

[Or in your shell config (Bash, Zsh, Fish, Powershell, tcsh).](https://github.com/nvbn/thefuck/wiki/Shell-aliases)

Changes are only available in a new shell session. To make changes immediately
available, run `source ~/.bashrc` (or your shell config file like `.zshrc`).

To run fixed commands without confirmation, use the `--yeah` option (or just `-y` for short, or `--hard` if you're especially frustrated):

```bash
fuck --yeah
```

To fix commands recursively until succeeding, use the `-r` option:

```bash
fuck -r
```

##### [Back to Contents](#contents)

## Updating

```bash
pip3 install thefuck --upgrade
```

**Note: Alias functionality was changed in v1.34 of *The Fuck***

## Uninstall

To remove *The Fuck*, reverse the installation process:
- erase or comment *thefuck* alias line from your Bash, Zsh, Fish, Powershell, tcsh, ... shell config
- use your package manager (brew, pip3, pkg, crew, pip) to uninstall the binaries

## How it works

*The Fuck* attempts to match the previous command with a rule. If a match is
found, a new command is created using the matched rule and executed. The
following rules are enabled by default:

* `adb_unknown_command` &ndash; fixes misspelled commands like `adb logcta`;
* `ag_literal` &ndash; adds `-Q` to `ag` when suggested;
* `aws_cli` &ndash; fixes misspelled commands like `aws dynamdb scan`;
* `az_cli` &ndash; fixes misspelled commands like `az providers`;
* `cargo` &ndash; runs `cargo build` instead of `cargo`;
* `cargo_no_command` &ndash; fixes wrong commands like `cargo buid`;
* `cat_dir` &ndash; replaces `cat` with `ls` when you try to `cat` a directory;
* `cd_correction` &ndash; spellchecks and corrects failed cd commands;
* `cd_cs` &ndash; changes `cs` to `cd`;
* `cd_mkdir` &ndash; creates directories before cd'ing into them;
* `cd_parent` &ndash; changes `cd..` to `cd ..`;
* `chmod_x` &ndash; adds execution bit;
* `choco_install` &ndash; appends common suffixes for chocolatey packages;
* `composer_not_command` &ndash; fixes composer command name;
* `conda_mistype` &ndash; fixes conda commands;
* `cp_create_destination` &ndash; creates a new directory when you attempt to `cp` or `mv` to a non-existent one
* `cp_omitting_directory` &ndash; adds `-a` when you `cp` directory;
* `cpp11` &ndash; adds missing `-std=c++11` to `g++` or `clang++`;
* `dirty_untar` &ndash; fixes `tar x` command that untarred in the current directory;
* `dirty_unzip` &ndash; fixes `unzip` command that unzipped in the current directory;
* `django_south_ghost` &ndash; adds `--delete-ghost-migrations` to failed because ghosts django south migration;
* `django_south_merge` &ndash; adds `--merge` to inconsistent django south migration;
* `docker_login` &ndash; executes a `docker login` and repeats the previous command;
* `docker_not_command` &ndash; fixes wrong docker commands like `docker tags`;
* `docker_image_being_used_by_container` &dash; removes the container that is using the image before removing the image;
* `dry` &ndash; fixes repetitions like `git git push`;
* `fab_command_not_found` &ndash; fixes misspelled fabric commands;
* `fix_alt_space` &ndash; replaces Alt+Space with Space character;
* `fix_file` &ndash; opens a file with an error in your `$EDITOR`;
* `gem_unknown_command` &ndash; fixes wrong `gem` commands;
* `git_add` &ndash; fixes *"pathspec 'foo' did not match any file(s) known to git."*;
* `git_add_force` &ndash; adds `--force` to `git add <pathspec>...` when paths are .gitignore'd;
* `git_bisect_usage` &ndash; fixes `git bisect strt`, `git bisect goood`, `git bisect rset`, etc. when bisecting;
* `git_branch_delete` &ndash; changes `git branch -d` to `git branch -D`;
* `git_branch_delete_checked_out` &ndash; changes `git branch -d` to `git checkout master && git branch -D` when trying to delete a checked out branch;
* `git_branch_exists` &ndash; offers `git branch -d foo`, `git branch -D foo` or `git checkout foo` when creating a branch that already exists;
* `git_branch_list` &ndash; catches `git branch list` in place of `git branch` and removes created branch;
* `git_branch_0flag` &ndash; fixes commands such as `git branch 0v` and `git branch 0r` removing the created branch;
* `git_checkout` &ndash; fixes branch name or creates new branch;
* `git_clone_git_clone` &ndash; replaces `git clone git clone ...` with `git clone ...`
* `git_clone_missing` &ndash; adds `git clone` to URLs that appear to link to a git repository.
* `git_commit_add` &ndash; offers `git commit -a ...` or `git commit -p ...` after previous commit if it failed because nothing was staged;
* `git_commit_amend` &ndash; offers `git commit --amend` after previous commit;
* `git_commit_reset` &ndash; offers `git reset HEAD~` after previous commit;
* `git_diff_no_index` &ndash; adds `--no-index` to previous `git diff` on untracked files;
* `git_diff_staged` &ndash; adds `--staged` to previous `git diff` with unexpected output;
* `git_fix_stash` &ndash; fixes `git stash` commands (misspelled subcommand and missing `save`);
* `git_flag_after_filename` &ndash; fixes `fatal: bad flag '...' after filename`
* `git_help_aliased` &ndash; fixes `git help <alias>` commands replacing <alias> with the aliased command;
* `git_hook_bypass` &ndash; adds `--no-verify` flag previous to `git am`, `git commit`, or `git push` command;
* `git_lfs_mistype` &ndash; fixes mistyped `git lfs <command>` commands;
* `git_main_master` &ndash; fixes incorrect branch name between `main` and `master`
* `git_merge` &ndash; adds remote to branch names;
* `git_merge_unrelated` &ndash; adds `--allow-unrelated-histories` when required
* `git_not_command` &ndash; fixes wrong git commands like `git brnch`;
* `git_pull` &ndash; sets upstream before executing previous `git pull`;
* `git_pull_clone` &ndash; clones instead of pulling when the repo does not exist;
* `git_pull_uncommitted_changes` &ndash; stashes changes before pulling and pops them afterwards;
* `git_push` &ndash; adds `--set-upstream origin $branch` to previous failed `git push`;
* `git_push_different_branch_names` &ndash; fixes pushes when local branch name does not match remote branch name;
* `git_push_pull` &ndash; runs `git pull` when `push` was rejected;
* `git_push_without_commits` &ndash; creates an initial commit if you forget and only `git add .`, when setting up a new project;
* `git_rebase_no_changes` &ndash; runs `git rebase --skip` instead of `git rebase --continue` when there are no changes;
* `git_remote_delete` &ndash; replaces `git remote delete remote_name` with `git remote remove remote_name`;
* `git_rm_local_modifications` &ndash; adds `-f` or `--cached` when you try to `rm` a locally modified file;
* `git_rm_recursive` &ndash; adds `-r` when you try to `rm` a directory;
* `git_rm_staged` &ndash;  adds `-f` or `--cached` when you try to `rm` a file with staged changes
* `git_rebase_merge_dir` &ndash; offers `git rebase (--continue | --abort | --skip)` or removing the `.git/rebase-merge` dir when a rebase is in progress;
* `git_remote_seturl_add` &ndash; runs `git remote add` when `git remote set_url` on nonexistent remote;
* `git_stash` &ndash; stashes your local modifications before rebasing or switching branch;
* `git_stash_pop` &ndash; adds your local modifications before popping stash, then resets;
* `git_tag_force` &ndash; adds `--force` to `git tag <tagname>` when the tag already exists;
* `git_two_dashes` &ndash; adds a missing dash to commands like `git commit -amend` or `git rebase -continue`;
* `go_run` &ndash; appends `.go` extension when compiling/running Go programs;
* `go_unknown_command` &ndash; fixes wrong `go` commands, for example `go bulid`;
* `gradle_no_task` &ndash; fixes not found or ambiguous `gradle` task;
* `gradle_wrapper` &ndash; replaces `gradle` with `./gradlew`;
* `grep_arguments_order` &ndash; fixes `grep` arguments order for situations like `grep -lir . test`;
* `grep_recursive` &ndash; adds `-r` when you try to `grep` directory;
* `grunt_task_not_found` &ndash; fixes misspelled `grunt` commands;
* `gulp_not_task` &ndash; fixes misspelled `gulp` tasks;
* `has_exists_script` &ndash; prepends `./` when script/binary exists;
* `heroku_multiple_apps` &ndash; adds `--app <app>` to `heroku` commands like `heroku pg`;
* `heroku_not_command` &ndash; fixes wrong `heroku` commands like `heroku log`;
* `history` &ndash; tries to replace command with the most similar command from history;
* `hostscli` &ndash; tries to fix `hostscli` usage;
* `ifconfig_device_not_found` &ndash; fixes wrong device names like `wlan0` to `wlp2s0`;
* `java` &ndash; removes `.java` extension when running Java programs;
* `javac` &ndash; appends missing `.java` when compiling Java files;
* `lein_not_task` &ndash; fixes wrong `lein` tasks like `lein rpl`;
* `long_form_help` &ndash; changes `-h` to `--help` when the short form version is not supported
* `ln_no_hard_link` &ndash; catches hard link creation on directories, suggest symbolic link;
* `ln_s_order` &ndash; fixes `ln -s` arguments order;
* `ls_all` &ndash; adds `-A` to `ls` when output is empty;
* `ls_lah` &ndash; adds `-lah` to `ls`;
* `man` &ndash; changes manual section;
* `man_no_space` &ndash; fixes man commands without spaces, for example `mandiff`;
* `mercurial` &ndash; fixes wrong `hg` commands;
* `missing_space_before_subcommand` &ndash; fixes command with missing space like `npminstall`;
* `mkdir_p` &ndash; adds `-p` when you try to create a directory without a parent;
* `mvn_no_command` &ndash; adds `clean package` to `mvn`;
* `mvn_unknown_lifecycle_phase` &ndash; fixes misspelled life cycle phases with `mvn`;
* `npm_missing_script` &ndash; fixes `npm` custom script name in `npm run-script <script>`;
* `npm_run_script` &ndash; adds missing `run-script` for custom `npm` scripts;
* `npm_wrong_command` &ndash; fixes wrong npm commands like `npm urgrade`;
* `no_command` &ndash; fixes wrong console commands, for example `vom/vim`;
* `no_such_file` &ndash; creates missing directories with `mv` and `cp` commands;
* `omnienv_no_such_command` &ndash; fixes wrong commands for `goenv`, `nodenv`, `pyenv` and `rbenv` (eg.: `pyenv isntall` or `goenv list`);
* `open` &ndash; either prepends `http://` to address passed to `open` or creates a new file or directory and passes it to `open`;
* `pip_install` &ndash; fixes permission issues with `pip install` commands by adding `--user` or prepending `sudo` if necessary;
* `pip_unknown_command` &ndash; fixes wrong `pip` commands, for example `pip instatl/pip install`;
* `php_s` &ndash; replaces `-s` by `-S` when trying to run a local php server;
* `port_already_in_use` &ndash; kills process that bound port;
* `prove_recursively` &ndash; adds `-r` when called with directory;
* `python_command` &ndash; prepends `python` when you try to run non-executable/without `./` python script;
* `python_execute` &ndash; appends missing `.py` when executing Python files;
* `python_module_error` &ndash; fixes ModuleNotFoundError by trying to `pip install` that module;
* `quotation_marks` &ndash; fixes uneven usage of `'` and `"` when containing args';
* `path_from_history` &ndash; replaces not found path with a similar absolute path from history;
* `rails_migrations_pending` &ndash; runs pending migrations;
* `react_native_command_unrecognized` &ndash; fixes unrecognized `react-native` commands;
* `remove_shell_prompt_literal` &ndash; removes leading shell prompt symbol `$`, common when copying commands from documentations;
* `remove_trailing_cedilla` &ndash; removes trailing cedillas `ç`, a common typo for European keyboard layouts;
* `rm_dir` &ndash; adds `-rf` when you try to remove a directory;
* `scm_correction` &ndash; corrects wrong scm like `hg log` to `git log`;
* `sed_unterminated_s` &ndash; adds missing '/' to `sed`'s `s` commands;
* `sl_ls` &ndash; changes `sl` to `ls`;
* `ssh_known_hosts` &ndash; removes host from `known_hosts` on warning;
* `sudo` &ndash; prepends `sudo` to the previous command if it failed because of permissions;
* `sudo_command_from_user_path` &ndash; runs commands from users `$PATH` with `sudo`;
* `switch_lang` &ndash; switches command from your local layout to en;
* `systemctl` &ndash; correctly orders parameters of confusing `systemctl`;
* `terraform_init.py` &ndash; runs `terraform init` before plan or apply;
* `terraform_no_command.py` &ndash; fixes unrecognized `terraform` commands;
* `test.py` &ndash; runs `pytest` instead of `test.py`;
* `touch` &ndash; creates missing directories before "touching";
* `tsuru_login` &ndash; runs `tsuru login` if not authenticated or session expired;
* `tsuru_not_command` &ndash; fixes wrong `tsuru` commands like `tsuru shell`;
* `tmux` &ndash; fixes `tmux` commands;
* `unknown_command` &ndash; fixes hadoop hdfs-style "unknown command", for example adds missing '-' to the command on `hdfs dfs ls`;
* `unsudo` &ndash; removes `sudo` from previous command if a process refuses to run on superuser privilege.
* `vagrant_up` &ndash; starts up the vagrant instance;
* `whois` &ndash; fixes `whois` command;
* `workon_doesnt_exists` &ndash; fixes `virtualenvwrapper` env name os suggests to create new.
* `wrong_hyphen_before_subcommand` &ndash; removes an improperly placed hyphen (`apt-install` -> `apt install`, `git-log` -> `git log`, etc.)
* `yarn_alias` &ndash; fixes aliased `yarn` commands like `yarn ls`;
* `yarn_command_not_found` &ndash; fixes misspelled `yarn` commands;
* `yarn_command_replaced` &ndash; fixes replaced `yarn` commands;
* `yarn_help` &ndash; makes it easier to open `yarn` documentation;

##### [Back to Contents](#contents)

The following rules are enabled by default on specific platforms only:

* `apt_get` &ndash; installs app from apt if it not installed (requires `python-commandnotfound` / `python3-commandnotfound`);
* `apt_get_search` &ndash; changes trying to search using `apt-get` with searching using `apt-cache`;
* `apt_invalid_operation` &ndash; fixes invalid `apt` and `apt-get` calls, like `apt-get isntall vim`;
* `apt_list_upgradable` &ndash; helps you run `apt list --upgradable` after `apt update`;
* `apt_upgrade` &ndash; helps you run `apt upgrade` after `apt list --upgradable`;
* `brew_cask_dependency` &ndash; installs cask dependencies;
* `brew_install` &ndash; fixes formula name for `brew install`;
* `brew_reinstall` &ndash; turns `brew install <formula>` into `brew reinstall <formula>`;
* `brew_link` &ndash; adds `--overwrite --dry-run` if linking fails;
* `brew_uninstall` &ndash; adds `--force` to `brew uninstall` if multiple versions were installed;
* `brew_unknown_command` &ndash; fixes wrong brew commands, for example `brew docto/brew doctor`;
* `brew_update_formula` &ndash; turns `brew update <formula>` into `brew upgrade <formula>`;
* `dnf_no_such_command` &ndash; fixes mistyped DNF commands;
* `nixos_cmd_not_found` &ndash; installs apps on NixOS;
* `pacman` &ndash; installs app with `pacman` if it is not installed (uses `yay`, `pikaur` or `yaourt` if available);
* `pacman_invalid_option` &ndash; replaces lowercase `pacman` options with uppercase.
* `pacman_not_found` &ndash; fixes package name with `pacman`, `yay`, `pikaur` or `yaourt`.
* `yum_invalid_operation` &ndash; fixes invalid `yum` calls, like `yum isntall vim`;

The following commands are bundled with *The Fuck*, but are not enabled by
default:

* `git_push_force` &ndash; adds `--force-with-lease` to a `git push` (may conflict with `git_push_pull`);
* `rm_root` &ndash; adds `--no-preserve-root` to `rm -rf /` command.

##### [Back to Contents](#contents)

## Creating your own rules

To add your own rule, create a file named `your-rule-name.py`
in `~/.config/thefuck/rules`. The rule file must contain two functions:

```python
match(command: Command) -> bool
get_new_command(command: Command) -> str | list[str]
```

Additionally, rules can contain optional functions:

```python
side_effect(old_command: Command, fixed_command: str) -> None
```
Rules can also contain the optional variables `enabled_by_default`, `requires_output` and `priority`.

`Command` has three attributes: `script`, `output` and `script_parts`.
Your rule should not change `Command`.


**Rules api changed in 3.0:** To access a rule's settings, import it with
 `from thefuck.conf import settings`

`settings` is a special object assembled from `~/.config/thefuck/settings.py`,
and values from env ([see more below](#settings)).

A simple example rule for running a script with `sudo`:

```python
def match(command):
    return ('permission denied' in command.output.lower()
            or 'EACCES' in command.output)


def get_new_command(command):
    return 'sudo {}'.format(command.script)

# Optional:
enabled_by_default = True

def side_effect(command, fixed_command):
    subprocess.call('chmod 777 .', shell=True)

priority = 1000  # Lower first, default is 1000

requires_output = True
```

[More examples of rules](https://github.com/nvbn/thefuck/tree/master/thefuck/rules),
[utility functions for rules](https://github.com/nvbn/thefuck/tree/master/thefuck/utils.py),
[app/os-specific helpers](https://github.com/nvbn/thefuck/tree/master/thefuck/specific/).

##### [Back to Contents](#contents)

## Settings

Several *The Fuck* parameters can be changed in the file `$XDG_CONFIG_HOME/thefuck/settings.py`
(`$XDG_CONFIG_HOME` defaults to `~/.config`):

* `rules` &ndash; list of enabled rules, by default `thefuck.const.DEFAULT_RULES`;
* `exclude_rules` &ndash; list of disabled rules, by default `[]`;
* `require_confirmation` &ndash; requires confirmation before running new command, by default `True`;
* `wait_command` &ndash; the max amount of time in seconds for getting previous command output;
* `no_colors` &ndash; disable colored output;
* `priority` &ndash; dict with rules priorities, rule with lower `priority` will be matched first;
* `debug` &ndash; enables debug output, by default `False`;
* `history_limit` &ndash; the numeric value of how many history commands will be scanned, like `2000`;
* `alter_history` &ndash; push fixed command to history, by default `True`;
* `wait_slow_command` &ndash; max amount of time in seconds for getting previous command output if it in `slow_commands` list;
* `slow_commands` &ndash; list of slow commands;
* `num_close_matches` &ndash; the maximum number of close matches to suggest, by default `3`.
* `excluded_search_path_prefixes` &ndash; path prefixes to ignore when searching for commands, by default `[]`.

An example of `settings.py`:

```python
rules = ['sudo', 'no_command']
exclude_rules = ['git_push']
require_confirmation = True
wait_command = 10
no_colors = False
priority = {'sudo': 100, 'no_command': 9999}
debug = False
history_limit = 9999
wait_slow_command = 20
slow_commands = ['react-native', 'gradle']
num_close_matches = 5
```

Or via environment variables:

* `THEFUCK_RULES` &ndash; list of enabled rules, like `DEFAULT_RULES:rm_root` or `sudo:no_command`;
* `THEFUCK_EXCLUDE_RULES` &ndash; list of disabled rules, like `git_pull:git_push`;
* `THEFUCK_REQUIRE_CONFIRMATION` &ndash; require confirmation before running new command, `true/false`;
* `THEFUCK_WAIT_COMMAND` &ndash; the max amount of time in seconds for getting previous command output;
* `THEFUCK_NO_COLORS` &ndash; disable colored output, `true/false`;
* `THEFUCK_PRIORITY` &ndash; priority of the rules, like `no_command=9999:apt_get=100`,
rule with lower `priority` will be matched first;
* `THEFUCK_DEBUG` &ndash; enables debug output, `true/false`;
* `THEFUCK_HISTORY_LIMIT` &ndash; how many history commands will be scanned, like `2000`;
* `THEFUCK_ALTER_HISTORY` &ndash; push fixed command to history `true/false`;
* `THEFUCK_WAIT_SLOW_COMMAND` &ndash; the max amount of time in seconds for getting previous command output if it in `slow_commands` list;
* `THEFUCK_SLOW_COMMANDS` &ndash; list of slow commands, like `lein:gradle`;
* `THEFUCK_NUM_CLOSE_MATCHES` &ndash; the maximum number of close matches to suggest, like `5`.
* `THEFUCK_EXCLUDED_SEARCH_PATH_PREFIXES` &ndash; path prefixes to ignore when searching for commands, by default `[]`.

For example:

```bash
export THEFUCK_RULES='sudo:no_command'
export THEFUCK_EXCLUDE_RULES='git_pull:git_push'
export THEFUCK_REQUIRE_CONFIRMATION='true'
export THEFUCK_WAIT_COMMAND=10
export THEFUCK_NO_COLORS='false'
export THEFUCK_PRIORITY='no_command=9999:apt_get=100'
export THEFUCK_HISTORY_LIMIT='2000'
export THEFUCK_NUM_CLOSE_MATCHES='5'
```

##### [Back to Contents](#contents)

## Third-party packages with rules

If you'd like to make a specific set of non-public rules, but would still like
to share them with others, create a package named `thefuck_contrib_*` with
the following structure:

```
thefuck_contrib_foo
  thefuck_contrib_foo
    rules
      __init__.py
      *third-party rules*
    __init__.py
    *third-party-utils*
  setup.py
```

*The Fuck* will find rules located in the `rules` module.

##### [Back to Contents](#contents)

## Experimental instant mode

The default behavior of *The Fuck* requires time to re-run previous commands.
When in instant mode, *The Fuck* saves time by logging output with [script](https://en.wikipedia.org/wiki/Script_(Unix)),
then reading the log.

[![gif with instant mode][instant-mode-gif-link]][instant-mode-gif-link]

Currently, instant mode only supports Python 3 with bash or zsh. zsh's autocorrect function also needs to be disabled in order for thefuck to work properly.

To enable instant mode, add `--enable-experimental-instant-mode`
to the alias initialization in `.bashrc`, `.bash_profile` or `.zshrc`.

For example:

```bash
eval $(thefuck --alias --enable-experimental-instant-mode)
```

##### [Back to Contents](#contents)

## Developing

See [CONTRIBUTING.md](CONTRIBUTING.md)

## License MIT
Project License can be found [here](LICENSE.md).


[version-badge]:   https://img.shields.io/pypi/v/thefuck.svg?label=version
[version-link]:    https://pypi.python.org/pypi/thefuck/
[workflow-badge]:  https://github.com/nvbn/thefuck/workflows/Tests/badge.svg
[workflow-link]:   https://github.com/nvbn/thefuck/actions?query=workflow%3ATests
[coverage-badge]:  https://img.shields.io/coveralls/nvbn/thefuck.svg
[coverage-link]:   https://coveralls.io/github/nvbn/thefuck
[license-badge]:   https://img.shields.io/badge/license-MIT-007EC7.svg
[examples-link]:   https://raw.githubusercontent.com/nvbn/thefuck/master/example.gif
[instant-mode-gif-link]:   https://raw.githubusercontent.com/nvbn/thefuck/master/example_instant_mode.gif
[homebrew]:        https://brew.sh/

##### [Back to Contents](#contents)


================================================
FILE: fastentrypoints.py
================================================
# Copyright (c) 2016, Aaron Christianson
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
Monkey patch setuptools to write faster console_scripts with this format:

    import sys
    from mymodule import entry_function
    sys.exit(entry_function())

This is better.

(c) 2016, Aaron Christianson
http://github.com/ninjaaron/fast-entry_points
'''
from setuptools.command import easy_install
import re
TEMPLATE = r'''\
# -*- coding: utf-8 -*-
# EASY-INSTALL-ENTRY-SCRIPT: '{3}','{4}','{5}'
__requires__ = '{3}'
import re
import sys

from {0} import {1}

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit({2}())'''


@classmethod
def get_args(cls, dist, header=None):
    """
    Yield write_script() argument tuples for a distribution's
    console_scripts and gui_scripts entry points.
    """
    if header is None:
        header = cls.get_header()
    spec = str(dist.as_requirement())
    for type_ in 'console', 'gui':
        group = type_ + '_scripts'
        for name, ep in dist.get_entry_map(group).items():
            # ensure_safe_name
            if re.search(r'[\\/]', name):
                raise ValueError("Path separators not allowed in script names")
            script_text = TEMPLATE.format(
                          ep.module_name, ep.attrs[0], '.'.join(ep.attrs),
                          spec, group, name)
            args = cls._get_script_args(type_, name, header, script_text)
            for res in args:
                yield res


easy_install.ScriptWriter.get_args = get_args


def main():
    import os
    import re
    import shutil
    import sys
    dests = sys.argv[1:] or ['.']
    filename = re.sub(r'\.pyc$', '.py', __file__)

    for dst in dests:
        shutil.copy(filename, dst)
        manifest_path = os.path.join(dst, 'MANIFEST.in')
        setup_path = os.path.join(dst, 'setup.py')

        # Insert the include statement to MANIFEST.in if not present
        with open(manifest_path, 'a+') as manifest:
            manifest.seek(0)
            manifest_content = manifest.read()
            if not 'include fastentrypoints.py' in manifest_content:
                manifest.write(('\n' if manifest_content else '')
                               + 'include fastentrypoints.py')

        # Insert the import statement to setup.py if not present
        with open(setup_path, 'a+') as setup:
            setup.seek(0)
            setup_content = setup.read()
            if not 'import fastentrypoints' in setup_content:
                setup.seek(0)
                setup.truncate()
                setup.write('import fastentrypoints\n' + setup_content)

print(__name__)


================================================
FILE: install.sh
================================================
#!/bin/sh

echo "Installation script is deprecated!"
echo "For installation instruction please visit https://github.com/nvbn/thefuck"


================================================
FILE: release.py
================================================
#!/usr/bin/env python
from subprocess import call
import os
import re


version = None


def get_new_setup_py_lines():
    global version
    with open('setup.py', 'r') as sf:
        current_setup = sf.readlines()
    for line in current_setup:
        if line.startswith('VERSION = '):
            major, minor = re.findall(r"VERSION = '(\d+)\.(\d+)'", line)[0]
            version = "{}.{}".format(major, int(minor) + 1)
            yield "VERSION = '{}'\n".format(version)
        else:
            yield line


lines = list(get_new_setup_py_lines())
with open('setup.py', 'w') as sf:
    sf.writelines(lines)

call('git pull', shell=True)
call('git commit -am "Bump to {}"'.format(version), shell=True)
call('git tag {}'.format(version), shell=True)
call('git push', shell=True)
call('git push --tags', shell=True)

env = os.environ
env['CONVERT_README'] = 'true'
call('rm -rf dist/*', shell=True, env=env)
call('python setup.py sdist bdist_wheel', shell=True, env=env)
call('twine upload dist/*', shell=True, env=env)


================================================
FILE: requirements.txt
================================================
flake8
pytest
mock
pytest-mock
wheel
setuptools>=17.1
pexpect
pypandoc
pytest-benchmark
pytest-docker-pexpect
twine


================================================
FILE: scripts/fuck.bat
================================================
@set PYTHONIOENCODING=utf-8
@powershell -noprofile -c "cmd /c \"$(thefuck %* $(doskey /history)[-2])\"; [Console]::ResetColor();"


================================================
FILE: scripts/fuck.ps1
================================================
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()


================================================
FILE: setup.cfg
================================================
[bdist_wheel]
universal = 1


================================================
FILE: setup.py
================================================
#!/usr/bin/env python
from setuptools import setup, find_packages
import pkg_resources
import sys
import os
import fastentrypoints


try:
    if int(pkg_resources.get_distribution("pip").version.split('.')[0]) < 6:
        print('pip older than 6.0 not supported, please upgrade pip with:\n\n'
              '    pip install -U pip')
        sys.exit(-1)
except pkg_resources.DistributionNotFound:
    pass

if os.environ.get('CONVERT_README'):
    import pypandoc

    long_description = pypandoc.convert('README.md', 'rst')
else:
    long_description = ''

version = sys.version_info[:2]
if version < (2, 7):
    print('thefuck requires Python version 2.7 or later' +
          ' ({}.{} detected).'.format(*version))
    sys.exit(-1)
elif (3, 0) < version < (3, 5):
    print('thefuck requires Python version 3.5 or later' +
          ' ({}.{} detected).'.format(*version))
    sys.exit(-1)

VERSION = '3.32'

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', '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",
      long_description=long_description,
      author='Vladimir Iakovlev',
      author_email='nvbn.rm@gmail.com',
      url='https://github.com/nvbn/thefuck',
      license='MIT',
      packages=find_packages(exclude=['ez_setup', 'examples',
                                      '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,
      scripts=scripts,
      entry_points=entry_points)


================================================
FILE: snapcraft.yaml
================================================
name: thefuck
version: stable
version-script: git -C parts/thefuck/build describe --abbrev=0 --tags
summary: Magnificent app which corrects your previous console command.
description: |
  The Fuck tries to match a rule for the previous command,
  creates a new command using the matched rule and runs it.

grade: stable
confinement: classic

apps:
  thefuck:
    command: bin/thefuck
    environment:
        PYTHONIOENCODING: utf-8
  fuck:
    command: bin/fuck
    environment:
        PYTHONIOENCODING: utf-8

parts:
  thefuck:
    source: https://github.com/nvbn/thefuck.git
    plugin: python


================================================
FILE: tests/Dockerfile
================================================
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


================================================
FILE: tests/__init__.py
================================================


================================================
FILE: tests/conftest.py
================================================
import os
import pytest
from thefuck import shells
from thefuck import conf, const
from thefuck.system import Path

shells.shell = shells.Generic()


def pytest_configure(config):
    config.addinivalue_line("markers", "functional: mark test as functional")


def pytest_addoption(parser):
    """Adds `--enable-functional` argument."""
    group = parser.getgroup("thefuck")
    group.addoption('--enable-functional', action="store_true", default=False,
                    help="Enable functional tests")


@pytest.fixture
def no_memoize(monkeypatch):
    monkeypatch.setattr('thefuck.utils.memoize.disabled', True)


@pytest.fixture(autouse=True)
def settings(request):
    def _reset_settings():
        conf.settings.clear()
        conf.settings.update(const.DEFAULT_SETTINGS)

    request.addfinalizer(_reset_settings)
    conf.settings.user_dir = Path('~/.thefuck')
    return conf.settings


@pytest.fixture
def no_colors(settings):
    settings.no_colors = True


@pytest.fixture(autouse=True)
def no_cache(monkeypatch):
    monkeypatch.setattr('thefuck.utils.cache.disabled', True)


@pytest.fixture(autouse=True)
def functional(request):
    if request.node.get_closest_marker('functional') \
            and not request.config.getoption('enable_functional'):
        pytest.skip('functional tests are disabled')


@pytest.fixture
def source_root():
    return Path(__file__).parent.parent.resolve()


@pytest.fixture
def set_shell(monkeypatch):
    def _set(cls):
        shell = cls()
        monkeypatch.setattr('thefuck.shells.shell', shell)
        return shell

    return _set


@pytest.fixture(autouse=True)
def os_environ(monkeypatch):
    env = {'PATH': os.environ['PATH']}
    monkeypatch.setattr('os.environ', env)
    return env


================================================
FILE: tests/entrypoints/__init__.py
================================================


================================================
FILE: tests/entrypoints/test_alias.py
================================================
from mock import Mock
import pytest
from thefuck.entrypoints.alias import _get_alias, print_alias


@pytest.mark.parametrize(
    'py2, enable_experimental_instant_mode, which, is_instant', [
        (False, True, True, True),
        (False, False, True, False),
        (False, True, False, False),
        (True, True, True, False),
        (True, True, False, False),
        (True, False, True, False)])
def test_get_alias(monkeypatch, mocker, py2,
                   enable_experimental_instant_mode,
                   which, is_instant):
    monkeypatch.setattr('six.PY2', py2)
    args = Mock(
        enable_experimental_instant_mode=enable_experimental_instant_mode,
        alias='fuck', )
    mocker.patch('thefuck.entrypoints.alias.which', return_value=which)
    shell = Mock(app_alias=lambda _: 'app_alias',
                 instant_mode_alias=lambda _: 'instant_mode_alias')
    monkeypatch.setattr('thefuck.entrypoints.alias.shell', shell)

    alias = _get_alias(args)
    if is_instant:
        assert alias == 'instant_mode_alias'
    else:
        assert alias == 'app_alias'


def test_print_alias(mocker):
    settings_mock = mocker.patch('thefuck.entrypoints.alias.settings')
    _get_alias_mock = mocker.patch('thefuck.entrypoints.alias._get_alias')
    known_args = Mock()
    print_alias(known_args)
    settings_mock.init.assert_called_once_with(known_args)
    _get_alias_mock.assert_called_once_with(known_args)


================================================
FILE: tests/entrypoints/test_fix_command.py
================================================
import pytest
from mock import Mock
from thefuck.entrypoints.fix_command import _get_raw_command


class TestGetRawCommand(object):
    def test_from_force_command_argument(self):
        known_args = Mock(force_command='git brunch')
        assert _get_raw_command(known_args) == ['git brunch']

    def test_from_command_argument(self, os_environ):
        os_environ['TF_HISTORY'] = None
        known_args = Mock(force_command=None,
                          command=['sl'])
        assert _get_raw_command(known_args) == ['sl']

    @pytest.mark.parametrize('history, result', [
        ('git br', 'git br'),
        ('git br\nfcuk', 'git br'),
        ('git br\nfcuk\nls', 'ls'),
        ('git br\nfcuk\nls\nfuk', 'ls')])
    def test_from_history(self, os_environ, history, result):
        os_environ['TF_HISTORY'] = history
        known_args = Mock(force_command=None,
                          command=None)
        assert _get_raw_command(known_args) == [result]


================================================
FILE: tests/entrypoints/test_not_configured.py
================================================
import pytest
import json
from six import StringIO
from mock import MagicMock
from thefuck.shells.generic import ShellConfiguration
from thefuck.entrypoints.not_configured import main


@pytest.fixture(autouse=True)
def usage_tracker(mocker):
    return mocker.patch(
        'thefuck.entrypoints.not_configured._get_not_configured_usage_tracker_path',
        new_callable=MagicMock)


@pytest.fixture(autouse=True)
def usage_tracker_io(usage_tracker):
    io = StringIO()
    usage_tracker.return_value \
                 .open.return_value \
                 .__enter__.return_value = io
    return io


@pytest.fixture(autouse=True)
def usage_tracker_exists(usage_tracker):
    usage_tracker.return_value \
                 .exists.return_value = True
    return usage_tracker.return_value.exists


def _assert_tracker_updated(usage_tracker_io, pid):
    usage_tracker_io.seek(0)
    info = json.load(usage_tracker_io)
    assert info['pid'] == pid


def _change_tracker(usage_tracker_io, pid):
    usage_tracker_io.truncate(0)
    info = {'pid': pid, 'time': 0}
    json.dump(info, usage_tracker_io)
    usage_tracker_io.seek(0)


@pytest.fixture(autouse=True)
def shell_pid(mocker):
    return mocker.patch('thefuck.entrypoints.not_configured._get_shell_pid',
                        new_callable=MagicMock)


@pytest.fixture(autouse=True)
def shell(mocker):
    shell = mocker.patch('thefuck.entrypoints.not_configured.shell',
                         new_callable=MagicMock)
    shell.get_history.return_value = []
    shell.how_to_configure.return_value = ShellConfiguration(
        content='eval $(thefuck --alias)',
        path='/tmp/.bashrc',
        reload='bash',
        can_configure_automatically=True)
    return shell


@pytest.fixture(autouse=True)
def shell_config(mocker):
    path_mock = mocker.patch('thefuck.entrypoints.not_configured.Path',
                             new_callable=MagicMock)
    return path_mock.return_value \
        .expanduser.return_value \
        .open.return_value \
        .__enter__.return_value


@pytest.fixture(autouse=True)
def logs(mocker):
    return mocker.patch('thefuck.entrypoints.not_configured.logs',
                        new_callable=MagicMock)


def test_for_generic_shell(shell, logs):
    shell.how_to_configure.return_value = None
    main()
    logs.how_to_configure_alias.assert_called_once()


def test_on_first_run(usage_tracker_io, usage_tracker_exists, shell_pid, logs):
    shell_pid.return_value = 12
    main()
    usage_tracker_exists.return_value = False
    _assert_tracker_updated(usage_tracker_io, 12)
    logs.how_to_configure_alias.assert_called_once()


def test_on_run_after_other_commands(usage_tracker_io, shell_pid, shell, logs):
    shell_pid.return_value = 12
    shell.get_history.return_value = ['fuck', 'ls']
    _change_tracker(usage_tracker_io, 12)
    main()
    logs.how_to_configure_alias.assert_called_once()


def test_on_first_run_from_current_shell(usage_tracker_io, shell_pid,
                                         shell, logs):
    shell.get_history.return_value = ['fuck']
    shell_pid.return_value = 12
    main()
    _assert_tracker_updated(usage_tracker_io, 12)
    logs.how_to_configure_alias.assert_called_once()


def test_when_cant_configure_automatically(shell_pid, shell, logs):
    shell_pid.return_value = 12
    shell.how_to_configure.return_value = ShellConfiguration(
        content='eval $(thefuck --alias)',
        path='/tmp/.bashrc',
        reload='bash',
        can_configure_automatically=False)
    main()
    logs.how_to_configure_alias.assert_called_once()


def test_when_already_configured(usage_tracker_io, shell_pid,
                                 shell, shell_config, logs):
    shell.get_history.return_value = ['fuck']
    shell_pid.return_value = 12
    _change_tracker(usage_tracker_io, 12)
    shell_config.read.return_value = 'eval $(thefuck --alias)'
    main()
    logs.already_configured.assert_called_once()


def test_when_successfully_configured(usage_tracker_io, shell_pid,
                                      shell, shell_config, logs):
    shell.get_history.return_value = ['fuck']
    shell_pid.return_value = 12
    _change_tracker(usage_tracker_io, 12)
    shell_config.read.return_value = ''
    main()
    shell_config.write.assert_any_call('eval $(thefuck --alias)')
    logs.configured_successfully.assert_called_once()


================================================
FILE: tests/functional/__init__.py
================================================


================================================
FILE: tests/functional/conftest.py
================================================
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)


================================================
FILE: tests/functional/plots.py
================================================
def _set_confirmation(proc, require):
    proc.sendline(u'mkdir -p ~/.thefuck')
    proc.sendline(
        u'echo "require_confirmation = {}" > ~/.thefuck/settings.py'.format(
            require))


def with_confirmation(proc, TIMEOUT):
    """Ensures that command can be fixed when confirmation enabled."""
    _set_confirmation(proc, True)

    proc.sendline(u'ehco test')

    proc.sendline(u'fuck')
    assert proc.expect([TIMEOUT, u'echo test'])
    assert proc.expect([TIMEOUT, u'enter'])
    assert proc.expect_exact([TIMEOUT, u'ctrl+c'])
    proc.send('\n')

    assert proc.expect([TIMEOUT, u'test'])


def history_changed(proc, TIMEOUT, *to):
    """Ensures that history changed."""
    proc.send('\033[A')
    pattern = [TIMEOUT]
    pattern.extend(to)
    assert proc.expect(pattern)


def history_not_changed(proc, TIMEOUT):
    """Ensures that history not changed."""
    proc.send('\033[A')
    assert proc.expect([TIMEOUT, u'fuck'])


def select_command_with_arrows(proc, TIMEOUT):
    """Ensures that command can be selected with arrow keys."""
    _set_confirmation(proc, True)

    proc.sendline(u'git h')
    assert proc.expect([TIMEOUT, u"git: 'h' is not a git command."])

    proc.sendline(u'fuck')
    assert proc.expect([TIMEOUT, u'git show'])
    proc.send('\033[B')
    assert proc.expect([TIMEOUT, u'git push'])
    proc.send('\033[B')
    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', u'git hook'])
    proc.send('\n')

    assert proc.expect([TIMEOUT, u'usage', u'fatal: not a git repository'])


def refuse_with_confirmation(proc, TIMEOUT):
    """Ensures that fix can be refused when confirmation enabled."""
    _set_confirmation(proc, True)

    proc.sendline(u'ehco test')

    proc.sendline(u'fuck')
    assert proc.expect([TIMEOUT, u'echo test'])
    assert proc.expect([TIMEOUT, u'enter'])
    assert proc.expect_exact([TIMEOUT, u'ctrl+c'])
    proc.send('\003')

    assert proc.expect([TIMEOUT, u'Aborted'])


def without_confirmation(proc, TIMEOUT):
    """Ensures that command can be fixed when confirmation disabled."""
    _set_confirmation(proc, False)

    proc.sendline(u'ehco test')

    proc.sendline(u'fuck')
    assert proc.expect([TIMEOUT, u'echo test'])
    assert proc.expect([TIMEOUT, u'test'])


def how_to_configure(proc, TIMEOUT):
    proc.sendline(u'fuck')
    assert proc.expect([TIMEOUT, u"alias isn't configured"])


================================================
FILE: tests/functional/test_bash.py
================================================
import pytest
from tests.functional.plots import with_confirmation, without_confirmation, \
    refuse_with_confirmation, history_changed, history_not_changed, \
    select_command_with_arrows, how_to_configure


python_3 = (u'thefuck/python3',
            u'',
            u'sh')

python_2 = (u'thefuck/python2',
            u'',
            u'sh')


init_bashrc = u'''echo '
export SHELL=/bin/bash
export PS1="$ "
echo > $HISTFILE
eval $(thefuck --alias {})
echo "instant mode ready: $THEFUCK_INSTANT_MODE"
' > ~/.bashrc'''


@pytest.fixture(params=[(python_3, False),
                        (python_3, True),
                        (python_2, False)])
def proc(request, spawnu, TIMEOUT):
    container, instant_mode = request.param
    proc = spawnu(*container)
    proc.sendline(init_bashrc.format(
        u'--enable-experimental-instant-mode' if instant_mode else ''))
    proc.sendline(u"bash")
    if instant_mode:
        assert proc.expect([TIMEOUT, u'instant mode ready: True'])
    return proc


@pytest.mark.functional
def test_with_confirmation(proc, TIMEOUT):
    with_confirmation(proc, TIMEOUT)
    history_changed(proc, TIMEOUT, u'echo test')


@pytest.mark.functional
def test_select_command_with_arrows(proc, TIMEOUT):
    select_command_with_arrows(proc, TIMEOUT)
    history_changed(proc, TIMEOUT, u'git help', u'git hook')


@pytest.mark.functional
def test_refuse_with_confirmation(proc, TIMEOUT):
    refuse_with_confirmation(proc, TIMEOUT)
    history_not_changed(proc, TIMEOUT)


@pytest.mark.functional
def test_without_confirmation(proc, TIMEOUT):
    without_confirmation(proc, TIMEOUT)
    history_changed(proc, TIMEOUT, u'echo test')


@pytest.mark.functional
def test_how_to_configure_alias(proc, TIMEOUT):
    proc.sendline('unset -f fuck')
    how_to_configure(proc, TIMEOUT)


================================================
FILE: tests/functional/test_fish.py
================================================
import pytest
from tests.functional.plots import with_confirmation, without_confirmation, \
    refuse_with_confirmation, select_command_with_arrows

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'thefuck --alias > ~/.config/fish/config.fish')
    proc.sendline(u'fish')
    return proc


@pytest.mark.functional
def test_with_confirmation(proc, TIMEOUT):
    with_confirmation(proc, TIMEOUT)


@pytest.mark.functional
def test_select_command_with_arrows(proc, TIMEOUT):
    select_command_with_arrows(proc, TIMEOUT)


@pytest.mark.functional
def test_refuse_with_confirmation(proc, TIMEOUT):
    refuse_with_confirmation(proc, TIMEOUT)


@pytest.mark.functional
def test_without_confirmation(proc, TIMEOUT):
    without_confirmation(proc, TIMEOUT)

# TODO: ensure that history changes.


================================================
FILE: tests/functional/test_tcsh.py
================================================
import pytest
from tests.functional.plots import with_confirmation, without_confirmation, \
    refuse_with_confirmation, select_command_with_arrows

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'tcsh')
    proc.sendline(u'setenv PYTHONIOENCODING utf8')
    proc.sendline(u'eval `thefuck --alias`')
    return proc


@pytest.mark.functional
def test_with_confirmation(proc, TIMEOUT):
    with_confirmation(proc, TIMEOUT)


@pytest.mark.functional
def test_select_command_with_arrows(proc, TIMEOUT):
    select_command_with_arrows(proc, TIMEOUT)


@pytest.mark.functional
def test_refuse_with_confirmation(proc, TIMEOUT):
    refuse_with_confirmation(proc, TIMEOUT)


@pytest.mark.functional
def test_without_confirmation(proc, TIMEOUT):
    without_confirmation(proc, TIMEOUT)

# TODO: ensure that history changes.


================================================
FILE: tests/functional/test_zsh.py
================================================
import pytest
from tests.functional.plots import with_confirmation, without_confirmation, \
    refuse_with_confirmation, history_changed, history_not_changed, \
    select_command_with_arrows, how_to_configure


python_3 = (u'thefuck/python3', u'', u'sh')
python_2 = (u'thefuck/python2', u'', u'sh')


init_zshrc = u'''echo '
export SHELL=/usr/bin/zsh
export HISTFILE=~/.zsh_history
echo > $HISTFILE
export SAVEHIST=100
export HISTSIZE=100
eval $(thefuck --alias {})
setopt INC_APPEND_HISTORY
echo "instant mode ready: $THEFUCK_INSTANT_MODE"
' > ~/.zshrc'''


@pytest.fixture(params=[(python_3, False),
                        (python_3, True),
                        (python_2, False)])
def proc(request, spawnu, TIMEOUT):
    container, instant_mode = request.param
    proc = spawnu(*container)
    proc.sendline(init_zshrc.format(
        u'--enable-experimental-instant-mode' if instant_mode else ''))
    proc.sendline(u"zsh")
    if instant_mode:
        assert proc.expect([TIMEOUT, u'instant mode ready: True'])
    return proc


@pytest.mark.functional
def test_with_confirmation(proc, TIMEOUT):
    with_confirmation(proc, TIMEOUT)
    history_changed(proc, TIMEOUT, u'echo test')


@pytest.mark.functional
def test_select_command_with_arrows(proc, TIMEOUT):
    select_command_with_arrows(proc, TIMEOUT)
    history_changed(proc, TIMEOUT, u'git help', u'git hook')


@pytest.mark.functional
def test_refuse_with_confirmation(proc, TIMEOUT):
    refuse_with_confirmation(proc, TIMEOUT)
    history_not_changed(proc, TIMEOUT)


@pytest.mark.functional
def test_without_confirmation(proc, TIMEOUT):
    without_confirmation(proc, TIMEOUT)
    history_changed(proc, TIMEOUT, u'echo test')


@pytest.mark.functional
def test_how_to_configure_alias(proc, TIMEOUT):
    proc.sendline(u'unfunction fuck')
    how_to_configure(proc, TIMEOUT)


================================================
FILE: tests/output_readers/test_rerun.py
================================================
# -*- encoding: utf-8 -*-

import pytest
import sys
from mock import Mock, patch
from psutil import AccessDenied, TimeoutExpired

from thefuck.output_readers import rerun


class TestRerun(object):
    def setup_method(self, test_method):
        self.patcher = patch('thefuck.output_readers.rerun.Process')
        process_mock = self.patcher.start()
        self.proc_mock = process_mock.return_value = Mock()

    def teardown_method(self, test_method):
        self.patcher.stop()

    @patch('thefuck.output_readers.rerun._wait_output', return_value=False)
    @patch('thefuck.output_readers.rerun.Popen')
    def test_get_output(self, popen_mock, wait_output_mock):
        popen_mock.return_value.stdout.read.return_value = b'output'
        assert rerun.get_output('', '') is None
        wait_output_mock.assert_called_once()

    @patch('thefuck.output_readers.rerun.Popen')
    def test_get_output_invalid_continuation_byte(self, popen_mock):
        output = b'ls: illegal option -- \xc3\nusage: ls [-@ABC...] [file ...]\n'
        expected = u'ls: illegal option -- \ufffd\nusage: ls [-@ABC...] [file ...]\n'
        popen_mock.return_value.stdout.read.return_value = output
        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')
        wait_output_mock.assert_called_once()

    def test_wait_output_is_slow(self, settings):
        assert rerun._wait_output(Mock(), True)
        self.proc_mock.wait.assert_called_once_with(settings.wait_slow_command)

    def test_wait_output_is_not_slow(self, settings):
        assert rerun._wait_output(Mock(), False)
        self.proc_mock.wait.assert_called_once_with(settings.wait_command)

    @patch('thefuck.output_readers.rerun._kill_process')
    def test_wait_output_timeout(self, kill_process_mock):
        self.proc_mock.wait.side_effect = TimeoutExpired(3)
        self.proc_mock.children.return_value = []
        assert not rerun._wait_output(Mock(), False)
        kill_process_mock.assert_called_once_with(self.proc_mock)

    @patch('thefuck.output_readers.rerun._kill_process')
    def test_wait_output_timeout_children(self, kill_process_mock):
        self.proc_mock.wait.side_effect = TimeoutExpired(3)
        self.proc_mock.children.return_value = [Mock()] * 2
        assert not rerun._wait_output(Mock(), False)
        assert kill_process_mock.call_count == 3

    def test_kill_process(self):
        proc = Mock()
        rerun._kill_process(proc)
        proc.kill.assert_called_once_with()

    @patch('thefuck.output_readers.rerun.logs')
    def test_kill_process_access_denied(self, logs_mock):
        proc = Mock()
        proc.kill.side_effect = AccessDenied()
        rerun._kill_process(proc)
        proc.kill.assert_called_once_with()
        logs_mock.debug.assert_called_once()


================================================
FILE: tests/rules/__init__.py
================================================


================================================
FILE: tests/rules/test_adb_unknown_command.py
================================================
import pytest
from thefuck.rules.adb_unknown_command import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def output():
    return '''Android Debug Bridge version 1.0.31

 -d                            - directs command to the only connected USB device
                                 returns an error if more than one USB device is present.
 -e                            - directs command to the only running emulator.
                                 returns an error if more than one emulator is running.
 -s <specific device>          - directs command to the device or emulator with the given
                                 serial number or qualifier. Overrides ANDROID_SERIAL
                                 environment variable.
'''


@pytest.mark.parametrize('script', [
    ('adb lgcat'),
    ('adb puhs')])
def test_match(output, script):
    assert match(Command(script, output))


@pytest.mark.parametrize('script', [
    'git branch foo',
    'abd push'])
def test_not_match(script):
    assert not match(Command(script, ''))


@pytest.mark.parametrize('script, new_command', [
    ('adb puhs test.bin /sdcard/test.bin', 'adb push test.bin /sdcard/test.bin'),
    ('adb -s 1111 logcta', 'adb -s 1111 logcat'),
    ('adb -P 666 pulll /sdcard/test.bin', 'adb -P 666 pull /sdcard/test.bin'),
    ('adb -d logcatt', 'adb -d logcat'),
    ('adb -e reboott', 'adb -e reboot')])
def test_get_new_command(script, output, new_command):
    assert get_new_command(Command(script, output)) == new_command


================================================
FILE: tests/rules/test_ag_literal.py
================================================
import pytest
from thefuck.rules.ag_literal import get_new_command, match
from thefuck.types import Command


@pytest.fixture
def output():
    return ('ERR: Bad regex! pcre_compile() failed at position 1: missing )\n'
            'If you meant to search for a literal string, run ag with -Q\n')


@pytest.mark.parametrize('script', ['ag \\('])
def test_match(script, output):
    assert match(Command(script, output))


@pytest.mark.parametrize('script', ['ag foo'])
def test_not_match(script):
    assert not match(Command(script, ''))


@pytest.mark.parametrize('script, new_cmd', [
    ('ag \\(', 'ag -Q \\(')])
def test_get_new_command(script, new_cmd, output):
    assert get_new_command((Command(script, output))) == new_cmd


================================================
FILE: tests/rules/test_apt_get.py
================================================
import pytest
from thefuck.rules.apt_get import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize('command, packages', [
    (Command('vim', 'vim: command not found'),
     [('vim', 'main'), ('vim-tiny', 'main')]),
    (Command('sudo vim', 'vim: command not found'),
     [('vim', 'main'), ('vim-tiny', 'main')]),
    (Command('vim', "The program 'vim' is currently not installed. You can install it by typing: sudo apt install vim"),
     [('vim', 'main'), ('vim-tiny', 'main')])])
def test_match(mocker, command, packages):
    mocker.patch('thefuck.rules.apt_get.which', return_value=None)
    mocker.patch('thefuck.rules.apt_get._get_packages',
                 create=True, return_value=packages)

    assert match(command)


@pytest.mark.parametrize('command, packages, which', [
    (Command('a_bad_cmd', 'a_bad_cmd: command not found'),
     [], None),
    (Command('vim', ''), [], None),
    (Command('', ''), [], None),
    (Command('vim', 'vim: command not found'),
     ['vim'], '/usr/bin/vim'),
    (Command('sudo vim', 'vim: command not found'),
     ['vim'], '/usr/bin/vim')])
def test_not_match(mocker, command, packages, which):
    mocker.patch('thefuck.rules.apt_get.which', return_value=which)
    mocker.patch('thefuck.rules.apt_get._get_packages',
                 create=True, return_value=packages)

    assert not match(command)


@pytest.mark.parametrize('command, new_command, packages', [
    (Command('vim', ''), 'sudo apt-get install vim && vim',
     [('vim', 'main'), ('vim-tiny', 'main')]),
    (Command('convert', ''), 'sudo apt-get install imagemagick && convert',
     [('imagemagick', 'main'),
      ('graphicsmagick-imagemagick-compat', 'universe')]),
    (Command('sudo vim', ''), 'sudo apt-get install vim && sudo vim',
     [('vim', 'main'), ('vim-tiny', 'main')]),
    (Command('sudo convert', ''), 'sudo apt-get install imagemagick && sudo convert',
     [('imagemagick', 'main'),
      ('graphicsmagick-imagemagick-compat', 'universe')])])
def test_get_new_command(mocker, command, new_command, packages):
    mocker.patch('thefuck.rules.apt_get._get_packages',
                 create=True, return_value=packages)

    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_apt_get_search.py
================================================
import pytest
from thefuck.rules.apt_get_search import get_new_command, match
from thefuck.types import Command


def test_match():
    assert match(Command('apt-get search foo', ''))


@pytest.mark.parametrize('command', [
    Command('apt-cache search foo', ''),
    Command('aptitude search foo', ''),
    Command('apt search foo', ''),
    Command('apt-get install foo', ''),
    Command('apt-get source foo', ''),
    Command('apt-get clean', ''),
    Command('apt-get remove', ''),
    Command('apt-get update', '')
])
def test_not_match(command):
    assert not match(command)


def test_get_new_command():
    new_command = get_new_command(Command('apt-get search foo', ''))
    assert new_command == 'apt-cache search foo'


================================================
FILE: tests/rules/test_apt_invalid_operation.py
================================================
from io import BytesIO
import pytest
from thefuck.types import Command
from thefuck.rules.apt_invalid_operation import match, get_new_command, \
    _get_operations

invalid_operation = 'E: Invalid operation {}'.format
apt_help = b'''apt 1.0.10.2ubuntu1 for amd64 compiled on Oct  5 2015 15:55:05
Usage: apt [options] command

CLI for apt.
Basic commands:
 list - list packages based on package names
 search - search in package descriptions
 show - show package details

 update - update list of available packages

 install - install packages
 remove  - remove packages

 upgrade - upgrade the system by installing/upgrading packages
 full-upgrade - upgrade the system by removing/installing/upgrading packages

 edit-sources - edit the source information file
'''
apt_operations = ['list', 'search', 'show', 'update', 'install', 'remove',
                  'upgrade', 'full-upgrade', 'edit-sources']

apt_get_help = b'''apt 1.0.10.2ubuntu1 for amd64 compiled on Oct  5 2015 15:55:05
Usage: apt-get [options] command
       apt-get [options] install|remove pkg1 [pkg2 ...]
       apt-get [options] source pkg1 [pkg2 ...]

apt-get is a simple command line interface for downloading and
installing packages. The most frequently used commands are update
and install.

Commands:
   update - Retrieve new lists of packages
   upgrade - Perform an upgrade
   install - Install new packages (pkg is libc6 not libc6.deb)
   remove - Remove packages
   autoremove - Remove automatically all unused packages
   purge - Remove packages and config files
   source - Download source archives
   build-dep - Configure build-dependencies for source packages
   dist-upgrade - Distribution upgrade, see apt-get(8)
   dselect-upgrade - Follow dselect selections
   clean - Erase downloaded archive files
   autoclean - Erase old downloaded archive files
   check - Verify that there are no broken dependencies
   changelog - Download and display the changelog for the given package
   download - Download the binary package into the current directory

Options:
  -h  This help text.
  -q  Loggable output - no progress indicator
  -qq No output except for errors
  -d  Download only - do NOT install or unpack archives
  -s  No-act. Perform ordering simulation
  -y  Assume Yes to all queries and do not prompt
  -f  Attempt to correct a system with broken dependencies in place
  -m  Attempt to continue if archives are unlocatable
  -u  Show a list of upgraded packages as well
  -b  Build the source package after fetching it
  -V  Show verbose version numbers
  -c=? Read this configuration file
  -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp
See the apt-get(8), sources.list(5) and apt.conf(5) manual
pages for more information and options.
                       This APT has Super Cow Powers.
'''
apt_get_operations = ['update', 'upgrade', 'install', 'remove', 'autoremove',
                      'purge', 'source', 'build-dep', 'dist-upgrade',
                      'dselect-upgrade', 'clean', 'autoclean', 'check',
                      'changelog', 'download']

new_apt_get_help = b'''apt 1.6.12 (amd64)
Usage: apt-get [options] command
       apt-get [options] install|remove pkg1 [pkg2 ...]
       apt-get [options] source pkg1 [pkg2 ...]

apt-get is a command line interface for retrieval of packages
and information about them from authenticated sources and
for installation, upgrade and removal of packages together
with their dependencies.

Most used commands:
  update - Retrieve new lists of packages
  upgrade - Perform an upgrade
  install - Install new packages (pkg is libc6 not libc6.deb)
  remove - Remove packages
  purge - Remove packages and config files
  autoremove - Remove automatically all unused packages
  dist-upgrade - Distribution upgrade, see apt-get(8)
  dselect-upgrade - Follow dselect selections
  build-dep - Configure build-dependencies for source packages
  clean - Erase downloaded archive files
  autoclean - Erase old downloaded archive files
  check - Verify that there are no broken dependencies
  source - Download source archives
  download - Download the binary package into the current directory
  changelog - Download and display the changelog for the given package

See apt-get(8) for more information about the available commands.
Configuration options and syntax is detailed in apt.conf(5).
Information about how to configure sources can be found in sources.list(5).
Package and version choices can be expressed via apt_preferences(5).
Security details are available in apt-secure(8).
                                        This APT has Super Cow Powers.
'''
new_apt_get_operations = ['update', 'upgrade', 'install', 'remove', 'purge',
                          'autoremove', 'dist-upgrade', 'dselect-upgrade',
                          'build-dep', 'clean', 'autoclean', 'check',
                          'source', 'download', 'changelog']


@pytest.mark.parametrize('script, output', [
    ('apt', invalid_operation('saerch')),
    ('apt-get', invalid_operation('isntall')),
    ('apt-cache', invalid_operation('rumove'))])
def test_match(script, output):
    assert match(Command(script, output))


@pytest.mark.parametrize('script, output', [
    ('vim', invalid_operation('vim')),
    ('apt-get', "")])
def test_not_match(script, output):
    assert not match(Command(script, output))


@pytest.fixture
def set_help(mocker):
    mock = mocker.patch('subprocess.Popen')

    def _set_text(text):
        mock.return_value.stdout = BytesIO(text)

    return _set_text


@pytest.mark.parametrize('app, help_text, operations', [
    ('apt', apt_help, apt_operations),
    ('apt-get', apt_get_help, apt_get_operations),
    ('apt-get', new_apt_get_help, new_apt_get_operations)
])
def test_get_operations(set_help, app, help_text, operations):
    set_help(help_text)
    assert _get_operations(app) == operations


@pytest.mark.parametrize('script, output, help_text, result', [
    ('apt-get isntall vim', invalid_operation('isntall'),
     apt_get_help, 'apt-get install vim'),
    ('apt saerch vim', invalid_operation('saerch'),
     apt_help, 'apt search vim'),
    ('apt uninstall vim', invalid_operation('uninstall'),
     apt_help, 'apt remove vim'),
])
def test_get_new_command(set_help, output, script, help_text, result):
    set_help(help_text)
    assert get_new_command(Command(script, output))[0] == result


================================================
FILE: tests/rules/test_apt_list_upgradable.py
================================================
# -*- coding: utf-8 -*-

import pytest
from thefuck.rules.apt_list_upgradable import get_new_command, match
from thefuck.types import Command

full_english_output = '''
Hit:1 http://us.archive.ubuntu.com/ubuntu zesty InRelease
Hit:2 http://us.archive.ubuntu.com/ubuntu zesty-updates InRelease
Get:3 http://us.archive.ubuntu.com/ubuntu zesty-backports InRelease [89.2 kB]
Hit:4 http://security.ubuntu.com/ubuntu zesty-security InRelease
Hit:5 http://ppa.launchpad.net/ubuntu-mozilla-daily/ppa/ubuntu zesty InRelease
Hit:6 https://download.docker.com/linux/ubuntu zesty InRelease
Hit:7 https://cli-assets.heroku.com/branches/stable/apt ./ InRelease
Fetched 89.2 kB in 0s (122 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
8 packages can be upgraded. Run 'apt list --upgradable' to see them.
'''

match_output = [
    full_english_output,
    'Führen Sie »apt list --upgradable« aus, um sie anzuzeigen.'  # German
]

no_match_output = '''
Hit:1 http://us.archive.ubuntu.com/ubuntu zesty InRelease
Get:2 http://us.archive.ubuntu.com/ubuntu zesty-updates InRelease [89.2 kB]
Get:3 http://us.archive.ubuntu.com/ubuntu zesty-backports InRelease [89.2 kB]
Get:4 http://security.ubuntu.com/ubuntu zesty-security InRelease [89.2 kB]
Hit:5 https://cli-assets.heroku.com/branches/stable/apt ./ InRelease
Hit:6 http://ppa.launchpad.net/ubuntu-mozilla-daily/ppa/ubuntu zesty InRelease
Hit:7 https://download.docker.com/linux/ubuntu zesty InRelease
Get:8 http://us.archive.ubuntu.com/ubuntu zesty-updates/main i386 Packages [232 kB]
Get:9 http://us.archive.ubuntu.com/ubuntu zesty-updates/main amd64 Packages [235 kB]
Get:10 http://us.archive.ubuntu.com/ubuntu zesty-updates/main amd64 DEP-11 Metadata [55.2 kB]
Get:11 http://us.archive.ubuntu.com/ubuntu zesty-updates/main DEP-11 64x64 Icons [32.3 kB]
Get:12 http://us.archive.ubuntu.com/ubuntu zesty-updates/universe amd64 Packages [156 kB]
Get:13 http://us.archive.ubuntu.com/ubuntu zesty-updates/universe i386 Packages [156 kB]
Get:14 http://us.archive.ubuntu.com/ubuntu zesty-updates/universe amd64 DEP-11 Metadata [175 kB]
Get:15 http://us.archive.ubuntu.com/ubuntu zesty-updates/universe DEP-11 64x64 Icons [253 kB]
Get:16 http://us.archive.ubuntu.com/ubuntu zesty-updates/multiverse amd64 DEP-11 Metadata [5,840 B]
Get:17 http://us.archive.ubuntu.com/ubuntu zesty-backports/universe amd64 DEP-11 Metadata [4,588 B]
Get:18 http://security.ubuntu.com/ubuntu zesty-security/main amd64 DEP-11 Metadata [12.7 kB]
Get:19 http://security.ubuntu.com/ubuntu zesty-security/main DEP-11 64x64 Icons [17.6 kB]
Get:20 http://security.ubuntu.com/ubuntu zesty-security/universe amd64 DEP-11 Metadata [21.6 kB]
Get:21 http://security.ubuntu.com/ubuntu zesty-security/universe DEP-11 64x64 Icons [47.7 kB]
Get:22 http://security.ubuntu.com/ubuntu zesty-security/multiverse amd64 DEP-11 Metadata [208 B]
Fetched 1,673 kB in 0s (1,716 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.
'''


@pytest.mark.parametrize('output', match_output)
def test_match(output):
    assert match(Command('sudo apt update', output))


@pytest.mark.parametrize('command', [
    Command('apt-cache search foo', ''),
    Command('aptitude search foo', ''),
    Command('apt search foo', ''),
    Command('apt-get install foo', ''),
    Command('apt-get source foo', ''),
    Command('apt-get clean', ''),
    Command('apt-get remove', ''),
    Command('apt-get update', ''),
    Command('sudo apt update', no_match_output)
])
def test_not_match(command):
    assert not match(command)


@pytest.mark.parametrize('output', match_output)
def test_get_new_command(output):
    new_command = get_new_command(Command('sudo apt update', output))
    assert new_command == 'sudo apt list --upgradable'

    new_command = get_new_command(Command('apt update', output))
    assert new_command == 'apt list --upgradable'


================================================
FILE: tests/rules/test_apt_upgrade.py
================================================
import pytest
from thefuck.rules.apt_upgrade import get_new_command, match
from thefuck.types import Command

match_output = '''
Listing... Done
heroku/stable 6.15.2-1 amd64 [upgradable from: 6.14.43-1]
resolvconf/zesty-updates,zesty-updates 1.79ubuntu4.1 all [upgradable from: 1.79ubuntu4]
squashfs-tools/zesty-updates 1:4.3-3ubuntu2.17.04.1 amd64 [upgradable from: 1:4.3-3ubuntu2]
unattended-upgrades/zesty-updates,zesty-updates 0.93.1ubuntu2.4 all [upgradable from: 0.93.1ubuntu2.3]
'''

no_match_output = '''
Listing... Done
'''


def test_match():
    assert match(Command('apt list --upgradable', match_output))
    assert match(Command('sudo apt list --upgradable', match_output))


@pytest.mark.parametrize('command', [
    Command('apt list --upgradable', no_match_output),
    Command('sudo apt list --upgradable', no_match_output)
])
def test_not_match(command):
    assert not match(command)


def test_get_new_command():
    new_command = get_new_command(Command('apt list --upgradable', match_output))
    assert new_command == 'apt upgrade'

    new_command = get_new_command(Command('sudo apt list --upgradable', match_output))
    assert new_command == 'sudo apt upgrade'


================================================
FILE: tests/rules/test_aws_cli.py
================================================
import pytest

from thefuck.rules.aws_cli import match, get_new_command
from thefuck.types import Command


no_suggestions = '''\
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: argument command: Invalid choice, valid choices are:

dynamodb                                 | dynamodbstreams
ec2                                      | ecr
'''


misspelled_command = '''\
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: argument command: Invalid choice, valid choices are:

dynamodb                                 | dynamodbstreams
ec2                                      | ecr


Invalid choice: 'dynamdb', maybe you meant:

  * dynamodb
'''


misspelled_subcommand = '''\
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: argument operation: Invalid choice, valid choices are:

query                                    | scan
update-item                              | update-table


Invalid choice: 'scn', maybe you meant:

  * scan
'''


misspelled_subcommand_with_multiple_options = '''\
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: argument operation: Invalid choice, valid choices are:

describe-table                           | get-item
list-tables                              | put-item


Invalid choice: 't-item', maybe you meant:

  * put-item
  * get-item
'''


@pytest.mark.parametrize('command', [
    Command('aws dynamdb scan', misspelled_command),
    Command('aws dynamodb scn', misspelled_subcommand),
    Command('aws dynamodb t-item',
            misspelled_subcommand_with_multiple_options)])
def test_match(command):
    assert match(command)


def test_not_match():
    assert not match(Command('aws dynamodb invalid', no_suggestions))


@pytest.mark.parametrize('command, result', [
    (Command('aws dynamdb scan', misspelled_command),
     ['aws dynamodb scan']),
    (Command('aws dynamodb scn', misspelled_subcommand),
     ['aws dynamodb scan']),
    (Command('aws dynamodb t-item',
             misspelled_subcommand_with_multiple_options),
     ['aws dynamodb put-item', 'aws dynamodb get-item'])])
def test_get_new_command(command, result):
    assert get_new_command(command) == result


================================================
FILE: tests/rules/test_az_cli.py
================================================
import pytest

from thefuck.rules.az_cli import match, get_new_command
from thefuck.types import Command


no_suggestions = '''\
az provider: error: the following arguments are required: _subcommand
usage: az provider [-h] {list,show,register,unregister,operation} ...
'''


misspelled_command = '''\
az: 'providers' is not in the 'az' command group. See 'az --help'.

The most similar choice to 'providers' is:
    provider
'''

misspelled_subcommand = '''\
az provider: 'lis' is not in the 'az provider' command group. See 'az provider --help'.

The most similar choice to 'lis' is:
    list
'''


@pytest.mark.parametrize('command', [
    Command('az providers', misspelled_command),
    Command('az provider lis', misspelled_subcommand)])
def test_match(command):
    assert match(command)


def test_not_match():
    assert not match(Command('az provider', no_suggestions))


@pytest.mark.parametrize('command, result', [
    (Command('az providers list', misspelled_command), ['az provider list']),
    (Command('az provider lis', misspelled_subcommand), ['az provider list'])
])
def test_get_new_command(command, result):
    assert get_new_command(command) == result


================================================
FILE: tests/rules/test_brew_cask_dependency.py
================================================
import pytest
from thefuck.rules.brew_cask_dependency import match, get_new_command
from thefuck.types import Command


output = '''sshfs: OsxfuseRequirement unsatisfied!

You can install with Homebrew-Cask:
  brew cask install osxfuse

You can download from:
  https://osxfuse.github.io/
Error: An unsatisfied requirement failed this build.'''


def test_match():
    command = Command('brew install sshfs', output)
    assert match(command)


@pytest.mark.parametrize('script, output', [
    ('brew link sshfs', output),
    ('cat output', output),
    ('brew install sshfs', '')])
def test_not_match(script, output):
    command = Command(script, output)
    assert not match(command)


@pytest.mark.parametrize('before, after', [
    ('brew install sshfs',
     'brew cask install osxfuse && brew install sshfs')])
def test_get_new_command(before, after):
    command = Command(before, output)
    assert get_new_command(command) == after


================================================
FILE: tests/rules/test_brew_install.py
================================================
import pytest
from thefuck.rules.brew_install import match, get_new_command, _get_suggestions
from thefuck.types import Command


@pytest.fixture
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 '''Install a formula or cask. Additional options specific to a formula may be'''


@pytest.fixture
def brew_already_installed():
    return '''Warning: git-2.3.5 already installed'''


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']


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 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))


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_one))\
        != 'brew install aha'


================================================
FILE: tests/rules/test_brew_link.py
================================================
import pytest
from thefuck.types import Command
from thefuck.rules.brew_link import get_new_command, match


@pytest.fixture
def output():
    return ("Error: Could not symlink bin/gcp\n"
            "Target /usr/local/bin/gcp\n"
            "already exists. You may want to remove it:\n"
            "  rm '/usr/local/bin/gcp'\n"
            "\n"
            "To force the link and overwrite all conflicting files:\n"
            "  brew link --overwrite coreutils\n"
            "\n"
            "To list all files that would be deleted:\n"
            "  brew link --overwrite --dry-run coreutils\n")


@pytest.fixture
def new_command(formula):
    return 'brew link --overwrite --dry-run {}'.format(formula)


@pytest.mark.parametrize('script', ['brew link coreutils', 'brew ln coreutils'])
def test_match(output, script):
    assert match(Command(script, output))


@pytest.mark.parametrize('script', ['brew link coreutils'])
def test_not_match(script):
    assert not match(Command(script, ''))


@pytest.mark.parametrize('script, formula, ', [('brew link coreutils', 'coreutils')])
def test_get_new_command(output, new_command, script, formula):
    assert get_new_command(Command(script, output)) == new_command


================================================
FILE: tests/rules/test_brew_reinstall.py
================================================
import pytest
from thefuck.types import Command
from thefuck.rules.brew_reinstall import get_new_command, match


output = ("Warning: thefuck 9.9 is already installed and up-to-date\nTo "
          "reinstall 9.9, run `brew reinstall thefuck`")


def test_match():
    command = Command('brew install thefuck', output)
    assert match(command)


@pytest.mark.parametrize('script', [
    'brew reinstall thefuck',
    'brew install foo'])
def test_not_match(script):
    assert not match(Command(script, ''))


@pytest.mark.parametrize('script, formula, ', [
    ('brew install foo', 'foo'),
    ('brew install bar zap', 'bar zap')])
def test_get_new_command(script, formula):
    command = Command(script, output)
    new_command = 'brew reinstall {}'.format(formula)
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_brew_uninstall.py
================================================
import pytest
from thefuck.types import Command
from thefuck.rules.brew_uninstall import get_new_command, match


@pytest.fixture
def output():
    return ("Uninstalling /usr/local/Cellar/tbb/4.4-20160916... (118 files, 1.9M)\n"
            "tbb 4.4-20160526, 4.4-20160722 are still installed.\n"
            "Remove all versions with `brew uninstall --force tbb`.\n")


@pytest.fixture
def new_command(formula):
    return 'brew uninstall --force {}'.format(formula)


@pytest.mark.parametrize('script', ['brew uninstall tbb', 'brew rm tbb', 'brew remove tbb'])
def test_match(output, script):
    assert match(Command(script, output))


@pytest.mark.parametrize('script', ['brew remove gnuplot'])
def test_not_match(script):
    output = 'Uninstalling /usr/local/Cellar/gnuplot/5.0.4_1... (44 files, 2.3M)\n'
    assert not match(Command(script, output))


@pytest.mark.parametrize('script, formula, ', [('brew uninstall tbb', 'tbb')])
def test_get_new_command(output, new_command, script, formula):
    assert get_new_command(Command(script, output)) == new_command


================================================
FILE: tests/rules/test_brew_unknown_command.py
================================================
import pytest
from thefuck.rules.brew_unknown_command import match, get_new_command
from thefuck.rules.brew_unknown_command import _brew_commands
from thefuck.types import Command


@pytest.fixture
def brew_unknown_cmd():
    return '''Error: Unknown command: inst'''


@pytest.fixture
def brew_unknown_cmd2():
    return '''Error: Unknown command: instaa'''


def test_match(brew_unknown_cmd):
    assert match(Command('brew inst', brew_unknown_cmd))
    for command in _brew_commands():
        assert not match(Command('brew ' + command, ''))


def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2):
    assert (get_new_command(Command('brew inst', brew_unknown_cmd))
            == ['brew list', 'brew install', 'brew uninstall'])

    cmds = get_new_command(Command('brew instaa', brew_unknown_cmd2))
    assert 'brew install' in cmds
    assert 'brew uninstall' in cmds


================================================
FILE: tests/rules/test_brew_update_formula.py
================================================
import pytest
from thefuck.types import Command
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`.")


def test_match():
    command = Command('brew update thefuck', output)
    assert match(command)


@pytest.mark.parametrize('script', [
    'brew upgrade foo',
    'brew update'])
def test_not_match(script):
    assert not match(Command(script, ''))


@pytest.mark.parametrize('script, formula, ', [
    ('brew update foo', 'foo'),
    ('brew update bar zap', 'bar zap')])
def test_get_new_command(script, formula):
    command = Command(script, output)
    new_command = 'brew upgrade {}'.format(formula)
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_cargo_no_command.py
================================================
import pytest
from thefuck.rules.cargo_no_command import match, get_new_command
from thefuck.types import Command


no_such_subcommand_old = """No such subcommand

        Did you mean `build`?
"""

no_such_subcommand = """error: no such subcommand

\tDid you mean `build`?
"""


@pytest.mark.parametrize('command', [
    Command('cargo buid', no_such_subcommand_old),
    Command('cargo buils', no_such_subcommand)])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command, new_command', [
    (Command('cargo buid', no_such_subcommand_old), 'cargo build'),
    (Command('cargo buils', no_such_subcommand), 'cargo build')])
def test_get_new_command(command, new_command):
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_cat_dir.py
================================================
import pytest
from thefuck.rules.cat_dir import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def isdir(mocker):
    return mocker.patch('thefuck.rules.cat_dir'
                        '.os.path.isdir')


@pytest.mark.parametrize('command', [
    Command('cat foo', 'cat: foo: Is a directory\n'),
    Command('cat /foo/bar/', 'cat: /foo/bar/: Is a directory\n'),
    Command('cat cat/', 'cat: cat/: Is a directory\n'),
])
def test_match(command, isdir):
    isdir.return_value = True
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('cat foo', 'foo bar baz'),
    Command('cat foo bar', 'foo bar baz'),
    Command('notcat foo bar', 'some output'),
])
def test_not_match(command, isdir):
    isdir.return_value = False
    assert not match(command)


@pytest.mark.parametrize('command, new_command', [
    (Command('cat foo', 'cat: foo: Is a directory\n'), 'ls foo'),
    (Command('cat /foo/bar/', 'cat: /foo/bar/: Is a directory\n'), 'ls /foo/bar/'),
    (Command('cat cat', 'cat: cat: Is a directory\n'), 'ls cat'),
])
def test_get_new_command(command, new_command):
    isdir.return_value = True
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_cd_correction.py
================================================
import pytest
from thefuck.rules.cd_correction import match
from thefuck.types import Command


@pytest.mark.parametrize('command', [
    Command('cd foo', 'cd: foo: No such file or directory'),
    Command('cd foo/bar/baz',
            'cd: foo: No such file or directory'),
    Command('cd foo/bar/baz', 'cd: can\'t cd to foo/bar/baz'),
    Command('cd /foo/bar/', 'cd: The directory "/foo/bar/" does not exist')])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('cd foo', ''), Command('', '')])
def test_not_match(command):
    assert not match(command)


# Note that get_new_command uses local filesystem, so not testing it here.
# Instead, see the functional test `functional.test_cd_correction`


================================================
FILE: tests/rules/test_cd_cs.py
================================================
from thefuck.rules.cd_cs import match, get_new_command
from thefuck.types import Command


def test_match():
    assert match(Command('cs', 'cs: command not found'))
    assert match(Command('cs /etc/', 'cs: command not found'))


def test_get_new_command():
    assert get_new_command(Command('cs /etc/', 'cs: command not found')) == 'cd /etc/'


================================================
FILE: tests/rules/test_cd_mkdir.py
================================================
import pytest
from thefuck.rules.cd_mkdir import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize('command', [
    Command('cd foo', 'cd: foo: No such file or directory'),
    Command('cd foo/bar/baz',
            'cd: foo: No such file or directory'),
    Command('cd foo/bar/baz', 'cd: can\'t cd to foo/bar/baz'),
    Command('cd /foo/bar/', 'cd: The directory "/foo/bar/" does not exist')])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('cd foo', ''), Command('', '')])
def test_not_match(command):
    assert not match(command)


@pytest.mark.parametrize('command, new_command', [
    (Command('cd foo', ''), 'mkdir -p foo && cd foo'),
    (Command('cd foo/bar/baz', ''), 'mkdir -p foo/bar/baz && cd foo/bar/baz')])
def test_get_new_command(command, new_command):
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_cd_parent.py
================================================
from thefuck.rules.cd_parent import match, get_new_command
from thefuck.types import Command


def test_match():
    assert match(Command('cd..', 'cd..: command not found'))
    assert not match(Command('', ''))


def test_get_new_command():
    assert get_new_command(Command('cd..', '')) == 'cd ..'


================================================
FILE: tests/rules/test_chmod_x.py
================================================
import pytest
from thefuck.types import Command
from thefuck.rules.chmod_x import match, get_new_command


@pytest.fixture
def file_exists(mocker):
    return mocker.patch('os.path.exists', return_value=True)


@pytest.fixture
def file_access(mocker):
    return mocker.patch('os.access', return_value=False)


@pytest.mark.usefixtures('file_exists', 'file_access')
@pytest.mark.parametrize('script, output', [
    ('./gradlew build', 'gradlew: Permission denied'),
    ('./install.sh --help', 'install.sh: permission denied')])
def test_match(script, output):
    assert match(Command(script, output))


@pytest.mark.parametrize('script, output, exists, callable', [
    ('./gradlew build', 'gradlew: Permission denied', True, True),
    ('./gradlew build', 'gradlew: Permission denied', False, False),
    ('./gradlew build', 'gradlew: error', True, False),
    ('gradlew build', 'gradlew: Permission denied', True, False)])
def test_not_match(file_exists, file_access, script, output, exists, callable):
    file_exists.return_value = exists
    file_access.return_value = callable
    assert not match(Command(script, output))


@pytest.mark.parametrize('script, result', [
    ('./gradlew build', 'chmod +x gradlew && ./gradlew build'),
    ('./install.sh --help', 'chmod +x install.sh && ./install.sh --help')])
def test_get_new_command(script, result):
    assert get_new_command(Command(script, '')) == result


================================================
FILE: tests/rules/test_choco_install.py
================================================
import pytest
from thefuck.rules.choco_install import match, get_new_command
from thefuck.types import Command


package_not_found_error = (
    'Chocolatey v0.10.15\n'
    'Installing the following packages:\n'
    'logstitcher\n'
    'By installing you accept licenses for the packages.\n'
    'logstitcher not installed. The package was not found with the source(s) listed.\n'
    ' Source(s): \'https://chocolatey.org/api/v2/\'\n'
    ' NOTE: When you specify explicit sources, it overrides default sources.\n'
    'If the package version is a prerelease and you didn\'t specify `--pre`,\n'
    ' the package may not be found.\n'
    'Please see https://chocolatey.org/docs/troubleshooting for more\n'
    ' assistance.\n'
    '\n'
    'Chocolatey installed 0/1 packages. 1 packages failed.\n'
    ' See the log for details (C:\\ProgramData\\chocolatey\\logs\\chocolatey.log).\n'
    '\n'
    'Failures\n'
    ' - logstitcher - logstitcher not installed. The package was not found with the source(s) listed.\n'
    ' Source(s): \'https://chocolatey.org/api/v2/\'\n'
    ' NOTE: When you specify explicit sources, it overrides default sources.\n'
    'If the package version is a prerelease and you didn\'t specify `--pre`,\n'
    ' the package may not be found.\n'
    'Please see https://chocolatey.org/docs/troubleshooting for more\n'
    ' assistance.\n'
)


@pytest.mark.parametrize('command', [
    Command('choco install logstitcher', package_not_found_error),
    Command('cinst logstitcher', package_not_found_error),
    Command('choco install logstitcher -y', package_not_found_error),
    Command('cinst logstitcher -y', package_not_found_error),
    Command('choco install logstitcher -y -n=test', package_not_found_error),
    Command('cinst logstitcher -y -n=test', package_not_found_error),
    Command('choco install logstitcher -y -n=test /env', package_not_found_error),
    Command('cinst logstitcher -y -n=test /env', package_not_found_error),
    Command('choco install chocolatey -y', package_not_found_error),
    Command('cinst chocolatey -y', package_not_found_error)])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('choco /?', ''),
    Command('choco upgrade logstitcher', ''),
    Command('cup logstitcher', ''),
    Command('choco upgrade logstitcher -y', ''),
    Command('cup logstitcher -y', ''),
    Command('choco upgrade logstitcher -y -n=test', ''),
    Command('cup logstitcher -y -n=test', ''),
    Command('choco upgrade logstitcher -y -n=test /env', ''),
    Command('cup logstitcher -y -n=test /env', ''),
    Command('choco upgrade chocolatey -y', ''),
    Command('cup chocolatey -y', ''),
    Command('choco uninstall logstitcher', ''),
    Command('cuninst logstitcher', ''),
    Command('choco uninstall logstitcher -y', ''),
    Command('cuninst logstitcher -y', ''),
    Command('choco uninstall logstitcher -y -n=test', ''),
    Command('cuninst logstitcher -y -n=test', ''),
    Command('choco uninstall logstitcher -y -n=test /env', ''),
    Command('cuninst logstitcher -y -n=test /env', ''),
    Command('choco uninstall chocolatey -y', ''),
    Command('cuninst chocolatey -y', '')])
def not_test_match(command):
    assert not match(command)


@pytest.mark.parametrize('before, after', [
    ('choco install logstitcher', 'choco install logstitcher.install'),
    ('cinst logstitcher', 'cinst logstitcher.install'),
    ('choco install logstitcher -y', 'choco install logstitcher.install -y'),
    ('cinst logstitcher -y', 'cinst logstitcher.install -y'),
    ('choco install logstitcher -y -n=test', 'choco install logstitcher.install -y -n=test'),
    ('cinst logstitcher -y -n=test', 'cinst logstitcher.install -y -n=test'),
    ('choco install logstitcher -y -n=test /env', 'choco install logstitcher.install -y -n=test /env'),
    ('cinst logstitcher -y -n=test /env', 'cinst logstitcher.install -y -n=test /env'),
    ('choco install chocolatey -y', 'choco install chocolatey.install -y'),
    ('cinst chocolatey -y', 'cinst chocolatey.install -y'), ])
def test_get_new_command(before, after):
    assert (get_new_command(Command(before, '')) == after)


================================================
FILE: tests/rules/test_composer_not_command.py
================================================
import pytest
from thefuck.rules.composer_not_command import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def composer_not_command():
    # that weird spacing is part of the actual command output
    return (
        '\n'
        '\n'
        '                                    \n'
        '  [InvalidArgumentException]        \n'
        '  Command "udpate" is not defined.  \n'
        '  Did you mean this?                \n'
        '      update                        \n'
        '                                    \n'
        '\n'
        '\n'
    )


@pytest.fixture
def composer_not_command_one_of_this():
    # that weird spacing is part of the actual command output
    return (
        '\n'
        '\n'
        '                                   \n'
        '  [InvalidArgumentException]       \n'
        '  Command "pdate" is not defined.  \n'
        '  Did you mean one of these?       \n'
        '      selfupdate                   \n'
        '      self-update                  \n'
        '      update                       \n'
        '                                   \n'
        '\n'
        '\n'
    )


@pytest.fixture
def composer_require_instead_of_install():
    return 'Invalid argument package. Use "composer require package" instead to add packages to your composer.json.'


def test_match(composer_not_command, composer_not_command_one_of_this, composer_require_instead_of_install):
    assert match(Command('composer udpate',
                         composer_not_command))
    assert match(Command('composer pdate',
                         composer_not_command_one_of_this))
    assert match(Command('composer install package',
                         composer_require_instead_of_install))
    assert not match(Command('ls update', composer_not_command))


def test_get_new_command(composer_not_command, composer_not_command_one_of_this, composer_require_instead_of_install):
    assert (get_new_command(Command('composer udpate',
                                    composer_not_command))
            == 'composer update')
    assert (get_new_command(Command('composer pdate',
                                    composer_not_command_one_of_this))
            == 'composer selfupdate')
    assert (get_new_command(Command('composer install package',
                                    composer_require_instead_of_install))
            == 'composer require package')


================================================
FILE: tests/rules/test_conda_mistype.py
================================================
import pytest

from thefuck.rules.conda_mistype import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def mistype_response():
    return """

CommandNotFoundError: No command 'conda lst'.
Did you mean 'conda list'?

    """


def test_match(mistype_response):
    assert match(Command('conda lst', mistype_response))
    err_response = 'bash: codna: command not found'
    assert not match(Command('codna list', err_response))


def test_get_new_command(mistype_response):
    assert (get_new_command(Command('conda lst', mistype_response)) == ['conda list'])


================================================
FILE: tests/rules/test_cp_create_destination.py
================================================
import pytest
from thefuck.rules.cp_create_destination import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize(
    "script, output",
    [("cp", "cp: directory foo does not exist\n"), ("mv", "No such file or directory")],
)
def test_match(script, output):
    assert match(Command(script, output))


@pytest.mark.parametrize(
    "script, output", [("cp", ""), ("mv", ""), ("ls", "No such file or directory")]
)
def test_not_match(script, output):
    assert not match(Command(script, output))


@pytest.mark.parametrize(
    "script, output, new_command",
    [
        ("cp foo bar/", "cp: directory foo does not exist\n", "mkdir -p bar/ && cp foo bar/"),
        ("mv foo bar/", "No such file or directory", "mkdir -p bar/ && mv foo bar/"),
        ("cp foo bar/baz/", "cp: directory foo does not exist\n", "mkdir -p bar/baz/ && cp foo bar/baz/"),
    ],
)
def test_get_new_command(script, output, new_command):
    assert get_new_command(Command(script, output)) == new_command


================================================
FILE: tests/rules/test_cp_omitting_directory.py
================================================
import pytest
from thefuck.rules.cp_omitting_directory import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize('script, output', [
    ('cp dir', 'cp: dor: is a directory'),
    ('cp dir', "cp: omitting directory 'dir'")])
def test_match(script, output):
    assert match(Command(script, output))


@pytest.mark.parametrize('script, output', [
    ('some dir', 'cp: dor: is a directory'),
    ('some dir', "cp: omitting directory 'dir'"),
    ('cp dir', '')])
def test_not_match(script, output):
    assert not match(Command(script, output))


def test_get_new_command():
    assert get_new_command(Command('cp dir', '')) == 'cp -a dir'


================================================
FILE: tests/rules/test_dirty_untar.py
================================================
import os
import pytest
import tarfile
from thefuck.rules.dirty_untar import match, get_new_command, side_effect, \
                                      tar_extensions  # noqa: E126
from thefuck.types import Command


@pytest.fixture
def tar_error(tmpdir):
    def fixture(filename):
        path = os.path.join(str(tmpdir), filename)

        def reset(path):
            os.mkdir('d')
            with tarfile.TarFile(path, 'w') as archive:
                for file in ('a', 'b', 'c', 'd/e'):
                    with open(file, 'w') as f:
                        f.write('*')

                    archive.add(file)

                    os.remove(file)

            with tarfile.TarFile(path, 'r') as archive:
                archive.extractall()

        os.chdir(str(tmpdir))
        reset(path)

        assert set(os.listdir('.')) == {filename, 'a', 'b', 'c', 'd'}
        assert set(os.listdir('./d')) == {'e'}

    return fixture


parametrize_extensions = pytest.mark.parametrize('ext', tar_extensions)

# (filename as typed by the user, unquoted filename, quoted filename as per shells.quote)
parametrize_filename = pytest.mark.parametrize('filename, unquoted, quoted', [
    ('foo{}', 'foo{}', 'foo{}'),
    ('"foo bar{}"', 'foo bar{}', "'foo bar{}'")])

parametrize_script = pytest.mark.parametrize('script, fixed', [
    ('tar xvf {}', 'mkdir -p {dir} && tar xvf {filename} -C {dir}'),
    ('tar -xvf {}', 'mkdir -p {dir} && tar -xvf {filename} -C {dir}'),
    ('tar --extract -f {}', 'mkdir -p {dir} && tar --extract -f {filename} -C {dir}')])


@parametrize_extensions
@parametrize_filename
@parametrize_script
def test_match(ext, tar_error, filename, unquoted, quoted, script, fixed):
    tar_error(unquoted.format(ext))
    assert match(Command(script.format(filename.format(ext)), ''))


@parametrize_extensions
@parametrize_filename
@parametrize_script
def test_side_effect(ext, tar_error, filename, unquoted, quoted, script, fixed):
    tar_error(unquoted.format(ext))
    side_effect(Command(script.format(filename.format(ext)), ''), None)
    assert set(os.listdir('.')) == {unquoted.format(ext), 'd'}


@parametrize_extensions
@parametrize_filename
@parametrize_script
def test_get_new_command(ext, tar_error, filename, unquoted, quoted, script, fixed):
    tar_error(unquoted.format(ext))
    assert (get_new_command(Command(script.format(filename.format(ext)), ''))
            == fixed.format(dir=quoted.format(''), filename=filename.format(ext)))


================================================
FILE: tests/rules/test_dirty_unzip.py
================================================
# -*- coding: utf-8 -*-

import os
import pytest
import zipfile
from thefuck.rules.dirty_unzip import match, get_new_command, side_effect
from thefuck.types import Command
from unicodedata import normalize


@pytest.fixture
def zip_error(tmpdir):
    def zip_error_inner(filename):
        path = os.path.join(str(tmpdir), filename)

        def reset(path):
            with zipfile.ZipFile(path, 'w') as archive:
                archive.writestr('a', '1')
                archive.writestr('b', '2')
                archive.writestr('c', '3')

                archive.writestr('d/e', '4')

                archive.extractall()

        os.chdir(str(tmpdir))
        reset(path)

        dir_list = os.listdir(u'.')
        if filename not in dir_list:
            filename = normalize('NFD', filename)

        assert set(dir_list) == {filename, 'a', 'b', 'c', 'd'}
        assert set(os.listdir('./d')) == {'e'}
    return zip_error_inner


@pytest.mark.parametrize('script,filename', [
    (u'unzip café', u'café.zip'),
    (u'unzip café.zip', u'café.zip'),
    (u'unzip foo', u'foo.zip'),
    (u'unzip foo.zip', u'foo.zip')])
def test_match(zip_error, script, filename):
    zip_error(filename)
    assert match(Command(script, ''))


@pytest.mark.parametrize('script,filename', [
    (u'unzip café', u'café.zip'),
    (u'unzip café.zip', u'café.zip'),
    (u'unzip foo', u'foo.zip'),
    (u'unzip foo.zip', u'foo.zip')])
def test_side_effect(zip_error, script, filename):
    zip_error(filename)
    side_effect(Command(script, ''), None)

    dir_list = os.listdir(u'.')
    if filename not in set(dir_list):
        filename = normalize('NFD', filename)

    assert set(dir_list) == {filename, 'd'}


@pytest.mark.parametrize('script,fixed,filename', [
    (u'unzip café', u"unzip café -d 'café'", u'café.zip'),
    (u'unzip foo', u'unzip foo -d foo', u'foo.zip'),
    (u"unzip 'foo bar.zip'", u"unzip 'foo bar.zip' -d 'foo bar'", u'foo.zip'),
    (u'unzip foo.zip', u'unzip foo.zip -d foo', u'foo.zip')])
def test_get_new_command(zip_error, script, fixed, filename):
    zip_error(filename)
    assert get_new_command(Command(script, '')) == fixed


================================================
FILE: tests/rules/test_django_south_ghost.py
================================================
import pytest
from thefuck.rules.django_south_ghost import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def output():
    return '''Traceback (most recent call last):
  File "/home/nvbn/work/.../bin/python", line 42, in <module>
    exec(compile(__file__f.read(), __file__, "exec"))
  File "/home/nvbn/work/.../app/manage.py", line 34, in <module>
    execute_from_command_line(sys.argv)
  File "/home/nvbn/work/.../lib/django/core/management/__init__.py", line 443, in execute_from_command_line
    utility.execute()
  File "/home/nvbn/work/.../lib/django/core/management/__init__.py", line 382, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/nvbn/work/.../lib/django/core/management/base.py", line 196, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/nvbn/work/.../lib/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/home/nvbn/work/.../app/lib/south/management/commands/migrate.py", line 108, in handle
    ignore_ghosts = ignore_ghosts,
  File "/home/nvbn/work/.../app/lib/south/migration/__init__.py", line 193, in migrate_app
    applied_all = check_migration_histories(applied_all, delete_ghosts, ignore_ghosts)
  File "/home/nvbn/work/.../app/lib/south/migration/__init__.py", line 88, in check_migration_histories
    raise exceptions.GhostMigrations(ghosts)
south.exceptions.GhostMigrations: 

 ! These migrations are in the database but not on disk:
    <app1: 0033_auto__...>
    <app1: 0034_fill_...>
    <app1: 0035_rename_...>
    <app2: 0003_add_...>
    <app2: 0004_denormalize_...>
    <app1: 0033_auto....>
    <app1: 0034_fill...>
 ! I'm not trusting myself; either fix this yourself by fiddling
 ! with the south_migrationhistory table, or pass --delete-ghost-migrations
 ! to South to have it delete ALL of these records (this may not be good).
'''  # noqa


def test_match(output):
    assert match(Command('./manage.py migrate', output))
    assert match(Command('python manage.py migrate', output))
    assert not match(Command('./manage.py migrate', ''))
    assert not match(Command('app migrate', output))
    assert not match(Command('./manage.py test', output))


def test_get_new_command():
    assert get_new_command(Command('./manage.py migrate auth', ''))\
        == './manage.py migrate auth --delete-ghost-migrations'


================================================
FILE: tests/rules/test_django_south_merge.py
================================================
import pytest
from thefuck.rules.django_south_merge import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def output():
    return '''Running migrations for app:
 ! Migration app:0003_auto... should not have been applied before app:0002_auto__add_field_query_due_date_ but was.
Traceback (most recent call last):
  File "/home/nvbn/work/.../bin/python", line 42, in <module>
    exec(compile(__file__f.read(), __file__, "exec"))
  File "/home/nvbn/work/.../app/manage.py", line 34, in <module>
    execute_from_command_line(sys.argv)
  File "/home/nvbn/work/.../lib/django/core/management/__init__.py", line 443, in execute_from_command_line
    utility.execute()
  File "/home/nvbn/work/.../lib/django/core/management/__init__.py", line 382, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/nvbn/work/.../lib/django/core/management/base.py", line 196, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/nvbn/work/.../lib/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/home/nvbn/work/.../app/lib/south/management/commands/migrate.py", line 108, in handle
    ignore_ghosts = ignore_ghosts,
  File "/home/nvbn/work/.../app/lib/south/migration/__init__.py", line 207, in migrate_app
    raise exceptions.InconsistentMigrationHistory(problems)
south.exceptions.InconsistentMigrationHistory: Inconsistent migration history
The following options are available:
    --merge: will just attempt the migration ignoring any potential dependency conflicts.
'''


def test_match(output):
    assert match(Command('./manage.py migrate', output))
    assert match(Command('python manage.py migrate', output))
    assert not match(Command('./manage.py migrate', ''))
    assert not match(Command('app migrate', output))
    assert not match(Command('./manage.py test', output))


def test_get_new_command():
    assert (get_new_command(Command('./manage.py migrate auth', ''))
            == './manage.py migrate auth --merge')


================================================
FILE: tests/rules/test_dnf_no_such_command.py
================================================
from io import BytesIO
import pytest
from thefuck.types import Command
from thefuck.rules.dnf_no_such_command import match, get_new_command, _get_operations


help_text = b'''usage: dnf [options] COMMAND

List of Main Commands:

autoremove                remove all unneeded packages that were originally installed as dependencies
check                     check for problems in the packagedb
check-update              check for available package upgrades
clean                     remove cached data
deplist                   List package's dependencies and what packages provide them
distro-sync               synchronize installed packages to the latest available versions
downgrade                 Downgrade a package
group                     display, or use, the groups information
help                      display a helpful usage message
history                   display, or use, the transaction history
info                      display details about a package or group of packages
install                   install a package or packages on your system
list                      list a package or groups of packages
makecache                 generate the metadata cache
mark                      mark or unmark installed packages as installed by user.
provides                  find what package provides the given value
reinstall                 reinstall a package
remove                    remove a package or packages from your system
repolist                  display the configured software repositories
repoquery                 search for packages matching keyword
repository-packages       run commands on top of all packages in given repository
search                    search package details for the given string
shell                     run an interactive DNF shell
swap                      run an interactive dnf mod for remove and install one spec
updateinfo                display advisories about packages
upgrade                   upgrade a package or packages on your system
upgrade-minimal           upgrade, but only 'newest' package match which fixes a problem that affects your system

List of Plugin Commands:

builddep                  Install build dependencies for package or spec file
config-manager            manage dnf configuration options and repositories
copr                      Interact with Copr repositories.
debug-dump                dump information about installed rpm packages to file
debug-restore             restore packages recorded in debug-dump file
debuginfo-install         install debuginfo packages
download                  Download package to current directory
needs-restarting          determine updated binaries that need restarting
playground                Interact with Playground repository.
repoclosure               Display a list of unresolved dependencies for repositories
repograph                 Output a full package dependency graph in dot format
repomanage                Manage a directory of rpm packages
reposync                  download all packages from remote repo

Optional arguments:
  -c [config file], --config [config file]
                        config file location
  -q, --quiet           quiet operation
  -v, --verbose         verbose operation
  --version             show DNF version and exit
  --installroot [path]  set install root
  --nodocs              do not install documentations
  --noplugins           disable all plugins
  --enableplugin [plugin]
                        enable plugins by name
  --disableplugin [plugin]
                        disable plugins by name
  --releasever RELEASEVER
                        override the value of $releasever in config and repo
                        files
  --setopt SETOPTS      set arbitrary config and repo options
  --skip-broken         resolve depsolve problems by skipping packages
  -h, --help, --help-cmd
                        show command help
  --allowerasing        allow erasing of installed packages to resolve
                        dependencies
  -b, --best            try the best available package versions in
                        transactions.
  -C, --cacheonly       run entirely from system cache, don't update cache
  -R [minutes], --randomwait [minutes]
                        maximum command wait time
  -d [debug level], --debuglevel [debug level]
                        debugging output level
  --debugsolver         dumps detailed solving results into files
  --showduplicates      show duplicates, in repos, in list/search commands
  -e ERRORLEVEL, --errorlevel ERRORLEVEL
                        error output level
  --obsoletes           enables dnf's obsoletes processing logic for upgrade
                        or display capabilities that the package obsoletes for
                        info, list and repoquery
  --rpmverbosity [debug level name]
                        debugging output level for rpm
  -y, --assumeyes       automatically answer yes for all questions
  --assumeno            automatically answer no for all questions
  --enablerepo [repo]
  --disablerepo [repo]
  --repo [repo], --repoid [repo]
                        enable just specific repositories by an id or a glob,
                        can be specified multiple times
  -x [package], --exclude [package], --excludepkgs [package]
                        exclude packages by name or glob
  --disableexcludes [repo], --disableexcludepkgs [repo]
                        disable excludepkgs
  --repofrompath [repo,path]
                        label and path to additional repository, can be
                        specified multiple times.
  --noautoremove        disable removal of dependencies that are no longer
                        used
  --nogpgcheck          disable gpg signature checking
  --color COLOR         control whether colour is used
  --refresh             set metadata as expired before running the command
  -4                    resolve to IPv4 addresses only
  -6                    resolve to IPv6 addresses only
  --destdir DESTDIR, --downloaddir DESTDIR
                        set directory to copy packages to
  --downloadonly        only download packages
  --bugfix              Include bugfix relevant packages, in updates
  --enhancement         Include enhancement relevant packages, in updates
  --newpackage          Include newpackage relevant packages, in updates
  --security            Include security relevant packages, in updates
  --advisory ADVISORY, --advisories ADVISORY
                        Include packages needed to fix the given advisory, in
                        updates
  --bzs BUGZILLA        Include packages needed to fix the given BZ, in
                        updates
  --cves CVES           Include packages needed to fix the given CVE, in
                        updates
  --sec-severity {Critical,Important,Moderate,Low}, --secseverity {Critical,Important,Moderate,Low}
                        Include security relevant packages matching the
                        severity, in updates
  --forcearch ARCH      Force the use of an architecture
'''

dnf_operations = ['autoremove', 'check', 'check-update', 'clean', 'deplist',
                  'distro-sync', 'downgrade', 'group', 'help', 'history',
                  'info', 'install', 'list', 'makecache', 'mark', 'provides',
                  'reinstall', 'remove', 'repolist', 'repoquery',
                  'repository-packages', 'search', 'shell', 'swap', 'updateinfo',
                  'upgrade', 'upgrade-minimal', 'builddep', 'config-manager',
                  'copr', 'debug-dump', 'debug-restore', 'debuginfo-install',
                  'download', 'needs-restarting', 'playground', 'repoclosure',
                  'repograph', 'repomanage', 'reposync']


def invalid_command(command):
    return """No such command: %s. Please use /usr/bin/dnf --help
It could be a DNF plugin command, try: "dnf install 'dnf-command(%s)'"
""" % (command, command)


@pytest.mark.parametrize('output', [
    (invalid_command('saerch')),
    (invalid_command('isntall'))
])
def test_match(output):
    assert match(Command('dnf', output))


@pytest.mark.parametrize('script, output', [
    ('pip', invalid_command('isntall')),
    ('vim', "")
])
def test_not_match(script, output):
    assert not match(Command(script, output))


@pytest.fixture
def set_help(mocker):
    mock = mocker.patch('subprocess.Popen')

    def _set_text(text):
        mock.return_value.stdout = BytesIO(text)

    return _set_text


def test_get_operations(set_help):
    set_help(help_text)
    assert _get_operations() == dnf_operations


@pytest.mark.parametrize('script, output, result', [
    ('dnf isntall vim', invalid_command('isntall'),
     'dnf install vim'),
    ('dnf saerch vim', invalid_command('saerch'),
     'dnf search vim'),
])
def test_get_new_command(set_help, output, script, result):
    set_help(help_text)
    assert result in get_new_command(Command(script, output))


================================================
FILE: tests/rules/test_docker_image_being_used_by_container.py
================================================
from thefuck.rules.docker_image_being_used_by_container import match, get_new_command
from thefuck.types import Command


def test_match():
    err_response = """Error response from daemon: conflict: unable to delete cd809b04b6ff (cannot be forced) - image is being used by running container e5e2591040d1"""
    assert match(Command('docker image rm -f cd809b04b6ff', err_response))


def test_not_match():
    err_response = 'bash: docker: command not found'
    assert not match(Command('docker image rm -f cd809b04b6ff', err_response))


def test_not_docker_command():
    err_response = """Error response from daemon: conflict: unable to delete cd809b04b6ff (cannot be forced) - image is being used by running container e5e2591040d1"""
    assert not match(Command('git image rm -f cd809b04b6ff', err_response))


def test_get_new_command():
    err_response = """
        Error response from daemon: conflict: unable to delete cd809b04b6ff (cannot be forced) - image
        is being used by running container e5e2591040d1
        """
    result = get_new_command(Command('docker image rm -f cd809b04b6ff', err_response))
    expected = 'docker container rm -f e5e2591040d1 && docker image rm -f cd809b04b6ff'
    assert result == expected


================================================
FILE: tests/rules/test_docker_login.py
================================================
from thefuck.rules.docker_login import match, get_new_command
from thefuck.types import Command


def test_match():
    err_response1 = """
    Sending build context to Docker daemon  118.8kB
Step 1/6 : FROM foo/bar:fdb7c6d
pull access denied for foo/bar, repository does not exist or may require 'docker login'
"""
    assert match(Command('docker build -t artifactory:9090/foo/bar:fdb7c6d .', err_response1))

    err_response2 = """
    The push refers to repository [artifactory:9090/foo/bar]
push access denied for foo/bar, repository does not exist or may require 'docker login'
"""
    assert match(Command('docker push artifactory:9090/foo/bar:fdb7c6d', err_response2))

    err_response3 = """
    docker push artifactory:9090/foo/bar:fdb7c6d
The push refers to repository [artifactory:9090/foo/bar]
9c29c7ad209d: Preparing
71f3ad53dfe0: Preparing
f58ee068224c: Preparing
aeddc924d0f7: Preparing
c2040e5d6363: Preparing
4d42df4f350f: Preparing
35723dab26f9: Preparing
71f3ad53dfe0: Pushed
cb95fa0faeb1: Layer already exists
"""
    assert not match(Command('docker push artifactory:9090/foo/bar:fdb7c6d', err_response3))


def test_get_new_command():
    assert get_new_command(Command('docker build -t artifactory:9090/foo/bar:fdb7c6d .', '')) == 'docker login && docker build -t artifactory:9090/foo/bar:fdb7c6d .'
    assert get_new_command(Command('docker push artifactory:9090/foo/bar:fdb7c6d', '')) == 'docker login && docker push artifactory:9090/foo/bar:fdb7c6d'


================================================
FILE: tests/rules/test_docker_not_command.py
================================================
import pytest
from io import BytesIO
from thefuck.types import Command
from thefuck.rules.docker_not_command import get_new_command, match


_DOCKER_SWARM_OUTPUT = '''
Usage:	docker swarm COMMAND

Manage Swarm

Commands:
  ca          Display and rotate the root CA
  init        Initialize a swarm
  join        Join a swarm as a node and/or manager
  join-token  Manage join tokens
  leave       Leave the swarm
  unlock      Unlock swarm
  unlock-key  Manage the unlock key
  update      Update the swarm

Run 'docker swarm COMMAND --help' for more information on a command.
'''
_DOCKER_IMAGE_OUTPUT = '''
Usage:	docker image COMMAND

Manage images

Commands:
  build       Build an image from a Dockerfile
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Display detailed information on one or more images
  load        Load an image from a tar archive or STDIN
  ls          List images
  prune       Remove unused images
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rm          Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

Run 'docker image COMMAND --help' for more information on a command.
'''


@pytest.fixture
def docker_help(mocker):
    help = b'''Usage: docker [OPTIONS] COMMAND [arg...]

A self-sufficient runtime for linux containers.

Options:

  --api-cors-header=                   Set CORS headers in the remote API
  -b, --bridge=                        Attach containers to a network bridge
  --bip=                               Specify network bridge IP
  -D, --debug=false                    Enable debug mode
  -d, --daemon=false                   Enable daemon mode
  --default-gateway=                   Container default gateway IPv4 address
  --default-gateway-v6=                Container default gateway IPv6 address
  --default-ulimit=[]                  Set default ulimits for containers
  --dns=[]                             DNS server to use
  --dns-search=[]                      DNS search domains to use
  -e, --exec-driver=native             Exec driver to use
  --exec-opt=[]                        Set exec driver options
  --exec-root=/var/run/docker          Root of the Docker execdriver
  --fixed-cidr=                        IPv4 subnet for fixed IPs
  --fixed-cidr-v6=                     IPv6 subnet for fixed IPs
  -G, --group=docker                   Group for the unix socket
  -g, --graph=/var/lib/docker          Root of the Docker runtime
  -H, --host=[]                        Daemon socket(s) to connect to
  -h, --help=false                     Print usage
  --icc=true                           Enable inter-container communication
  --insecure-registry=[]               Enable insecure registry communication
  --ip=0.0.0.0                         Default IP when binding container ports
  --ip-forward=true                    Enable net.ipv4.ip_forward
  --ip-masq=true                       Enable IP masquerading
  --iptables=true                      Enable addition of iptables rules
  --ipv6=false                         Enable IPv6 networking
  -l, --log-level=info                 Set the logging level
  --label=[]                           Set key=value labels to the daemon
  --log-driver=json-file               Default driver for container logs
  --log-opt=map[]                      Set log driver options
  --mtu=0                              Set the containers network MTU
  -p, --pidfile=/var/run/docker.pid    Path to use for daemon PID file
  --registry-mirror=[]                 Preferred Docker registry mirror
  -s, --storage-driver=                Storage driver to use
  --selinux-enabled=false              Enable selinux support
  --storage-opt=[]                     Set storage driver options
  --tls=false                          Use TLS; implied by --tlsverify
  --tlscacert=~/.docker/ca.pem         Trust certs signed only by this CA
  --tlscert=~/.docker/cert.pem         Path to TLS certificate file
  --tlskey=~/.docker/key.pem           Path to TLS key file
  --tlsverify=false                    Use TLS and verify the remote
  --userland-proxy=true                Use userland proxy for loopback traffic
  -v, --version=false                  Print version information and quit

Commands:
    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders from a container's filesystem to the host path
    create    Create a new container
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    exec      Run a command in a running container
    export    Stream the contents of a container as a tar archive
    history   Show the history of an image
    images    List images
    import    Create a new filesystem image from the contents of a tarball
    info      Display system-wide information
    inspect   Return low-level information on a container or image
    kill      Kill a running container
    load      Load an image from a tar archive
    login     Register or log in to a Docker registry server
    logout    Log out from a Docker registry server
    logs      Fetch the logs of a container
    pause     Pause all processes within a container
    port      Lookup the public-facing port that is NAT-ed to PRIVATE_PORT
    ps        List containers
    pull      Pull an image or a repository from a Docker registry server
    push      Push an image or a repository to a Docker registry server
    rename    Rename an existing container
    restart   Restart a running container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    save      Save an image to a tar archive
    search    Search for an image on the Docker Hub
    start     Start a stopped container
    stats     Display a stream of a containers' resource usage statistics
    stop      Stop a running container
    tag       Tag an image into a repository
    top       Lookup the running processes of a container
    unpause   Unpause a paused container
    version   Show the Docker version information
    wait      Block until a container stops, then print its exit code

Run 'docker COMMAND --help' for more information on a command.
'''
    mock = mocker.patch('subprocess.Popen')
    mock.return_value.stdout = BytesIO(help)
    return mock


@pytest.fixture
def docker_help_new(mocker):
    helptext_new = b'''
Usage:	docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default "/Users/ik1ne/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var
                           and default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/Users/ik1ne/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/Users/ik1ne/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/Users/ik1ne/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Management Commands:
  builder     Manage builds
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  image       Manage images
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker COMMAND --help' for more information on a command.
'''
    mock = mocker.patch('subprocess.Popen')
    mock.return_value.stdout = BytesIO(b'')
    mock.return_value.stderr = BytesIO(helptext_new)
    return mock


def output(cmd):
    return "docker: '{}' is not a docker command.\n" \
           "See 'docker --help'.".format(cmd)


def test_match():
    assert match(Command('docker pes', output('pes')))


# tests docker (management command)
@pytest.mark.usefixtures('no_memoize')
@pytest.mark.parametrize('script, output', [
    ('docker swarn', output('swarn')),
    ('docker imge', output('imge'))])
def test_match_management_cmd(script, output):
    assert match(Command(script, output))


# tests docker (management cmd) (management subcmd)
@pytest.mark.usefixtures('no_memoize')
@pytest.mark.parametrize('script, output', [
    ('docker swarm int', _DOCKER_SWARM_OUTPUT),
    ('docker image la', _DOCKER_IMAGE_OUTPUT)])
def test_match_management_subcmd(script, output):
    assert match(Command(script, output))


@pytest.mark.parametrize('script, output', [
    ('docker ps', ''),
    ('cat pes', output('pes'))])
def test_not_match(script, output):
    assert not match(Command(script, output))


@pytest.mark.usefixtures('no_memoize', 'docker_help')
@pytest.mark.parametrize('wrong, fixed', [
    ('pes', ['ps', 'push', 'pause']),
    ('tags', ['tag', 'stats', 'images'])])
def test_get_new_command(wrong, fixed):
    command = Command('docker {}'.format(wrong), output(wrong))
    assert get_new_command(command) == ['docker {}'.format(x) for x in fixed]


@pytest.mark.usefixtures('no_memoize', 'docker_help_new')
@pytest.mark.parametrize('wrong, fixed', [
    ('swarn', ['swarm', 'start', 'search']),
    ('inage', ['image', 'images', 'rename'])])
def test_get_new_management_command(wrong, fixed):
    command = Command('docker {}'.format(wrong), output(wrong))
    assert get_new_command(command) == ['docker {}'.format(x) for x in fixed]


@pytest.mark.usefixtures('no_memoize', 'docker_help_new')
@pytest.mark.parametrize('wrong, fixed, output', [
    ('swarm int', ['swarm init', 'swarm join', 'swarm join-token'], _DOCKER_SWARM_OUTPUT),
    ('image la', ['image load', 'image ls', 'image tag'], _DOCKER_IMAGE_OUTPUT)])
def test_get_new_management_command_subcommand(wrong, fixed, output):
    command = Command('docker {}'.format(wrong), output)
    assert get_new_command(command) == ['docker {}'.format(x) for x in fixed]


================================================
FILE: tests/rules/test_dry.py
================================================
import pytest
from thefuck.rules.dry import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize('command', [
    Command('cd cd foo', ''),
    Command('git git push origin/master', '')])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command, new_command', [
    (Command('cd cd foo', ''), 'cd foo'),
    (Command('git git push origin/master', ''), 'git push origin/master')])
def test_get_new_command(command, new_command):
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_fab_command_not_found.py
================================================
import pytest
from thefuck.rules.fab_command_not_found import match, get_new_command
from thefuck.types import Command

output = '''
Warning: Command(s) not found:
    extenson
    deloyp

Available commands:

    update_config
    prepare_extension
    Template               A string class for supporting $-substitutions.
    deploy
    glob                   Return a list of paths matching a pathname pattern.
    install_web
    set_version
'''


@pytest.mark.parametrize('command', [
    Command('fab extenson', output),
    Command('fab deloyp', output),
    Command('fab extenson deloyp', output)])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('gulp extenson', output),
    Command('fab deloyp', '')])
def test_not_match(command):
    assert not match(command)


@pytest.mark.parametrize('script, result', [
    ('fab extenson', 'fab prepare_extension'),
    ('fab extenson:version=2016',
     'fab prepare_extension:version=2016'),
    ('fab extenson:version=2016 install_web set_version:val=0.5.0',
     'fab prepare_extension:version=2016 install_web set_version:val=0.5.0'),
    ('fab extenson:version=2016 deloyp:beta=true -H the.fuck',
     'fab prepare_extension:version=2016 deploy:beta=true -H the.fuck'),
])
def test_get_new_command(script, result):
    command = Command(script, output)
    assert get_new_command(command) == result


================================================
FILE: tests/rules/test_fix_alt_space.py
================================================
# -*- encoding: utf-8 -*-

from thefuck.rules.fix_alt_space import match, get_new_command
from thefuck.types import Command


def test_match():
    """The character before 'grep' is Alt+Space, which happens frequently
    on the Mac when typing the pipe character (Alt+7), and holding the Alt
    key pressed for longer than necessary.

    """
    assert match(Command(u'ps -ef | grep foo',
                         u'-bash:  grep: command not found'))
    assert not match(Command('ps -ef | grep foo', ''))
    assert not match(Command('', ''))


def test_get_new_command():
    """ Replace the Alt+Space character by a simple space """
    assert (get_new_command(Command(u'ps -ef | grep foo', ''))
            == 'ps -ef | grep foo')


================================================
FILE: tests/rules/test_fix_file.py
================================================
# -*- coding: utf-8 -*-

import pytest
import os
from collections import namedtuple
from thefuck.rules.fix_file import match, get_new_command
from thefuck.types import Command

FixFileTest = namedtuple('FixFileTest', ['script', 'file', 'line', 'col', 'output'])

tests = (
    FixFileTest('gcc a.c', 'a.c', 3, 1, """
a.c: In function 'main':
a.c:3:1: error: expected expression before '}' token
 }
  ^
"""),

    FixFileTest('clang a.c', 'a.c', 3, 1, """
a.c:3:1: error: expected expression
}
^
"""),

    FixFileTest('perl a.pl', 'a.pl', 3, None, """
syntax error at a.pl line 3, at EOF
Execution of a.pl aborted due to compilation errors.
"""),

    FixFileTest('perl a.pl', 'a.pl', 2, None, """
Search pattern not terminated at a.pl line 2.
"""),

    FixFileTest('sh a.sh', 'a.sh', 2, None, """
a.sh: line 2: foo: command not found
"""),

    FixFileTest('zsh a.sh', 'a.sh', 2, None, """
a.sh:2: command not found: foo
"""),

    FixFileTest('bash a.sh', 'a.sh', 2, None, """
a.sh: line 2: foo: command not found
"""),

    FixFileTest('rustc a.rs', 'a.rs', 2, 5, """
a.rs:2:5: 2:6 error: unexpected token: `+`
a.rs:2     +
           ^
"""),

    FixFileTest('cargo build', 'src/lib.rs', 3, 5, """
   Compiling test v0.1.0 (file:///tmp/fix-error/test)
   src/lib.rs:3:5: 3:6 error: unexpected token: `+`
   src/lib.rs:3     +
                    ^
Could not compile `test`.

To learn more, run the command again with --verbose.
"""),

    FixFileTest('python a.py', 'a.py', 2, None, """
  File "a.py", line 2
      +
          ^
SyntaxError: invalid syntax
"""),

    FixFileTest('python a.py', 'a.py', 8, None, """
Traceback (most recent call last):
  File "a.py", line 8, in <module>
    match("foo")
  File "a.py", line 5, in match
    m = re.search(None, command)
  File "/usr/lib/python3.4/re.py", line 170, in search
    return _compile(pattern, flags).search(string)
  File "/usr/lib/python3.4/re.py", line 293, in _compile
    raise TypeError("first argument must be string or compiled pattern")
TypeError: first argument must be string or compiled pattern
"""),

    FixFileTest(u'python café.py', u'café.py', 8, None, u"""
Traceback (most recent call last):
  File "café.py", line 8, in <module>
    match("foo")
  File "café.py", line 5, in match
    m = re.search(None, command)
  File "/usr/lib/python3.4/re.py", line 170, in search
    return _compile(pattern, flags).search(string)
  File "/usr/lib/python3.4/re.py", line 293, in _compile
    raise TypeError("first argument must be string or compiled pattern")
TypeError: first argument must be string or compiled pattern
"""),

    FixFileTest('ruby a.rb', 'a.rb', 3, None, """
a.rb:3: syntax error, unexpected keyword_end
"""),

    FixFileTest('lua a.lua', 'a.lua', 2, None, """
lua: a.lua:2: unexpected symbol near '+'
"""),

    FixFileTest('fish a.sh', '/tmp/fix-error/a.sh', 2, None, """
fish: Unknown command 'foo'
/tmp/fix-error/a.sh (line 2): foo
                              ^
"""),

    FixFileTest('./a', './a', 2, None, """
awk: ./a:2: BEGIN { print "Hello, world!" + }
awk: ./a:2:                                 ^ syntax error
"""),

    FixFileTest('llc a.ll', 'a.ll', 1, 2, """
llc: a.ll:1:2: error: expected top-level entity
+
^
"""),

    FixFileTest('go build a.go', 'a.go', 1, 2, """
can't load package:
a.go:1:2: expected 'package', found '+'
"""),

    FixFileTest('make', 'Makefile', 2, None, """
bidule
make: bidule: Command not found
Makefile:2: recipe for target 'target' failed
make: *** [target] Error 127
"""),

    FixFileTest('git st', '/home/martin/.config/git/config', 1, None, """
fatal: bad config file line 1 in /home/martin/.config/git/config
"""),

    FixFileTest('node fuck.js asdf qwer', '/Users/pablo/Workspace/barebones/fuck.js', '2', 5, """
/Users/pablo/Workspace/barebones/fuck.js:2
conole.log(arg);  // this should read console.log(arg);
^
ReferenceError: conole is not defined
    at /Users/pablo/Workspace/barebones/fuck.js:2:5
    at Array.forEach (native)
    at Object.<anonymous> (/Users/pablo/Workspace/barebones/fuck.js:1:85)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3
"""),

    FixFileTest('pep8', './tests/rules/test_systemctl.py', 17, 80, """
./tests/rules/test_systemctl.py:17:80: E501 line too long (93 > 79 characters)
./tests/rules/test_systemctl.py:18:80: E501 line too long (103 > 79 characters)
./tests/rules/test_whois.py:20:80: E501 line too long (89 > 79 characters)
./tests/rules/test_whois.py:22:80: E501 line too long (83 > 79 characters)
"""),

    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")

    @pytest.mark.parametrize('test', tests)
    @pytest.mark.usefixtures('no_memoize')
    def test_get_new_command(monkeypatch, test):
>       mocker.patch('os.path.isfile', return_value=True)
E       NameError: name 'mocker' is not defined

/home/thefuck/tests/rules/test_fix_file.py:218: NameError
"""),
)


@pytest.mark.parametrize('test', tests)
@pytest.mark.usefixtures('no_memoize')
def test_match(mocker, monkeypatch, test):
    mocker.patch('os.path.isfile', return_value=True)
    monkeypatch.setenv('EDITOR', 'dummy_editor')
    assert match(Command('', test.output))


@pytest.mark.parametrize('test', tests)
@pytest.mark.usefixtures('no_memoize')
def test_no_editor(mocker, monkeypatch, test):
    mocker.patch('os.path.isfile', return_value=True)
    if 'EDITOR' in os.environ:
        monkeypatch.delenv('EDITOR')

    assert not match(Command('', test.output))


@pytest.mark.parametrize('test', tests)
@pytest.mark.usefixtures('no_memoize')
def test_not_file(mocker, monkeypatch, test):
    mocker.patch('os.path.isfile', return_value=False)
    monkeypatch.setenv('EDITOR', 'dummy_editor')

    assert not match(Command('', test.output))


@pytest.mark.parametrize('test', tests)
@pytest.mark.usefixtures('no_memoize')
def test_get_new_command(mocker, monkeypatch, test):
    mocker.patch('os.path.isfile', return_value=True)
    monkeypatch.setenv('EDITOR', 'dummy_editor')


@pytest.mark.parametrize('test', tests)
@pytest.mark.usefixtures('no_memoize')
def test_get_new_command_with_settings(mocker, monkeypatch, test, settings):
    mocker.patch('os.path.isfile', return_value=True)
    monkeypatch.setenv('EDITOR', 'dummy_editor')

    cmd = Command(test.script, test.output)
    settings.fixcolcmd = '{editor} {file} +{line}:{col}'

    if test.col:
        assert (get_new_command(cmd) ==
                u'dummy_editor {} +{}:{} && {}'.format(test.file, test.line, test.col, test.script))
    else:
        assert (get_new_command(cmd) ==
                u'dummy_editor {} +{} && {}'.format(test.file, test.line, test.script))


================================================
FILE: tests/rules/test_gem_unknown_command.py
================================================
import pytest
from six import BytesIO
from thefuck.rules.gem_unknown_command import match, get_new_command
from thefuck.types import Command

output = '''
ERROR:  While executing gem ... (Gem::CommandLineError)
    Unknown command {}
'''

gem_help_commands_stdout = b'''
GEM commands are:

    build             Build a gem from a gemspec
    cert              Manage RubyGems certificates and signing settings
    check             Check a gem repository for added or missing files
    cleanup           Clean up old versions of installed gems
    contents          Display the contents of the installed gems
    dependency        Show the dependencies of an installed gem
    environment       Display information about the RubyGems environment
    fetch             Download a gem and place it in the current directory
    generate_index    Generates the index files for a gem server directory
    help              Provide help on the 'gem' command
    install           Install a gem into the local repository
    list              Display local gems whose name matches REGEXP
    lock              Generate a lockdown list of gems
    mirror            Mirror all gem files (requires rubygems-mirror)
    open              Open gem sources in editor
    outdated          Display all gems that need updates
    owner             Manage gem owners of a gem on the push server
    pristine          Restores installed gems to pristine condition from files
                      located in the gem cache
    push              Push a gem up to the gem server
    query             Query gem information in local or remote repositories
    rdoc              Generates RDoc for pre-installed gems
    search            Display remote gems whose name matches REGEXP
    server            Documentation and gem repository HTTP server
    sources           Manage the sources and cache file RubyGems uses to search
                      for gems
    specification     Display gem specification (in yaml)
    stale             List gems along with access times
    uninstall         Uninstall gems from the local repository
    unpack            Unpack an installed gem to the current directory
    update            Update installed gems to the latest version
    which             Find the location of a library file you can require
    yank              Remove a pushed gem from the index

For help on a particular command, use 'gem help COMMAND'.

Commands may be abbreviated, so long as they are unambiguous.
e.g. 'gem i rake' is short for 'gem install rake'.

'''


@pytest.fixture(autouse=True)
def gem_help_commands(mocker):
    patch = mocker.patch('subprocess.Popen')
    patch.return_value.stdout = BytesIO(gem_help_commands_stdout)
    return patch


@pytest.mark.parametrize('script, command', [
    ('gem isntall jekyll', 'isntall'),
    ('gem last --local', 'last')])
def test_match(script, command):
    assert match(Command(script, output.format(command)))


@pytest.mark.parametrize('script, output', [
    ('gem install jekyll', ''),
    ('git log', output.format('log'))])
def test_not_match(script, output):
    assert not match(Command(script, output))


@pytest.mark.parametrize('script, output, result', [
    ('gem isntall jekyll', output.format('isntall'), 'gem install jekyll'),
    ('gem last --local', output.format('last'), 'gem list --local')])
def test_get_new_command(script, output, result):
    new_command = get_new_command(Command(script, output))
    assert new_command[0] == result


================================================
FILE: tests/rules/test_git_add.py
================================================
import pytest
from thefuck.rules.git_add import match, get_new_command
from thefuck.types import Command


@pytest.fixture(autouse=True)
def path_exists(mocker):
    return mocker.patch('thefuck.rules.git_add.Path.exists',
                        return_value=True)


@pytest.fixture
def output(target):
    return ("error: pathspec '{}' did not match any "
            'file(s) known to git.'.format(target))


@pytest.mark.parametrize('script, target', [
    ('git submodule update unknown', 'unknown'),
    ('git commit unknown', 'unknown')])
def test_match(output, script, target):
    assert match(Command(script, output))


@pytest.mark.parametrize('script, target, exists', [
    ('git submodule update known', '', True),
    ('git commit known', '', True),
    ('git submodule update known', output, False)])
def test_not_match(path_exists, output, script, target, exists):
    path_exists.return_value = exists
    assert not match(Command(script, output))


@pytest.mark.parametrize('script, target, new_command', [
    ('git submodule update unknown', 'unknown',
     'git add -- unknown && git submodule update unknown'),
    ('git commit unknown', 'unknown',
     'git add -- unknown && git commit unknown')])
def test_get_new_command(output, script, target, new_command):
    assert get_new_command(Command(script, output)) == new_command


================================================
FILE: tests/rules/test_git_add_force.py
================================================
import pytest
from thefuck.rules.git_add_force import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def output():
    return ('The following paths are ignored by one of your .gitignore files:\n'
            'dist/app.js\n'
            'dist/background.js\n'
            'dist/options.js\n'
            'Use -f if you really want to add them.\n')


def test_match(output):
    assert match(Command('git add dist/*.js', output))
    assert not match(Command('git add dist/*.js', ''))


def test_get_new_command(output):
    assert (get_new_command(Command('git add dist/*.js', output))
            == "git add --force dist/*.js")


================================================
FILE: tests/rules/test_git_bisect_usage.py
================================================
import pytest
from thefuck.types import Command
from thefuck.rules.git_bisect_usage import match, get_new_command


@pytest.fixture
def output():
    return ("usage: git bisect [help|start|bad|good|new|old"
            "|terms|skip|next|reset|visualize|replay|log|run]")


@pytest.mark.parametrize('script', [
    'git bisect strt', 'git bisect rset', 'git bisect goood'])
def test_match(output, script):
    assert match(Command(script, output))


@pytest.mark.parametrize('script', [
    'git bisect', 'git bisect start', 'git bisect good'])
def test_not_match(script):
    assert not match(Command(script, ''))


@pytest.mark.parametrize('script, new_cmd, ', [
    ('git bisect goood', ['good', 'old', 'log']),
    ('git bisect strt', ['start', 'terms', 'reset']),
    ('git bisect rset', ['reset', 'next', 'start'])])
def test_get_new_command(output, script, new_cmd):
    new_cmd = ['git bisect %s' % cmd for cmd in new_cmd]
    assert get_new_command(Command(script, output)) == new_cmd


================================================
FILE: tests/rules/test_git_branch_0flag.py
================================================
import pytest

from thefuck.rules.git_branch_0flag import get_new_command, match
from thefuck.types import Command


@pytest.fixture
def output_branch_exists():
    return "fatal: A branch named 'bar' already exists."


@pytest.mark.parametrize(
    "script",
    [
        "git branch 0a",
        "git branch 0d",
        "git branch 0f",
        "git branch 0r",
        "git branch 0v",
        "git branch 0d foo",
        "git branch 0D foo",
    ],
)
def test_match(script, output_branch_exists):
    assert match(Command(script, output_branch_exists))


@pytest.mark.parametrize(
    "script",
    [
        "git branch -a",
        "git branch -r",
        "git branch -v",
        "git branch -d foo",
        "git branch -D foo",
    ],
)
def test_not_match(script, output_branch_exists):
    assert not match(Command(script, ""))


@pytest.mark.parametrize(
    "script, new_command",
    [
        ("git branch 0a", "git branch -D 0a && git branch -a"),
        ("git branch 0v", "git branch -D 0v && git branch -v"),
        ("git branch 0d foo", "git branch -D 0d && git branch -d foo"),
        ("git branch 0D foo", "git branch -D 0D && git branch -D foo"),
        ("git branch 0l 'maint-*'", "git branch -D 0l && git branch -l 'maint-*'"),
        ("git branch 0u upstream", "git branch -D 0u && git branch -u upstream"),
    ],
)
def test_get_new_command_branch_exists(script, output_branch_exists, new_command):
    assert get_new_command(Command(script, output_branch_exists)) == new_command


@pytest.fixture
def output_not_valid_object():
    return "fatal: Not a valid object name: 'bar'."


@pytest.mark.parametrize(
    "script, new_command",
    [
        ("git branch 0l 'maint-*'", "git branch -l 'maint-*'"),
        ("git branch 0u upstream", "git branch -u upstream"),
    ],
)
def test_get_new_command_not_valid_object(script, output_not_valid_object, new_command):
    assert get_new_command(Command(script, output_not_valid_object)) == new_command


================================================
FILE: tests/rules/test_git_branch_delete.py
================================================
import pytest
from thefuck.rules.git_branch_delete import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def output():
    return '''error: The branch 'branch' is not fully merged.
If you are sure you want to delete it, run 'git branch -D branch'.

'''


def test_match(output):
    assert match(Command('git branch -d branch', output))
    assert not match(Command('git branch -d branch', ''))
    assert not match(Command('ls', output))


def test_get_new_command(output):
    assert get_new_command(Command('git branch -d branch', output))\
        == "git branch -D branch"


================================================
FILE: tests/rules/test_git_branch_delete_checked_out.py
================================================
import pytest
from thefuck.rules.git_branch_delete_checked_out import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def output():
    return "error: Cannot delete branch 'foo' checked out at '/bar/foo'"


@pytest.mark.parametrize("script", ["git branch -d foo", "git branch -D foo"])
def test_match(script, output):
    assert match(Command(script, output))


@pytest.mark.parametrize("script", ["git branch -d foo", "git branch -D foo"])
def test_not_match(script):
    assert not match(Command(script, "Deleted branch foo (was a1b2c3d)."))


@pytest.mark.parametrize(
    "script, new_command",
    [
        ("git branch -d foo", "git checkout master && git branch -D foo"),
        ("git branch -D foo", "git checkout master && git branch -D foo"),
    ],
)
def test_get_new_command(script, new_command, output):
    assert get_new_command(Command(script, output)) == new_command


================================================
FILE: tests/rules/test_git_branch_exists.py
================================================
import pytest
from thefuck.rules.git_branch_exists import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def output(src_branch_name):
    return "fatal: A branch named '{}' already exists.".format(src_branch_name)


@pytest.fixture
def new_command(branch_name):
    return [cmd.format(branch_name) for cmd in [
        'git branch -d {0} && git branch {0}',
        'git branch -d {0} && git checkout -b {0}',
        'git branch -D {0} && git branch {0}',
        'git branch -D {0} && git checkout -b {0}', 'git checkout {0}']]


@pytest.mark.parametrize('script, src_branch_name, branch_name', [
    ('git branch foo', 'foo', 'foo'),
    ('git checkout bar', 'bar', 'bar'),
    ('git checkout -b "let\'s-push-this"', '"let\'s-push-this"', '"let\'s-push-this"')])
def test_match(output, script, branch_name):
    assert match(Command(script, output))


@pytest.mark.parametrize('script', [
    'git branch foo',
    'git checkout bar',
    'git checkout -b "let\'s-push-this"'])
def test_not_match(script):
    assert not match(Command(script, ''))


@pytest.mark.parametrize('script, src_branch_name, branch_name', [
    ('git branch foo', 'foo', 'foo'),
    ('git checkout bar', 'bar', 'bar'),
    ('git checkout -b "let\'s-push-this"', "let's-push-this", "let\\'s-push-this")])
def test_get_new_command(output, new_command, script, src_branch_name, branch_name):
    assert get_new_command(Command(script, output)) == new_command


================================================
FILE: tests/rules/test_git_branch_list.py
================================================
from thefuck.rules.git_branch_list import match, get_new_command
from thefuck.shells import shell
from thefuck.types import Command


def test_match():
    assert match(Command('git branch list', ''))


def test_not_match():
    assert not match(Command('', ''))
    assert not match(Command('git commit', ''))
    assert not match(Command('git branch', ''))
    assert not match(Command('git stash list', ''))


def test_get_new_command():
    assert (get_new_command(Command('git branch list', '')) ==
            shell.and_('git branch --delete list', 'git branch'))


================================================
FILE: tests/rules/test_git_checkout.py
================================================
import pytest
from io import BytesIO
from thefuck.rules.git_checkout import match, get_branches, get_new_command
from thefuck.types import Command


def did_not_match(target, did_you_forget=False):
    error = ("error: pathspec '{}' did not match any "
             "file(s) known to git.".format(target))
    if did_you_forget:
        error = ("{}\nDid you forget to 'git add'?'".format(error))
    return error


@pytest.fixture
def git_branch(mocker, branches):
    mock = mocker.patch('subprocess.Popen')
    mock.return_value.stdout = BytesIO(branches)
    return mock


@pytest.mark.parametrize('command', [
    Command('git checkout unknown', did_not_match('unknown')),
    Command('git commit unknown', did_not_match('unknown'))])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('git submodule update unknown',
            did_not_match('unknown', True)),
    Command('git checkout known', ''),
    Command('git commit known', '')])
def test_not_match(command):
    assert not match(command)


@pytest.mark.parametrize('branches, branch_list', [
    (b'', []),
    (b'* master', ['master']),
    (b'  remotes/origin/master', ['master']),
    (b'  remotes/origin/test/1', ['test/1']),
    (b'  remotes/origin/test/1/2/3', ['test/1/2/3']),
    (b'  test/1', ['test/1']),
    (b'  test/1/2/3', ['test/1/2/3']),
    (b'  remotes/origin/HEAD -> origin/master', []),
    (b'  just-another-branch', ['just-another-branch']),
    (b'* master\n  just-another-branch', ['master', 'just-another-branch']),
    (b'* master\n  remotes/origin/master\n  just-another-branch',
     ['master', 'master', 'just-another-branch'])])
def test_get_branches(branches, branch_list, git_branch):
    git_branch(branches)
    assert list(get_branches()) == branch_list


@pytest.mark.parametrize('branches, command, new_command', [
    (b'',
     Command('git checkout unknown', did_not_match('unknown')),
     ['git checkout -b unknown']),
    (b'',
     Command('git commit unknown', did_not_match('unknown')),
     ['git branch unknown && git commit unknown']),
    (b'  test-random-branch-123',
     Command('git checkout tst-rdm-brnch-123',
             did_not_match('tst-rdm-brnch-123')),
     ['git checkout test-random-branch-123', 'git checkout -b tst-rdm-brnch-123']),
    (b'  test-random-branch-123',
     Command('git commit tst-rdm-brnch-123',
             did_not_match('tst-rdm-brnch-123')),
     ['git commit test-random-branch-123'])])
def test_get_new_command(branches, command, new_command, git_branch):
    git_branch(branches)
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_git_clone_git_clone.py
================================================
from thefuck.rules.git_clone_git_clone import match, get_new_command
from thefuck.types import Command


output_clean = """
fatal: Too many arguments.

usage: git clone [<options>] [--] <repo> [<dir>]
"""


def test_match():
    assert match(Command('git clone git clone foo', output_clean))


def test_not_match():
    assert not match(Command('', ''))
    assert not match(Command('git branch', ''))
    assert not match(Command('git clone foo', ''))
    assert not match(Command('git clone foo bar baz', output_clean))


def test_get_new_command():
    assert get_new_command(Command('git clone git clone foo', output_clean)) == 'git clone foo'


================================================
FILE: tests/rules/test_git_clone_missing.py
================================================
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


================================================
FILE: tests/rules/test_git_commit_add.py
================================================
import pytest
from thefuck.rules.git_commit_add import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize(
    "script, output",
    [
        ('git commit -m "test"', "no changes added to commit"),
        ("git commit", "no changes added to commit"),
    ],
)
def test_match(output, script):
    assert match(Command(script, output))


@pytest.mark.parametrize(
    "script, output",
    [
        ('git commit -m "test"', " 1 file changed, 15 insertions(+), 14 deletions(-)"),
        ("git branch foo", ""),
        ("git checkout feature/test_commit", ""),
        ("git push", ""),
    ],
)
def test_not_match(output, script):
    assert not match(Command(script, output))


@pytest.mark.parametrize(
    "script, new_command",
    [
        ("git commit", ["git commit -a", "git commit -p"]),
        ('git commit -m "foo"', ['git commit -a -m "foo"', 'git commit -p -m "foo"']),
    ],
)
def test_get_new_command(script, new_command):
    assert get_new_command(Command(script, "")) == new_command


================================================
FILE: tests/rules/test_git_commit_amend.py
================================================
import pytest
from thefuck.rules.git_commit_amend import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize('script, output', [
    ('git commit -m "test"', 'test output'),
    ('git commit', '')])
def test_match(output, script):
    assert match(Command(script, output))


@pytest.mark.parametrize('script', [
    'git branch foo',
    'git checkout feature/test_commit',
    'git push'])
def test_not_match(script):
    assert not match(Command(script, ''))


@pytest.mark.parametrize('script', [
    ('git commit -m "test commit"'),
    ('git commit')])
def test_get_new_command(script):
    assert get_new_command(Command(script, '')) == 'git commit --amend'


================================================
FILE: tests/rules/test_git_commit_reset.py
================================================
import pytest
from thefuck.rules.git_commit_reset import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize('script, output', [
    ('git commit -m "test"', 'test output'),
    ('git commit', '')])
def test_match(output, script):
    assert match(Command(script, output))


@pytest.mark.parametrize('script', [
    'git branch foo',
    'git checkout feature/test_commit',
    'git push'])
def test_not_match(script):
    assert not match(Command(script, ''))


@pytest.mark.parametrize('script', [
    ('git commit -m "test commit"'),
    ('git commit')])
def test_get_new_command(script):
    assert get_new_command(Command(script, '')) == 'git reset HEAD~'


================================================
FILE: tests/rules/test_git_diff_no_index.py
================================================
import pytest
from thefuck.rules.git_diff_no_index import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize('command', [
    Command('git diff foo bar', '')])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('git diff --no-index foo bar', ''),
    Command('git diff foo', ''),
    Command('git diff foo bar baz', '')])
def test_not_match(command):
    assert not match(command)


@pytest.mark.parametrize('command, new_command', [
    (Command('git diff foo bar', ''), 'git diff --no-index foo bar')])
def test_get_new_command(command, new_command):
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_git_diff_staged.py
================================================
import pytest
from thefuck.rules.git_diff_staged import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize('command', [
    Command('git diff foo', ''),
    Command('git diff', '')])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('git diff --staged', ''),
    Command('git tag', ''),
    Command('git branch', ''),
    Command('git log', '')])
def test_not_match(command):
    assert not match(command)


@pytest.mark.parametrize('command, new_command', [
    (Command('git diff', ''), 'git diff --staged'),
    (Command('git diff foo', ''), 'git diff --staged foo')])
def test_get_new_command(command, new_command):
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_git_fix_stash.py
================================================
import pytest
from thefuck.rules.git_fix_stash import match, get_new_command
from thefuck.types import Command


git_stash_err = '''
usage: git stash list [<options>]
   or: git stash show [<stash>]
   or: git stash drop [-q|--quiet] [<stash>]
   or: git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
   or: git stash branch <branchname> [<stash>]
   or: git stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
\t\t       [-u|--include-untracked] [-a|--all] [<message>]]
   or: git stash clear
'''


@pytest.mark.parametrize('wrong', [
    'git stash opp',
    'git stash Some message',
    'git stash saev Some message'])
def test_match(wrong):
    assert match(Command(wrong, git_stash_err))


def test_not_match():
    assert not match(Command("git", git_stash_err))


@pytest.mark.parametrize('wrong,fixed', [
    ('git stash opp', 'git stash pop'),
    ('git stash Some message', 'git stash save Some message'),
    ('git stash saev Some message', 'git stash save Some message')])
def test_get_new_command(wrong, fixed):
    assert get_new_command(Command(wrong, git_stash_err)) == fixed


================================================
FILE: tests/rules/test_git_flag_after_filename.py
================================================
import pytest
from thefuck.rules.git_flag_after_filename import match, get_new_command
from thefuck.types import Command

command1 = Command('git log README.md -p',
                   "fatal: bad flag '-p' used after filename")
command2 = Command('git log README.md -p CONTRIBUTING.md',
                   "fatal: bad flag '-p' used after filename")
command3 = Command('git log -p README.md --name-only',
                   "fatal: bad flag '--name-only' used after filename")
command4 = Command('git log README.md -p',
                   "fatal: option '-p' must come before non-option arguments")
command5 = Command('git log README.md -p CONTRIBUTING.md',
                   "fatal: option '-p' must come before non-option arguments")
command6 = Command('git log -p README.md --name-only',
                   "fatal: option '--name-only' must come before non-option arguments")


@pytest.mark.parametrize('command', [
    command1, command2, command3, command4, command5, command6])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('git log README.md', ''),
    Command('git log -p README.md', '')])
def test_not_match(command):
    assert not match(command)


@pytest.mark.parametrize('command, result', [
    (command1, "git log -p README.md"),
    (command2, "git log -p README.md CONTRIBUTING.md"),
    (command3, "git log -p --name-only README.md"),
    (command4, "git log -p README.md"),
    (command5, "git log -p README.md CONTRIBUTING.md"),
    (command6, "git log -p --name-only README.md")])
def test_get_new_command(command, result):
    assert get_new_command(command) == result


================================================
FILE: tests/rules/test_git_help_aliased.py
================================================
import pytest
from thefuck.rules.git_help_aliased import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize('script, output', [
    ('git help st', "`git st' is aliased to `status'"),
    ('git help ds', "`git ds' is aliased to `diff --staged'")])
def test_match(script, output):
    assert match(Command(script, output))


@pytest.mark.parametrize('script, output', [
    ('git help status', "GIT-STATUS(1)...Git Manual...GIT-STATUS(1)"),
    ('git help diff', "GIT-DIFF(1)...Git Manual...GIT-DIFF(1)")])
def test_not_match(script, output):
    assert not match(Command(script, output))


@pytest.mark.parametrize('script, output, new_command', [
    ('git help st', "`git st' is aliased to `status'", 'git help status'),
    ('git help ds', "`git ds' is aliased to `diff --staged'", 'git help diff')])
def test_get_new_command(script, output, new_command):
    assert get_new_command(Command(script, output)) == new_command


================================================
FILE: tests/rules/test_git_hook_bypass.py
================================================
import pytest
from thefuck.rules.git_hook_bypass import match, get_new_command
from thefuck.types import Command


@pytest.mark.parametrize(
    "command",
    [
        Command("git am", ""),
        Command("git commit", ""),
        Command("git commit -m 'foo bar'", ""),
        Command("git push", ""),
        Command("git push -u foo bar", ""),
    ],
)
def test_match(command):
    assert match(command)


@pytest.mark.parametrize(
    "command",
    [
        Command("git add foo", ""),
        Command("git status", ""),
        Command("git diff foo bar", ""),
    ],
)
def test_not_match(command):
    assert not match(command)


@pytest.mark.parametrize(
    "command, new_command",
    [
        (Command("git am", ""), "git am --no-verify"),
        (Command("git commit", ""), "git commit --no-verify"),
        (Command("git commit -m 'foo bar'", ""), "git commit --no-verify -m 'foo bar'"),
        (Command("git push", ""), "git push --no-verify"),
        (Command("git push -p", ""), "git push --no-verify -p"),
    ],
)
def test_get_new_command(command, new_command):
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_git_lfs_mistype.py
================================================
import pytest

from thefuck.rules.git_lfs_mistype import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def mistype_response():
    return """
Error: unknown command "evn" for "git-lfs"

Did you mean this?
        env
        ext

Run 'git-lfs --help' for usage.
    """


def test_match(mistype_response):
    assert match(Command('git lfs evn', mistype_response))
    err_response = 'bash: git: command not found'
    assert not match(Command('git lfs env', err_response))
    assert not match(Command('docker lfs env', mistype_response))


def test_get_new_command(mistype_response):
    assert (get_new_command(Command('git lfs evn', mistype_response))
            == ['git lfs env', 'git lfs ext'])


================================================
FILE: tests/rules/test_git_main_master.py
================================================
import pytest
from thefuck.rules.git_main_master import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def output(branch_name):
    if not branch_name:
        return ""
    output_str = u"error: pathspec '{}' did not match any file(s) known to git"
    return output_str.format(branch_name)


@pytest.mark.parametrize(
    "script, branch_name",
    [
        ("git checkout main", "main"),
        ("git checkout master", "master"),
        ("git show main", "main"),
    ],
)
def test_match(script, branch_name, output):
    assert match(Command(script, output))


@pytest.mark.parametrize(
    "script, branch_name",
    [
        ("git checkout master", ""),
        ("git checkout main", ""),
        ("git checkout wibble", "wibble"),
    ],
)
def test_not_match(script, branch_name, output):
    assert not match(Command(script, output))


@pytest.mark.parametrize(
    "script, branch_name, new_command",
    [
        ("git checkout main", "main", "git checkout master"),
        ("git checkout master", "master", "git checkout main"),
        ("git checkout wibble", "wibble", "git checkout wibble"),
    ],
)
def test_get_new_command(script, branch_name, new_command, output):
    assert get_new_command(Command(script, output)) == new_command


================================================
FILE: tests/rules/test_git_merge.py
================================================
import pytest
from thefuck.rules.git_merge import match, get_new_command
from thefuck.types import Command


output = 'merge: local - not something we can merge\n\n' \
         'Did you mean this?\n\tremote/local'


def test_match():
    assert match(Command('git merge test', output))
    assert not match(Command('git merge master', ''))
    assert not match(Command('ls', output))


@pytest.mark.parametrize('command, new_command', [
    (Command('git merge local', output),
     'git merge remote/local'),
    (Command('git merge -m "test" local', output),
     'git merge -m "test" remote/local'),
    (Command('git merge -m "test local" local', output),
     'git merge -m "test local" remote/local')])
def test_get_new_command(command, new_command):
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_git_merge_unrelated.py
================================================
import pytest
from thefuck.rules.git_merge_unrelated import match, get_new_command
from thefuck.types import Command


output = 'fatal: refusing to merge unrelated histories'


def test_match():
    assert match(Command('git merge test', output))
    assert not match(Command('git merge master', ''))
    assert not match(Command('ls', output))


@pytest.mark.parametrize('command, new_command', [
    (Command('git merge local', output),
     'git merge local --allow-unrelated-histories'),
    (Command('git merge -m "test" local', output),
     'git merge -m "test" local --allow-unrelated-histories'),
    (Command('git merge -m "test local" local', output),
     'git merge -m "test local" local --allow-unrelated-histories')])
def test_get_new_command(command, new_command):
    assert get_new_command(command) == new_command


================================================
FILE: tests/rules/test_git_not_command.py
================================================
import pytest
from thefuck.rules.git_not_command import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def git_not_command():
    return """git: 'brnch' is not a git command. See 'git --help'.

The most similar command is
branch
"""


@pytest.fixture
def git_not_command_one_of_this():
    return """git: 'st' is not a git command. See 'git --help'.

The most similar commands are
status
reset
stage
stash
stats
"""


@pytest.fixture
def git_not_command_closest():
    return '''git: 'tags' is not a git command. See 'git --help'.

The most similar commands are
\tstage
\ttag
'''


@pytest.fixture
def git_command():
    return "* master"


def test_match(git_not_command, git_command, git_not_command_one_of_this):
    assert match(Command('git brnch', git_not_command))
    assert match(Command('git st', git_not_command_one_of_this))
    assert not match(Command('ls brnch', git_not_command))
    assert not match(Command('git branch', git_command))


def test_get_new_command(git_not_command, git_not_command_one_of_this,
                         git_not_command_closest):
    assert (get_new_command(Command('git brnch', git_not_command))
            == ['git branch'])
    assert (get_new_command(Command('git st', git_not_command_one_of_this))
            == ['git stats', 'git stash', 'git stage'])
    assert (get_new_command(Command('git tags', git_not_command_closest))
            == ['git tag', 'git stage'])


================================================
FILE: tests/rules/test_git_pull.py
================================================
import pytest
from thefuck.rules.git_pull import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def output():
    return '''There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=<remote>/<branch> master

'''


def test_match(output):
    assert match(Command('git pull', output))
    assert not match(Command('git pull', ''))
    assert not match(Command('ls', output))


def test_get_new_command(output):
    assert (get_new_command(Command('git pull', output))
            == "git branch --set-upstream-to=origin/master master && git pull")


================================================
FILE: tests/rules/test_git_pull_clone.py
================================================
import pytest
from thefuck.rules.git_pull_clone import match, get_new_command
from thefuck.types import Command


git_err = '''
fatal: Not a git r
Download .txt
gitextract_9f8tmqdi/

├── .devcontainer/
│   ├── Dockerfile
│   └── devcontainer.json
├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   └── workflows/
│       └── test.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.md
├── MANIFEST.in
├── README.md
├── fastentrypoints.py
├── install.sh
├── release.py
├── requirements.txt
├── scripts/
│   ├── fuck.bat
│   └── fuck.ps1
├── setup.cfg
├── setup.py
├── snapcraft.yaml
├── tests/
│   ├── Dockerfile
│   ├── __init__.py
│   ├── conftest.py
│   ├── entrypoints/
│   │   ├── __init__.py
│   │   ├── test_alias.py
│   │   ├── test_fix_command.py
│   │   └── test_not_configured.py
│   ├── functional/
│   │   ├── __init__.py
│   │   ├── conftest.py
│   │   ├── plots.py
│   │   ├── test_bash.py
│   │   ├── test_fish.py
│   │   ├── test_tcsh.py
│   │   └── test_zsh.py
│   ├── output_readers/
│   │   └── test_rerun.py
│   ├── rules/
│   │   ├── __init__.py
│   │   ├── test_adb_unknown_command.py
│   │   ├── test_ag_literal.py
│   │   ├── test_apt_get.py
│   │   ├── test_apt_get_search.py
│   │   ├── test_apt_invalid_operation.py
│   │   ├── test_apt_list_upgradable.py
│   │   ├── test_apt_upgrade.py
│   │   ├── test_aws_cli.py
│   │   ├── test_az_cli.py
│   │   ├── test_brew_cask_dependency.py
│   │   ├── test_brew_install.py
│   │   ├── test_brew_link.py
│   │   ├── test_brew_reinstall.py
│   │   ├── test_brew_uninstall.py
│   │   ├── test_brew_unknown_command.py
│   │   ├── test_brew_update_formula.py
│   │   ├── test_cargo_no_command.py
│   │   ├── test_cat_dir.py
│   │   ├── test_cd_correction.py
│   │   ├── test_cd_cs.py
│   │   ├── test_cd_mkdir.py
│   │   ├── test_cd_parent.py
│   │   ├── test_chmod_x.py
│   │   ├── test_choco_install.py
│   │   ├── test_composer_not_command.py
│   │   ├── test_conda_mistype.py
│   │   ├── test_cp_create_destination.py
│   │   ├── test_cp_omitting_directory.py
│   │   ├── test_dirty_untar.py
│   │   ├── test_dirty_unzip.py
│   │   ├── test_django_south_ghost.py
│   │   ├── test_django_south_merge.py
│   │   ├── test_dnf_no_such_command.py
│   │   ├── test_docker_image_being_used_by_container.py
│   │   ├── test_docker_login.py
│   │   ├── test_docker_not_command.py
│   │   ├── test_dry.py
│   │   ├── test_fab_command_not_found.py
│   │   ├── test_fix_alt_space.py
│   │   ├── test_fix_file.py
│   │   ├── test_gem_unknown_command.py
│   │   ├── test_git_add.py
│   │   ├── test_git_add_force.py
│   │   ├── test_git_bisect_usage.py
│   │   ├── test_git_branch_0flag.py
│   │   ├── test_git_branch_delete.py
│   │   ├── test_git_branch_delete_checked_out.py
│   │   ├── test_git_branch_exists.py
│   │   ├── test_git_branch_list.py
│   │   ├── test_git_checkout.py
│   │   ├── test_git_clone_git_clone.py
│   │   ├── test_git_clone_missing.py
│   │   ├── test_git_commit_add.py
│   │   ├── test_git_commit_amend.py
│   │   ├── test_git_commit_reset.py
│   │   ├── test_git_diff_no_index.py
│   │   ├── test_git_diff_staged.py
│   │   ├── test_git_fix_stash.py
│   │   ├── test_git_flag_after_filename.py
│   │   ├── test_git_help_aliased.py
│   │   ├── test_git_hook_bypass.py
│   │   ├── test_git_lfs_mistype.py
│   │   ├── test_git_main_master.py
│   │   ├── test_git_merge.py
│   │   ├── test_git_merge_unrelated.py
│   │   ├── test_git_not_command.py
│   │   ├── test_git_pull.py
│   │   ├── test_git_pull_clone.py
│   │   ├── test_git_pull_uncommitted_changes.py
│   │   ├── test_git_pull_unstaged_changes.py
│   │   ├── test_git_push.py
│   │   ├── test_git_push_different_branch_names.py
│   │   ├── test_git_push_force.py
│   │   ├── test_git_push_pull.py
│   │   ├── test_git_push_without_commits.py
│   │   ├── test_git_rebase_merge_dir.py
│   │   ├── test_git_rebase_no_changes.py
│   │   ├── test_git_remote_delete.py
│   │   ├── test_git_remote_seturl_add.py
│   │   ├── test_git_rm_local_modifications.py
│   │   ├── test_git_rm_recursive.py
│   │   ├── test_git_rm_staged.py
│   │   ├── test_git_stash.py
│   │   ├── test_git_stash_pop.py
│   │   ├── test_git_tag_force.py
│   │   ├── test_git_two_dashes.py
│   │   ├── test_go_run.py
│   │   ├── test_go_unknown_command.py
│   │   ├── test_gradle_not_task.py
│   │   ├── test_gradle_wrapper.py
│   │   ├── test_grep_arguments_order.py
│   │   ├── test_grep_recursive.py
│   │   ├── test_grunt_task_not_found.py
│   │   ├── test_gulp_not_task.py
│   │   ├── test_has_exists_script.py
│   │   ├── test_heroku_multiple_apps.py
│   │   ├── test_heroku_not_command.py
│   │   ├── test_history.py
│   │   ├── test_hostscli.py
│   │   ├── test_ifconfig_device_not_found.py
│   │   ├── test_java.py
│   │   ├── test_javac.py
│   │   ├── test_lein_not_task.py
│   │   ├── test_ln_no_hard_link.py
│   │   ├── test_ln_s_order.py
│   │   ├── test_long_form_help.py
│   │   ├── test_ls_all.py
│   │   ├── test_ls_lah.py
│   │   ├── test_man.py
│   │   ├── test_man_no_space.py
│   │   ├── test_mercurial.py
│   │   ├── test_missing_space_before_subcommand.py
│   │   ├── test_mkdir_p.py
│   │   ├── test_mvn_no_command.py
│   │   ├── test_mvn_unknown_lifecycle_phase.py
│   │   ├── test_nixos_cmd_not_found.py
│   │   ├── test_no_command.py
│   │   ├── test_no_such_file.py
│   │   ├── test_npm_missing_script.py
│   │   ├── test_npm_run_script.py
│   │   ├── test_npm_wrong_command.py
│   │   ├── test_omnienv_no_such_command.py
│   │   ├── test_open.py
│   │   ├── test_pacman.py
│   │   ├── test_pacman_invalid_option.py
│   │   ├── test_pacman_not_found.py
│   │   ├── test_path_from_history.py
│   │   ├── test_php_s.py
│   │   ├── test_pip_install.py
│   │   ├── test_pip_unknown_command.py
│   │   ├── test_port_already_in_use.py
│   │   ├── test_prove_recursively.py
│   │   ├── test_python_command.py
│   │   ├── test_python_execute.py
│   │   ├── test_python_module_error.py
│   │   ├── test_quotation_marks.py
│   │   ├── test_rails_migrations_pending.py
│   │   ├── test_react_native_command_unrecognized.py
│   │   ├── test_remove_shell_prompt_literal.py
│   │   ├── test_remove_trailing_cedilla.py
│   │   ├── test_rm_dir.py
│   │   ├── test_rm_root.py
│   │   ├── test_scm_correction.py
│   │   ├── test_sed_unterminated_s.py
│   │   ├── test_sl_ls.py
│   │   ├── test_ssh_known_host.py
│   │   ├── test_sudo.py
│   │   ├── test_sudo_command_from_user_path.py
│   │   ├── test_switch_lang.py
│   │   ├── test_systemctl.py
│   │   ├── test_terraform_init.py
│   │   ├── test_terraform_no_command.py
│   │   ├── test_tmux.py
│   │   ├── test_touch.py
│   │   ├── test_tsuru_login.py
│   │   ├── test_tsuru_not_command.py
│   │   ├── test_unknown_command.py
│   │   ├── test_unsudo.py
│   │   ├── test_vagrant_up.py
│   │   ├── test_whois.py
│   │   ├── test_workon_doesnt_exists.py
│   │   ├── test_wrong_hyphen_before_subcommand.py
│   │   ├── test_yarn_alias.py
│   │   ├── test_yarn_command_not_found.py
│   │   ├── test_yarn_command_replaced.py
│   │   ├── test_yarn_help.py
│   │   └── test_yum_invalid_operation.py
│   ├── shells/
│   │   ├── __init__.py
│   │   ├── conftest.py
│   │   ├── test_bash.py
│   │   ├── test_fish.py
│   │   ├── test_generic.py
│   │   ├── test_powershell.py
│   │   ├── test_tcsh.py
│   │   └── test_zsh.py
│   ├── specific/
│   │   ├── __init__.py
│   │   ├── test_git.py
│   │   ├── test_npm.py
│   │   └── test_sudo.py
│   ├── test_argument_parser.py
│   ├── test_conf.py
│   ├── test_corrector.py
│   ├── test_logs.py
│   ├── test_readme.py
│   ├── test_types.py
│   ├── test_ui.py
│   ├── test_utils.py
│   └── utils.py
├── thefuck/
│   ├── __init__.py
│   ├── argument_parser.py
│   ├── conf.py
│   ├── const.py
│   ├── corrector.py
│   ├── entrypoints/
│   │   ├── __init__.py
│   │   ├── alias.py
│   │   ├── fix_command.py
│   │   ├── main.py
│   │   ├── not_configured.py
│   │   └── shell_logger.py
│   ├── exceptions.py
│   ├── logs.py
│   ├── output_readers/
│   │   ├── __init__.py
│   │   ├── read_log.py
│   │   ├── rerun.py
│   │   └── shell_logger.py
│   ├── rules/
│   │   ├── __init__.py
│   │   ├── adb_unknown_command.py
│   │   ├── ag_literal.py
│   │   ├── apt_get.py
│   │   ├── apt_get_search.py
│   │   ├── apt_invalid_operation.py
│   │   ├── apt_list_upgradable.py
│   │   ├── apt_upgrade.py
│   │   ├── aws_cli.py
│   │   ├── az_cli.py
│   │   ├── brew_cask_dependency.py
│   │   ├── brew_install.py
│   │   ├── brew_link.py
│   │   ├── brew_reinstall.py
│   │   ├── brew_uninstall.py
│   │   ├── brew_unknown_command.py
│   │   ├── brew_update_formula.py
│   │   ├── cargo.py
│   │   ├── cargo_no_command.py
│   │   ├── cat_dir.py
│   │   ├── cd_correction.py
│   │   ├── cd_cs.py
│   │   ├── cd_mkdir.py
│   │   ├── cd_parent.py
│   │   ├── chmod_x.py
│   │   ├── choco_install.py
│   │   ├── composer_not_command.py
│   │   ├── conda_mistype.py
│   │   ├── cp_create_destination.py
│   │   ├── cp_omitting_directory.py
│   │   ├── cpp11.py
│   │   ├── dirty_untar.py
│   │   ├── dirty_unzip.py
│   │   ├── django_south_ghost.py
│   │   ├── django_south_merge.py
│   │   ├── dnf_no_such_command.py
│   │   ├── docker_image_being_used_by_container.py
│   │   ├── docker_login.py
│   │   ├── docker_not_command.py
│   │   ├── dry.py
│   │   ├── fab_command_not_found.py
│   │   ├── fix_alt_space.py
│   │   ├── fix_file.py
│   │   ├── gem_unknown_command.py
│   │   ├── git_add.py
│   │   ├── git_add_force.py
│   │   ├── git_bisect_usage.py
│   │   ├── git_branch_0flag.py
│   │   ├── git_branch_delete.py
│   │   ├── git_branch_delete_checked_out.py
│   │   ├── git_branch_exists.py
│   │   ├── git_branch_list.py
│   │   ├── git_checkout.py
│   │   ├── git_clone_git_clone.py
│   │   ├── git_clone_missing.py
│   │   ├── git_commit_add.py
│   │   ├── git_commit_amend.py
│   │   ├── git_commit_reset.py
│   │   ├── git_diff_no_index.py
│   │   ├── git_diff_staged.py
│   │   ├── git_fix_stash.py
│   │   ├── git_flag_after_filename.py
│   │   ├── git_help_aliased.py
│   │   ├── git_hook_bypass.py
│   │   ├── git_lfs_mistype.py
│   │   ├── git_main_master.py
│   │   ├── git_merge.py
│   │   ├── git_merge_unrelated.py
│   │   ├── git_not_command.py
│   │   ├── git_pull.py
│   │   ├── git_pull_clone.py
│   │   ├── git_pull_uncommitted_changes.py
│   │   ├── git_push.py
│   │   ├── git_push_different_branch_names.py
│   │   ├── git_push_force.py
│   │   ├── git_push_pull.py
│   │   ├── git_push_without_commits.py
│   │   ├── git_rebase_merge_dir.py
│   │   ├── git_rebase_no_changes.py
│   │   ├── git_remote_delete.py
│   │   ├── git_remote_seturl_add.py
│   │   ├── git_rm_local_modifications.py
│   │   ├── git_rm_recursive.py
│   │   ├── git_rm_staged.py
│   │   ├── git_stash.py
│   │   ├── git_stash_pop.py
│   │   ├── git_tag_force.py
│   │   ├── git_two_dashes.py
│   │   ├── go_run.py
│   │   ├── go_unknown_command.py
│   │   ├── gradle_no_task.py
│   │   ├── gradle_wrapper.py
│   │   ├── grep_arguments_order.py
│   │   ├── grep_recursive.py
│   │   ├── grunt_task_not_found.py
│   │   ├── gulp_not_task.py
│   │   ├── has_exists_script.py
│   │   ├── heroku_multiple_apps.py
│   │   ├── heroku_not_command.py
│   │   ├── history.py
│   │   ├── hostscli.py
│   │   ├── ifconfig_device_not_found.py
│   │   ├── java.py
│   │   ├── javac.py
│   │   ├── lein_not_task.py
│   │   ├── ln_no_hard_link.py
│   │   ├── ln_s_order.py
│   │   ├── long_form_help.py
│   │   ├── ls_all.py
│   │   ├── ls_lah.py
│   │   ├── man.py
│   │   ├── man_no_space.py
│   │   ├── mercurial.py
│   │   ├── missing_space_before_subcommand.py
│   │   ├── mkdir_p.py
│   │   ├── mvn_no_command.py
│   │   ├── mvn_unknown_lifecycle_phase.py
│   │   ├── nixos_cmd_not_found.py
│   │   ├── no_command.py
│   │   ├── no_such_file.py
│   │   ├── npm_missing_script.py
│   │   ├── npm_run_script.py
│   │   ├── npm_wrong_command.py
│   │   ├── omnienv_no_such_command.py
│   │   ├── open.py
│   │   ├── pacman.py
│   │   ├── pacman_invalid_option.py
│   │   ├── pacman_not_found.py
│   │   ├── path_from_history.py
│   │   ├── php_s.py
│   │   ├── pip_install.py
│   │   ├── pip_unknown_command.py
│   │   ├── port_already_in_use.py
│   │   ├── prove_recursively.py
│   │   ├── python_command.py
│   │   ├── python_execute.py
│   │   ├── python_module_error.py
│   │   ├── quotation_marks.py
│   │   ├── rails_migrations_pending.py
│   │   ├── react_native_command_unrecognized.py
│   │   ├── remove_shell_prompt_literal.py
│   │   ├── remove_trailing_cedilla.py
│   │   ├── rm_dir.py
│   │   ├── rm_root.py
│   │   ├── scm_correction.py
│   │   ├── sed_unterminated_s.py
│   │   ├── sl_ls.py
│   │   ├── ssh_known_hosts.py
│   │   ├── sudo.py
│   │   ├── sudo_command_from_user_path.py
│   │   ├── switch_lang.py
│   │   ├── systemctl.py
│   │   ├── terraform_init.py
│   │   ├── terraform_no_command.py
│   │   ├── test.py.py
│   │   ├── tmux.py
│   │   ├── touch.py
│   │   ├── tsuru_login.py
│   │   ├── tsuru_not_command.py
│   │   ├── unknown_command.py
│   │   ├── unsudo.py
│   │   ├── vagrant_up.py
│   │   ├── whois.py
│   │   ├── workon_doesnt_exists.py
│   │   ├── wrong_hyphen_before_subcommand.py
│   │   ├── yarn_alias.py
│   │   ├── yarn_command_not_found.py
│   │   ├── yarn_command_replaced.py
│   │   ├── yarn_help.py
│   │   └── yum_invalid_operation.py
│   ├── shells/
│   │   ├── __init__.py
│   │   ├── bash.py
│   │   ├── fish.py
│   │   ├── generic.py
│   │   ├── powershell.py
│   │   ├── tcsh.py
│   │   └── zsh.py
│   ├── specific/
│   │   ├── __init__.py
│   │   ├── apt.py
│   │   ├── archlinux.py
│   │   ├── brew.py
│   │   ├── dnf.py
│   │   ├── git.py
│   │   ├── nix.py
│   │   ├── npm.py
│   │   ├── sudo.py
│   │   └── yum.py
│   ├── system/
│   │   ├── __init__.py
│   │   ├── unix.py
│   │   └── win32.py
│   ├── types.py
│   ├── ui.py
│   └── utils.py
└── tox.ini
Download .txt
SYMBOL INDEX (1470 symbols across 400 files)

FILE: fastentrypoints.py
  function get_args (line 55) | def get_args(cls, dist, header=None):
  function main (line 80) | def main():

FILE: release.py
  function get_new_setup_py_lines (line 10) | def get_new_setup_py_lines():

FILE: tests/conftest.py
  function pytest_configure (line 10) | def pytest_configure(config):
  function pytest_addoption (line 14) | def pytest_addoption(parser):
  function no_memoize (line 22) | def no_memoize(monkeypatch):
  function settings (line 27) | def settings(request):
  function no_colors (line 38) | def no_colors(settings):
  function no_cache (line 43) | def no_cache(monkeypatch):
  function functional (line 48) | def functional(request):
  function source_root (line 55) | def source_root():
  function set_shell (line 60) | def set_shell(monkeypatch):
  function os_environ (line 70) | def os_environ(monkeypatch):

FILE: tests/entrypoints/test_alias.py
  function test_get_alias (line 14) | def test_get_alias(monkeypatch, mocker, py2,
  function test_print_alias (line 33) | def test_print_alias(mocker):

FILE: tests/entrypoints/test_fix_command.py
  class TestGetRawCommand (line 6) | class TestGetRawCommand(object):
    method test_from_force_command_argument (line 7) | def test_from_force_command_argument(self):
    method test_from_command_argument (line 11) | def test_from_command_argument(self, os_environ):
    method test_from_history (line 22) | def test_from_history(self, os_environ, history, result):

FILE: tests/entrypoints/test_not_configured.py
  function usage_tracker (line 10) | def usage_tracker(mocker):
  function usage_tracker_io (line 17) | def usage_tracker_io(usage_tracker):
  function usage_tracker_exists (line 26) | def usage_tracker_exists(usage_tracker):
  function _assert_tracker_updated (line 32) | def _assert_tracker_updated(usage_tracker_io, pid):
  function _change_tracker (line 38) | def _change_tracker(usage_tracker_io, pid):
  function shell_pid (line 46) | def shell_pid(mocker):
  function shell (line 52) | def shell(mocker):
  function shell_config (line 65) | def shell_config(mocker):
  function logs (line 75) | def logs(mocker):
  function test_for_generic_shell (line 80) | def test_for_generic_shell(shell, logs):
  function test_on_first_run (line 86) | def test_on_first_run(usage_tracker_io, usage_tracker_exists, shell_pid,...
  function test_on_run_after_other_commands (line 94) | def test_on_run_after_other_commands(usage_tracker_io, shell_pid, shell,...
  function test_on_first_run_from_current_shell (line 102) | def test_on_first_run_from_current_shell(usage_tracker_io, shell_pid,
  function test_when_cant_configure_automatically (line 111) | def test_when_cant_configure_automatically(shell_pid, shell, logs):
  function test_when_already_configured (line 122) | def test_when_already_configured(usage_tracker_io, shell_pid,
  function test_when_successfully_configured (line 132) | def test_when_successfully_configured(usage_tracker_io, shell_pid,

FILE: tests/functional/conftest.py
  function build_container_mock (line 8) | def build_container_mock(mocker):
  function run_side_effect (line 12) | def run_side_effect(*args, **kwargs):
  function run_mock (line 19) | def run_mock(mocker):

FILE: tests/functional/plots.py
  function _set_confirmation (line 1) | def _set_confirmation(proc, require):
  function with_confirmation (line 8) | def with_confirmation(proc, TIMEOUT):
  function history_changed (line 23) | def history_changed(proc, TIMEOUT, *to):
  function history_not_changed (line 31) | def history_not_changed(proc, TIMEOUT):
  function select_command_with_arrows (line 37) | def select_command_with_arrows(proc, TIMEOUT):
  function refuse_with_confirmation (line 59) | def refuse_with_confirmation(proc, TIMEOUT):
  function without_confirmation (line 74) | def without_confirmation(proc, TIMEOUT):
  function how_to_configure (line 85) | def how_to_configure(proc, TIMEOUT):

FILE: tests/functional/test_bash.py
  function proc (line 28) | def proc(request, spawnu, TIMEOUT):
  function test_with_confirmation (line 40) | def test_with_confirmation(proc, TIMEOUT):
  function test_select_command_with_arrows (line 46) | def test_select_command_with_arrows(proc, TIMEOUT):
  function test_refuse_with_confirmation (line 52) | def test_refuse_with_confirmation(proc, TIMEOUT):
  function test_without_confirmation (line 58) | def test_without_confirmation(proc, TIMEOUT):
  function test_how_to_configure_alias (line 64) | def test_how_to_configure_alias(proc, TIMEOUT):

FILE: tests/functional/test_fish.py
  function proc (line 10) | def proc(request, spawnu, TIMEOUT):
  function test_with_confirmation (line 18) | def test_with_confirmation(proc, TIMEOUT):
  function test_select_command_with_arrows (line 23) | def test_select_command_with_arrows(proc, TIMEOUT):
  function test_refuse_with_confirmation (line 28) | def test_refuse_with_confirmation(proc, TIMEOUT):
  function test_without_confirmation (line 33) | def test_without_confirmation(proc, TIMEOUT):

FILE: tests/functional/test_tcsh.py
  function proc (line 10) | def proc(request, spawnu, TIMEOUT):
  function test_with_confirmation (line 19) | def test_with_confirmation(proc, TIMEOUT):
  function test_select_command_with_arrows (line 24) | def test_select_command_with_arrows(proc, TIMEOUT):
  function test_refuse_with_confirmation (line 29) | def test_refuse_with_confirmation(proc, TIMEOUT):
  function test_without_confirmation (line 34) | def test_without_confirmation(proc, TIMEOUT):

FILE: tests/functional/test_zsh.py
  function proc (line 26) | def proc(request, spawnu, TIMEOUT):
  function test_with_confirmation (line 38) | def test_with_confirmation(proc, TIMEOUT):
  function test_select_command_with_arrows (line 44) | def test_select_command_with_arrows(proc, TIMEOUT):
  function test_refuse_with_confirmation (line 50) | def test_refuse_with_confirmation(proc, TIMEOUT):
  function test_without_confirmation (line 56) | def test_without_confirmation(proc, TIMEOUT):
  function test_how_to_configure_alias (line 62) | def test_how_to_configure_alias(proc, TIMEOUT):

FILE: tests/output_readers/test_rerun.py
  class TestRerun (line 11) | class TestRerun(object):
    method setup_method (line 12) | def setup_method(self, test_method):
    method teardown_method (line 17) | def teardown_method(self, test_method):
    method test_get_output (line 22) | def test_get_output(self, popen_mock, wait_output_mock):
    method test_get_output_invalid_continuation_byte (line 28) | def test_get_output_invalid_continuation_byte(self, popen_mock):
    method test_get_output_unicode_misspell (line 37) | def test_get_output_unicode_misspell(self, wait_output_mock):
    method test_wait_output_is_slow (line 41) | def test_wait_output_is_slow(self, settings):
    method test_wait_output_is_not_slow (line 45) | def test_wait_output_is_not_slow(self, settings):
    method test_wait_output_timeout (line 50) | def test_wait_output_timeout(self, kill_process_mock):
    method test_wait_output_timeout_children (line 57) | def test_wait_output_timeout_children(self, kill_process_mock):
    method test_kill_process (line 63) | def test_kill_process(self):
    method test_kill_process_access_denied (line 69) | def test_kill_process_access_denied(self, logs_mock):

FILE: tests/rules/test_adb_unknown_command.py
  function output (line 7) | def output():
  function test_match (line 23) | def test_match(output, script):
  function test_not_match (line 30) | def test_not_match(script):
  function test_get_new_command (line 40) | def test_get_new_command(script, output, new_command):

FILE: tests/rules/test_ag_literal.py
  function output (line 7) | def output():
  function test_match (line 13) | def test_match(script, output):
  function test_not_match (line 18) | def test_not_match(script):
  function test_get_new_command (line 24) | def test_get_new_command(script, new_cmd, output):

FILE: tests/rules/test_apt_get.py
  function test_match (line 13) | def test_match(mocker, command, packages):
  function test_not_match (line 30) | def test_not_match(mocker, command, packages, which):
  function test_get_new_command (line 49) | def test_get_new_command(mocker, command, new_command, packages):

FILE: tests/rules/test_apt_get_search.py
  function test_match (line 6) | def test_match():
  function test_not_match (line 20) | def test_not_match(command):
  function test_get_new_command (line 24) | def test_get_new_command():

FILE: tests/rules/test_apt_invalid_operation.py
  function test_match (line 123) | def test_match(script, output):
  function test_not_match (line 130) | def test_not_match(script, output):
  function set_help (line 135) | def set_help(mocker):
  function test_get_operations (line 149) | def test_get_operations(set_help, app, help_text, operations):
  function test_get_new_command (line 162) | def test_get_new_command(set_help, output, script, help_text, result):

FILE: tests/rules/test_apt_list_upgradable.py
  function test_match (line 59) | def test_match(output):
  function test_not_match (line 74) | def test_not_match(command):
  function test_get_new_command (line 79) | def test_get_new_command(output):

FILE: tests/rules/test_apt_upgrade.py
  function test_match (line 18) | def test_match():
  function test_not_match (line 27) | def test_not_match(command):
  function test_get_new_command (line 31) | def test_get_new_command():

FILE: tests/rules/test_aws_cli.py
  function test_match (line 84) | def test_match(command):
  function test_not_match (line 88) | def test_not_match():
  function test_get_new_command (line 100) | def test_get_new_command(command, result):

FILE: tests/rules/test_az_cli.py
  function test_match (line 31) | def test_match(command):
  function test_not_match (line 35) | def test_not_match():
  function test_get_new_command (line 43) | def test_get_new_command(command, result):

FILE: tests/rules/test_brew_cask_dependency.py
  function test_match (line 16) | def test_match():
  function test_not_match (line 25) | def test_not_match(script, output):
  function test_get_new_command (line 33) | def test_get_new_command(before, after):

FILE: tests/rules/test_brew_install.py
  function brew_no_available_formula_one (line 7) | def brew_no_available_formula_one():
  function brew_no_available_formula_two (line 12) | def brew_no_available_formula_two():
  function brew_no_available_formula_three (line 17) | def brew_no_available_formula_three():
  function brew_install_no_argument (line 22) | def brew_install_no_argument():
  function brew_already_installed (line 27) | def brew_already_installed():
  function test_suggestions (line 31) | def test_suggestions():
  function test_match (line 37) | def test_match(brew_no_available_formula_one, brew_no_available_formula_...
  function test_get_new_command (line 51) | def test_get_new_command(brew_no_available_formula_one, brew_no_availabl...

FILE: tests/rules/test_brew_link.py
  function output (line 7) | def output():
  function new_command (line 21) | def new_command(formula):
  function test_match (line 26) | def test_match(output, script):
  function test_not_match (line 31) | def test_not_match(script):
  function test_get_new_command (line 36) | def test_get_new_command(output, new_command, script, formula):

FILE: tests/rules/test_brew_reinstall.py
  function test_match (line 10) | def test_match():
  function test_not_match (line 18) | def test_not_match(script):
  function test_get_new_command (line 25) | def test_get_new_command(script, formula):

FILE: tests/rules/test_brew_uninstall.py
  function output (line 7) | def output():
  function new_command (line 14) | def new_command(formula):
  function test_match (line 19) | def test_match(output, script):
  function test_not_match (line 24) | def test_not_match(script):
  function test_get_new_command (line 30) | def test_get_new_command(output, new_command, script, formula):

FILE: tests/rules/test_brew_unknown_command.py
  function brew_unknown_cmd (line 8) | def brew_unknown_cmd():
  function brew_unknown_cmd2 (line 13) | def brew_unknown_cmd2():
  function test_match (line 17) | def test_match(brew_unknown_cmd):
  function test_get_new_command (line 23) | def test_get_new_command(brew_unknown_cmd, brew_unknown_cmd2):

FILE: tests/rules/test_brew_update_formula.py
  function test_match (line 10) | def test_match():
  function test_not_match (line 18) | def test_not_match(script):
  function test_get_new_command (line 25) | def test_get_new_command(script, formula):

FILE: tests/rules/test_cargo_no_command.py
  function test_match (line 20) | def test_match(command):
  function test_get_new_command (line 27) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_cat_dir.py
  function isdir (line 7) | def isdir(mocker):
  function test_match (line 17) | def test_match(command, isdir):
  function test_not_match (line 27) | def test_not_match(command, isdir):
  function test_get_new_command (line 37) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_cd_correction.py
  function test_match (line 12) | def test_match(command):
  function test_not_match (line 18) | def test_not_match(command):

FILE: tests/rules/test_cd_cs.py
  function test_match (line 5) | def test_match():
  function test_get_new_command (line 10) | def test_get_new_command():

FILE: tests/rules/test_cd_mkdir.py
  function test_match (line 12) | def test_match(command):
  function test_not_match (line 18) | def test_not_match(command):
  function test_get_new_command (line 25) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_cd_parent.py
  function test_match (line 5) | def test_match():
  function test_get_new_command (line 10) | def test_get_new_command():

FILE: tests/rules/test_chmod_x.py
  function file_exists (line 7) | def file_exists(mocker):
  function file_access (line 12) | def file_access(mocker):
  function test_match (line 20) | def test_match(script, output):
  function test_not_match (line 29) | def test_not_match(file_exists, file_access, script, output, exists, cal...
  function test_get_new_command (line 38) | def test_get_new_command(script, result):

FILE: tests/rules/test_choco_install.py
  function test_match (line 44) | def test_match(command):
  function not_test_match (line 70) | def not_test_match(command):
  function test_get_new_command (line 85) | def test_get_new_command(before, after):

FILE: tests/rules/test_composer_not_command.py
  function composer_not_command (line 7) | def composer_not_command():
  function composer_not_command_one_of_this (line 24) | def composer_not_command_one_of_this():
  function composer_require_instead_of_install (line 43) | def composer_require_instead_of_install():
  function test_match (line 47) | def test_match(composer_not_command, composer_not_command_one_of_this, c...
  function test_get_new_command (line 57) | def test_get_new_command(composer_not_command, composer_not_command_one_...

FILE: tests/rules/test_conda_mistype.py
  function mistype_response (line 8) | def mistype_response():
  function test_match (line 17) | def test_match(mistype_response):
  function test_get_new_command (line 23) | def test_get_new_command(mistype_response):

FILE: tests/rules/test_cp_create_destination.py
  function test_match (line 10) | def test_match(script, output):
  function test_not_match (line 17) | def test_not_match(script, output):
  function test_get_new_command (line 29) | def test_get_new_command(script, output, new_command):

FILE: tests/rules/test_cp_omitting_directory.py
  function test_match (line 9) | def test_match(script, output):
  function test_not_match (line 17) | def test_not_match(script, output):
  function test_get_new_command (line 21) | def test_get_new_command():

FILE: tests/rules/test_dirty_untar.py
  function tar_error (line 10) | def tar_error(tmpdir):
  function test_match (line 53) | def test_match(ext, tar_error, filename, unquoted, quoted, script, fixed):
  function test_side_effect (line 61) | def test_side_effect(ext, tar_error, filename, unquoted, quoted, script,...
  function test_get_new_command (line 70) | def test_get_new_command(ext, tar_error, filename, unquoted, quoted, scr...

FILE: tests/rules/test_dirty_unzip.py
  function zip_error (line 12) | def zip_error(tmpdir):
  function test_match (line 43) | def test_match(zip_error, script, filename):
  function test_side_effect (line 53) | def test_side_effect(zip_error, script, filename):
  function test_get_new_command (line 69) | def test_get_new_command(zip_error, script, fixed, filename):

FILE: tests/rules/test_django_south_ghost.py
  function output (line 7) | def output():
  function test_match (line 43) | def test_match(output):
  function test_get_new_command (line 51) | def test_get_new_command():

FILE: tests/rules/test_django_south_merge.py
  function output (line 7) | def output():
  function test_match (line 33) | def test_match(output):
  function test_get_new_command (line 41) | def test_get_new_command():

FILE: tests/rules/test_dnf_no_such_command.py
  function invalid_command (line 145) | def invalid_command(command):
  function test_match (line 155) | def test_match(output):
  function test_not_match (line 163) | def test_not_match(script, output):
  function set_help (line 168) | def set_help(mocker):
  function test_get_operations (line 177) | def test_get_operations(set_help):
  function test_get_new_command (line 188) | def test_get_new_command(set_help, output, script, result):

FILE: tests/rules/test_docker_image_being_used_by_container.py
  function test_match (line 5) | def test_match():
  function test_not_match (line 10) | def test_not_match():
  function test_not_docker_command (line 15) | def test_not_docker_command():
  function test_get_new_command (line 20) | def test_get_new_command():

FILE: tests/rules/test_docker_login.py
  function test_match (line 5) | def test_match():
  function test_get_new_command (line 35) | def test_get_new_command():

FILE: tests/rules/test_docker_not_command.py
  function docker_help (line 48) | def docker_help(mocker):
  function docker_help_new (line 148) | def docker_help_new(mocker):
  function output (line 235) | def output(cmd):
  function test_match (line 240) | def test_match():
  function test_match_management_cmd (line 249) | def test_match_management_cmd(script, output):
  function test_match_management_subcmd (line 258) | def test_match_management_subcmd(script, output):
  function test_not_match (line 265) | def test_not_match(script, output):
  function test_get_new_command (line 273) | def test_get_new_command(wrong, fixed):
  function test_get_new_management_command (line 282) | def test_get_new_management_command(wrong, fixed):
  function test_get_new_management_command_subcommand (line 291) | def test_get_new_management_command_subcommand(wrong, fixed, output):

FILE: tests/rules/test_dry.py
  function test_match (line 9) | def test_match(command):
  function test_get_new_command (line 16) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_fab_command_not_found.py
  function test_match (line 26) | def test_match(command):
  function test_not_match (line 33) | def test_not_match(command):
  function test_get_new_command (line 46) | def test_get_new_command(script, result):

FILE: tests/rules/test_fix_alt_space.py
  function test_match (line 7) | def test_match():
  function test_get_new_command (line 19) | def test_get_new_command():

FILE: tests/rules/test_fix_file.py
  function test_match (line 177) | def test_match(mocker, monkeypatch, test):
  function test_no_editor (line 185) | def test_no_editor(mocker, monkeypatch, test):
  function test_not_file (line 195) | def test_not_file(mocker, monkeypatch, test):
  function test_get_new_command (line 204) | def test_get_new_command(mocker, monkeypatch, test):
  function test_get_new_command_with_settings (line 211) | def test_get_new_command_with_settings(mocker, monkeypatch, test, settin...

FILE: tests/rules/test_gem_unknown_command.py
  function gem_help_commands (line 57) | def gem_help_commands(mocker):
  function test_match (line 66) | def test_match(script, command):
  function test_not_match (line 73) | def test_not_match(script, output):
  function test_get_new_command (line 80) | def test_get_new_command(script, output, result):

FILE: tests/rules/test_git_add.py
  function path_exists (line 7) | def path_exists(mocker):
  function output (line 13) | def output(target):
  function test_match (line 21) | def test_match(output, script, target):
  function test_not_match (line 29) | def test_not_match(path_exists, output, script, target, exists):
  function test_get_new_command (line 39) | def test_get_new_command(output, script, target, new_command):

FILE: tests/rules/test_git_add_force.py
  function output (line 7) | def output():
  function test_match (line 15) | def test_match(output):
  function test_get_new_command (line 20) | def test_get_new_command(output):

FILE: tests/rules/test_git_bisect_usage.py
  function output (line 7) | def output():
  function test_match (line 14) | def test_match(output, script):
  function test_not_match (line 20) | def test_not_match(script):
  function test_get_new_command (line 28) | def test_get_new_command(output, script, new_cmd):

FILE: tests/rules/test_git_branch_0flag.py
  function output_branch_exists (line 8) | def output_branch_exists():
  function test_match (line 24) | def test_match(script, output_branch_exists):
  function test_not_match (line 38) | def test_not_match(script, output_branch_exists):
  function test_get_new_command_branch_exists (line 53) | def test_get_new_command_branch_exists(script, output_branch_exists, new...
  function output_not_valid_object (line 58) | def output_not_valid_object():
  function test_get_new_command_not_valid_object (line 69) | def test_get_new_command_not_valid_object(script, output_not_valid_objec...

FILE: tests/rules/test_git_branch_delete.py
  function output (line 7) | def output():
  function test_match (line 14) | def test_match(output):
  function test_get_new_command (line 20) | def test_get_new_command(output):

FILE: tests/rules/test_git_branch_delete_checked_out.py
  function output (line 7) | def output():
  function test_match (line 12) | def test_match(script, output):
  function test_not_match (line 17) | def test_not_match(script):
  function test_get_new_command (line 28) | def test_get_new_command(script, new_command, output):

FILE: tests/rules/test_git_branch_exists.py
  function output (line 7) | def output(src_branch_name):
  function new_command (line 12) | def new_command(branch_name):
  function test_match (line 24) | def test_match(output, script, branch_name):
  function test_not_match (line 32) | def test_not_match(script):
  function test_get_new_command (line 40) | def test_get_new_command(output, new_command, script, src_branch_name, b...

FILE: tests/rules/test_git_branch_list.py
  function test_match (line 6) | def test_match():
  function test_not_match (line 10) | def test_not_match():
  function test_get_new_command (line 17) | def test_get_new_command():

FILE: tests/rules/test_git_checkout.py
  function did_not_match (line 7) | def did_not_match(target, did_you_forget=False):
  function git_branch (line 16) | def git_branch(mocker, branches):
  function test_match (line 25) | def test_match(command):
  function test_not_match (line 34) | def test_not_match(command):
  function test_get_branches (line 51) | def test_get_branches(branches, branch_list, git_branch):
  function test_get_new_command (line 71) | def test_get_new_command(branches, command, new_command, git_branch):

FILE: tests/rules/test_git_clone_git_clone.py
  function test_match (line 12) | def test_match():
  function test_not_match (line 16) | def test_not_match():
  function test_get_new_command (line 23) | def test_get_new_command():

FILE: tests/rules/test_git_clone_missing.py
  function test_match (line 33) | def test_match(cmd, output):
  function test_not_match (line 40) | def test_not_match(cmd, output):
  function test_get_new_command (line 47) | def test_get_new_command(script, output):

FILE: tests/rules/test_git_commit_add.py
  function test_match (line 13) | def test_match(output, script):
  function test_not_match (line 26) | def test_not_match(output, script):
  function test_get_new_command (line 37) | def test_get_new_command(script, new_command):

FILE: tests/rules/test_git_commit_amend.py
  function test_match (line 9) | def test_match(output, script):
  function test_not_match (line 17) | def test_not_match(script):
  function test_get_new_command (line 24) | def test_get_new_command(script):

FILE: tests/rules/test_git_commit_reset.py
  function test_match (line 9) | def test_match(output, script):
  function test_not_match (line 17) | def test_not_match(script):
  function test_get_new_command (line 24) | def test_get_new_command(script):

FILE: tests/rules/test_git_diff_no_index.py
  function test_match (line 8) | def test_match(command):
  function test_not_match (line 16) | def test_not_match(command):
  function test_get_new_command (line 22) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_git_diff_staged.py
  function test_match (line 9) | def test_match(command):
  function test_not_match (line 18) | def test_not_match(command):
  function test_get_new_command (line 25) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_git_fix_stash.py
  function test_match (line 22) | def test_match(wrong):
  function test_not_match (line 26) | def test_not_match():
  function test_get_new_command (line 34) | def test_get_new_command(wrong, fixed):

FILE: tests/rules/test_git_flag_after_filename.py
  function test_match (line 21) | def test_match(command):
  function test_not_match (line 28) | def test_not_match(command):
  function test_get_new_command (line 39) | def test_get_new_command(command, result):

FILE: tests/rules/test_git_help_aliased.py
  function test_match (line 9) | def test_match(script, output):
  function test_not_match (line 16) | def test_not_match(script, output):
  function test_get_new_command (line 23) | def test_get_new_command(script, output, new_command):

FILE: tests/rules/test_git_hook_bypass.py
  function test_match (line 16) | def test_match(command):
  function test_not_match (line 28) | def test_not_match(command):
  function test_get_new_command (line 42) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_git_lfs_mistype.py
  function mistype_response (line 8) | def mistype_response():
  function test_match (line 20) | def test_match(mistype_response):
  function test_get_new_command (line 27) | def test_get_new_command(mistype_response):

FILE: tests/rules/test_git_main_master.py
  function output (line 7) | def output(branch_name):
  function test_match (line 22) | def test_match(script, branch_name, output):
  function test_not_match (line 34) | def test_not_match(script, branch_name, output):
  function test_get_new_command (line 46) | def test_get_new_command(script, branch_name, new_command, output):

FILE: tests/rules/test_git_merge.py
  function test_match (line 10) | def test_match():
  function test_get_new_command (line 23) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_git_merge_unrelated.py
  function test_match (line 9) | def test_match():
  function test_get_new_command (line 22) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_git_not_command.py
  function git_not_command (line 7) | def git_not_command():
  function git_not_command_one_of_this (line 16) | def git_not_command_one_of_this():
  function git_not_command_closest (line 29) | def git_not_command_closest():
  function git_command (line 39) | def git_command():
  function test_match (line 43) | def test_match(git_not_command, git_command, git_not_command_one_of_this):
  function test_get_new_command (line 50) | def test_get_new_command(git_not_command, git_not_command_one_of_this,

FILE: tests/rules/test_git_pull.py
  function output (line 7) | def output():
  function test_match (line 21) | def test_match(output):
  function test_get_new_command (line 27) | def test_get_new_command(output):

FILE: tests/rules/test_git_pull_clone.py
  function test_match (line 14) | def test_match(command):
  function test_get_new_command (line 20) | def test_get_new_command(command, output):

FILE: tests/rules/test_git_pull_uncommitted_changes.py
  function output (line 7) | def output():
  function test_match (line 11) | def test_match(output):
  function test_get_new_command (line 17) | def test_get_new_command(output):

FILE: tests/rules/test_git_pull_unstaged_changes.py
  function output (line 7) | def output():
  function test_match (line 11) | def test_match(output):
  function test_get_new_command (line 17) | def test_get_new_command(output):

FILE: tests/rules/test_git_push.py
  function output (line 7) | def output(branch_name):
  function output_bitbucket (line 19) | def output_bitbucket():
  function test_match (line 34) | def test_match(output, script, branch_name):
  function test_match_bitbucket (line 38) | def test_match_bitbucket(output_bitbucket):
  function test_not_match (line 45) | def test_not_match(output, script, branch_name):
  function test_get_new_command (line 74) | def test_get_new_command(output, script, branch_name, new_command):

FILE: tests/rules/test_git_push_different_branch_names.py
  function error_msg (line 20) | def error_msg(localbranch, remotebranch):
  function test_match (line 24) | def test_match():
  function test_not_match (line 33) | def test_not_match(command):
  function test_get_new_command (line 37) | def test_get_new_command():

FILE: tests/rules/test_git_push_force.py
  function test_match (line 32) | def test_match(command):
  function test_not_match (line 43) | def test_not_match(command):
  function test_get_new_command (line 51) | def test_get_new_command(command, output):

FILE: tests/rules/test_git_push_pull.py
  function test_match (line 46) | def test_match(command):
  function test_not_match (line 57) | def test_not_match(command):
  function test_get_new_command (line 72) | def test_get_new_command(command, output):

FILE: tests/rules/test_git_push_without_commits.py
  function test_match (line 5) | def test_match():
  function test_not_match (line 11) | def test_not_match():
  function test_get_new_command (line 16) | def test_get_new_command():

FILE: tests/rules/test_git_rebase_merge_dir.py
  function output (line 7) | def output():
  function test_match (line 22) | def test_match(output, script):
  function test_not_match (line 27) | def test_not_match(script):
  function test_get_new_command (line 41) | def test_get_new_command(output, script, result):

FILE: tests/rules/test_git_rebase_no_changes.py
  function output (line 7) | def output():
  function test_match (line 20) | def test_match(output):
  function test_get_new_command (line 26) | def test_get_new_command(output):

FILE: tests/rules/test_git_remote_delete.py
  function test_match (line 6) | def test_match():
  function test_not_match (line 15) | def test_not_match(command):
  function test_get_new_command (line 23) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_git_remote_seturl_add.py
  function test_match (line 8) | def test_match(command):
  function test_not_match (line 18) | def test_not_match(command):
  function test_get_new_command (line 25) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_git_rm_local_modifications.py
  function output (line 7) | def output(target):
  function test_match (line 15) | def test_match(output, script, target):
  function test_not_match (line 20) | def test_not_match(script):
  function test_get_new_command (line 27) | def test_get_new_command(output, script, target, new_command):

FILE: tests/rules/test_git_rm_recursive.py
  function output (line 7) | def output(target):
  function test_match (line 14) | def test_match(output, script, target):
  function test_not_match (line 19) | def test_not_match(script):
  function test_get_new_command (line 26) | def test_get_new_command(output, script, target, new_command):

FILE: tests/rules/test_git_rm_staged.py
  function output (line 7) | def output(target):
  function test_match (line 15) | def test_match(output, script, target):
  function test_not_match (line 20) | def test_not_match(script):
  function test_get_new_command (line 27) | def test_get_new_command(output, script, target, new_command):

FILE: tests/rules/test_git_stash.py
  function test_match (line 20) | def test_match(command):
  function test_not_match (line 27) | def test_not_match(command):
  function test_get_new_command (line 36) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_git_stash_pop.py
  function output (line 7) | def output():
  function test_match (line 11) | def test_match(output):
  function test_get_new_command (line 16) | def test_get_new_command(output):

FILE: tests/rules/test_git_tag_force.py
  function output (line 7) | def output():
  function test_match (line 11) | def test_match(output):
  function test_get_new_command (line 16) | def test_get_new_command(output):

FILE: tests/rules/test_git_two_dashes.py
  function test_match (line 15) | def test_match(command):
  function test_not_match (line 25) | def test_not_match(command):
  function test_get_new_command (line 44) | def test_get_new_command(command, output):

FILE: tests/rules/test_go_run.py
  function test_match (line 9) | def test_match(command):
  function test_get_new_command (line 16) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_go_unknown_command.py
  function build_misspelled_output (line 8) | def build_misspelled_output():
  function go_stderr (line 14) | def go_stderr(mocker):
  function test_match (line 72) | def test_match(build_misspelled_output):
  function test_not_match (line 76) | def test_not_match():
  function test_get_new_command (line 81) | def test_get_new_command(build_misspelled_output):

FILE: tests/rules/test_gradle_not_task.py
  function tasks (line 124) | def tasks(mocker):
  function test_match (line 135) | def test_match(command):
  function test_not_match (line 144) | def test_not_match(command):
  function test_get_new_command (line 157) | def test_get_new_command(command, result):

FILE: tests/rules/test_gradle_wrapper.py
  function exists (line 7) | def exists(mocker):
  function test_match (line 15) | def test_match(mocker, command):
  function test_not_match (line 25) | def test_not_match(mocker, exists, command, gradlew, which):
  function test_get_new_command (line 36) | def test_get_new_command(script, result):

FILE: tests/rules/test_grep_arguments_order.py
  function os_path (line 9) | def os_path(monkeypatch):
  function test_match (line 18) | def test_match(script, file):
  function test_not_match (line 28) | def test_not_match(script, output):
  function test_get_new_command (line 39) | def test_get_new_command(script, output, result):

FILE: tests/rules/test_grep_recursive.py
  function test_match (line 7) | def test_match():
  function test_get_new_command (line 13) | def test_get_new_command():

FILE: tests/rules/test_grunt_task_not_found.py
  function grunt_help (line 103) | def grunt_help(mocker):
  function test_match (line 112) | def test_match(command):
  function test_not_match (line 119) | def test_not_match(command):
  function test_get_new_command (line 128) | def test_get_new_command(command, result):

FILE: tests/rules/test_gulp_not_task.py
  function output (line 7) | def output(task):
  function test_match (line 14) | def test_match():
  function test_not_march (line 21) | def test_not_march(script, stdout):
  function test_get_new_command (line 25) | def test_get_new_command(mocker):

FILE: tests/rules/test_has_exists_script.py
  function test_match (line 6) | def test_match():
  function test_get_new_command (line 17) | def test_get_new_command():

FILE: tests/rules/test_heroku_multiple_apps.py
  function test_match (line 40) | def test_match(cmd):
  function test_not_match (line 47) | def test_not_match(script, output):
  function test_get_new_command (line 53) | def test_get_new_command(cmd, result):

FILE: tests/rules/test_heroku_not_command.py
  function test_match (line 16) | def test_match(cmd):
  function test_not_match (line 23) | def test_not_match(script, output):
  function test_get_new_command (line 29) | def test_get_new_command(cmd, result):

FILE: tests/rules/test_history.py
  function history_without_current (line 7) | def history_without_current(mocker):
  function test_match (line 14) | def test_match(script):
  function test_not_match (line 19) | def test_not_match(script):
  function test_get_new_command (line 26) | def test_get_new_command(script, result):

FILE: tests/rules/test_hostscli.py
  function test_match (line 19) | def test_match(command):
  function test_get_new_command (line 26) | def test_get_new_command(command, result):

FILE: tests/rules/test_ifconfig_device_not_found.py
  function ifconfig (line 22) | def ifconfig(mocker):
  function test_match (line 33) | def test_match(script, output):
  function test_not_match (line 42) | def test_not_match(script, output):
  function test_get_new_comman (line 50) | def test_get_new_comman(script, result):

FILE: tests/rules/test_java.py
  function test_match (line 9) | def test_match(command):
  function test_get_new_command (line 16) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_javac.py
  function test_match (line 9) | def test_match(command):
  function test_get_new_command (line 16) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_lein_not_task.py
  function is_not_task (line 7) | def is_not_task():
  function test_match (line 16) | def test_match(is_not_task):
  function test_get_new_command (line 21) | def test_get_new_command(is_not_task):

FILE: tests/rules/test_ln_no_hard_link.py
  function test_match (line 13) | def test_match(script, output):
  function test_not_match (line 23) | def test_not_match(script, output):
  function test_get_new_command (line 35) | def test_get_new_command(script, result):

FILE: tests/rules/test_ln_s_order.py
  function file_exists (line 7) | def file_exists(mocker):
  function test_not_match (line 19) | def test_not_match(file_exists, script, output, exists):
  function test_match (line 29) | def test_match(script, result):

FILE: tests/rules/test_long_form_help.py
  function test_match (line 8) | def test_match(output):
  function test_not_match (line 12) | def test_not_match():
  function test_get_new_command (line 21) | def test_get_new_command(before, after):

FILE: tests/rules/test_ls_all.py
  function test_match (line 5) | def test_match():
  function test_get_new_command (line 10) | def test_get_new_command():

FILE: tests/rules/test_ls_lah.py
  function test_match (line 5) | def test_match():
  function test_get_new_command (line 14) | def test_get_new_command():

FILE: tests/rules/test_man.py
  function test_match (line 14) | def test_match(command):
  function test_not_match (line 21) | def test_not_match(command):
  function test_get_new_command (line 34) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_man_no_space.py
  function test_match (line 5) | def test_match():
  function test_get_new_command (line 10) | def test_get_new_command():

FILE: tests/rules/test_mercurial.py
  function test_match (line 39) | def test_match(command):
  function test_not_match (line 65) | def test_not_match(command):
  function test_extract_possibilities (line 99) | def test_extract_possibilities(command, possibilities):
  function test_get_new_command (line 133) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_missing_space_before_subcommand.py
  function all_executables (line 8) | def all_executables(mocker):
  function test_match (line 16) | def test_match(script):
  function test_not_match (line 21) | def test_not_match(script):
  function test_get_new_command (line 30) | def test_get_new_command(script, result):

FILE: tests/rules/test_mkdir_p.py
  function test_match (line 11) | def test_match(command):
  function test_not_match (line 22) | def test_not_match(command):
  function test_get_new_command (line 31) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_mvn_no_command.py
  function test_match (line 8) | def test_match(command):
  function test_not_match (line 32) | def test_not_match(command):
  function test_get_new_command (line 39) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_mvn_unknown_lifecycle_phase.py
  function test_match (line 8) | def test_match(command):
  function test_not_match (line 32) | def test_not_match(command):
  function test_get_new_command (line 39) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_nixos_cmd_not_found.py
  function test_match (line 8) | def test_match(mocker, command):
  function test_not_match (line 16) | def test_not_match(mocker, command):
  function test_get_new_command (line 24) | def test_get_new_command(mocker, command, new_command):

FILE: tests/rules/test_no_command.py
  function get_all_executables (line 7) | def get_all_executables(mocker):
  function history_without_current (line 13) | def history_without_current(mocker):
  function test_match (line 26) | def test_match(mocker, script, output):
  function test_not_match (line 37) | def test_not_match(mocker, script, output, which):
  function test_get_new_command (line 49) | def test_get_new_command(script, result):

FILE: tests/rules/test_no_such_file.py
  function test_match (line 10) | def test_match(command):
  function test_not_match (line 18) | def test_not_match(command):
  function test_get_new_command (line 26) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_npm_missing_script.py
  function run_script (line 38) | def run_script(mocker):
  function test_match (line 48) | def test_match(command):
  function test_not_match (line 56) | def test_not_match(command):
  function test_get_new_command (line 66) | def test_get_new_command(script, output, result):

FILE: tests/rules/test_npm_run_script.py
  function run_script (line 51) | def run_script(mocker):
  function test_match (line 60) | def test_match(script):
  function test_not_match (line 71) | def test_not_match(run_script, command, run_script_out):
  function test_get_new_command (line 82) | def test_get_new_command(script, result):

FILE: tests/rules/test_npm_wrong_command.py
  function test_match (line 40) | def test_match(script):
  function test_not_match (line 49) | def test_not_match(script, output):
  function test_get_new_command (line 57) | def test_get_new_command(script, result):

FILE: tests/rules/test_omnienv_no_such_command.py
  function output (line 8) | def output(pyenv_cmd):
  function Popen (line 13) | def Popen(mocker):
  function test_match (line 32) | def test_match(script, pyenv_cmd, output):
  function test_match_goenv_output_quote (line 36) | def test_match_goenv_output_quote():
  function test_not_match (line 46) | def test_not_match(script, output):
  function test_get_new_command (line 56) | def test_get_new_command(script, pyenv_cmd, output, result):

FILE: tests/rules/test_open.py
  function output (line 7) | def output(script):
  function test_is_arg_url (line 22) | def test_is_arg_url(script):
  function test_not_is_arg_url (line 27) | def test_not_is_arg_url(script):
  function test_match (line 37) | def test_match(script, output):
  function test_get_new_command (line 48) | def test_get_new_command(script, new_command, output):

FILE: tests/rules/test_pacman.py
  function test_match (line 25) | def test_match(command):
  function test_match_mocked (line 34) | def test_match_mocked(subp_mock, command, return_value):
  function test_not_match (line 42) | def test_not_match(command):
  function test_get_new_command (line 68) | def test_get_new_command(command, new_command, mocker):
  function test_get_new_command_mocked (line 80) | def test_get_new_command_mocked(subp_mock, command, new_command, return_...

FILE: tests/rules/test_pacman_invalid_option.py
  function test_not_match_good_output (line 13) | def test_not_match_good_output(option):
  function test_not_match_bad_output (line 18) | def test_not_match_bad_output(option):
  function test_match (line 23) | def test_match(option):
  function test_get_new_command (line 28) | def test_get_new_command(option):

FILE: tests/rules/test_pacman_not_found.py
  function test_match (line 19) | def test_match(command):
  function test_match_mocked (line 30) | def test_match_mocked(subp_mock, command):
  function test_get_new_command (line 43) | def test_get_new_command(command, fixed):
  function test_get_new_command_mocked (line 54) | def test_get_new_command_mocked(subp_mock, command, fixed):

FILE: tests/rules/test_path_from_history.py
  function history (line 7) | def history(mocker):
  function path_exists (line 14) | def path_exists(mocker):
  function test_match (line 25) | def test_match(script, output):
  function test_not_match (line 33) | def test_not_match(script, output):
  function test_get_new_command (line 41) | def test_get_new_command(script, output, result):

FILE: tests/rules/test_php_s.py
  function test_match (line 10) | def test_match(command):
  function test_not_match (line 18) | def test_not_match(command):
  function test_get_new_command (line 26) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_pip_install.py
  function test_match (line 6) | def test_match():
  function test_get_new_command (line 24) | def test_get_new_command():

FILE: tests/rules/test_pip_unknown_command.py
  function pip_unknown_cmd_without_recommend (line 7) | def pip_unknown_cmd_without_recommend():
  function broken (line 12) | def broken():
  function suggested (line 17) | def suggested():
  function pip_unknown_cmd (line 22) | def pip_unknown_cmd(broken, suggested):
  function test_match (line 26) | def test_match(pip_unknown_cmd, pip_unknown_cmd_without_recommend):
  function test_get_new_command (line 35) | def test_get_new_command(script, new_cmd, pip_unknown_cmd):

FILE: tests/rules/test_port_already_in_use.py
  function lsof (line 70) | def lsof(mocker):
  function test_match (line 81) | def test_match(command):
  function test_not_match (line 90) | def test_not_match(lsof, command, lsof_output):
  function test_get_new_command (line 100) | def test_get_new_command(command):

FILE: tests/rules/test_prove_recursively.py
  function isdir (line 11) | def isdir(mocker):
  function test_match (line 19) | def test_match(isdir, script, output):
  function test_not_match (line 29) | def test_not_match(isdir, script, output, isdir_result):
  function test_get_new_command (line 38) | def test_get_new_command(before, after):

FILE: tests/rules/test_python_command.py
  function test_match (line 5) | def test_match():
  function test_get_new_command (line 10) | def test_get_new_command():

FILE: tests/rules/test_python_execute.py
  function test_match (line 9) | def test_match(command):
  function test_get_new_command (line 16) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_python_module_error.py
  function module_error_output (line 8) | def module_error_output(filename, module_name):
  function test_not_match (line 30) | def test_not_match(test):
  function test_match (line 53) | def test_match(script, filename, module_name, corrected_script, module_e...
  function test_get_new_command (line 60) | def test_get_new_command(

FILE: tests/rules/test_quotation_marks.py
  function test_match (line 10) | def test_match(command):
  function test_get_new_command (line 18) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_rails_migrations_pending.py
  function test_match (line 24) | def test_match(command):
  function test_not_match (line 34) | def test_not_match(command):
  function test_get_new_command (line 45) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_react_native_command_unrecognized.py
  function test_match (line 43) | def test_match(command):
  function test_not_match (line 50) | def test_not_match(command):
  function test_get_new_command (line 59) | def test_get_new_command(mocker, command, result):

FILE: tests/rules/test_remove_shell_prompt_literal.py
  function output (line 7) | def output():
  function test_match (line 20) | def test_match(script, output):
  function test_not_match (line 34) | def test_not_match(command):
  function test_get_new_command (line 47) | def test_get_new_command(script, new_command, output):

FILE: tests/rules/test_remove_trailing_cedilla.py
  function test_match (line 9) | def test_match(command):
  function test_get_new_command (line 16) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_rm_dir.py
  function test_match (line 12) | def test_match(command):
  function test_not_match (line 22) | def test_not_match(command):
  function test_get_new_command (line 30) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_rm_root.py
  function test_match (line 6) | def test_match():
  function test_not_match (line 14) | def test_not_match(command):
  function test_get_new_command (line 18) | def test_get_new_command():

FILE: tests/rules/test_scm_correction.py
  function get_actual_scm_mock (line 7) | def get_actual_scm_mock(mocker):
  function test_match (line 19) | def test_match(get_actual_scm_mock, script, output, actual_scm):
  function test_not_match (line 35) | def test_not_match(get_actual_scm_mock, script, output, actual_scm):
  function test_get_new_command (line 43) | def test_get_new_command(get_actual_scm_mock, script, actual_scm, result):

FILE: tests/rules/test_sed_unterminated_s.py
  function sed_unterminated_s (line 7) | def sed_unterminated_s():
  function test_match (line 11) | def test_match(sed_unterminated_s):
  function test_get_new_command (line 20) | def test_get_new_command(sed_unterminated_s):

FILE: tests/rules/test_sl_ls.py
  function test_match (line 6) | def test_match():
  function test_get_new_command (line 11) | def test_get_new_command():

FILE: tests/rules/test_ssh_known_host.py
  function ssh_error (line 9) | def ssh_error(tmpdir):
  function test_match (line 44) | def test_match(ssh_error):
  function test_side_effect (line 56) | def test_side_effect(ssh_error):
  function test_get_new_command (line 64) | def test_get_new_command(ssh_error, monkeypatch):

FILE: tests/rules/test_sudo.py
  function test_match (line 19) | def test_match(output):
  function test_not_match (line 23) | def test_not_match():
  function test_get_new_command (line 33) | def test_get_new_command(before, after):

FILE: tests/rules/test_sudo_command_from_user_path.py
  function which (line 10) | def which(mocker):
  function test_match (line 18) | def test_match(script, output):
  function test_not_match (line 26) | def test_not_match(which, script, output, which_result):
  function test_get_new_command (line 38) | def test_get_new_command(script, output, result):

FILE: tests/rules/test_switch_lang.py
  function test_match (line 15) | def test_match(command):
  function test_not_match (line 26) | def test_not_match(command):
  function test_get_new_command (line 38) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_systemctl.py
  function test_match (line 5) | def test_match():
  function test_get_new_command (line 15) | def test_get_new_command():

FILE: tests/rules/test_terraform_init.py
  function test_match (line 15) | def test_match(script, output):
  function test_not_match (line 24) | def test_not_match(script, output):
  function test_get_new_command (line 32) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_terraform_no_command.py
  function test_match (line 9) | def test_match(script, output):
  function test_not_match (line 18) | def test_not_match(script, output):
  function test_get_new_command (line 26) | def test_get_new_command(script, output, new_command):

FILE: tests/rules/test_tmux.py
  function tmux_ambiguous (line 7) | def tmux_ambiguous():
  function test_match (line 13) | def test_match(tmux_ambiguous):
  function test_get_new_command (line 17) | def test_get_new_command(tmux_ambiguous):

FILE: tests/rules/test_touch.py
  function output (line 6) | def output(is_bsd):
  function test_match (line 15) | def test_match(script, is_bsd):
  function test_not_match (line 23) | def test_not_match(command):
  function test_get_new_command (line 30) | def test_get_new_command(script, is_bsd):

FILE: tests/rules/test_tsuru_login.py
  function test_match (line 17) | def test_match(command):
  function test_not_match (line 26) | def test_not_match(command):
  function test_get_new_command (line 36) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_tsuru_not_command.py
  function test_match (line 32) | def test_match(command):
  function test_not_match (line 60) | def test_not_match(command):
  function test_get_new_command (line 89) | def test_get_new_command(command, new_commands):

FILE: tests/rules/test_unknown_command.py
  function test_match (line 11) | def test_match(command):
  function test_not_match (line 20) | def test_not_match(command):
  function test_get_new_command (line 33) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_unsudo.py
  function test_match (line 8) | def test_match(output):
  function test_not_match (line 12) | def test_not_match():
  function test_get_new_command (line 21) | def test_get_new_command(before, after):

FILE: tests/rules/test_vagrant_up.py
  function test_match (line 13) | def test_match(command):
  function test_not_match (line 22) | def test_not_match(command):
  function test_get_new_command (line 33) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_whois.py
  function test_match (line 10) | def test_match(command):
  function test_not_match (line 14) | def test_not_match():
  function test_get_new_command (line 28) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_workon_doesnt_exists.py
  function envs (line 7) | def envs(mocker):
  function test_match (line 15) | def test_match(script):
  function test_not_match (line 21) | def test_not_match(script):
  function test_get_new_command (line 29) | def test_get_new_command(script, result):

FILE: tests/rules/test_wrong_hyphen_before_subcommand.py
  function get_all_executables (line 8) | def get_all_executables(mocker):
  function test_match (line 16) | def test_match(script):
  function test_not_match (line 21) | def test_not_match(script):
  function test_get_new_command (line 29) | def test_get_new_command(script, new_command):

FILE: tests/rules/test_yarn_alias.py
  function test_match (line 15) | def test_match(command):
  function test_get_new_command (line 23) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_yarn_command_not_found.py
  function yarn_help (line 89) | def yarn_help(mocker):
  function test_match (line 97) | def test_match(command):
  function test_not_match (line 104) | def test_not_match(command):
  function test_get_new_command (line 113) | def test_get_new_command(command, result):

FILE: tests/rules/test_yarn_command_replaced.py
  function test_match (line 14) | def test_match(command):
  function test_not_match (line 20) | def test_not_match(command):
  function test_get_new_command (line 31) | def test_get_new_command(command, new_command):

FILE: tests/rules/test_yarn_help.py
  function test_match (line 49) | def test_match(command):
  function test_get_new_command (line 56) | def test_get_new_command(command, url):

FILE: tests/rules/test_yum_invalid_operation.py
  function test_match (line 139) | def test_match(command):
  function test_not_match (line 150) | def test_not_match(command, output):
  function yum_help (line 155) | def yum_help(mocker):
  function test_get_operations (line 162) | def test_get_operations():
  function test_get_new_command (line 172) | def test_get_new_command(script, output, result):

FILE: tests/shells/conftest.py
  function builtins_open (line 5) | def builtins_open(mocker):
  function isfile (line 10) | def isfile(mocker):
  function history_lines (line 16) | def history_lines(mocker):
  function config_exists (line 26) | def config_exists(mocker):

FILE: tests/shells/test_bash.py
  class TestBash (line 9) | class TestBash(object):
    method shell (line 11) | def shell(self):
    method Popen (line 15) | def Popen(self, mocker):
    method shell_aliases (line 20) | def shell_aliases(self):
    method test_from_shell (line 32) | def test_from_shell(self, before, after, shell):
    method test_to_shell (line 35) | def test_to_shell(self, shell):
    method test_and_ (line 38) | def test_and_(self, shell):
    method test_or_ (line 41) | def test_or_(self, shell):
    method test_get_aliases (line 44) | def test_get_aliases(self, shell):
    method test_app_alias (line 50) | def test_app_alias(self, shell):
    method test_app_alias_variables_correctly_set (line 56) | def test_app_alias_variables_correctly_set(self, shell):
    method test_get_history (line 64) | def test_get_history(self, history_lines, shell):
    method test_split_command (line 68) | def test_split_command(self, shell):
    method test_how_to_configure (line 73) | def test_how_to_configure(self, shell, config_exists):
    method test_how_to_configure_when_config_not_found (line 77) | def test_how_to_configure_when_config_not_found(self, shell,
    method test_info (line 82) | def test_info(self, shell, Popen):
    method test_get_version_error (line 86) | def test_get_version_error(self, shell, Popen):

FILE: tests/shells/test_fish.py
  class TestFish (line 9) | class TestFish(object):
    method shell (line 11) | def shell(self):
    method Popen (line 15) | def Popen(self, mocker):
    method test_get_overridden_aliases (line 30) | def test_get_overridden_aliases(self, shell, os_environ, key, value):
    method test_from_shell (line 51) | def test_from_shell(self, before, after, shell):
    method test_to_shell (line 54) | def test_to_shell(self, shell):
    method test_and_ (line 57) | def test_and_(self, shell):
    method test_or_ (line 60) | def test_or_(self, shell):
    method test_get_aliases (line 63) | def test_get_aliases(self, shell):
    method test_app_alias (line 79) | def test_app_alias(self, shell):
    method test_app_alias_alter_history (line 88) | def test_app_alias_alter_history(self, settings, shell):
    method test_get_history (line 99) | def test_get_history(self, history_lines, shell):
    method test_put_to_history (line 107) | def test_put_to_history(self, entry, entry_utf8, builtins_open, mocker...
    method test_how_to_configure (line 113) | def test_how_to_configure(self, shell, config_exists):
    method test_how_to_configure_when_config_not_found (line 117) | def test_how_to_configure_when_config_not_found(self, shell,
    method test_get_version (line 122) | def test_get_version(self, shell, Popen):
    method test_get_version_error (line 131) | def test_get_version_error(self, side_effect, exception, shell, Popen):

FILE: tests/shells/test_generic.py
  class TestGeneric (line 7) | class TestGeneric(object):
    method shell (line 9) | def shell(self):
    method test_from_shell (line 12) | def test_from_shell(self, shell):
    method test_to_shell (line 15) | def test_to_shell(self, shell):
    method test_and_ (line 18) | def test_and_(self, shell):
    method test_or_ (line 21) | def test_or_(self, shell):
    method test_get_aliases (line 24) | def test_get_aliases(self, shell):
    method test_app_alias (line 27) | def test_app_alias(self, shell):
    method test_get_history (line 34) | def test_get_history(self, history_lines, shell):
    method test_split_command (line 40) | def test_split_command(self, shell):
    method test_how_to_configure (line 44) | def test_how_to_configure(self, shell):
    method test_info (line 51) | def test_info(self, side_effect, expected_info, warn, shell, mocker):

FILE: tests/shells/test_powershell.py
  class TestPowershell (line 8) | class TestPowershell(object):
    method shell (line 10) | def shell(self):
    method Popen (line 14) | def Popen(self, mocker):
    method test_and_ (line 18) | def test_and_(self, shell):
    method test_app_alias (line 21) | def test_app_alias(self, shell):
    method test_how_to_configure (line 26) | def test_how_to_configure(self, shell):
    method test_info (line 34) | def test_info(self, side_effect, expected_version, call_args, shell, P...
    method test_get_version_error (line 40) | def test_get_version_error(self, shell, Popen):

FILE: tests/shells/test_tcsh.py
  class TestTcsh (line 8) | class TestTcsh(object):
    method shell (line 10) | def shell(self):
    method Popen (line 14) | def Popen(self, mocker):
    method test_from_shell (line 28) | def test_from_shell(self, before, after, shell):
    method test_to_shell (line 31) | def test_to_shell(self, shell):
    method test_and_ (line 34) | def test_and_(self, shell):
    method test_or_ (line 37) | def test_or_(self, shell):
    method test_get_aliases (line 40) | def test_get_aliases(self, shell):
    method test_app_alias (line 46) | def test_app_alias(self, shell):
    method test_get_history (line 52) | def test_get_history(self, history_lines, shell):
    method test_how_to_configure (line 56) | def test_how_to_configure(self, shell, config_exists):
    method test_how_to_configure_when_config_not_found (line 60) | def test_how_to_configure_when_config_not_found(self, shell,
    method test_info (line 65) | def test_info(self, shell, Popen):
    method test_get_version_error (line 73) | def test_get_version_error(self, side_effect, exception, shell, Popen):

FILE: tests/shells/test_zsh.py
  class TestZsh (line 9) | class TestZsh(object):
    method shell (line 11) | def shell(self):
    method Popen (line 15) | def Popen(self, mocker):
    method shell_aliases (line 20) | def shell_aliases(self):
    method test_from_shell (line 31) | def test_from_shell(self, before, after, shell):
    method test_to_shell (line 34) | def test_to_shell(self, shell):
    method test_and_ (line 37) | def test_and_(self, shell):
    method test_or_ (line 40) | def test_or_(self, shell):
    method test_get_aliases (line 43) | def test_get_aliases(self, shell):
    method test_app_alias (line 50) | def test_app_alias(self, shell):
    method test_app_alias_variables_correctly_set (line 56) | def test_app_alias_variables_correctly_set(self, shell):
    method test_get_history (line 64) | def test_get_history(self, history_lines, shell):
    method test_how_to_configure (line 68) | def test_how_to_configure(self, shell, config_exists):
    method test_how_to_configure_when_config_not_found (line 72) | def test_how_to_configure_when_config_not_found(self, shell,
    method test_info (line 77) | def test_info(self, shell, Popen):
    method test_get_version_error (line 81) | def test_get_version_error(self, shell, Popen):

FILE: tests/specific/test_git.py
  function test_git_support (line 14) | def test_git_support(called, command, output):
  function test_git_support_match (line 31) | def test_git_support_match(command, is_git, output):

FILE: tests/specific/test_npm.py
  function test_get_scripts (line 23) | def test_get_scripts(mocker):

FILE: tests/specific/test_sudo.py
  function test_sudo_support (line 14) | def test_sudo_support(return_value, command, called, result):

FILE: tests/test_argument_parser.py
  function _args (line 6) | def _args(**override):
  function test_parse (line 35) | def test_parse(argv, result):

FILE: tests/test_conf.py
  function load_source (line 9) | def load_source(mocker):
  function test_settings_defaults (line 13) | def test_settings_defaults(load_source, settings):
  class TestSettingsFromFile (line 20) | class TestSettingsFromFile(object):
    method test_from_file (line 21) | def test_from_file(self, load_source, settings):
    method test_from_file_with_DEFAULT (line 36) | def test_from_file_with_DEFAULT(self, load_source, settings):
  class TestSettingsFromEnv (line 47) | class TestSettingsFromEnv(object):
    method test_from_env (line 48) | def test_from_env(self, os_environ, settings):
    method test_from_env_with_DEFAULT (line 71) | def test_from_env_with_DEFAULT(self, os_environ, settings):
  function test_settings_from_args (line 77) | def test_settings_from_args(settings):
  class TestInitializeSettingsFile (line 84) | class TestInitializeSettingsFile(object):
    method test_ignore_if_exists (line 85) | def test_ignore_if_exists(self, settings):
    method test_create_if_doesnt_exists (line 92) | def test_create_if_doesnt_exists(self, settings):
  function test_get_user_dir_path (line 114) | def test_get_user_dir_path(mocker, os_environ, settings, legacy_dir_exists,

FILE: tests/test_corrector.py
  function glob (line 12) | def glob(mocker):
  class TestGetRules (line 19) | class TestGetRules(object):
    method load_source (line 21) | def load_source(self, monkeypatch):
    method _compare_names (line 25) | def _compare_names(self, rules, names):
    method test_get_rules (line 33) | def test_get_rules(self, glob, settings, paths, conf_rules, exclude_ru...
  function test_get_rules_rule_exception (line 43) | def test_get_rules_rule_exception(mocker, glob):
  function test_get_corrected_commands (line 51) | def test_get_corrected_commands(mocker):
  function test_organize_commands (line 64) | def test_organize_commands():

FILE: tests/test_logs.py
  function test_color (line 5) | def test_color(settings):
  function test_debug (line 16) | def test_debug(capsys, settings, debug, stderr):

FILE: tests/test_readme.py
  function test_readme (line 1) | def test_readme(source_root):

FILE: tests/test_types.py
  class TestCorrectedCommand (line 14) | class TestCorrectedCommand(object):
    method test_equality (line 16) | def test_equality(self):
    method test_hashable (line 22) | def test_hashable(self):
    method test_representable (line 26) | def test_representable(self):
    method test_run (line 40) | def test_run(self, capsys, settings, script, printed, override_settings):
  class TestRule (line 47) | class TestRule(object):
    method test_from_path_rule_exception (line 48) | def test_from_path_rule_exception(self, mocker):
    method test_from_path (line 54) | def test_from_path(self, mocker):
    method test_from_path_excluded_rule (line 69) | def test_from_path_excluded_rule(self, mocker, settings):
    method test_is_enabled (line 83) | def test_is_enabled(self, settings, rules, rule, is_enabled):
    method test_isnt_match (line 87) | def test_isnt_match(self):
    method test_is_match (line 91) | def test_is_match(self):
    method test_isnt_match_when_rule_failed (line 96) | def test_isnt_match_when_rule_failed(self, capsys):
    method test_get_corrected_commands_with_rule_returns_list (line 102) | def test_get_corrected_commands_with_rule_returns_list(self):
    method test_get_corrected_commands_with_rule_returns_command (line 109) | def test_get_corrected_commands_with_rule_returns_command(self):
  class TestCommand (line 116) | class TestCommand(object):
    method Popen (line 118) | def Popen(self, monkeypatch):
    method prepare (line 125) | def prepare(self, monkeypatch):
    method test_from_script_calls (line 129) | def test_from_script_calls(self, Popen, settings, os_environ):
    method test_from_script (line 149) | def test_from_script(self, script, result):

FILE: tests/test_ui.py
  function patch_get_key (line 11) | def patch_get_key(monkeypatch):
  function test_read_actions (line 19) | def test_read_actions(patch_get_key):
  function test_command_selector (line 40) | def test_command_selector():
  class TestSelectCommand (line 54) | class TestSelectCommand(object):
    method commands_with_side_effect (line 56) | def commands_with_side_effect(self):
    method commands (line 61) | def commands(self):
    method test_without_commands (line 65) | def test_without_commands(self, capsys):
    method test_without_confirmation (line 69) | def test_without_confirmation(self, capsys, commands, settings):
    method test_without_confirmation_with_side_effects (line 74) | def test_without_confirmation_with_side_effects(
    method test_with_confirmation (line 81) | def test_with_confirmation(self, capsys, patch_get_key, commands):
    method test_with_confirmation_abort (line 87) | def test_with_confirmation_abort(self, capsys, patch_get_key, commands):
    method test_with_confirmation_with_side_effct (line 93) | def test_with_confirmation_with_side_effct(self, capsys, patch_get_key,
    method test_with_confirmation_select_second (line 101) | def test_with_confirmation_select_second(self, capsys, patch_get_key, ...

FILE: tests/test_utils.py
  function test_default_settings (line 17) | def test_default_settings(settings, override, old, new):
  function test_memoize (line 24) | def test_memoize():
  function test_no_memoize (line 33) | def test_no_memoize():
  class TestGetClosest (line 41) | class TestGetClosest(object):
    method test_when_can_match (line 42) | def test_when_can_match(self):
    method test_when_cant_match (line 45) | def test_when_cant_match(self):
    method test_without_fallback (line 48) | def test_without_fallback(self):
  class TestGetCloseMatches (line 53) | class TestGetCloseMatches(object):
    method test_call_with_n (line 55) | def test_call_with_n(self, difflib_mock):
    method test_call_without_n (line 60) | def test_call_without_n(self, difflib_mock, settings):
  function get_aliases (line 66) | def get_aliases(mocker):
  function test_get_all_executables (line 72) | def test_get_all_executables():
  function os_environ_pathsep (line 80) | def os_environ_pathsep(monkeypatch, path, pathsep):
  function test_get_all_executables_pathsep (line 91) | def test_get_all_executables_pathsep(path, pathsep):
  function test_get_all_executables_exclude_paths (line 101) | def test_get_all_executables_exclude_paths(path, pathsep, excluded, sett...
  function test_replace_argument (line 114) | def test_replace_argument(args, result):
  function test_get_all_matched_commands (line 143) | def test_get_all_matched_commands(stderr, result):
  function test_is_app (line 154) | def test_is_app(script, names, result):
  function test_for_app (line 165) | def test_for_app(script, names, result):
  class TestCache (line 173) | class TestCache(object):
    method shelve (line 175) | def shelve(self, mocker):
    method enable_cache (line 198) | def enable_cache(self, monkeypatch, shelve):
    method mtime (line 203) | def mtime(self, mocker):
    method fn (line 207) | def fn(self):
    method key (line 215) | def key(self, monkeypatch):
    method test_with_blank_cache (line 220) | def test_with_blank_cache(self, shelve, fn, key):
    method test_with_filled_cache (line 225) | def test_with_filled_cache(self, shelve, fn, key):
    method test_when_etag_changed (line 231) | def test_when_etag_changed(self, shelve, fn, key):
  class TestGetValidHistoryWithoutCurrent (line 237) | class TestGetValidHistoryWithoutCurrent(object):
    method fail_on_warning (line 239) | def fail_on_warning(self):
    method history (line 245) | def history(self, mocker):
    method alias (line 254) | def alias(self, mocker):
    method bins (line 259) | def bins(self, mocker):
    method test_get_valid_history_without_current (line 274) | def test_get_valid_history_without_current(self, script, result):

FILE: tests/utils.py
  class Rule (line 5) | class Rule(types.Rule):
    method __init__ (line 6) | def __init__(self, name='', match=lambda *_: True,
  class CorrectedCommand (line 17) | class CorrectedCommand(types.CorrectedCommand):
    method __init__ (line 18) | def __init__(self, script='', side_effect=None, priority=DEFAULT_PRIOR...

FILE: thefuck/argument_parser.py
  class Parser (line 7) | class Parser(object):
    method __init__ (line 13) | def __init__(self):
    method _add_arguments (line 17) | def _add_arguments(self):
    method _add_conflicting_arguments (line 54) | def _add_conflicting_arguments(self):
    method _prepare_arguments (line 66) | def _prepare_arguments(self, argv):
    method parse (line 84) | def parse(self, argv):
    method print_usage (line 88) | def print_usage(self):
    method print_help (line 91) | def print_help(self):

FILE: thefuck/conf.py
  function load_source (line 11) | def load_source(name, pathname, _file=None):
  class Settings (line 20) | class Settings(dict):
    method __getattr__ (line 21) | def __getattr__(self, item):
    method __setattr__ (line 24) | def __setattr__(self, key, value):
    method init (line 27) | def init(self, args=None):
    method _init_settings_file (line 46) | def _init_settings_file(self):
    method _get_user_dir_path (line 54) | def _get_user_dir_path(self):
    method _setup_user_dir (line 68) | def _setup_user_dir(self):
    method _settings_from_file (line 77) | def _settings_from_file(self):
    method _rules_from_env (line 85) | def _rules_from_env(self, val):
    method _priority_from_env (line 92) | def _priority_from_env(self, val):
    method _val_from_env (line 101) | def _val_from_env(self, env, attr):
    method _settings_from_env (line 119) | def _settings_from_env(self):
    method _settings_from_args (line 125) | def _settings_from_args(self, args):

FILE: thefuck/const.py
  class _GenConst (line 4) | class _GenConst(object):
    method __init__ (line 5) | def __init__(self, name):
    method __repr__ (line 8) | def __repr__(self):

FILE: thefuck/corrector.py
  function get_loaded_rules (line 8) | def get_loaded_rules(rules_paths):
  function get_rules_import_paths (line 22) | def get_rules_import_paths():
  function get_rules (line 40) | def get_rules():
  function organize_commands (line 52) | def organize_commands(corrected_commands):
  function get_corrected_commands (line 81) | def get_corrected_commands(command):

FILE: thefuck/entrypoints/alias.py
  function _get_alias (line 8) | def _get_alias(known_args):
  function print_alias (line 26) | def print_alias(known_args):

FILE: thefuck/entrypoints/fix_command.py
  function _get_raw_command (line 13) | def _get_raw_command(known_args):
  function fix_command (line 29) | def fix_command(known_args):

FILE: thefuck/entrypoints/main.py
  function main (line 16) | def main():

FILE: thefuck/entrypoints/not_configured.py
  function _get_shell_pid (line 19) | def _get_shell_pid():
  function _get_not_configured_usage_tracker_path (line 29) | def _get_not_configured_usage_tracker_path():
  function _record_first_run (line 36) | def _record_first_run():
  function _get_previous_command (line 46) | def _get_previous_command():
  function _is_second_run (line 55) | def _is_second_run():
  function _is_already_configured (line 75) | def _is_already_configured(configuration_details):
  function _configure (line 82) | def _configure(configuration_details):
  function main (line 91) | def main():

FILE: thefuck/entrypoints/shell_logger.py
  function _read (line 14) | def _read(f, fd):
  function _set_pty_size (line 27) | def _set_pty_size(master_fd):
  function _spawn (line 33) | def _spawn(shell, master_read):
  function shell_logger (line 64) | def shell_logger(output):

FILE: thefuck/exceptions.py
  class EmptyCommand (line 1) | class EmptyCommand(Exception):
  class NoRuleMatched (line 5) | class NoRuleMatched(Exception):
  class ScriptNotInLog (line 9) | class ScriptNotInLog(Exception):

FILE: thefuck/logs.py
  function color (line 12) | def color(color_):
  function warn (line 20) | def warn(title):
  function exception (line 28) | def exception(title, exc_info):
  function rule_failed (line 39) | def rule_failed(rule, exc_info):
  function failed (line 43) | def failed(msg):
  function show_corrected_command (line 50) | def show_corrected_command(corrected_command):
  function confirm_text (line 59) | def confirm_text(corrected_command):
  function debug (line 75) | def debug(msg):
  function debug_time (line 85) | def debug_time(msg):
  function how_to_configure_alias (line 93) | def how_to_configure_alias(configuration_details):
  function already_configured (line 117) | def already_configured(configuration_details):
  function configured_successfully (line 127) | def configured_successfully(configuration_details):
  function version (line 137) | def version(thefuck_version, python_version, shell_info):

FILE: thefuck/output_readers/__init__.py
  function get_output (line 5) | def get_output(script, expanded):

FILE: thefuck/output_readers/read_log.py
  function _group_by_calls (line 15) | def _group_by_calls(log):
  function _get_script_group_lines (line 42) | def _get_script_group_lines(grouped, script):
  function _get_output_lines (line 55) | def _get_output_lines(script, log_file):
  function _skip_old_lines (line 67) | def _skip_old_lines(log_file):
  function get_output (line 73) | def get_output(script):

FILE: thefuck/output_readers/rerun.py
  function _kill_process (line 10) | def _kill_process(proc):
  function _wait_output (line 24) | def _wait_output(popen, is_slow):
  function get_output (line 46) | def get_output(script, expanded):

FILE: thefuck/output_readers/shell_logger.py
  function _get_socket_path (line 12) | def _get_socket_path():
  function is_available (line 16) | def is_available():
  function _get_last_n (line 29) | def _get_last_n(n):
  function _get_output_lines (line 41) | def _get_output_lines(output):
  function get_output (line 49) | def get_output(script):

FILE: thefuck/rules/adb_unknown_command.py
  function match (line 43) | def match(command):
  function get_new_command (line 48) | def get_new_command(command):

FILE: thefuck/rules/ag_literal.py
  function match (line 5) | def match(command):
  function get_new_command (line 9) | def get_new_command(command):

FILE: thefuck/rules/apt_get.py
  function _get_executable (line 21) | def _get_executable(command):
  function get_package (line 29) | def get_package(executable):
  function match (line 38) | def match(command):
  function get_new_command (line 46) | def get_new_command(command):

FILE: thefuck/rules/apt_get_search.py
  function match (line 9) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/apt_invalid_operation.py
  function match (line 11) | def match(command):
  function _parse_apt_operations (line 16) | def _parse_apt_operations(help_text_lines):
  function _parse_apt_get_and_cache_operations (line 28) | def _parse_apt_get_and_cache_operations(help_text_lines):
  function _get_operations (line 42) | def _get_operations(app):
  function get_new_command (line 55) | def get_new_command(command):

FILE: thefuck/rules/apt_list_upgradable.py
  function match (line 10) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/apt_upgrade.py
  function match (line 10) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/aws_cli.py
  function match (line 10) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/az_cli.py
  function match (line 10) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/brew_cask_dependency.py
  function match (line 7) | def match(command):
  function _get_cask_install_lines (line 13) | def _get_cask_install_lines(output):
  function _get_script_for_brew_cask (line 20) | def _get_script_for_brew_cask(output):
  function get_new_command (line 28) | def get_new_command(command):

FILE: thefuck/rules/brew_install.py
  function _get_suggestions (line 8) | def _get_suggestions(str):
  function match (line 14) | def match(command):
  function get_new_command (line 21) | def get_new_command(command):

FILE: thefuck/rules/brew_link.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/brew_reinstall.py
  function match (line 12) | def match(command):
  function get_new_command (line 18) | def get_new_command(command):

FILE: thefuck/rules/brew_uninstall.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/brew_unknown_command.py
  function _get_brew_commands (line 13) | def _get_brew_commands(brew_path_prefix):
  function _get_brew_tap_specific_commands (line 21) | def _get_brew_tap_specific_commands(brew_path_prefix):
  function _is_brew_tap_cmd_naming (line 44) | def _is_brew_tap_cmd_naming(name):
  function _get_directory_names_only (line 48) | def _get_directory_names_only(path):
  function _brew_commands (line 53) | def _brew_commands():
  function match (line 68) | def match(command):
  function get_new_command (line 79) | def get_new_command(command):

FILE: thefuck/rules/brew_update_formula.py
  function match (line 5) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/cargo.py
  function match (line 1) | def match(command):
  function get_new_command (line 5) | def get_new_command(command):

FILE: thefuck/rules/cargo_no_command.py
  function match (line 6) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/cat_dir.py
  function match (line 6) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/cd_correction.py
  function _get_sub_dirs (line 14) | def _get_sub_dirs(parent):
  function match (line 21) | def match(command):
  function get_new_command (line 32) | def get_new_command(command):

FILE: thefuck/rules/cd_cs.py
  function match (line 12) | def match(command):
  function get_new_command (line 17) | def get_new_command(command):

FILE: thefuck/rules/cd_mkdir.py
  function match (line 9) | def match(command):
  function get_new_command (line 19) | def get_new_command(command):

FILE: thefuck/rules/cd_parent.py
  function match (line 11) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/chmod_x.py
  function match (line 5) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/choco_install.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/composer_not_command.py
  function match (line 6) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/conda_mistype.py
  function match (line 6) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/cp_create_destination.py
  function match (line 6) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/cp_omitting_directory.py
  function match (line 8) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/cpp11.py
  function match (line 5) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/dirty_untar.py
  function _is_tar_extract (line 12) | def _is_tar_extract(cmd):
  function _tar_file (line 21) | def _tar_file(cmd):
  function match (line 29) | def match(command):
  function get_new_command (line 35) | def get_new_command(command):
  function side_effect (line 41) | def side_effect(old_cmd, command):

FILE: thefuck/rules/dirty_unzip.py
  function _is_bad_zip (line 7) | def _is_bad_zip(file):
  function _zip_file (line 15) | def _zip_file(command):
  function match (line 29) | def match(command):
  function get_new_command (line 40) | def get_new_command(command):
  function side_effect (line 45) | def side_effect(old_cmd, command):

FILE: thefuck/rules/django_south_ghost.py
  function match (line 1) | def match(command):
  function get_new_command (line 7) | def get_new_command(command):

FILE: thefuck/rules/django_south_merge.py
  function match (line 1) | def match(command):
  function get_new_command (line 7) | def get_new_command(command):

FILE: thefuck/rules/dnf_no_such_command.py
  function match (line 13) | def match(command):
  function _parse_operations (line 17) | def _parse_operations(help_text_lines):
  function _get_operations (line 22) | def _get_operations():
  function get_new_command (line 32) | def get_new_command(command):

FILE: thefuck/rules/docker_image_being_used_by_container.py
  function match (line 6) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/docker_login.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/docker_not_command.py
  function match (line 10) | def match(command):
  function _parse_commands (line 14) | def _parse_commands(lines, starts_with):
  function get_docker_commands (line 21) | def get_docker_commands():
  function get_new_command (line 42) | def get_new_command(command):

FILE: thefuck/rules/dry.py
  function match (line 1) | def match(command):
  function get_new_command (line 9) | def get_new_command(command):

FILE: thefuck/rules/fab_command_not_found.py
  function match (line 5) | def match(command):
  function _get_between (line 11) | def _get_between(content, start, end=None):
  function get_new_command (line 25) | def get_new_command(command):

FILE: thefuck/rules/fix_alt_space.py
  function match (line 8) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/fix_file.py
  function _make_pattern (line 38) | def _make_pattern(pattern):
  function _search (line 49) | def _search(output):
  function match (line 56) | def match(command):
  function get_new_command (line 65) | def get_new_command(command):

FILE: thefuck/rules/gem_unknown_command.py
  function match (line 7) | def match(command):
  function _get_unknown_command (line 13) | def _get_unknown_command(command):
  function _get_all_commands (line 18) | def _get_all_commands():
  function get_new_command (line 33) | def get_new_command(command):

FILE: thefuck/rules/git_add.py
  function _get_missing_file (line 9) | def _get_missing_file(command):
  function match (line 18) | def match(command):
  function get_new_command (line 24) | def get_new_command(command):

FILE: thefuck/rules/git_add_force.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_bisect_usage.py
  function match (line 7) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/git_branch_0flag.py
  function first_0flag (line 7) | def first_0flag(script_parts):
  function match (line 12) | def match(command):
  function get_new_command (line 17) | def get_new_command(command):

FILE: thefuck/rules/git_branch_delete.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_branch_delete_checked_out.py
  function match (line 7) | def match(command):
  function get_new_command (line 16) | def get_new_command(command):

FILE: thefuck/rules/git_branch_exists.py
  function match (line 8) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/git_branch_list.py
  function match (line 6) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/git_checkout.py
  function match (line 10) | def match(command):
  function get_branches (line 15) | def get_branches():
  function get_new_command (line 31) | def get_new_command(command):

FILE: thefuck/rules/git_clone_git_clone.py
  function match (line 5) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/git_clone_missing.py
  function match (line 17) | def match(command):
  function get_new_command (line 41) | def get_new_command(command):

FILE: thefuck/rules/git_commit_add.py
  function match (line 6) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/git_commit_amend.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/git_commit_reset.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/git_diff_no_index.py
  function match (line 6) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/git_diff_staged.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_fix_stash.py
  function match (line 7) | def match(command):
  function get_new_command (line 28) | def get_new_command(command):

FILE: thefuck/rules/git_flag_after_filename.py
  function match (line 9) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/git_help_aliased.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/git_hook_bypass.py
  function match (line 8) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/git_lfs_mistype.py
  function match (line 7) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/git_main_master.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/git_merge.py
  function match (line 7) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/git_merge_unrelated.py
  function match (line 5) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/git_not_command.py
  function match (line 7) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/git_pull.py
  function match (line 6) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/git_pull_clone.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_pull_uncommitted_changes.py
  function match (line 6) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/git_push.py
  function match (line 7) | def match(command):
  function _get_upstream_option_index (line 12) | def _get_upstream_option_index(command_parts):
  function get_new_command (line 22) | def get_new_command(command):

FILE: thefuck/rules/git_push_different_branch_names.py
  function match (line 6) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/git_push_force.py
  function match (line 6) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/git_push_pull.py
  function match (line 7) | def match(command):
  function get_new_command (line 18) | def get_new_command(command):

FILE: thefuck/rules/git_push_without_commits.py
  function match (line 7) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/git_rebase_merge_dir.py
  function match (line 6) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/git_rebase_no_changes.py
  function match (line 5) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_remote_delete.py
  function match (line 7) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_remote_seturl_add.py
  function match (line 6) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/git_rm_local_modifications.py
  function match (line 5) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_rm_recursive.py
  function match (line 5) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_rm_staged.py
  function match (line 5) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_stash.py
  function match (line 6) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/git_stash_pop.py
  function match (line 6) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/git_tag_force.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/git_two_dashes.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/go_run.py
  function match (line 10) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/go_unknown_command.py
  function get_golang_commands (line 7) | def get_golang_commands():
  function match (line 21) | def match(command):
  function get_new_command (line 25) | def get_new_command(command):

FILE: thefuck/rules/gradle_no_task.py
  function match (line 9) | def match(command):
  function _get_all_tasks (line 14) | def _get_all_tasks(gradle):
  function get_new_command (line 31) | def get_new_command(command):

FILE: thefuck/rules/gradle_wrapper.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/grep_arguments_order.py
  function _get_actual_file (line 5) | def _get_actual_file(parts):
  function match (line 12) | def match(command):
  function get_new_command (line 17) | def get_new_command(command):

FILE: thefuck/rules/grep_recursive.py
  function match (line 5) | def match(command):
  function get_new_command (line 9) | def get_new_command(command):

FILE: thefuck/rules/grunt_task_not_found.py
  function match (line 9) | def match(command):
  function _get_all_tasks (line 15) | def _get_all_tasks():
  function get_new_command (line 32) | def get_new_command(command):

FILE: thefuck/rules/gulp_not_task.py
  function match (line 7) | def match(command):
  function get_gulp_tasks (line 12) | def get_gulp_tasks():
  function get_new_command (line 19) | def get_new_command(command):

FILE: thefuck/rules/has_exists_script.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/heroku_multiple_apps.py
  function match (line 6) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/heroku_not_command.py
  function match (line 6) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/history.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/hostscli.py
  function match (line 11) | def match(command):
  function get_new_command (line 20) | def get_new_command(command):

FILE: thefuck/rules/ifconfig_device_not_found.py
  function match (line 6) | def match(command):
  function _get_possible_interfaces (line 12) | def _get_possible_interfaces():
  function get_new_command (line 20) | def get_new_command(command):

FILE: thefuck/rules/java.py
  function match (line 12) | def match(command):
  function get_new_command (line 16) | def get_new_command(command):

FILE: thefuck/rules/javac.py
  function match (line 13) | def match(command):
  function get_new_command (line 17) | def get_new_command(command):

FILE: thefuck/rules/lein_not_task.py
  function match (line 8) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/ln_no_hard_link.py
  function match (line 16) | def match(command):
  function get_new_command (line 22) | def get_new_command(command):

FILE: thefuck/rules/ln_s_order.py
  function _get_destination (line 5) | def _get_destination(script_parts):
  function match (line 13) | def match(command):
  function get_new_command (line 21) | def get_new_command(command):

FILE: thefuck/rules/long_form_help.py
  function match (line 8) | def match(command):
  function get_new_command (line 18) | def get_new_command(command):

FILE: thefuck/rules/ls_all.py
  function match (line 5) | def match(command):
  function get_new_command (line 9) | def get_new_command(command):

FILE: thefuck/rules/ls_lah.py
  function match (line 5) | def match(command):
  function get_new_command (line 9) | def get_new_command(command):

FILE: thefuck/rules/man.py
  function match (line 5) | def match(command):
  function get_new_command (line 9) | def get_new_command(command):

FILE: thefuck/rules/man_no_space.py
  function match (line 1) | def match(command):
  function get_new_command (line 6) | def get_new_command(command):

FILE: thefuck/rules/mercurial.py
  function extract_possibilities (line 5) | def extract_possibilities(command):
  function match (line 16) | def match(command):
  function get_new_command (line 23) | def get_new_command(command):

FILE: thefuck/rules/missing_space_before_subcommand.py
  function _get_executable (line 5) | def _get_executable(script_part):
  function match (line 11) | def match(command):
  function get_new_command (line 16) | def get_new_command(command):

FILE: thefuck/rules/mkdir_p.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/mvn_no_command.py
  function match (line 5) | def match(command):
  function get_new_command (line 9) | def get_new_command(command):

FILE: thefuck/rules/mvn_unknown_lifecycle_phase.py
  function _get_failed_lifecycle (line 5) | def _get_failed_lifecycle(command):
  function _getavailable_lifecycles (line 10) | def _getavailable_lifecycles(command):
  function match (line 16) | def match(command):
  function get_new_command (line 22) | def get_new_command(command):

FILE: thefuck/rules/nixos_cmd_not_found.py
  function match (line 9) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/no_command.py
  function match (line 7) | def match(command):
  function _get_used_executables (line 15) | def _get_used_executables(command):
  function get_new_command (line 21) | def get_new_command(command):

FILE: thefuck/rules/no_such_file.py
  function match (line 13) | def match(command):
  function get_new_command (line 21) | def get_new_command(command):

FILE: thefuck/rules/npm_missing_script.py
  function match (line 9) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/npm_run_script.py
  function match (line 8) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/npm_wrong_command.py
  function _get_wrong_command (line 8) | def _get_wrong_command(script_parts):
  function match (line 16) | def match(command):
  function _get_available_commands (line 23) | def _get_available_commands(stdout):
  function get_new_command (line 38) | def get_new_command(command):

FILE: thefuck/rules/omnienv_no_such_command.py
  function match (line 18) | def match(command):
  function get_app_commands (line 22) | def get_app_commands(app):
  function get_new_command (line 27) | def get_new_command(command):

FILE: thefuck/rules/open.py
  function is_arg_url (line 12) | def is_arg_url(command):
  function match (line 26) | def match(command):
  function get_new_command (line 33) | def get_new_command(command):

FILE: thefuck/rules/pacman.py
  function match (line 5) | def match(command):
  function get_new_command (line 9) | def get_new_command(command):

FILE: thefuck/rules/pacman_invalid_option.py
  function match (line 9) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/pacman_not_found.py
  function match (line 13) | def match(command):
  function get_new_command (line 20) | def get_new_command(command):

FILE: thefuck/rules/path_from_history.py
  function _get_destination (line 16) | def _get_destination(command):
  function match (line 24) | def match(command):
  function _get_all_absolute_paths_from_history (line 28) | def _get_all_absolute_paths_from_history(command):
  function get_new_command (line 44) | def get_new_command(command):

FILE: thefuck/rules/php_s.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/pip_install.py
  function match (line 7) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/pip_unknown_command.py
  function match (line 8) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/port_already_in_use.py
  function _get_pid_by_port (line 15) | def _get_pid_by_port(port):
  function _get_used_port (line 25) | def _get_used_port(command):
  function match (line 32) | def match(command):
  function get_new_command (line 37) | def get_new_command(command):

FILE: thefuck/rules/prove_recursively.py
  function _is_recursive (line 5) | def _is_recursive(part):
  function _isdir (line 12) | def _isdir(part):
  function match (line 17) | def match(command):
  function get_new_command (line 24) | def get_new_command(command):

FILE: thefuck/rules/python_command.py
  function match (line 8) | def match(command):
  function get_new_command (line 16) | def get_new_command(command):

FILE: thefuck/rules/python_execute.py
  function match (line 10) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/python_module_error.py
  function match (line 7) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/quotation_marks.py
  function match (line 7) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/rails_migrations_pending.py
  function match (line 8) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/react_native_command_unrecognized.py
  function match (line 7) | def match(command):
  function _get_commands (line 13) | def _get_commands():
  function get_new_command (line 30) | def get_new_command(command):

FILE: thefuck/rules/remove_shell_prompt_literal.py
  function match (line 15) | def match(command):
  function get_new_command (line 22) | def get_new_command(command):

FILE: thefuck/rules/remove_trailing_cedilla.py
  function match (line 6) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/rm_dir.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/rm_root.py
  function match (line 7) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/scm_correction.py
  function _get_actual_scm (line 16) | def _get_actual_scm():
  function match (line 23) | def match(command):
  function get_new_command (line 30) | def get_new_command(command):

FILE: thefuck/rules/sed_unterminated_s.py
  function match (line 7) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/sl_ls.py
  function match (line 9) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/ssh_known_hosts.py
  function match (line 8) | def match(command):
  function get_new_command (line 23) | def get_new_command(command):
  function side_effect (line 27) | def side_effect(old_cmd, command):

FILE: thefuck/rules/sudo.py
  function match (line 31) | def match(command):
  function get_new_command (line 41) | def get_new_command(command):

FILE: thefuck/rules/sudo_command_from_user_path.py
  function _get_command_name (line 5) | def _get_command_name(command):
  function match (line 12) | def match(command):
  function get_new_command (line 18) | def get_new_command(command):

FILE: thefuck/rules/switch_lang.py
  function _get_matched_layout (line 49) | def _get_matched_layout(command):
  function _switch (line 64) | def _switch(ch, layout):
  function _switch_command (line 70) | def _switch_command(command, layout):
  function _decompose_korean (line 79) | def _decompose_korean(command):
  function match (line 100) | def match(command):
  function get_new_command (line 112) | def get_new_command(command):

FILE: thefuck/rules/systemctl.py
  function match (line 10) | def match(command):
  function get_new_command (line 19) | def get_new_command(command):

FILE: thefuck/rules/terraform_init.py
  function match (line 6) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/terraform_no_command.py
  function match (line 9) | def match(command):
  function get_new_command (line 13) | def get_new_command(command):

FILE: thefuck/rules/test.py.py
  function match (line 1) | def match(command):
  function get_new_command (line 5) | def get_new_command(command):

FILE: thefuck/rules/tmux.py
  function match (line 6) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/touch.py
  function match (line 7) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/tsuru_login.py
  function match (line 6) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/tsuru_not_command.py
  function match (line 6) | def match(command):
  function get_new_command (line 11) | def get_new_command(command):

FILE: thefuck/rules/unknown_command.py
  function match (line 5) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/unsudo.py
  function match (line 4) | def match(command):
  function get_new_command (line 14) | def get_new_command(command):

FILE: thefuck/rules/vagrant_up.py
  function match (line 6) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/whois.py
  function match (line 7) | def match(command):
  function get_new_command (line 27) | def get_new_command(command):

FILE: thefuck/rules/workon_doesnt_exists.py
  function _get_all_environments (line 7) | def _get_all_environments():
  function match (line 18) | def match(command):
  function get_new_command (line 23) | def get_new_command(command):

FILE: thefuck/rules/wrong_hyphen_before_subcommand.py
  function match (line 6) | def match(command):
  function get_new_command (line 15) | def get_new_command(command):

FILE: thefuck/rules/yarn_alias.py
  function match (line 6) | def match(command):
  function get_new_command (line 10) | def get_new_command(command):

FILE: thefuck/rules/yarn_command_not_found.py
  function match (line 10) | def match(command):
  function _get_all_tasks (line 18) | def _get_all_tasks():
  function get_new_command (line 36) | def get_new_command(command):

FILE: thefuck/rules/yarn_command_replaced.py
  function match (line 8) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/yarn_help.py
  function match (line 7) | def match(command):
  function get_new_command (line 12) | def get_new_command(command):

FILE: thefuck/rules/yum_invalid_operation.py
  function match (line 13) | def match(command):
  function _get_operations (line 17) | def _get_operations():
  function get_new_command (line 33) | def get_new_command(command):

FILE: thefuck/shells/__init__.py
  function _get_shell_from_env (line 23) | def _get_shell_from_env():
  function _get_shell_from_proc (line 30) | def _get_shell_from_proc():

FILE: thefuck/shells/bash.py
  class Bash (line 11) | class Bash(Generic):
    method app_alias (line 14) | def app_alias(self, alias_name):
    method instant_mode_alias (line 37) | def instant_mode_alias(self, alias_name):
    method _parse_alias (line 56) | def _parse_alias(self, alias):
    method get_aliases (line 63) | def get_aliases(self):
    method _get_history_file_name (line 68) | def _get_history_file_name(self):
    method _get_history_line (line 72) | def _get_history_line(self, command_script):
    method how_to_configure (line 75) | def how_to_configure(self):
    method _get_version (line 88) | def _get_version(self):

FILE: thefuck/shells/fish.py
  function _get_functions (line 14) | def _get_functions(overridden):
  function _get_aliases (line 21) | def _get_aliases(overridden):
  class Fish (line 40) | class Fish(Generic):
    method _get_overridden_aliases (line 43) | def _get_overridden_aliases(self):
    method app_alias (line 51) | def app_alias(self, alias_name):
    method get_aliases (line 68) | def get_aliases(self):
    method _expand_aliases (line 75) | def _expand_aliases(self, command_script):
    method _get_history_file_name (line 85) | def _get_history_file_name(self):
    method _get_history_line (line 88) | def _get_history_line(self, command_script):
    method _script_from_history (line 91) | def _script_from_history(self, line):
    method and_ (line 97) | def and_(self, *commands):
    method or_ (line 100) | def or_(self, *commands):
    method how_to_configure (line 103) | def how_to_configure(self):
    method _get_version (line 109) | def _get_version(self):
    method put_to_history (line 114) | def put_to_history(self, command):
    method _put_to_history (line 120) | def _put_to_history(self, command_script):

FILE: thefuck/shells/generic.py
  class Generic (line 16) | class Generic(object):
    method get_aliases (line 19) | def get_aliases(self):
    method _expand_aliases (line 22) | def _expand_aliases(self, command_script):
    method from_shell (line 30) | def from_shell(self, command_script):
    method to_shell (line 34) | def to_shell(self, command_script):
    method app_alias (line 38) | def app_alias(self, alias_name):
    method instant_mode_alias (line 42) | def instant_mode_alias(self, alias_name):
    method _get_history_file_name (line 46) | def _get_history_file_name(self):
    method _get_history_line (line 49) | def _get_history_line(self, command_script):
    method get_history (line 53) | def get_history(self):
    method _get_history_lines (line 56) | def _get_history_lines(self):
    method and_ (line 73) | def and_(self, *commands):
    method or_ (line 76) | def or_(self, *commands):
    method how_to_configure (line 79) | def how_to_configure(self):
    method split_command (line 82) | def split_command(self, command):
    method encode_utf8 (line 93) | def encode_utf8(self, command):
    method decode_utf8 (line 98) | def decode_utf8(self, command_parts):
    method quote (line 103) | def quote(self, s):
    method _script_from_history (line 113) | def _script_from_history(self, line):
    method put_to_history (line 116) | def put_to_history(self, command):
    method get_builtin_commands (line 124) | def get_builtin_commands(self):
    method _get_version (line 136) | def _get_version(self):
    method info (line 140) | def info(self):
    method _create_shell_configuration (line 149) | def _create_shell_configuration(self, content, path, reload):

FILE: thefuck/shells/powershell.py
  class Powershell (line 6) | class Powershell(Generic):
    method app_alias (line 9) | def app_alias(self, alias_name):
    method and_ (line 22) | def and_(self, *commands):
    method how_to_configure (line 25) | def how_to_configure(self):
    method _get_version (line 32) | def _get_version(self):

FILE: thefuck/shells/tcsh.py
  class Tcsh (line 8) | class Tcsh(Generic):
    method app_alias (line 11) | def app_alias(self, alias_name):
    method _parse_alias (line 16) | def _parse_alias(self, alias):
    method get_aliases (line 21) | def get_aliases(self):
    method _get_history_file_name (line 28) | def _get_history_file_name(self):
    method _get_history_line (line 32) | def _get_history_line(self, command_script):
    method how_to_configure (line 35) | def how_to_configure(self):
    method _get_version (line 41) | def _get_version(self):

FILE: thefuck/shells/zsh.py
  class Zsh (line 12) | class Zsh(Generic):
    method app_alias (line 15) | def app_alias(self, alias_name):
    method instant_mode_alias (line 40) | def instant_mode_alias(self, alias_name):
    method _parse_alias (line 61) | def _parse_alias(self, alias):
    method get_aliases (line 68) | def get_aliases(self):
    method _get_history_file_name (line 73) | def _get_history_file_name(self):
    method _get_history_line (line 77) | def _get_history_line(self, command_script):
    method _script_from_history (line 80) | def _script_from_history(self, line):
    method how_to_configure (line 86) | def how_to_configure(self):
    method _get_version (line 92) | def _get_version(self):

FILE: thefuck/specific/archlinux.py
  function get_pkgfile (line 7) | def get_pkgfile(command):
  function archlinux_env (line 34) | def archlinux_env():

FILE: thefuck/specific/brew.py
  function get_brew_path_prefix (line 9) | def get_brew_path_prefix():

FILE: thefuck/specific/git.py
  function git_support (line 8) | def git_support(fn, command):

FILE: thefuck/specific/npm.py
  function get_scripts (line 10) | def get_scripts():

FILE: thefuck/specific/sudo.py
  function sudo_support (line 6) | def sudo_support(fn, command):

FILE: thefuck/system/unix.py
  function getch (line 12) | def getch():
  function get_key (line 22) | def get_key():
  function open_command (line 40) | def open_command(arg):
  function _expanduser (line 52) | def _expanduser(self):

FILE: thefuck/system/win32.py
  function init_output (line 7) | def init_output():
  function get_key (line 13) | def get_key():
  function open_command (line 28) | def open_command(arg):
  function _expanduser (line 38) | def _expanduser(self):

FILE: thefuck/types.py
  class Command (line 12) | class Command(object):
    method __init__ (line 15) | def __init__(self, script, output):
    method stdout (line 26) | def stdout(self):
    method stderr (line 31) | def stderr(self):
    method script_parts (line 36) | def script_parts(self):
    method __eq__ (line 47) | def __eq__(self, other):
    method __repr__ (line 53) | def __repr__(self):
    method update (line 57) | def update(self, **kwargs):
    method from_raw_script (line 68) | def from_raw_script(cls, raw_script):
  class Rule (line 85) | class Rule(object):
    method __init__ (line 88) | def __init__(self, name, match, get_new_command,
    method __eq__ (line 110) | def __eq__(self, other):
    method __repr__ (line 121) | def __repr__(self):
    method from_path (line 130) | def from_path(cls, path):
    method is_enabled (line 156) | def is_enabled(self):
    method is_match (line 168) | def is_match(self, command):
    method get_corrected_commands (line 185) | def get_corrected_commands(self, command):
  class CorrectedCommand (line 201) | class CorrectedCommand(object):
    method __init__ (line 204) | def __init__(self, script, side_effect, priority):
    method __eq__ (line 216) | def __eq__(self, other):
    method __hash__ (line 224) | def __hash__(self):
    method __repr__ (line 227) | def __repr__(self):
    method _get_script (line 231) | def _get_script(self):
    method run (line 247) | def run(self, old_cmd):

FILE: thefuck/ui.py
  function read_actions (line 11) | def read_actions():
  class CommandSelector (line 27) | class CommandSelector(object):
    method __init__ (line 30) | def __init__(self, commands):
    method _realise (line 40) | def _realise(self):
    method next (line 45) | def next(self):
    method previous (line 49) | def previous(self):
    method value (line 54) | def value(self):
  function select_command (line 59) | def select_command(corrected_commands):

FILE: thefuck/utils.py
  function memoize (line 25) | def memoize(fn):
  function which (line 49) | def which(program):
  function default_settings (line 73) | def default_settings(params):
  function get_closest (line 90) | def get_closest(word, possibilities, cutoff=0.6, fallback_to_first=True):
  function get_close_matches (line 100) | def get_close_matches(word, possibilities, n=None, cutoff=0.6):
  function include_path_in_search (line 107) | def include_path_in_search(path):
  function get_all_executables (line 112) | def get_all_executables():
  function replace_argument (line 136) | def replace_argument(script, from_, to):
  function eager (line 148) | def eager(fn, *args, **kwargs):
  function get_all_matched_commands (line 153) | def get_all_matched_commands(stderr, separator='Did you mean'):
  function replace_command (line 167) | def replace_command(command, broken, matched):
  function is_app (line 175) | def is_app(command, *app_names, **kwargs):
  function for_app (line 188) | def for_app(*app_names, **kwargs):
  class Cache (line 199) | class Cache(object):
    method __init__ (line 202) | def __init__(self):
    method _init_db (line 205) | def _init_db(self):
    method _setup_db (line 212) | def _setup_db(self):
    method _get_cache_dir (line 226) | def _get_cache_dir(self):
    method _get_mtime (line 240) | def _get_mtime(self, path):
    method _get_key (line 246) | def _get_key(self, fn, depends_on, args, kwargs):
    method get_value (line 251) | def get_value(self, fn, depends_on, args, kwargs):
  function cache (line 271) | def cache(*depends_on):
  function get_installation_version (line 297) | def get_installation_version():
  function get_alias (line 308) | def get_alias():
  function get_valid_history_without_current (line 313) | def get_valid_history_without_current(command):
  function format_raw_script (line 335) | def format_raw_script(raw_script):
Condensed preview — 434 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (630K chars).
[
  {
    "path": ".devcontainer/Dockerfile",
    "chars": 536,
    "preview": "# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.163.1/containers/python-3/.dev"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "chars": 1500,
    "preview": "// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:\n// https://github.co"
  },
  {
    "path": ".editorconfig",
    "chars": 145,
    "preview": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 4\n\n[*.p"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 1081,
    "preview": "<!-- If you have any issue with The Fuck, sorry about that, but we will do what we\ncan to fix that. Actually, maybe we a"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 2547,
    "preview": "name: Tests\n\non: [push, pull_request]\n\nenv:\n  PYTHON_LATEST: \"3.11\"\n\njobs:\n  test:\n    strategy:\n      matrix:\n        o"
  },
  {
    "path": ".gitignore",
    "chars": 744,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 3193,
    "preview": "# Report issues\nIf you have any issue with The Fuck, sorry about that, but we will do what we\ncan to fix that. Actually,"
  },
  {
    "path": "LICENSE.md",
    "chars": 1111,
    "preview": "The MIT License (MIT)\n=====================\n\nCopyright (c) 2015-2022 Vladimir Iakovlev\n\nPermission is hereby granted, fr"
  },
  {
    "path": "MANIFEST.in",
    "chars": 46,
    "preview": "include LICENSE.md\ninclude fastentrypoints.py\n"
  },
  {
    "path": "README.md",
    "chars": 26450,
    "preview": "# The Fuck [![Version][version-badge]][version-link] [![Build Status][workflow-badge]][workflow-link] [![Coverage][cover"
  },
  {
    "path": "fastentrypoints.py",
    "chars": 3952,
    "preview": "# Copyright (c) 2016, Aaron Christianson\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, w"
  },
  {
    "path": "install.sh",
    "chars": 134,
    "preview": "#!/bin/sh\n\necho \"Installation script is deprecated!\"\necho \"For installation instruction please visit https://github.com/"
  },
  {
    "path": "release.py",
    "chars": 1024,
    "preview": "#!/usr/bin/env python\nfrom subprocess import call\nimport os\nimport re\n\n\nversion = None\n\n\ndef get_new_setup_py_lines():\n "
  },
  {
    "path": "requirements.txt",
    "chars": 116,
    "preview": "flake8\npytest\nmock\npytest-mock\nwheel\nsetuptools>=17.1\npexpect\npypandoc\npytest-benchmark\npytest-docker-pexpect\ntwine\n"
  },
  {
    "path": "scripts/fuck.bat",
    "chars": 130,
    "preview": "@set PYTHONIOENCODING=utf-8\n@powershell -noprofile -c \"cmd /c \\\"$(thefuck %* $(doskey /history)[-2])\\\"; [Console]::Reset"
  },
  {
    "path": "scripts/fuck.ps1",
    "chars": 622,
    "preview": "if ((Get-Command \"fuck\").CommandType -eq \"Function\") {\n\tfuck @args;\n\t[Console]::ResetColor()\n\texit\n}\n\n\"First time use of"
  },
  {
    "path": "setup.cfg",
    "chars": 28,
    "preview": "[bdist_wheel]\nuniversal = 1\n"
  },
  {
    "path": "setup.py",
    "chars": 2481,
    "preview": "#!/usr/bin/env python\nfrom setuptools import setup, find_packages\nimport pkg_resources\nimport sys\nimport os\nimport faste"
  },
  {
    "path": "snapcraft.yaml",
    "chars": 598,
    "preview": "name: thefuck\nversion: stable\nversion-script: git -C parts/thefuck/build describe --abbrev=0 --tags\nsummary: Magnificent"
  },
  {
    "path": "tests/Dockerfile",
    "chars": 218,
    "preview": "ARG PYTHON_VERSION\nFROM python:${PYTHON_VERSION}\nRUN apt-get update -y\nRUN apt-get install -yy --no-install-recommends -"
  },
  {
    "path": "tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/conftest.py",
    "chars": 1754,
    "preview": "import os\nimport pytest\nfrom thefuck import shells\nfrom thefuck import conf, const\nfrom thefuck.system import Path\n\nshel"
  },
  {
    "path": "tests/entrypoints/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/entrypoints/test_alias.py",
    "chars": 1443,
    "preview": "from mock import Mock\nimport pytest\nfrom thefuck.entrypoints.alias import _get_alias, print_alias\n\n\n@pytest.mark.paramet"
  },
  {
    "path": "tests/entrypoints/test_fix_command.py",
    "chars": 975,
    "preview": "import pytest\nfrom mock import Mock\nfrom thefuck.entrypoints.fix_command import _get_raw_command\n\n\nclass TestGetRawComma"
  },
  {
    "path": "tests/entrypoints/test_not_configured.py",
    "chars": 4398,
    "preview": "import pytest\nimport json\nfrom six import StringIO\nfrom mock import MagicMock\nfrom thefuck.shells.generic import ShellCo"
  },
  {
    "path": "tests/functional/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/functional/conftest.py",
    "chars": 558,
    "preview": "import pytest\n\nfrom pytest_docker_pexpect.docker import run as pexpect_docker_run, \\\n    stats as pexpect_docker_stats\n\n"
  },
  {
    "path": "tests/functional/plots.py",
    "chars": 2529,
    "preview": "def _set_confirmation(proc, require):\n    proc.sendline(u'mkdir -p ~/.thefuck')\n    proc.sendline(\n        u'echo \"requi"
  },
  {
    "path": "tests/functional/test_bash.py",
    "chars": 1813,
    "preview": "import pytest\nfrom tests.functional.plots import with_confirmation, without_confirmation, \\\n    refuse_with_confirmation"
  },
  {
    "path": "tests/functional/test_fish.py",
    "chars": 967,
    "preview": "import pytest\nfrom tests.functional.plots import with_confirmation, without_confirmation, \\\n    refuse_with_confirmation"
  },
  {
    "path": "tests/functional/test_tcsh.py",
    "chars": 996,
    "preview": "import pytest\nfrom tests.functional.plots import with_confirmation, without_confirmation, \\\n    refuse_with_confirmation"
  },
  {
    "path": "tests/functional/test_zsh.py",
    "chars": 1847,
    "preview": "import pytest\nfrom tests.functional.plots import with_confirmation, without_confirmation, \\\n    refuse_with_confirmation"
  },
  {
    "path": "tests/output_readers/test_rerun.py",
    "chars": 3053,
    "preview": "# -*- encoding: utf-8 -*-\n\nimport pytest\nimport sys\nfrom mock import Mock, patch\nfrom psutil import AccessDenied, Timeou"
  },
  {
    "path": "tests/rules/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/rules/test_adb_unknown_command.py",
    "chars": 1541,
    "preview": "import pytest\nfrom thefuck.rules.adb_unknown_command import match, get_new_command\nfrom thefuck.types import Command\n\n\n@"
  },
  {
    "path": "tests/rules/test_ag_literal.py",
    "chars": 732,
    "preview": "import pytest\nfrom thefuck.rules.ag_literal import get_new_command, match\nfrom thefuck.types import Command\n\n\n@pytest.fi"
  },
  {
    "path": "tests/rules/test_apt_get.py",
    "chars": 2245,
    "preview": "import pytest\nfrom thefuck.rules.apt_get import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark."
  },
  {
    "path": "tests/rules/test_apt_get_search.py",
    "chars": 732,
    "preview": "import pytest\nfrom thefuck.rules.apt_get_search import get_new_command, match\nfrom thefuck.types import Command\n\n\ndef te"
  },
  {
    "path": "tests/rules/test_apt_invalid_operation.py",
    "chars": 6388,
    "preview": "from io import BytesIO\nimport pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.apt_invalid_operation import m"
  },
  {
    "path": "tests/rules/test_apt_list_upgradable.py",
    "chars": 3939,
    "preview": "# -*- coding: utf-8 -*-\n\nimport pytest\nfrom thefuck.rules.apt_list_upgradable import get_new_command, match\nfrom thefuck"
  },
  {
    "path": "tests/rules/test_apt_upgrade.py",
    "chars": 1189,
    "preview": "import pytest\nfrom thefuck.rules.apt_upgrade import get_new_command, match\nfrom thefuck.types import Command\n\nmatch_outp"
  },
  {
    "path": "tests/rules/test_aws_cli.py",
    "chars": 2674,
    "preview": "import pytest\n\nfrom thefuck.rules.aws_cli import match, get_new_command\nfrom thefuck.types import Command\n\n\nno_suggestio"
  },
  {
    "path": "tests/rules/test_az_cli.py",
    "chars": 1175,
    "preview": "import pytest\n\nfrom thefuck.rules.az_cli import match, get_new_command\nfrom thefuck.types import Command\n\n\nno_suggestion"
  },
  {
    "path": "tests/rules/test_brew_cask_dependency.py",
    "chars": 943,
    "preview": "import pytest\nfrom thefuck.rules.brew_cask_dependency import match, get_new_command\nfrom thefuck.types import Command\n\n\n"
  },
  {
    "path": "tests/rules/test_brew_install.py",
    "chars": 2610,
    "preview": "import pytest\nfrom thefuck.rules.brew_install import match, get_new_command, _get_suggestions\nfrom thefuck.types import "
  },
  {
    "path": "tests/rules/test_brew_link.py",
    "chars": 1220,
    "preview": "import pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.brew_link import get_new_command, match\n\n\n@pytest.fix"
  },
  {
    "path": "tests/rules/test_brew_reinstall.py",
    "chars": 820,
    "preview": "import pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.brew_reinstall import get_new_command, match\n\n\noutput"
  },
  {
    "path": "tests/rules/test_brew_uninstall.py",
    "chars": 1069,
    "preview": "import pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.brew_uninstall import get_new_command, match\n\n\n@pytes"
  },
  {
    "path": "tests/rules/test_brew_unknown_command.py",
    "chars": 884,
    "preview": "import pytest\nfrom thefuck.rules.brew_unknown_command import match, get_new_command\nfrom thefuck.rules.brew_unknown_comm"
  },
  {
    "path": "tests/rules/test_brew_update_formula.py",
    "chars": 807,
    "preview": "import pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.brew_update_formula import get_new_command, match\n\n\no"
  },
  {
    "path": "tests/rules/test_cargo_no_command.py",
    "chars": 755,
    "preview": "import pytest\nfrom thefuck.rules.cargo_no_command import match, get_new_command\nfrom thefuck.types import Command\n\n\nno_s"
  },
  {
    "path": "tests/rules/test_cat_dir.py",
    "chars": 1208,
    "preview": "import pytest\nfrom thefuck.rules.cat_dir import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.fixtu"
  },
  {
    "path": "tests/rules/test_cd_correction.py",
    "chars": 756,
    "preview": "import pytest\nfrom thefuck.rules.cd_correction import match\nfrom thefuck.types import Command\n\n\n@pytest.mark.parametrize"
  },
  {
    "path": "tests/rules/test_cd_cs.py",
    "chars": 346,
    "preview": "from thefuck.rules.cd_cs import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_match():\n    assert "
  },
  {
    "path": "tests/rules/test_cd_mkdir.py",
    "chars": 911,
    "preview": "import pytest\nfrom thefuck.rules.cd_mkdir import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark"
  },
  {
    "path": "tests/rules/test_cd_parent.py",
    "chars": 301,
    "preview": "from thefuck.rules.cd_parent import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_match():\n    ass"
  },
  {
    "path": "tests/rules/test_chmod_x.py",
    "chars": 1418,
    "preview": "import pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.chmod_x import match, get_new_command\n\n\n@pytest.fixtu"
  },
  {
    "path": "tests/rules/test_choco_install.py",
    "chars": 4174,
    "preview": "import pytest\nfrom thefuck.rules.choco_install import match, get_new_command\nfrom thefuck.types import Command\n\n\npackage"
  },
  {
    "path": "tests/rules/test_composer_not_command.py",
    "chars": 2444,
    "preview": "import pytest\nfrom thefuck.rules.composer_not_command import match, get_new_command\nfrom thefuck.types import Command\n\n\n"
  },
  {
    "path": "tests/rules/test_conda_mistype.py",
    "chars": 588,
    "preview": "import pytest\n\nfrom thefuck.rules.conda_mistype import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytes"
  },
  {
    "path": "tests/rules/test_cp_create_destination.py",
    "chars": 1018,
    "preview": "import pytest\nfrom thefuck.rules.cp_create_destination import match, get_new_command\nfrom thefuck.types import Command\n\n"
  },
  {
    "path": "tests/rules/test_cp_omitting_directory.py",
    "chars": 672,
    "preview": "import pytest\nfrom thefuck.rules.cp_omitting_directory import match, get_new_command\nfrom thefuck.types import Command\n\n"
  },
  {
    "path": "tests/rules/test_dirty_untar.py",
    "chars": 2475,
    "preview": "import os\nimport pytest\nimport tarfile\nfrom thefuck.rules.dirty_untar import match, get_new_command, side_effect, \\\n    "
  },
  {
    "path": "tests/rules/test_dirty_unzip.py",
    "chars": 2156,
    "preview": "# -*- coding: utf-8 -*-\n\nimport os\nimport pytest\nimport zipfile\nfrom thefuck.rules.dirty_unzip import match, get_new_com"
  },
  {
    "path": "tests/rules/test_django_south_ghost.py",
    "chars": 2407,
    "preview": "import pytest\nfrom thefuck.rules.django_south_ghost import match, get_new_command\nfrom thefuck.types import Command\n\n\n@p"
  },
  {
    "path": "tests/rules/test_django_south_merge.py",
    "chars": 2060,
    "preview": "import pytest\nfrom thefuck.rules.django_south_merge import match, get_new_command\nfrom thefuck.types import Command\n\n\n@p"
  },
  {
    "path": "tests/rules/test_dnf_no_such_command.py",
    "chars": 8968,
    "preview": "from io import BytesIO\nimport pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.dnf_no_such_command import mat"
  },
  {
    "path": "tests/rules/test_docker_image_being_used_by_container.py",
    "chars": 1245,
    "preview": "from thefuck.rules.docker_image_being_used_by_container import match, get_new_command\nfrom thefuck.types import Command\n"
  },
  {
    "path": "tests/rules/test_docker_login.py",
    "chars": 1480,
    "preview": "from thefuck.rules.docker_login import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_match():\n    "
  },
  {
    "path": "tests/rules/test_docker_not_command.py",
    "chars": 13012,
    "preview": "import pytest\nfrom io import BytesIO\nfrom thefuck.types import Command\nfrom thefuck.rules.docker_not_command import get_"
  },
  {
    "path": "tests/rules/test_dry.py",
    "chars": 540,
    "preview": "import pytest\nfrom thefuck.rules.dry import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark.para"
  },
  {
    "path": "tests/rules/test_fab_command_not_found.py",
    "chars": 1410,
    "preview": "import pytest\nfrom thefuck.rules.fab_command_not_found import match, get_new_command\nfrom thefuck.types import Command\n\n"
  },
  {
    "path": "tests/rules/test_fix_alt_space.py",
    "chars": 738,
    "preview": "# -*- encoding: utf-8 -*-\n\nfrom thefuck.rules.fix_alt_space import match, get_new_command\nfrom thefuck.types import Comm"
  },
  {
    "path": "tests/rules/test_fix_file.py",
    "chars": 7113,
    "preview": "# -*- coding: utf-8 -*-\n\nimport pytest\nimport os\nfrom collections import namedtuple\nfrom thefuck.rules.fix_file import m"
  },
  {
    "path": "tests/rules/test_gem_unknown_command.py",
    "chars": 3517,
    "preview": "import pytest\nfrom six import BytesIO\nfrom thefuck.rules.gem_unknown_command import match, get_new_command\nfrom thefuck."
  },
  {
    "path": "tests/rules/test_git_add.py",
    "chars": 1353,
    "preview": "import pytest\nfrom thefuck.rules.git_add import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.fixtu"
  },
  {
    "path": "tests/rules/test_git_add_force.py",
    "chars": 657,
    "preview": "import pytest\nfrom thefuck.rules.git_add_force import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest"
  },
  {
    "path": "tests/rules/test_git_bisect_usage.py",
    "chars": 993,
    "preview": "import pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.git_bisect_usage import match, get_new_command\n\n\n@pyt"
  },
  {
    "path": "tests/rules/test_git_branch_0flag.py",
    "chars": 1984,
    "preview": "import pytest\n\nfrom thefuck.rules.git_branch_0flag import get_new_command, match\nfrom thefuck.types import Command\n\n\n@py"
  },
  {
    "path": "tests/rules/test_git_branch_delete.py",
    "chars": 606,
    "preview": "import pytest\nfrom thefuck.rules.git_branch_delete import match, get_new_command\nfrom thefuck.types import Command\n\n\n@py"
  },
  {
    "path": "tests/rules/test_git_branch_delete_checked_out.py",
    "chars": 913,
    "preview": "import pytest\nfrom thefuck.rules.git_branch_delete_checked_out import match, get_new_command\nfrom thefuck.types import C"
  },
  {
    "path": "tests/rules/test_git_branch_exists.py",
    "chars": 1463,
    "preview": "import pytest\nfrom thefuck.rules.git_branch_exists import match, get_new_command\nfrom thefuck.types import Command\n\n\n@py"
  },
  {
    "path": "tests/rules/test_git_branch_list.py",
    "chars": 570,
    "preview": "from thefuck.rules.git_branch_list import match, get_new_command\nfrom thefuck.shells import shell\nfrom thefuck.types imp"
  },
  {
    "path": "tests/rules/test_git_checkout.py",
    "chars": 2639,
    "preview": "import pytest\nfrom io import BytesIO\nfrom thefuck.rules.git_checkout import match, get_branches, get_new_command\nfrom th"
  },
  {
    "path": "tests/rules/test_git_clone_git_clone.py",
    "chars": 648,
    "preview": "from thefuck.rules.git_clone_git_clone import match, get_new_command\nfrom thefuck.types import Command\n\n\noutput_clean = "
  },
  {
    "path": "tests/rules/test_git_clone_missing.py",
    "chars": 1613,
    "preview": "import pytest\nfrom thefuck.rules.git_clone_missing import match, get_new_command\nfrom thefuck.types import Command\n\nvali"
  },
  {
    "path": "tests/rules/test_git_commit_add.py",
    "chars": 1039,
    "preview": "import pytest\nfrom thefuck.rules.git_commit_add import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytes"
  },
  {
    "path": "tests/rules/test_git_commit_amend.py",
    "chars": 696,
    "preview": "import pytest\nfrom thefuck.rules.git_commit_amend import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyt"
  },
  {
    "path": "tests/rules/test_git_commit_reset.py",
    "chars": 693,
    "preview": "import pytest\nfrom thefuck.rules.git_commit_reset import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyt"
  },
  {
    "path": "tests/rules/test_git_diff_no_index.py",
    "chars": 689,
    "preview": "import pytest\nfrom thefuck.rules.git_diff_no_index import match, get_new_command\nfrom thefuck.types import Command\n\n\n@py"
  },
  {
    "path": "tests/rules/test_git_diff_staged.py",
    "chars": 757,
    "preview": "import pytest\nfrom thefuck.rules.git_diff_staged import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyte"
  },
  {
    "path": "tests/rules/test_git_fix_stash.py",
    "chars": 1108,
    "preview": "import pytest\nfrom thefuck.rules.git_fix_stash import match, get_new_command\nfrom thefuck.types import Command\n\n\ngit_sta"
  },
  {
    "path": "tests/rules/test_git_flag_after_filename.py",
    "chars": 1649,
    "preview": "import pytest\nfrom thefuck.rules.git_flag_after_filename import match, get_new_command\nfrom thefuck.types import Command"
  },
  {
    "path": "tests/rules/test_git_help_aliased.py",
    "chars": 959,
    "preview": "import pytest\nfrom thefuck.rules.git_help_aliased import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyt"
  },
  {
    "path": "tests/rules/test_git_hook_bypass.py",
    "chars": 1143,
    "preview": "import pytest\nfrom thefuck.rules.git_hook_bypass import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyte"
  },
  {
    "path": "tests/rules/test_git_lfs_mistype.py",
    "chars": 732,
    "preview": "import pytest\n\nfrom thefuck.rules.git_lfs_mistype import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyt"
  },
  {
    "path": "tests/rules/test_git_main_master.py",
    "chars": 1284,
    "preview": "import pytest\nfrom thefuck.rules.git_main_master import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyte"
  },
  {
    "path": "tests/rules/test_git_merge.py",
    "chars": 808,
    "preview": "import pytest\nfrom thefuck.rules.git_merge import match, get_new_command\nfrom thefuck.types import Command\n\n\noutput = 'm"
  },
  {
    "path": "tests/rules/test_git_merge_unrelated.py",
    "chars": 832,
    "preview": "import pytest\nfrom thefuck.rules.git_merge_unrelated import match, get_new_command\nfrom thefuck.types import Command\n\n\no"
  },
  {
    "path": "tests/rules/test_git_not_command.py",
    "chars": 1450,
    "preview": "import pytest\nfrom thefuck.rules.git_not_command import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyte"
  },
  {
    "path": "tests/rules/test_git_pull.py",
    "chars": 797,
    "preview": "import pytest\nfrom thefuck.rules.git_pull import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.fixt"
  },
  {
    "path": "tests/rules/test_git_pull_clone.py",
    "chars": 693,
    "preview": "import pytest\nfrom thefuck.rules.git_pull_clone import match, get_new_command\nfrom thefuck.types import Command\n\n\ngit_er"
  },
  {
    "path": "tests/rules/test_git_pull_uncommitted_changes.py",
    "chars": 546,
    "preview": "import pytest\nfrom thefuck.rules.git_pull_uncommitted_changes import match, get_new_command\nfrom thefuck.types import Co"
  },
  {
    "path": "tests/rules/test_git_pull_unstaged_changes.py",
    "chars": 560,
    "preview": "import pytest\nfrom thefuck.rules.git_pull_uncommitted_changes import match, get_new_command\nfrom thefuck.types import Co"
  },
  {
    "path": "tests/rules/test_git_push.py",
    "chars": 2598,
    "preview": "import pytest\nfrom thefuck.rules.git_push import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.fixt"
  },
  {
    "path": "tests/rules/test_git_push_different_branch_names.py",
    "chars": 1029,
    "preview": "import pytest\nfrom thefuck.rules.git_push_different_branch_names import get_new_command, match\nfrom thefuck.types import"
  },
  {
    "path": "tests/rules/test_git_push_force.py",
    "chars": 1757,
    "preview": "import pytest\nfrom thefuck.rules.git_push_force import match, get_new_command\nfrom thefuck.types import Command\n\n\ngit_er"
  },
  {
    "path": "tests/rules/test_git_push_pull.py",
    "chars": 2614,
    "preview": "import pytest\nfrom thefuck.rules.git_push_pull import match, get_new_command\nfrom thefuck.types import Command\n\n\ngit_err"
  },
  {
    "path": "tests/rules/test_git_push_without_commits.py",
    "chars": 719,
    "preview": "from thefuck.types import Command\nfrom thefuck.rules.git_push_without_commits import get_new_command, match\n\n\ndef test_m"
  },
  {
    "path": "tests/rules/test_git_rebase_merge_dir.py",
    "chars": 1602,
    "preview": "import pytest\nfrom thefuck.rules.git_rebase_merge_dir import match, get_new_command\nfrom thefuck.types import Command\n\n\n"
  },
  {
    "path": "tests/rules/test_git_rebase_no_changes.py",
    "chars": 930,
    "preview": "import pytest\nfrom thefuck.rules.git_rebase_no_changes import match, get_new_command\nfrom thefuck.types import Command\n\n"
  },
  {
    "path": "tests/rules/test_git_remote_delete.py",
    "chars": 702,
    "preview": "import pytest\nfrom thefuck.rules.git_remote_delete import get_new_command, match\nfrom thefuck.types import Command\n\n\ndef"
  },
  {
    "path": "tests/rules/test_git_remote_seturl_add.py",
    "chars": 920,
    "preview": "import pytest\nfrom thefuck.rules.git_remote_seturl_add import match, get_new_command\nfrom thefuck.types import Command\n\n"
  },
  {
    "path": "tests/rules/test_git_rm_local_modifications.py",
    "chars": 1003,
    "preview": "import pytest\nfrom thefuck.rules.git_rm_local_modifications import match, get_new_command\nfrom thefuck.types import Comm"
  },
  {
    "path": "tests/rules/test_git_rm_recursive.py",
    "chars": 852,
    "preview": "import pytest\nfrom thefuck.rules.git_rm_recursive import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyt"
  },
  {
    "path": "tests/rules/test_git_rm_staged.py",
    "chars": 998,
    "preview": "import pytest\nfrom thefuck.rules.git_rm_staged import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest"
  },
  {
    "path": "tests/rules/test_git_stash.py",
    "chars": 1155,
    "preview": "import pytest\nfrom thefuck.rules.git_stash import match, get_new_command\nfrom thefuck.types import Command\n\n\ncherry_pick"
  },
  {
    "path": "tests/rules/test_git_stash_pop.py",
    "chars": 529,
    "preview": "import pytest\nfrom thefuck.rules.git_stash_pop import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest"
  },
  {
    "path": "tests/rules/test_git_tag_force.py",
    "chars": 460,
    "preview": "import pytest\nfrom thefuck.rules.git_tag_force import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest"
  },
  {
    "path": "tests/rules/test_git_two_dashes.py",
    "chars": 1559,
    "preview": "import pytest\nfrom thefuck.rules.git_two_dashes import match, get_new_command\nfrom thefuck.types import Command\n\n\noutput"
  },
  {
    "path": "tests/rules/test_go_run.py",
    "chars": 511,
    "preview": "import pytest\nfrom thefuck.rules.go_run import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark.p"
  },
  {
    "path": "tests/rules/test_go_unknown_command.py",
    "chars": 2564,
    "preview": "import pytest\nfrom io import BytesIO\nfrom thefuck.rules.go_unknown_command import match, get_new_command\nfrom thefuck.ty"
  },
  {
    "path": "tests/rules/test_gradle_not_task.py",
    "chars": 6101,
    "preview": "import pytest\nfrom io import BytesIO\nfrom thefuck.rules.gradle_no_task import match, get_new_command\nfrom thefuck.types "
  },
  {
    "path": "tests/rules/test_gradle_wrapper.py",
    "chars": 1318,
    "preview": "import pytest\nfrom thefuck.rules.gradle_wrapper import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytes"
  },
  {
    "path": "tests/rules/test_grep_arguments_order.py",
    "chars": 1411,
    "preview": "import pytest\nfrom thefuck.rules.grep_arguments_order import get_new_command, match\nfrom thefuck.types import Command\n\no"
  },
  {
    "path": "tests/rules/test_grep_recursive.py",
    "chars": 500,
    "preview": "# -*- coding: utf-8 -*-\n\nfrom thefuck.rules.grep_recursive import match, get_new_command\nfrom thefuck.types import Comma"
  },
  {
    "path": "tests/rules/test_grunt_task_not_found.py",
    "chars": 5303,
    "preview": "# -*- encoding: utf-8 -*-\n\nfrom io import BytesIO\nimport pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.gru"
  },
  {
    "path": "tests/rules/test_gulp_not_task.py",
    "chars": 875,
    "preview": "import pytest\nfrom io import BytesIO\nfrom thefuck.types import Command\nfrom thefuck.rules.gulp_not_task import match, ge"
  },
  {
    "path": "tests/rules/test_has_exists_script.py",
    "chars": 637,
    "preview": "from mock import patch\nfrom thefuck.rules.has_exists_script import match, get_new_command\nfrom thefuck.types import Comm"
  },
  {
    "path": "tests/rules/test_heroku_multiple_apps.py",
    "chars": 1701,
    "preview": "# -*- coding: utf-8 -*-\n\nimport pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.heroku_multiple_apps import "
  },
  {
    "path": "tests/rules/test_heroku_not_command.py",
    "chars": 851,
    "preview": "# -*- coding: utf-8 -*-\n\nimport pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.heroku_not_command import ma"
  },
  {
    "path": "tests/rules/test_history.py",
    "chars": 765,
    "preview": "import pytest\nfrom thefuck.rules.history import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.fixtu"
  },
  {
    "path": "tests/rules/test_hostscli.py",
    "chars": 858,
    "preview": "import pytest\nfrom thefuck.rules.hostscli import no_website, get_new_command, match\nfrom thefuck.types import Command\n\nn"
  },
  {
    "path": "tests/rules/test_ifconfig_device_not_found.py",
    "chars": 1726,
    "preview": "import pytest\nfrom six import BytesIO\nfrom thefuck.rules.ifconfig_device_not_found import match, get_new_command\nfrom th"
  },
  {
    "path": "tests/rules/test_java.py",
    "chars": 511,
    "preview": "import pytest\nfrom thefuck.rules.java import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark.par"
  },
  {
    "path": "tests/rules/test_javac.py",
    "chars": 508,
    "preview": "import pytest\nfrom thefuck.rules.javac import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark.pa"
  },
  {
    "path": "tests/rules/test_lein_not_task.py",
    "chars": 548,
    "preview": "import pytest\nfrom thefuck.rules.lein_not_task import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest"
  },
  {
    "path": "tests/rules/test_ln_no_hard_link.py",
    "chars": 1177,
    "preview": "# -*- coding: utf-8 -*-\nimport pytest\nfrom thefuck.rules.ln_no_hard_link import match, get_new_command\nfrom thefuck.type"
  },
  {
    "path": "tests/rules/test_ln_s_order.py",
    "chars": 1088,
    "preview": "import pytest\nfrom thefuck.rules.ln_s_order import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.fi"
  },
  {
    "path": "tests/rules/test_long_form_help.py",
    "chars": 613,
    "preview": "import pytest\nfrom thefuck.rules.long_form_help import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytes"
  },
  {
    "path": "tests/rules/test_ls_all.py",
    "chars": 359,
    "preview": "from thefuck.rules.ls_all import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_match():\n    assert"
  },
  {
    "path": "tests/rules/test_ls_lah.py",
    "chars": 543,
    "preview": "from thefuck.rules.ls_lah import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_match():\n    assert"
  },
  {
    "path": "tests/rules/test_man.py",
    "chars": 1181,
    "preview": "import pytest\nfrom thefuck.rules.man import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark.para"
  },
  {
    "path": "tests/rules/test_man_no_space.py",
    "chars": 316,
    "preview": "from thefuck.rules.man_no_space import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_match():\n    "
  },
  {
    "path": "tests/rules/test_mercurial.py",
    "chars": 4260,
    "preview": "import pytest\n\nfrom thefuck.types import Command\nfrom thefuck.rules.mercurial import (\n    extract_possibilities, match,"
  },
  {
    "path": "tests/rules/test_missing_space_before_subcommand.py",
    "chars": 929,
    "preview": "import pytest\nfrom thefuck.rules.missing_space_before_subcommand import (\n    match, get_new_command)\nfrom thefuck.types"
  },
  {
    "path": "tests/rules/test_mkdir_p.py",
    "chars": 1186,
    "preview": "import pytest\nfrom thefuck.rules.mkdir_p import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark."
  },
  {
    "path": "tests/rules/test_mvn_no_command.py",
    "chars": 3596,
    "preview": "import pytest\nfrom thefuck.rules.mvn_no_command import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytes"
  },
  {
    "path": "tests/rules/test_mvn_unknown_lifecycle_phase.py",
    "chars": 3547,
    "preview": "import pytest\nfrom thefuck.rules.mvn_unknown_lifecycle_phase import match, get_new_command\nfrom thefuck.types import Com"
  },
  {
    "path": "tests/rules/test_nixos_cmd_not_found.py",
    "chars": 892,
    "preview": "import pytest\nfrom thefuck.rules.nixos_cmd_not_found import match, get_new_command\nfrom thefuck.types import Command\n\n\n@"
  },
  {
    "path": "tests/rules/test_no_command.py",
    "chars": 1771,
    "preview": "import pytest\nfrom thefuck.rules.no_command import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.fi"
  },
  {
    "path": "tests/rules/test_no_such_file.py",
    "chars": 990,
    "preview": "import pytest\nfrom thefuck.rules.no_such_file import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest."
  },
  {
    "path": "tests/rules/test_npm_missing_script.py",
    "chars": 2120,
    "preview": "import pytest\nfrom io import BytesIO\nfrom thefuck.types import Command\nfrom thefuck.rules.npm_missing_script import matc"
  },
  {
    "path": "tests/rules/test_npm_run_script.py",
    "chars": 2870,
    "preview": "import pytest\nfrom io import BytesIO\nfrom thefuck.rules.npm_run_script import match, get_new_command\nfrom thefuck.types "
  },
  {
    "path": "tests/rules/test_npm_wrong_command.py",
    "chars": 1919,
    "preview": "import pytest\nfrom thefuck.rules.npm_wrong_command import match, get_new_command\nfrom thefuck.types import Command\n\noutp"
  },
  {
    "path": "tests/rules/test_omnienv_no_such_command.py",
    "chars": 2037,
    "preview": "import pytest\n\nfrom thefuck.rules.omnienv_no_such_command import get_new_command, match\nfrom thefuck.types import Comman"
  },
  {
    "path": "tests/rules/test_open.py",
    "chars": 1418,
    "preview": "import pytest\nfrom thefuck.rules.open import is_arg_url, match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyt"
  },
  {
    "path": "tests/rules/test_pacman.py",
    "chars": 3677,
    "preview": "import pytest\nfrom mock import patch\nfrom thefuck.rules import pacman\nfrom thefuck.rules.pacman import match, get_new_co"
  },
  {
    "path": "tests/rules/test_pacman_invalid_option.py",
    "chars": 1004,
    "preview": "import pytest\nfrom thefuck.rules.pacman_invalid_option import get_new_command, match\nfrom thefuck.types import Command\n\n"
  },
  {
    "path": "tests/rules/test_pacman_not_found.py",
    "chars": 3053,
    "preview": "import pytest\nfrom mock import patch\nfrom thefuck.rules import pacman_not_found\nfrom thefuck.rules.pacman_not_found impo"
  },
  {
    "path": "tests/rules/test_path_from_history.py",
    "chars": 1362,
    "preview": "import pytest\nfrom thefuck.rules.path_from_history import match, get_new_command\nfrom thefuck.types import Command\n\n\n@py"
  },
  {
    "path": "tests/rules/test_php_s.py",
    "chars": 761,
    "preview": "import pytest\nfrom thefuck.rules.php_s import get_new_command, match\nfrom thefuck.types import Command\n\n\n@pytest.mark.pa"
  },
  {
    "path": "tests/rules/test_pip_install.py",
    "chars": 1228,
    "preview": "# -*- coding: UTF-8 -*-\nfrom thefuck.rules.pip_install import match, get_new_command\nfrom thefuck.types import Command\n\n"
  },
  {
    "path": "tests/rules/test_pip_unknown_command.py",
    "chars": 1085,
    "preview": "import pytest\nfrom thefuck.rules.pip_unknown_command import match, get_new_command\nfrom thefuck.types import Command\n\n\n@"
  },
  {
    "path": "tests/rules/test_port_already_in_use.py",
    "chars": 3441,
    "preview": "from io import BytesIO\n\nimport pytest\nfrom thefuck.rules.port_already_in_use import match, get_new_command\nfrom thefuck."
  },
  {
    "path": "tests/rules/test_prove_recursively.py",
    "chars": 1173,
    "preview": "import pytest\nfrom thefuck.rules.prove_recursively import match, get_new_command\nfrom thefuck.types import Command\n\n\nout"
  },
  {
    "path": "tests/rules/test_python_command.py",
    "chars": 343,
    "preview": "from thefuck.rules.python_command import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_match():\n  "
  },
  {
    "path": "tests/rules/test_python_execute.py",
    "chars": 519,
    "preview": "import pytest\nfrom thefuck.rules.python_execute import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytes"
  },
  {
    "path": "tests/rules/test_python_module_error.py",
    "chars": 1629,
    "preview": "import pytest\n\nfrom thefuck.rules.python_module_error import get_new_command, match\nfrom thefuck.types import Command\n\n\n"
  },
  {
    "path": "tests/rules/test_quotation_marks.py",
    "chars": 763,
    "preview": "import pytest\nfrom thefuck.rules.quotation_marks import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyte"
  },
  {
    "path": "tests/rules/test_rails_migrations_pending.py",
    "chars": 1169,
    "preview": "import pytest\nfrom thefuck.rules.rails_migrations_pending import match, get_new_command\nfrom thefuck.types import Comman"
  },
  {
    "path": "tests/rules/test_react_native_command_unrecognized.py",
    "chars": 2567,
    "preview": "import pytest\nfrom io import BytesIO\nfrom thefuck.rules.react_native_command_unrecognized import match, \\\n    get_new_co"
  },
  {
    "path": "tests/rules/test_remove_shell_prompt_literal.py",
    "chars": 1169,
    "preview": "import pytest\nfrom thefuck.rules.remove_shell_prompt_literal import match, get_new_command\nfrom thefuck.types import Com"
  },
  {
    "path": "tests/rules/test_remove_trailing_cedilla.py",
    "chars": 571,
    "preview": "import pytest\nfrom thefuck.rules.remove_trailing_cedilla import match, get_new_command, CEDILLA\nfrom thefuck.types impor"
  },
  {
    "path": "tests/rules/test_rm_dir.py",
    "chars": 918,
    "preview": "import pytest\nfrom thefuck.rules.rm_dir import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark.p"
  },
  {
    "path": "tests/rules/test_rm_root.py",
    "chars": 558,
    "preview": "import pytest\nfrom thefuck.rules.rm_root import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_matc"
  },
  {
    "path": "tests/rules/test_scm_correction.py",
    "chars": 1697,
    "preview": "import pytest\nfrom thefuck.rules.scm_correction import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytes"
  },
  {
    "path": "tests/rules/test_sed_unterminated_s.py",
    "chars": 1186,
    "preview": "import pytest\nfrom thefuck.rules.sed_unterminated_s import match, get_new_command\nfrom thefuck.types import Command\n\n\n@p"
  },
  {
    "path": "tests/rules/test_sl_ls.py",
    "chars": 270,
    "preview": "\nfrom thefuck.rules.sl_ls import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_match():\n    assert"
  },
  {
    "path": "tests/rules/test_ssh_known_host.py",
    "chars": 2383,
    "preview": "import os\nimport pytest\nfrom thefuck.rules.ssh_known_hosts import match, get_new_command, \\\n    side_effect\nfrom thefuck"
  },
  {
    "path": "tests/rules/test_sudo.py",
    "chars": 1225,
    "preview": "import pytest\nfrom thefuck.rules.sudo import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark.par"
  },
  {
    "path": "tests/rules/test_sudo_command_from_user_path.py",
    "chars": 1388,
    "preview": "import pytest\nfrom thefuck.rules.sudo_command_from_user_path import match, get_new_command\nfrom thefuck.types import Com"
  },
  {
    "path": "tests/rules/test_switch_lang.py",
    "chars": 1361,
    "preview": "# -*- encoding: utf-8 -*-\n\nimport pytest\n\nfrom thefuck.rules import switch_lang\nfrom thefuck.types import Command\n\n\n@pyt"
  },
  {
    "path": "tests/rules/test_systemctl.py",
    "chars": 938,
    "preview": "from thefuck.rules.systemctl import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef test_match():\n    ass"
  },
  {
    "path": "tests/rules/test_terraform_init.py",
    "chars": 1455,
    "preview": "import pytest\nfrom thefuck.rules.terraform_init import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytes"
  },
  {
    "path": "tests/rules/test_terraform_no_command.py",
    "chars": 1218,
    "preview": "import pytest\nfrom thefuck.rules.terraform_no_command import match, get_new_command\nfrom thefuck.types import Command\n\n\n"
  },
  {
    "path": "tests/rules/test_tmux.py",
    "chars": 585,
    "preview": "import pytest\nfrom thefuck.rules.tmux import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.fixture\n"
  },
  {
    "path": "tests/rules/test_touch.py",
    "chars": 948,
    "preview": "import pytest\nfrom thefuck.rules.touch import match, get_new_command\nfrom thefuck.types import Command\n\n\ndef output(is_b"
  },
  {
    "path": "tests/rules/test_tsuru_login.py",
    "chars": 1078,
    "preview": "import pytest\nfrom thefuck.rules.tsuru_login import match, get_new_command\nfrom thefuck.types import Command\n\n\nerror_msg"
  },
  {
    "path": "tests/rules/test_tsuru_not_command.py",
    "chars": 2671,
    "preview": "import pytest\n\nfrom thefuck.types import Command\nfrom thefuck.rules.tsuru_not_command import match, get_new_command\n\n\n@p"
  },
  {
    "path": "tests/rules/test_unknown_command.py",
    "chars": 1612,
    "preview": "import pytest\nfrom thefuck.rules.unknown_command import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pyte"
  },
  {
    "path": "tests/rules/test_unsudo.py",
    "chars": 694,
    "preview": "import pytest\nfrom thefuck.rules.unsudo import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark.p"
  },
  {
    "path": "tests/rules/test_vagrant_up.py",
    "chars": 2165,
    "preview": "import pytest\nfrom thefuck.rules.vagrant_up import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.ma"
  },
  {
    "path": "tests/rules/test_whois.py",
    "chars": 953,
    "preview": "import pytest\nfrom thefuck.rules.whois import match, get_new_command\nfrom thefuck.types import Command\n\n\n@pytest.mark.pa"
  },
  {
    "path": "tests/rules/test_workon_doesnt_exists.py",
    "chars": 922,
    "preview": "import pytest\nfrom thefuck.rules.workon_doesnt_exists import match, get_new_command\nfrom thefuck.types import Command\n\n\n"
  },
  {
    "path": "tests/rules/test_wrong_hyphen_before_subcommand.py",
    "chars": 890,
    "preview": "import pytest\n\nfrom thefuck.rules.wrong_hyphen_before_subcommand import match, get_new_command\nfrom thefuck.types import"
  },
  {
    "path": "tests/rules/test_yarn_alias.py",
    "chars": 796,
    "preview": "import pytest\nfrom thefuck.rules.yarn_alias import match, get_new_command\nfrom thefuck.types import Command\n\n\noutput_rem"
  },
  {
    "path": "tests/rules/test_yarn_command_not_found.py",
    "chars": 3812,
    "preview": "# -*- encoding: utf-8 -*-\n\nfrom io import BytesIO\nimport pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.yar"
  },
  {
    "path": "tests/rules/test_yarn_command_replaced.py",
    "chars": 1026,
    "preview": "import pytest\nfrom thefuck.types import Command\nfrom thefuck.rules.yarn_command_replaced import match, get_new_command\n\n"
  }
]

// ... and 234 more files (download for full content)

About this extraction

This page contains the full source code of the nvbn/thefuck GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 434 files (568.5 KB), approximately 153.3k tokens, and a symbol index with 1470 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!