1
0
Fork 0
mirror of https://github.com/python-poetry/install.python-poetry.org.git synced 2024-11-23 14:30:57 -05:00

Compare commits

..

1 commit

Author SHA1 Message Date
Tatsunori Uchino
07185e6663 Add PowerShell snippets for postinstall 2022-07-17 18:54:20 +09:00
7 changed files with 154 additions and 317 deletions

3
.flake8 Normal file
View file

@ -0,0 +1,3 @@
[flake8]
max-line-length = 88
ignore = E501, E203, W503

View file

@ -1,6 +0,0 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly

View file

@ -15,7 +15,7 @@ on:
- '**'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
group: installer-${{ github.head_ref || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
@ -25,32 +25,27 @@ jobs:
strategy:
matrix:
os: [Ubuntu, macOS, Windows]
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11-dev"]
args:
- ""
- "--preview"
- "--git https://github.com/python-poetry/poetry.git"
- "--version 1.1.14"
include:
- os: Ubuntu
image: ubuntu-22.04
image: ubuntu-latest
- os: Windows
image: windows-2022
- os: macOS
image: macos-12
fail-fast: false
image: macos-11
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
@ -63,10 +58,10 @@ jobs:
run: echo "$APPDATA\Python\Scripts" >> $GITHUB_PATH
- name: Install Poetry
run: python install-poetry.py -y ${{ matrix.args }}
run: python install-poetry.py -y
- name: Upload Failure Log
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v2
if: failure()
with:
name: poetry-installer-error.log
@ -86,56 +81,3 @@ jobs:
run: |
python install-poetry.py -y --uninstall
{ type poetry 2>/dev/null >&2 && exit 1; } || exit 0
# debian/ubuntu needs special testing due to various issues around python packaging
# and configuration
integration-ubuntu:
name: Integration Test / Ubuntu / ${{ matrix.tag }}
runs-on: ubuntu-latest
container: docker.io/ubuntu:${{ matrix.tag }}
strategy:
matrix:
tag:
- focal
- jammy
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- name: Install Packages
run: |
apt-get -y update
apt-get -y install python3 ca-certificates
apt-get -y install --reinstall python3-distutils
- name: Update PATH
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install Poetry
env:
DEB_PYTHON_INSTALL_LAYOUT: "deb"
run: python3 install-poetry.py -y
- name: Upload Failure Log
uses: actions/upload-artifact@v4
if: failure()
with:
name: poetry-installer-error.log
path: poetry-installer-error-*.log
- name: Verify Installation
run: |
set -e
poetry new foobar
cd foobar
poetry config virtualenvs.in-project true
poetry env use python3
[ "$(poetry run python --version)" == "$(python3 --version)" ] \
|| { echo >&2 "ERROR: Virtual environment Python version do not match system version." && exit 1; }
- name: Uninstall Poetry
run: |
python3 install-poetry.py -y --uninstall
{ type poetry 2>/dev/null >&2 && exit 1; } || exit 0

View file

@ -1,20 +1,28 @@
repos:
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 23.9.1
- repo: https://github.com/psf/black
rev: 22.6.0
hooks:
- id: black
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
hooks:
- id: flake8
additional_dependencies:
- flake8-bugbear==22.4.25
- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
- id: isort
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: debug-statements
- id: pretty-format-json
args: [--autofix]
args:
- --autofix
- id: check-json
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.290
hooks:
- id: ruff

View file

@ -1,7 +1,4 @@
# Python Poetry Installer
[![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/)
This repository contains Poetry's official installation script, installer source and
related hosting configuration.
@ -14,21 +11,16 @@ Poetry provides a custom installer that will install `poetry` isolated
from the rest of your system.
### osx / linux / bashonwindows / Windows+MinGW install instructions
```bash
curl -sSL https://install.python-poetry.org | python3 -
curl -sSL https://install.python-poetry.org | python -
```
### windows powershell install instructions
```powershell
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -
```
> If you have installed Python through the Microsoft Store, replace `py` with `python` in the command above.
**Warning**: The previous `get-poetry.py` installer is now deprecated, if you are currently using it
you should migrate to the new, supported, `install.python-poetry.org` installer.
you should migrate to the new, supported, `install-poetry.py` installer.
The installer installs the `poetry` tool to Poetry's `bin` directory. This location depends on your system:
@ -49,88 +41,40 @@ poetry --version
If you see something like `Poetry (version 1.2.0)` then you are ready to use Poetry.
If you decide Poetry isn't your thing, you can completely remove it from your system
by running the installer again with the `--uninstall` option or by setting
the `POETRY_UNINSTALL` environment variable before executing the installer:
the `POETRY_UNINSTALL` environment variable before executing the installer.
```bash
curl -sSL https://install.python-poetry.org | python3 - --uninstall
curl -sSL https://install.python-poetry.org | POETRY_UNINSTALL=1 python3 -
python install-poetry.py --uninstall
POETRY_UNINSTALL=1 python install-poetry.py
```
By default, Poetry is installed into the user's platform-specific home directory.
If you wish to change this, you may define the `POETRY_HOME` environment variable:
```bash
curl -sSL https://install.python-poetry.org | POETRY_HOME=/etc/poetry python3 -
POETRY_HOME=/etc/poetry python install-poetry.py
```
If you want to install prerelease versions, you can do so by passing `--preview` option or by using the `POETRY_PREVIEW`
environment variable:
If you want to install prerelease versions, you can do so by passing `--preview` option to `install-poetry.py`
or by using the `POETRY_PREVIEW` environment variable:
```bash
curl -sSL https://install.python-poetry.org | python3 - --preview
curl -sSL https://install.python-poetry.org | POETRY_PREVIEW=1 python3 -
python install-poetry.py --preview
POETRY_PREVIEW=1 python install-poetry.py
```
Similarly, if you want to install a specific version, you can use `--version` option or the `POETRY_VERSION`
environment variable:
```bash
curl -sSL https://install.python-poetry.org | python3 - --version 1.2.0
curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.2.0 python3 -
python install-poetry.py --version 1.2.0
POETRY_VERSION=1.2.0 python install-poetry.py
```
You can also install Poetry for a `git` repository by using the `--git` option:
```bash
curl -sSL https://install.python-poetry.org | python3 - --git https://github.com/python-poetry/poetry.git@master
python install-poetry.py --git https://github.com/python-poetry/poetry.git@master
````
> **Note**: The installer does not support Python < 3.6.
## Known Issues
### Debian/Ubuntu
On Debian and Ubuntu systems, there are various issues that maybe caused due to how
various Python standard library components are packaged and configured. The following
details issues we are presently aware of, and potential workarounds.
> **Note:** This can also affect WSL users on Windows.
#### Installation Layout
If you encounter an error similar to the following, this might be due to
[pypa/virtualenv#2350](https://github.com/pypa/virtualenv/issues/2350).
```console
FileNotFoundError: [Errno 2] No such file or directory: '/root/.local/share/pypoetry/venv/bin/python'
```
You can work around this issue by setting the `DEB_PYTHON_INSTALL_LAYOUT` environment
variable to `deb` in order to emulate previously working behaviour.
```bash
export DEB_PYTHON_INSTALL_LAYOUT=deb
```
#### Missing `distutils` Module
In certain Debian/Ubuntu environments, you might encounter the following error message
in error logs (`poetry-installer-error-*.log`) provided when the installer fails.
```console
ModuleNotFoundError: No module named 'distutils.cmd'
```
This is probably due to [this bug](https://bugs.launchpad.net/ubuntu/+source/python3.10/+bug/1940705).
See also [pypa/get-pip#124](https://github.com/pypa/get-pip/issues/124).
The known workaround for this issue is to reinstall the `distutils` package provided by
the distribution.
```bash
apt-get install --reinstall python3-distutils
```
If you have installed a specific python version, eg: `3.10`, you might have to use the
package name `python3.10-distutils`.
**Note**: Note that the installer does not support Python < 3.6.

View file

@ -1,43 +1,27 @@
#!/usr/bin/env python3
r"""
This script will install Poetry and its dependencies in an isolated fashion.
"""
This script will install Poetry and its dependencies.
It will perform the following steps:
* Create a new virtual environment using the built-in venv module, or the virtualenv zipapp if venv is unavailable.
This will be created at a platform-specific path (or `$POETRY_HOME` if `$POETRY_HOME` is set:
- `~/Library/Application Support/pypoetry` on macOS
- `$XDG_DATA_HOME/pypoetry` on Linux/Unix (`$XDG_DATA_HOME` is `~/.local/share` if unset)
- `%APPDATA%\pypoetry` on Windows
* Update pip inside the virtual environment to avoid bugs in older versions.
* Install the latest (or a given) version of Poetry inside this virtual environment using pip.
* Install a `poetry` script into a platform-specific path (or `$POETRY_HOME/bin` if `$POETRY_HOME` is set):
- `~/.local/bin` on Unix
- `%APPDATA%\Python\Scripts` on Windows
* Attempt to inform the user if they need to add this bin directory to their `$PATH`, as well as how to do so.
* Upon failure, write an error log to `poetry-installer-error-<hash>.log and restore any previous environment.
This script performs minimal magic, and should be relatively stable. However, it is optimized for interactive developer
use and trivial pipelines. If you are considering using this script in production, you should consider manually-managed
installs, or use of pipx as alternatives to executing arbitrary, unversioned code from the internet. If you prefer this
script to alternatives, consider maintaining a local copy as part of your infrastructure.
For full documentation, visit https://python-poetry.org/docs/#installation.
""" # noqa: E501
import sys
# Eager version check so we fail nicely before possible syntax errors
if sys.version_info < (3, 6): # noqa: UP036
sys.stdout.write("Poetry installer requires Python 3.6 or newer to run!\n")
sys.exit(1)
It does, in order:
- Creates a virtual environment using venv (or virtualenv zipapp) in the correct OS data dir which will be
- `%APPDATA%\\pypoetry` on Windows
- ~/Library/Application Support/pypoetry on MacOS
- `${XDG_DATA_HOME}/pypoetry` (or `~/.local/share/pypoetry` if it's not set) on UNIX systems
- In `${POETRY_HOME}` if it's set.
- Installs the latest or given version of Poetry inside this virtual environment.
- Installs a `poetry` script in the Python user directory (or `${POETRY_HOME/bin}` if `POETRY_HOME` is set).
- On failure, the error log is written to poetry-installer-error-*.log and any previously existing environment
is restored.
"""
import argparse
import json
import os
import re
import shutil
import site
import subprocess
import sys
import sysconfig
import tempfile
@ -114,8 +98,8 @@ def is_decorated():
if WINDOWS:
return (
os.getenv("ANSICON") is not None
or os.getenv("ConEmuANSI") == "ON" # noqa: SIM112
or os.getenv("Term") == "xterm" # noqa: SIM112
or "ON" == os.getenv("ConEmuANSI")
or "xterm" == os.getenv("Term")
)
if not hasattr(sys.stdout, "fileno"):
@ -141,7 +125,7 @@ def colorize(style, text):
if not is_decorated():
return text
return f"{STYLES[style]}{text}\033[0m"
return "{}{}\033[0m".format(STYLES[style], text)
def string_to_bool(value):
@ -150,29 +134,38 @@ def string_to_bool(value):
return value in {"true", "1", "y", "yes"}
def data_dir() -> Path:
def data_dir(version: Optional[str] = None) -> Path:
if os.getenv("POETRY_HOME"):
return Path(os.getenv("POETRY_HOME")).expanduser()
if WINDOWS:
base_dir = Path(_get_win_folder("CSIDL_APPDATA"))
const = "CSIDL_APPDATA"
path = os.path.normpath(_get_win_folder(const))
path = os.path.join(path, "pypoetry")
elif MACOS:
base_dir = Path("~/Library/Application Support").expanduser()
path = os.path.expanduser("~/Library/Application Support/pypoetry")
else:
base_dir = Path(os.getenv("XDG_DATA_HOME", "~/.local/share")).expanduser()
path = os.getenv("XDG_DATA_HOME", os.path.expanduser("~/.local/share"))
path = os.path.join(path, "pypoetry")
base_dir = base_dir.resolve()
return base_dir / "pypoetry"
if version:
path = os.path.join(path, version)
return Path(path)
def bin_dir() -> Path:
def bin_dir(version: Optional[str] = None) -> Path:
if os.getenv("POETRY_HOME"):
return Path(os.getenv("POETRY_HOME")).expanduser() / "bin"
return Path(os.getenv("POETRY_HOME"), "bin").expanduser()
user_base = site.getuserbase()
if WINDOWS and not MINGW:
return Path(_get_win_folder("CSIDL_APPDATA")) / "Python/Scripts"
bin_dir = os.path.join(user_base, "Scripts")
else:
return Path("~/.local/bin").expanduser()
bin_dir = os.path.join(user_base, "bin")
return Path(bin_dir)
def _get_win_folder_from_registry(csidl_name):
@ -188,9 +181,9 @@ def _get_win_folder_from_registry(csidl_name):
_winreg.HKEY_CURRENT_USER,
r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders",
)
path, _ = _winreg.QueryValueEx(key, shell_folder_name)
dir, type = _winreg.QueryValueEx(key, shell_folder_name)
return path
return dir
def _get_win_folder_with_ctypes(csidl_name):
@ -272,7 +265,7 @@ You can execute `set -U fish_user_paths {poetry_home_bin} $fish_user_paths`
POST_MESSAGE_CONFIGURE_WINDOWS = """
You can choose and execute one of the following commands in PowerShell:
A. Append the bin directory to your user environment variable `PATH`:
A. Appends the bin directory to your user environment variable `PATH`:
```
[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";{poetry_home_bin}", "User")
@ -288,7 +281,7 @@ echo 'if (-not (Get-Command poetry -ErrorAction Ignore)) {{ $env:Path += ";{poet
class PoetryInstallationError(RuntimeError):
def __init__(self, return_code: int = 0, log: Optional[str] = None):
super().__init__()
super(PoetryInstallationError, self).__init__()
self.return_code = return_code
self.log = log
@ -299,7 +292,7 @@ class VirtualEnvironment:
self._bin_path = self._path.joinpath(
"Scripts" if WINDOWS and not MINGW else "bin"
)
# str is for compatibility with subprocess.run on CPython <= 3.7 on Windows
# str is required for compatibility with subprocess run on CPython <= 3.7 on Windows
self._python = str(
self._path.joinpath(self._bin_path, "python.exe" if WINDOWS else "python")
)
@ -314,18 +307,7 @@ class VirtualEnvironment:
@classmethod
def make(cls, target: Path) -> "VirtualEnvironment":
if not sys.executable:
raise ValueError(
"Unable to determine sys.executable. Set PATH to a sane value or set it"
" explicitly with PYTHONEXECUTABLE."
)
try:
# on some linux distributions (eg: debian), the distribution provided python
# installation might not include ensurepip, causing the venv module to
# fail when attempting to create a virtual environment
# we import ensurepip but do not use it explicitly here
import ensurepip # noqa: F401
import venv
builder = venv.EnvBuilder(clear=True, with_pip=True, symlinks=False)
@ -362,7 +344,7 @@ class VirtualEnvironment:
env = cls(target)
# this ensures that outdated system default pip does not trigger older bugs
# we do this here to ensure that outdated system default pip does not trigger older bugs
env.pip("install", "--disable-pip-version-check", "--upgrade", "pip")
return env
@ -394,32 +376,32 @@ class Cursor:
self._output = sys.stdout
def move_up(self, lines: int = 1) -> "Cursor":
self._output.write(f"\x1b[{lines}A")
self._output.write("\x1b[{}A".format(lines))
return self
def move_down(self, lines: int = 1) -> "Cursor":
self._output.write(f"\x1b[{lines}B")
self._output.write("\x1b[{}B".format(lines))
return self
def move_right(self, columns: int = 1) -> "Cursor":
self._output.write(f"\x1b[{columns}C")
self._output.write("\x1b[{}C".format(columns))
return self
def move_left(self, columns: int = 1) -> "Cursor":
self._output.write(f"\x1b[{columns}D")
self._output.write("\x1b[{}D".format(columns))
return self
def move_to_column(self, column: int) -> "Cursor":
self._output.write(f"\x1b[{column}G")
self._output.write("\x1b[{}G".format(column))
return self
def move_to_position(self, column: int, row: int) -> "Cursor":
self._output.write(f"\x1b[{row + 1};{column}H")
self._output.write("\x1b[{};{}H".format(row + 1, column))
return self
@ -504,26 +486,9 @@ class Installer:
self._accept_all = accept_all
self._git = git
self._path = path
self._cursor = Cursor()
self._bin_dir = None
self._data_dir = None
@property
def bin_dir(self) -> Path:
if not self._bin_dir:
self._bin_dir = bin_dir()
return self._bin_dir
@property
def data_dir(self) -> Path:
if not self._data_dir:
self._data_dir = data_dir()
return self._data_dir
@property
def version_file(self) -> Path:
return self.data_dir.joinpath("VERSION")
self._bin_dir = bin_dir()
self._cursor = Cursor()
def allows_prereleases(self) -> bool:
return self._preview
@ -549,20 +514,18 @@ class Installer:
mx = self.VERSION_REGEX.match(x)
if mx is None:
# the version is not semver, perhaps scm or file
# we assume upgrade is supported
# the version is not semver, perhaps scm or file, we assume upgrade is supported
return True
vx = (*tuple(int(p) for p in mx.groups()[:3]), mx.group(5))
vx = tuple(int(p) for p in mx.groups()[:3]) + (mx.group(5),)
return vx >= (1, 1, 7)
if version and not _is_self_upgrade_supported(version):
self._write(
colorize(
"warning",
f"You are installing {version}. When using the current installer, "
"this version does not support updating using the 'self update' "
"command. Please use 1.1.7 or later.",
f"You are installing {version}. When using the current installer, this version does not support "
f"updating using the 'self update' command. Please use 1.1.7 or later.",
)
)
if not self._accept_all:
@ -575,14 +538,14 @@ class Installer:
except subprocess.CalledProcessError as e:
raise PoetryInstallationError(
return_code=e.returncode, log=e.output.decode()
) from e
)
self._write("")
self.display_post_message(version)
return 0
def install(self, version):
def install(self, version, upgrade=False):
"""
Installs Poetry in $POETRY_HOME.
"""
@ -595,13 +558,13 @@ class Installer:
with self.make_env(version) as env:
self.install_poetry(version, env)
self.make_bin(version, env)
self.version_file.write_text(version)
self._data_dir.joinpath("VERSION").write_text(version)
self._install_comment(version, "Done")
return 0
def uninstall(self) -> int:
if not self.data_dir.exists():
if not self._data_dir.exists():
self._write(
"{} is not currently installed.".format(colorize("info", "Poetry"))
)
@ -609,8 +572,8 @@ class Installer:
return 1
version = None
if self.version_file.exists():
version = self.version_file.read_text().strip()
if self._data_dir.joinpath("VERSION").exists():
version = self._data_dir.joinpath("VERSION").read_text().strip()
if version:
self._write(
@ -621,10 +584,10 @@ class Installer:
else:
self._write("Removing {}".format(colorize("info", "Poetry")))
shutil.rmtree(str(self.data_dir))
for script in ["poetry", "poetry.bat", "poetry.exe"]:
if self.bin_dir.joinpath(script).exists():
self.bin_dir.joinpath(script).unlink()
shutil.rmtree(str(self._data_dir))
for script in ["poetry", "poetry.bat"]:
if self._bin_dir.joinpath(script).exists():
self._bin_dir.joinpath(script).unlink()
return 0
@ -639,7 +602,7 @@ class Installer:
@contextmanager
def make_env(self, version: str) -> VirtualEnvironment:
env_path = self.data_dir.joinpath("venv")
env_path = self._data_dir.joinpath("venv")
env_path_saved = env_path.with_suffix(".save")
if env_path.exists():
@ -671,20 +634,20 @@ class Installer:
def make_bin(self, version: str, env: VirtualEnvironment) -> None:
self._install_comment(version, "Creating script")
self.bin_dir.mkdir(parents=True, exist_ok=True)
self._bin_dir.mkdir(parents=True, exist_ok=True)
script = "poetry.exe" if WINDOWS else "poetry"
target_script = env.bin_path.joinpath(script)
if self.bin_dir.joinpath(script).exists():
self.bin_dir.joinpath(script).unlink()
if self._bin_dir.joinpath(script).exists():
self._bin_dir.joinpath(script).unlink()
try:
self.bin_dir.joinpath(script).symlink_to(target_script)
self._bin_dir.joinpath(script).symlink_to(target_script)
except OSError:
# This can happen if the user
# does not have the correct permission on Windows
shutil.copy(target_script, self.bin_dir.joinpath(script))
shutil.copy(target_script, self._bin_dir.joinpath(script))
def install_poetry(self, version: str, env: VirtualEnvironment) -> None:
self._install_comment(version, "Installing Poetry")
@ -701,7 +664,7 @@ class Installer:
def display_pre_message(self) -> None:
kwargs = {
"poetry": colorize("info", "Poetry"),
"poetry_home_bin": colorize("comment", self.bin_dir),
"poetry_home_bin": colorize("comment", self._bin_dir),
}
self._write(PRE_MESSAGE.format(**kwargs))
@ -718,17 +681,17 @@ class Installer:
path = self.get_windows_path_var()
message = POST_MESSAGE_NOT_IN_PATH
if path and str(self.bin_dir) in path:
if path and str(self._bin_dir) in path:
message = POST_MESSAGE
self._write(
message.format(
poetry=colorize("info", "Poetry"),
version=colorize("b", version),
poetry_home_bin=colorize("comment", self.bin_dir),
poetry_executable=colorize("b", self.bin_dir.joinpath("poetry")),
poetry_home_bin=colorize("comment", self._bin_dir),
poetry_executable=colorize("b", self._bin_dir.joinpath("poetry")),
configure_message=POST_MESSAGE_CONFIGURE_WINDOWS.format(
poetry_home_bin=colorize("comment", self.bin_dir)
poetry_home_bin=colorize("comment", self._bin_dir)
),
test_command=colorize("b", "poetry --version"),
)
@ -737,9 +700,8 @@ class Installer:
def get_windows_path_var(self) -> Optional[str]:
import winreg
with winreg.ConnectRegistry(
None, winreg.HKEY_CURRENT_USER
) as root, winreg.OpenKey(root, "Environment", 0, winreg.KEY_ALL_ACCESS) as key:
with winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) as root:
with winreg.OpenKey(root, "Environment", 0, winreg.KEY_ALL_ACCESS) as key:
path, _ = winreg.QueryValueEx(key, "PATH")
return path
@ -750,17 +712,17 @@ class Installer:
).decode("utf-8")
message = POST_MESSAGE_NOT_IN_PATH
if fish_user_paths and str(self.bin_dir) in fish_user_paths:
if fish_user_paths and str(self._bin_dir) in fish_user_paths:
message = POST_MESSAGE
self._write(
message.format(
poetry=colorize("info", "Poetry"),
version=colorize("b", version),
poetry_home_bin=colorize("comment", self.bin_dir),
poetry_executable=colorize("b", self.bin_dir.joinpath("poetry")),
poetry_home_bin=colorize("comment", self._bin_dir),
poetry_executable=colorize("b", self._bin_dir.joinpath("poetry")),
configure_message=POST_MESSAGE_CONFIGURE_FISH.format(
poetry_home_bin=colorize("comment", self.bin_dir)
poetry_home_bin=colorize("comment", self._bin_dir)
),
test_command=colorize("b", "poetry --version"),
)
@ -770,30 +732,30 @@ class Installer:
paths = os.getenv("PATH", "").split(":")
message = POST_MESSAGE_NOT_IN_PATH
if paths and str(self.bin_dir) in paths:
if paths and str(self._bin_dir) in paths:
message = POST_MESSAGE
self._write(
message.format(
poetry=colorize("info", "Poetry"),
version=colorize("b", version),
poetry_home_bin=colorize("comment", self.bin_dir),
poetry_executable=colorize("b", self.bin_dir.joinpath("poetry")),
poetry_home_bin=colorize("comment", self._bin_dir),
poetry_executable=colorize("b", self._bin_dir.joinpath("poetry")),
configure_message=POST_MESSAGE_CONFIGURE_UNIX.format(
poetry_home_bin=colorize("comment", self.bin_dir)
poetry_home_bin=colorize("comment", self._bin_dir)
),
test_command=colorize("b", "poetry --version"),
)
)
def ensure_directories(self) -> None:
self.data_dir.mkdir(parents=True, exist_ok=True)
self.bin_dir.mkdir(parents=True, exist_ok=True)
self._data_dir.mkdir(parents=True, exist_ok=True)
self._bin_dir.mkdir(parents=True, exist_ok=True)
def get_version(self):
current_version = None
if self.version_file.exists():
current_version = self.version_file.read_text().strip()
if self._data_dir.joinpath("VERSION").exists():
current_version = self._data_dir.joinpath("VERSION").read_text().strip()
self._write(colorize("info", "Retrieving Poetry metadata"))
@ -803,8 +765,8 @@ class Installer:
mx = self.VERSION_REGEX.match(x)
my = self.VERSION_REGEX.match(y)
vx = (*tuple(int(p) for p in mx.groups()[:3]), mx.group(5))
vy = (*tuple(int(p) for p in my.groups()[:3]), my.group(5))
vx = tuple(int(p) for p in mx.groups()[:3]) + (mx.group(5),)
vy = tuple(int(p) for p in my.groups()[:3]) + (my.group(5),)
if vx < vy:
return -1
@ -819,7 +781,7 @@ class Installer:
)
if self._version and self._version not in releases:
msg = f"Version {self._version} does not exist."
msg = "Version {} does not exist.".format(self._version)
self._write(colorize("error", msg))
raise ValueError(msg)
@ -837,7 +799,9 @@ class Installer:
if current_version == version and not self._force:
self._write(
f'The latest version ({colorize("b", version)}) is already installed.'
"The latest version ({}) is already installed.".format(
colorize("b", version)
)
)
return None, current_version
@ -948,8 +912,7 @@ def main():
text=True,
)
installer._write(colorize("error", f"See {path} for error logs."))
tb = "".join(traceback.format_tb(e.__traceback__))
text = f"{e.log}\nTraceback:\n\n{tb}"
text = f"{e.log}\nTraceback:\n\n{''.join(traceback.format_tb(e.__traceback__))}"
Path(path).write_text(text)
return e.return_code

View file

@ -1,29 +1,12 @@
[tool.ruff]
fix = true
unfixable = [
"ERA", # do not autoremove commented out code
]
target-version = "py37"
[tool.isort]
profile = "black"
force_single_line = true
atomic = true
lines_after_imports = 2
lines_between_types = 1
filter_files = true
[tool.black]
line-length = 88
extend-select = [
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"ERA", # flake8-eradicate/eradicate
"I", # isort
"N", # pep8-naming
"PIE", # flake8-pie
"PGH", # pygrep
"RUF", # ruff checks
"SIM", # flake8-simplify
"TCH", # flake8-type-checking
"TID", # flake8-tidy-imports
"UP", # pyupgrade
]
[tool.ruff.flake8-tidy-imports]
ban-relative-imports = "all"
[tool.ruff.isort]
force-single-line = true
lines-between-types = 1
lines-after-imports = 2
include = '\.pyi?$'