\documentclass[j-spec.tex]{subfiles}

\begin{document}
\section{Управление проектом: сборщики проектов}
\subsection{В предыдущих сериях...}
В прошлом разделе мы рассмотрели:
\begin{itemize}
\item краткую историю;
\item что скачать, и как это выбирать;
\item какие шестерёнки крутятся внутри;
\item структуру простого и обычного проекта;
\item стандартную утилиту для создания документации;
\item сторонние инструменты автоматизации сборки.
\end{itemize}

\subsection{В этом разделе}
Будет коротко рассмотрена мотивация создания и использования сборщиков проектов (зачем это нужно), какой эволюционный путь прошли специализированные сборщики проектов, какие новые понятия появились при их использовании. Рассмотрим два самых популярных на сегодняшний день сборщика и один экзотический, но достаточно быстро набирающий обороты. Поймём какой путь проделывает чужая библиотека, чтобы попасть в наш проект и научимся публиковать собственный код, делая тем самым вклад в сообщество.
\begin{itemize}
\item \nom{Ant}{Apache Ant (англ. ant — муравей и акроним — «Another Neat Tool») — утилита для автоматизации процесса сборки программного продукта. Является кросс-платформенным аналогом утилиты make, где все команды записываются в XML-формате.}
\item \nom{Ivy}{Apache Ivy переходный пакетный менеджер. Является подпроектом Apache Ant, которому нужен для разрешения зависимостей. Внешний XML файл определяет зависимости проекта и перечисляет ресурсы, необходимые для сборки проекта. Ivy ищет и скачивает ресурсы из репозитория (приватного или публичного).};
\item \nom{Maven}{Apache Maven — фреймворк для автоматизации сборки проектов на основе описания их структуры в файлах на языке POM (англ. Project Object Model), являющемся подмножеством XML. В отличие от Ant, декларативный. Проект Maven издаётся сообществом Apache Software Foundation. Название системы является словом из языка идиш, смысл которого можно примерно выразить как «собиратель знания».};
\item \nom{Gradle}{система автоматической сборки, построенная на принципах Apache Ant и Apache Maven, но предоставляющая специалььный предметно-ориентированный диалект на языках Groovy и Kotlin вместо традиционной XML-образной формы представления конфигурации проекта.};
\item \nom{Bazel}{свободный программный продукт для автоматизации сборки и тестирования приложений. Компания Google использует внутренний инструмент под названием Blaze, и выпустила свободно распространяемый вариант с открытым исходным кодом под названием Bazel (анаграмма Blaze). Bazel впервые выпущен в марте 2015.};
\item \nom{Артефакт}{Артефакт — это любой созданный искусственно элемент программной системы. К элементам программной системы, а, следовательно, и к артефактам, могут относиться исполняемые файлы, исходные тексты, веб страницы, справочные файлы, сопроводительные документы, файлы с данными, модели и многое другое, являющееся физическим носителем информации.};
\item \nom{Репозиторий}{место, где хранятся и поддерживаются какие-либо данные. Чаще всего данные в репозитории хранятся в виде файлов, доступных для дальнейшего распространения по сети};
\item \nom{Прокси}{промежуточный комплекс, выполняющий роль посредника между пользователем и целевым сервером, позволяющий клиентам как выполнять косвенные запросы к другим сетевым службам, так и получать ответы. Сначала клиент подключается к прокси и запрашивает какой-либо ресурс (например артефакт), затем прокси либо подключается к указанному серверу и получает ресурс у него, либо возвращает ресурс из собственного кэша.};
\end{itemize}

\subsection{Мотивация и схема (зачем это нужно и как это работает)}

% Комментатор_Ильнар.  Вот тут ощущение что мы недостаточно ребятам объяснили что реальный проект - это не только свой код, который мы написали в IDE, но и большое количество всего остального, что мы при этом используем - библиотеки, фреймворки и т.п. Более того, здесь ребята могут ничего не знать про jar файлы, в которые запаковывается проект. Я бы наверное (возможно в 1-й лекции) рассказал про jar, сделал "исполняемый файл" который можно скормить JRE, а потом на этой лекции рассказал что руками собирать все нужные библиотеки, указывать их в класспаф и т.п. - это дико неудобно, эту работу можно всю автоматизировать с помощью сборщиков, а сборщики - это вот то про что мы тут собственно и рассказываешь)

Сборщики проекта - это сложный инструментарий, который может скрывать обширный объём работы, который при ручном подходе требует значительных затрат и может оказаться весьма утомительным.

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

\begin{frm}
  Система сборки это программа, которая собирает другие программы. На вход система сборки получает исходный код, написанный разработчиком, а на выход выдаёт программу, которую уже можно запустить. Отличается от компилятора тем, что вызывает его при своей работе, а компилятор о системе сборки ничего не знает, то есть является инструментом более широкого спектра.
