mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-11 06:56:58 +02:00
eclass is a file, as opposed to the package, which is a directory. So doing `git -C eclass/foo.eclass log -- .` will fail because we can't do "cd eclass/foo.eclass", which is what `-C` is trying to do.
317 lines
7.9 KiB
Bash
Executable File
317 lines
7.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
##
|
|
## Used for syncing with gentoo. Needs to be called from the
|
|
## toplevel-directory of portage-stable. If syncing everything or
|
|
## syncing metadata/glsa specifically, it is expected that the Gentoo
|
|
## repo will have the GLSA files stored in metadata/glsa too.
|
|
##
|
|
## Parameters:
|
|
## -h: this help
|
|
## -b: be brief, print only names of changed entries and errors
|
|
## -s: skip adding source git commit hash information to commits
|
|
##
|
|
## Positional:
|
|
## 0: Gentoo repository
|
|
## #: Entries to update (can be a package name, eclass, category, some special
|
|
## directories like profiles or . for everything)
|
|
##
|
|
## Example invocations:
|
|
##
|
|
## sync_with_gentoo -h
|
|
##
|
|
## Print a help message.
|
|
##
|
|
## sync_with_gentoo dev-libs/nettle app-crypt/argon2
|
|
##
|
|
## This will update the packages, each in a separate commit. The
|
|
## commit message will contain the commit hash from gentoo repo.
|
|
##
|
|
## sync_with_gentoo dev-libs
|
|
##
|
|
## This will update all the packages in dev-libs category. The
|
|
## commit message will contain the commit hash from gentoo repo.
|
|
##
|
|
|
|
set -euo pipefail
|
|
|
|
source "$(dirname "${BASH_SOURCE[0]}")/util.sh"
|
|
|
|
BRIEF=
|
|
SKIP_GIT_INFO=
|
|
|
|
while true; do
|
|
case ${1-} in
|
|
-h)
|
|
print_help
|
|
exit 0
|
|
;;
|
|
-b)
|
|
BRIEF=x
|
|
shift
|
|
;;
|
|
-s)
|
|
SKIP_GIT_INFO=x
|
|
shift
|
|
;;
|
|
--)
|
|
shift
|
|
break
|
|
;;
|
|
-*)
|
|
fail "unknown flag '${1}'"
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ $# -lt 2 ]]; then
|
|
fail 'expected at least two positional parameters: a Gentoo repository and at least one package, use -h to print help'
|
|
fi
|
|
|
|
if [[ ! -e 'profiles/repo_name' ]]; then
|
|
fail 'sync is only possible from ebuild packages top-level directory (a directory from which "./profiles/repo_name" is accessible)'
|
|
fi
|
|
|
|
function vcall() {
|
|
if [[ -z ${BRIEF} ]]; then
|
|
"${@}"
|
|
fi
|
|
}
|
|
|
|
function bcall() {
|
|
if [[ -n ${BRIEF} ]]; then
|
|
"${@}"
|
|
fi
|
|
}
|
|
|
|
GENTOO=$(realpath "${1}"); shift
|
|
# rest are package names
|
|
|
|
if [[ $(realpath '.') = "${GENTOO}" ]]; then
|
|
fail 'trying to sync within a Gentoo repo?'
|
|
fi
|
|
|
|
if [[ -z ${SKIP_GIT_INFO} ]] && [[ ! -e ${GENTOO}/.git ]]; then
|
|
info "Skipping adding source git commit hash information to commits, ${GENTOO@Q} is not a git repository"
|
|
SKIP_GIT_INFO=x
|
|
fi
|
|
|
|
glsa_repo=${GENTOO}/metadata/glsa
|
|
if [[ -z ${SKIP_GIT_INFO} ]] && [[ -e ${glsa_repo} ]] && [[ ! -e ${glsa_repo}/.git ]] && [[ $(git -C "${GENTOO}" status --porcelain -- metadata/glsa) = '?? metadata/glsa' ]]; then
|
|
info "Skipping adding source git commit hash information to commits, ${glsa_repo@Q} exists, but it is not a git repository and is not a part of Gentoo git repository"
|
|
SKIP_GIT_INFO=x
|
|
fi
|
|
unset glsa_repo
|
|
|
|
# Synchronizes given path with its Gentoo counterpart. Returns true if
|
|
# there were changes.
|
|
#
|
|
# Params:
|
|
#
|
|
# 1 - path within ebuild repo
|
|
function sync_git_prepare() {
|
|
local path
|
|
path=${1}; shift
|
|
|
|
local gentoo_path
|
|
gentoo_path="${GENTOO}/${path}"
|
|
|
|
if [[ ! -e "${gentoo_path}" ]]; then
|
|
info "no ${path@Q} in Gentoo repository"
|
|
if [[ ${path} = 'metadata/glsa' ]]; then
|
|
info "did you forget to clone https://gitweb.gentoo.org/data/glsa.git/ into ${gentoo_path@Q}?"
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
local -a rsync_opts=( --archive --delete-before )
|
|
|
|
case ${path} in
|
|
profiles)
|
|
rsync_opts+=( --exclude /profiles/repo_name )
|
|
;;
|
|
esac
|
|
|
|
local parent
|
|
dirname_out "${path}" parent
|
|
mkdir --parents "${parent}"
|
|
rsync "${rsync_opts[@]}" "${gentoo_path}" "${parent}"
|
|
if [[ -n $(git status --porcelain -- "${path}") ]]; then
|
|
bcall info "updated ${path}"
|
|
git add "${path}"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Creates a git commit. If checking Gentoo commit ID is enabled the
|
|
# given path is used to get the ID of the commit with the last change
|
|
# in the path. Name parameter is used for denoting which part has
|
|
# changed, and sync parameter to denote if the commit is about adding
|
|
# new package or updating an existing one.
|
|
#
|
|
# Params:
|
|
#
|
|
# 1 - path
|
|
# 2 - name
|
|
# 3 - not empty if existing package was updated, or an empty string if
|
|
# the package is new
|
|
function commit_with_gentoo_sha() {
|
|
local path name sync
|
|
path=${1}; shift
|
|
name=${1}; shift
|
|
sync=${1:-}; shift
|
|
|
|
local -a commit_extra=()
|
|
if [[ -z ${SKIP_GIT_INFO} ]]; then
|
|
local commit
|
|
|
|
commit=$(git -C "${GENTOO}" log --pretty=oneline -1 -- "${path}" | cut -f1 -d' ')
|
|
commit_extra+=( --message "It's from Gentoo commit ${commit}." )
|
|
unset commit
|
|
fi
|
|
commit_msg="${name}: Add from Gentoo"
|
|
if [[ -n "${sync}" ]]; then
|
|
commit_msg="${name}: Sync with Gentoo"
|
|
fi
|
|
git commit --quiet --message "${commit_msg}" "${commit_extra[@]}"
|
|
GIT_PAGER='cat' vcall git show --stat
|
|
}
|
|
|
|
# Simple path sync and commit; takes the contents from Gentoo at the
|
|
# given path and puts it in the repo.
|
|
#
|
|
# 1 - path to sync
|
|
# 2 - name for commit message
|
|
function path_sync() {
|
|
local path name
|
|
path=${1}; shift
|
|
name=${1}; shift
|
|
|
|
local sync
|
|
sync=''
|
|
if [[ -e "${path}" ]]; then
|
|
sync='x'
|
|
fi
|
|
|
|
if sync_git_prepare "${path}"; then
|
|
commit_with_gentoo_sha "${path}" "${name}" "${sync}"
|
|
else
|
|
vcall info "no changes in ${path}"
|
|
fi
|
|
}
|
|
|
|
# Goes over the given directory and syncs its subdirectories or
|
|
# files. No commit is created.
|
|
function prepare_dir() {
|
|
local dir
|
|
dir=${1}; shift
|
|
|
|
local pkg mod=''
|
|
for pkg in "${dir}/"*; do
|
|
if sync_git_prepare "${pkg}"; then
|
|
mod=x
|
|
fi
|
|
done
|
|
if [[ -n ${mod} ]]; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Synces entire category of packages and creates a commit. Note that
|
|
# if the category already exists, no new packages will be added.
|
|
#
|
|
# Params:
|
|
#
|
|
# 1 - path to the category directory
|
|
function category_sync() {
|
|
local path
|
|
path=${1}; shift
|
|
|
|
if [[ ! -e "${path}" ]]; then
|
|
if sync_git_prepare "${path}"; then
|
|
commit_with_gentoo_sha "${path}" "${path}"
|
|
fi
|
|
else
|
|
if prepare_dir "${path}"; then
|
|
commit_with_gentoo_sha "${path}" "${path}" 'x'
|
|
fi
|
|
fi
|
|
|
|
}
|
|
|
|
# Synces entire repo. No new packages will be added.
|
|
function everything_sync() {
|
|
local path mod
|
|
|
|
for path in *; do
|
|
case ${path} in
|
|
licenses|profiles|scripts)
|
|
if sync_git_prepare "${path}"; then
|
|
mod=x
|
|
fi
|
|
;;
|
|
metadata)
|
|
# do only metadata updates
|
|
if sync_git_prepare metadata/glsa; then
|
|
mod=x
|
|
fi
|
|
;;
|
|
eclass|virtual|*-*)
|
|
if prepare_dir "${path}"; then
|
|
mod=x
|
|
fi
|
|
;;
|
|
changelog|*.md)
|
|
# ignore those
|
|
:
|
|
;;
|
|
*)
|
|
info "Unknown entry ${path@Q}, ignoring"
|
|
;;
|
|
esac
|
|
done
|
|
if [[ -n ${mod} ]]; then
|
|
commit_with_gentoo_sha '.' '*' 'x'
|
|
fi
|
|
}
|
|
|
|
shopt -s extglob
|
|
|
|
for cpn; do
|
|
cpn=${cpn%%*(/)}
|
|
case ${cpn} in
|
|
.)
|
|
everything_sync
|
|
;;
|
|
licenses|profiles|scripts)
|
|
path_sync "${cpn}" "${cpn}"
|
|
;;
|
|
eclass/*.eclass)
|
|
path_sync "${cpn}" "${cpn%.eclass}"
|
|
;;
|
|
metadata/glsa)
|
|
path_sync "${cpn}" "${cpn}"
|
|
;;
|
|
metadata)
|
|
fail "metadata directory can't be synced, did you mean metadata/glsa?"
|
|
;;
|
|
virtual/*/*|*-*/*/*)
|
|
fail "invalid thing to sync: ${cpn}"
|
|
;;
|
|
virtual/*|*-*/*)
|
|
path_sync "${cpn}" "${cpn}"
|
|
;;
|
|
eclass|virtual|*-*)
|
|
category_sync "${cpn}"
|
|
;;
|
|
*)
|
|
fail "invalid thing to sync: ${cpn}"
|
|
;;
|
|
esac
|
|
done
|