Comments 38
Ещё один швейцарский нож который зашёл одному разработчику и теперь он думает, что все хотят ещё одну зависимость вместо мейкфайла?
Ну, выбор не велик - либо "ещё одна зависимость" либо бардак. Makefile не поставит используемые утилиты нужных проекту версий, не задаст переменные окружения и секреты проекта. Задачи описать в Makefile можно, но, будем откровенны, это не особо удобно, и это не основная задача make, а скорее misuse. В результате плюс к Makefile появляются .env или env.sh и дополнительные инструкции в README описывающие какие утилиты нужно самостоятельно установить для работы с проектом. Дальше версии этих утилит у разных разработчиков и на CI разъезжаются, что периодически создаёт странные проблемы. Утилиты, которые призваны эти проблемы порешать (asdf, direnv, taskfile, …) решают только часть да ещё и сами новые проблемы привносят. На этом фоне mise приятно выделяется. Но если не вникать в детали - то да, будет ровно такое впечатление, как Вы сказали.
Вообще обычно для подобных случаев использутеся связка из:
require-dev блока в композере, npm и т.п., чтобы ставить зависимости нужные для разработки только если они нужны
.env все же более универсальный механизм и позволяет не хранить все секреты в одном месте
Что касается разъезжающихся версий у разрабов - если человек по каким-то причинам не обновляет инструментарий, ему утилиты не помогут.
Но может ваша утилита и взлетит, питоновский uv вон набирает популярность, хотя его смысл вообще мне не понятен.
В том-то и дело, что упомянутые в статье задачи нужно решать на всех проектах, и при этом полно решений, которые как-то эти задачи решают - но обычно они это делают не очень хорошо, ограничено или специфичным для конкретного языка способом. Например, для того же .env до сих пор нет единого стандарта, что в нём можно делать более сложного чем A=5. Ключевое отличие mise как раз в том, что она делает сразу всё и делает это правильно и очень гибко. Т.е. на сегодня это объективно лучшее решение, на которое действительно есть смысл перейти.
Что касается разъезжающихся версий у разрабов - если человек по каким-то причинам не обновляет инструментарий, ему утилиты не помогут.
Во-первых, утилиты помогут - об этом и речь в статье. А во-вторых тупым обновлением инструментария можно обойтись если работаешь над единственным проектом. А если проектов несколько, то у всех будут свои требования к инструментарию, и соблюдать их без помощи таких утилит будет крайне сложно.
питоновский uv вон набирает популярность, хотя его смысл вообще мне не понятен.
а смысл poetry, pipenv и т.п. понятен? тот же package manager, но с очень быстрым вычислением зависимостей + куча фич, которые нужны в управлении проектом.
uv это ещё и менеджер "всего остального что есть в огромном мире python" с uv run *.py и uv python install
It just works (c) (tm)
Причем без шуток. Сидишь на чистом pip - мучаешься с зависимостями, которые обновляются неизвестно когда, причем якобы минорный багфикс, но меняется поведение, пересаживаешься на conda - мучаешься с тем насколько долго это работает, все ещё требует активации, и dependency hell продолжается, потому что тут нужен conda forge, там какой то другой сборник пакетов. Перешёл на uv - just works. Хочешь поставить чисто torch из репы Nvidia - пожалуйста, хочешь поставить все "как нибудь" - окей, вот тебе через 0.1 секунду ошибка несовместимости, причем конкретная и иногда с путями решения.
Кажется что source .venv/bin/activate это всего несколько символов, но насколько же удобнее без этого, просто uv run из нужной директории и все работает. Причем это обратно совместимо, если нужен чистый venv - он доступен.
Я через uv иногда просто для старых проектов venv собираю потому что он и с requirements.txt работает и позволяет получить преимущество удобства/скорости в установке и потом все равно uv run работает. Даже залочить зависимости можно без pyproject.toml, если мне не изменяет память.
Это инструмент который помимо общего улучшения приносит кучу мелких удобств. Это как работа с проектом без git и с git. Абсолютно другой уровень, хотя идея простая. Просто "правильно" реализована.
Вообще обычно для подобных случаев использутеся связка из:
require-dev блока в композере, npm и т.п., чтобы ставить зависимости нужные для разработки только если они нужны
Речь о разных зависимостях - mise не заменяет условный composer.json или package.json и не управляет зависимостями библиотек в проекте. Но и composer при наличии в require "php": ">=7.4" нужную версию php не установит, в отличии от mise. Более того - имея несколько проектов с разными версиями того же php, mise автоматически подставляет в PATH нужную, снимая всю головную боль с update-alternatives и прочими приседаниями с тем "а какая версия php/node/python/ruby/etc. у меня сейчас". (Хотя в наше время и без контейнера это уже анахронизм)
.env все же более универсальный механизм и позволяет не хранить все секреты в одном месте
И он тоже поддерживается mise. Если пользовались direnv - это и его замена в том числе.
Что касается разъезжающихся версий у разрабов - если человек по каким-то причинам не обновляет инструментарий, ему утилиты не помогут.
Это +\- работает если разработчик один и проектов или немного или они все однотипные. В крупных проектах ситуация, когда версия языка отстала от актуальной, хорошо если не на мажорную (как часто с php), а хотя бы на 2-3 минорных, встречается в примерно 90% случаях, а сам процесс обновления - тот еще техдолг.
Но может ваша утилита и взлетит
Давненько уже взлетела, как и сама концепция - достаточно глянуть и что альтернативы появились - aqua, vfox, и что "родоначальник" asdf из набора bash-скриптов переписался полностью на go
питоновский uv вон набирает популярность, хотя его смысл вообще мне не понятен.
pyenv, pip, pipenv, virtualenv, poetry - ни о чем не говорят? Если да - вы скорее всего не работали над крупными проектами и/или в крупных компаниях
Ни разу в жизни не видел того, кого бы устраивал makefile, везде где его встречал это был write-once костыль, который и открывать то было стремно, не говоря уже о добавлении чего-то нового.
mise заменяет все остальные аналогичные утилиты т.к. содержит весь необходимый функционал
Какие утилиты, какой функционал? Введения о том какую проблему оно решает нет, зато дохрена рассказов как это настроить.
Честно говоря, я просто не хотел превращать статью в перечисление тучи заменяемых утилит с описанием проблем каждой. Но, если хотите, вот краткий список:
Установка/обновление инструментов: asdf, aqua, nvm, pyenv, rbenv, go get -tool, …
Настройка конфигурации: direnv, dotenv, env.sh, …
Выполнение задач проекта: make, taskfile, just, mage, ./scripts/test, …
И это только для основного функционала. А помимо этого есть ещё поддержка секретов, автозапуск задач при изменении файлов - и для этого тоже есть существующие утилиты, которые заменяет mise.
Так в этом то вся соль. Вы должны были мотивировать как-то отказ от простых утилит, большинство из которых успешно следуют unix way и де-факто являются стандартами в своей области. Но вы этого не сделали.. поэтому статья читается как "зачем.. зачем.. пролистать, минус"
Что касается концепции "швейцарского ножа", то имхо она в принципе своём ущербна. Утилита должна исполнять только свою маленькую роль в большом оркестре, а не пытаться быть этим самым оркестром. Это та атомарность, которая позволяет поддерживать их и в любой момент заменить каждый из компонентов на альтернативу.
Я сам люблю unix way, но иногда ради юзабилити приходится от него отходить, и это нормально - unix way это не абсолютный идеал для вообще всех приложений.
Впрочем, лично для меня не очевидно, что в случае mise действительно необходимо в одной утилите объединить весь этот функционал. И меня немного беспокоит дальнейшее расширение её функционала. Именно поэтому я в статье не писал, что mise идеальна, но я писал, что она задала минимальную планку для будущих утилит в этом классе - потому что mise первая, кто действительно хорошо решил все три задачи.
Вообще, часть функционала автор mise реализует в отдельных утилитах: usage, fnox, pitchfork; равно как и использует чужие утилиты: watchexec. Ну т.е. про unix way он в курсе, и для объединения трех разных функций в mise возможно есть веские причины.
Вы должны были мотивировать как-то отказ от простых утилит
Это не совсем так. Лично я до mise никакими из этих утилит не пользовался. Пытался, но довольно быстро обнаруживал серьёзные проблемы, из-за чего отказывался от них и возвращался к самопальным решениям (env.sh, скрипты, tools.go). mise - первая утилита без серьёзных проблем, из всех что я видел. Поэтому статья мотивирует не отказ от других утилит, а использование именно mise. Более того, по этой причине я ничего не написал про совместимость с другими утилитами (в основном asdf и direnv), которую старается поддерживать mise для упрощения миграции.
Для чего эта куча букывок?
Для тооо чтобы не читать Readme? )))
mise — утилита, необходимая каждому разработчику и в каждом проекте
Это Вы провели опрос каждого разработчика на планете? Или как?
Write programs that do one thing and do it well.
mise соответствует типовым ожиданиям от современной утилиты:
• Написана на Rust
У меня примерно миллион ожиданий от каждой современной утилиты, но уж язык, на котором она написана — меня точно не волнует.
Я пишу постоянно на трех языках, спорадически — еще на пяти, у каждого свои разной степени игривости танцы с бубном по настройке окружения, но asdf меня лично не подводил никогда; буквально, не было случая, чтобы я столкнулся с «чёрт, не получается».
Чем mise лучше? Столько букв, а ответа на этот очевидный вопрос нет.
Есть коротко: безопаснее, быстрее, удобнее, устанавливает больше инструментов, плюс поддержка переменных окружения и задач. Изначально mise разрабатывалась как drop-in replacement именно для asdf (в то время mise называлась rtx, если не путаю).
Вот детальное сравнение с asdf: https://mise.jdx.dev/dev-tools/comparison-to-asdf.html
Я читал этот текст, когда мне в прошлый раз повстречался миссионер дислектических мышей. Вот мои ¢2:
безопаснее — актуально для людей, которые устанавливают какую-то совсем экзотику, но ленятся пробежать глазами шеллскрипт;
быстрее — это смешно, пардон, когда речь идет про доли секунды и команду выполняемую раз в год;
удобнее — вкусовщина, я с
asdf15 лет живу (а кота этого впервые вижу);устанавливает больше инструментов — очевидный минус, я не хочу, чтобы мне кто-то зачем-то устанавливал больше каких-то там еще инструментов;
поддержка переменных окружения — три раза нет, ну может быть, иногда удобно, хотя для этого тоже есть миллион инструментов;
поддержка переменных задач — это я не понял, что такое.
В общем, неангажированный вывод для тех кто сюда забредет: если у вас уже asdf, вам вряд ли понравится, если нет — лучше, наверное, начинать прямо с mise.
Не совсем так. Учитывая, что в большинстве случаев asdf заменяется на mise как drop-in, т.е. просто вместо команды asdf выполняете mise с теми же аргументами, то все эти плюсы начинают выглядеть намного интереснее даже если пока нет понимания зачем они лично Вам - просто потому, что их можно получить практически бесплатно.
По скорости - команда выполняется не раз в год, а регулярно. В случае asdf - это запуск любого инструмента, т.к. они все запускаются через shims. В старом asdf на шелле это тормозило вообще неприлично, в новом asdf на go уже приемлемо, но mise всё-равно быстрее. Но да, есть люди которых такие задержки бесят, а есть те, кто их не замечает.
Безопасность экосистемы asdf - это реальная проблема, потому что авторы asdf-плагинов это не авторы самой asdf и не авторы нужной утилиты, а абсолютно случайные товарищи, которые получают возможность выполнить любой шелл-код на вашем компе. Эти товарищи - совершенно лишние в цепочке доверия поставкам.
Больше инструментов сами по себе не установятся, просто через mise есть возможность установить такие инструменты, которые asdf устанавливать не умеет.
Миллион инструментов для работы с переменными окружения страдают от кучи разных проблем, которых нет в mise.
устанавливает больше инструментов — очевидный минус, я не хочу, чтобы мне кто-то зачем-то устанавливал больше каких-то там еще инструментов
Максимально странный поинт, типа - что плохого, что в регистри mise больше тулинга, который можно установить?
поддержка переменных окружения — три раза нет, ну может быть, иногда удобно, хотя для этого тоже есть миллион инструментов;
Ну вот встречный вопрос - а зачем мне мучаться с "миллионом инструментов"?
неангажированный вывод для тех кто сюда забредет: если у вас уже
asdf, вам вряд ли понравится, если нет — лучше, наверное, начинать прямо сmise
Пересел с asdf спустя год использования на mise еще во времена, когда mise был rtx - вообще ни о чем не жалею: была постоянная боль с asdf+make+direnv+доморощенные shell-хуки - все заменилось одним, которые сразу работает нормально.
Прочитал статью, прочитал комменты, ладно, продано)
Пока не смотрел репо, но как понял штука классная когда у тебя несколько стеков и несколько рабочих девайсов.
Так же онбординг упростить очень сильно с виду.
Очередную тулзу учить конечно в падлу, но с виду оно того стоит.
Вопрос к автору, насколько убервафля применима для раскати ci/cd ? Есть примеры ?
Интеграция с CI обычно в одну-две строки в конфиге CI: https://mise.jdx.dev/continuous-integration.html
Что до CD - если напишете логику деплоя в задаче "deploy", то на CI деплой запустится командой mise run deploy. В смысле, ничего именно mise-специфичного в CD нет.
По поводу написания, воды ОЧЕНЬ много, в моменте появляется вайб tldr. На хабре вообще хочется видеть перед статьей сноску небольшую сверхсжатую с основной информацией.
Есть nix-shell, который даёт гарантированную воспроизводимость, но имеется более крутая кривая обучения:
https://www.cecg.io/blog/nix-shell-vs-mise
Стоит посмотреть в сторону nix/NixOS, если занимаетесь проектами со сложными зависимостями, есть необходимость в гарантированной воспроизводимости и не пугает кривая обучения языка nix.
Nix реально нужен в проектах со сложными зависимостями от уровня C (системные библиотеки, компилятор C, etc.) - и через mise это контролировать невозможно. Но и там в плане юзабилити есть смысл использовать mise (в т.ч. и потому, что nix не особо позволяет управлять переменными окружения/секретами и задачами проекта). Просто запускать mise в этом случае нужно будет внутри nix-shell, ну и плюс можно будет упростить конфиг nix, ограничив его исключительно тем, что нельзя устанавливать/контролировать через mise.
в т.ч. и потому, что nix не особо позволяет управлять переменными окружения/секретами и задачами проекта
Можешь по подробнее расписать?
Вроде для секретов в nix есть Agenix, Sops-nix, Git-crypt.
Возьмём типовой пример: разработчику локально нужно иметь возможность переопределить номер порта, который используется в url нужной проекту.
Вот как ИИ предлагает решать эту задачу на nix:
shell.nix{ pkgs ? import <nixpkgs> {} , port ? 8080 }: let url = "http://localhost:${toString port}"; in pkgs.mkShell { shellHook = '' export PORT=${toString port} export URL=${url} ''; }shell.local.nixlet base = import ./shell.nix; in base { port = 9090; }
А вот как это делается на mise:
mise.toml[env] PORT = '8080' URL = { value = 'http://localhost:$PORT', tools = true }mise.local.toml[env] PORT = '9090'
Поддержки работы с секретам в nix вообще нет, предлагается запускать утилиту для расшировки (age/sops/gpg/etc.) и как-то подставлять её вывод в значение переменной окружения.
Те простыни, которые ИИ показывает в формате nix для того, чтобы реализовать запуск задачи "test" при которой выполнится команда go test -race ./... мне сюда даже копипастить страшно. Ну т.е. nix формально это может, но это настолько больно и длинно, что проще (и рекомендуется) вызывать стороннюю запускалку задач вроде make/taskfile/just/свой скрипт или собственно mise.
Т.е. работа с переменными окружения в nix сложнее чем в mise из-за функционального языка nix, а работа с секретами упирается в лишние телодвижения с Agenix/Sops-nix/Git-crypt?
Т.е. nix просто не предназначен для этого, он решает другие проблемы, которые mise решить не в состоянии. Да, в nix ногами можно запихать и такое тоже, но это будет больно и неудобно. Те проблемы, которые решает mise, намного удобнее решать именно через mise, в т.ч. используя его совместно с nix-shell если нужен контроль окружения уровня C, который mise реализовать не в состоянии.
То, что в других утилитах работало странно или не поддерживалось - в mise сделано правильно!
У нас в клубе принято джентльменам верить на слово!
Переменные окружения для всех шеллов и GUIшных программ настраиваются в ~/.config/environment.d/
Сам люблю mise всей душой, еще со времени когда он назывался rtx, и делал пару контрибьютов в его регистри, но статья слабо продающая, что видно в комментах. Не хватает прям практического примера, что мол "вот у нас проект на такой-то python, в нем и makefile, и .python-version, и .env, и requirements.txt, а вот так mise во все это интегрируется практически нативно, но еще больше фичей можно получить если взять mise.toml".
Ну, мне казалось, что основным show stopper для внедрения "ещё одной утилиты" будет как раз сложность внедрения, поэтому сделал упор на том, что показал насколько просто и неинвазивно можно внедрять mise в проект, с минимальными требованиями к остальным разработчикам.
А чтобы полноценно "продать" нужно было бы перечислить кучу проблем в других утилитах, всё то, что там криво а в mise работает правильно. Но тогда до mise в статье бы вообще не добрались, потому что утонули бы в чужих проблемах.
В общем, присоединяйтесь - напишите свою статью про mise. Чем больше народу про неё узнает, тем проще нам всем будет работать.

mise — утилита, необходимая каждому разработчику и в каждом проекте