Python + bash
Если вам часто требуется запускать shell команды из Python-кода, какой способ вы используете?
Самый низкоуровневый это функция os.system(), либо os.popen(). Рекомендованный способ это subprocess.call(). Но это всё еще достаточно неудобно.
Советую обратить своё внимание на очень крутую библиотеку sh.
Что она умеет?
🔸 удобный синтаксис вызова команд как функций
# os
import os
os.system("tar cvf demo.tar ~/")
# subprocess
import subprocess
subprocess.call(['tar', 'cvf', 'demo.tar', '~/'])
# sh
import sh
sh.tar('cvf', 'demo.tar', "~/")
🔸 простое создание функции-алиаса для длинной команды
fn = sh.lsof.bake('-i', '-P', '-n')
output = sh.grep(fn(), 'LISTEN')
в этом примере также задействован пайпинг
🔸 удобный вызов команд от sudo
with sh.contrib.sudo:
print(ls("/root"))
Такой запрос спросит пароль. Чтобы это работало нужно соответствующим способом настроить юзера.
А вот вариант с вводом пароля через код.
password = "secret"
sudo = sh.sudo.bake("-S", _in=password+"\n")
print(sudo.ls("/root"))
Это не все фишки. Больше интересных примеров смотрите в документации.
Специально для Windows💀 юзеров
#libs#linux
🐘 В мире Android и тем более KMP проектов огромное количество зависимостей. Та самая ситуация, когда build зеленый, sync прошел, но приложение падает в рантайме из-за NoSuchMethodError или ClassNotFoundException, знакома многим. Причина — тихий конфликт версий. Gradle по умолчанию старается брать самую новую версию из всех найденных, но срабатывает не всегда. В разных модулях одного проекта могут спокойно жить разные версии одной библиотеки (например, okhttp 4.9.0 в модуле А и 4.11.0 в модуле Б). Gradle не считает это конфликтом, потому что модули изолированы. В рантайме при передаче объекта между модулями — ClassCastException. Особенно больно это бьет в KMP, где общая бизнес-логика связывает всё в единую цепочку.
Плагин 🐱Dependency Conflict Analyzer переворачивает подход. Он встраивается в Gradle и каждый раз при синхронизации автоматически анализирует весь граф зависимостей по всем модулям. Не нужно ничего запускать вручную или гадать, кто что подтянул. Если есть расхождение в major-версиях — плагин сразу покажет конфликт в консоли. Причём он найдет даже скрытые расхождения между разными модулями, которые Gradle игнорирует.
# Пример работы плагина
Version conflict detected: org.slf4j:slf4j-api
- version 2.0.17 via:
- project :app -> ch.qos.logback:logback-classic:1.4.11 -> org.slf4j:slf4j-api:2.0.17
...
- version 1.7.25 via:
- project :app -> org.apache.logging.log4j:log4j-slf4j-impl:2.17.1 -> org.slf4j:slf4j-api:1.7.25
Такая проактивная проверка помогает фиксить конфликты еще на этапе разработки и писать более стабильный код. Попробуйте.
#Gradle
🐘Вышел Gradle 9.1.0 с поддержкой Java 25 и новыми фичами. Из интересно - "Визуалиация таска графов", но сразу грусть - не ждите картинки 😡 Насыпали везде по немного улучшений, запромоутили фичи в стабильные, поправили баги и на этом всё.
#gradle
📹Обзор что нового в Gradle 9.0 (EN, 25м)
00:00 – Что нового в Gradle 9 и как обновиться
03:08 – Configuration Cache
08:59 – Поддержка Kotlin 2.2
10:10 – Kotlin build script compilation avoidance
10:46 – Улучшения nullability в Gradle API
14:05 – Gradle теперь требует Java 17 или выше
15:39 – Обновление до Groovy 4
16:43 – Reproducible архивы включены по умолчанию
19:00 – JAVA_HOME теперь может использоваться как источник toolchain в Daemon JVM
21:39 – Gradle Wrapper теперь поддерживает символьные версии и SemVer (например, latest.release)
23:32 – Какие фичи стали стабильными, что устарело и что удалено
25:05 – Полезные ссылки на документацию и ресурсы
26:06 – Рекомендованные best practices для работы с Gradle 9
26:53 – Заключение
#gradle
🐘Вышел Gradle 9.0
Самое важное в Gradle 9 - ❗️пришло время адаптировать Configuration Cache❗️. Пока его не включили по умолчанию и отложили до 10 версии, но включение режима - рекомендованный подход для всех! Кэш конфигурации очень сильно прокачали и улучшили, он уже готов к использованию!
Что еще:
👉 Обновили используемый Kotlin до версии 2.2, а Groovy до версии 4.0
👉 Kotlin build script теперь поддерживают compilation avoidance - будет пропускаться их повторная компиляции, если не найдется значимых изменений. Это положительно скажется на время сборке, если вы используете Kotlin в buildSrc
👉 Перешли на использование JSpecify Nullability аннотаций
👉Минимальная версия Java - 17
👉Улучшения для авторов плагинов
Как и с любым мажорным релизом Gradle часть фичей стала стабильной, а deprecated API удалили, так что после миграции ваш проект может потребовать доработки или обновления подключенных Gradle плагинов.
#gradle
🐘Gradle начиная с версии 8.0. обязательно требует зависимостей между task, если один использует результаты другого
Явное объявление зависимостей требуется чтобы корректно выстроить порядок выполнения task-ок, гарантировать воспроизводимость сборки.
#gradle
🐘Состояние Gradle Configuration Cache и будущее фичи
В больших проектах на Gradle одной из самых долгих является фаза конфигурации проекта, во время которой создаются все задачи и устанавливаются связи между ними.
Команда Gradle уже давно работает над решением этой проблемы с помощью Gradle Configuration Cache — возможности сохранять результаты фазы конфигурации и повторно использовать их в последующих запусках.
В блоге Gradle вышла подробная статья о текущем состоянии этой функции: State of the Configuration Cache. Согласно статье, начиная с Gradle 9 Configuration Cache будет включён по умолчанию система станет деликатно напоминать о необходимости включения Configuration Cache.
В одном из будущих мажорных релизов после Gradle 9, Configuration Cache станет единственным доступным режимом работы — но только после того, как к этому будет готово всё сообщество.
До этого момента Gradle будет активно улучшать технологию и сотрудничать с партнёрами для расширения совместимости и интеграций.
#gradle
🐘ВышелGradle 8.13
🔥Автоматическая загрузка JVM для Gradle Daemon: теперь Gradle может автоматически загружать необходимую версию JVM для работы Daemon, если подходящая версия не найдена локально.
👉 В Scala-плагине появилась возможность явно задавать версию Scala через расширение scala.
👉Точные временные метки в JUnit XML: временные метки в отчетах JUnit XML теперь имеют миллисекундную точность, что улучшает детализацию отчетов.
🛠 Более 700 мелких исправлений и улучшений
Кроме того, добавлены улучшения для авторов сборок и разработчиков плагинов, включая улучшенный доступ к директории настроек в скриптах сборки, новый отчет о преобразовании артефактов, возможность создания пользовательских отчетов о тестировании и новый плагин distribution-base - сборка ZIP или TAR с необходимыми артефактами из проекта
#gradle
🤖androidx.lint — это Jetpack-библиотека с набором lint-проверок специально для авторов Gradle-плагинов.
Если ты пишешь Gradle plugin для Android — она ловит ошибки, которые сложно заметить вручную:
👉 использование внутренних API Gradle и AGP (которые могут сломаться в любой момент)
👉 eager task configuration вместо lazy (withType без configureEach)
👉 вызовы, несовместимые с Gradle Project Isolation (getRootProject, findProject, getParent)
👉Provider<String>.toString() — почти всегда баг
👉configurations.create вместо configurations.register (проблема с Gradle 8.14+)
👉System.getenv() напрямую вместо Provider API
👉mustRunAfter / shouldRunAfter — дорогие операции из-за перестройки task graph
Сейчас в alpha06 (апрель 2026), стабильного релиза ещё нет, но и в прод этот код не пойдет.
#Gradle#Android