示例#1
0
def test_exporter_exports_requirements_txt_with_legacy_packages(
        tmp_dir, poetry):
    poetry.pool.add_repository(
        LegacyRepository(
            "custom",
            "https://example.com/simple",
        ))
    poetry.locker.mock_lock_data({
        "package": [
            {
                "name": "foo",
                "version": "1.2.3",
                "category": "main",
                "optional": False,
                "python-versions": "*",
            },
            {
                "name": "bar",
                "version": "4.5.6",
                "category": "dev",
                "optional": False,
                "python-versions": "*",
                "source": {
                    "type": "legacy",
                    "url": "https://example.com/simple",
                    "reference": "",
                },
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": ["12345"],
                "bar": ["67890"]
            },
        },
    })
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export("requirements.txt",
                    Path(tmp_dir),
                    "requirements.txt",
                    dev=True)

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
--extra-index-url https://example.com/simple

bar==4.5.6 \\
    --hash=sha256:67890
foo==1.2.3 \\
    --hash=sha256:12345
"""

    assert expected == content
示例#2
0
def test_exporter_can_export_requirements_txt_with_file_packages(
        tmp_dir, poetry):
    poetry.locker.mock_lock_data({
        "package": [{
            "name": "foo",
            "version": "1.2.3",
            "category": "main",
            "optional": False,
            "python-versions": "*",
            "source": {
                "type": "file",
                "url": "tests/fixtures/distributions/demo-0.1.0.tar.gz",
                "reference": "",
            },
        }],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": []
            },
        },
    })
    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
tests/fixtures/distributions/demo-0.1.0.tar.gz
"""

    assert expected == content
示例#3
0
def test_exporter_can_export_requirements_txt_with_git_packages(
        tmp_dir, poetry):
    poetry.locker.mock_lock_data({
        "package": [{
            "name": "foo",
            "version": "1.2.3",
            "category": "main",
            "optional": False,
            "python-versions": "*",
            "source": {
                "type": "git",
                "url": "https://github.com/foo/foo.git",
                "reference": "123456",
            },
        }],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": []
            },
        },
    })
    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
-e git+https://github.com/foo/foo.git@123456#egg=foo
"""

    assert expected == content
示例#4
0
    def handle(self):
        fmt = self.option("format")

        if fmt not in Exporter.ACCEPTED_FORMATS:
            raise ValueError("Invalid export format: {}".format(fmt))

        locker = self.poetry.locker
        if not locker.is_locked():
            self.line(
                "<comment>The lock file does not exist. Locking.</comment>")
            options = []
            if self.io.is_debug():
                options.append(("-vvv", None))
            elif self.io.is_very_verbose():
                options.append(("-vv", None))
            elif self.io.is_verbose():
                options.append(("-v", None))

            self.call("lock", options)

        if not locker.is_fresh():
            self.line("<warning>"
                      "Warning: The lock file is not up to date with "
                      "the latest changes in pyproject.toml. "
                      "You may be getting outdated dependencies. "
                      "Run update to update them."
                      "</warning>")

        exporter = Exporter(self.poetry.locker)
        exporter.export(
            fmt,
            self.poetry.file.parent,
            with_hashes=not self.option("without-hashes"),
            dev=self.option("dev"),
        )
示例#5
0
def test_exporter_exports_requirements_txt_with_optional_packages_if_opted_in(
    tmp_dir, poetry
):
    poetry.locker.mock_lock_data(
        {
            "package": [
                {
                    "name": "foo",
                    "version": "1.2.3",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                },
                {
                    "name": "bar",
                    "version": "4.5.6",
                    "category": "main",
                    "optional": True,
                    "python-versions": "*",
                    "dependencies": {"spam": ">=0.1"},
                },
                {
                    "name": "spam",
                    "version": "0.1.0",
                    "category": "main",
                    "optional": True,
                    "python-versions": "*",
                },
            ],
            "metadata": {
                "python-versions": "*",
                "content-hash": "123456789",
                "hashes": {"foo": ["12345"], "bar": ["67890"], "spam": ["abcde"]},
            },
            "extras": {"feature_bar": ["bar"]},
        }
    )
    exporter = Exporter(poetry)

    exporter.export(
        "requirements.txt",
        Path(tmp_dir),
        "requirements.txt",
        dev=True,
        extras=["feature_bar"],
    )

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
bar==4.5.6 \\
    --hash=sha256:67890
foo==1.2.3 \\
    --hash=sha256:12345
spam==0.1.0 \\
    --hash=sha256:abcde
"""

    assert expected == content
