예제 #1
0
def test_requirements_txt(rule_runner: RuleRunner) -> None:
    """This tests that we correctly create a new python_requirement_library for each entry in a
    requirements.txt file.

    Some edge cases:
    * We ignore comments and options (values that start with `--`).
    * If a module_mapping is given, and the project is in the map, we copy over a subset of the
      mapping to the created target.
    * Projects get normalized thanks to Requirement.parse().
    """
    assert_python_requirements(
        rule_runner,
        "python_requirements(module_mapping={'ansicolors': ['colors']})",
        dedent(
            """\
            # Comment.
            --find-links=https://duckduckgo.com
            ansicolors>=1.18.0
            Django==3.2 ; python_version>'3'
            Un-Normalized-PROJECT  # Inline comment.
            pip@ git+https://github.com/pypa/pip.git
            """
        ),
        expected_file_dep=PythonRequirementsFile(
            {"sources": ["requirements.txt"]},
            address=Address("", target_name="requirements.txt"),
        ),
        expected_targets=[
            PythonRequirementLibrary(
                {
                    "dependencies": [":requirements.txt"],
                    "requirements": [Requirement.parse("ansicolors>=1.18.0")],
                    "module_mapping": {"ansicolors": ["colors"]},
                },
                address=Address("", target_name="ansicolors"),
            ),
            PythonRequirementLibrary(
                {
                    "dependencies": [":requirements.txt"],
                    "requirements": [Requirement.parse("Django==3.2 ; python_version>'3'")],
                },
                address=Address("", target_name="Django"),
            ),
            PythonRequirementLibrary(
                {
                    "dependencies": [":requirements.txt"],
                    "requirements": [Requirement.parse("Un_Normalized_PROJECT")],
                },
                address=Address("", target_name="Un-Normalized-PROJECT"),
            ),
            PythonRequirementLibrary(
                {
                    "dependencies": [":requirements.txt"],
                    "requirements": [Requirement.parse("pip@ git+https://github.com/pypa/pip.git")],
                },
                address=Address("", target_name="pip"),
            ),
        ],
    )
예제 #2
0
def test_pipfile_lock(rule_runner: RuleRunner) -> None:
    """This tests that we correctly create a new python_requirement_library for each entry in a
    Pipfile.lock file.

    Edge cases:
    * Develop and Default requirements are used
    * If a module_mapping is given, and the project is in the map, we copy over a subset of the
        mapping to the created target.
    """
    assert_pipenv_requirements(
        rule_runner,
        "pipenv_requirements(module_mapping={'ansicolors': ['colors']})",
        {
            "default": {
                "ansicolors": {
                    "version": ">=1.18.0"
                }
            },
            "develop": {
                "cachetools": {
                    "markers": "python_version ~= '3.5'",
                    "version": "==4.1.1"
                }
            },
        },
        expected_file_dep=PythonRequirementsFile(
            {"sources": ["Pipfile.lock"]},
            Address("", target_name="Pipfile.lock")),
        expected_targets=[
            PythonRequirementLibrary(
                {
                    "requirements": [Requirement.parse("ansicolors>=1.18.0")],
                    "dependencies": [":Pipfile.lock"],
                    "module_mapping": {
                        "ansicolors": ["colors"]
                    },
                },
                Address("", target_name="ansicolors"),
            ),
            PythonRequirementLibrary(
                {
                    "requirements": [
                        Requirement.parse(
                            "cachetools==4.1.1;python_version ~= '3.5'")
                    ],
                    "dependencies": [":Pipfile.lock"],
                },
                Address("", target_name="cachetools"),
            ),
        ],
    )
예제 #3
0
def test_supply_python_requirements_file(rule_runner: RuleRunner) -> None:
    """This tests that we can supply our own `_python_requirements_file`."""
    assert_pipenv_requirements(
        rule_runner,
        dedent(
            """
            pipenv_requirements(
                requirements_relpath='custom/pipfile/Pipfile.lock',
                pipfile_target='//:custom_pipfile_target'
            )

            _python_requirements_file(
                name='custom_pipfile_target',
                sources=['custom/pipfile/Pipfile.lock']
            )
            """
        ),
        {"default": {"ansicolors": {"version": ">=1.18.0"}}},
        expected_file_dep=PythonRequirementsFile(
            {"sources": ["custom/pipfile/Pipfile.lock"]},
            address=Address("", target_name="custom_pipfile_target"),
        ),
        expected_targets=[
            PythonRequirementLibrary(
                {
                    "requirements": [Requirement.parse("ansicolors>=1.18.0")],
                    "dependencies": ["//:custom_pipfile_target"],
                },
                address=Address("", target_name="ansicolors"),
            ),
        ],
        pipfile_lock_relpath="custom/pipfile/Pipfile.lock",
    )
예제 #4
0
def test_relpath_override(rule_runner: RuleRunner) -> None:
    assert_poetry_requirements(
        rule_runner,
        "poetry_requirements(pyproject_toml_relpath='subdir/pyproject.toml')",
        dedent(
            """\
            [tool.poetry.dependencies]
            ansicolors = ">=1.18.0"
            [tool.poetry.dev-dependencies]
            """
        ),
        pyproject_toml_relpath="subdir/pyproject.toml",
        expected_file_dep=PythonRequirementsFile(
            {"sources": ["subdir/pyproject.toml"]},
            address=Address("", target_name="subdir_pyproject.toml"),
        ),
        expected_targets=[
            PythonRequirementLibrary(
                {
                    "dependencies": [":subdir_pyproject.toml"],
                    "requirements": [Requirement.parse("ansicolors>=1.18.0")],
                },
                address=Address("", target_name="ansicolors"),
            ),
        ],
    )
