| #!/usr/bin/env sh |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you 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. |
| |
| # Syntax: ./setup-worktree-plugins.sh [plugins-branch] |
| # |
| # plugins/ is listed in .gitignore and is itself an independent git |
| # repository (see pullPluginSource.sh / pullAllPluginsSource.sh). Because |
| # it's gitignored, `git worktree add` for this repo does not populate it -- |
| # a freshly created linked worktree gets no plugins/ directory at all, which |
| # later fails the build (missing-plugins-dir builds silently skip all plugin |
| # subprojects; a wrong-branch plugins/ instead fails with a misleading |
| # Groovy-version dependency conflict). |
| # |
| # Run this script from inside a linked worktree of *this* repo (i.e. after |
| # `git worktree add ../some-path -b some-branch`) to give that worktree a |
| # plugins/ checkout on a matching branch, without re-cloning: it adds a |
| # linked worktree of the *existing* plugins/ git repository found via the |
| # main checkout. |
| # |
| # The matching plugins/ branch is found by name first, then (for a |
| # feature/ticket branch with no plugins/ branch of the same name) by |
| # walking this repo's actual branch ancestry to find the branch it was cut |
| # from -- no assumption is made about branch-naming conventions. |
| |
| set -e |
| |
| if [ -e "plugins" ]; then |
| echo "ERROR: plugins/ already exists here ($(pwd)/plugins) -- refusing to overwrite it. Remove it first if you want this script to (re)create it." >&2 |
| exit 1 |
| fi |
| |
| git_common_dir=$(git rev-parse --git-common-dir 2>/dev/null) || { |
| echo "ERROR: not inside a git repository." >&2 |
| exit 1 |
| } |
| main_worktree=$(cd "$(dirname "$git_common_dir")" && pwd) |
| plugins_repo="$main_worktree/plugins" |
| |
| if [ ! -e "$plugins_repo/.git" ]; then |
| echo "ERROR: no plugins/ git repository found at $plugins_repo -- expected the main ofbiz checkout to have a working plugins/ git checkout to branch off of." >&2 |
| exit 1 |
| fi |
| |
| branch_exists() { |
| git -C "$plugins_repo" show-ref --verify --quiet "refs/heads/$1" || |
| git -C "$plugins_repo" show-ref --verify --quiet "refs/remotes/origin/$1" |
| } |
| |
| ofbiz_branch=$(git branch --show-current) |
| plugins_branch="" |
| |
| if [ -n "$1" ]; then |
| plugins_branch=$1 |
| if ! branch_exists "$plugins_branch"; then |
| echo "ERROR: plugins branch '$plugins_branch' not found (checked refs/heads and refs/remotes/origin in $plugins_repo)." >&2 |
| exit 1 |
| fi |
| elif [ -z "$ofbiz_branch" ]; then |
| echo "ERROR: this worktree is in detached HEAD state, so the matching plugins branch can't be inferred. Pass it explicitly: ./setup-worktree-plugins.sh <branch>" >&2 |
| exit 1 |
| elif branch_exists "$ofbiz_branch"; then |
| plugins_branch=$ofbiz_branch |
| else |
| # No plugins branch shares this worktree's exact branch name -- it's |
| # presumably a feature/ticket branch. Rather than guess from naming |
| # conventions (which vary per team/fork), walk this repo's own branch |
| # ancestry, nearest first, to find the branch it was actually cut from, |
| # and use that name in plugins/ instead. Keep walking further back |
| # (e.g. past an intermediate release branch to trunk) until one of |
| # them has a matching plugins branch. |
| candidates=$( |
| for ref in $(git for-each-ref --format='%(refname:short)' refs/heads refs/remotes/origin); do |
| if [ "$ref" = "$ofbiz_branch" ] || [ "$ref" = "origin/$ofbiz_branch" ] || [ "$ref" = "origin/HEAD" ]; then |
| continue |
| fi |
| if git merge-base --is-ancestor "$ref" HEAD 2>/dev/null; then |
| distance=$(git rev-list --count "$ref"..HEAD 2>/dev/null) && echo "$distance $ref" |
| fi |
| done | sort -n |
| ) |
| old_ifs=$IFS |
| IFS=' |
| ' |
| for line in $candidates; do |
| ref=${line#* } |
| candidate=${ref#origin/} |
| if branch_exists "$candidate"; then |
| plugins_branch=$candidate |
| break |
| fi |
| done |
| IFS=$old_ifs |
| fi |
| |
| if [ -z "$plugins_branch" ]; then |
| echo "ERROR: could not determine a plugins/ branch matching ofbiz branch '$ofbiz_branch'." >&2 |
| echo "Pass one explicitly: ./setup-worktree-plugins.sh <branch>" >&2 |
| echo "Branches available in $plugins_repo:" >&2 |
| git -C "$plugins_repo" branch -a --format=' %(refname:short)' >&2 |
| exit 1 |
| fi |
| |
| echo "Setting up plugins/ as a linked worktree of $plugins_repo on branch '$plugins_branch'..." |
| |
| # If that branch is already checked out elsewhere (e.g. in the main |
| # checkout this was branched from), git refuses a second worktree on the |
| # same branch -- fall back to a detached checkout of the same commit, |
| # which is fine for building since we only need matching source, not to |
| # commit from inside this worktree's plugins/. |
| if worktree_add_output=$(git -C "$plugins_repo" worktree add "$(pwd)/plugins" "$plugins_branch" 2>&1); then |
| echo "$worktree_add_output" |
| elif echo "$worktree_add_output" | grep -q "already checked out"; then |
| echo "Branch '$plugins_branch' is already checked out elsewhere; using a detached checkout of the same commit instead." |
| git -C "$plugins_repo" worktree add --detach "$(pwd)/plugins" "$plugins_branch" |
| else |
| echo "$worktree_add_output" >&2 |
| exit 1 |
| fi |
| |
| echo "Done: plugins/ is ready on '$plugins_branch'." |