示例#6
0
def test_exporter_can_export_requirements_txt_with_directory_packages(
        tmp_dir, locker):
    locker.mock_lock_data({
        "package": [{
            "name": "foo",
            "version": "1.2.3",
            "category": "main",
            "optional": False,
            "python-versions": "*",
            "source": {
                "type": "directory",
                "url": "../foo",
                "reference": ""
            },
        }],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": []
            },
        },
    })
    exporter = Exporter(locker)

    exporter.export("requirements.txt", Path(tmp_dir))

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
-e ../foo
"""

    assert expected == content
示例#7
0
def test_exporter_exports_requirements_txt_with_dev_extras(
        tmp_dir, poetry, dev, expected):
    poetry.locker.mock_lock_data({
        "package": [
            {
                "name": "foo",
                "version": "1.2.1",
                "category": "main",
                "optional": False,
                "python-versions": "*",
            },
            {
                "name": "bar",
                "version": "1.2.2",
                "category": "main",
                "optional": False,
                "python-versions": "*",
                "dependencies": {
                    "baz": {
                        "version": ">=0.1.0",
                        "optional": True,
                        "markers": "extra == 'baz'",
                    }
                },
                "extras": {
                    "baz": ["baz (>=0.1.0)"]
                },
            },
            {
                "name": "baz",
                "version": "1.2.3",
                "category": "dev",
                "optional": False,
                "python-versions": "*",
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": [],
                "bar": [],
                "baz": []
            },
        },
    })
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export("requirements.txt",
                    Path(tmp_dir),
                    "requirements.txt",
                    dev=dev)

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    assert content == "{}\n".format("\n".join(expected))
示例#8
0
def test_exporter_exports_requirements_txt_with_optional_packages(
    tmp_dir, poetry, extras, lines
):
    poetry.locker.mock_lock_data(
        {
            "package": [
                {
                    "name": "foo",
                    "version": "1.2.3",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                },
                {
                    "name": "bar",
                    "version": "4.5.6",
                    "category": "main",
                    "optional": True,
                    "python-versions": "*",
                    "dependencies": {"spam": ">=0.1"},
                },
                {
                    "name": "spam",
                    "version": "0.1.0",
                    "category": "main",
                    "optional": True,
                    "python-versions": "*",
                },
            ],
            "metadata": {
                "python-versions": "*",
                "content-hash": "123456789",
                "hashes": {"foo": ["12345"], "bar": ["67890"], "spam": ["abcde"]},
            },
            "extras": {"feature_bar": ["bar"]},
        }
    )
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export(
        "requirements.txt",
        Path(tmp_dir),
        "requirements.txt",
        dev=True,
        with_hashes=False,
        extras=extras,
    )

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = "\n".join(lines)

    assert content.strip() == expected
示例#9
0
def test_exporter_can_export_requirements_txt_with_standard_packages_and_markers(
        tmp_dir, poetry):
    poetry.locker.mock_lock_data({
        "package": [
            {
                "name": "foo",
                "version": "1.2.3",
                "category": "main",
                "optional": False,
                "python-versions": "*",
                "marker": "python_version < '3.7'",
            },
            {
                "name": "bar",
                "version": "4.5.6",
                "category": "main",
                "optional": False,
                "python-versions": "*",
                "marker": "extra =='foo'",
            },
            {
                "name": "baz",
                "version": "7.8.9",
                "category": "main",
                "optional": False,
                "python-versions": "*",
                "marker": "sys_platform == 'win32'",
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": [],
                "bar": [],
                "baz": []
            },
        },
    })
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
bar==4.5.6
baz==7.8.9; sys_platform == "win32"
foo==1.2.3; python_version < "3.7"
"""

    assert expected == content
示例#10
0
def test_exporter_can_export_requirements_txt_with_nested_packages_cyclic(
    tmp_dir, poetry
):
    poetry.locker.mock_lock_data(
        {
            "package": [
                {
                    "name": "foo",
                    "version": "1.2.3",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {"bar": {"version": "4.5.6"}},
                },
                {
                    "name": "bar",
                    "version": "4.5.6",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {"baz": {"version": "7.8.9"}},
                },
                {
                    "name": "baz",
                    "version": "7.8.9",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {"foo": {"version": "1.2.3"}},
                },
            ],
            "metadata": {
                "python-versions": "*",
                "content-hash": "123456789",
                "hashes": {"foo": [], "bar": [], "baz": []},
            },
        }
    )
    set_package_requires(poetry, skip={"bar", "baz"})

    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
