Что: fbfbf62ce9cb0a3fcb97e02d6fc05c249bb4e162 Когда: 2020-11-20 19:40:50+03:00 ------------------------------------------------------------------------ Темы: go redo ------------------------------------------------------------------------ I redo redo http://git.cypherpunks.ru/cgit.cgi/goredo.git/tree/README Психанул и написал свою redo реализацию на Go! Python apenwarr/redo всем хорош, но Python зависимость не очень приятна. Плюс при большом уровне параллелизма у него иногда что-то сбоит и он падает. Не критично, ибо всё равно потом всё недособранное можно пересобрать (это ж не Make, где с чистого листа только безопасно будет), но не приятно. redo-c не имеет redo-stamp команды. С ней просто приятнее и удобнее жить. Плюс он не уважает umask, ибо просто используется mkstemp(). И мозолят глаза его .dep. файлы в каждой директории. Решил было просто переписать его на Go. И в основу он полностью и лёг. Но на Go так приятно и легко пишется, что я по сути почти все фичи apenwarr/redo реализации засунул. Ровно один день чтобы написать рабочую (текущие проекты полностью мочь без проблем *пере*собирать) redo реализацию. Тестами ничего не покрыто, но у себя всё что в голову приходило и на нетривиальном проекте с default/redo-stamp разнообразием оно отрабатывает идеально. Сейчас я даже Python реализацию удалил из путей. Что добавил, чего не было в redo-c: * всегда захватывать stdout. Как и в apenwarr/redo, явно проверяется не записал ли пользователь И в stdout И в $3. Я не раз по неосторожности так делал и это сильно помогало * явно проверять что собранный файл не изменился пользователем, вне контекста сборки redo, опять же, как это делает apenwarr/redo -- это очень удобно, ибо позволяет временно вносить правки и смотреть что получится, но файлы не будут перезатёрты * исполняемые файлы запускаются как есть, содержащие shebang -- запускаются с ним. Ну а оставшиеся с /bin/sh -e (или -x в дополнении) * redo -x покажет trace (sh -x) только для текущих указанных целей, а не всех -- оказалось это очень удобно (но можно через env выставить и показ вообще всего для всех) * уважение umask * redo-stamp, redo-whichdo (мне не надо, но сделать легко) * в .dep файле сохраняется и UUID сборки, по которому можно понять а была ли цель уже собрана, ведь от неё могут зависеть многие, а на ней стоит redo-always или redo-stamp какой-нибудь. Позволяет избежать возможных повторных ненужных сборок. В apenwarr/redo тоже хранится информация о конкретной сборки, поэтому в нём тоже избежали эту проблему * lock-и и зависимости для каждой цели у меня аналогично в отдельных файлах, но все они собраны в .redo поддиректории (каждой директории проекта), что просто разгружает глаз. Там же хранятся и .log файлы А теперь отличия от навороченного apenwarr/redo: * apenwarr/redo проверяет размеры, mtime и ещё несколько параметров файла для определения его свежести. Насколько понимаю, ctime он не использует потому что он меняется с изменением link count-а. Я использовал подход redo-c: проверка ctime, если не совпал, то проверка хэша файла. Проверка хэша убирает false positive срабатывание. Если хочется иметь "вечную" цель, то, как и redo-c, как и apenwarr/redo, отсутствие файла воспринимают как тухлость. Последние правки в redo-c не удаляют файл, если stdout был пуст -- это ломает подобный подход. Я поэтому делал revert коммита. Ибо это добавляет гибкости и отсутствие проблем из-за хэширования пустоты. В итоге имеем и гибкость и false positive защиту хэшом. Если покажется кому-то медленным, то добавил возможность отключения хэширования (как apenwarr/redo будет). Для хэша использую BLAKE2b * я явно делаю sync для созданных целей и файлов зависимостей, а также директорий после переименования файлов. Можно отключить. apenwarr/redo не делает sync ни для целей, ни для SQLite3 БД, явно отключая синхронность * распараллеливание работы делается через jobserver-like протокол, но с возможностью infinite работ. У меня на C проекте это позволяет сверх быстро собрать его * у меня разукрашенный вывод, с удобными indent-ами, возможностью показа когда цель завершена и сколько это заняло времени, возможностью показа PID-ов. stderr задач можно тоже показывать с PID-ом самого shell-скрипта выполняющегося. У меня сверх verbose debug вывод, весь из себя разукрашенный, показывающий все принимаемые решения и шаги * stderr каждой цели можно сохранить на диск автоматом, но в нём каждая строка будет ещё и с TAI64N timestamp-ом, совместимым с tai64nlocal утилитой. redo-log команда позволит просмотреть его * состояние хранится в .dep файлах которые являются recfile-ами (8249370437018ad186c7946f22242731fba52035, d47bdefa40f41b81435565029c035f62614fe0da) Особо надобности в этом нет, oneline формат redo-c не проблематичен, но так красивее, мне кажется * в процессе работы создаются временные файлы, которые при убийстве процесса не подчищаются. Сделал отдельную redo-cleanup команду для их подчистки и возможности вообще удаления .redo отовсюду, для начала с чистого листа * apenwarr/redo даже в FAQ говорит что скорее всего начнёт создавать .redo поддиректории в каждой директории, ибо не понятно как выяснять что является верхним уровнем проекта. Я сделал подход redo-c: вплоть до корня ФС он будет искать .do файлы. Но, с возможностью ограничения "сверху" через REDO_TOP_DIR переменную или наличию .redo/top файла. И оптимизация и безопасность если проект и подпроект используют redo, но должны быть независимы друг от друга. Насколько понимаю, apenwarr/redo тут будет иметь проблемы Наконец, goredo имеет "gore" корень, что не может меня, любителя goregrind, не радовать. Это один исполняемый файл, на который нужно создать символические ссылки. Точнее запустить с -symlinks опцией, чтобы он это сделал сам. goredo в итоге работает и собирает проект даже на глаз ОЩУТИМО быстрее. Всё же, как ни крути, но Python это Python и быстро запуститься программа на нём не может. Чтобы просто перезапустить rebuild, который пройдёт по целям делающим redo-stamp, apenwarr/redo нужно время заметное на глаз, тогда как goredo отрабатывает вмиг. В общем, пока для меня это идеальная redo реализация! Смотрел ли я ещё на какие-нибудь? * Haskell реализация поддерживает только redo-ifchange. Да, это основное и главное, но нет, хочется большего * Есть 2-3 реализации на shell (не считая работающего apenwarr/do, но не делающего rebuild), но либо они требуют либо GNU утилит, либо вообще bash (идёт сразу в жопу) * redux на Go я даже пробовал запускать. Он создавал какое-то дичайшее количество (многие мегабайты) JSON файлов, но .do вроде запускал. Только с безумно низкой скоростью это всё работало и я даже через десятки секунд (минуты?) не дождался конца и нажал Ctrl-C. Просто неюзабельно * C++ не смотрел, ибо нафиг этот язык, тем более для выполнения redo задачи * Отпадают не совместимые с redo(-ifchange) реализации И только с написанием goredo я наконец-то понял надобность в redo-ifcreate! Например есть цель "foo", но нет "foo.do", а есть "default.do" (где-нибудь). Если в зависимости будет прописано только "foo" и "default.do", то появление "foo.do" не заставить цель протухнуть! Поэтому пути поиска default.do файлов автоматически прописываются в зависимости, как-будто был вызван redo-ifcreate. Очень красиво, на мой взгляд. Как пользователь, я redo-ifcreate так и не знаю где вызвать, но внутри без него вижу что нельзя. Ведь и зависимость от .do файла явно никто не прописывает -- оно автоматически. ------------------------------------------------------------------------ оставить комментарий: mailto:comment@blog.stargrave.org?subject=Re:%20I%20redo%20redo%20%28fbfbf62ce9cb0a3fcb97e02d6fc05c249bb4e162%29 ------------------------------------------------------------------------ комментарий 0: From: kmeaw Date: 2020-12-02 16:08:53Z Похоже, то ли что-то случилось со ссылкой, то ли cgit обновился, но я получаю 404. Вот работающая ссылка: http://git.cypherpunks.ru/?p=goredo.git;a=blob;f=README;h=1c9e59be4026be59a0999487ff49602a700fd5da;hb=HEAD ------------------------------------------------------------------------ комментарий 1: From: Sergey Matveev Date: 2020-12-02 16:11:29Z *** kmeaw [2020-12-02 19:03]: >Похоже, то ли что-то случилось со ссылкой, то ли cgit обновился Я буквально сегодня заменил cgit на gitweb, который из коробки с git-ом идёт. Всё равно находится в системе да и проще его собирать. Сейчас более корректная ссылка это http://www.goredo.cypherpunks.ru/ ------------------------------------------------------------------------ Сгенерирован: SGBlog 0.34.0