#!/bin/bash # Copyright (C) 2016 Paul Kocialkowski # # 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 . DOTGIT=".git" HEAD="HEAD" ORIGIN_HEAD="origin/HEAD" WILDDOTPATCH="*.patch" GIT_NAME="Libreboot" GIT_EMAIL="libreboot@libreboot.org" git_check() { local repository_path=$1 directory_filled_check "$repository_path/$DOTGIT" } git_clone() { local repository_path=$1 local url=$2 git clone "$url" "$repository_path" } git_submodule_update() { local repository_path=$1 ( cd "$repository_path" git submodule update --init ) } git_merge() { local repository_path=$1 local revision=$2 ( cd "$repository_path" git merge "$revision" ) } git_branch_create() { local repository_path=$1 local branch=$2 local revision=$3 ( cd "$repository_path" git checkout -B "$branch" if ! [ -z "$revision" ] then git reset --hard "$revision" fi ) } git_branch_delete() { local repository_path=$1 local branch=$2 ( cd "$repository_path" git branch -D "$branch" ) } git_branch_checkout() { local repository_path=$1 local branch=$2 ( cd "$repository_path" git checkout "$branch" > /dev/null ) } git_branch_check() { local repository_path=$1 local branch=$2 ( cd "$repository_path" 2> /dev/null > /dev/null if [ $? -ne 0 ] then return 1 fi git rev-parse --verify "$branch" 2> /dev/null > /dev/null if [ $? -ne 0 ] then return 1 fi ) } git_fetch() { local repository_path=$1 ( cd "$repository_path" git fetch origin ) } git_fetch_check() { local repository_path=$1 ( cd "$repository_path" 2> /dev/null > /dev/null if [ $? -ne 0 ] then return 1 fi local output=$( git fetch --dry-run origin 2>&1 ) if ! [ -z "$output" ] then return 1 fi ) } git_clean() { local repository_path=$1 ( cd "$repository_path" git clean -df ) } git_remove() { local repository_path=$1 local path=$2 ( cd "$repository_path" git rm -rf "$path" ) } git_commit() { local repository_path=$1 local message=$2 ( export GIT_COMMITTER_NAME=$GIT_NAME export GIT_COMMITTER_EMAIL=$GIT_EMAIL cd "$repository_path" git commit --author="$GIT_NAME <$GIT_EMAIL>" -m "$message" ) } git_patch() { local repository_path=$1 local branch=$2 local patch=$3 ( export GIT_COMMITTER_NAME=$GIT_NAME export GIT_COMMITTER_EMAIL=$GIT_EMAIL cd "$repository_path" git checkout "$branch" 2> /dev/null > /dev/null git am "$patch" ) } git_revision() { local repository_path=$1 ( cd "$repository_path" git rev-parse "$HEAD" ) } git_describe() { local repository_path=$1 ( cd "$repository_path" git describe --tags ) } git_files() { local repository_path="$1" ( cd "${repository_path}" # Reproducible sorting. git ls-files -z | env LC_ALL='C.UTF-8' sort -z ) } git_project_repository_path() { local repository=$1 printf '%s\n' "$root/$SOURCES/$repository" } git_project_check() { local repository=$1 local repository_path=$( git_project_repository_path "$repository" ) git_check "$repository_path" } git_project_patch_recursive() { local project="$1" local repository="$2" local branch="$3" local path="${4:-.}" local repository_path="$(git_project_repository_path "${repository}")" local project_path="$(project_path "${project}")" local patches_path="${project_path}/${PATCHES}/${path}" if ! [[ -d "${patches_path}" ]]; then return fi if [[ "${path}" != "." ]]; then git_project_patch_recursive "${project}" "${repository}" "${branch}" "$(dirname "${path}")" fi for patch in "${patches_path}"/[!.]*.{patch,diff}; do if [[ "${patch##*.}" == "patch" ]]; then git_patch "${repository_path}" "${branch}" "${patch}" else diff_patch_file "${repository_path}" "${patch}" fi done } git_project_clone() { local repository=$1 shift local urls=$@ local repository_path=$( git_project_repository_path "$repository" ) local directory_path=$( dirname "$repository_path" ) local url mkdir -p "$directory_path" ( set +e for url in $urls do git_clone "$repository_path" "$url" if [ $? -eq 0 ] then return 0 fi done return 1 ) } git_project_prepare() { local project=$1 shift local repository=$1 shift git_project_prepare_revision "$project" "$repository" "$@" git_project_prepare_blobs "$project" "$repository" "$@" git_project_prepare_patch "$project" "$repository" "$@" } git_project_prepare_blobs() { local project=$1 shift local repository=$1 shift local repository_path=$( git_project_repository_path "$repository" ) local blobs_path=$( project_blobs_path "$project" "$@" ) local blob if ! [ -f "$blobs_path" ] then return fi while read blob do git_remove "$repository_path" "$blob" done < "$blobs_path" git_commit "$repository_path" "Removed blobs" } git_project_prepare_patch() { local project=$1 shift local repository=$1 shift local project_path=$( project_path "$project" ) local configs_path="$project_path/$CONFIGS" local prepare_branch local prepare_path local branch=$project local argument local path for argument in "" "$@" do if ! [ -z "$argument" ] then if [ -z "$path" ] then path="$argument" else path="$path/$argument" fi branch="$branch-$argument" fi local revision_path="$configs_path/$path/$REVISION" if ! [ -f "$revision_path" ] then continue fi prepare_branch=$branch prepare_path=$path done if ! [ -z "$prepare_branch" ] then git_project_patch_recursive "$project" "$repository" "$prepare_branch" "$prepare_path" fi } git_project_prepare_revision() { local project=$1 shift local repository=$1 shift local repository_path=$( git_project_repository_path "$repository" ) local project_path=$( project_path "$project" ) local configs_path="$project_path/$CONFIGS" local prepare_branch local prepare_revision local branch=$project local argument local path for argument in "" "$@" do if ! [ -z "$argument" ] then if [ -z "$path" ] then path="$argument" else path="$path/$argument" fi branch="$branch-$argument" fi local revision_path="$configs_path/$path/$REVISION" if ! [ -f "$revision_path" ] then continue fi prepare_branch=$branch prepare_revision=$( cat "$revision_path" ) done if ! [ -z "$prepare_branch" ] then git_branch_create "$repository_path" "$prepare_branch" "$prepare_revision" fi } git_project_prepare_check() { local project=$1 shift local repository=$1 shift local repository_path=$( git_project_repository_path "$repository" ) local project_path=$( project_path "$project" ) local configs_path="$project_path/$CONFIGS" local prepare_branch local branch=$project local argument local path for argument in "" "$@" do if ! [ -z "$argument" ] then if [ -z "$path" ] then path="$argument" else path="$path/$argument" fi branch="$branch-$argument" fi local revision_path="$configs_path/$path/$REVISION" if ! [ -f "$revision_path" ] then continue fi prepare_branch=$branch done if ! [ -z "$prepare_branch" ] then git_branch_check "$repository_path" "$prepare_branch" fi } git_project_prepare_clean() { local project=$1 shift local repository=$1 shift local repository_path=$( git_project_repository_path "$repository" ) local prepare_branch local branch=$project local argument for argument in "" "$@" do if ! [ -z "$argument" ] then branch="$branch-$argument" fi if ! git_branch_check "$repository_path" "$branch" then continue fi prepare_branch=$branch done if ! [ -z "$prepare_branch" ] then # Let's not worry about missing branches. ( set +e git_branch_delete "$repository_path" "$prepare_branch" if [ $? -ne 0 ] then return 0 fi ) fi } git_project_checkout() { local project=$1 shift local repository=$1 shift local repository_path=$( git_project_repository_path "$repository" ) local checkout_branch local branch=$project local argument for argument in "" "$@" do if ! [ -z "$argument" ] then branch="$branch-$argument" fi if ! git_branch_check "$repository_path" "$branch" then continue fi checkout_branch=$branch done if ! [ -z "$checkout_branch" ] then git_branch_checkout "$repository_path" "$checkout_branch" git_submodule_update "$repository_path" fi } git_project_update() { local project=$1 shift local repository=$1 shift local repository_path=$( git_project_repository_path "$repository" ) git_fetch "$repository_path" git_branch_checkout "$repository_path" "$ORIGIN_HEAD" git_project_prepare_clean "$project" "$repository" "$@" git_project_prepare "$project" "$repository" "$@" } git_project_update_check() { local project=$1 shift local repository=$1 shift git_project_prepare_check "$project" "$repository" "$@" git_fetch_check "$repository_path" } git_project_release() { local project=$1 shift local repository=$1 shift local arguments=$@ local repository_path=$( git_project_repository_path "$repository" ) local release_branch local branch=$project local argument for argument in "" "$@" do if ! [ -z "$argument" ] then branch="$branch-$argument" fi if ! git_branch_check "$repository_path" "$branch" then continue fi release_branch=$branch done if ! [ -z "$release_branch" ] then local archive_path="$root/$RELEASE/$SOURCES/$project/$release_branch.$TAR_XZ" local sources_path="$root/$SOURCES/$repository" printf '%s\n' "Releasing sources archive for $project (with ${arguments:-no argument}) from "$repository" git" git_branch_checkout "$repository_path" "$release_branch" git_submodule_update "$repository_path" git_clean "$repository_path" archive_create "$archive_path" "$sources_path" "$release_branch" file_verification_create "$archive_path" fi } git_project_release_check() { local project=$1 shift local repository=$1 shift local repository_path=$( git_project_repository_path "$repository" ) local release_branch local branch=$project local argument for argument in "" "$@" do if ! [ -z "$argument" ] then branch="$branch-$argument" fi if ! git_branch_check "$repository_path" "$branch" then continue fi release_branch=$branch done if ! [ -z "$release_branch" ] then local archive_path="$root/$RELEASE/$SOURCES/$project/$release_branch.$TAR_XZ" file_exists_check "$archive_path" if [ $? -ne 0 ] then return 1 else return 0 fi fi }