EDIT: This appears to be a shebang character limit issue. The workaround appears to be to create a wrapper script. If anyone has a better solution I'm all ears!
I'm building a CLI tool, i'm using virtualenvironment to build my package and create a command I can execute from the command line. I followed the guides from click here: https://click.palletsprojects.com/en/8.1.x/setuptools/
I'm using pip install -e . to install the package.
- I can see the
./venv/bindirectory in my $PATH - I can see the shim for the cli in the ./venv/bin directory (see tree below)
- running
where cligives me:<full path to venv>/venv/bin/cliso its on my path
If I try to run cli then i get cli: Command not found.
If I replace the shebang in the generated cli shim with #!/usr/bin/env python then it works!
I have tried setting the permissions to 777, this doesn't resolve the issue.
First question is why doesn't the default shebang work, second question is either how to resolve that issue or default to using #!/usr/bin/env python as the shebang?
I've put some more info about my environment etc below:
My environment:
- shell is tcsh (cant switch)
- Python 3.8.2
- rhel 7
simple test dir structure is as follows:
.
├── cli_test
│ ├── __init__.py
│ └── cli.py
├── cli_test.egg-info
│ ├── dependency_links.txt
│ ├── entry_points.txt
│ ├── PKG-INFO
│ ├── requires.txt
│ ├── SOURCES.txt
│ └── top_level.txt
├── venv
│ ├── bin
│ │ ├── activate
│ │ ├── activate.csh
│ │ ├── activate.fish
│ │ ├── Activate.ps1
│ │ ├── cli
│ │ ├── easy_install
│ │ ├── easy_install-3.8
│ │ ├── pip
│ │ ├── pip3
│ │ ├── pip3.8
│ │ ├── python
│ │ └── python3
│ └── pyvenv.cfg
└── setup.py
cli.py:
def cli():
print("Hello world")
setup.py:
#!/usr/bin/env python
from setuptools import setup, find_packages
setup(
name="cli_test",
version=0.1,
packages=find_packages(),
python_requires='>=3.8',
install_requires = [
"Click"
],
entry_points = {
'console_scripts': [
'cli=cli_test.cli:cli'
],
},
)
The generated cli shim:
#!<full path to my venv>/venv/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'cli-test','console_scripts','cli'
__requires__ = 'cli-test'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('cli-test', 'console_scripts', 'cli')()
)