Skip to content

Commit dfb8cab

Browse files
committed
Show helpful error message when task executable is not on the path
1 parent f500668 commit dfb8cab

4 files changed

Lines changed: 103 additions & 18 deletions

File tree

.github/workflows/ci.yml

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ jobs:
6161
- name: Run tests
6262
run: poetry run pytest -v
6363

64-
build-release:
65-
name: Build and release
64+
build:
65+
name: Build distribution
6666
runs-on: ubuntu-latest
6767
needs: [code-quality, run-tests]
6868
steps:
@@ -78,18 +78,76 @@ jobs:
7878
- name: Build package
7979
run: poetry build
8080

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

87-
- name: Update homebrew formula
88-
# if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
88+
pypi-publish:
89+
name: Upload release to PyPI
90+
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
91+
needs: [build]
92+
runs-on: ubuntu-latest
93+
environment:
94+
name: pypi
95+
url: https://pypi.org/p/poethepoet
96+
permissions:
97+
id-token: write
98+
steps:
99+
- name: Download all the dists
100+
uses: actions/download-artifact@v3
101+
with:
102+
name: python-package-distributions
103+
path: dist/
104+
105+
- name: Publish distribution 📦 to PyPI
106+
uses: pypa/gh-action-pypi-publish@release/v1
107+
108+
homebrew-publish:
109+
name: Upload homebrew formula
110+
needs: [pypi-publish]
111+
runs-on: ubuntu-latest
112+
steps:
113+
- name: Trigger update of homebrew formula
89114
run: >
90115
curl -L -X POST
91116
-H "Accept: application/vnd.github+json"
92117
-H "Authorization: Bearer ${{ secrets.homebrew_pat }}"
93118
-H "X-GitHub-Api-Version: 2022-11-28"
94119
https://api.github.com/repos/nat-n/homebrew-poethepoet/actions/workflows/71211730/dispatches
95120
-d '{"ref":"main", "inputs":{}}'
121+
122+
github-release:
123+
name: >-
124+
Sign the Python 🐍 distribution 📦 with Sigstore and upload them to GitHub Release
125+
needs: [pypi-publish]
126+
runs-on: ubuntu-latest
127+
128+
permissions:
129+
contents: write
130+
id-token: write
131+
132+
steps:
133+
- name: Download all the dists
134+
uses: actions/download-artifact@v3
135+
with:
136+
name: python-package-distributions
137+
path: dist/
138+
- name: Sign the dists with Sigstore
139+
uses: sigstore/gh-action-sigstore-python@v1.2.3
140+
with:
141+
inputs: >-
142+
./dist/*.tar.gz
143+
./dist/*.whl
144+
- name: Upload artifact signatures to GitHub Release
145+
env:
146+
GITHUB_TOKEN: ${{ github.token }}
147+
# Upload to GitHub Release using the `gh` CLI.
148+
# `dist/` contains the built packages, and the
149+
# sigstore-produced signatures and certificates.
150+
run: >-
151+
gh release upload
152+
'${{ github.ref_name }}' dist/**
153+
--repo '${{ github.repository }}'

poethepoet/executor/base.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,24 @@ def _execute_cmd(
151151
process. Using exec supports fewer options, and doesn't work on windows.
152152
"""
153153

154-
if use_exec:
155-
if input:
156-
raise ExecutionError("Cannot exec task that requires input!")
157-
if shell:
158-
raise ExecutionError("Cannot exec task that requires shell!")
159-
if not self._is_windows:
160-
# execvpe doesn't work properly on windows so we just don't go there
161-
return self._exec(cmd, env=env)
162-
163-
return self._exec_via_subproc(cmd, input=input, env=env, shell=shell)
154+
try:
155+
if use_exec:
156+
if input:
157+
raise ExecutionError("Cannot exec task that requires input!")
158+
if shell:
159+
raise ExecutionError("Cannot exec task that requires shell!")
160+
if not self._is_windows:
161+
# execvpe doesn't work properly on windows so we just don't go there
162+
return self._exec(cmd, env=env)
163+
164+
return self._exec_via_subproc(cmd, input=input, env=env, shell=shell)
165+
except FileNotFoundError as error:
166+
return self._handle_file_not_found(cmd, error)
167+
168+
def _handle_file_not_found(
169+
self, cmd: Sequence[str], error: FileNotFoundError
170+
) -> int:
171+
raise PoeException(f"executable {cmd[0]!r} could not be found") from error
164172

165173
def _exec(
166174
self,

poethepoet/executor/poetry.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from pathlib import Path
33
from typing import Dict, Optional, Sequence, Type
44

5+
from ..exceptions import PoeException
56
from .base import PoeExecutor
67

78

@@ -46,6 +47,15 @@ def execute(
4647
use_exec=use_exec,
4748
)
4849

50+
def _handle_file_not_found(
51+
self, cmd: Sequence[str], error: FileNotFoundError
52+
) -> int:
53+
poetry_env = self._get_poetry_virtualenv()
54+
error_context = f" using virtualenv {poetry_env!r}" if poetry_env else ""
55+
raise PoeException(
56+
f"executable {cmd[0]!r} could not be found{error_context}"
57+
) from error
58+
4959
def _get_poetry_virtualenv(self, force: bool = True):
5060
"""
5161
Ask poetry where it put the virtualenv for this project.

poethepoet/executor/virtualenv.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ def execute(
3030
use_exec=use_exec,
3131
)
3232

33+
def _handle_file_not_found(
34+
self, cmd: Sequence[str], error: FileNotFoundError
35+
) -> int:
36+
venv = self._resolve_virtualenv()
37+
error_context = f" using virtualenv {str(venv.path)!r}" if venv else ""
38+
raise PoeException(
39+
f"executable {cmd[0]!r} could not be found{error_context}"
40+
) from error
41+
3342
def _resolve_virtualenv(self) -> "Virtualenv":
3443
from ..virtualenv import Virtualenv
3544

0 commit comments

Comments
 (0)