Люди,
Я разбил сложный скрипт на Python на пакет для облегчения обслуживания и распространения. Я создал новый setup.py
(используя setupmeta
) с точкой входа console_scripts
и структурой пакета. Пока все хорошо.
У меня были некоторые необычные требования:
- пакет всегда должен быть установлен в
virtualenvwrapper
проекте,
- поэтому скрипт установлен в каталоге
${VIRTUAL_ENV}/bin
...
- ... и я должен создать символическую ссылку для сценария в каталоге
${VIRTUALENVWRAPPER_PROJECT_PATH}/bin
. (не спрашивай ...: -)
Для этой цели:
- Я добавил
locate_project_path()
функцию в сценарий setup.py
,
добавил следующий install_and_symlink_script
подкласс к setuptools.command.install.install
:
class install_and_symlink_script(install):
"""Do normal install, but symlink script to project directory"""
def run(self):
install.run(self)
script_path = os.path.join(self.install_scripts, SCRIPT_NAME)
project_path = locate_project_path()
symlink_path = os.path.join(project_path, "bin", SCRIPT_NAME)
print("creating %s script symlink" % SCRIPT_NAME)
if os.path.exists(symlink_path):
print("removing existing symlink %s" % symlink_path)
os.unlink(symlink_path)
print("creating symlink from %s to %s" % (
symlink_path, script_path))
os.symlink(script_path, symlink_path)
и настроен setup()
таким образом:
setup(
...
entry_points={
"console_scripts": ["%s=myscriptpackage.cli:main" % SCRIPT_NAME],
},
cmdclass={
"install": install_and_symlink_script,
},
...
)
При выполнении локального python ./setup.py install
установка пакета и создание символической ссылки работают отлично.
Но при выполнении pip install git+ssh://.../myscriptpackage.git
происходит сбой:
...
running install_egg_info
Copying src/myscriptpackage.egg-info to build/bdist.linux-x86_64/wheel/myscriptpackage-0.4.0-py2.7.egg-info
running install_scripts
creating my-script script symlink
creating symlink from /path/to/virtualenvwrapper/project/bin/my-script to build/bdist.linux-x86_64/wheel/myscriptpackage-0.4.0.data/scripts/my-script
error: [Errno 17] File exists
error
Failed building wheel for myscriptpackage
...
Значение при установке через pip
вместо python ./setup.py install
:
- он не может обнаружить существующую символическую ссылку и удалить ее.
- переменная
install_and_symlink_script.install_scripts
указывает на скрипт внутри каталога сборки вместо каталога окончательной установки скриптов ...: - |
Итак ... знаете ли вы способ получить правильный каталог установки скриптов, совместимый как с pip install
, так и с python ./setup.py install
?
(Кстати, я использую python 2.7.13, setuptools 39.1.0, virtualenvwrapper 4.8.2 под Debian 9)
ОБНОВЛЕНИЕ 1
Я знал, что проблема error: [Errno 17] File exists
исходила от os.path.exists(symlink_path)
звонка.
Я просто понял, почему: если символическая ссылка была создана из предыдущей установки, эта символическая ссылка не работает во время новой установки. os.path.exists
возвращает False для прерванной символической ссылки. OTOH, os.path.lexists
возвращает True, если символическая ссылка существует, повреждена или нет ...