bar==4.5.6
baz==7.8.9
foo==1.2.3
"""

    assert expected == content
示例#11
0
def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers_any(
        tmp_dir, poetry, dev, lines):
    poetry.locker.mock_lock_data({
        "package": [
            {
                "name": "a",
                "version": "1.2.3",
                "category": "main",
                "optional": False,
                "python-versions": "*",
            },
            {
                "name": "b",
                "version": "4.5.6",
                "category": "dev",
                "optional": False,
                "python-versions": "*",
                "dependencies": {
                    "a": ">=1.2.3"
                },
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "a": [],
                "b": []
            },
        },
    })

    poetry.package.requires = [
        Factory.create_dependency(name="a",
                                  constraint=dict(version="^1.2.3",
                                                  python="<3.8")),
    ]
    poetry.package.dev_requires = [
        Factory.create_dependency(name="b",
                                  constraint=dict(version="^4.5.6"),
                                  category="dev"),
    ]

    exporter = Exporter(poetry)

    exporter.export("requirements.txt",
                    Path(tmp_dir),
                    "requirements.txt",
                    dev=dev)

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    assert content.strip() == "\n".join(lines)
示例#12
0
def test_exporter_exports_requirements_txt_with_dev_packages_if_opted_in(
        tmp_dir, poetry):
    poetry.locker.mock_lock_data({
        "package": [
            {
                "name": "foo",
                "version": "1.2.3",
                "category": "main",
                "optional": False,
                "python-versions": "*",
            },
            {
                "name": "bar",
                "version": "4.5.6",
                "category": "dev",
                "optional": False,
                "python-versions": "*",
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": ["12345"],
                "bar": ["67890"]
            },
        },
    })
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export("requirements.txt",
                    Path(tmp_dir),
                    "requirements.txt",
                    dev=True)

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
bar==4.5.6 \\
    --hash=sha256:67890
foo==1.2.3 \\
    --hash=sha256:12345
"""

    assert expected == content
示例#13
0
def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes_disabled(
        tmp_dir, poetry):
    poetry.locker.mock_lock_data({
        "package": [
            {
                "name": "foo",
                "version": "1.2.3",
                "category": "main",
                "optional": False,
                "python-versions": "*",
            },
            {
                "name": "bar",
                "version": "4.5.6",
                "category": "main",
                "optional": False,
                "python-versions": "*",
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": ["12345"],
                "bar": ["67890"]
            },
        },
    })
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export("requirements.txt",
                    Path(tmp_dir),
                    "requirements.txt",
                    with_hashes=False)

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
bar==4.5.6
foo==1.2.3
"""

    assert expected == content
示例#14
0
def main(argv: Optional[Sequence[str]] = None) -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--dev",
        action="store_true",
        help="Include development dependencies.",
    )
    parser.add_argument(
        "-e",
        "--extras",
        action="append",
        help="Extra sets of dependencies to include.",
    )
    parser.add_argument(
        "--without-hashes",
        action="store_true",
        help="Exclude hashes from the exported file.",
    )
    parser.add_argument(
        "--with-credentials",
        action="store_true",
        help="Include credentials for extra indices.",
    )
    parser.add_argument(
        "--project-directory",
        action="store",
        help="Directory which includes the pyproject.toml file.",
    )
    parser.add_argument("filename", help="Filename to check.")
    args = parser.parse_args(argv)

    poetry = Factory().create_poetry(os.getcwd())
    exporter = Exporter(poetry)
    with open(os.path.join(args.project_directory, "requirements.txt",
                           "w")) as req:
        exporter.export(
            fmt="requirements.txt",
            cwd=args.project_directory,
            output=req,
            with_hashes=not args.without_hashes,
            dev=args.dev,
            extras=args.extras,
            with_credentials=args.with_credentials,
        )
示例#15
0
def test_exporter_can_export_requirements_txt_with_directory_packages_and_markers(
    tmp_dir, poetry, working_directory
):
    poetry.locker.mock_lock_data(
        {
            "package": [
                {
                    "name": "foo",
                    "version": "1.2.3",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "marker": "python_version < '3.7'",
                    "source": {
                        "type": "directory",
                        "url": "tests/fixtures/sample_project",
                        "reference": "",
                    },
                }
            ],
            "metadata": {
                "python-versions": "*",
                "content-hash": "123456789",
                "hashes": {"foo": []},
            },
        }
    )
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
foo @ {}/tests/fixtures/sample_project; python_version < "3.7"
""".format(
        working_directory.as_posix()
    )

    assert expected == content
