aboutsummaryrefslogtreecommitdiff
path: root/libs/project
diff options
context:
space:
mode:
Diffstat (limited to 'libs/project')
-rwxr-xr-xlibs/project1471
1 files changed, 1471 insertions, 0 deletions
diff --git a/libs/project b/libs/project
new file mode 100755
index 00000000..44de3957
--- /dev/null
+++ b/libs/project
@@ -0,0 +1,1471 @@
+#!/bin/bash
+
+# Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+PROJECT_ACTIONS_GENERIC="usage download extract update build install release clean"
+PROJECT_ACTIONS_HELPERS="arguments"
+PROJECT_FUNCTIONS=$( for action in $PROJECT_ACTIONS_GENERIC ; do echo "$action" "$action""_check" ; done ; echo "$PROJECT_ACTIONS_HELPERS" )
+
+INSTALL_REGEX="\([^:]*\):\(.*\)"
+
+project_include() {
+ local project=$1
+
+ local project_path=$( project_path "$project" )
+
+ unset -f $PROJECT_FUNCTIONS
+
+ . "$project_path/$project"
+
+ project_helper_include "$project"
+}
+
+project_helper_include() {
+ local project=$1
+
+ local project_path=$( project_path "$project" )
+ local include="$project_path/$project-helper"
+
+ if [ -f "$include" ]
+ then
+ . "$include"
+ fi
+}
+
+project_check() {
+ local project=$1
+
+ local project_path=$( project_path "$project" )
+
+ if ! [ -f "$project_path/$project" ]
+ then
+ return 1
+ fi
+
+ return 0
+}
+
+project_function_check() {
+ local project=$1
+ local function=$2
+
+ project_include "$project"
+
+ if ! function_check "$function"
+ then
+ return 1
+ fi
+
+ return 0
+}
+
+project_action() {
+ local action=$1
+ shift
+ local project=$1
+ shift
+ local arguments=$@
+
+ (
+ set +e
+
+ if ! project_check "$project"
+ then
+ printf "Project $project check failed\n" >&2
+ return 1
+ fi
+
+ project_action_check "$action" "$project" "$@"
+
+ if [ $? -eq 0 ]
+ then
+ return 0
+ fi
+
+ project_include "$project"
+
+ if ! function_check "$action"
+ then
+ return 0
+ fi
+
+ printf "Project $project $action (with ${arguments:-no argument})\n" >&2
+
+ (
+ set -e
+ "$action" "$@"
+ )
+
+ if [ $? -ne 0 ]
+ then
+ printf "\nProject $project $action (with ${arguments:-no argument}) failed\n" >&2
+ return 1
+ else
+ printf "\nProject $project $action (with ${arguments:-no argument}) completed\n" >&2
+ fi
+ )
+}
+
+project_action_check() {
+ local action=$1
+ shift
+ local project=$1
+ shift
+
+ (
+ set +e
+
+ if ! project_check "$project"
+ then
+ printf "Project $project check failed\n" >&2
+ return 1
+ fi
+
+ project_include "$project"
+
+ if ! function_check "$action""_check"
+ then
+ return 1
+ fi
+
+ for project_force in $PROJECTS_FORCE
+ do
+ if [ "$project_force" = "$project" ]
+ then
+ return 1
+ fi
+ done
+
+ (
+ set -e
+ "$action""_check" "$@"
+ )
+ )
+}
+
+project_action_helper() {
+ local helper=$1
+ shift
+ local project=$1
+ shift
+
+ (
+ set +e
+
+ if ! project_check "$project"
+ then
+ printf "Project $project check failed\n" >&2
+ return 1
+ fi
+
+ project_include "$project"
+
+ if ! function_check "$helper"
+ then
+ return 0
+ fi
+
+ (
+ set -e
+ "$helper" "$@"
+ )
+ )
+}
+
+project_action_arguments() {
+ local action=$1
+ shift
+ local project=$1
+ shift
+
+ project_action_arguments_verify_recursive "$action" "$project" "$@"
+ project_action_arguments_recursive "$action" "$project" "$@"
+}
+
+project_action_arguments_verify_recursive() {
+ local action=$1
+ shift
+ local project=$1
+ shift
+
+ local action_helper_arguments
+
+ # Store final argument.
+ local argument=${@:$#}
+
+ local test
+
+ if [ $# -gt 1 ]
+ then
+ # Set previous arguments.
+ set "${@:1:$#-1}"
+ elif [ $# -eq 1 ]
+ then
+ shift
+ else
+ return 0
+ fi
+
+ action_helper_arguments=$( project_action_helper "arguments" "$project" "$@" )
+
+ if ! [ -z "$action_helper_arguments" ]
+ then
+ test=$( echo "$action_helper_arguments" | grep -P "^$argument$" || true )
+
+ if [ -z "$test" ]
+ then
+ printf "Invalid argument $argument for project $project action $action\n" >&2
+ return 1
+ fi
+ fi
+
+ project_action_arguments_verify_recursive "$action" "$project" "$@"
+}
+
+project_action_arguments_recursive() {
+ local action=$1
+ shift
+ local project=$1
+ shift
+
+ local action_helper_arguments
+ local argument
+ local ifs_save
+
+ action_helper_arguments=$( project_action_helper "arguments" "$project" "$@" )
+
+ if [ $? -ne 0 ] || [ -z "$action_helper_arguments" ]
+ then
+ project_action "$action" "$project" "$@"
+ else
+ # This it to allow space characters in arguments.
+ ifs_save=$IFS
+ IFS=$'\n'
+
+ for argument in $( echo "$action_helper_arguments" )
+ do
+ (
+ IFS=$ifs_save
+
+ # Only a single argument at a time is returned by the helper.
+ project_action_arguments_recursive "$action" "$project" "$@" "$argument"
+ )
+ done
+
+ IFS=$ifs_save
+ fi
+}
+
+project_action_projects() {
+ local action=$1
+ shift
+ local project=$1
+ shift
+
+ local project_path=$( project_path "$project" )
+ local project_projects_path="$project_path/$CONFIGS/$PROJECTS"
+ local project_projects_action_path="$project_path/$CONFIGS/$PROJECTS-$action"
+ local arguments
+ local path
+
+ if [ -f "$project_projects_action_path" ]
+ then
+ path=$project_projects_action_path
+ else
+ path=$project_projects_path
+ fi
+
+ # Multiple arguments can be read from the file.
+ while read arguments
+ do
+ eval "project_action_arguments "$action" $arguments"
+ done < "$path"
+}
+
+project_path() {
+ local project=$1
+
+ local project_path="$root/$PROJECTS/$project"
+
+ echo "$project_path"
+}
+
+project_sources_path() {
+ local project=$1
+ shift
+ local repository=$1
+ shift
+
+ local sources_path
+ local argument
+ local path
+
+ # Check downloaded and extracted sources first, using "$project."
+ path="$root/$SOURCES/$project"
+
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ path="$path-$argument"
+ fi
+
+ if ! directory_filled_check "$path"
+ then
+ continue
+ fi
+
+ sources_path=$path
+ done
+
+ if ! [ -z "$sources_path" ]
+ then
+ echo "$sources_path"
+ return
+ fi
+
+ # Check downloaded sources then, using "$repository."
+ path="$root/$SOURCES/$repository"
+
+ if directory_filled_check "$path"
+ then
+ echo "$path"
+ return
+ fi
+
+ # Check project sources finally, using "$project."
+ path="$root/$PROJECTS/$project/$SOURCES"
+
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ path="$path/$argument"
+ fi
+
+ if ! directory_filled_check "$path"
+ then
+ continue
+ fi
+
+ sources_path=$path
+ done
+
+ if ! [ -z "$sources_path" ]
+ then
+ echo "$sources_path"
+ return
+ fi
+}
+
+project_sources_directory_filled_check() {
+ local project=$1
+ shift
+
+ local sources_path=$( project_sources_path "$project" "$@" )
+
+ test ! -z "$sources_path"
+}
+
+project_sources_directory_filled_error() {
+ local project=$1
+ shift
+ local arguments=$@
+
+ local sources_path=$( project_sources_path "$project" "$@" )
+
+ if ! [ -z "$sources_path" ]
+ then
+ printf "Sources directory for project $project (with ${arguments:-no argument}) already exists\n" >&2
+ return 1
+ else
+ return 0
+ fi
+}
+
+project_sources_directory_missing_empty_error() {
+ local project=$1
+ shift
+ local arguments=$@
+
+ local sources_path=$( project_sources_path "$project" "$@" )
+
+ if [ -z "$sources_path" ]
+ then
+ printf "Sources directory for project $project (with ${arguments:-no argument}) missing or empty\n" >&2
+ return 1
+ else
+ return 0
+ fi
+}
+
+project_sources_archive() {
+ local project=$1
+ shift
+
+ local sources_archive
+ local argument
+ local path="$root/$SOURCES/$project"
+
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ path="$path-$argument"
+ fi
+
+ local archive="$path.$TAR_XZ"
+
+ if ! [ -f "$archive" ]
+ then
+ continue
+ fi
+
+ sources_archive=$archive
+ done
+
+ if ! [ -z "$sources_archive" ]
+ then
+ echo "$sources_archive"
+ fi
+}
+
+project_sources_archive_extract() {
+ local project=$1
+ shift
+ local arguments=$@
+
+ local archive=$( project_sources_archive "$project" "$@" )
+ local destination=$( dirname "$archive" )
+
+ printf "Extracting source archive for $project (with ${arguments:-no argument})\n"
+
+ file_verification_check "$archive"
+ archive_extract "$archive" "$destination"
+}
+
+project_sources_archive_update() {
+ local project=$1
+ shift
+ local arguments=$@
+
+ local repository=$project
+ local sources_path=$( project_sources_path "$project" "$repository" "$@" )
+ local archive=$( project_sources_archive "$project" "$@" )
+ local destination=$( dirname "$archive" )
+
+ if [ -d "$sources_path" ]
+ then
+ rm -rf "$sources_path"
+ fi
+
+ printf "Extracting source archive for $project (with ${arguments:-no argument})\n"
+
+ file_verification_check "$archive"
+ archive_extract "$archive" "$destination"
+}
+
+project_sources_archive_missing_error() {
+ local project=$1
+ shift
+ local arguments=$@
+
+ local archive=$( project_sources_archive "$project" "$@" )
+ if [ -z "$archive" ] || ! [ -f "$archive" ]
+ then
+ printf "Missing sources archive for $project (with ${arguments:-no argument})\n" >&2
+ return 1
+ else
+ return 0
+ fi
+}
+
+project_sources_archive_missing_check() {
+ local project=$1
+ shift
+
+ local archive=$( project_sources_archive "$project" "$@" )
+ if [ -z "$archive" ] || ! [ -f "$archive" ]
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+project_blobs_path() {
+ local project=$1
+ shift
+
+ local project_path=$( project_path "$project" )
+ local configs_path="$project_path/$CONFIGS"
+ local argument
+ local path
+
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ if [ -z "$path" ]
+ then
+ path="$argument"
+ else
+ path="$path/$argument"
+ fi
+ fi
+
+ local blobs_path="$configs_path/$path/$BLOBS"
+
+ if [ -f "$blobs_path" ]
+ then
+ echo "$blobs_path"
+ return
+ fi
+ done
+}
+
+project_blobs_ignore_path() {
+ local project=$1
+ shift
+
+ local project_path=$( project_path "$project" )
+ local configs_path="$project_path/$CONFIGS"
+ local argument
+ local path
+
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ if [ -z "$path" ]
+ then
+ path="$argument"
+ else
+ path="$path/$argument"
+ fi
+ fi
+
+ blobs_ignore_path="$configs_path/$path/$BLOBS_IGNORE"
+
+ if [ -f "$blobs_ignore_path" ]
+ then
+ echo "$blobs_ignore_path"
+ return
+ fi
+ done
+}
+
+project_arguments_targets() {
+ local project=$1
+ shift
+
+ local project_path=$( project_path "$project" )
+ local targets_path="$project_path/$CONFIGS"
+ local argument
+
+ for argument in "$@"
+ do
+ targets_path="$targets_path/$argument"
+ done
+
+ targets_path="$targets_path/$TARGETS"
+
+ if [ -f "$targets_path" ]
+ then
+ cat "$targets_path"
+ fi
+}
+
+project_usage_actions() {
+ local project=$1
+ shift
+
+ printf "\nGeneric actions:\n"
+
+ for action in $PROJECT_ACTIONS_GENERIC
+ do
+ if function_check "$action"
+ then
+ printf " $action\n"
+ fi
+ done
+
+ if [ $# -gt 0 ]
+ then
+ printf "\nSpecific actions:\n"
+
+ for action in "$@"
+ do
+ printf " $action\n"
+ done
+ fi
+}
+
+project_usage_arguments() {
+ local project=$1
+ shift
+
+ printf "\nArguments:\n"
+
+ project_usage_arguments_recursive "$project" " " "$@"
+}
+
+project_usage_arguments_recursive() {
+ local project=$1
+ shift
+ local spacing=$1
+ shift
+
+ local action_helper_arguments
+ local argument
+
+ action_helper_arguments=$( project_action_helper "arguments" "$project" "$@" )
+
+ if ! [ -z "$action_helper_arguments" ]
+ then
+ echo "$action_helper_arguments" | while read argument
+ do
+ printf "$spacing$argument\n"
+ project_usage_arguments_recursive "$project" " $spacing" "$@" "$argument"
+ done
+ fi
+}
+
+project_download_git() {
+ local project=$1
+ shift
+ local repository=$1
+ shift
+ local urls=$1
+ shift
+
+ requirements "git"
+
+ if ! git_project_check "$repository"
+ then
+ project_sources_directory_filled_error "$project" "$repository" "$@"
+
+ git_project_clone "$repository" "$urls"
+ fi
+
+ git_project_prepare "$project" "$repository" "$@"
+}
+
+project_download_check_git() {
+ local project=$1
+ shift
+ local repository=$1
+ shift
+
+ requirements "git"
+
+ git_project_check "$repository"
+ git_project_prepare_check "$project" "$repository" "$@"
+}
+
+project_extract() {
+ local project=$1
+ shift
+
+ local repository=$project
+
+ if ! project_sources_directory_filled_check "$project" "$repository" "$@"
+ then
+ project_sources_archive_missing_error "$project" "$@"
+ project_sources_archive_extract "$project" "$@"
+ fi
+}
+
+project_extract_check() {
+ local project=$1
+ shift
+
+ local repository=$project
+
+ project_sources_directory_filled_check "$project" "$repository" "$@"
+}
+
+project_update_git() {
+ local project=$1
+ shift
+ local repository=$1
+ shift
+
+ requirements "git"
+
+ project_sources_directory_missing_empty_error "$project" "$repository" "$@"
+
+ if git_project_check "$repository"
+ then
+ git_project_update "$project" "$repository" "$@"
+ else
+ if ! project_sources_archive_missing_check "$project" "$@"
+ then
+ project_sources_archive_update "$project" "$@"
+ fi
+ fi
+}
+
+project_update_check_git() {
+ local project=$1
+ shift
+ local repository=$1
+ shift
+
+ requirements "git"
+
+ if git_project_check "$repository"
+ then
+ # Git repository should always be updated (even if upstream didn't progress).
+ # For instance, this is useful for testing new versions of patches without changing revision.
+ return 1
+ else
+ project_sources_archive_missing_check "$project" "$@"
+ fi
+}
+
+project_build_check() {
+ local project=$1
+ shift
+
+ local project_path=$( project_path "$project" )
+ local build_path=$( project_build_path "$project" "$@" )
+ local source_file_path
+ local argument
+ local rule
+ local path
+
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ if [ -z "$path" ]
+ then
+ path="$argument"
+ else
+ path="$path/$argument"
+ fi
+ fi
+
+ configs_install_path="$project_path/$CONFIGS/$path/$INSTALL"
+
+ if ! [ -f "$configs_install_path" ]
+ then
+ continue
+ fi
+
+ while read rule
+ do
+ source=$( echo "$rule" | sed "s/$INSTALL_REGEX/\1/g" )
+ source_path="$build_path/$source"
+
+ # Source may contain a wildcard.
+ path_wildcard_expand "$source_path" | while read source_file_path
+ do
+ if ! [ -f "$source_file_path" ] && ! [ -d "$source_file_path" ]
+ then
+ false
+ fi
+ done
+ done < "$configs_install_path"
+ done
+}
+
+project_build_path() {
+ local project=$1
+ shift
+
+ local build_path="$root/$BUILD/$project"
+ local argument
+
+ for argument in "$@"
+ do
+ build_path="$build_path-$argument"
+ done
+
+ echo "$build_path"
+}
+
+project_build_directory_missing_empty_error() {
+ local project=$1
+ shift
+ local arguments=$@
+
+ local build_path=$( project_build_path "$project" "$@" )
+
+ if ! directory_filled_check "$build_path"
+ then
+ printf "Build directory for project $project (with ${arguments:-no argument}) missing or empty\n" >&2
+ return 1
+ else
+ return 0
+ fi
+}
+
+project_install() {
+ local project=$1
+ shift
+
+ local project_path=$( project_path "$project" )
+ local build_path=$( project_build_path "$project" "$@" )
+ local install_path=$( project_install_path "$project" "$@" )
+ local source_file_path
+ local argument
+ local rule
+ local path
+
+ # Install built files first.
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ if [ -z "$path" ]
+ then
+ path="$argument"
+ else
+ path="$path/$argument"
+ fi
+ fi
+
+ configs_install_path="$project_path/$CONFIGS/$path/$INSTALL"
+
+ if ! [ -f "$configs_install_path" ]
+ then
+ continue
+ fi
+
+ project_build_directory_missing_empty_error "$project" "$@"
+
+ while read rule
+ do
+ source=$( echo "$rule" | sed "s/$INSTALL_REGEX/\1/g" )
+ source_path="$build_path/$source"
+
+ destination=$( echo "$rule" | sed "s/$INSTALL_REGEX/\2/g" )
+ destination_path="$install_path/$destination"
+ destination_directory_path=$( dirname "$destination_path" )
+
+ mkdir -p "$destination_directory_path"
+
+ # Source may contain a wildcard.
+ path_wildcard_expand "$source_path" | while read source_file_path
+ do
+ cp -rT "$source_file_path" "$destination_path"
+ done
+ done < "$configs_install_path"
+ done
+
+ path=""
+
+ # Install install files then.
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ if [ -z "$path" ]
+ then
+ path="$argument"
+ else
+ path="$path/$argument"
+ fi
+ fi
+
+ install_install_path="$project_path/$INSTALL/$path/$INSTALL"
+
+ if ! [ -f "$install_install_path" ]
+ then
+ continue
+ fi
+
+ while read rule
+ do
+ source=$( echo "$rule" | sed "s/$INSTALL_REGEX/\1/g" )
+ source_path="$project_path/$INSTALL/$path/$source"
+
+ destination=$( echo "$rule" | sed "s/$INSTALL_REGEX/\2/g" )
+ destination_path="$install_path/$destination"
+ destination_directory_path=$( dirname "$destination_path" )
+
+ mkdir -p "$destination_directory_path"
+
+ # Source may contain a wildcard.
+ path_wildcard_expand "$source_path" | while read source_file_path
+ do
+ cp -rT "$source_file_path" "$destination_path"
+ done
+ done < "$install_install_path"
+ done
+}
+
+project_install_check() {
+ local project=$1
+ shift
+
+ local project_path=$( project_path "$project" )
+ local build_path=$( project_build_path "$project" "$@" )
+ local install_path=$( project_install_path "$project" "$@" )
+ local argument
+ local rule
+ local path
+
+ # Install built files first.
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ if [ -z "$path" ]
+ then
+ path="$argument"
+ else
+ path="$path/$argument"
+ fi
+ fi
+
+ configs_install_path="$project_path/$CONFIGS/$path/$INSTALL"
+
+ if ! [ -f "$configs_install_path" ]
+ then
+ continue
+ fi
+
+ project_build_directory_missing_empty_error "$project" "$@"
+
+ while read rule
+ do
+ destination=$( echo "$rule" | sed "s/$INSTALL_REGEX/\2/g" )
+ destination_path="$install_path/$destination"
+
+ if ! [ -f "$destination_path" ] && ! [ -d "$destination_path" ]
+ then
+ false
+ fi
+ done < "$configs_install_path"
+ done
+
+ path=""
+
+ # Install install files then.
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ if [ -z "$path" ]
+ then
+ path="$argument"
+ else
+ path="$path/$argument"
+ fi
+ fi
+
+ install_install_path="$project_path/$INSTALL/$path/$INSTALL"
+
+ if ! [ -f "$install_install_path" ]
+ then
+ continue
+ fi
+
+ while read rule
+ do
+ destination=$( echo "$rule" | sed "s/$INSTALL_REGEX/\2/g" )
+ destination_path="$install_path/$destination"
+
+ if ! [ -f "$destination_path" ] && ! [ -d "$destination_path" ]
+ then
+ false
+ fi
+ done < "$install_install_path"
+ done
+}
+
+project_install_path() {
+ local project=$1
+ shift
+
+ local install_path="$root/$INSTALL/$project"
+ local argument
+
+ for argument in "$@"
+ do
+ install_path="$install_path-$argument"
+ done
+
+ echo "$install_path"
+}
+
+project_install_directory_missing_empty_error() {
+ local project=$1
+ shift
+ local arguments=$@
+
+ local install_path=$( project_install_path "$project" "$@" )
+
+ if ! directory_filled_check "$install_path"
+ then
+ printf "Install directory for project $project (with ${arguments:-no argument}) missing or empty\n" >&2
+ return 1
+ else
+ return 0
+ fi
+}
+
+project_release_path() {
+ local project=$1
+ shift
+ local prefix=$1
+
+ local release_path="$root/$RELEASE/$prefix"
+
+ # Special care for tools and systems, that depend on the host arch.
+ if [ "$prefix" = "$SYSTEMS" ] || [ "$prefix" = "$TOOLS" ]
+ then
+ local machine=$( uname -m )
+
+ release_path="$release_path/$machine/$project"
+ else
+ release_path="$release_path/$project"
+ fi
+
+ echo "$release_path"
+}
+
+project_release_archive_path() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+
+ local release_path=$( project_release_path "$project" "$prefix" )
+ local argument
+ local path="$project"
+
+ for argument in "$@"
+ do
+ path="$path-$argument"
+ done
+
+ local archive_path="$release_path/$path.$TAR_XZ"
+
+ echo "$archive_path"
+}
+
+project_release_rootfs_path() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+
+ local release_path=$( project_release_path "$project" "$prefix" )
+ local argument
+ local path="$project"
+
+ for argument in "$@"
+ do
+ path="$path-$argument"
+ done
+
+ local rootfs_path="$release_path/$path.$TAR_XZ"
+
+ echo "$rootfs_path"
+}
+
+project_release_sources_archive_path() {
+ local project=$1
+ shift
+
+ local sources_path="$root/$SOURCES/"
+ local release_path
+ local argument
+ local path="$project"
+
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ path="$path-$argument"
+ fi
+
+ local directory_path="$sources_path/$path"
+
+ if ! directory_filled_check "$directory_path"
+ then
+ continue
+ fi
+
+ release_path=$path
+ done
+
+ if ! [ -z "$release_path" ]
+ then
+ local archive_path="$root/$RELEASE/$SOURCES/$project/$release_path.$TAR_XZ"
+
+ echo "$archive_path"
+ fi
+}
+
+project_release_sources_archive_create() {
+ local project=$1
+ shift
+ local arguments=$@
+
+ local repository=$project
+ local archive_path=$( project_release_sources_archive_path "$project" "$@" )
+ local sources_path=$( project_sources_path "$project" "$repository" "$@" )
+
+ printf "Releasing sources archive for $project (with ${arguments:-no argument})\n"
+
+ archive_create "$archive_path" "$sources_path"
+ file_verification_create "$archive_path"
+}
+
+project_release_sources_archive_exists_check() {
+ local project=$1
+ shift
+
+ local archive_path=$( project_release_sources_archive_path "$project" "$@" )
+ if [ -z "$archive_path" ] || ! [ -f "$archive_path" ]
+ then
+ return 1
+ else
+ return 0
+ fi
+}
+
+project_release_sources_git() {
+ local project=$1
+ shift
+ local repository=$1
+ shift
+
+ requirements "git"
+
+ project_sources_directory_missing_empty_error "$project" "$repository" "$@"
+
+ if git_project_check "$repository"
+ then
+ if ! git_project_release_check "$project" "$repository" "$@"
+ then
+ git_project_release "$project" "$repository" "$@"
+ fi
+ else
+ if ! project_release_sources_archive_exists_check "$project" "$@"
+ then
+ project_release_sources_archive_create "$project" "$@"
+ fi
+ fi
+}
+
+project_release_check_sources_git() {
+ local project=$1
+ shift
+ local repository=$1
+ shift
+
+ requirements "git"
+
+ if git_project_check "$repository"
+ then
+ git_project_release_check "$project" "$repository" "$@"
+ else
+ project_release_sources_archive_exists_check "$project" "$@"
+ fi
+}
+
+project_release_install() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+
+ local install_path=$( project_install_path "$project" "$@" )
+ local release_path=$( project_release_path "$project" "$prefix" )
+ local directory_path
+ local path
+
+ project_install_directory_missing_empty_error "$project" "$@"
+
+ local files=$( cd "$install_path" && find -type f || true )
+ local file
+
+ echo "$files" | while read file
+ do
+ path="$release_path/$file"
+ directory_path=$( dirname "$path" )
+
+ mkdir -p "$directory_path"
+
+ cp "$install_path/$file" "$path"
+ file_verification_create "$path"
+ done
+}
+
+project_release_install_check() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+
+ local install_path=$( project_install_path "$project" "$@" )
+ local release_path=$( project_release_path "$project" "$prefix" )
+ local path
+
+ project_install_directory_missing_empty_error "$project" "$@"
+
+ local files=$( cd "$install_path" && find -type f || true )
+ local file
+
+ echo "$files" | while read file
+ do
+ path="$release_path/$file"
+
+ file_exists_check "$path"
+ done
+}
+
+project_release_install_archive() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+
+ project_install_directory_missing_empty_error "$project" "$@"
+
+ if ! project_release_install_archive_exists_check "$project" "$prefix" "$@"
+ then
+ project_release_install_archive_create "$project" "$prefix" "$@"
+ fi
+}
+
+project_release_install_archive_check() {
+ local project=$1
+ shift
+
+ project_release_install_archive_exists_check "$project" "$@"
+}
+
+project_release_install_archive_create() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+ local arguments=$@
+
+ local install_path=$( project_install_path "$project" "$@" )
+ local archive_path=$( project_release_archive_path "$project" "$prefix" "$@" )
+
+ printf "Releasing $prefix archive for $project (with ${arguments:-no argument})\n"
+
+ archive_create "$archive_path" "$install_path"
+ file_verification_create "$archive_path"
+}
+
+project_release_install_archive_exists_check() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+
+ local archive_path=$( project_release_archive_path "$project" "$prefix" "$@" )
+
+ file_exists_check "$archive_path"
+}
+
+project_release_install_rootfs() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+
+ project_install_directory_missing_empty_error "$project" "$@"
+
+ if ! project_release_install_rootfs_exists_check "$project" "$prefix" "$@"
+ then
+ project_release_install_rootfs_create "$project" "$prefix" "$@"
+ fi
+}
+
+project_release_install_rootfs_check() {
+ local project=$1
+ shift
+
+ project_release_install_rootfs_exists_check "$project" "$@"
+}
+
+project_release_install_rootfs_create() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+ local arguments=$@
+
+ local install_path=$( project_install_path "$project" "$@" )
+ local rootfs_path=$( project_release_rootfs_path "$project" "$prefix" "$@" )
+
+ printf "Releasing $prefix rootfs for $project (with ${arguments:-no argument})\n"
+
+ rootfs_create "$rootfs_path" "$install_path"
+ file_verification_create "$rootfs_path"
+}
+
+project_release_install_rootfs_exists_check() {
+ local project=$1
+ shift
+ local prefix=$1
+ shift
+
+ local rootfs_path=$( project_release_rootfs_path "$project" "$prefix" "$@" )
+
+ file_exists_check "$rootfs_path"
+}
+
+project_clean() {
+ local project=$1
+ shift
+
+ project_clean_build "$project" "$@"
+ project_clean_install "$project" "$@"
+ project_clean_release "$project" "$@"
+}
+
+project_clean_build() {
+ local project=$1
+ shift
+
+ local build_path=$( project_build_path "$project" "$@" )
+
+ rm -rf "$build_path"
+}
+
+project_clean_install() {
+ local project=$1
+ shift
+
+ local install_path=$( project_install_path "$project" "$@" )
+
+ rm -rf "$install_path"
+}
+
+project_clean_release() {
+ local project=$1
+ shift
+
+ local prefix
+
+ for prefix in "$SOURCES" "$SYSTEMS" "$IMAGES" "$TOOLS" "$DOCS"
+ do
+ local release_path=$( project_release_path "$project" "$prefix" )
+
+ rm -rf "$release_path"
+ done
+}
+
+project_clean_rootfs() {
+ local project=$1
+ shift
+
+ project_clean_build "$project" "$@"
+ project_clean_rootfs_install "$project" "$@"
+ project_clean_release "$project" "$@"
+
+}
+
+project_clean_rootfs_install() {
+ local project=$1
+ shift
+
+ local install_path=$( project_install_path "$project" "$@" )
+
+ execute_root rm -rf "$install_path"
+
+}
+
+project_file_path() {
+ local project=$1
+ shift
+ local directory=$1
+ shift
+ local file=$1
+ shift
+
+ local project_path=$( project_path "$project" )
+ local path="$project_path/$directory"
+ local argument
+ local file_path
+
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ path="$path/$argument"
+ fi
+
+ if ! [ -f "$path/$file" ]
+ then
+ continue
+ fi
+
+ file_path="$path/$file"
+ done
+
+ if [ -z "$file_path" ]
+ then
+ return 1
+ fi
+
+ echo "$file_path"
+}
+
+project_file_test() {
+ local file_path=$( project_file_path "$@" )
+
+ test -f "$file_path"
+}
+
+project_file_contents() {
+ local file_path=$( project_file_path "$@" )
+
+ cat "$file_path"
+}
+
+project_file_contents_herit() {
+ local project=$1
+ shift
+ local directory=$1
+ shift
+ local file=$1
+ shift
+
+ local project_path=$( project_path "$project" )
+ local path="$project_path/$directory"
+ local argument
+ local file_path
+
+ for argument in "" "$@"
+ do
+ if ! [ -z "$argument" ]
+ then
+ path="$path/$argument"
+ fi
+
+ file_path="$path/$file"
+
+ if ! [ -f "$file_path" ]
+ then
+ continue
+ fi
+
+ cat "$file_path"
+ done
+}