Вопрос или проблема
Я автоматизирую обновление версий моего проекта с помощью этого bash-скрипта:
#!/usr/bin/env bash
CHANGELOG="Changelog.md"
DEBIAN_CHANGELOG="debian/changelog"
UPSTREAM_VERSION=$(cat VERSION)
# Обновление записей в файлах rpm
DEB_RELEASE_NOTES=$(awk '{print " * " $0}' < RELEASE_NOTES)
echo "Добавление новой записи в Debian changelog для версии $UPSTREAM_VERSION."
dch -D unstable -m "$DEB_RELEASE_NOTES" --newversion "$UPSTREAM_VERSION-0debian1-unstable1"
# Позволяет пользователю редактировать Debian changelog
$EDITOR_CHOICE "$DEBIAN_CHANGELOG"
echo "Версия успешно обновлена: $UPSTREAM_VERSION"
Что делает синхронизацию и устанавливает версию в пакетах rpm и debian. Но эта команда:
dch -D unstable -m "$DEB_RELEASE_NOTES" --newversion "$UPSTREAM_VERSION-0debian1-unstable1"
Вызывает у меня некоторые проблемы, потому что в debian/changelog появляется следующее:
mkdotenv (0.2.0-0debian1-unstable1) unstable; urgency=medium
* * 1. Разделение кодовой базы на несколько файлов. * 2. Использование отдельного
файла версии и определение версии при компиляции. * 4. [BUGFIX]
Если входной файл такой же, как и выходной, скопируйте входной файл во
временный. * 5. Улучшенная документация
-- Dimitrios Desyllas <[email protected]> Пн, 10 марта 2025 20:08:00 +0200
Тогда как файл RELEASE_NOTES
содержит:
1. Разделение кодовой базы на несколько файлов.
2. Использование отдельного файла версии и определение версии при компиляции.
4. [BUGFIX] Если входной файл такой же, как и выходной файл, скопируйте входной файл во временный.
5. Улучшенная документация
Знаете ли вы, почему все строки слипаются в один маркер???
dch
ожидает одну запись в changelog, без оформления. Он сам отформатирует это, добавляя звездочку и делая перенос строк по мере необходимости.
Для вашего случая необходимо запускать его для каждой записи, не указывая целевое распространение. Затем, чтобы “закрыть” записи для целевой версии, выполните команду
dch -r -D unstable ignored
(Это требует аргумента, но игнорирует его.)
Общий процесс будет выглядеть следующим образом:
DEB_VERSION="$UPSTREAM_VERSION-0debian1-unstable1"
while IFS= read -r line; do
dch -v "$DEB_VERSION" -- "$line"
done < RELEASE_NOTES
dch -r -D unstable ignored
Нет необходимости “инициализировать” новую версию, это происходит автоматически, когда dch
получает версию, которая не совпадает с версией вверху changelog.
В конце получилось то, что сказал @Stephen Kitt:
#!/usr/bin/env bash
UPSTREAM_VERSION=$(cat VERSION)
echo "Добавление новой записи в Debian changelog для версии $UPSTREAM_VERSION."
DEB_VERSION="$UPSTREAM_VERSION-0debian1~unstable1"
dch --distribution unstable --newversion $DEB_VERSION -m ""
while IFS= read -r line; do
echo $line;
dch -a "$line"
done < RELEASE_NOTES
# Позволяет пользователю редактировать Debian changelog
$EDITOR_CHOICE "$DEBIAN_CHANGELOG"
echo "Версия успешно обновлена: $UPSTREAM_VERSION"
Для этого необходимо инициализировать версию, вызвав:
dch --newversion "$DEB_VERSION"
Затем для каждой строки в файле RELEASE_NOTES
нам нужно вызвать:
dch --newversion "$DEB_VERSION" -a "$line"
Это добавляет строку в файл debian/changelog
, после чего мы завершаем строку:
dch --newversion "$DEB_VERSION" --distribution unstable ignored
Затем выпустить релиз нужно, финализировав его следующим образом:
dch --newversion "$DEB_VERSION" --distribution unstable ignored
В вашем примере это приведет к следующей записи в changelog:
mkdotenv (0.2.0-0debian1-unstable1) unstable; urgency=medium
[ John Doe ]
* 1. Разделение кодовой базы на несколько файлов.
* 2. Использование отдельного файла версии и определение версии при компиляции.
* 4. [BUGFIX] Если входной файл такой же, как и выходной, скопируйте входной файл во временный.
* 5. Улучшенная документация
-- имя пользователя <имя_пользователя@hostname> Пн, 10 марта 2025 22:01:07 +0200
Ответ или решение
Ваша проблема с добавлением многострочной записи в файл изменений Debian (debian/changelog) заключена в специфике работы утилиты dch
. Когда вы использовали команду dch -D unstable -m "$DEB_RELEASE_NOTES" --newversion "$UPSTREAM_VERSION-0debian1-unstable1"
, вся строка, переданная в качестве аргумента, была воспринимается как одна запись. Это привело к тому, что все строки объединялись как один пункт с несколькими звездочками и без перехода по строкам, так как dch
использует специфичное форматирование.
Теория
Утилита dch
предназначена для облегчения задачи внесения изменений в последовательность Debian. Она ожидает входящие данные в формате, соответствующем стилю Debian, и сама обрабатывает форматирование, включая добавление звездочек для пунктов списка и разбиение по строкам, как это необходимо. Это означает, что форматирование записей изменений должно довериться dch
, и попытка предварительно форматировать текст может привести к неожиданным результатам.
Пример
Рассмотрим предоставленную вами команду и входной файл RELEASE_NOTES
. Вы пытались передать несколько строк через переменную DEB_RELEASE_NOTES
, однако из-за специфики awk
, который просто добавляет префикс *
к каждой строке, итоговая переменная DEB_RELEASE_NOTES
все равно оказывается одной длинной строкой. Как следствие, dch
воспринимает это как одну строку и отображает в файле debian/changelog
в неправильном формате.
Применение
Чтобы правильно записать изменения, необходимо изменить подход к передаче данных в dch
. Лучше всего записывать каждую строку изменений отдельно, используя цикл, и позволить dch
самостоятельно добавлять пунктуацию и форматировать список. Это можно сделать следующим образом:
#!/usr/bin/env bash
UPSTREAM_VERSION=$(cat VERSION)
DEB_VERSION="$UPSTREAM_VERSION-0debian1~unstable1"
echo "Добавление новой записи в changelog для версии $UPSTREAM_VERSION."
# Инициализация нового раздела в changelog
dch --distribution unstable --newversion "$DEB_VERSION" -m ""
# Добавление каждой строки как отдельной записи
while IFS= read -r line; do
echo "Добавление записи: $line"
dch -a "$line"
done < RELEASE_NOTES
# Предложение пользователю редактировать changelog
$EDITOR_CHOICE "$DEBIAN_CHANGELOG"
echo "Версия обновлена успешно: $UPSTREAM_VERSION"
Шаги
-
Инициализация новой версии: Команда
dch --newversion "$DEB_VERSION"
создает новую запись в файлеdebian/changelog
, позволяя вам начать запись новой информации о версии. -
Цикл по строкам: Использование цикла
while IFS= read -r line; do ... done < RELEASE_NOTES
обеспечивает считывание каждой строки отдельно из файлаRELEASE_NOTES
. -
Добавление без форматирования:
dch -a "$line"
используется для добавления каждой строки как отдельного пункта, при этомdch
берет на себя оформление и добавление звездочек. -
Финализация: Команда
dch -r -D unstable ignored
завершает текущую редакцию и удостоверяет правильное отражение изменений.
Заключение
Соблюдая вышеописанные шаги, вы сможете правильно записать многострочное изменение в деб-пакетный журнал. Этот метод обеспечивает логическую раздельность между оформлением данных и их содержанием, позволяя утилите dch
выполнить свою работу наиболее эффективно. Следует помнить, что малейшая ошибка в формате может привести к неправильной интерпретации данных, поэтому важно следить за правильностью используемых команд и процедур.