示例#16
0
文件: export.py 项目: tony/poetry
    def handle(self) -> None:
        fmt = self.option("format")

        if fmt not in Exporter.ACCEPTED_FORMATS:
            raise ValueError(f"Invalid export format: {fmt}")

        output = self.option("output")

        locker = self.poetry.locker
        if not locker.is_locked():
            self.line_error("<comment>The lock file does not exist. Locking.</comment>")
            options = []
            if self.io.is_debug():
                options.append("-vvv")
            elif self.io.is_very_verbose():
                options.append("-vv")
            elif self.io.is_verbose():
                options.append("-v")

            self.call("lock", " ".join(options))

        if not locker.is_fresh():
            self.line_error(
                "<warning>"
                "Warning: The lock file is not up to date with "
                "the latest changes in pyproject.toml. "
                "You may be getting outdated dependencies. "
                "Run update to update them."
                "</warning>"
            )

        exporter = Exporter(self.poetry)
        exporter.export(
            fmt,
            self.poetry.file.parent,
            output or self.io,
            with_hashes=not self.option("without-hashes"),
            dev=self.option("dev"),
            extras=self.option("extras"),
            with_credentials=self.option("with-credentials"),
            with_urls=not self.option("without-urls"),
        )
示例#17
0
def test_exporter_exports_requirements_txt_to_standard_output(
        tmp_dir, poetry, capsys):
    poetry.locker.mock_lock_data({
        "package": [
            {
                "name": "foo",
                "version": "1.2.3",
                "category": "main",
                "optional": False,
                "python-versions": "*",
            },
            {
                "name": "bar",
                "version": "4.5.6",
                "category": "main",
                "optional": False,
                "python-versions": "*",
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": [],
                "bar": []
            },
        },
    })
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), sys.stdout)

    out, err = capsys.readouterr()
    expected = """\
bar==4.5.6
foo==1.2.3
"""

    assert out == expected
示例#18
0
def test_exporter_exports_requirements_txt_without_dev_packages_by_default(
        tmp_dir, locker):
    locker.mock_lock_data({
        "package": [
            {
                "name": "foo",
                "version": "1.2.3",
                "category": "main",
                "optional": False,
                "python-versions": "*",
            },
            {
                "name": "bar",
                "version": "4.5.6",
                "category": "dev",
                "optional": False,
                "python-versions": "*",
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": ["12345"],
                "bar": ["67890"]
            },
        },
    })
    exporter = Exporter(locker)

    exporter.export("requirements.txt", Path(tmp_dir))

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
foo==1.2.3 \\
    --hash=sha256:12345
"""

    assert expected == content
示例#19
0
def test_exporter_can_export_requirements_txt_pyinstaller(tmp_dir, poetry):
    """Regression test for #3254"""

    poetry.locker.mock_lock_data(
        {
            "package": [
                {
                    "name": "pyinstaller",
                    "version": "4.0",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {
                        "altgraph": "*",
                        "macholib": {
                            "version": "*",
                            "markers": "sys_platform == 'darwin'",
                        },
                    },
                },
                {
                    "name": "altgraph",
                    "version": "0.17",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                },
                {
                    "name": "macholib",
                    "version": "1.8",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {"altgraph": ">=0.15"},
                },
            ],
            "metadata": {
                "python-versions": "*",
                "content-hash": "123456789",
                "hashes": {"pyinstaller": [], "altgraph": [], "macholib": []},
            },
        }
    )
    set_package_requires(poetry, skip={"altgraph", "macholib"})

    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    # Rationale for the results:
    #  * PyInstaller has an explicit dependency on altgraph, so it must always be installed.
    #  * PyInstaller requires macholib on Darwin, which in turn requires altgraph.
    # The dependency graph:
    # pyinstaller 4.0 PyInstaller bundles a Python application and all its dependencies into a single package.
    # ├── altgraph *
    # ├── macholib >=1.8 -- only on Darwin
    # │   └── altgraph >=0.15
    expected = {
        "pyinstaller": dependency_from_pep_508("pyinstaller==4.0"),
        "altgraph": dependency_from_pep_508("altgraph==0.17"),
        "macholib": dependency_from_pep_508("macholib==1.8; sys_platform == 'darwin'"),
    }

    for line in content.strip().split("\n"):
        dependency = dependency_from_pep_508(line)
        assert dependency.name in expected
        expected_dependency = expected.pop(dependency.name)
        assert dependency == expected_dependency
        assert dependency.marker == expected_dependency.marker
