示例#1
0
 def __init__(self, poetry: "Poetry", io: Union["BufferedIO",
                                                "ConsoleIO"]) -> None:
     self._poetry = poetry
     self._package = poetry.package
     self._io = io
     self._uploader = Uploader(poetry, io)
     self._authenticator = Authenticator(poetry.config, self._io)
示例#2
0
def test_uploader_properly_handles_403_errors(http):
    http.register_uri(http.POST, "https://foo.com", status=403, body="Unauthorized")
    uploader = Uploader(Factory().create_poetry(project("simple_project")), NullIO())

    with pytest.raises(UploadError) as e:
        uploader.upload("https://foo.com")

    assert "HTTP Error 403: Forbidden" == str(e.value)
示例#3
0
def test_uploader_skip_existing_bubbles_unskippable_errors(
        http: type[httpretty.httpretty], uploader: Uploader):
    http.register_uri(http.POST,
                      "https://foo.com",
                      status=403,
                      body="Unauthorized")

    with pytest.raises(UploadError):
        uploader.upload("https://foo.com", skip_existing=True)
示例#4
0
def test_uploader_properly_handles_403_errors(
        http: Type["httpretty.httpretty"], uploader: Uploader):
    http.register_uri(http.POST,
                      "https://foo.com",
                      status=403,
                      body="Unauthorized")

    with pytest.raises(UploadError) as e:
        uploader.upload("https://foo.com")

    assert str(e.value) == "HTTP Error 403: Forbidden"
示例#5
0
def test_uploader_properly_handles_400_errors(
        http: Type["httpretty.httpretty"], uploader: Uploader):
    http.register_uri(http.POST,
                      "https://foo.com",
                      status=400,
                      body="Bad request")

    with pytest.raises(UploadError) as e:
        uploader.upload("https://foo.com")

    assert str(e.value) == "HTTP Error 400: Bad Request"
示例#6
0
def test_uploader_registers_for_appropriate_400_errors(mocker, http):
    register = mocker.patch("poetry.publishing.uploader.Uploader._register")
    http.register_uri(
        http.POST, "https://foo.com", status=400, body="No package was ever registered"
    )
    uploader = Uploader(Factory().create_poetry(project("simple_project")), NullIO())

    with pytest.raises(UploadError):
        uploader.upload("https://foo.com")

    assert 1 == register.call_count
示例#7
0
def test_uploader_registers_for_appropriate_400_errors(
        mocker: "MockerFixture", http: Type["httpretty.httpretty"],
        uploader: Uploader):
    register = mocker.patch("poetry.publishing.uploader.Uploader._register")
    http.register_uri(http.POST,
                      "https://foo.com",
                      status=400,
                      body="No package was ever registered")

    with pytest.raises(UploadError):
        uploader.upload("https://foo.com")

    assert register.call_count == 1
示例#8
0
def test_uploader_properly_handles_301_redirects(
        http: Type["httpretty.httpretty"], uploader: Uploader):
    http.register_uri(http.POST,
                      "https://foo.com",
                      status=301,
                      body="Redirect")

    with pytest.raises(UploadError) as e:
        uploader.upload("https://foo.com")

    assert (str(
        e.value
    ) == "Redirects are not supported. Is the URL missing a trailing slash?")
示例#9
0
def test_uploader_properly_handles_301_redirects(http):
    http.register_uri(http.POST,
                      "https://foo.com",
                      status=301,
                      body="Redirect")
    uploader = Uploader(Factory().create_poetry(project("simple_project")),
                        NullIO())

    with pytest.raises(UploadError) as e:
        uploader.upload("https://foo.com")

    assert "Redirects are not supported. Is the URL missing a trailing slash?" == str(
        e.value)
示例#10
0
 def __init__(self, poetry: Poetry, io: BufferedIO | ConsoleIO) -> None:
     self._poetry = poetry
     self._package = poetry.package
     self._io = io
     self._uploader = Uploader(poetry, io)
     self._authenticator = Authenticator(poetry.config, self._io)
