В проектах JavaScript, я могу указать следующее в моих package.json
:Как я могу легко создать свои собственные команды setup.py?
{
"name": "dredd",
"version": "1.0.4",
"description": "API Blueprint testing tool",
"main": "lib/dredd.js",
"bin": {
"dredd": "bin/dredd"
},
"scripts": {
"lint": "coffeelint ./src",
"pretest": "npm run lint",
"test": "find ./test/ -name '*-test.coffee' | xargs mocha --compilers 'coffee:coffee-script/register' --reporter spec --timeout 120000 --recursive",
...
"coveralls": "./scripts/coveralls.sh",
...
},
"dependencies": {
...
Смотрите раздел scripts
. Я могу определить любой «скрипт» любого имени и любой реализации. Тогда я могу запустить его как npm run <name>
(и некоторые специальные, я могу даже запустить непосредственно как npm <name>
, например npm test
). Реализация «скрипта» может быть только одной командой или строкой, которая работает так же, как и в моей оболочке (в то время как переносимость - это то, что мне нужно для достижения самостоятельно, npm
не помогает мне в этом, но это ОК). npm правильно передает любые заданные аргументы, а также коды выхода. Таким образом, чтобы подвести итог, я могу:
- определить пользовательские команды
- определяют
pre<name>
команды, которые будут выполняться всегда перед<name>
команда получает вызывается - эти команды могут быть в основном все, что иначе работать в моем терминале
- они правильно размножать аргументы и коды выхода, из коробки
- в идеале, родительская команда может список доступных сценариев
Так что это что-то вроде rake
, , grunt
, gulp
и т. Д., Но встроенный и очень простой, очень простой в управлении. Я пропущу что-то подобное в проектах Python. Я чувствую, что setup.py
- это файл, который изначально имел в виду единственная точка входа в проекты Python, и мне нравится идея, и я хотел бы ее охватить. В идеале я хотел бы иметь что-то вроде:
python setup.py test
python setup.py lint
python setup.py <my command>
Я хочу одну точку входа, потому что я хочу, чтобы мой проект был интуитивным. Люди не должны быть вынуждены читать документацию или .travis.yml
для запуска linter, тестов и т. Д. Для моего проекта. Им не нужно заботиться о том, использую ли я nosetests
или py.test
для тестирования или flake8
для литья. Это детализация реализации.
Однако этого, по-видимому, нелегко достичь. Например. Я бы хотел, чтобы моя команда lint
содержала flake8
и, возможно, другие материалы. Затем я хочу, чтобы моя команда test
также всегда запускала lint
, прежде чем она запустится сама.
Я видел некоторые способы реализации пользовательских команд путем подкласса Command
и имеющий объявление такой команды в setup(...)
в setup.py
, но я не нашел красивой официальной документации. Кроме того, многие статьи старые, и очень сложно понять текущее состояние дел и современную передовую практику в 2016 году, поскольку существует исторически множество проектов, связанных с упаковкой (distutils
, setuptools
, pip
, easy_install
, ...). Даже если я смогу реализовать класс и вызвать его, и у вас есть команда, указанная в python setup.py --help
, мне все равно придется реализовать себе часть подпроцесса, код выхода, stdin, stderr и перенаправление аргументов. Это слишком сложно для моего сценария, я хочу, чтобы мой проект был прост и сосредоточен на его собственной цели.
Тестовые фреймворки обычно идут путем реализации некоторых специальных команд тяжелого веса, которые могут быть установлены как замена для python setup.py test
.Реализация выполняется на сотнях строк, и если я хочу добавить что-то к команде (например, если я хочу, чтобы flake8 && pytest tests
каждый раз, когда я вызываю python setup.py test
), это кажется едва достижимым.
Я видел много людей, чтобы уйти от правильного проектирования команд, как они слишком трудно писать, и они just do following:
# setup.py
if sys.argv[0] == 'test':
# do something
if sys.argv[0] == 'publish':
# do something
setup(...
Это просто, но это не интегрирована в существующую setup.py
инфраструктуру и I все равно нужно выполнить всю работу подпроцесса, если я хочу просто вызвать команду оболочки. Кроме того, я не уверен, что можно легко вызвать исходную команду (например, я хочу обернуть python setup.py test
чем-то, поэтому я напишу блок if sys.argv[0] == 'test':
и сделаю что-то обычай, но как я могу продолжить тестирование после этого? docs для этого ...).
Ни один из вышеперечисленных вариантов не прост в написании или обслуживании. Тем не менее, я не верю, что нет ничего похожего на то, что я ищу в экосистеме Python. Я думаю, что я должен что-то упустить. Может ли кто-нибудь указать мне хотя бы на правильное направление? По крайней мере, объясните мне ситуацию с setuptools
и distutils
и где я могу найти всю соответствующую документацию?