Beri bash i ebash / Говнокод #16780 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
...
%install
%{__rm} -rf %{buildroot}
mkdir -m 755 -p %{buildroot}%{_datadir}/common-lisp/source/%{name}
for s in $(find -regex '.+\.\(lisp\|asd\|org\)$'); do
  install -D -m 644 $s %{buildroot}%{_datadir}/common-lisp/source/%{name}
done;
mkdir -m 755 -p %{buildroot}/etc/common-lisp/source-registry.conf.d
for las_conf in $(ls %{buildroot}/etc/common-lisp/source-registry.conf.d | tail -n 1); do
    for last in $(echo "${last_conf}" | grep -oP '^[0-9]+'); do
        for cl_prefix in $(echo "${last}+1" | bc); do
            echo '(:include "/usr/share/common-lisp/source/%{name}/")' > \
	            "%{buildroot}/etc/common-lisp/source-registry.conf.d/${cl_prefix}-%{name}.conf"
            install -m 644 ${cl_prefix}-%{name}.conf %{buildroot}/etc/common-lisp/source-registry.conf.d
        done;
    done;
done;

%files
%defattr(-,root,root,-)
%{_datadir}/common-lisp/source/%{name}/*
...

И ведь что показательно, работает!

Вот просто не предать словами, как я это ненавижу. Менеджер пакетов завдующий установкой ПО написан на Питоне, но нельзя просто так взять и на Питоне же написать установочный скрипт. Надо горбатится над каким-то недоязыком с феноменально шизофреничными макросами полным отсутствием каких-либо высокоуровневых инструментов, типа структур и интерфейсов...

Запостил: wvxvw wvxvw, (Updated )

Комментарии (26) RSS

  • > Надо горбатится над каким-то недоязыком

    шелл как шелл. просто кто-то очень очень сильно извратился в строках 9-11.

    ЗЫ строки 12-14 пахнут. install в 14й перепишет тот файл который echo в 12-13 создает.

    > Менеджер пакетов завдующий установкой ПО написан на Питоне, но нельзя просто так взять и на Питоне же написать установочный скрипт.

    Почему нет? Пишешь питон скрипт, включаешь его в пакет, вызываешь его во время инсталяции, а потом удаляешь. Или там какой извратный chroot используется во время инсталяции?
    Ответить
    • Да, с инстоллом промахнулся. Очень все пути похоже выглядят.
      Тут главная фишка в том, что в .spec файле переменную не объявить. Т.е. эти циклы не нужны (каждый цикл выполняется ровно один раз).
      Да понятно, что можно написать инсталятор отдельно и включить его в... другой (убогий) инсталятор. Зачем они его придумали? Питон же уже был. А даже если и нет, то Перл точно был.

      Почему шелл плох для этого? Куча бойлерплейта. Вот то, что я запостил - инсталяция одного пакета, а мне для полного счастья нужно около десятка. И они все будут выглядеть на 90% одинаковыми (потому что нет модульности, структур и интерфейсов).
      Ответить
      • > Тут главная фишка в том, что в .spec файле переменную не объявить.

        а зачем тебе переменная на уровне spec файла то сдалась?

        то что сверху это всего лишь template скрипта, где %{} заменятся на значения, и результат будет скормлен шелу. почти тот же самый принцип что и в GNU make.

        другими словами, пишешь например, `R="%{buildroot}";` и дальше можешь пользоватся `$R` вместо `%{buildroot}`.

        > Почему шелл плох для этого? Куча бойлерплейта.

        признайся самому себе: ты просто не знаешь шела.

        то что написано сверху (нахождение номера последнего пакета + 1) делается весьма прямолинейно и без извратов. например:

        LAST_NUM=$(ls -1 %{buildroot}/etc/common-lisp/source-registry.conf.d | tail -n 1 | sed 's!^\(\d*\).*!\1!; s!^0*!!;')
        test -n "$LAST_NUM" || LAST_NUM=0
        let "NEW_NUM=$LAST_NUM+1"
        cl_prefix=`printf "%02d" $NEW_NUM` # уверен что там ведущие нули есть, иначе ls правильно сортировать не будет.
        echo ...
        install ...


        зы еще пахнет то что если предварительно ничего не было установлено, то ничего в /etc/common-lisp/source-registry.conf.d/ и не будет скопировано. плюс, я уверен что номера как минимум двухзначные с ведущими нулями.

        но от этого говно не станет меньше. потому что поочередно инсталируя/деинтсталируя пару пакетов в разном порядке (что может случится, например, в случае апгрейда) можно счётчик до бесконечности накручивать. это первый раз когда я вижу что используются нефиксированые числа при инсталяции в .d каталог.

        > И они все будут выглядеть на 90% одинаковыми

        ну блин, тебе даже же %{name} предоставляют. чего тебе еще не хватает что бы из сделать 100% одинаковыми?

        ЗЫ к слову. я тут чисто про шелл говорю - спеки ни разу не писал.

        ЗЗЫ а вот это - find -regex '.+\.\(lisp\|asd\|org\)$' - по человечески пишется find -name '*.list' -o -name '*.asd' -o -name '*.org'. (регулярка скипает имена состоящие только из расширений - если это так и задумывалось, то добавь '?' перед '*'.)
        Ответить
        • Зачем мне на уровне spec файла переменная? - Мне удобнее программировать с переменными, чем без.
          О, а в Мейкфале тоже просто так нельзя взять и объявить переменную.

          > Без извратов.
          Без извратов это так:
          last = int(listdir("/etc/common-lisp/source-registry.conf.d")[-1].split('-'))
          cl_prefix = str(last + 1).zfill(2)


          никто не сказал, что это весь скрипт, /etc/common-lisp/source-registry.conf.d/ создается где-то раньше.

          Что мне не хватает?
          Открой как-нибудь SCons файл и сравни количество текста.
          В spec файле дохрена насторек которые можно было бы заполнить по-умолчанию.
          Название пакета - почему бы не взять название папки в которой сорцы находятся? в 99% случаев это и будет название пакета. Сорцы - ровно точно так же: название папки + tar.gz. Описание? Почему бы не посмотреть в ту же папку и не прочитать его из файла README?
          А как думаешь, в каком файле окажется %changelog?
          Более того, если бы это был нормальный язык, можно было бы, например, унаследовать класс один раз от стандартного шаблона, переопределить в нем пару методов и использовать этот новый класс для однотипных задач для которых он был сделан. Тут же я вынужден копипастить бесполезную херню типа %prep %build и т.д.
          Ну вот например, хочу я, чтобы ченжлог генерировался из логов Гита? Почему бы и нет, ну правда ж в 21-м веке живем все-таки. И хочу я это для всех проектов. И что мне остается? - правильно, либо написать инсталятор на другом языке и вызывать его из RPM скрипта (нафиг тогда нужен RPM скрипт?), либо паста в RPM скрипте.

          Да, у меня есть папка .org в проекте, там локальные настройки Org-mode хранятся.
          Ответить
          • > Открой как-нибудь SCons файл и сравни количество текста.

            Я видел SCons'ы (и до этого перловы Cons'ы) из продакшн проектов. Текста там было наааамного больше. 🙂

            > Более того, если бы это был нормальный язык

            Ты зациклился на каком-то оverdesign'е. Как я и говорю, то чего тебе не хватает это простое знание шелла.

            В сети валяется в хтмл "Unix Power Tools". Книга типа "cookbook" и содержит много разных примеров как чего можно делать с помощью шелли и базовых утилит. (случайно нагуглил: http://bioinfo2.ugr.es/OReillyReferenceLibrary/unix/upt/index.htm - програмирование на шелле: http://bioinfo2.ugr.es/OReillyReferenceLibrary/unix/upt/part08.htm )

            > Более того, если бы это был нормальный язык [...]

            Нафиг не нужно потому что как правило в пост-инстале обрабатываются только какие-то исключения.

            Да и переплюнуть шелл по работе с файлами и текстом - в батч режиме - весьма сложно. Нужно только уметь.

            В конце концов, написать кучу говна можно на любом языке. Но это не становится виной языка.
            Ответить
            • Ага, SCnos файл для тривиального проекта на, скажем, Яве, выглядит так:
              Java()

              И все. И это описывает и сборку и как удалить стартые результаты сборки, интерфейс командной строки и т.д.

              Можно ли сделать на Шелле? - да. Нужно ли? - это совсем другой вопрос. Примеры Шелла, а особено подражания, где это доведено до абсурда, Автомейк, язык матрешка: макросы на одном языке раскрываются в макросы на другом языке (последовательным вызовом 5-6 разных програм!), а потом оказывается что если раскрыть макросы на третьем языке то из них получится 100500 разных недоязыков специальных для каждой команды этого языка. Более того, они сгенерируют 99% кода который у меня уже был, вот ну совсем рядом в соседней папке.

              Например, для использования sed не достаточно знать регулярные выражения и Шелл, нужно знать мини-язык, которым sed описывает операции которые он может сделать. И так практически с каждой коммандой. find - аналогично, printf - то же самое, и т.д. Т.е. для того, чтобы понять программу на Питоне - достаточно знать Питон (т.е. каких-то 10-20 ключевых слов и столько же встроеных функций, остальное можно понять из комбинаций предыдущего). С Шеллом так не получится, потому что каждая команда использует свой алфавит и свои правила. Это не экономно с точки зрения того, какой выразительной силой должен обладать язык для того, чтобы описать необходимые операции.
              Ответить
              • > SCnos файл для тривиального проекта на, скажем, Яве, выглядит так:
                Java()

                Тривиальные проекты на яве никому не нужны. Нужно управление зависимостями, подключение сторонних репозиториев пакетов, минимизация жарников, гибридная Scala/Java - компиляция, накатывания миграций на базы, тыщи действий, которые наполнят живые SCons файлы сотнями строк.
                Ответить
          • last = int(listdir("/etc/common-lisp/source-registry.conf.d")[-1].split('-'))
            cl_prefix = str(last + 1).zfill(2)

            позвольте мне это переписать еще раз на шелле:
            cl_prefix=$(python -c 'last = int(listdir("/etc/common-lisp/source-registry.conf.d")[-1].split("-")); print str(last + 1).zfill(2)')

            😉
            Ответить
        • А, да, эта .d не совсем обычная, и как числа тут расставлять - я не знаю. По-хорошему, кто-то должен взяться и обновить common-lisp-listener пакет, который бы занимался регистрацией библиотек (он это делал, но так давно и плохо, что на него все забили). Т.е. по-идее, я не должен заниматься этой конфигосодомией. Но проблема в том, что нету "резидента", который бы это сделал.
          Т.е. кто-то должен быть в системе и следить за базой данных, какие пакеты установлены, что делать если один и тот же пакет пытается установиться, не почистив предыдущую установку и т.п. Разбираться с такими нюансами из установочного скрипта - буэ. Но другого нет.
          Ответить
    • > Почему нет? Пишешь питон скрипт, включаешь его в пакет, вызываешь его во время инсталяции, а потом удаляешь.

      Вызывать во время инсталляции пакета скрипт, который находится в пакете, который устанавливаем? Проблема курицы и яйца. Вероятно, есть некоторая ошибка в терминологии, но идея верна.

      %install - фаза, на которой происходит инсталляция собранных бинарников в DESTDIR, выполняется он в корне проекта, подлежащего упаковке. Поэтому дёргать из него можно всё что угодно. Теже питоны, лишь бы они были в BuildRequires. Обычно там тупой (с)make install или вызов вашего любимой системы сборки для инсталляции.
      Ответить
  • > Менеджер пакетов завдующий установкой ПО написан на Питоне

    Вот до чего же люди плохо мыслят в четырёх измерениях. Пакетный менеджер rpm написан на сишке. Управление зависимостями с пистоном появились не сразу. А переделывать всю инфраструктуру, чтобы писать скрипты на питоне - идея так себе.

    Кроме того, типичные скрипты для инсталляции выглядят одинаково паршиво и требуют много бойлерплейта на любом языке. Особенно при сборке сишного софта.
    Ответить
    • В том-то все и дело, что не требуют они этого бойлерпейта. Бойлерплейт можно было один раз написать и использовать его потом много раз один и тот же, вместо того, чтобы генерировать по-новой.

      Вообще, и Питон не нужен для этого. Изначально, когда GNU только задумывался, языком расширений должна была стать Схема (Guile). И вобщем, они к этому и идут, только очень медлено. То, что ЮНИКС решили реализовывать, по крайней мере в этом смысле, было ошибкой. Тогда, это конечно дало возможность использовать готовые програмы, но врезультате получилось то, чего и боялись (тогда от Tcl) - непродуманый беспомощный язык расширений + зоопарк замен этому языку.
      Ответить
      • Не должно быть в %install никакого бойлерплейта. Вызов make install / вашей любой системы сборки.
        Ответить
      • По поводу бойлерплейта в именах и прочее:

        Из исходников, как правило, собирается больше одного пакета. Шареные либы, платфомо-независимые данные, основные сервисы, утилиты, дебажные символы, devel-пакеты с публичными хедерами и библиотеками без soname, emacsen-пакеты, плагины для вима, очень много всего.

        Более того, это даже не отношение один ко многим, скорее многие ко многим. Для сборки тулов LLVM нужно сразу несколько архивов с исходным кодом.

        Да, логично упростить для простых пакетов. В дебиане для этого есть тула dh_make. C rpm я работал недолго, может, и там что-то такое есть.

        Но для грамотной упаковки изучать инфраструктуру пакетирования всё равно придётся, и подстановка пары имён - меньшее из всех зол.

        И что ещё важно понимать - в опенсорсе люди, которые собирают пакеты, как правило, не те же люди, что пишут софт. У них есть доступ в основном к релизным архивам с исходниками. Версии пакетов лишь отчасти связаны с версиями софта - пакеты могут накатывать собственные патчи на софт из архива в процессе сборки. Отсюда растут многие неудобства, возникающие при попытке упаковывать софт, который сам же и пишешь.

        У нас, например, метаданные пакетов версионируются в отдельном git-репозитории, и changelog пакетов генерится из git log в этом репозитории.
        Ответить
        • Да, да, и мегабайты одинакового кода из, например configure ну просто необходимо поэтому скопировать в каждый проект. А как же по-другому?
          В Дебиане те же яйца только в профиль. Нужно менять подход, а не придумавать дополнительные инструменты, которые могут нагенерировать нового бойлерпейта, т.как с каждым таким инструметном количество бойлерплейта только увеличивается.
          В чем принципиальное отличие SCons от Make? - Не в том, что единичный тривиальный билд будет меньше, а в том, что если у меня есть одинаковые сколько угодно сложные билды, написав на SCons билд один раз, я этот билд проинсталирую в системе, и все остальные билды смогут использовать его (внимание, никакого бойлерплейта! используется тот же код), или смогут импортировать часть! другого уже готового билда. Будь это Ява, Ц++, да что угодно, я смогу общий код из разных билдов использовать повторно, не копируя его!
          Ответить
          • Ок, можно собрать кучу готовых рецептов для make, положить их в пакет, добавить пакет в build-depends и не писать кучу бойлерплейта.

            Именно так у нас и сделано.

            > В чем принципиальное отличие SCons от Make?

            В том, что make есть практически на любой юникс-системе, не нужно трахаться с обратно несовместимыми версиями питона и можно рассчитывать, что твой софт будет стабильно собираться даже на кофеварке.

            Это никак не опровергает тот факт, что autotools и прочие configure - лютое говнище, а пакетирование под линупс - костыли и шаманство.
            Ответить
            • Так может надо стремиться к хорошему, вместо того, чтобы жить с уверенностью, что раз есть говно, которое мытарствами и слезами удалось довести до состояния, когда оно иногда работает, то с ним нужно оставаться жить навсегда?
              Куча готовых рецептов для Мейка - это называется замести под ковер, вместо того, чтобы решить проблему.
              Ответить
              • Я честно стремлюсь, но SCons далеко не ответ на все вопросы. CMake тоже говно. GYP тоже говно.

                Давно хочу написать свою систему сборки с ориентацией на сишкопроекты, с Lua в качестве языка описания задач, поддержкой герметичных билдов, быстрыми инкрементальными сборками и подключением зависимстей из гитхабика одной строчкой.
                Ответить
                • > Давно хочу написать свою систему сборки с ориентацией на сишкопроекты [...]

                  да как по мне простой тулзы не хватает, которая нативно рекурсивна и просто А в Б по заданому правилу транслирует (включая случаи когда не только А, но и Б есть набор файлов). (в мэйке педрилы так и не сделали определения правил независимым от А и Б.)

                  до сишко/этц проектов еще дорости надо.

                  все зацикливаются на высокоуровневых функциях (авто зависимости) в то время как база остается слабой.

                  вот даже то повсеместное инсталирование библиотек и хидеров (внутри большого проекта) никто толком отслеживать не умеет. (что бы зависимости продолжали работать.) Cons умел - но SCons вроде так и не перенял.
                  Ответить
                    • > Есть ещё вот такая интересная штука [...]

                      идея правильная - но на неправильном языке. 🙂
                      Ответить
        • > метаданные пакетов версионируются в отдельном git-репозитории, и changelog пакетов генерится из git log в этом репозитории.
          - мне нравится эта идея. Надо будет попробовать как-то
          Ответить

Добавить комментарий

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8