\end{frm}

Сборщик часто решает целый спектр задач, для решения которых компилятор не предусмотрен. Например:
\begin{itemize}
\item загрузить зависимые библиотеки;
\item скомпилировать классы модуля;
\item сгенерировать дополнительные файлы: SQL-скрипты, XML-конфиги и пр.;
\item упаковать скомпилированные классоы в архивы;
\item компилировать и запустить модульные тесты и рассчитать процент покрытия;
\item развернуть (deploy) файлы проекта на удаленный сервер;
\item генерировать документацию и отчеты.
\end{itemize}

Системы сборок имеют схожую верхнеуровневую архитектуру:
\begin{enumerate}
\item Конфигурации - собственная конфигурация, где хранятся «личные» настройки системы. Например, такие как информация о месте установки или окружении, информация о репозиториях и прочее;
\item Конфигурация модуля, где описывается место расположения проекта, его зависимости и задачи, которые требуется выполнять для проекта;
% Комментатор_Ильнар. Слово зависимости мы еще не ввели. студенты его могли не слышать. Надо как раз как в прошлом комментарии показать что наш проект может использовать сторонние библиотеки. При этом мы легко можем скачать и положить их рядом на своем компе и прописать в класспаф при javac и даже некоторую автоматизацию сделать. Но, если мы хотим это разместить где-то в другом месте (деплой на сервере), то это становится уже далеко не так удобно. Библиотеки (и все остальное) с которыми связан наш проект (читай от которых он зависит) называются зависимостями. И одна из задач, которую решают сборщики проектов - это как раз таки работа с этими зависимостями.

\item Парсеры конфигураций - парсер способный «прочитать» конфигурацию самой системы, для её настройки соответствующим образом;
\item Парсер конфигурации модуля, где некоторыми «понятными человеку» терминами описываются задачи для системы сборки;
\item Сама система — некоторая утилита + скрипт для её запуска в вашей ОС, которая после чтения всех конфигураций начнет выполнять тот или иной алгоритм, необходимый для реализации запущенной задачи;
\item Система плагинов — дополнительные подключаемые надстройки для системы, в которых описаны алгоритмы реализации типовых задач;
\item Локальный репозиторий — репозиторий (некоторое структурированное хранилище некоторых данных), расположенный на локальной машине, для кэширования запрашиваемых файлов на удаленных репозиториях.

% Комментатор_Ильнар. Я бы тут простыми словами еще раз это сказал. Локальный репозиторий - это то место на вашем компьютере куда будут скачаны зависимости для вашего проекта. Хотя это наверное больше для сценария, но немного упростил бы все равно.

\end{enumerate}

Для языка Java основных систем сборок три:
\begin{itemize}
\item Иногда можно встретить Ant в сочетании с инструментом по управлению зависимостями Ivy, в чистом виде Ant почти никогда не применялся;
\item Самый популярный инструмент - это Maven, используется для JavaEE и приложений с использованием Spring Framework;
\item Gradle основной инструмент в мобильной разработке, часто Groovy/Kotlin описания сборки оказываются удобнее XML;
% Комментатор_Ильнар. Тут предполагается что читатель знает причем тут XML, но это может быть не так. Можно добавить XML, который используется в Maven или что-то типа того. Или в блок про Мавен написать что в нем описание сборки в виде XML файла дается.
\end{itemize}

Экзотическая Bazel. Её отличает полная кроссплатформенность и кросстехнологичность, что делает её особенно привлекательной для микросервисных проектах, использующих несколько языков программирования.

\subsection{С чего всё начиналось (Ant, Ivy)}
Первый специализированный инструмент автоматизации задач для языка Java. По сути, это аналог \code{Makefile}, то есть набор скриптов (которые в разговорной речи называются тасками\footnote{от англ task - задача, задание}). В отличие от make, утилита Ant имеет только одну зависимость — JRE. Ещё одним важным отличием от мейка является отказ от использования команд операционной системы. Всё что пишется в ант пишется на XML, что обеспечивает переносимость сценариев между платформами.

Управление процессом сборки как только что было сказано, происходит посредством XML-сценария, также называемого Build-файлом. В первую очередь этот файл содержит определение проекта, состоящего из отдельных целей (таргетов, с этим понятием мы познакомились когда говорили о мейкфайлах). Цели в терминах ант сравнимы с процедурами в языках программирования и содержат вызовы команд-заданий (тасков). Каждое задание представляет собой неделимую, атомарную команду, выполняющую некоторое элементарное действие.

Между целями могут быть определены зависимости — каждая цель выполняется только после того, как выполнены все цели, от которых она зависит (если они уже были выполнены ранее, повторного выполнения не производится). Типичными примерами целей являются clean (удаление промежуточных файлов), compile (компиляция всех классов), deploy (развёртывание приложения на сервере).

