#!/usr/bin/env 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 [[ -n "$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 [[ -n "$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 [[ -n "$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 [[ -n "$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 [[ -n "$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 [[ -n "$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 [[ -n "$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 [[ -n "$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 [[ -n "$argument" ]] then branch="$branch-$argument" fi if ! git_branch_check "$repository_path" "$branch" then continue fi prepare_branch=$branch done if [[ -n "$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 [[ -n "$argument" ]] then branch="$branch-$argument" fi if ! git_branch_check "$repository_path" "$branch" then continue fi checkout_branch=$branch done if [[ -n "$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 [[ -n "$argument" ]] then branch="$branch-$argument" fi if ! git_branch_check "$repository_path" "$branch" then continue fi release_branch=$branch done if [[ -n "$release_branch" ]] then local archive_path="$root/$RELEASE/$SOURCES/$project/$release_branch.$ARCHIVE" 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 [[ -n "$argument" ]] then branch="$branch-$argument" fi if ! git_branch_check "$repository_path" "$branch" then continue fi release_branch=$branch done if [[ -n "$release_branch" ]] then local archive_path="$root/$RELEASE/$SOURCES/$project/$release_branch.$ARCHIVE" file_exists_check "$archive_path" if [[ $? -ne 0 ]] then return 1 else return 0 fi fi }