示例#20
0
def test_exporter_can_export_requirements_txt_with_nested_packages_and_multiple_markers(
        tmp_dir, poetry):
    poetry.locker.mock_lock_data({
        "package": [
            {
                "name": "foo",
                "version": "1.2.3",
                "category": "main",
                "optional": False,
                "python-versions": "*",
                "dependencies": {
                    "bar": [
                        {
                            "version": ">=1.2.3,<7.8.10",
                            "markers": 'platform_system != "Windows"',
                        },
                        {
                            "version": ">=4.5.6,<7.8.10",
                            "markers": 'platform_system == "Windows"',
                        },
                    ]
                },
            },
            {
                "name": "bar",
                "version": "7.8.9",
                "category": "main",
                "optional": True,
                "python-versions": "*",
                "dependencies": {
                    "baz": {
                        "version": "!=10.11.12",
                        "markers": 'platform_system == "Windows"',
                    }
                },
            },
            {
                "name": "baz",
                "version": "10.11.13",
                "category": "main",
                "optional": True,
                "python-versions": "*",
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": [],
                "bar": [],
                "baz": []
            },
        },
    })
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export("requirements.txt",
                    Path(tmp_dir),
                    "requirements.txt",
                    with_hashes=False)

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
bar==7.8.9
baz==10.11.13; platform_system == "Windows"
foo==1.2.3
"""

    assert expected == content
示例#21
0
def test_exporter_can_export_requirements_txt_poetry(tmp_dir, poetry):
    """Regression test for #3254"""

    poetry.locker.mock_lock_data(
        {
            "package": [
                {
                    "name": "poetry",
                    "version": "1.1.4",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {"keyring": "*"},
                },
                {
                    "name": "junit-xml",
                    "version": "1.9",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {"six": "*"},
                },
                {
                    "name": "keyring",
                    "version": "21.8.0",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {
                        "SecretStorage": {
                            "version": "*",
                            "markers": "sys_platform == 'linux'",
                        }
                    },
                },
                {
                    "name": "secretstorage",
                    "version": "3.3.0",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {"cryptography": "*"},
                },
                {
                    "name": "cryptography",
                    "version": "3.2",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "dependencies": {"six": "*"},
                },
                {
                    "name": "six",
                    "version": "1.15.0",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                },
            ],
            "metadata": {
                "python-versions": "*",
                "content-hash": "123456789",
                "hashes": {
                    "poetry": [],
                    "keyring": [],
                    "secretstorage": [],
                    "cryptography": [],
                    "six": [],
                    "junit-xml": [],
                },
            },
        }
    )
    set_package_requires(
        poetry, skip={"keyring", "secretstorage", "cryptography", "six"}
    )

    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    # The dependency graph:
    # junit-xml 1.9 Creates JUnit XML test result documents that can be read by tools such as Jenkins
    # └── six *
    # poetry 1.1.4 Python dependency management and packaging made easy.
    # ├── keyring >=21.2.0,<22.0.0
    # │   ├── importlib-metadata >=1
    # │   │   └── zipp >=0.5
    # │   ├── jeepney >=0.4.2
    # │   ├── pywin32-ctypes <0.1.0 || >0.1.0,<0.1.1 || >0.1.1
    # │   └── secretstorage >=3.2 -- On linux only
    # │       ├── cryptography >=2.0
    # │       │   └── six >=1.4.1
    # │       └── jeepney >=0.6 (circular dependency aborted here)
    expected = {
        "poetry": dependency_from_pep_508("poetry==1.1.4"),
        "junit-xml": dependency_from_pep_508("junit-xml==1.9"),
        "keyring": dependency_from_pep_508("keyring==21.8.0"),
        "secretstorage": dependency_from_pep_508(
            "secretstorage==3.3.0; sys_platform=='linux'"
        ),
        "cryptography": dependency_from_pep_508(
            "cryptography==3.2; sys_platform=='linux'"
        ),
        "six": dependency_from_pep_508("six==1.15.0"),
    }

    for line in content.strip().split("\n"):
        dependency = dependency_from_pep_508(line)
        assert dependency.name in expected
        expected_dependency = expected.pop(dependency.name)
        assert dependency == expected_dependency
        print(dependency.marker)
        print(expected_dependency.marker)
        assert dependency.marker == expected_dependency.marker
