blob: 6bc33e2972846df97dcfa441700edbf367d4234a [file] [log] [blame]
#!/bin/sh
# Copyright 2018 Fairphone B.V.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Exported globals:
# DEBUG
# DRY_RUN
# SHELL_LIBS
# VERBOSE
set -e
export SHELL_LIBS="$(dirname $(readlink -f $0))/../shell-libs"
. "${SHELL_LIBS}/utils.sh"
_usage() {
cat <<heredoc
Fetch branches and tags from a remote and push to Fairphone's hosted Android
projects. Missing projects will be created if needed.
Locally defined branches and tags based on the remote's manifest project
revisions can also be created and pushed to the fairphone remote.
Usage:
$0 [-m|--manifest MANIFEST] [-nb|--new-branch NEW_BRANCH]
[-rb|--remote-branch REMOTE_BRANCH TARGET_BRANCH] [-nt|--new-tag NEW_TAG]
[-rt|--remote-tag REMOTE_TAG] [-g|--groups "<group1>,..."]
[-p|--projects "project1 project2"] [-d|--debug] [-v|--verbose]
[-n|--dry-run] [-s|--skip-init] [-h|--help]
Options:
-m, --manifest MANIFEST : Local hosted remote manifest found in
.repo/manifests/
-nb, --new-branch NEW_BRANCH : New branch to create and push.
-rb, --remote-branch REMOTE_BRANCH TARGET_BRANCH
: Names of remote branch to fetch and target
branch to push to remote 'fairphone'.
-nt, --new-tag NEW_TAG : Name of a new tag to create and push.
-rt, --remote-tag REMOTE_TAG : Name of remote tag to fetch and import.
-g, --groups "<group>,..." : Quote enclosed, comma separated, manifest
groups.
Default: "all"
E.g. "pdk,pdk-qcom"
-p, --projects "project ..." : Quote enclosed, space separated, list of
projects to work on. When undefined script
will run commands on all projects allowed by
MANIFEST_GROUPS.
E.g. -p "cts dalvik"
--dry-run : Run git and ssh commands but do not modify
remote.
-d, --debug : Show commands being run. I.e. set -x.
-v, --verbose : Show additional logging.
-s, --skip-init : Skip 'repo init' and 'repo sync' commands.
Only set this if you are sure all projects
have been synced and point to the correct
remote and revision.
-h, --help : Print this help message
Examples:
$0 -m aosp/aosp-9.0.0_r8.xml -rb pie-r2-s1-release aosp/pie-r2-s1-release -rt android-9.0.0_r8
$0 -m caf/default_LA.UM.7.6.2.r1-03400-89xx.0.xml -nb staging/arima/fp3/p/r0
heredoc
}
# Perform a repo init and sync on a specified remote manifest
#
# Globals:
# REPO_PROJECTS
# Arguments:
# manifest Remote manifest to use.
# groups repo groups to use.
# platform repo platform to use.
# Returns:
# None
_init_projects()
{
local manifest="$1"
local groups="${2:-"all"}"
local platform="${3:-"linux"}"
# Manifest must be set and point to a valid file
if [ -z "${manifest}" ] || [ ! -f ".repo/manifests/${manifest}" ] ; then
log_e "Cannot find reference remote manifest \
$(pwd)/.repo/manifests/${manifest}"
fi
log_bold "Repo init:"
repo init \
--manifest-name="${manifest}" \
--groups="${groups}" \
--platform="${platform}"
log_bold "Repo sync:"
repo sync --current-branch --detach --no-tags ${REPO_PROJECTS}
}
repo_forall='repo --no-pager forall --abort-on-errors --verbose'
# Add remote 'fairphone' and create new remote projects if needed.
#
# Globals:
# REPO_FORALL_FUNCTIONS
# REPO_PROJECTS
# Arguments:
# None
# Returns:
# None
_prepare_projects()
{
log_bold "Preparing projects:"
${repo_forall} ${REPO_PROJECTS} --command \
'. $1; \
add_fairphone_remote; \
add_project_to_fairphone_remote' \
"${REPO_FORALL_FUNCTIONS}"
}
# Create a local branch at the manifest revisions and push to 'fairphone'
#
# Globals:
# REPO_FORALL_FUNCTIONS
# REPO_PROJECTS
# Arguments:
# new_branch Name of the branch to create and push.
# Returns:
# None
_import_new_branch()
{
local new_branch="$1"
log_bold "BRANCH: Create and push ${new_branch}:"
# Create the branch
repo start "${new_branch}" ${REPO_PROJECTS:-"--all"}
# Push branch to the 'fairphone'
${repo_forall} ${REPO_PROJECTS} --command \
'. $1; \
remove_shallow_clone; \
push_branch_to_fairphone $2 $2' \
"${REPO_FORALL_FUNCTIONS}" "${new_branch}"
}
# Fetch a remote branch and push to 'fairphone'
#
# Globals:
# REPO_FORALL_FUNCTIONS
# REPO_PROJECTS
# Arguments:
# remote_branch Name of the remote branch to fetch.
# target_branch Name of the target branch to push to.
# Returns:
# None
_import_remote_branch()
{
local remote_branch="$1"
local target_branch="$2"
log_bold "BRANCH: Fetch ${remote_branch} and push ${target_branch}:"
# Fetch remote branch and push to 'fairphone'.
${repo_forall} $REPO_PROJECTS --command \
'. $1; \
fetch_remote_branch $2; \
push_branch_to_fairphone $2 $3' \
"${REPO_FORALL_FUNCTIONS}" "${remote_branch}" "${target_branch}"
}
# Create a new tag at the manifest revisions and push to 'fairphone'
#
# Globals:
# REPO_FORALL_FUNCTIONS
# REPO_PROJECTS
# Arguments:
# new_tag Name of the tag to create and push
# Returns:
# None
_import_new_tag()
{
local new_tag="$1"
log_bold "TAG: Create and push ${new_tag}:"
${repo_forall} ${REPO_PROJECTS} --command \
'. $1; \
git tag $2; \
remove_shallow_clone; \
push_tag_to_fairphone $2;' \
"${REPO_FORALL_FUNCTIONS}" "${new_tag}"
}
# Fetch a remote tag and push to 'fairphone'
#
# Globals:
# REPO_FORALL_FUNCTIONS
# REPO_PROJECTS
# Arguments:
# remote_tag - Name of the remote tag to fetch and push
# Returns:
# None
_import_remote_tag()
{
local remote_tag="$1"
log_bold "TAG: Fetch and push ${remote_tag}:"
${repo_forall} ${REPO_PROJECTS} --command \
'. $1; \
fetch_remote_tag $2; \
push_tag_to_fairphone $2' \
"${REPO_FORALL_FUNCTIONS}" "${remote_tag}"
}
while [ $# -gt 0 ]; do
case "$1" in
-m|--manifest)
if [ $# -lt 2 ]; then
_usage >&2
exit 1
fi
MANIFEST="$2"
shift 2
;;
-nb|--new-branch)
if [ $# -lt 2 ]; then
_usage >&2
exit 1
fi
NEW_BRANCH="$2"
shift 2
;;
-rb|--remote-branch)
if [ $# -lt 3 ]; then
_usage >&2
exit 1
fi
REMOTE_BRANCH="$2"
TARGET_BRANCH="$3"
shift 3
;;
-nt|--new-tag)
if [ $# -lt 2 ]; then
_usage >&2
exit 1
fi
NEW_TAG="$2"
shift 2
;;
-rt|--remote-tag)
if [ $# -lt 2 ]; then
_usage >&2
exit 1
fi
REMOTE_TAG="$2"
shift 2
;;
-g|--groups)
if [ $# -lt 2 ]; then
_usage >&2
exit 1
fi
MANIFEST_GROUPS="$2"
shift 2
;;
-p|--projects)
if [ $# -lt 2 ]; then
_usage >&2
exit 1
fi
REPO_PROJECTS="$2"
shift 2
;;
--dry-run)
export DRY_RUN="--dry-run"
shift 1
;;
-v|--verbose)
export VERBOSE="--verbose"
shift 1
;;
-d|--debug)
set -x
export DEBUG="true"
shift 1
;;
-s|--skip-init)
SKIP_INIT=true
shift 1
;;
-h|--help)
_usage
exit 0
;;
*)
echo "Unknown option $*" >&2
_usage >&2
exit 1
;;
esac
done
REPO_FORALL_FUNCTIONS="${SHELL_LIBS}/repo-forall-functions.sh"
if [ ! -f "${REPO_FORALL_FUNCTIONS}" ] ; then
log_e "Unable to find repo-forall-functions.sh" || _usage >&2
exit 1
fi
# Navigate to the Android's root
croot
# Initialize Android tree
if [ -z "${SKIP_INIT}" ] ; then
_init_projects "${MANIFEST}" "${MANIFEST_GROUPS}" "${MANIFEST_PLATFORM}"
fi
_prepare_projects
if [ -n "${NEW_BRANCH}" ] ; then
_import_new_branch "${NEW_BRANCH}"
fi
if [ -n "${REMOTE_BRANCH}" ] && [ -n "${TARGET_BRANCH}" ] ; then
_import_remote_branch "${REMOTE_BRANCH}" "${TARGET_BRANCH}"
fi
if [ -n "${NEW_TAG}" ] ; then
_import_new_tag "${NEW_TAG}"
fi
if [ -n "${REMOTE_TAG}" ] ; then
_import_remote_tag "${REMOTE_TAG}"
fi