Browse Source

refactor(git-flow): extract `git-flow` completion logic

Marc Cornellà 2 years ago
parent
commit
7a38fa35c4
2 changed files with 334 additions and 350 deletions
  1. 327 0
      plugins/git-flow/_git-flow
  2. 7 350
      plugins/git-flow/git-flow.plugin.zsh

+ 327 - 0
plugins/git-flow/_git-flow

@@ -0,0 +1,327 @@
+#compdef git-flow
+
+_git-flow () {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+
+  _arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+  case $state in
+    (command)
+
+      local -a subcommands
+      subcommands=(
+        'init:Initialize a new git repo with support for the branching model.'
+        'feature:Manage your feature branches.'
+        'release:Manage your release branches.'
+        'hotfix:Manage your hotfix branches.'
+        'support:Manage your support branches.'
+        'version:Shows version information.'
+      )
+      _describe -t commands 'git flow' subcommands
+    ;;
+
+    (options)
+      case $line[1] in
+
+        (init)
+          _arguments \
+            -f'[Force setting of gitflow branches, even if already configured]'
+          ;;
+
+          (version)
+          ;;
+
+          (hotfix)
+            __git-flow-hotfix
+          ;;
+
+          (release)
+            __git-flow-release
+          ;;
+
+          (feature)
+            __git-flow-feature
+          ;;
+      esac
+    ;;
+  esac
+}
+
+__git-flow-release () {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+
+  _arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+  case $state in
+    (command)
+
+      local -a subcommands
+      subcommands=(
+        'start:Start a new release branch.'
+        'finish:Finish a release branch.'
+        'list:List all your release branches. (Alias to `git flow release`)'
+        'publish: public'
+        'track: track'
+      )
+      _describe -t commands 'git flow release' subcommands
+      _arguments \
+        -v'[Verbose (more) output]'
+    ;;
+
+    (options)
+      case $line[1] in
+
+        (start)
+          _arguments \
+            -F'[Fetch from origin before performing finish]'\
+            ':version:__git_flow_version_list'
+        ;;
+
+        (finish)
+          _arguments \
+            -F'[Fetch from origin before performing finish]' \
+            -s'[Sign the release tag cryptographically]'\
+            -u'[Use the given GPG-key for the digital signature (implies -s)]'\
+            -m'[Use the given tag message]'\
+            -p'[Push to $ORIGIN after performing finish]'\
+            -k'[Keep branch after performing finish]'\
+            -n"[Don't tag this release]"\
+            ':version:__git_flow_version_list'
+        ;;
+
+        (publish)
+          _arguments \
+            ':version:__git_flow_version_list'\
+        ;;
+
+        (track)
+          _arguments \
+            ':version:__git_flow_version_list'\
+        ;;
+
+        *)
+          _arguments \
+            -v'[Verbose (more) output]'
+        ;;
+      esac
+    ;;
+  esac
+}
+
+__git-flow-hotfix () {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+
+  _arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+  case $state in
+    (command)
+
+      local -a subcommands
+      subcommands=(
+        'start:Start a new hotfix branch.'
+        'finish:Finish a hotfix branch.'
+        'list:List all your hotfix branches. (Alias to `git flow hotfix`)'
+      )
+      _describe -t commands 'git flow hotfix' subcommands
+      _arguments \
+        -v'[Verbose (more) output]'
+    ;;
+
+    (options)
+      case $line[1] in
+
+        (start)
+          _arguments \
+            -F'[Fetch from origin before performing finish]'\
+            ':hotfix:__git_flow_version_list'\
+            ':branch-name:__git_branch_names'
+        ;;
+
+        (finish)
+          _arguments \
+            -F'[Fetch from origin before performing finish]' \
+            -s'[Sign the release tag cryptographically]'\
+            -u'[Use the given GPG-key for the digital signature (implies -s)]'\
+            -m'[Use the given tag message]'\
+            -p'[Push to $ORIGIN after performing finish]'\
+            -k'[Keep branch after performing finish]'\
+            -n"[Don't tag this release]"\
+            ':hotfix:__git_flow_hotfix_list'
+        ;;
+
+        *)
+          _arguments \
+            -v'[Verbose (more) output]'
+        ;;
+      esac
+    ;;
+  esac
+}
+
+__git-flow-feature () {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+
+  _arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+  case $state in
+    (command)
+
+      local -a subcommands
+      subcommands=(
+        'start:Start a new feature branch.'
+        'finish:Finish a feature branch.'
+        'list:List all your feature branches. (Alias to `git flow feature`)'
+        'publish: publish'
+        'track: track'
+        'diff: diff'
+        'rebase: rebase'
+        'checkout: checkout'
+        'pull: pull'
+      )
+      _describe -t commands 'git flow feature' subcommands
+      _arguments \
+        -v'[Verbose (more) output]'
+    ;;
+
+    (options)
+      case $line[1] in
+
+        (start)
+          _arguments \
+            -F'[Fetch from origin before performing finish]'\
+            ':feature:__git_flow_feature_list'\
+            ':branch-name:__git_branch_names'
+        ;;
+
+        (finish)
+          _arguments \
+            -F'[Fetch from origin before performing finish]' \
+            -r'[Rebase instead of merge]'\
+            -k'[Keep branch after performing finish]'\
+            ':feature:__git_flow_feature_list'
+        ;;
+
+        (publish)
+          _arguments \
+            ':feature:__git_flow_feature_list'\
+        ;;
+
+        (track)
+          _arguments \
+            ':feature:__git_flow_feature_list'\
+        ;;
+
+        (diff)
+          _arguments \
+            ':branch:__git_flow_feature_list'\
+        ;;
+
+        (rebase)
+          _arguments \
+            -i'[Do an interactive rebase]' \
+            ':branch:__git_flow_feature_list'
+        ;;
+
+        (checkout)
+          _arguments \
+            ':branch:__git_flow_feature_list'\
+        ;;
+
+        (pull)
+          _arguments \
+            ':remote:__git_remotes'\
+            ':branch:__git_flow_feature_list'
+        ;;
+
+        *)
+          _arguments \
+            -v'[Verbose (more) output]'
+        ;;
+      esac
+    ;;
+  esac
+}
+
+__git_flow_version_list () {
+  local expl
+  declare -a versions
+
+  versions=(${${(f)"$(_call_program versions git flow release list 2> /dev/null | tr -d ' |*')"}})
+  __git_command_successful || return
+
+  _wanted versions expl 'version' compadd $versions
+}
+
+__git_flow_feature_list () {
+  local expl
+  declare -a features
+
+  features=(${${(f)"$(_call_program features git flow feature list 2> /dev/null | tr -d ' |*')"}})
+  __git_command_successful || return
+
+  _wanted features expl 'feature' compadd $features
+}
+
+__git_remotes () {
+  local expl gitdir remotes
+
+  gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
+  __git_command_successful || return
+
+  remotes=(${${(f)"$(_call_program remotes git config --get-regexp '"^remote\..*\.url$"')"}//#(#b)remote.(*).url */$match[1]})
+  __git_command_successful || return
+
+  # TODO: Should combine the two instead of either or.
+  if (( $#remotes > 0 )); then
+    _wanted remotes expl remote compadd $* - $remotes
+  else
+    _wanted remotes expl remote _files $* - -W "($gitdir/remotes)" -g "$gitdir/remotes/*"
+  fi
+}
+
+__git_flow_hotfix_list () {
+  local expl
+  declare -a hotfixes
+
+  hotfixes=(${${(f)"$(_call_program hotfixes git flow hotfix list 2> /dev/null | tr -d ' |*')"}})
+  __git_command_successful || return
+
+  _wanted hotfixes expl 'hotfix' compadd $hotfixes
+}
+
+__git_branch_names () {
+  local expl
+  declare -a branch_names
+
+  branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
+  __git_command_successful || return
+
+  _wanted branch-names expl branch-name compadd $* - $branch_names
+}
+
+__git_command_successful () {
+  if (( ${#pipestatus:#0} > 0 )); then
+    _message 'not a git repository'
+    return 1
+  fi
+  return 0
+}
+
+zstyle ':completion:*:*:git:*' user-commands flow:'description for foo'
+
+# Detect if script is sourced or called via autoload
+[[ "$ZSH_EVAL_CONTEXT" != *:file ]] || return
+
+_git-flow "$@"

+ 7 - 350
plugins/git-flow/git-flow.plugin.zsh

@@ -1,26 +1,4 @@
-#!zsh
-#
-# Installation
-# ------------
-#
-# To achieve git-flow completion nirvana:
-#
-#  0. Update your zsh's git-completion module to the newest version.
-#     From here. https://raw.githubusercontent.com/zsh-users/zsh/master/Completion/Unix/Command/_git
-#
-#  1. Install this file. Either:
-#
-#     a. Place it in your .zshrc:
-#
-#     b. Or, copy it somewhere (e.g. ~/.git-flow-completion.zsh) and put the following line in
-#        your .zshrc:
-#
-#            source ~/.git-flow-completion.zsh
-#
-#     c. Or, use this file as an oh-my-zsh plugin.
-#
-
-#Alias
+# Aliases
 alias gfl='git flow'
 alias gfli='git flow init'
 alias gcd='git checkout $(git config gitflow.branch.develop)'
@@ -44,330 +22,9 @@ alias gflfpc='git flow feature publish $(echo $(current_branch) | cut -c 9-)'
 alias gflrfc='git flow release finish $(echo $(current_branch) | cut -c 9-)'
 alias gflrpc='git flow release publish $(echo $(current_branch) | cut -c 9-)'
 
-_git-flow ()
-{
-	local curcontext="$curcontext" state line
-	typeset -A opt_args
-
-	_arguments -C \
-		':command:->command' \
-		'*::options:->options'
-
-	case $state in
-		(command)
-
-			local -a subcommands
-			subcommands=(
-				'init:Initialize a new git repo with support for the branching model.'
-				'feature:Manage your feature branches.'
-				'release:Manage your release branches.'
-				'hotfix:Manage your hotfix branches.'
-				'support:Manage your support branches.'
-				'version:Shows version information.'
-			)
-			_describe -t commands 'git flow' subcommands
-		;;
-
-		(options)
-			case $line[1] in
-
-				(init)
-					_arguments \
-						-f'[Force setting of gitflow branches, even if already configured]'
-					;;
-
-					(version)
-					;;
-
-					(hotfix)
-						__git-flow-hotfix
-					;;
-
-					(release)
-						__git-flow-release
-					;;
-
-					(feature)
-						__git-flow-feature
-					;;
-			esac
-		;;
-	esac
-}
-
-__git-flow-release ()
-{
-	local curcontext="$curcontext" state line
-	typeset -A opt_args
-
-	_arguments -C \
-		':command:->command' \
-		'*::options:->options'
-
-	case $state in
-		(command)
-
-			local -a subcommands
-			subcommands=(
-				'start:Start a new release branch.'
-				'finish:Finish a release branch.'
-				'list:List all your release branches. (Alias to `git flow release`)'
-				'publish: public'
-				'track: track'
-			)
-			_describe -t commands 'git flow release' subcommands
-			_arguments \
-				-v'[Verbose (more) output]'
-		;;
-
-		(options)
-			case $line[1] in
-
-				(start)
-					_arguments \
-						-F'[Fetch from origin before performing finish]'\
-						':version:__git_flow_version_list'
-				;;
-
-				(finish)
-					_arguments \
-						-F'[Fetch from origin before performing finish]' \
-						-s'[Sign the release tag cryptographically]'\
-						-u'[Use the given GPG-key for the digital signature (implies -s)]'\
-						-m'[Use the given tag message]'\
-						-p'[Push to $ORIGIN after performing finish]'\
-						-k'[Keep branch after performing finish]'\
-						-n"[Don't tag this release]"\
-						':version:__git_flow_version_list'
-				;;
-
-				(publish)
-					_arguments \
-						':version:__git_flow_version_list'\
-				;;
-
-				(track)
-					_arguments \
-						':version:__git_flow_version_list'\
-				;;
-
-				*)
-					_arguments \
-						-v'[Verbose (more) output]'
-				;;
-			esac
-		;;
-	esac
-}
-
-__git-flow-hotfix ()
-{
-	local curcontext="$curcontext" state line
-	typeset -A opt_args
-
-	_arguments -C \
-		':command:->command' \
-		'*::options:->options'
-
-	case $state in
-		(command)
-
-			local -a subcommands
-			subcommands=(
-				'start:Start a new hotfix branch.'
-				'finish:Finish a hotfix branch.'
-				'list:List all your hotfix branches. (Alias to `git flow hotfix`)'
-			)
-			_describe -t commands 'git flow hotfix' subcommands
-			_arguments \
-				-v'[Verbose (more) output]'
-		;;
-
-		(options)
-			case $line[1] in
-
-				(start)
-					_arguments \
-						-F'[Fetch from origin before performing finish]'\
-						':hotfix:__git_flow_version_list'\
-						':branch-name:__git_branch_names'
-				;;
-
-				(finish)
-					_arguments \
-						-F'[Fetch from origin before performing finish]' \
-						-s'[Sign the release tag cryptographically]'\
-						-u'[Use the given GPG-key for the digital signature (implies -s)]'\
-						-m'[Use the given tag message]'\
-						-p'[Push to $ORIGIN after performing finish]'\
-						-k'[Keep branch after performing finish]'\
-						-n"[Don't tag this release]"\
-						':hotfix:__git_flow_hotfix_list'
-				;;
-
-				*)
-					_arguments \
-						-v'[Verbose (more) output]'
-				;;
-			esac
-		;;
-	esac
-}
-
-__git-flow-feature ()
-{
-	local curcontext="$curcontext" state line
-	typeset -A opt_args
-
-	_arguments -C \
-		':command:->command' \
-		'*::options:->options'
-
-	case $state in
-		(command)
-
-			local -a subcommands
-			subcommands=(
-				'start:Start a new feature branch.'
-				'finish:Finish a feature branch.'
-				'list:List all your feature branches. (Alias to `git flow feature`)'
-				'publish: publish'
-				'track: track'
-				'diff: diff'
-				'rebase: rebase'
-				'checkout: checkout'
-				'pull: pull'
-			)
-			_describe -t commands 'git flow feature' subcommands
-			_arguments \
-				-v'[Verbose (more) output]'
-		;;
-
-		(options)
-			case $line[1] in
-
-				(start)
-					_arguments \
-						-F'[Fetch from origin before performing finish]'\
-						':feature:__git_flow_feature_list'\
-						':branch-name:__git_branch_names'
-				;;
-
-				(finish)
-					_arguments \
-						-F'[Fetch from origin before performing finish]' \
-						-r'[Rebase instead of merge]'\
-						-k'[Keep branch after performing finish]'\
-						':feature:__git_flow_feature_list'
-				;;
-
-				(publish)
-					_arguments \
-						':feature:__git_flow_feature_list'\
-				;;
-
-				(track)
-					_arguments \
-						':feature:__git_flow_feature_list'\
-				;;
-
-				(diff)
-					_arguments \
-						':branch:__git_flow_feature_list'\
-				;;
-
-				(rebase)
-					_arguments \
-						-i'[Do an interactive rebase]' \
-						':branch:__git_flow_feature_list'
-				;;
-
-				(checkout)
-					_arguments \
-						':branch:__git_flow_feature_list'\
-				;;
-
-				(pull)
-					_arguments \
-						':remote:__git_remotes'\
-						':branch:__git_flow_feature_list'
-				;;
-
-				*)
-					_arguments \
-						-v'[Verbose (more) output]'
-				;;
-			esac
-		;;
-	esac
-}
-
-__git_flow_version_list ()
-{
-	local expl
-	declare -a versions
-
-	versions=(${${(f)"$(_call_program versions git flow release list 2> /dev/null | tr -d ' |*')"}})
-	__git_command_successful || return
-
-	_wanted versions expl 'version' compadd $versions
-}
-
-__git_flow_feature_list ()
-{
-	local expl
-	declare -a features
-
-	features=(${${(f)"$(_call_program features git flow feature list 2> /dev/null | tr -d ' |*')"}})
-	__git_command_successful || return
-
-	_wanted features expl 'feature' compadd $features
-}
-
-__git_remotes () {
-	local expl gitdir remotes
-
-	gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
-	__git_command_successful || return
-
-	remotes=(${${(f)"$(_call_program remotes git config --get-regexp '"^remote\..*\.url$"')"}//#(#b)remote.(*).url */$match[1]})
-	__git_command_successful || return
-
-	# TODO: Should combine the two instead of either or.
-	if (( $#remotes > 0 )); then
-		_wanted remotes expl remote compadd $* - $remotes
-	else
-		_wanted remotes expl remote _files $* - -W "($gitdir/remotes)" -g "$gitdir/remotes/*"
-	fi
-}
-
-__git_flow_hotfix_list ()
-{
-	local expl
-	declare -a hotfixes
-
-	hotfixes=(${${(f)"$(_call_program hotfixes git flow hotfix list 2> /dev/null | tr -d ' |*')"}})
-	__git_command_successful || return
-
-	_wanted hotfixes expl 'hotfix' compadd $hotfixes
-}
-
-__git_branch_names () {
-	local expl
-	declare -a branch_names
-
-	branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
-	__git_command_successful || return
-
-	_wanted branch-names expl branch-name compadd $* - $branch_names
-}
-
-__git_command_successful () {
-	if (( ${#pipestatus:#0} > 0 )); then
-		_message 'not a git repository'
-		return 1
-	fi
-	return 0
-}
-
-zstyle ':completion:*:*:git:*' user-commands flow:'description for foo'
+# Source completion script
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+source "${0:A:h}/_git-flow"