示例#22
0
def test_exporter_can_export_requirements_txt_with_nested_directory_packages(
        tmp_dir, poetry, working_directory):
    poetry.locker.mock_lock_data({
        "package": [
            {
                "name": "foo",
                "version": "1.2.3",
                "category": "main",
                "optional": False,
                "python-versions": "*",
                "source": {
                    "type": "directory",
                    "url": "tests/fixtures/sample_project",
                    "reference": "",
                },
            },
            {
                "name": "bar",
                "version": "4.5.6",
                "category": "main",
                "optional": False,
                "python-versions": "*",
                "source": {
                    "type": "directory",
                    "url":
                    "tests/fixtures/sample_project/../project_with_nested_local/bar",
                    "reference": "",
                },
            },
            {
                "name": "baz",
                "version": "7.8.9",
                "category": "main",
                "optional": False,
                "python-versions": "*",
                "source": {
                    "type": "directory",
                    "url":
                    "tests/fixtures/sample_project/../project_with_nested_local/bar/..",
                    "reference": "",
                },
            },
        ],
        "metadata": {
            "python-versions": "*",
            "content-hash": "123456789",
            "hashes": {
                "foo": [],
                "bar": [],
                "baz": []
            },
        },
    })
    set_package_requires(poetry)

    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = """\
bar @ {}/tests/fixtures/project_with_nested_local/bar
baz @ {}/tests/fixtures/project_with_nested_local
foo @ {}/tests/fixtures/sample_project
""".format(
        working_directory.as_uri(),
        working_directory.as_uri(),
        working_directory.as_uri(),
    )

    assert expected == content
示例#23
0
def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers(
    tmp_dir, poetry
):
    poetry.locker.mock_lock_data(
        {
            "package": [
                {
                    "name": "a",
                    "version": "1.2.3",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "marker": "python_version < '3.7'",
                    "dependencies": {"b": ">=0.0.0", "c": ">=0.0.0"},
                },
                {
                    "name": "b",
                    "version": "4.5.6",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "marker": "platform_system == 'Windows'",
                    "dependencies": {"d": ">=0.0.0"},
                },
                {
                    "name": "c",
                    "version": "7.8.9",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                    "marker": "sys_platform == 'win32'",
                    "dependencies": {"d": ">=0.0.0"},
                },
                {
                    "name": "d",
                    "version": "0.0.1",
                    "category": "main",
                    "optional": False,
                    "python-versions": "*",
                },
            ],
            "metadata": {
                "python-versions": "*",
                "content-hash": "123456789",
                "hashes": {"a": [], "b": [], "c": [], "d": []},
            },
        }
    )
    set_package_requires(poetry, skip={"b", "c", "d"})

    exporter = Exporter(poetry)

    exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

    with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
        content = f.read()

    expected = {
        "a": dependency_from_pep_508("a==1.2.3; python_version < '3.7'"),
        "b": dependency_from_pep_508(
            "b==4.5.6; platform_system == 'Windows' and python_version < '3.7'"
        ),
        "c": dependency_from_pep_508(
            "c==7.8.9; sys_platform == 'win32' and python_version < '3.7'"
        ),
        "d": dependency_from_pep_508(
            "d==0.0.1; platform_system == 'Windows' and python_version < '3.7' or sys_platform == 'win32' and python_version < '3.7'"
        ),
    }

    for line in content.strip().split("\n"):
        dependency = dependency_from_pep_508(line)
        assert dependency.name in expected
        expected_dependency = expected.pop(dependency.name)
        assert dependency == expected_dependency
        assert dependency.marker == expected_dependency.marker

    assert expected == {}