示例#11
0
class Publisher:
    """
    Registers and publishes packages to remote repositories.
    """

    def __init__(self, poetry: Poetry, io: BufferedIO | ConsoleIO) -> None:
        self._poetry = poetry
        self._package = poetry.package
        self._io = io
        self._uploader = Uploader(poetry, io)
        self._authenticator = Authenticator(poetry.config, self._io)

    @property
    def files(self) -> list[Path]:
        return self._uploader.files

    def publish(
        self,
        repository_name: str | None,
        username: str | None,
        password: str | None,
        cert: Path | None = None,
        client_cert: Path | None = None,
        dry_run: bool = False,
        skip_existing: bool = False,
    ) -> None:
        if not repository_name:
            url = "https://upload.pypi.org/legacy/"
            repository_name = "pypi"
        else:
            # Retrieving config information
            url = self._poetry.config.get(f"repositories.{repository_name}.url")
            if url is None:
                raise RuntimeError(f"Repository {repository_name} is not defined")

        if not (username and password):
            # Check if we have a token first
            token = self._authenticator.get_pypi_token(repository_name)
            if token:
                logger.debug(f"Found an API token for {repository_name}.")
                username = "******"
                password = token
            else:
                auth = self._authenticator.get_http_auth(repository_name)
                if auth:
                    logger.debug(
                        f"Found authentication information for {repository_name}."
                    )
                    username = auth.username
                    password = auth.password

        certificates = self._authenticator.get_certs_for_repository(repository_name)
        resolved_cert = cert or certificates.cert or certificates.verify
        resolved_client_cert = client_cert or certificates.client_cert

        self._uploader.auth(username, password)

        if repository_name == "pypi":
            repository_name = "PyPI"
        self._io.write_line(
            f"Publishing <c1>{self._package.pretty_name}</c1>"
            f" (<c2>{self._package.pretty_version}</c2>) to"
            f" <info>{repository_name}</info>"
        )

        self._uploader.upload(
            url,
            cert=resolved_cert,
            client_cert=resolved_client_cert,
            dry_run=dry_run,
            skip_existing=skip_existing,
        )
示例#12
0
def uploader():
    return Uploader(Factory().create_poetry(project("simple_project")),
                    NullIO())
示例#13
0
def uploader(fixture_dir: "FixtureDirGetter") -> Uploader:
    return Uploader(Factory().create_poetry(fixture_dir("simple_project")),
                    NullIO())
示例#14
0
class Publisher:
    """
    Registers and publishes packages to remote repositories.
    """
    def __init__(self, poetry: Poetry, io: BufferedIO | ConsoleIO) -> None:
        self._poetry = poetry
        self._package = poetry.package
        self._io = io
        self._uploader = Uploader(poetry, io)
        self._authenticator = Authenticator(poetry.config, self._io)

    @property
    def files(self) -> list[Path]:
        return self._uploader.files

    def publish(
        self,
        repository_name: str | None,
        username: str | None,
        password: str | None,
        cert: Path | None = None,
        client_cert: Path | None = None,
        dry_run: bool = False,
    ) -> None:
        if not repository_name:
            url = "https://upload.pypi.org/legacy/"
            repository_name = "pypi"
        else:
            # Retrieving config information
            url = self._poetry.config.get(
                f"repositories.{repository_name}.url")
            if url is None:
                raise RuntimeError(
                    f"Repository {repository_name} is not defined")

        if not (username and password):
            # Check if we have a token first
            token = self._authenticator.get_pypi_token(repository_name)
            if token:
                logger.debug(f"Found an API token for {repository_name}.")
                username = "******"
                password = token
            else:
                auth = self._authenticator.get_http_auth(repository_name)
                if auth:
                    logger.debug(
                        f"Found authentication information for {repository_name}."
                    )
                    username = auth["username"]
                    password = auth["password"]

        resolved_client_cert = client_cert or get_client_cert(
            self._poetry.config, repository_name)
        # Requesting missing credentials but only if there is not a client cert defined.
        if not resolved_client_cert:
            if username is None:
                username = self._io.ask("Username:"******"Password:"******"pypi":
            repository_name = "PyPI"
        self._io.write_line(f"Publishing <c1>{self._package.pretty_name}</c1>"
                            f" (<c2>{self._package.pretty_version}</c2>) to"
                            f" <info>{repository_name}</info>")

        self._uploader.upload(
            url,
            cert=cert or get_cert(self._poetry.config, repository_name),
            client_cert=resolved_client_cert,
            dry_run=dry_run,
        )
示例#15
0
def test_uploader_skips_existing(http: type[httpretty.httpretty],
                                 uploader: Uploader, status: int, body: str):
    http.register_uri(http.POST, "https://foo.com", status=status, body=body)

    # should not raise
    uploader.upload("https://foo.com", skip_existing=True)