\documentclass[russian,notitlepage,a4paper]{article}
\usepackage[koi8-r]{inputenc}
\usepackage{babel}

\textwidth=18cm
\oddsidemargin=-1.04cm
%\headheight=0cm
%\textheight=28cm
%\headsep=0cm
%\topmargin=-1.54cm

\author{Dmitry~V.~Levin <ldv@altlinux.org>\\ALT Linux Team}
\title{ALT Specfile Conventions\\(revision 0.5)}

\begin{document}
\maketitle

\section{Обоснование}

При разработке этих правил решались следующие задачи:
\begin{description}
	\item[Обеспечить желаемую функциональность:] наши пакеты должны отвечать
	определенным правилам, о которых пойдет речь несколько позже. Для этого
	надо, чтобы {\it spec}-файлы обеспечивали выполнение этих правил.
	\item[Помочь разработчику:] так как {\it spec}-файлы все еще пишут
	люди, то их работу нужно свести к тому минимуму, который, собственно, и
	требует участия человека. Разработчик не должен копировать блоки кода
	из файла в файл, ибо эта неинтеллектуальная работа отнимает массу сил и
	чревата ошибками. Для этого есть макросы. Если какой-то код появляется в
	разных {\it spec}-файлах более одного раза, то надо написать макрос(ы).
\end{description}

\section{Spec-файлы.}

\subsection{Устаревшие конструкции.}
Не следует использовать устаревшие конструкции - они лишь загромождают {\it spec}-файл,
снижая тем самым его читабельность. К устаревшим конструкциям, в частности, относятся:
\begin{itemize}
	\item тэг {\it BuildRoot:};
	\item строки вида {\it rm -rf \$RPM\_BUILD\_ROOT};
	\item {\it \%\_defattr} со стандартными	аргументами в начале файлов и секций {\it \%files};
	\item секция {\it \%clean}, пустая либо без разумного содержания.
\end{itemize}

\subsection{Фигурные скобки.}
Нет смысла засорять текст {\it spec}-файла ненужными фигурными скобками.
Избавится от них можно с помощью команды
\begin{verbatim}
cleanup_spec spec-файл
\end{verbatim}

\subsection{Выравнивание.}
Используйте табуляции для выравнивания. Избегайте пробельных символов в конце строк.

\subsection{Порядок тэгов.}
Рекомендуемый порядок заголовочных тэгов: {\it Name}, {\it Version}, {\it Release}, {\it Serial},
далее {\it Summary}, {\it License}, {\it Group}, {\it Url}, {\it Packager}, {\it BuildArch},
потом {\it Source*}, {\it Patch*}, далее {\it PreReqs}, {\it Requires}, {\it Provides}, {\it Conflicts},
и, наконец, {\it Prefix}, {\it BuildPreReqs}, {\it BuildRequires}.
Разумеется, не все из вышеперечисленных тэгов используются, равно как встречаются
и другие редко используемые тэги. В связи с тем, что {\it BuildRequires} зарезервирован
для автоматически вычисляемых зависимостей, для указания особых зависимостей следует
использовать {\it BuildPreReq}.

\subsection{Значения тэгов.}
Значение тэга от его имени следует разделять одним пробелом.
Элементы списка значений следует разделять запятой с последующим пробелом.
Значение тэга {\it Summary} следует начинать с прописной буквы.
Значение тэга {\it Summary} не следует завершать точкой.
Значения тэгов {\it Summary} и {\it \%description} могут содержать названия
команд только в не измененном виде.

\subsection{Номера релизов.}
Значение тэга {\it Release} должно иметь вид
\begin{verbatim}
altREVISION
\end{verbatim}
Eсли пакет содержит альфа-/бета-/пререлиз- версию какого-то программного
обеспечения и параметр Version содержит будущий номер версии, то номер
релиза такого пакета должен иметь вид
\begin{verbatim}
alt0.REVISION
\end{verbatim}
При обновлении более старой ветки релиз пакета должен иметь вид
\begin{verbatim}
BRANCH_POINT_RELEASE.BRANCH.REVISION
\end{verbatim}

где:
\begin{description}
	\item[REVISION] - номер ревизии пакета внутри репозитория, увеличивающийся при каждом обновлении;
	\item[BRANCH\_POINT\_RELEASE] - строка, описывающая релиз, из которого ``растет'' данная ветка;
	\item[BRANCH] - версия ветки (например, ``M24'' в ``ALT Linux 2.4 Master'').
\end{description}

При обновлении до новой версии REVISION сбрасывается в 1 и, в случае старой ветки,\\
BRANCH\_POINT\_RELEASE устанавливается в ``alt0''.

\subsection{Группы.}
Значение тэга {\it Group} должно соответствовать действительности и при этом принадлежать
фиксированному множеству, перечисленному в файле {\it /usr/lib/rpm/GROUPS}.

\subsection{ChangeLog.}
При формировании первой строки changelog-записи используйте утилиту
\begin{verbatim}
add_changelog spec-файл
\end{verbatim}
Описание изменений должно быть информативным; недостаточно объявить о наличии изменений,
необходимо их все явно перечислить.

\subsection{Файлы локализации.}
Если в состав пакета входят файлы локализации либо другие файлы на разных языках,
следует использовать макрос {\it \%find\_lang}. Подробную информацию можно получить,
выполнив команду {\it /usr/lib/rpm/find-lang -h}.

