From 35ea4dce71f2b67c3c8c74acf6b75ab326bfa971 Mon Sep 17 00:00:00 2001 From: Joseph Frazier <1212jtraceur@gmail.com> Date: Fri, 10 Mar 2017 12:54:15 -0500 Subject: [PATCH 1/3] Add `yarn_help` rule Yarn likes to keep its documentation online, rather than in `yarn help` output. For example, `yarn help clean` doesn't tell you anything about the `clean` subcommand. Instead, it points you towards https://yarnpkg.com/en/docs/cli/clean This rule detects when that happens, and suggests opening the URL. One caveat is the currently only OSX is supported, as Linux uses `xdg-open` instead of `open`. --- README.md | 1 + tests/rules/test_yarn_help.py | 55 +++++++++++++++++++++++++++++++++++ thefuck/rules/yarn_help.py | 13 +++++++++ 3 files changed, 69 insertions(+) create mode 100644 tests/rules/test_yarn_help.py create mode 100644 thefuck/rules/yarn_help.py diff --git a/README.md b/README.md index 3e84a35..b4b8b5a 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,7 @@ using the matched rule and runs it. Rules enabled by default are as follows: * `workon_doesnt_exists` – fixes `virtualenvwrapper` env name os suggests to create new. * `yarn_alias` – fixes aliased `yarn` commands like `yarn ls`; * `yarn_command_not_found` – fixes misspelled `yarn` commands; +* `yarn_help` – makes it easier to open `yarn` documentation; Enabled by default only on specific platforms: diff --git a/tests/rules/test_yarn_help.py b/tests/rules/test_yarn_help.py new file mode 100644 index 0000000..499528f --- /dev/null +++ b/tests/rules/test_yarn_help.py @@ -0,0 +1,55 @@ +import pytest +from thefuck.rules.yarn_help import match, get_new_command +from tests.utils import Command + + +stdout_clean = ''' + + Usage: yarn [command] [flags] + + Options: + + -h, --help output usage information + -V, --version output the version number + --verbose output verbose messages on internal operations + --offline trigger an error if any required dependencies are not available in local cache + --prefer-offline use network only if dependencies are not available in local cache + --strict-semver + --json + --ignore-scripts don't run lifecycle scripts + --har save HAR output of network traffic + --ignore-platform ignore platform checks + --ignore-engines ignore engines check + --ignore-optional ignore optional dependencies + --force ignore all caches + --no-bin-links don't generate bin links when setting up packages + --flat only allow one version of a package + --prod, --production [prod] + --no-lockfile don't read or generate a lockfile + --pure-lockfile don't generate a lockfile + --frozen-lockfile don't generate a lockfile and fail if an update is needed + --link-duplicates create hardlinks to the repeated modules in node_modules + --global-folder + --modules-folder rather than installing modules into the node_modules folder relative to the cwd, output them here + --cache-folder specify a custom folder to store the yarn cache + --mutex [:specifier] use a mutex to ensure only one yarn instance is executing + --no-emoji disable emoji in output + --proxy + --https-proxy + --no-progress disable progress bar + --network-concurrency maximum number of concurrent network requests + + Visit https://yarnpkg.com/en/docs/cli/clean for documentation about this command. +''' # noqa + + +@pytest.mark.parametrize('command', [ + Command(script='yarn help clean', stdout=stdout_clean)]) +def test_match(command): + assert match(command) + + +@pytest.mark.parametrize('command, new_command', [ + (Command('yarn help clean', stdout=stdout_clean), 'open https://yarnpkg.com/en/docs/cli/clean')]) +def test_get_new_command(command, new_command): + assert get_new_command(command) == new_command diff --git a/thefuck/rules/yarn_help.py b/thefuck/rules/yarn_help.py new file mode 100644 index 0000000..7fb8280 --- /dev/null +++ b/thefuck/rules/yarn_help.py @@ -0,0 +1,13 @@ +import re +from thefuck.utils import for_app + + +@for_app('yarn', at_least=2) +def match(command): + return command.script_parts[1] == 'help' and ('for documentation about this command.' in command.stdout) + + +def get_new_command(command): + fix = re.findall(r'Visit ([^ ]*) for documentation about this command.', command.stdout)[0] + + return 'open ' + fix From 4b53b1d3e3a755f140c5cc5c7b1dd3fb81f11e16 Mon Sep 17 00:00:00 2001 From: Joseph Frazier <1212jtraceur@gmail.com> Date: Fri, 10 Mar 2017 15:22:48 -0500 Subject: [PATCH 2/3] Support Linux/Windows in `yarn_help` rule See https://www.dwheeler.com/essays/open-files-urls.html and https://stackoverflow.com/questions/5226958/which-equivalent-function-in-python/15133367#15133367 --- tests/rules/test_yarn_help.py | 3 ++- thefuck/rules/yarn_help.py | 5 +++-- thefuck/system/unix.py | 8 ++++++++ thefuck/system/win32.py | 5 +++++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/rules/test_yarn_help.py b/tests/rules/test_yarn_help.py index 499528f..4bb06b2 100644 --- a/tests/rules/test_yarn_help.py +++ b/tests/rules/test_yarn_help.py @@ -1,6 +1,7 @@ import pytest from thefuck.rules.yarn_help import match, get_new_command from tests.utils import Command +from thefuck.system import open_command stdout_clean = ''' @@ -50,6 +51,6 @@ def test_match(command): @pytest.mark.parametrize('command, new_command', [ - (Command('yarn help clean', stdout=stdout_clean), 'open https://yarnpkg.com/en/docs/cli/clean')]) + (Command('yarn help clean', stdout=stdout_clean), open_command('https://yarnpkg.com/en/docs/cli/clean'))]) def test_get_new_command(command, new_command): assert get_new_command(command) == new_command diff --git a/thefuck/rules/yarn_help.py b/thefuck/rules/yarn_help.py index 7fb8280..3902eb5 100644 --- a/thefuck/rules/yarn_help.py +++ b/thefuck/rules/yarn_help.py @@ -1,5 +1,6 @@ import re from thefuck.utils import for_app +from thefuck.system import open_command @for_app('yarn', at_least=2) @@ -8,6 +9,6 @@ def match(command): def get_new_command(command): - fix = re.findall(r'Visit ([^ ]*) for documentation about this command.', command.stdout)[0] + url = re.findall(r'Visit ([^ ]*) for documentation about this command.', command.stdout)[0] - return 'open ' + fix + return open_command(url) diff --git a/thefuck/system/unix.py b/thefuck/system/unix.py index ca87803..aac2532 100644 --- a/thefuck/system/unix.py +++ b/thefuck/system/unix.py @@ -3,6 +3,7 @@ import sys import tty import termios import colorama +from distutils.spawn import find_executable from .. import const init_output = colorama.init @@ -35,6 +36,13 @@ def get_key(): return ch + +def open_command(arg): + if (find_executable('xdg-open')): + return 'xdg-open ' + arg + return 'open ' + arg + + try: from pathlib import Path except ImportError: diff --git a/thefuck/system/win32.py b/thefuck/system/win32.py index 5e49ff6..2851498 100644 --- a/thefuck/system/win32.py +++ b/thefuck/system/win32.py @@ -26,6 +26,11 @@ def get_key(): encoding = sys.stdout.encoding or os.environ.get('PYTHONIOENCODING', 'utf-8') return ch.decode(encoding) + +def open_command(arg): + return 'cmd /c start ' + arg + + try: from pathlib import Path except ImportError: From c7d7a6d1d70ac48c1d1b5dee252fbcccb4bd8e3d Mon Sep 17 00:00:00 2001 From: Vladimir Iakovlev Date: Mon, 13 Mar 2017 13:30:07 +0100 Subject: [PATCH 3/3] #612: Little cleanup --- tests/rules/test_yarn_help.py | 3 ++- thefuck/rules/yarn_help.py | 7 +++++-- thefuck/system/unix.py | 2 +- thefuck/system/win32.py | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/rules/test_yarn_help.py b/tests/rules/test_yarn_help.py index 4bb06b2..18a607f 100644 --- a/tests/rules/test_yarn_help.py +++ b/tests/rules/test_yarn_help.py @@ -51,6 +51,7 @@ def test_match(command): @pytest.mark.parametrize('command, new_command', [ - (Command('yarn help clean', stdout=stdout_clean), open_command('https://yarnpkg.com/en/docs/cli/clean'))]) + (Command('yarn help clean', stdout=stdout_clean), + open_command('https://yarnpkg.com/en/docs/cli/clean'))]) def test_get_new_command(command, new_command): assert get_new_command(command) == new_command diff --git a/thefuck/rules/yarn_help.py b/thefuck/rules/yarn_help.py index 3902eb5..a4d8f93 100644 --- a/thefuck/rules/yarn_help.py +++ b/thefuck/rules/yarn_help.py @@ -5,10 +5,13 @@ from thefuck.system import open_command @for_app('yarn', at_least=2) def match(command): - return command.script_parts[1] == 'help' and ('for documentation about this command.' in command.stdout) + return (command.script_parts[1] == 'help' + and 'for documentation about this command.' in command.stdout) def get_new_command(command): - url = re.findall(r'Visit ([^ ]*) for documentation about this command.', command.stdout)[0] + url = re.findall( + r'Visit ([^ ]*) for documentation about this command.', + command.stdout)[0] return open_command(url) diff --git a/thefuck/system/unix.py b/thefuck/system/unix.py index aac2532..0a29bb6 100644 --- a/thefuck/system/unix.py +++ b/thefuck/system/unix.py @@ -38,7 +38,7 @@ def get_key(): def open_command(arg): - if (find_executable('xdg-open')): + if find_executable('xdg-open'): return 'xdg-open ' + arg return 'open ' + arg diff --git a/thefuck/system/win32.py b/thefuck/system/win32.py index 2851498..ce649a4 100644 --- a/thefuck/system/win32.py +++ b/thefuck/system/win32.py @@ -23,7 +23,8 @@ def get_key(): if ch == b'P': return const.KEY_DOWN - encoding = sys.stdout.encoding or os.environ.get('PYTHONIOENCODING', 'utf-8') + encoding = (sys.stdout.encoding + or os.environ.get('PYTHONIOENCODING', 'utf-8')) return ch.decode(encoding)