Actually getting started
------------------------

Start building a new releng-tool project by creating the following root and
package folders for a project, and venture into the root folder:

.. code-block:: shell

    mkdir -p <my-project>/package
    cd <my-project>/

Inside the root folder, create a releng-tool configuration file ``releng`` with
the following skeleton content:

.. code-block:: python

   #!/usr/bin/env python
   # -*- coding: utf-8 -*-

   packages = [
   ]

This configuration defines a releng-tool project with no packages. Start to
change this by adding a package or more for each a module to be built. For
example, packages can be individual static libraries, simple asset fetching
(e.g. image/document downloading) and more.

For each package, create a new folder inside ``<my-project>/package`` to
represent the package.

.. code-block:: shell

    mkdir <my-project>/package/<my-package>

Inside each newly created package, create a package definition file. This
(Python-based) file will be named with the same name as the package folder (i.e.
``<my-project>/package/<my-package>/<my-package>``). An initial skeleton
structure for the definition file is as follows:

.. code-block:: python

   #!/usr/bin/env python
   # -*- coding: utf-8 -*-

   MY_PACKAGE_DEPENDENCIES=[]
   MY_PACKAGE_LICENSE=['<license name>']
   MY_PACKAGE_LICENSE_FILES=['<license file>']
   MY_PACKAGE_SITE='<location for sources>'
   MY_PACKAGE_TYPE='<package-type>'
   MY_PACKAGE_VERSION='<package-version>'

Initial changes to note:

- For a package, any support package variable requires the package name as a
  prefix. The prefix should be a underscore-separated all-uppercase string
  value. In the above example, if the package name was ``my-package``, the
  prefix will be ``MY_PACKAGE_``.
- One of the most important options is the version option
  (``MY_PACKAGE_VERSION``). This value is used to help manage downloaded asset
  names, build output directories and sometimes even revision values for
  source-fetching. An example of a good version value is '1.0'; however, the
  value can vary depending on the package being defined.
- The site value (``MY_PACKAGE_SITE``) is used to identify where source/assets
  can be fetched from. A site can be a Git repository, a URL, SCP location, a
  site value supported by a custom fetch extension or more.
- A helpful configuration option is the dependency list
  (``MY_PACKAGE_DEPENDENCIES``). If a package depends on another package being
  built, the name of the package should be listed in this option. This ensures
  that releng-tool will invoke package stages in the appropriate order.
- While not required, it is recommended to provide license tracking for packages
  when possible. ``MY_PACKAGE_LICENSE`` and ``MY_PACKAGE_LICENSE_FILES`` are
  list values to define the list of licenses applicable to this package and the
  location of the respective license files found in the sources. A developer can
  exclude these options if desired. If a developer does provide these options,
  the end of the build process will compile a document of used licenses for the
  project.
- The type of package (``MY_PACKAGE_TYPE``) can be used to take advantage of
  various package types supported by releng-tool. By default, packages are
  script-based, where Python scripts inside the packages are invoked during each
  stage (e.g. ``<my-project>/package/build`` would be invoked during the build
  phase). releng-tool also supports other package types such as autotools, CMake
  and more to limit the need to define custom scripts for common build steps.
  Developers can also use package types defined by included extensions (if any).

A detailed list of options can be found in `common package configurations`_ and
`advanced package configurations`_.

Once all packages have been prepared with desired package definitions options,
the root configuration script (``releng``) should be updated to indicate which
packages should be built. All packages can be defined in the ``packages`` list
if desired. For example, if a project has packages ``liba``, ``libb`` and
``programc``, the following package list can be defined:

.. code-block:: python

   packages = [
       'liba',
       'libb',
       'programc',
   ]

Note that a developer does not need to explicitly add each component if
dependencies are configured. Considering the same packages listed above, if
``programc`` depends on both ``liba`` and ``libb`` packages, only ``programc``
needs to be explicitly listed:

.. code-block:: python

   packages = [
       'programc',
   ]

When processing, both ``liba`` and ``libb`` packages will be implicitly loaded
and processed like any other package.

Once all the project's packages are ready, a developer can try their luck by
attempting to perform a build:

.. code-block:: shell

    releng-tool

A developer may not have luck on the first go. Tweaks may be needed on the
package definitions, custom scripts (if used) and issues found in sources. A
developer may invoke ``releng-tool`` multiple times to attempt to continue the
build process for a project. A developer may wish to use the ``clean`` option to
remove an existing extracted sources/partially built sources:

.. code-block:: shell

    releng-tool clean

Or start from a completely fresh state using ``mrproper`` to remove any built
images and file mode flags:

.. code-block:: shell

    releng-tool mrproper

There may also be times if a single project needs to be cleaned:

.. code-block:: shell

    releng-tool my-package-clean

Consult the :doc:`user's guide <user-guide>` for more action information.

Eventually the project should be in a good state that each package is being
built as expected. Now a user can decide on what to do with the resulting files.
After the invoke of a releng-tool process, it is typical for final binaries,
public includes, etc. to be found inside the ``<root>/output/target`` directory.
If a developer only desires to manually take the assets from this folder and
distribute/store them, no additional steps are required. However, it may be
common that a developer wants to package some assets (whether it be a
tar/zip/etc. container, pkg/rpm/etc. package or more). A developer could deal
with such a capability outside the releng-tool process; but if a developer
wishes to hook the end of the process, a post-processing script can be used.

A developer may create a post-processing file ``releng-post-build`` in the root
directory. On the completion of processing each package, the post-processing
script will be invoked. It is important to note that the post-processing script
may be invoked multiple times if a user attempts to rebuild the project. For
example, if the file ``releng-post-build`` has the following contents:

.. code-block:: python

   #!/usr/bin/env python
   # -*- coding: utf-8 -*-

   print('project target directory: {}'.format(TARGET_DIR))

The target directory will be output to standard out at the end of the build. A
developer may wish to define their own Python script to decide on how to package
the contents found in ``TARGET_DIR`` (see also `script helpers`_ for helper
variables/functions).
