Skip to content

Commit

Permalink
Show helpful error message when task executable is not on the path
Browse files Browse the repository at this point in the history
  • Loading branch information
nat-n committed Oct 7, 2023
1 parent f500668 commit dfb8cab
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 18 deletions.
74 changes: 66 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ jobs:
- name: Run tests
run: poetry run pytest -v

build-release:
name: Build and release
build:
name: Build distribution
runs-on: ubuntu-latest
needs: [code-quality, run-tests]
steps:
Expand All @@ -78,18 +78,76 @@ jobs:
- name: Build package
run: poetry build

- name: Publish package to PyPI
- name: Store the distribution packages
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
run: poetry publish -n
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.pypi }}
uses: actions/upload-artifact@v3
with:
name: python-package-distributions
path: dist/

- name: Update homebrew formula
# if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
pypi-publish:
name: Upload release to PyPI
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
needs: [build]
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/poethepoet
permissions:
id-token: write
steps:
- name: Download all the dists
uses: actions/download-artifact@v3
with:
name: python-package-distributions
path: dist/

- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

homebrew-publish:
name: Upload homebrew formula
needs: [pypi-publish]
runs-on: ubuntu-latest
steps:
- name: Trigger update of homebrew formula
run: >
curl -L -X POST
-H "Accept: application/vnd.github+json"
-H "Authorization: Bearer ${{ secrets.homebrew_pat }}"
-H "X-GitHub-Api-Version: 2022-11-28"
https://api.github.com/repos/nat-n/homebrew-poethepoet/actions/workflows/71211730/dispatches
-d '{"ref":"main", "inputs":{}}'
github-release:
name: >-
Sign the Python 🐍 distribution 📦 with Sigstore and upload them to GitHub Release
needs: [pypi-publish]
runs-on: ubuntu-latest

permissions:
contents: write
id-token: write

steps:
- name: Download all the dists
uses: actions/download-artifact@v3
with:
name: python-package-distributions
path: dist/
- name: Sign the dists with Sigstore
uses: sigstore/gh-action-sigstore-python@v1.2.3
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Upload artifact signatures to GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
# Upload to GitHub Release using the `gh` CLI.
# `dist/` contains the built packages, and the
# sigstore-produced signatures and certificates.
run: >-
gh release upload
'${{ github.ref_name }}' dist/**
--repo '${{ github.repository }}'
28 changes: 18 additions & 10 deletions poethepoet/executor/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,24 @@ def _execute_cmd(
process. Using exec supports fewer options, and doesn't work on windows.
"""

if use_exec:
if input:
raise ExecutionError("Cannot exec task that requires input!")
if shell:
raise ExecutionError("Cannot exec task that requires shell!")
if not self._is_windows:
# execvpe doesn't work properly on windows so we just don't go there
return self._exec(cmd, env=env)

return self._exec_via_subproc(cmd, input=input, env=env, shell=shell)
try:
if use_exec:
if input:
raise ExecutionError("Cannot exec task that requires input!")
if shell:
raise ExecutionError("Cannot exec task that requires shell!")
if not self._is_windows:
# execvpe doesn't work properly on windows so we just don't go there
return self._exec(cmd, env=env)

return self._exec_via_subproc(cmd, input=input, env=env, shell=shell)
except FileNotFoundError as error:
return self._handle_file_not_found(cmd, error)

def _handle_file_not_found(
self, cmd: Sequence[str], error: FileNotFoundError
) -> int:
raise PoeException(f"executable {cmd[0]!r} could not be found") from error

def _exec(
self,
Expand Down
10 changes: 10 additions & 0 deletions poethepoet/executor/poetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from pathlib import Path
from typing import Dict, Optional, Sequence, Type

from ..exceptions import PoeException
from .base import PoeExecutor


Expand Down Expand Up @@ -46,6 +47,15 @@ def execute(
use_exec=use_exec,
)

def _handle_file_not_found(
self, cmd: Sequence[str], error: FileNotFoundError
) -> int:
poetry_env = self._get_poetry_virtualenv()
error_context = f" using virtualenv {poetry_env!r}" if poetry_env else ""
raise PoeException(
f"executable {cmd[0]!r} could not be found{error_context}"
) from error

def _get_poetry_virtualenv(self, force: bool = True):
"""
Ask poetry where it put the virtualenv for this project.
Expand Down
9 changes: 9 additions & 0 deletions poethepoet/executor/virtualenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ def execute(
use_exec=use_exec,
)

def _handle_file_not_found(
self, cmd: Sequence[str], error: FileNotFoundError
) -> int:
venv = self._resolve_virtualenv()
error_context = f" using virtualenv {str(venv.path)!r}" if venv else ""
raise PoeException(
f"executable {cmd[0]!r} could not be found{error_context}"
) from error

def _resolve_virtualenv(self) -> "Virtualenv":
from ..virtualenv import Virtualenv

Expand Down

0 comments on commit dfb8cab

Please sign in to comment.