\subsection{Внутрипакетные зависимости.}
При работе с мультипакетными {\it spec}-файлами соблюдайте правило внутрипакетных зависимостей:
Если один пакет в какой-либо мере зависит от другого подпакета,
то эта зависимость должна быть указана полностью, включая не только имя, но также версию,
релиз и serial (если есть). Например,
\begin{verbatim}
Requires: \%name = \%version-\%release''.
\end{verbatim}
или
\begin{verbatim}
Requires: \%name = \%serial:\%version-\%release''.
\end{verbatim}
Обратите внимание на синтаксис: знак равенства, в отличие от дефиса, окружен пробелами.

\subsection{Разделяемые библиотеки.}
Пакеты, содержащие как разделяемые библиотеки, так и использующие их программы,
должны быть разделены на подпакеты таким образом, чтобы в подпакет,
содержащий разделяемые библиотеки, не входили использующие их программы.
Это, в частности, позволяет уменьшить количество циклических зависимостей.
По традиции, имена пакетов, состоящих только из разделяемых библиотек,
должны начинаться с префикса {\it lib} либо содержать его внутри слова.
При разделении подпакетов следует помнить о внутрипакетных зависимостях.

Каждый пакет, содержащий разделяемые библиотеки в каталоге {\it /lib}, {\it /usr/lib}
или {\it /usr/X11R6/lib}, должен их регистрировать при установке/обновлениях и удалении
с помощью макросов {\it \%post\_ldconfig} и {\it \%postun\_ldconfig} соответственно.

\subsection{Статические библиотеки.}
Статические библиотеки должны паковаться в отдельные подпакеты,
что связано со спецификой их использования.
Если имя devel-подпакета заканчивается суффиксом {\it -devel},
то имя нового devel-static-подпакета будет заканчиваться суффиксом {\it -devel-static}.
При разделении подпакетов следует помнить о внутрипакетных зависимостях:
В списке зависимостей devel-static-подпакета должна присутствовать зависимость
от {\it -devel = \%version-\%release}.

\subsection{Переименование пакетов.}
Иногда пакеты переименовывают. Например, это случается при упаковке разделяемых библиотек.
В таких случаях следует указывать правильную информацию о зависимостях,
необходимую для корректного обновления. В частности, должен присутствовать:
\begin{itemize}
	\item тэг {\it Provides: старое\_имя = \%version}
	\item тэг {\it Obsoletes: старое\_имя}
\end{itemize}

\section{Патчи.}

\subsection{Наименование патчей.}
При создании новых патчей, а также при импортировании патчей из других источников необходимо
придерживаться единых правил наименования имен патч-файлов:
\begin{verbatim}
NAME-VERSION-ORIGIN-WHAT.patch
\end{verbatim}
где
\begin{itemize}
	\item {\it NAME} и {\it VERSION} -- имя и версия пакета, для которого сделан патч;
	\item {\it ORIGIN} - аббревиатуры источников патча (обычно дистрибутивов);
	\item {\it WHAT} - краткое описание патча.
\end{itemize}

В случае, когда патч образован из нескольких частей, полученных из разных
источников, компонента имени {\it ORIGIN} должна содержать аббревиатуры
всех источников, перечисленные в порядке убывания важности.  Если патч был
создан или адаптирован для ALT Linux, то в {\it ORIGIN}, соответственно,
должно присутствовать {\it-alt-}.  Для патчей, взятых из репозитория,
в котором разрабатывается программа (например, из CVS), компонента имени
{\it ORIGIN} должна начинаться с {\it cvs-YYYYMMDD}.  Исправления от
основных разработчиков могут содержать "up" в поле {\it ORIGIN}.

Если описание патча {\it WHAT} состоит из нескольких слов, следует
разделять их дефисами.  Не следует использовать в этом качестве знаки
подчёркивания.

При составлении описания патча следует иметь в виду следующие общепринятые сокращения:
\begin{description}
	\item[makefile:] патчи, затрагивающие исключительно makefile*;
	\item[bound:] проверки на границы (буфера, целых чисел, и т.п.);
	\item[config:] патчи, затрагивающие исключительно конфигурационные файлы;
	\item[configure:] патчи, затрагивающие исключительно configure*;
	\item[doc:] патчи, затрагивающие исключительно документацию;
	\item[fixes:] кумулятивные патчи и/или исправления по надежности и/или безопасности;
	\item[format:] патчи на использование форматирования строк (printf);
	\item[install:] патчи, направленные на возможность выполнения ``make install'' непривилегированным пользователем;
	\item[linux:] патчи, предназначенные для портирования ПО на Linux;
	\item[man:] патчи, затрагивающие исключительно man-страницы;
	\item[texinfo:] патчи, затрагивающие исключительно документацию в формате texinfo;
	\item[tmp:] патчи, предназначенные для решения различных вопросов, связанных с временными файлами;
	\item[vitmp:] патчи, направленные на поддержку vitmp(1);
	\item[warnings:] патчи, исправляющие ошибки, найденные компилятором.
\end{description}

Это, конечно же, не обязывает вас подгонять свои исправления под одну
из указанных категорий - это всего лишь рекомендация на случай, если,
например, у вас есть файл исправлений, попадающий под одну из категорий,
называть его соответствующим образом (например, "tmp", а не "mkstemp").

\section{Исходный код.}

\subsection{Формат хранения.}
Исходный код большого объема (как архивы, так и патчи, по статусу приравненные к ним) следует хранить
в упакованном виде. Метод сжатия, {\it gzip} или {\it bzip2}, следует выбирать таким образом,
чтобы размер архива был минимальным, например, с помощью утилиты {\it zme}. Исключение составляют
{\it nosurce}-пакеты: в них отсутствующие файлы следует указывать в виде корректных URL.

\begin{thebibliography}{9}
\bibitem{altrpm} ALT Linux packaging: ftp://ftp.altlinux.ru/pub/distributions/ALTLinux/Sisyphus/doc/alt-packaging/
\end{thebibliography}

\end{document}
