aboutsummaryrefslogblamecommitdiff
path: root/libs/git
blob: 1ca2358e222add6e7862e813ed6e2f4da8c0e59b (plain) (tree)
1
                   




























































                                                                       
                                         
 
                                       






























                                                              
                                 



                                                                         
                                 


















                                                              
                                 


                                
                                                               
                                     






































































                                                                          
                                  
         
                                     
                                       
                                                              




                               
                                                  



                           
                                                                          



                                    


                             
 

                                                                            
 
                                           
                      
          
                                                                                                   
          
 
                                                            
                                                        
                                                                       
                    
                                                                   
                  






                           
                                                                          









                                                           
                                         
























                                                                  
                                                                          
                  
                                   
















                                                     
                                                     







                                                   
                                       
                    
                                           









                                                                   
                                              






                                      
                                     









                                                                                                      
                                                                          







                                                   
                                       
                    
                                           









                                                                   
                                              



                                      
                                                        
            
                                     









                                                                                          
                                                                          






                                                   
                                       
                    
                                           









                                                                   
                                              





                                      
                                     









                                                                     
                                                                          




                               
                                       










                                                                  
                                     





                                                                              
                                         











                                        
                                                                          




                               
                                       










                                                                  
                                      










                                                                         
                                                                          
























                                                               
                                                                          




                               
                                       










                                                                  
                                     
            
                                                                                              
                                                               
                                                                                                                              













                                                                                
                                                                          




                               
                                       










                                                                  
                                     
            
                                                                                              

                                                 
                                 





                                
#!/usr/bin/env 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/>.

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
}