#!/bin/sh
# ------------------------------------------------------------------------------
#
# git-qselect.sh: Implement the Git-MQ "git qselect" extension command.
#
# Set, reset (clear), or display guards on any one Git-MQ patch, or display
# guards on all patches in the series.
#
# $Id$
#
# ------------------------------------------------------------------------------
#
mq_facility="git qselect"

# I'd have liked to call this a "SYNOPSIS", (which is what it is), but git's
# git-sh-setup script requires the much less appropriate name "OPTIONS_SPEC",
# (which describes only a small subset of its actual content).
#
OPTIONS_SPEC="\
git qguard [-s | --series] [-v | --verbose]
git qselect [--pop | --reapply] [-n | --none | <guard> ...]

Activate, deactivate, or display the active guards, controlling the
selection of Git-MQ patches which may be applied.
--
pop!        pop back to predecessor of first guarded patch
reapply!    pop, then reapply unguarded patches to current topmost
s,series!   list all guards specified in the series file
n,none!     deactivate all guards"
#
# ------------------------------------------------------------------------------
#
# $Id$
#
# Written by Keith Marshall <keith@users.osdn.me>
# Copyright (C) 2018-2020, 2022, Keith Marshall
#
#
# This file is part of the Git-MQ program suite.
#
# The Git-MQ program suite is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public Licence
# as published by the Free Software Foundation, either version 3 of
# the Licence, or (at your option) any later version.
#
# The Git-MQ program suite 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 Licence for more details.
#
# You should have received a copy of the GNU General Public Licence
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
# ------------------------------------------------------------------------------
#
# Although they may not always have any effect, all Git-MQ commands, like
# their hg counterparts, are expected to accept the global verbosity, and
# colour control options; ensure that they are declared:
#
OPTIONS_SPEC="$OPTIONS_SPEC
colour?*     generic output colour control -- may have no effect"
${OPTION_VERBOSE_DEFINED-false} || OPTIONS_SPEC="$OPTIONS_SPEC
v,verbose!*  generic verbosity selector -- may have no effect"

# For Git-MQ options, such as "--colour", we prefer a spelling convention
# which conforms to "World English" standards; however, git itself adopts
# "US English" convention.  Thus, we must also accommodate users who will
# specify "--color" instead of "--colour", without creating any ambiguity
# in the possible abbreviations; to achieve this, we check for "--color",
# among the command-line arguments, replacing it with "--colour", BEFORE
# we allow git to parse them.
#
for mq_argv
do case "$mq_argv" in
     --color*) mq_argv=`echo $mq_argv | sed 's/^--colo/&u/'` ;;
     --no-color) mq_argv="--no-colour" ;;
   esac
   ${mq_argv_init-true} && { set -- "$mq_argv"; mq_argv_init=false
   } || set -- "$@" "$mq_argv"
done

# Now, we may let git parse the command line, and set up its shell script
# processing environment, for use within a git working directory tree.
#
SUBDIRECTORY_OK=true . "`git --exec-path`/git-sh-setup" && require_work_tree

libexecdir=`dirname "$0"`
test `basename "$libexecdir"` = bin && libexecdir=`dirname "$libexecdir"`
libexecdir="$libexecdir/libexec/git-mq/${VERSION=1.0}"

mq_require(){ test -f "$1" || die "fatal: '$1' not found."; . "$1"; }
mq_require "$libexecdir/git-mq-setup.sh"

# Parse any command line options, which the user may have specified;
# the git_mq_getopt function will implicitly handle the default global
# options, but we must explicitly handle command specific effects.
#
while git_mq_getopt "$@"
do case $1 in
     --pop)
         mq_pop_option="git-qpop-backend"
	 ;;
     --reapply)
         mq_reapply_option="git-qpush-backend"
	 mq_pop_option="git-qpop-backend"
	 ;;
     -s) mq_list_option=true ;;
     -n) mq_drop_option=true ;;
     -v) mq_verbose=true ;;
   esac; shift
done

# After parsing any options, we must invoke exactly one of the three
# possible primary actions, namely:
#
#   1) activate named, or deactivate all guards;
#   2) list, and optionally (with "--verbose") count references
#      to, all guards which are named in the series file;
#   3) display the names of any active guards.
#
# FIXME: These three actions are mutually exclusive; however, there is
# no attempt to forbid any use of combinations of options and arguments
# which might appear to invoke more than one!  Rather, the three actions
# are prioritized in the above order, and any additional options, which
# would normally select a lower priority action, are silently ignored.
# Although this behaviour may seem anomalous, it is consistent with
# that of Mercurial Queues, (as implemented in hg-2.7.1).
#
if { test $# -gt 0 || ${mq_drop_option-false}; }
#
# This is the guard activation/dectivation case.
#
# Any remaining arguments are assumed to represent the names of guards
# which are to be activated; activation has the highest priority of all
# primary actions, and overrides the effects of both the "--none", and
# the "--series" options.  Alternatively, with no arguments, "--none"
# becomes the highest priority option, in which case the activation
# action is invoked, with the effect of deactivation.
#
then mq_require mq-select-activate "$@"

elif ${mq_list_option-false}
#
# This is the guards listing and reference counting case.
#
# Conversely, when the "--series" option has been specified, and it is
# not overridden by either "--none", or the presence of other arguments,
# then the next priority primary action it to compile a listing of all
# guards which have been specified in the series file.
#
then mq_map_control_file_refs "$mq_patchdir" series
  awk -f "$libexecdir/mq-select-list.awk" facility="$mq_facility" \
    ${mq_verbose+"verbose=##NONE"} "$mq_series_file"

else mq_map_control_file_refs "$mq_patchdir" guards
#
# Finally, in the absence of any arguments, and neither "--none", nor
# "--series" have been specified, we fall back to the lowest priority
# primary action, which is to display all currently active guards, as
# recorded in the guards file.
#
  awk '{ for( fld = 1; NF >= fld; fld++ ) print $fld; active += NF; }
    END { if( ! active ) print facility ": there are no active guards"; }
  ' facility="$mq_facility" "$mq_guards_file"
fi

# Following invocation of the primary action, if the "--pop" option,
# or the "--reapply" option (which implies "--pop") is present, then
# there is a secondary "backend" action to be performed.
#
test ${mq_pop_option+set} && mq_require mq-select-backend
#
# ------------------------------------------------------------------------------
# $RCSfile$: end of file