Скачивание и установка, ant для Linux-подобных ОС выполняется привычной командой установки в вашем пакетном менеджере, вроде sudo apt install ant, а для Windows можно перейти на сайте ant.apache.org и скачать архив, распаковав его и прописав соответствующий путь в переменные среды. Проверить версию можно командой ant -version

% Комментатор_Ильнар. Команды типа sudo apt-install ant и т.п. давайте выделять как-то в тексте. наверное тут можно это красиво сделать

% Комментатор_Ильнар. теперь к тому что ниже. нужен некоторый переход. Иначе мы с ant -version перешли на некоторую магию. Надо пояснить что мы сейчас будем делать.

% --- слайд
\begin{lstlisting}[language=XML,style=ASMStyle]
<?xml version="1.0"?>
<project name="HelloWorld" default="hello">
  <target name="hello">
    <echo>Hello, World!</echo>
  </target>
</project>
\end{lstlisting}
% --- конец слайда

Теперь можно написать простой сценарий HelloWorld: в нём мы указываем версию XML, без этого никакой XML никогда не работает. затем говорим, что наш проект называется "привет мир", а собирать по умолчанию для этого проекта надо таргет hello. далее в проекте идут описания таргетов, в нашем случае таргет будет один, он будет носить имя хелло, а в рамках таргета нужно будет вывести в терминал приветствие миру.
% Комментатор_Ильнар. к тексту выше. надо все же чуть более явно пояснить отдельные детали. Например, когда мы пишем что по умолчанию будет выполняться таргет hello, то можно в скобках сделать пояснение (см. default="hello") и так по всем пунктам.

% --- слайд
\begin{lstlisting}[language=C,style=CCodeStyle]
mkdir hello
cd hello
ant
\end{lstlisting}
% --- конец слайда

Затем, нужно создать подкаталог hello и сохранить туда файл с именем build.xml, который содержит сценарий. Далее надо перейти в каталог и вызвать ant. Полный перечень команд:

% Комментатор_Ильнар. ощущение что этот слайд находится чуть выше. После этого слайда также вроде текст сбит, должен находиться до него

% --- слайд
\begin{verbatim}
Buildfile: /home/hello/build.xml

hello:
[echo] Hello, World!
BUILD SUCCESSFULL
\end{verbatim}
% --- конец слайда

В результате выполнения которых получим следующий вывод. Что именно произошло? система сборки нашла файл сценария с именем по умолчанию, по удачному стечению обстоятельств система ищет файл с именем build.xml и выполнила цель указанную по умолчанию, здесь уже никаких удачных стечений обстоятельств, мы явно указали, что нужно по умолчанию выполнять таргет с именем hello. Чтобы не запутаться в более сложном проекте, мы указали имя проекта, с помощью атрибута name.

% --- слайд
\begin{lstlisting}[language=XML,style=ASMStyle]
<!-- Очистка -->
<target name="clean" description="Removes all temporary files">
  <!-- Удаление файлов -->
  <delete dir="${build.classes}"/>
</target>
\end{lstlisting}
% --- конец слайда

В стандартной поставке ant присутствует более 100 заранее созданных заданий, таких как: удаление файлов и директорий (delete), компиляция java-кода (javac), вывод сообщений в консоль (echo) и т.д. Вот пример реализации удаления временных файлов, используя задание delete

\subsection{Репозитории, артефакты, конфигурации}
\subsection{Классический подход (Maven)}
\subsection{Всем давно надоел XML (Gradle)}
\subsection{Собственные прокси, хостинг и закрытая сеть}
\subsection{Немного экзотики (Bazel)}



Ant, Ant+Ivy
Первым для автоматизации этих задач появился Ant. Это аналог make-файла, а по сути набор скриптов (которые называются tasks). В отличие от make, утилита Ant полностью независима от платформы, требуется лишь наличие на применяемой системе установленной рабочей среды Java — JRE. Отказ от использования команд операционной системы и формат XML обеспечивают переносимость сценариев.
Управление процессом сборки происходит посредством XML-сценария, также называемого Build-файлом. В первую очередь этот файл содержит определение проекта, состоящего из отдельных целей (Targets). Цели сравнимы с процедурами в языках программирования и содержат вызовы команд-заданий (Tasks). Каждое задание представляет собой неделимую, атомарную команду, выполняющую некоторое элементарное действие.
Между целями могут быть определены зависимости — каждая цель выполняется только после того, как выполнены все цели, от которых она зависит (если они уже были выполнены ранее, повторного выполнения не производится). Типичными примерами целей являются clean (удаление промежуточных файлов), compile (компиляция всех классов), deploy (развёртывание приложения на сервере).
Скачивание и установка, в случае каких-то неисправностей, ant для Linux выполняется командой вроде sudo apt-get install ant, а для Windows можно перейти на сайте ant.apache.org и скачать архив.
Проверить версию можно командой ant -version
Теперь можно написать простой сценарий HelloWorld

