mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
Rework cmdparse.Script API
The API now requires a command argument from signature. Parsing errors (no command from input) is thrown as a custom exception, and caught by the outmost possible invocation to emit a message from click.
This commit is contained in:
+11
-6
@@ -4,22 +4,27 @@ import shlex
|
||||
import six
|
||||
|
||||
|
||||
class ScriptEmptyError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
class Script(object):
|
||||
"""Parse a script line (in Pipfile's [scripts] section).
|
||||
|
||||
This always works in POSIX mode, even on Windows.
|
||||
"""
|
||||
def __init__(self, parts):
|
||||
if not parts:
|
||||
raise ValueError('invalid script')
|
||||
self._parts = parts
|
||||
|
||||
def __init__(self, command, args=None):
|
||||
self._parts = [command]
|
||||
if args:
|
||||
self._parts.extend(args)
|
||||
|
||||
@classmethod
|
||||
def parse(cls, value):
|
||||
if isinstance(value, six.string_types):
|
||||
value = shlex.split(value)
|
||||
return cls(value)
|
||||
if not value:
|
||||
raise ScriptEmptyError(value)
|
||||
return cls(value[0], value[1:])
|
||||
|
||||
def __repr__(self):
|
||||
return 'Script({0!r})'.format(self._parts)
|
||||
|
||||
+14
-15
@@ -4,7 +4,6 @@ import logging
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import shlex
|
||||
import signal
|
||||
import time
|
||||
import tempfile
|
||||
@@ -25,6 +24,7 @@ from blindspin import spinner
|
||||
from requests.packages import urllib3
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
from .cmdparse import ScriptEmptyError
|
||||
from .project import Project
|
||||
from .utils import (
|
||||
convert_deps_from_pip,
|
||||
@@ -2195,23 +2195,14 @@ def inline_activate_virtualenv():
|
||||
)
|
||||
|
||||
|
||||
def do_run_nt(command, args):
|
||||
"""Run command by appending space-joined args to it!"""
|
||||
def do_run_nt(script):
|
||||
import subprocess
|
||||
p = subprocess.Popen(
|
||||
project.build_script(command, args).cmdify(),
|
||||
shell=True, universal_newlines=True,
|
||||
)
|
||||
p = subprocess.Popen(script.cmdify(), shell=True, universal_newlines=True)
|
||||
p.communicate()
|
||||
sys.exit(p.returncode)
|
||||
|
||||
|
||||
def do_run_posix(command, args):
|
||||
"""Attempt to run command either pulling from project or interpreting as executable.
|
||||
|
||||
Args are appended to the command in [scripts] section of project if found.
|
||||
"""
|
||||
script = project.build_script(command, args)
|
||||
def do_run_posix(script, command):
|
||||
command_path = system_which(script.command)
|
||||
if not command_path:
|
||||
if project.has_script(command):
|
||||
@@ -2241,15 +2232,23 @@ def do_run_posix(command, args):
|
||||
|
||||
|
||||
def do_run(command, args, three=None, python=False):
|
||||
"""Attempt to run command either pulling from project or interpreting as executable.
|
||||
|
||||
Args are appended to the command in [scripts] section of project if found.
|
||||
"""
|
||||
# Ensure that virtualenv is available.
|
||||
ensure_project(three=three, python=python, validate=False)
|
||||
load_dot_env()
|
||||
# Activate virtualenv under the current interpreter's environment
|
||||
inline_activate_virtualenv()
|
||||
try:
|
||||
script = project.build_script(command, args)
|
||||
except ScriptEmptyError:
|
||||
click.echo("Can't run script {0!r}—it's empty?", err=True)
|
||||
if os.name == 'nt':
|
||||
do_run_nt(command, args)
|
||||
do_run_nt(script)
|
||||
else:
|
||||
do_run_posix(command, args)
|
||||
do_run_posix(script, command=command)
|
||||
|
||||
|
||||
def do_check(three=None, python=False, system=False, unused=False, args=None):
|
||||
|
||||
+1
-3
@@ -399,9 +399,7 @@ class Project(object):
|
||||
try:
|
||||
script = Script.parse(self.parsed_pipfile['scripts'][name])
|
||||
except KeyError:
|
||||
script = Script([name])
|
||||
except ValueError:
|
||||
raise ValueError('invalid script entry {0!r}'.format(name))
|
||||
script = Script(name)
|
||||
if extra_args:
|
||||
script.extend(extra_args)
|
||||
return script
|
||||
|
||||
+12
-5
@@ -1,8 +1,7 @@
|
||||
import textwrap
|
||||
|
||||
from pipenv.cmdparse import Script
|
||||
import pytest
|
||||
|
||||
from pipenv.cmdparse import Script, ScriptEmptyError
|
||||
|
||||
|
||||
@pytest.mark.run
|
||||
@pytest.mark.script
|
||||
@@ -12,9 +11,17 @@ def test_parse():
|
||||
assert script.args == ['-c', "print('hello')"], script
|
||||
|
||||
|
||||
@pytest.mark.run
|
||||
@pytest.mark.script
|
||||
def test_parse_error():
|
||||
with pytest.raises(ScriptEmptyError) as e:
|
||||
Script.parse('')
|
||||
assert str(e.value) == "[]"
|
||||
|
||||
|
||||
@pytest.mark.run
|
||||
def test_extend():
|
||||
script = Script.parse(['python', '-c', "print('hello')"])
|
||||
script = Script('python', ['-c', "print('hello')"])
|
||||
script.extend(['--verbose'])
|
||||
assert script.command == 'python'
|
||||
assert script.args == ['-c', "print('hello')", "--verbose"], script
|
||||
@@ -23,7 +30,7 @@ def test_extend():
|
||||
@pytest.mark.run
|
||||
@pytest.mark.script
|
||||
def test_cmdify():
|
||||
script = Script.parse(['python', '-c', "print('hello')"])
|
||||
script = Script('python', ['-c', "print('hello')"])
|
||||
cmd = script.cmdify()
|
||||
assert cmd == '"python" "-c" "print(\'hello\')"', script
|
||||
|
||||
|
||||
Reference in New Issue
Block a user