#!/bin/bash # -*- coding: utf-8; mode: sh; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=sh:et:sw=4:ts=4:sts=4 # Note: # This script is sourced by the mpbb wrapper script. # Do not execute this directly! checkout-usage() { # "prog" is defined in mpbb-help. # shellcheck disable=SC2154 cat <] checkout [] Obtain a working copy of the jobs tools and ports tree and configure MacPorts to use the latter as a port source. Options: --git[=] Use Git to obtain the jobs tools and ports tree; this is the default behavior. The path to a Git client may be provided explicitly, otherwise \`git' is used. Cannot be specified together with --svn. --jobs-url= URL to a repository containing the jobs tools. Only used when checking out a new working copy. Defaults to \`https://github.com/macports/macports-infrastructure.git' for Git and \`https://github.com/macports/macports-infrastructure.git/trunk/jobs' for Subversion. --ports-branch= The branch of the remote repository from which the ports tree will be checked out. Only used with Git; defaults to \`master'. --ports-commit= A commit or revision at which the ports tree will be checked out. Any specifier understood by the version-control client may be used. Defaults to \`FETCH_HEAD' for Git and \`HEAD' for Subversion. --ports-url= URL to a repository containing the ports tree. Only used when checking out a new working copy. Defaults to \`https://github.com/macports/macports-ports.git' for Git and \`https://github.com/macports/macports-ports.git/trunk' for Subversion. --svn[=] Use Subversion to obtain the jobs tools and ports tree. The path to a Subversion client may be provided explicitly, otherwise \`svn' is used. Cannot be specified together with --git. Run \`$prog help' for global options and a list of other subcommands. EOF } is-empty() { if [[ $# -ne 1 || -z $1 ]]; then err 'is-empty requires a single non-null argument' return 2 fi (shopt -s dotglob nullglob; f=("$1"/*); (( ! ${#f[@]} ))) } git-checkout() { if (( $# < 2 )); then err 'git-checkout requires at least two arguments' return 2 fi local -r dst=$1 src=$2 commitish=${3-FETCH_HEAD} branch=${4-master} # top is null unless dst exists somewhere in a Git working tree. local -r top=$({ cd "$dst" && "$git" rev-parse --show-toplevel; } 2>/dev/null) if ! { [[ -z $top ]] && is-empty "$dst" || [[ $top -ef $dst ]]; }; then err "\`$dst' is not an empty directory or" \ 'the top level of a Git working tree' return 1 fi printf "\n---> Updating Git repository from \`%s' branch of \`%s'\n" \ "$branch" "$src" ( # "git init" creates the intermediate directories and is safe to # run in an existing repository. "$git" init "$dst" || exit # Change directories explicitly because Lion's Git (1.7.12.4) is # too old to understand "git -C" (requires 1.8.5). cd "$dst" || exit # Fetch directly from the URL to avoid fussing with remotes and # to allow switching sources easily. "$git" fetch --tags "$src" "$branch" || exit # Maintain master to prevent Git from garbage-collecting the # fetched objects. "$git" update-ref -m "mpbb checkout $(date -u +%Y-%m-%dT%TZ)" \ refs/heads/master FETCH_HEAD || exit # Only update the working tree here, at the very end. "$git" checkout --detach "$commitish" ) } svn-checkout() { if (( $# < 2 )); then err 'svn-checkout requires at least two arguments' return 2 fi local -r dst=$1 src=$2 rev=${3-HEAD} local -r svn=("$svn" --non-interactive) local -r root=$("${svn[@]}" info --show-item wc-root "$dst" 2>/dev/null) if [[ -z $root ]] && is-empty "$dst"; then printf "\n---> Checking out Subversion repository from \`%s'\n" "$src" # "svn checkout" creates the intermediate directories. "${svn[@]}" checkout --revision "$rev" "$src" "$dst" elif [[ $root -ef $dst ]]; then # TODO Allow switching the Subversion server. printf "\n---> Updating Subversion repository from \`%s'\n" \ "$("${svn[@]}" info --show-item url "$dst")" "${svn[@]}" cleanup "$dst" \ && "${svn[@]}" update --revision "$rev" "$dst" else err "\`$dst' is not an empty directory or" \ 'the root of a Subversion working copy' return 1 fi } checkout() { local args parseopt git::,jobs-url:,ports-branch:,ports-commit:,ports-url:,svn::,svn-url: "$@" \ || return # shellcheck disable=SC2086 set -- ${args+"${args[@]}"} # shellcheck disable=SC2154 # To maintain backwards compatibility, --svn-url implies --svn. if [[ -n ${option_svn_url+_} ]]; then : "${option_svn=}" fi # shellcheck disable=SC2154 local -r ports_dir=${option_work_dir}/ports local checkout git jobs_dir svn # shellcheck disable=SC2100 disable=SC2154 if [[ -z ${option_svn+_} ]] && git=${option_git:-$(command -v git)}; then checkout=git-checkout # Checking out "jobs_url" should create a "jobs" subdirectory. jobs_dir=$(dirname "${option_jobs_dir}") : "${option_jobs_url=https://github.com/macports/macports-infrastructure.git}" : "${option_ports_url=https://github.com/macports/macports-ports.git}" elif [[ -z ${option_git+_} ]] && svn=${option_svn:-$(command -v svn)}; then checkout=svn-checkout jobs_dir=${option_jobs_dir} if [[ -n ${option_svn_url+_} ]]; then : "${option_jobs_url=${option_svn_url}/base/portmgr/jobs}" : "${option_ports_url=${option_svn_url}/dports}" else : "${option_jobs_url=https://github.com/macports/macports-infrastructure.git/trunk/jobs}" : "${option_ports_url=https://github.com/macports/macports-ports.git/trunk}" fi else case ${option_git+_},${option_svn+_} in _,_) err 'cannot use both Git and Subversion'; return 2 ;; _,) err 'cannot find a Git client' ;; ,_) err 'cannot find a Subversion client' ;; ,) err 'cannot find any Git or Subversion clients' ;; esac return 1 fi readonly checkout git jobs_dir svn $checkout "${jobs_dir}" "${option_jobs_url}" || return # shellcheck disable=SC2086 disable=SC2154 $checkout "${ports_dir}" "${option_ports_url}" \ ${option_ports_commit+"${option_ports_commit}"} \ ${option_ports_branch+"${option_ports_branch}"} || return # $option_prefix is set in mpbb # shellcheck disable=SC2154 (cd "${ports_dir}" && "${option_prefix}/bin/portindex") || return local -ar mirrors=(aarnet.au cjj.kr fco.it her.gr jnb.za jog.id lil.fr mse.uk nou.nc nue.de osl.no sea.us ykf.ca) # Unset IFS to ensure "${mirrors[*]}" uses spaces as separators. (unset IFS && cat > "${option_work_dir}/macports.conf" < "${option_work_dir}/sources.conf" <