mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-31 02:01:13 +00:00
Move all app/os specific utils to specific
package
This commit is contained in:
parent
2e002f666b
commit
b21c9ebb43
@ -29,7 +29,7 @@ def test_match(command):
|
||||
@pytest.mark.parametrize('command, return_value', [
|
||||
(Command(script='vim', stderr='vim: command not found'), PKGFILE_OUTPUT_VIM),
|
||||
(Command(script='sudo vim', stderr='sudo: vim: command not found'), PKGFILE_OUTPUT_VIM)])
|
||||
@patch('thefuck.utils.subprocess')
|
||||
@patch('thefuck.specific.archlinux.subprocess')
|
||||
@patch.multiple(pacman, create=True, pacman=pacman_cmd)
|
||||
def test_match_mocked(subp_mock, command, return_value):
|
||||
subp_mock.check_output.return_value = return_value
|
||||
@ -75,7 +75,7 @@ def test_get_new_command(command, new_command, mocker):
|
||||
(Command('convert'), ['{} -S extra/imagemagick && convert'.format(pacman_cmd)], PKGFILE_OUTPUT_CONVERT),
|
||||
(Command('sudo'), ['{} -S core/sudo && sudo'.format(pacman_cmd)], PKGFILE_OUTPUT_SUDO),
|
||||
(Command('sudo convert'), ['{} -S extra/imagemagick && sudo convert'.format(pacman_cmd)], PKGFILE_OUTPUT_CONVERT)])
|
||||
@patch('thefuck.utils.subprocess')
|
||||
@patch('thefuck.specific.archlinux.subprocess')
|
||||
@patch.multiple(pacman, create=True, pacman=pacman_cmd)
|
||||
def test_get_new_command_mocked(subp_mock, command, new_command, return_value):
|
||||
subp_mock.check_output.return_value = return_value
|
||||
|
@ -22,7 +22,7 @@ def test_match(command):
|
||||
Command(script='yaourt -S llc', stderr='error: target not found: llc'),
|
||||
Command(script='pacman llc', stderr='error: target not found: llc'),
|
||||
Command(script='sudo pacman llc', stderr='error: target not found: llc')])
|
||||
@patch('thefuck.utils.subprocess')
|
||||
@patch('thefuck.specific.archlinux.subprocess')
|
||||
def test_match_mocked(subp_mock, command):
|
||||
subp_mock.check_output.return_value = PKGFILE_OUTPUT_LLC
|
||||
assert match(command, None)
|
||||
@ -42,7 +42,7 @@ def test_get_new_command(command, fixed):
|
||||
(Command(script='yaourt -S llc', stderr='error: target not found: llc'), ['yaourt -S extra/llvm', 'yaourt -S extra/llvm35']),
|
||||
(Command(script='pacman -S llc', stderr='error: target not found: llc'), ['pacman -S extra/llvm', 'pacman -S extra/llvm35']),
|
||||
(Command(script='sudo pacman -S llc', stderr='error: target not found: llc'), ['sudo pacman -S extra/llvm', 'sudo pacman -S extra/llvm35'])])
|
||||
@patch('thefuck.utils.subprocess')
|
||||
@patch('thefuck.specific.archlinux.subprocess')
|
||||
def test_get_new_command_mocked(subp_mock, command, fixed):
|
||||
subp_mock.check_output.return_value = PKGFILE_OUTPUT_LLC
|
||||
assert get_new_command(command, None) == fixed
|
||||
|
0
tests/specific/__init__.py
Normal file
0
tests/specific/__init__.py
Normal file
29
tests/specific/test_git.py
Normal file
29
tests/specific/test_git.py
Normal file
@ -0,0 +1,29 @@
|
||||
import pytest
|
||||
from thefuck.specific.git import git_support
|
||||
from tests.utils import Command
|
||||
|
||||
|
||||
@pytest.mark.parametrize('called, command, stderr', [
|
||||
('git co', 'git checkout', "19:22:36.299340 git.c:282 trace: alias expansion: co => 'checkout'"),
|
||||
('git com file', 'git commit --verbose file',
|
||||
"19:23:25.470911 git.c:282 trace: alias expansion: com => 'commit' '--verbose'")])
|
||||
def test_git_support(called, command, stderr):
|
||||
@git_support
|
||||
def fn(command, settings): return command.script
|
||||
|
||||
assert fn(Command(script=called, stderr=stderr), None) == command
|
||||
|
||||
|
||||
@pytest.mark.parametrize('command, is_git', [
|
||||
('git pull', True),
|
||||
('hub pull', True),
|
||||
('git push --set-upstream origin foo', True),
|
||||
('hub push --set-upstream origin foo', True),
|
||||
('ls', False),
|
||||
('cat git', False),
|
||||
('cat hub', False)])
|
||||
def test_git_support_match(command, is_git):
|
||||
@git_support
|
||||
def fn(command, settings): return True
|
||||
|
||||
assert fn(Command(script=command), None) == is_git
|
18
tests/specific/test_sudo.py
Normal file
18
tests/specific/test_sudo.py
Normal file
@ -0,0 +1,18 @@
|
||||
import pytest
|
||||
from mock import Mock
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
from tests.utils import Command
|
||||
|
||||
|
||||
@pytest.mark.parametrize('return_value, command, called, result', [
|
||||
('ls -lah', 'sudo ls', 'ls', 'sudo ls -lah'),
|
||||
('ls -lah', 'ls', 'ls', 'ls -lah'),
|
||||
(['ls -lah'], 'sudo ls', 'ls', ['sudo ls -lah']),
|
||||
(True, 'sudo ls', 'ls', True),
|
||||
(True, 'ls', 'ls', True),
|
||||
(False, 'sudo ls', 'ls', False),
|
||||
(False, 'ls', 'ls', False)])
|
||||
def test_sudo_support(return_value, command, called, result):
|
||||
fn = Mock(return_value=return_value, __name__='')
|
||||
assert sudo_support(fn)(Command(command), None) == result
|
||||
fn.assert_called_once_with(Command(called), None)
|
@ -1,10 +1,9 @@
|
||||
import pytest
|
||||
from mock import Mock
|
||||
from thefuck.utils import git_support, sudo_support, wrap_settings,\
|
||||
from thefuck.utils import wrap_settings,\
|
||||
memoize, get_closest, get_all_executables, replace_argument, \
|
||||
get_all_matched_commands
|
||||
from thefuck.types import Settings
|
||||
from tests.utils import Command
|
||||
|
||||
|
||||
@pytest.mark.parametrize('override, old, new', [
|
||||
@ -16,43 +15,6 @@ def test_wrap_settings(override, old, new):
|
||||
assert wrap_settings(override)(fn)(None, Settings(old)) == new
|
||||
|
||||
|
||||
@pytest.mark.parametrize('return_value, command, called, result', [
|
||||
('ls -lah', 'sudo ls', 'ls', 'sudo ls -lah'),
|
||||
('ls -lah', 'ls', 'ls', 'ls -lah'),
|
||||
(['ls -lah'], 'sudo ls', 'ls', ['sudo ls -lah']),
|
||||
(True, 'sudo ls', 'ls', True),
|
||||
(True, 'ls', 'ls', True),
|
||||
(False, 'sudo ls', 'ls', False),
|
||||
(False, 'ls', 'ls', False)])
|
||||
def test_sudo_support(return_value, command, called, result):
|
||||
fn = Mock(return_value=return_value, __name__='')
|
||||
assert sudo_support(fn)(Command(command), None) == result
|
||||
fn.assert_called_once_with(Command(called), None)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('called, command, stderr', [
|
||||
('git co', 'git checkout', "19:22:36.299340 git.c:282 trace: alias expansion: co => 'checkout'"),
|
||||
('git com file', 'git commit --verbose file', "19:23:25.470911 git.c:282 trace: alias expansion: com => 'commit' '--verbose'")])
|
||||
def test_git_support(called, command, stderr):
|
||||
@git_support
|
||||
def fn(command, settings): return command.script
|
||||
assert fn(Command(script=called, stderr=stderr), None) == command
|
||||
|
||||
|
||||
@pytest.mark.parametrize('command, is_git', [
|
||||
('git pull', True),
|
||||
('hub pull', True),
|
||||
('git push --set-upstream origin foo', True),
|
||||
('hub push --set-upstream origin foo', True),
|
||||
('ls', False),
|
||||
('cat git', False),
|
||||
('cat hub', False)])
|
||||
def test_git_support_match(command, is_git):
|
||||
@git_support
|
||||
def fn(command, settings): return True
|
||||
assert fn(Command(script=command), None) == is_git
|
||||
|
||||
|
||||
def test_memoize():
|
||||
fn = Mock(__name__='fn')
|
||||
memoized = memoize(fn)
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import os
|
||||
from difflib import get_close_matches
|
||||
from thefuck.utils import sudo_support
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
from thefuck.rules import cd_mkdir
|
||||
|
||||
__author__ = "mmussomele"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import re
|
||||
from thefuck import shells
|
||||
from thefuck.utils import sudo_support
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
@ -1,5 +1,5 @@
|
||||
import re
|
||||
from thefuck.utils import sudo_support
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
@ -1,7 +1,8 @@
|
||||
from itertools import dropwhile, takewhile, islice
|
||||
import re
|
||||
import subprocess
|
||||
from thefuck.utils import sudo_support, replace_command
|
||||
from thefuck.utils import replace_command
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
import re
|
||||
from thefuck.utils import sudo_support
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
@ -1,14 +1,15 @@
|
||||
import re
|
||||
from thefuck import utils, shells
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return ('did not match any file(s) known to git.' in command.stderr
|
||||
and "Did you forget to 'git add'?" in command.stderr)
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
missing_file = re.findall(
|
||||
r"error: pathspec '([^']*)' "
|
||||
|
@ -1,13 +1,14 @@
|
||||
from thefuck import utils
|
||||
from thefuck.utils import replace_argument
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return ('branch -d' in command.script
|
||||
and 'If you are sure you want to delete it' in command.stderr)
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
return replace_argument(command.script, '-d', '-D')
|
||||
|
@ -1,12 +1,13 @@
|
||||
from thefuck import utils, shells
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
# catches "git branch list" in place of "git branch"
|
||||
return command.script.split()[1:] == 'branch list'.split()
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
return shells.and_('git branch --delete list', 'git branch')
|
||||
|
@ -2,9 +2,10 @@ import re
|
||||
import subprocess
|
||||
from thefuck import shells, utils
|
||||
from thefuck.utils import replace_argument
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return ('did not match any file(s) known to git.' in command.stderr
|
||||
and "Did you forget to 'git add'?" not in command.stderr)
|
||||
@ -23,7 +24,7 @@ def get_branches():
|
||||
yield line.strip()
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
missing_file = re.findall(
|
||||
r"error: pathspec '([^']*)' "
|
||||
|
@ -1,13 +1,14 @@
|
||||
from thefuck import utils
|
||||
from thefuck.utils import replace_argument
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return ('diff' in command.script and
|
||||
'--staged' not in command.script)
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
return replace_argument(command.script, 'diff', 'diff --staged')
|
||||
|
@ -1,8 +1,9 @@
|
||||
from thefuck import utils
|
||||
from thefuck.utils import replace_argument
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return (command.script.split()[1] == 'stash'
|
||||
and 'usage:' in command.stderr)
|
||||
@ -19,7 +20,7 @@ stash_commands = (
|
||||
'show')
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
stash_cmd = command.script.split()[2]
|
||||
fixed = utils.get_closest(stash_cmd, stash_commands, fallback_to_first=False)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import re
|
||||
from thefuck.utils import (git_support,
|
||||
get_all_matched_commands, replace_command)
|
||||
from thefuck.utils import get_all_matched_commands, replace_command
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@git_support
|
||||
|
@ -1,13 +1,14 @@
|
||||
from thefuck import shells, utils
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return ('pull' in command.script
|
||||
and 'set-upstream' in command.stderr)
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
line = command.stderr.split('\n')[-3].strip()
|
||||
branch = line.split(' ')[-1]
|
||||
|
@ -1,13 +1,14 @@
|
||||
from thefuck import utils
|
||||
from thefuck.utils import replace_argument
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return ('fatal: Not a git repository' in command.stderr
|
||||
and "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)." in command.stderr)
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
return replace_argument(command.script, 'pull', 'clone')
|
||||
|
@ -1,12 +1,13 @@
|
||||
from thefuck import utils
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return ('push' in command.script
|
||||
and 'set-upstream' in command.stderr)
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
return command.stderr.split('\n')[-3].strip()
|
||||
|
@ -1,8 +1,9 @@
|
||||
from thefuck import utils
|
||||
from thefuck.utils import replace_argument
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return ('push' in command.script
|
||||
and '! [rejected]' in command.stderr
|
||||
@ -10,7 +11,7 @@ def match(command, settings):
|
||||
and 'Updates were rejected because the tip of your current branch is behind' in command.stderr)
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
return replace_argument(command.script, 'push', 'push --force')
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
from thefuck import utils, shells
|
||||
from thefuck.utils import replace_argument
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
return ('push' in command.script
|
||||
and '! [rejected]' in command.stderr
|
||||
@ -10,7 +11,7 @@ def match(command, settings):
|
||||
and 'Updates were rejected because the tip of your current branch is behind' in command.stderr)
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
return shells.and_(replace_argument(command.script, 'push', 'pull'),
|
||||
command.script)
|
||||
|
@ -1,14 +1,15 @@
|
||||
from thefuck import shells, utils
|
||||
from thefuck.specific.git import git_support
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def match(command, settings):
|
||||
# catches "Please commit or stash them" and "Please, commit your changes or
|
||||
# stash them before you can switch branches."
|
||||
return 'or stash them' in command.stderr
|
||||
|
||||
|
||||
@utils.git_support
|
||||
@git_support
|
||||
def get_new_command(command, settings):
|
||||
formatme = shells.and_('git stash', '{}')
|
||||
return formatme.format(command.script)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import os
|
||||
from thefuck.utils import sudo_support
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
@ -1,6 +1,6 @@
|
||||
import re
|
||||
from thefuck.utils import sudo_support,\
|
||||
replace_command, get_all_matched_commands
|
||||
from thefuck.utils import replace_command, get_all_matched_commands
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
@ -1,5 +1,5 @@
|
||||
import re
|
||||
from thefuck.utils import sudo_support
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
@ -1,5 +1,6 @@
|
||||
from difflib import get_close_matches
|
||||
from thefuck.utils import sudo_support, get_all_executables
|
||||
from thefuck.utils import get_all_executables
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
@ -1,4 +1,4 @@
|
||||
from thefuck.utils import get_pkgfile, archlinux_env
|
||||
from thefuck.specific.archlinux import get_pkgfile, archlinux_env
|
||||
from thefuck import shells
|
||||
|
||||
|
||||
|
@ -6,7 +6,8 @@ should be:
|
||||
yaourt -S llvm
|
||||
"""
|
||||
|
||||
from thefuck.utils import replace_command, get_pkgfile, archlinux_env
|
||||
from thefuck.utils import replace_command
|
||||
from thefuck.specific.archlinux import get_pkgfile, archlinux_env
|
||||
|
||||
|
||||
def match(command, settings):
|
||||
|
@ -1,4 +1,4 @@
|
||||
from thefuck.utils import sudo_support
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
# add 'python' suffix to the command if
|
||||
# 1) The script does not have execute permission or
|
||||
# 2) is interpreted as shell script
|
||||
|
@ -1,5 +1,5 @@
|
||||
import re
|
||||
from thefuck.utils import sudo_support
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
@ -1,5 +1,4 @@
|
||||
from thefuck.utils import sudo_support
|
||||
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
enabled_by_default = False
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""
|
||||
The confusion in systemctl's param order is massive.
|
||||
"""
|
||||
from thefuck.utils import sudo_support
|
||||
from thefuck.specific.sudo import sudo_support
|
||||
|
||||
|
||||
@sudo_support
|
||||
|
0
thefuck/specific/__init__.py
Normal file
0
thefuck/specific/__init__.py
Normal file
41
thefuck/specific/archlinux.py
Normal file
41
thefuck/specific/archlinux.py
Normal file
@ -0,0 +1,41 @@
|
||||
""" This file provide some utility functions for Arch Linux specific rules."""
|
||||
import thefuck.utils
|
||||
import subprocess
|
||||
|
||||
|
||||
@thefuck.utils.memoize
|
||||
def get_pkgfile(command):
|
||||
""" Gets the packages that provide the given command using `pkgfile`.
|
||||
|
||||
If the command is of the form `sudo foo`, searches for the `foo` command
|
||||
instead.
|
||||
"""
|
||||
try:
|
||||
command = command.strip()
|
||||
|
||||
if command.startswith('sudo '):
|
||||
command = command[5:]
|
||||
|
||||
command = command.split(" ")[0]
|
||||
|
||||
packages = subprocess.check_output(
|
||||
['pkgfile', '-b', '-v', command],
|
||||
universal_newlines=True, stderr=thefuck.utils.DEVNULL
|
||||
).splitlines()
|
||||
|
||||
return [package.split()[0] for package in packages]
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
|
||||
def archlinux_env():
|
||||
if thefuck.utils.which('yaourt'):
|
||||
pacman = 'yaourt'
|
||||
elif thefuck.utils.which('pacman'):
|
||||
pacman = 'sudo pacman'
|
||||
else:
|
||||
return False, None
|
||||
|
||||
enabled_by_default = thefuck.utils.which('pkgfile')
|
||||
|
||||
return enabled_by_default, pacman
|
37
thefuck/specific/git.py
Normal file
37
thefuck/specific/git.py
Normal file
@ -0,0 +1,37 @@
|
||||
from functools import wraps
|
||||
import re
|
||||
from shlex import split
|
||||
from ..types import Command
|
||||
from ..utils import quote
|
||||
|
||||
|
||||
def git_support(fn):
|
||||
"""Resolves git aliases and supports testing for both git and hub."""
|
||||
@wraps(fn)
|
||||
def wrapper(command, settings):
|
||||
# supports GitHub's `hub` command
|
||||
# which is recommended to be used with `alias git=hub`
|
||||
# but at this point, shell aliases have already been resolved
|
||||
is_git_cmd = command.script.startswith(('git', 'hub'))
|
||||
|
||||
if not is_git_cmd:
|
||||
return False
|
||||
|
||||
# perform git aliases expansion
|
||||
if 'trace: alias expansion:' in command.stderr:
|
||||
search = re.search("trace: alias expansion: ([^ ]*) => ([^\n]*)",
|
||||
command.stderr)
|
||||
alias = search.group(1)
|
||||
|
||||
# by default git quotes everything, for example:
|
||||
# 'commit' '--amend'
|
||||
# which is surprising and does not allow to easily test for
|
||||
# eg. 'git commit'
|
||||
expansion = ' '.join(map(quote, split(search.group(2))))
|
||||
new_script = command.script.replace(alias, expansion)
|
||||
|
||||
command = Command._replace(command, script=new_script)
|
||||
|
||||
return fn(command, settings)
|
||||
|
||||
return wrapper
|
24
thefuck/specific/sudo.py
Normal file
24
thefuck/specific/sudo.py
Normal file
@ -0,0 +1,24 @@
|
||||
from functools import wraps
|
||||
import six
|
||||
from ..types import Command
|
||||
|
||||
|
||||
def sudo_support(fn):
|
||||
"""Removes sudo before calling fn and adds it after."""
|
||||
@wraps(fn)
|
||||
def wrapper(command, settings):
|
||||
if not command.script.startswith('sudo '):
|
||||
return fn(command, settings)
|
||||
|
||||
result = fn(Command(command.script[5:],
|
||||
command.stdout,
|
||||
command.stderr),
|
||||
settings)
|
||||
|
||||
if result and isinstance(result, six.string_types):
|
||||
return u'sudo {}'.format(result)
|
||||
elif isinstance(result, list):
|
||||
return [u'sudo {}'.format(x) for x in result]
|
||||
else:
|
||||
return result
|
||||
return wrapper
|
@ -1,14 +1,12 @@
|
||||
from subprocess import CalledProcessError
|
||||
import subprocess
|
||||
from difflib import get_close_matches
|
||||
from functools import wraps
|
||||
from pathlib import Path
|
||||
from shlex import split
|
||||
|
||||
import os
|
||||
import pickle
|
||||
import re
|
||||
|
||||
from pathlib import Path
|
||||
import six
|
||||
from .types import Command
|
||||
|
||||
|
||||
DEVNULL = open(os.devnull, 'w')
|
||||
@ -57,59 +55,6 @@ def wrap_settings(params):
|
||||
return decorator
|
||||
|
||||
|
||||
def sudo_support(fn):
|
||||
"""Removes sudo before calling fn and adds it after."""
|
||||
@wraps(fn)
|
||||
def wrapper(command, settings):
|
||||
if not command.script.startswith('sudo '):
|
||||
return fn(command, settings)
|
||||
|
||||
result = fn(Command(command.script[5:],
|
||||
command.stdout,
|
||||
command.stderr),
|
||||
settings)
|
||||
|
||||
if result and isinstance(result, six.string_types):
|
||||
return u'sudo {}'.format(result)
|
||||
elif isinstance(result, list):
|
||||
return [u'sudo {}'.format(x) for x in result]
|
||||
else:
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
|
||||
def git_support(fn):
|
||||
"""Resolves git aliases and supports testing for both git and hub."""
|
||||
@wraps(fn)
|
||||
def wrapper(command, settings):
|
||||
# supports GitHub's `hub` command
|
||||
# which is recommended to be used with `alias git=hub`
|
||||
# but at this point, shell aliases have already been resolved
|
||||
is_git_cmd = command.script.startswith(('git', 'hub'))
|
||||
|
||||
if not is_git_cmd:
|
||||
return False
|
||||
|
||||
# perform git aliases expansion
|
||||
if 'trace: alias expansion:' in command.stderr:
|
||||
search = re.search("trace: alias expansion: ([^ ]*) => ([^\n]*)",
|
||||
command.stderr)
|
||||
alias = search.group(1)
|
||||
|
||||
# by default git quotes everything, for example:
|
||||
# 'commit' '--amend'
|
||||
# which is surprising and does not allow to easily test for
|
||||
# eg. 'git commit'
|
||||
expansion = ' '.join(map(quote, split(search.group(2))))
|
||||
new_script = command.script.replace(alias, expansion)
|
||||
|
||||
command = Command._replace(command, script=new_script)
|
||||
|
||||
return fn(command, settings)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def memoize(fn):
|
||||
"""Caches previous calls to the function."""
|
||||
memo = {}
|
||||
@ -187,41 +132,3 @@ def replace_command(command, broken, matched):
|
||||
new_cmds = get_close_matches(broken, matched, cutoff=0.1)
|
||||
return [replace_argument(command.script, broken, new_cmd.strip())
|
||||
for new_cmd in new_cmds]
|
||||
|
||||
|
||||
@memoize
|
||||
def get_pkgfile(command):
|
||||
""" Gets the packages that provide the given command using `pkgfile`.
|
||||
|
||||
If the command is of the form `sudo foo`, searches for the `foo` command
|
||||
instead.
|
||||
"""
|
||||
try:
|
||||
command = command.strip()
|
||||
|
||||
if command.startswith('sudo '):
|
||||
command = command[5:]
|
||||
|
||||
command = command.split(" ")[0]
|
||||
|
||||
packages = subprocess.check_output(
|
||||
['pkgfile', '-b', '-v', command],
|
||||
universal_newlines=True, stderr=DEVNULL
|
||||
).splitlines()
|
||||
|
||||
return [package.split()[0] for package in packages]
|
||||
except CalledProcessError:
|
||||
return None
|
||||
|
||||
|
||||
def archlinux_env():
|
||||
if which('yaourt'):
|
||||
pacman = 'yaourt'
|
||||
elif which('pacman'):
|
||||
pacman = 'sudo pacman'
|
||||
else:
|
||||
return False, None
|
||||
|
||||
enabled_by_default = which('pkgfile')
|
||||
|
||||
return enabled_by_default, pacman
|
Loading…
x
Reference in New Issue
Block a user