Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #3 - allow passing paths through stdin #4

Merged
merged 1 commit into from
Nov 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 23 additions & 14 deletions req_compile/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import argparse
import datetime
import itertools
import logging
import os
import shutil
Expand Down Expand Up @@ -157,30 +156,39 @@ def _create_req_from_path(path):
Returns:

"""
dist = req_compile.metadata.extract_metadata(path)
dist.meta = True
try:
dist = req_compile.metadata.extract_metadata(path)
except req_compile.metadata.MetadataError:
dist = None

if dist is None:
raise ValueError(
'Input arg "{}" is not directory containing setup.py or requirements file'.format(path))
'Input arg "{}" is not directory containing a valid setup.py'.format(path))
return dist


def _create_input_reqs(input_arg):
def _create_input_reqs(input_arg, extra_sources):
input_arg = input_arg.strip()
if input_arg == '-':
stdin_contents = sys.stdin.readlines()

def _create_stdin_input_req(line):
try:
return _create_input_reqs(line)
result = _create_req_from_path(line)
extra_sources.append(line)
return utils.parse_requirement('{}=={}'.format(*result.to_definition(None)))
except ValueError:
return (utils.parse_requirement(line),)
return utils.parse_requirement(line)

return DistInfo('-', None, list(itertools.chain(*[_create_stdin_input_req(line)
for line in stdin_contents])), meta=True)
reqs = (_create_stdin_input_req(line.strip())
for line in stdin_contents
if line.strip())
reqs = (req for req in reqs if req is not None)
return DistInfo('-', None, reqs, meta=True)

if os.path.isfile(input_arg):
return RequirementsFile.from_file(input_arg)

return _create_req_from_path(input_arg)


Expand Down Expand Up @@ -211,14 +219,15 @@ def run_compile(input_args,
else:
input_args = ('.',)

input_reqs = [_create_input_reqs(input_arg) for input_arg in input_args]
if extra_sources:
# Add the sources provided to the search repos
repo = MultiRepository(*([SourceRepository(source) for source in extra_sources] + [repo]))
input_reqs = [_create_input_reqs(input_arg, extra_sources) for input_arg in input_args]

constraint_reqs = None
if constraint_files is not None:
constraint_reqs = [_create_input_reqs(input_arg) for input_arg in constraint_files]
constraint_reqs = [_create_input_reqs(input_arg, extra_sources) for input_arg in constraint_files]

if extra_sources:
# Add the sources provided to the search repos
repo = MultiRepository(*([SourceRepository(source) for source in extra_sources] + [repo]))

try:
results, roots = perform_compile(input_reqs, repo, extras=extras,
Expand Down
47 changes: 44 additions & 3 deletions tests/test_cmdline.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import os

import pkg_resources
import pytest

from req_compile.cmdline import compile_main
import os
from six import StringIO

from req_compile.cmdline import compile_main, _create_input_reqs

from req_compile.dists import DistInfo
from req_compile.repos.findlinks import FindLinksRepository
from req_compile.repos.pypi import PyPIRepository
from req_compile.repos.solution import SolutionRepository
from req_compile.repos.source import SourceRepository
from req_compile import utils


@pytest.fixture
Expand Down Expand Up @@ -62,3 +65,41 @@ def test_source_dirs_dont_hit_pypi(mocker, basic_compile_mock):
compile_main(['source/myproj'])
perform_compile_args = basic_compile_mock.mock_calls[0][1]
assert perform_compile_args[0][0].name == 'myproj'


@pytest.fixture
def mock_stdin(mocker):
fake_stdin = StringIO()

def _write(value):
fake_stdin.write(value)
fake_stdin.seek(0, 0)

mocker.patch('sys.stdin', fake_stdin)
return _write


def test_stdin_paths(mock_stdin):
"""Verify that paths work correctly from stdin"""
mono_dir = os.path.join(os.path.dirname(__file__), 'repos', 'monorepo')
mono1 = os.path.join(mono_dir, 'pkg1')
mono2 = os.path.join(mono_dir, 'pkg2')
mono3 = os.path.join(mono_dir, 'subdir', 'pkg3')
mock_stdin(mono1 + '\n' + mono2 + '\n' + mono3 + '\n')

extra_sources = []
result = _create_input_reqs('-', extra_sources)

assert set(extra_sources) == {mono1, mono2, mono3}
assert set(result.reqs) == set(pkg_resources.parse_requirements(['pkg1==1.0.0', 'pkg2==2.0.1', 'pkg3==0.0.0']))


def test_stdin_reqs(mock_stdin):
"""Verify that lists of requirements work correctly from stdin, including comment and blank lines"""
mock_stdin('pytest\n# Comment\n\npytest-mock\n')

extra_sources = []
result = _create_input_reqs('-', extra_sources)

assert extra_sources == []
assert set(result.reqs) == set(pkg_resources.parse_requirements(['pytest', 'pytest-mock']))