예제 #5
0
def test_multiple_versions(rule_runner: RuleRunner) -> None:
    """This tests that we correctly create a new python_requirement_library for each unique
    dependency name in a requirements.txt file, grouping duplicated dependency names to handle
    multiple requirement strings per PEP 508."""

    assert_python_requirements(
        rule_runner,
        "python_requirements()",
        dedent(
            """\
            Django>=3.2
            Django==3.2.7
            confusedmonkey==86
            repletewateringcan>=7
            """
        ),
        expected_file_dep=PythonRequirementsFile(
            {"sources": ["requirements.txt"]},
            Address("", target_name="requirements.txt"),
        ),
        expected_targets=[
            PythonRequirementLibrary(
                {
                    "dependencies": [":requirements.txt"],
                    "requirements": [
                        Requirement.parse("Django>=3.2"),
                        Requirement.parse("Django==3.2.7"),
                    ],
                },
                Address("", target_name="Django"),
            ),
            PythonRequirementLibrary(
                {
                    "dependencies": [":requirements.txt"],
                    "requirements": [Requirement.parse("confusedmonkey==86")],
                },
                Address("", target_name="confusedmonkey"),
            ),
            PythonRequirementLibrary(
                {
                    "dependencies": [":requirements.txt"],
                    "requirements": [Requirement.parse("repletewateringcan>=7")],
                },
                Address("", target_name="repletewateringcan"),
            ),
        ],
    )
예제 #6
0
def test_properly_creates_extras_requirements(rule_runner: RuleRunner) -> None:
    """This tests the proper parsing of requirements installed with specified extras."""
    assert_pipenv_requirements(
        rule_runner,
        "pipenv_requirements()",
        {
            "default": {
                "ansicolors": {
                    "version": ">=1.18.0",
                    "extras": ["neon"]
                }
            },
            "develop": {
                "cachetools": {
                    "markers": "python_version ~= '3.5'",
                    "version": "==4.1.1",
                    "extras": ["ring", "mongo"],
                }
            },
        },
        expected_file_dep=PythonRequirementsFile(
            {"sources": ["Pipfile.lock"]},
            Address("", target_name="Pipfile.lock")),
        expected_targets=[
            PythonRequirementLibrary(
                {
                    "requirements":
                    [Requirement.parse("ansicolors[neon]>=1.18.0")],
                    "dependencies": [":Pipfile.lock"],
                },
                Address("", target_name="ansicolors"),
            ),
            PythonRequirementLibrary(
                {
                    "requirements": [
                        Requirement.parse(
                            "cachetools[ring,mongo]==4.1.1;python_version ~= '3.5'"
                        )
                    ],
                    "dependencies": [":Pipfile.lock"],
                },
                Address("", target_name="cachetools"),
            ),
        ],
    )
예제 #7
0
 def test_relpath_override(self) -> None:
     self.assert_python_requirements(
         "python_requirements(requirements_relpath='subdir/requirements.txt')",
         "ansicolors>=1.18.0",
         requirements_txt_relpath="subdir/requirements.txt",
         expected_file_dep=PythonRequirementsFile(
             {"sources": ["subdir/requirements.txt"]},
             address=Address("", target_name="subdir/requirements.txt"),
         ),
         expected_targets=[
             PythonRequirementLibrary(
                 {
                     "dependencies": [":subdir/requirements.txt"],
                     "requirements": [Requirement.parse("ansicolors>=1.18.0")],
                 },
                 address=Address("", target_name="ansicolors"),
             ),
         ],
     )
예제 #8
0
def test_pyproject_toml(rule_runner: RuleRunner) -> None:
    """This tests that we correctly create a new python_requirement_library for each entry in a
    pyproject.toml file.

    Note that this just ensures proper targets are created; see prior tests for specific parsing
    edge cases.
    """
    assert_poetry_requirements(
        rule_runner,
        dedent(
            """\
            poetry_requirements(
                # module_mapping should work regardless of capitalization.
                module_mapping={'ansiCOLORS': ['colors']},
                type_stubs_module_mapping={'Django-types': ['django']},
            )
            """
        ),
        dedent(
            """\
            [tool.poetry.dependencies]
            Django = {version = "3.2", python = "3"}
            Django-types = "2"
            Un-Normalized-PROJECT = "1.0.0"
            [tool.poetry.dev-dependencies]
            ansicolors = ">=1.18.0"
            """
        ),
        expected_file_dep=PythonRequirementsFile(
            {"sources": ["pyproject.toml"]},
            address=Address("", target_name="pyproject.toml"),
        ),
        expected_targets=[
            PythonRequirementLibrary(
                {
                    "dependencies": [":pyproject.toml"],
                    "requirements": [Requirement.parse("ansicolors>=1.18.0")],
                    "module_mapping": {"ansicolors": ["colors"]},
                },
                address=Address("", target_name="ansicolors"),
            ),
            PythonRequirementLibrary(
                {
                    "dependencies": [":pyproject.toml"],
                    "requirements": [Requirement.parse("Django==3.2 ; python_version == '3'")],
                },
                address=Address("", target_name="Django"),
            ),
            PythonRequirementLibrary(
                {
                    "dependencies": [":pyproject.toml"],
                    "requirements": [Requirement.parse("Django-types==2")],
                    "type_stubs_module_mapping": {"Django-types": ["django"]},
                },
                address=Address("", target_name="Django-types"),
            ),
            PythonRequirementLibrary(
                {
                    "dependencies": [":pyproject.toml"],
                    "requirements": [Requirement.parse("Un_Normalized_PROJECT == 1.0.0")],
                },
                address=Address("", target_name="Un-Normalized-PROJECT"),
            ),
        ],
    )