<?xml version="1.0"?>
<project name="HelloWorld" default="hello">
    <target name="hello">
        <echo>Hello, World!</echo>
    </target>
</project>


Затем, нужно создать подкаталог hello и сохранить туда файл с именем build.xml, который содержит сценарий. Далее надо перейти в каталог и вызвать ant. Полный перечень команд:

\begin{lstlisting}[language=C,style=CCodeStyle]
  $ mkdir hello
  $ cd hello
  $ ant
  Buildfile: /home/hello/build.xml

hello:
[echo] Hello, World!
BUILD SUCCESSFULL
\end{lstlisting}


Теперь нужно бы пояснить, что произошло: система сборки нашла файл сценария с указанным по умолчанию именем build и выполнила цель с именем hello, который указан в теге проекта, с помощью атрибута default со значением hello, а также имя проекта, с помощью атрибута name.
В стандартной версии ant присутствует более 100 заданий, такие как: удаление файлов и директорий (delete), компиляция java-кода (javac), вывод сообщений в консоль (echo) и т.д. Вот пример реализации удаления временных файлов, используя задание delete:

\begin{lstlisting}[language=C,style=CCodeStyle]
  <!-- Очистка -->
  <target name="clean" description="Removes all temporary files">
  <!-- Удаление файлов -->
  <delete dir="${build.classes}"/>
  </target>
\end{lstlisting}

На данный момент Ant используют в связке с Ivy, которая является гибким, настраиваемым инструментом для управления (записи, отслеживания, разрешения и отчетности) зависимостями Java проекта.
Некоторые достоинства Ivy:

гибкость и конфигурируемость – Ivy по существу не зависит от процесса и не привязан к какой-либо методологии или структуре;
тесная интеграция с Apache Ant – Ivy доступна как автономный инструмент, однако он особенно хорошо работает с Apache Ant, предоставляя ряд мощных задач от разрешения до создания отчетов и публикации зависимостей;
транзитивность – возможность использовать зависимости других зависимостей.

Немного о функциях Ivy:

управление проектными зависимостями;
отчеты о зависимостях. Ivy производит два основных типа отчетов: отчеты HTML и графические отчеты;
Ivy наиболее часто используется для разрешения зависимостей и копирует их в директории проекта. После копирования зависимостей, сборка больше не зависит от Apache Ivy;
расширяемость. Если настроек по умолчанию недостаточно, вы можете расширить конфигурацию для решения вашей проблемы. Например, вы можете подключить свой собственный репозиторий, свой собственный менеджер конфликтов;
XML-управляемая декларация зависимостей проекта и хранилищ JAR;
настраиваемые определения состояний проекта, которые позволяют определить несколько наборов зависимостей.

Apache Ivy обязана быть сконфигурирована, чтобы выполнять поставленные задачи. Конфигурация задается специальным файлом, в котором содержится информация об организации, модуле, ревизии, имени артефакта и его расширении.
Некоторые модули могут использоваться по разному и эти различные пути использования могут требовать своих, конкретных артефактов для работы программы. Кроме того, модуль может требовать одни зависимости во время компиляции и сборки, и другие во время выполнения.
Конфигурация модуля определяется в Ivy файле в формате .xml, он будет использоваться, чтобы обнаружить все зависимости для дальнейшей загрузки артефактов. Понятие «загрузка» артефакта имеет различные варианты выполнения, в зависимости от расположения артефакта: артефакт может находиться на веб-сайте или в локальной файловой системе вашего компьютера. В целом, загрузкой считается передача файла из хранилища в кеш Ivy.
Пример конфигурации зависимостей с библиотекой Lombok:

<ivy-module version="2.0">
    <info organisation="org.apache" module="hello-ivy"/>
    <dependencies>
         <dependency org="org.projectlombok" name="lombok" rev="1.18.24" conf="build->master"/>
    </dependencies>
</ivy-module>


Его структура довольно проста, первый корневой элемент <ivy-module version="2.0"> указывает на версию Ivy, с которой данный файл совместим. Следующий тег <info organisation="org.apache" module="hello-ivy"/> содержит информацию о программном модуле, для которого указаны зависимости, здесь определяются название организации разработчика и название модуля, хотя можно написать в данный тег что угодно. Наконец, сегмент <dependencies> позволяет определить зависимости. В данной примере модулю необходимо одна сторонняя библиотека: lombok.
Однако, у такой системы, как Ant есть и свои минусы: Ant-файлы могут разрастаться до нескольких десятков мегабайт по мере увеличения проекта. На маленьких проектах выглядит всё достаточно неплохо, но на больших они длинные и неструктурированные, а потому сложны для понимания.
Что привело к появлению новой системы - Maven.


\end{document}