mirror of
https://github.com/nvbn/thefuck.git
synced 2025-04-20 09:40:46 +01:00
#N/A: Add npm_missing_script
rule
This commit is contained in:
parent
b09a4e394e
commit
fdfbfc80c0
@ -200,6 +200,7 @@ using the matched rule and runs it. Rules enabled by default are as follows:
|
|||||||
* `mkdir_p` – adds `-p` when you trying to create directory without parent;
|
* `mkdir_p` – adds `-p` when you trying to create directory without parent;
|
||||||
* `mvn_no_command` – adds `clean package` to `mvn`;
|
* `mvn_no_command` – adds `clean package` to `mvn`;
|
||||||
* `mvn_unknown_lifecycle_phase` – fixes misspelled lifecycle phases with `mvn`;
|
* `mvn_unknown_lifecycle_phase` – fixes misspelled lifecycle phases with `mvn`;
|
||||||
|
* `npm_missing_script` – fixes `npm` custom script name in `npm run-script <script>`;
|
||||||
* `npm_run_script` – adds missing `run-script` for custom `npm` scripts;
|
* `npm_run_script` – adds missing `run-script` for custom `npm` scripts;
|
||||||
* `npm_wrong_command` – fixes wrong npm commands like `npm urgrade`;
|
* `npm_wrong_command` – fixes wrong npm commands like `npm urgrade`;
|
||||||
* `no_command` – fixes wrong console commands, for example `vom/vim`;
|
* `no_command` – fixes wrong console commands, for example `vom/vim`;
|
||||||
|
69
tests/rules/test_npm_missing_script.py
Normal file
69
tests/rules/test_npm_missing_script.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import pytest
|
||||||
|
from io import BytesIO
|
||||||
|
from tests.utils import Command
|
||||||
|
from thefuck.rules.npm_missing_script import match, get_new_command
|
||||||
|
|
||||||
|
stderr = '''
|
||||||
|
npm ERR! Linux 4.4.0-31-generic
|
||||||
|
npm ERR! argv "/opt/node/bin/node" "/opt/node/bin/npm" "run" "dvelop"
|
||||||
|
npm ERR! node v4.4.7
|
||||||
|
npm ERR! npm v2.15.8
|
||||||
|
|
||||||
|
npm ERR! missing script: {}
|
||||||
|
npm ERR!
|
||||||
|
npm ERR! If you need help, you may report this error at:
|
||||||
|
npm ERR! <https://github.com/npm/npm/issues>
|
||||||
|
|
||||||
|
npm ERR! Please include the following file with any support request:
|
||||||
|
npm ERR! /home/nvbn/exp/code_view/client_web/npm-debug.log
|
||||||
|
'''.format
|
||||||
|
|
||||||
|
run_script_stdout = b'''
|
||||||
|
Lifecycle scripts included in code-view-web:
|
||||||
|
test
|
||||||
|
jest
|
||||||
|
|
||||||
|
available via `npm run-script`:
|
||||||
|
build
|
||||||
|
cp node_modules/ace-builds/src-min/ -a resources/ace/ && webpack --progress --colors -p --config ./webpack.production.config.js
|
||||||
|
develop
|
||||||
|
cp node_modules/ace-builds/src/ -a resources/ace/ && webpack-dev-server --progress --colors
|
||||||
|
watch-test
|
||||||
|
jest --verbose --watch
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def run_script(mocker):
|
||||||
|
patch = mocker.patch('thefuck.specific.npm.Popen')
|
||||||
|
patch.return_value.stdout = BytesIO(run_script_stdout)
|
||||||
|
return patch.return_value
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('command', [
|
||||||
|
Command('npm ru wach', stderr=stderr('wach')),
|
||||||
|
Command('npm run live-tes', stderr=stderr('live-tes')),
|
||||||
|
Command('npm run-script sahare', stderr=stderr('sahare'))])
|
||||||
|
def test_match(command):
|
||||||
|
assert match(command)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('command', [
|
||||||
|
Command('npm wach', stderr=stderr('wach')),
|
||||||
|
Command('vim live-tes', stderr=stderr('live-tes')),
|
||||||
|
Command('npm run-script sahare')])
|
||||||
|
def test_not_match(command):
|
||||||
|
assert not match(command)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('script, stderr, result', [
|
||||||
|
('npm ru wach-tests', stderr('wach-tests'), 'npm ru watch-test'),
|
||||||
|
('npm -i run-script dvelop', stderr('dvelop'),
|
||||||
|
'npm -i run-script develop'),
|
||||||
|
('npm -i run-script buld -X POST', stderr('buld'),
|
||||||
|
'npm -i run-script build -X POST')])
|
||||||
|
def test_get_new_command(script, stderr, result):
|
||||||
|
command = Command(script, stderr=stderr)
|
||||||
|
|
||||||
|
assert get_new_command(command)[0] == result
|
@ -49,7 +49,7 @@ available via `npm run-script`:
|
|||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def run_script(mocker):
|
def run_script(mocker):
|
||||||
patch = mocker.patch('thefuck.rules.npm_run_script.Popen')
|
patch = mocker.patch('thefuck.specific.npm.Popen')
|
||||||
patch.return_value.stdout = BytesIO(run_script_stdout)
|
patch.return_value.stdout = BytesIO(run_script_stdout)
|
||||||
return patch.return_value
|
return patch.return_value
|
||||||
|
|
||||||
|
26
tests/specific/test_npm.py
Normal file
26
tests/specific/test_npm.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from thefuck.specific.npm import get_scripts
|
||||||
|
|
||||||
|
run_script_stdout = b'''
|
||||||
|
Lifecycle scripts included in code-view-web:
|
||||||
|
test
|
||||||
|
jest
|
||||||
|
|
||||||
|
available via `npm run-script`:
|
||||||
|
build
|
||||||
|
cp node_modules/ace-builds/src-min/ -a resources/ace/ && webpack --progress --colors -p --config ./webpack.production.config.js
|
||||||
|
develop
|
||||||
|
cp node_modules/ace-builds/src/ -a resources/ace/ && webpack-dev-server --progress --colors
|
||||||
|
watch-test
|
||||||
|
jest --verbose --watch
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures('no_memoize')
|
||||||
|
def test_get_scripts(mocker):
|
||||||
|
patch = mocker.patch('thefuck.specific.npm.Popen')
|
||||||
|
patch.return_value.stdout = BytesIO(run_script_stdout)
|
||||||
|
assert get_scripts() == ['build', 'develop', 'watch-test']
|
17
thefuck/rules/npm_missing_script.py
Normal file
17
thefuck/rules/npm_missing_script.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import re
|
||||||
|
from thefuck.utils import for_app, replace_command
|
||||||
|
from thefuck.specific.npm import get_scripts, npm_available
|
||||||
|
|
||||||
|
enabled_by_default = npm_available
|
||||||
|
|
||||||
|
|
||||||
|
@for_app('npm')
|
||||||
|
def match(command):
|
||||||
|
return (any(part.startswith('ru') for part in command.script_parts)
|
||||||
|
and 'npm ERR! missing script: ' in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def get_new_command(command):
|
||||||
|
misspelled_script = re.findall(
|
||||||
|
r'.*missing script: (.*)\n', command.stderr)[0]
|
||||||
|
return replace_command(command, misspelled_script, get_scripts())
|
@ -1,21 +1,7 @@
|
|||||||
import re
|
from thefuck.specific.npm import npm_available, get_scripts
|
||||||
from subprocess import Popen, PIPE
|
from thefuck.utils import for_app
|
||||||
from thefuck.utils import for_app, memoize, eager
|
|
||||||
|
|
||||||
|
enabled_by_default = npm_available
|
||||||
@memoize
|
|
||||||
@eager
|
|
||||||
def get_scripts():
|
|
||||||
proc = Popen(['npm', 'run-script'], stdout=PIPE)
|
|
||||||
should_yeild = False
|
|
||||||
for line in proc.stdout.readlines():
|
|
||||||
line = line.decode()
|
|
||||||
if 'available via `npm run-script`:' in line:
|
|
||||||
should_yeild = True
|
|
||||||
continue
|
|
||||||
|
|
||||||
if should_yeild and re.match(r'^ [^ ]+', line):
|
|
||||||
yield line.strip().split(' ')[0]
|
|
||||||
|
|
||||||
|
|
||||||
@for_app('npm')
|
@for_app('npm')
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
from thefuck.specific.npm import npm_available
|
||||||
from thefuck.utils import replace_argument, for_app, eager, get_closest
|
from thefuck.utils import replace_argument, for_app, eager, get_closest
|
||||||
from thefuck.specific.sudo import sudo_support
|
from thefuck.specific.sudo import sudo_support
|
||||||
|
|
||||||
|
enabled_by_default = npm_available
|
||||||
|
|
||||||
|
|
||||||
def _get_wrong_command(script_parts):
|
def _get_wrong_command(script_parts):
|
||||||
commands = [part for part in script_parts[1:] if not part.startswith('-')]
|
commands = [part for part in script_parts[1:] if not part.startswith('-')]
|
||||||
|
21
thefuck/specific/npm.py
Normal file
21
thefuck/specific/npm.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import re
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
from thefuck.utils import memoize, eager, which
|
||||||
|
|
||||||
|
npm_available = bool(which('npm'))
|
||||||
|
|
||||||
|
|
||||||
|
@memoize
|
||||||
|
@eager
|
||||||
|
def get_scripts():
|
||||||
|
"""Get custom npm scripts."""
|
||||||
|
proc = Popen(['npm', 'run-script'], stdout=PIPE)
|
||||||
|
should_yeild = False
|
||||||
|
for line in proc.stdout.readlines():
|
||||||
|
line = line.decode()
|
||||||
|
if 'available via `npm run-script`:' in line:
|
||||||
|
should_yeild = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
if should_yeild and re.match(r'^ [^ ]+', line):
|
||||||
|
yield line.strip().split(' ')[0]
|
Loading…
x
Reference in New Issue
Block a user