submodules: add the lib-submodule-update.sh test library

Add this test library to simplify covering all combinations of submodule
update scenarios without having to add those to a test of each work tree
manipulating command over and over again.

The functions test_submodule_switch() and test_submodule_forced_switch()
are intended to be called from a test script with a single argument. This
argument is either a work tree manipulating command (including any command
line options) or a function (when more than a single git command is needed
to switch work trees from the current HEAD to another commit). This
command (or function) is passed a target branch as argument. The two new
functions check that each submodule transition is handled as expected,
which currently means that submodule work trees are not affected until
"git submodule update" is called. The "forced" variant is for commands
using their '-f' or '--hard' option and expects them to overwrite local
modifications as a result. Each of these two functions contains 14
tests_expect_* calls.

Calling one of these test functions the first time creates a repository
named "submodule_update_repo". At first it contains two files, then a
single submodule is added in another commit followed by commits covering
all relevant submodule modifications. This repository is newly cloned into
the "submodule_update" for each test_expect_* to avoid interference
between different parts of the test functions (some to-be-tested commands
also manipulate refs along with the work tree, e.g. "git reset").

Follow-up commits will then call these two test functions for all work
tree manipulating commands (with a combination of all their options
relevant to what they do with the work tree) making sure they work as
expected. Later this test library will be extended to cover merges
resulting in conflicts too. Also it is intended to be easily extendable
for the recursive update functionality, where even more combinations of
submodule modifications have to be tested for.

This version documents two bugs in current Git with expected failures:

*) When a submodule is replaced with a tracked file of the same name the
   submodule work tree including any local modifications (and even the
   whole history if it uses a .git directory instead of a gitfile!) is
   silently removed.

*) Forced work tree updates happily manipulate files in the directory of a
   submodule that has just been removed in the superproject (but is of
   course still present in the work tree due to the way submodules are
   currently handled). This becomes dangerous when files in the submodule
   directory are overwritten by files from the new superproject commit, as
   any modifications to the submodule files will be lost) and is expected
   to also destroy history in the - admittedly unlikely case - the new
   commit adds a file named ".git" to the submodule directory.

Signed-off-by: Jens Lehmann <3a81d01482cca860e4077eb409d7db78ebdc6f24@web.de>
Signed-off-by: Junio C Hamano <a6723cc3f76163bf7adb636a73ac3b0ceb3e6b9b@pobox.com>

# Create a submodule layout used for all tests below.
#
# The following use cases are covered:
# - New submodule (no_submodule => add_sub1)
# - Removed submodule (add_sub1 => remove_sub1)
# - Updated submodule (add_sub1 => modify_sub1)
# - Submodule updated to invalid commit (add_sub1 => invalid_sub1)
# - Submodule updated from invalid commit (invalid_sub1 => valid_sub1)
# - Submodule replaced by tracked files in directory (add_sub1 =>
#   replace_sub1_with_directory)
# - Directory containing tracked files replaced by submodule
#   (replace_sub1_with_directory => replace_directory_with_sub1)
# - Submodule replaced by tracked file with the same name (add_sub1 =>
#   replace_sub1_with_file)
# - Tracked file replaced by submodule (replace_sub1_with_file =>
#   replace_file_with_sub1)
#
#                   --O-----O
#                  /  ^     replace_directory_with_sub1
#                 /   replace_sub1_with_directory
#                /----O
#               /     ^
#              /      modify_sub1
#      O------O-------O
#      ^      ^\      ^
#      |      | \     remove_sub1
#      |      |  -----O-----O
#      |      |   \   ^     replace_file_with_sub1
#      |      |    \  replace_sub1_with_file
#      |   add_sub1 --O-----O
# no_submodule        ^     valid_sub1
#                     invalid_sub1
#
create_lib_submodule_repo () {
	git init submodule_update_repo &&
	(
		cd submodule_update_repo &&
		echo "expect" >>.gitignore &&
		echo "actual" >>.gitignore &&
		echo "x" >file1 &&
		echo "y" >file2 &&
		git add .gitignore file1 file2 &&
		git commit -m "Base" &&
		git branch "no_submodule" &&

		git checkout -b "add_sub1" &&
		git submodule add ./. sub1 &&
		git config -f .gitmodules submodule.sub1.ignore all &&
		git config submodule.sub1.ignore all &&
		git add .gitmodules &&
		git commit -m "Add sub1" &&
		git checkout -b remove_sub1 &&
		git revert HEAD &&

		git checkout -b "modify_sub1" "add_sub1" &&
		git submodule update &&
		(
			cd sub1 &&
			git fetch &&
			git checkout -b "modifications" &&
			echo "z" >file2 &&
			echo "x" >file3 &&
			git add file2 file3 &&
			git commit -m "modified file2 and added file3" &&
			git push origin modifications
		) &&
		git add sub1 &&
		git commit -m "Modify sub1" &&

		git checkout -b "replace_sub1_with_directory" "add_sub1" &&
		git submodule update &&
		(
			cd sub1 &&
			git checkout modifications
		) &&
		git rm --cached sub1 &&
		rm sub1/.git* &&
		git config -f .gitmodules --remove-section "submodule.sub1" &&
		git add .gitmodules sub1/* &&
		git commit -m "Replace sub1 with directory" &&
		git checkout -b replace_directory_with_sub1 &&
		git revert HEAD &&

		git checkout -b "replace_sub1_with_file" "add_sub1" &&
		git rm sub1 &&
		echo "content" >sub1 &&
		git add sub1 &&
		git commit -m "Replace sub1 with file" &&
		git checkout -b replace_file_with_sub1 &&
		git revert HEAD &&

		git checkout -b "invalid_sub1" "add_sub1" &&
		git update-index --cacheinfo 160000 0123456789012345678901234567890123456789 sub1 &&
		git commit -m "Invalid sub1 commit" &&
		git checkout -b valid_sub1 &&
		git revert HEAD &&
		git checkout master
	)
}

# Helper function to replace gitfile with .git directory
replace_gitfile_with_git_dir () {
	(
		cd "$1" &&
		git_dir="$(git rev-parse --git-dir)" &&
		rm -f .git &&
		cp -R "$git_dir" .git &&
		GIT_WORK_TREE=. git config --unset core.worktree
	)
}

# Test that the .git directory in the submodule is unchanged (except for the
# core.worktree setting, which appears only in $GIT_DIR/modules/$1/config).
# Call this function before test_submodule_content as the latter might
# write the index file leading to false positive index differences.
#
# Note that this only supports submodules at the root level of the
# superproject, with the default name, i.e. same as its path.
test_git_directory_is_unchanged () {
	(
		cd ".git/modules/$1" &&
		# does core.worktree point at the right place?
		test "$(git config core.worktree)" = "../../../$1" &&
		# remove it temporarily before comparing, as
		# "$1/.git/config" lacks it...
		git config --unset core.worktree
	) &&
	diff -r ".git/modules/$1" "$1/.git" &&
	(
		# ... and then restore.
		cd ".git/modules/$1" &&
		git config core.worktree "../../../$1"
	)
}

# Helper function to be executed at the start of every test below, it sets up
# the submodule repo if it doesn't exist and configures the most problematic
# settings for diff.ignoreSubmodules.
prolog () {
	(test -d submodule_update_repo || create_lib_submodule_repo) &&
	test_config_global diff.ignoreSubmodules all &&
	test_config diff.ignoreSubmodules all
}

# Helper function to bring work tree back into the state given by the
# commit. This includes trying to populate sub1 accordingly if it exists and
# should be updated to an existing commit.
reset_work_tree_to () {
	rm -rf submodule_update &&
	git clone submodule_update_repo submodule_update &&
	(
		cd submodule_update &&
		rm -rf sub1 &&
		git checkout -f "$1" &&
		git status -u -s >actual &&
		test_must_be_empty actual &&
		sha1=$(git rev-parse --revs-only HEAD:sub1) &&
		if test -n "$sha1" &&
		   test $(cd "sub1" && git rev-parse --verify "$sha1^{commit}")
		then
			git submodule update --init --recursive "sub1"
		fi
	)
}

# Test that the superproject contains the content according to commit "$1"
# (the work tree must match the index for everything but submodules but the
# index must exactly match the given commit including any submodule SHA-1s).
test_superproject_content () {
	git diff-index --cached "$1" >actual &&
	test_must_be_empty actual &&
	git diff-files --ignore-submodules >actual &&
	test_must_be_empty actual
}

# Test that the given submodule at path "$1" contains the content according
# to the submodule commit recorded in the superproject's commit "$2"
test_submodule_content () {
	if test $# != 2
	then
		echo "test_submodule_content needs two arguments"
		return 1
	fi &&
	submodule="$1" &&
	commit="$2" &&
	test -d "$submodule"/ &&
	if ! test -f "$submodule"/.git && ! test -d "$submodule"/.git
	then
		echo "Submodule $submodule is not populated"
		return 1
	fi &&
	sha1=$(git rev-parse --verify "$commit:$submodule") &&
	if test -z "$sha1"
	then
		echo "Couldn't retrieve SHA-1 of $submodule for $commit"
		return 1
	fi &&
	(
		cd "$submodule" &&
		git status -u -s >actual &&
		test_must_be_empty actual &&
		git diff "$sha1" >actual &&
		test_must_be_empty actual
	)
}

# Test that the following transitions are correctly handled:
# - Updated submodule
# - New submodule
# - Removed submodule
# - Directory containing tracked files replaced by submodule
# - Submodule replaced by tracked files in directory
# - Submodule replaced by tracked file with the same name
# - tracked file replaced by submodule
#
# The default is that submodule contents aren't changed until "git submodule
# update" is run. And even then that command doesn't delete the work tree of
# a removed submodule.
#
# Removing a submodule containing a .git directory must fail even when forced
# to protect the history!
#

# Test that submodule contents are currently not updated when switching
# between commits that change a submodule.
test_submodule_switch () {
	command="$1"
	######################### Appearing submodule #########################
	# Switching to a commit letting a submodule appear creates empty dir ...
	test_expect_success "$command: added submodule creates empty directory" '
		prolog &&
		reset_work_tree_to no_submodule &&
		(
			cd submodule_update &&
			git branch -t add_sub1 origin/add_sub1 &&
			$command add_sub1 &&
			test_superproject_content origin/add_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... and doesn't care if it already exists ...
	test_expect_success "$command: added submodule leaves existing empty directory alone" '
		prolog &&
		reset_work_tree_to no_submodule &&
		(
			cd submodule_update &&
			mkdir sub1 &&
			git branch -t add_sub1 origin/add_sub1 &&
			$command add_sub1 &&
			test_superproject_content origin/add_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... unless there is an untracked file in its place.
	test_expect_success "$command: added submodule doesn't remove untracked unignored file with same name" '
		prolog &&
		reset_work_tree_to no_submodule &&
		(
			cd submodule_update &&
			git branch -t add_sub1 origin/add_sub1 &&
			>sub1 &&
			test_must_fail $command add_sub1 &&
			test_superproject_content origin/no_submodule &&
			test_must_be_empty sub1
		)
	'
	# Replacing a tracked file with a submodule produces an empty
	# directory ...
	test_expect_success "$command: replace tracked file with submodule creates empty directory" '
		prolog &&
		reset_work_tree_to replace_sub1_with_file &&
		(
			cd submodule_update &&
			git branch -t replace_file_with_sub1 origin/replace_file_with_sub1 &&
			$command replace_file_with_sub1 &&
			test_superproject_content origin/replace_file_with_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/replace_file_with_sub1
		)
	'
	# ... as does removing a directory with tracked files with a
	# submodule.
	test_expect_success "$command: replace directory with submodule" '
		prolog &&
		reset_work_tree_to replace_sub1_with_directory &&
		(
			cd submodule_update &&
			git branch -t replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
			$command replace_directory_with_sub1 &&
			test_superproject_content origin/replace_directory_with_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/replace_directory_with_sub1
		)
	'

	######################## Disappearing submodule #######################
	# Removing a submodule doesn't remove its work tree ...
	test_expect_success "$command: removed submodule leaves submodule directory and its contents in place" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t remove_sub1 origin/remove_sub1 &&
			$command remove_sub1 &&
			test_superproject_content origin/remove_sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... especially when it contains a .git directory.
	test_expect_success "$command: removed submodule leaves submodule containing a .git directory alone" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t remove_sub1 origin/remove_sub1 &&
			replace_gitfile_with_git_dir sub1 &&
			$command remove_sub1 &&
			test_superproject_content origin/remove_sub1 &&
			test_git_directory_is_unchanged sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# Replacing a submodule with files in a directory must fail as the
	# submodule work tree isn't removed ...
	test_expect_success "$command: replace submodule with a directory must fail" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
			test_must_fail $command replace_sub1_with_directory &&
			test_superproject_content origin/add_sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... especially when it contains a .git directory.
	test_expect_success "$command: replace submodule containing a .git directory with a directory must fail" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
			replace_gitfile_with_git_dir sub1 &&
			test_must_fail $command replace_sub1_with_directory &&
			test_superproject_content origin/add_sub1 &&
			test_git_directory_is_unchanged sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# Replacing it with a file must fail as it could throw away any local
	# work tree changes ...
	test_expect_failure "$command: replace submodule with a file must fail" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
			test_must_fail $command replace_sub1_with_file &&
			test_superproject_content origin/add_sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... or even destroy unpushed parts of submodule history if that
	# still uses a .git directory.
	test_expect_failure "$command: replace submodule containing a .git directory with a file must fail" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
			replace_gitfile_with_git_dir sub1 &&
			test_must_fail $command replace_sub1_with_file &&
			test_superproject_content origin/add_sub1 &&
			test_git_directory_is_unchanged sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'

	########################## Modified submodule #########################
	# Updating a submodule sha1 doesn't update the submodule's work tree
	test_expect_success "$command: modified submodule does not update submodule work tree" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t modify_sub1 origin/modify_sub1 &&
			$command modify_sub1 &&
			test_superproject_content origin/modify_sub1 &&
			test_submodule_content sub1 origin/add_sub1 &&
			git submodule update &&
			test_submodule_content sub1 origin/modify_sub1
		)
	'

	# Updating a submodule to an invalid sha1 doesn't update the
	# submodule's work tree, subsequent update will fail
	test_expect_success "$command: modified submodule does not update submodule work tree to invalid commit" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t invalid_sub1 origin/invalid_sub1 &&
			$command invalid_sub1 &&
			test_superproject_content origin/invalid_sub1 &&
			test_submodule_content sub1 origin/add_sub1 &&
			test_must_fail git submodule update &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# Updating a submodule from an invalid sha1 doesn't update the
	# submodule's work tree, subsequent update will succeed
	test_expect_success "$command: modified submodule does not update submodule work tree from invalid commit" '
		prolog &&
		reset_work_tree_to invalid_sub1 &&
		(
			cd submodule_update &&
			git branch -t valid_sub1 origin/valid_sub1 &&
			$command valid_sub1 &&
			test_superproject_content origin/valid_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/valid_sub1
		)
	'
}

# Test that submodule contents are currently not updated when switching
# between commits that change a submodule, but throwing away local changes in
# the superproject is allowed.
test_submodule_forced_switch () {
	command="$1"
	######################### Appearing submodule #########################
	# Switching to a commit letting a submodule appear creates empty dir ...
	test_expect_success "$command: added submodule creates empty directory" '
		prolog &&
		reset_work_tree_to no_submodule &&
		(
			cd submodule_update &&
			git branch -t add_sub1 origin/add_sub1 &&
			$command add_sub1 &&
			test_superproject_content origin/add_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... and doesn't care if it already exists ...
	test_expect_success "$command: added submodule leaves existing empty directory alone" '
		prolog &&
		reset_work_tree_to no_submodule &&
		(
			cd submodule_update &&
			git branch -t add_sub1 origin/add_sub1 &&
			mkdir sub1 &&
			$command add_sub1 &&
			test_superproject_content origin/add_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... unless there is an untracked file in its place.
	test_expect_success "$command: added submodule does remove untracked unignored file with same name when forced" '
		prolog &&
		reset_work_tree_to no_submodule &&
		(
			cd submodule_update &&
			git branch -t add_sub1 origin/add_sub1 &&
			>sub1 &&
			$command add_sub1 &&
			test_superproject_content origin/add_sub1 &&
			test_dir_is_empty sub1
		)
	'
	# Replacing a tracked file with a submodule produces an empty
	# directory ...
	test_expect_success "$command: replace tracked file with submodule creates empty directory" '
		prolog &&
		reset_work_tree_to replace_sub1_with_file &&
		(
			cd submodule_update &&
			git branch -t replace_file_with_sub1 origin/replace_file_with_sub1 &&
			$command replace_file_with_sub1 &&
			test_superproject_content origin/replace_file_with_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/replace_file_with_sub1
		)
	'
	# ... as does removing a directory with tracked files with a
	# submodule.
	test_expect_success "$command: replace directory with submodule" '
		prolog &&
		reset_work_tree_to replace_sub1_with_directory &&
		(
			cd submodule_update &&
			git branch -t replace_directory_with_sub1 origin/replace_directory_with_sub1 &&
			$command replace_directory_with_sub1 &&
			test_superproject_content origin/replace_directory_with_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/replace_directory_with_sub1
		)
	'

	######################## Disappearing submodule #######################
	# Removing a submodule doesn't remove its work tree ...
	test_expect_success "$command: removed submodule leaves submodule directory and its contents in place" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t remove_sub1 origin/remove_sub1 &&
			$command remove_sub1 &&
			test_superproject_content origin/remove_sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... especially when it contains a .git directory.
	test_expect_success "$command: removed submodule leaves submodule containing a .git directory alone" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t remove_sub1 origin/remove_sub1 &&
			replace_gitfile_with_git_dir sub1 &&
			$command remove_sub1 &&
			test_superproject_content origin/remove_sub1 &&
			test_git_directory_is_unchanged sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# Replacing a submodule with files in a directory must fail as the
	# submodule work tree isn't removed ...
	test_expect_failure "$command: replace submodule with a directory must fail" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
			test_must_fail $command replace_sub1_with_directory &&
			test_superproject_content origin/add_sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... especially when it contains a .git directory.
	test_expect_failure "$command: replace submodule containing a .git directory with a directory must fail" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t replace_sub1_with_directory origin/replace_sub1_with_directory &&
			replace_gitfile_with_git_dir sub1 &&
			test_must_fail $command replace_sub1_with_directory &&
			test_superproject_content origin/add_sub1 &&
			test_git_directory_is_unchanged sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# Replacing it with a file must fail as it could throw away any local
	# work tree changes ...
	test_expect_failure "$command: replace submodule with a file must fail" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
			test_must_fail $command replace_sub1_with_file &&
			test_superproject_content origin/add_sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# ... or even destroy unpushed parts of submodule history if that
	# still uses a .git directory.
	test_expect_failure "$command: replace submodule containing a .git directory with a file must fail" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t replace_sub1_with_file origin/replace_sub1_with_file &&
			replace_gitfile_with_git_dir sub1 &&
			test_must_fail $command replace_sub1_with_file &&
			test_superproject_content origin/add_sub1 &&
			test_git_directory_is_unchanged sub1 &&
			test_submodule_content sub1 origin/add_sub1
		)
	'

	########################## Modified submodule #########################
	# Updating a submodule sha1 doesn't update the submodule's work tree
	test_expect_success "$command: modified submodule does not update submodule work tree" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t modify_sub1 origin/modify_sub1 &&
			$command modify_sub1 &&
			test_superproject_content origin/modify_sub1 &&
			test_submodule_content sub1 origin/add_sub1 &&
			git submodule update &&
			test_submodule_content sub1 origin/modify_sub1
		)
	'
	# Updating a submodule to an invalid sha1 doesn't update the
	# submodule's work tree, subsequent update will fail
	test_expect_success "$command: modified submodule does not update submodule work tree to invalid commit" '
		prolog &&
		reset_work_tree_to add_sub1 &&
		(
			cd submodule_update &&
			git branch -t invalid_sub1 origin/invalid_sub1 &&
			$command invalid_sub1 &&
			test_superproject_content origin/invalid_sub1 &&
			test_submodule_content sub1 origin/add_sub1 &&
			test_must_fail git submodule update &&
			test_submodule_content sub1 origin/add_sub1
		)
	'
	# Updating a submodule from an invalid sha1 doesn't update the
	# submodule's work tree, subsequent update will succeed
	test_expect_success "$command: modified submodule does not update submodule work tree from invalid commit" '
		prolog &&
		reset_work_tree_to invalid_sub1 &&
		(
			cd submodule_update &&
			git branch -t valid_sub1 origin/valid_sub1 &&
			$command valid_sub1 &&
			test_superproject_content origin/valid_sub1 &&
			test_dir_is_empty sub1 &&
			git submodule update --init --recursive &&
			test_submodule_content sub1 origin/valid_sub1
		)
	'
}

error: pathspec 't/lib-submodule-update.sh' did not match any file(s) known to git


Mod in example

Mod in example

Former-commit-id: ce840451d4df1260ef7c40d86fe8cb86a4c4f6a5 [formerly ae04111a7c429e7e71d8dc32d2ac61c8c48f5499] [formerly e3e2a67281f29459a2ff6f4d88cf0ecc4f41e886 [formerly a692359edbf811fb3c87e97eb83db9ff0c2f78be]]
Former-commit-id: 90f937ea997eb2b91bbb9f7ffc9e2ba0df9791b8
Former-commit-id: 0e4b743ecca2b4327f3ed60d932561a25a0a0052

#!/bin/bash
echo "Example downloads ./testdata directory from http://mrbrain.cs.jhu.edu/data/projects/disa/OCPprojects/testdata/ ..."
echo "Example script running ..."

# Exit script on first error
set -e

# VAR DECL
TEST_DATA=./testdata
FIBER=$TEST_DATA/test_fiber.dat
ROI_XML=$TEST_DATA/test_roi.xml
ROI_RAW=$TEST_DATA/test_roi.raw
SMALL_DIR=$TEST_DATA/small
BIG_DIR=$TEST_DATA/big

SMALL_GR_FN=test_fiber_small.graphml
BIG_GR_FN=test_fiber_big.graphml

if [ ! -d $TEST_DATA ]
then
  echo "making $TEST_DATA directory ..."
  mkdir $TEST_DATA
fi

if [ -f $FIBER ]
then
  echo "$FIBER exists ..."
else
  echo "Downloading $FIBER file..."
  wget --output-document=$FIBER http://mrbrain.cs.jhu.edu/data/projects/disa/OCPprojects/testdata/test_fiber.dat
fi

if [ -f $ROI_RAW ]
then
  echo "$ROI_RAW exists ..."
else
  echo "Downloading $ROI_RAW file..."
  wget --output-document=$ROI_RAW http://mrbrain.cs.jhu.edu/data/projects/disa/OCPprojects/testdata/test_roi.raw
fi

if [ -f $ROI_XML ]
then
  echo "$ROI_XML exists ..."
else
  echo "Downloading $ROI_XML file..."
  wget --output-document=$ROI_XML http://mrbrain.cs.jhu.edu/data/projects/disa/OCPprojects/testdata/test_roi.xml
fi

# SMALL
# Graph generation:
echo "../graph_exec -h. For help"
# Build a small graph given fiber streamline: test_fiber, fiber ROI's: test_roi.xml and test_roi.raw
python ../graph_exec $FIBER $ROI_XML $ROI_RAW -S $SMALL_DIR -g $SMALL_GR_FN

# Invariants:
echo "./inv_exec -h. For help"
python ../inv_exec $SMALL_DIR/$SMALL_GR_FN -A -S $SMALL_DIR

# BIG
# Uncomment to Build big graph WARNING: Can take up to 2 hours to complete
if [[ $1 == "-b" ]]; then
  python ../graph_exec $FIBER $ROI_XML $ROI_RAW -S $BIG_DIR -b -g $BIG_GR_FN

  # Invariants:
  echo "./inv_exec -h. For help"
  python .././inv_exec $BIG_DIR/$BIG_GR_FN -A -S $BIG_DIR
else
  echo 'To build a big graph pass -b as the 1 argument to the example script'
fi

#!/bin/bash
echo "Example downloads ./testdata directory from http://mrbrain.cs.jhu.edu/data/projects/disa/OCPprojects/testdata/ ..."
echo "Example script running ..."

# VAR DECL
TEST_DATA=./testdata
FIBER=$TEST_DATA/test_fiber.dat
ROI_XML=$TEST_DATA/test_roi.xml
ROI_RAW=$TEST_DATA/test_roi.raw
SMALL_DIR=$TEST_DATA/small
BIG_DIR=$TEST_DATA/big

SMALL_GR_FN=test_fiber_small.graphml
BIG_GR_FN=test_fiber_big.graphml

if [ ! -d $TEST_DATA ]
then
  echo "making $TEST_DATA directory ..."
  mkdir $TEST_DATA
fi

if [ -f $FIBER ]
then
  echo "$FIBER exists ..."
else
  echo "Downloading $FIBER file..."
  wget --output-document=$FIBER http://mrbrain.cs.jhu.edu/data/projects/disa/OCPprojects/testdata/test_fiber.dat
fi

if [ -f $ROI_RAW ]
then
  echo "$ROI_RAW exists ..."
else
  echo "Downloading $ROI_RAW file..."
  wget --output-document=$ROI_RAW http://mrbrain.cs.jhu.edu/data/projects/disa/OCPprojects/testdata/test_roi.raw
fi

if [ -f $ROI_XML ]
then
  echo "$ROI_XML exists ..."
else
  echo "Downloading $ROI_XML file..."
  wget --output-document=$ROI_XML http://mrbrain.cs.jhu.edu/data/projects/disa/OCPprojects/testdata/test_roi.xml
fi

# SMALL
# Graph generation:
echo "../graph_exec -h. For help"
# Build a small graph given fiber streamline: test_fiber, fiber ROI's: test_roi.xml and test_roi.raw
../graph_exec $FIBER $ROI_XML $ROI_RAW -S $SMALL_DIR -g $SMALL_GR_FN

# Invariants:
echo "./inv_exec -h. For help"
../inv_exec $SMALL_DIR/$SMALL_GR_FN -A -S $SMALL_DIR

# BIG
# Uncomment to Build big graph WARNING: Can take up to 6 hours to complete
../graph_exec $FIBER $ROI_XML $ROI_RAW -S $BIG_DIR -b -g $BIG_GR_FN

# Invariants:
echo "./inv_exec -h. For help"
.././inv_exec $BIG_DIR/$BIG_GR_FN -A -S $BIG_DIR


Don't send notifications for services on a host that is down

Change-Id: I16a17358220f66813482f25833daf685327c4022

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/B-LUC/NMS.git/'


Adding missing file required by RailsService

git-svn-id: 9e8631a84d97bf96d7d440e76c2e3d95216d1dc3@835932 13f79535-47bb-0310-9956-ffa450edef68

#!/bin/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.
#
# This script captures various information related to the rails app
# running environment. It is used by the 'RailsService'.
#
# First locate ruby
RUBY=`which ruby`
if [ $? -eq 0 ] ; then
	echo "Ruby version"
	echo "------------"
	$RUBY -v
	echo "\n"
fi

GEM=`which gem`
if [ $? -eq 0 ] ; then
    echo "Gems Installed"
	echo "--------------"
	$GEM list
fi

error: pathspec 'workload/rails/trunk/bin/rails_env.sh' did not match any file(s) known to git


Create ArduinoEventStatesURI_bashCompanion_backupBeforeUsing_xinputForKeyPresses.sh

#!/bin/bash

# quick & ditry test to see if "We/I can make this particular bear dance [again]" ;D
#
# Nb: digg the following for maybe a way to know wich keys are currently pressed ( aka more than one at a time -> better to update our event states URI ;p )
# http://superuser.com/questions/248517/show-keys-pressed-in-linux
# also
# http://stackoverflow.com/questions/9731281/bash-script-listen-for-key-press-to-move-on
# &
# http://stackoverflow.com/questions/23462221/bash-read-input-only-once-and-do-not-continue-reading-until-key-is-released

# --------------------------------------------
# Source used aliases & fcns
source ~/.bash_stephaneag_functions
source ~/.bash_stephaneag_aliases

# --------------------------------------------
# trap ctrl-c and call ctrl_c() ( useful for cleanup )
trap ctrl_c INT

ctrl_c() {
  #echo
  #echo "** Trapped CTRL-C ! **"
  # do some cleanup
  cleanup

  # fix to restore the prompt ( ' having invisible commands typing, because "read" disbles local echo ( .. ) )
  #reset - as efficient but has side effects :/
  stty "$console_bckp"

  exit 0
}

#--------------------------------------------
# cleanup
cleanup(){
  # TODO: delete file descriptor used for the Arduino serial conn
  echo -en "\rcleanup done!"
}

#--------------------------------------------
# Arduino event states URI chunks
read_chunk_C1=0   # chunk #1  ( ltrig )
read_chunk_H1=0   # chunk #2  ( rtrig )
read_chunk_C2=128 # chunk #3  ( ljoyY )      / resting voltage 2.3V on 4.6V
read_chunk_H2=128 # chunk #4  ( ljoyX )      / resting voltage 2.3V on 4.6V
read_chunk_C3=1   # chunk #5  ( ljoyS )      / HIGH by default ( 4.4V on 4.6V )
read_chunk_H3=128 # chunk #6  ( rjoyY )      / resting voltage 2.3V on 4.6V
read_chunk_C4=128 # chunk #7  ( rjoyX )      / resting voltage 2.3V on 4.6V
read_chunk_H4=1   # chunk #8  ( rjoyS )      / HIGH by default ( 4.4V on 4.6V )
read_chunk_C5=1   # chunk #9  ( btnBack )    / HIGH by default ( 4.4V on 4.6V )
read_chunk_H5=1   # chunk #10 ( btnStart )   / HIGH by default ( 4.4V on 4.6V )
read_chunk_C6=0   # chunk #11 ( btnY )
read_chunk_H6=0   # chunk #12 ( btnA )
read_chunk_C7=0   # chunk #13 ( btnX )
read_chunk_H7=0   # chunk #14 ( btnB )
read_chunk_C8=1   # chunk #15 ( keypadUp )   / HIGH by default ( 4.4V on 4.6V )
read_chunk_H8=1   # chunk #16 ( keypadDown ) / HIGH by default ( 4.4V on 4.6V )

#--------------------------------------------
# No need to specify control defaults ( & neither keyup events ) as they're automatically reset at the beginning of each loop on the uC side

#--------------------------------------------
# Analog controls defaults & range to be used in arithmetical expressions responsible for smoothing - not currently used
# chunk #1  ( ltrig )
ltrig_min=0
ltrig_max=255
curr_ltrig=0
# chunk #2  ( rtrig )
ltrig_min=0
ltrig_max=255
curr_ltrig=0

# chunk #3  ( ljoyY )      / resting voltage 2.3V on 4.6V
ljoyY_min=0
ljoyY_max=255
curr_ljoyY=128
# chunk #4  ( ljoyX )      / resting voltage 2.3V on 4.6V
ljoyY_min=0
ljoyY_max=255
curr_ljoyY=128
# chunk #6  ( rjoyY )      / resting voltage 2.3V on 4.6V
ljoyY_min=0
ljoyY_max=255
curr_ljoyY=128
# chunk #7  ( rjoyX )      / resting voltage 2.3V on 4.6V
ljoyY_min=0
ljoyY_max=255
curr_ljoyY=128

#--------------------------------------------
# Simple arithmetical expressions & stuff ( maybe to be used later with AAF for a character control on a map ? ;P )
x=0
x_max=100 # screen width
y=0
y_max=50 # screen height
curr_x=50
curr_y=25

zoom=0
zoom_max=100
curr_zoom=50

#--------------------------------------------
# Functions using arithmetical expressions to update curr_x & curr_y, and also curr_zoom ;)
upKeyPress(){
  if (( "$curr_x" >= "$x_max" )); then
    curr_x="$x"
  else
    let curr_x++
  fi
}
downKeyPress(){
  if (( "$curr_x" <= "$x" )); then
    curr_x="$x_max"
  else
    let curr_x--
  fi
}
leftKeyPress(){
  if (( "$curr_y" <= "$y" )); then
    curr_y="$y_max"
  else
    let curr_y--
  fi
}
rightKeyPress(){
  if (( "$curr_y" >= "$y_max" )); then
    curr_y="$y"
  else
    let curr_y++
  fi
}

#--------------------------------------------
# Event states URI logging
# the following is the default uC callback received from serial
eventStatesURI="ltrig:0/rtrig:0/ljoyY:128/ljoyX:128/ljoyS:1/rjoyY:128/rjoyX:128/rjoyS:1/back:1/start:1/Y:0/A:0/X:0/B:0/Up:1/Up:1"
logEventStates(){
  echo -en "\rARDUINO CALLBACK: [ $eventStatesURI ]"
}

#--------------------------------------------
# Hacky handling of arrow keys ( using "A"(up), "B"(down), "D"(left), "C"(right))
hackyKeyboardHandle(){
  # fix to prevent previous lines from appearing ( contains more spaces than the most wide stuff echoed, nb: better ? -> cursor ( AAF ) )
  echo -en "\r                                                                                "
  case $key in
  x) ltrigPress ;; # LTRIG
  n) rtrigPress ;; # RTRIG
  f) ljoyUp ;; # LJOY UP
  v) ljoyDown ;; # LJOY DOWN
  d) ljoyLeft ;; # LJOY LEFT
  g) ljoyRight ;; # LJOY RIGHT
  r) ljoySelect ;; # LJOY SELECT
  A) btnYPress ;; # BTN Y
  B) btnAPress ;; # BTN A
  D) btnXPress ;; # BTN X
  C) btnBPress ;; # BTN B
  u) btnBackPress ;; # BTN BACK
  i) btnStartPress ;; # BTN START
  o) keypadUpPress ;; # KEYPAD UP
  p) keypadUpPress ;; # KEYPAD DOWN
  *) logInfos $key # helpful for debugging
  esac

  # log either the default infos or actual infos updated after getting a serial callback from the Arduino
  logEventStates

}

#--------------------------------------------
#Init & args debug

# TODO: init the arduino serial conn & hackety trick

# fix to restore the prompt ( see code in trap Ctrl-C )
console_bckp=$(stty -g)

#--------------------------------------------
# Automation -> if we're passed an automation script, we should source it instead of runnig an infinite loop to get the user's controls
# the so-colled automation script is
automation_path_arg="$1"
echo "AUTOMATION PATH PASSED AS ARG: $automation_path_arg"

#--------------------------------------------
# Infinite loop
while true
do
  read -s -n1 key # Read 1 characters.
  #echo -en "\rREAD: [" $key "]"
  hackyKeyboardHandle
done

error: pathspec 'pyxhook/symlink_checkArduinoDevUsingBashTtyTest/ArduinoEventStatesURI_bashCompanion_backupBeforeUsing_xinputForKeyPresses.sh' did not match any file(s) known to git


vmware: Added upload to vcloud script

vmware: Added upload to vcloud script

#!/bin/bash

ovftool_location="/Applications/VMware OVF Tool/ovftool"
vcloud_address=""
username=""
org=""
vapp=""

file_to_upload=$1
if [ -z $file_to_upload ]; then
	echo No file supplied, exiting
	exit 1
fi

"$ovftool_location" --overwrite $file_to_upload "vcloud://$username@$vcloud_address:443?org=$org&vapp=$vapp"

error: pathspec 'vmware/upload_to_vcloud.sh' did not match any file(s) known to git


Update Expand to External Drive.sh

Update Expand to External Drive.sh

Added -w to final check. Needed due to changes in RetroPie caused by upstream changes in Raspbian

error: pathspec 'EAZYHAX/Expand' did not match any file(s) known to git
error: pathspec 'to' did not match any file(s) known to git
error: pathspec 'External' did not match any file(s) known to git
error: pathspec 'Drive.sh' did not match any file(s) known to git


added generic skript to rebuild packages that are using python3.9

#!/bin/bash
####
# @see: https://linuxundich.de/gnu-linux/upgrade-auf-python-3-10-zeit-die-aur-pakete-neu-zu-bauen/
# @since 2018-07-22
# @author stev leibelt <artodeto@bazzline.net>
####

function _upgrade()
{
    local PACKAGEMANAGER='';
    local PATH_TO_OUTDATED_PYTHON_PACKAGE='/usr/lib/python3.9'

    #begin of testing if we are on the right system
    if [[ ! -f /usr/bin/pacman ]];
    then
        echo ":: Can not install on your system."
        echo "   Sorry dude, I can only install things on a arch linux."

        exit 1
    fi

    if [[ -f /usr/bin/yay ]];
    then
        PACKAGEMANAGER='yay';
    elif [[ -f /usr/bin/paru ]];
    then
        PACKAGEMANAGER='yay';
    else
        echo ":: Can not upgrade your aur python packages."
        echo "   Neither yay or paru was found."

        exit 2
    fi

    echo ":: Fetching python packages to upgrade."
    pacman -Qop "${PATH_TO_OUTDATED_PYTHON_PACKAGE}"

    echo ""
    echo ":: Rebuilding packages."
    pacman -Qop "${PATH_TO_OUTDATED_PYTHON_PACKAGE}" | ${PACKAGEMANAGER} -S - --rebuild

    echo ":: Just for testing ... fetching python packages to upgrade."
    pacman -Qop "${PATH_TO_OUTDATED_PYTHON_PACKAGE}"
}

_upgrade

error: pathspec 'setup/package_manager/python_rebuild_packages.sh' did not match any file(s) known to git


Jump through some hoops to deal with pycalendar putting its python code into a subdirectory.

git-svn-id: 0c33e958600270102f91bf5868e396345dde476c@7210 e27351fd-9f3e-4f54-a53b-843176b1656c

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/red-hood/calendarserver.git/'


forgot to add in merge of buzz5

forgot to add in merge of buzz5

error: pathspec 'xio/xioperf/source/dirt.sh' did not match any file(s) known to git


Add plex xrandr screenlayout config

Add plex xrandr screenlayout config

#!/bin/sh
xrandr --output VGA-1 --off --output HDMI-1 --off --output DP-1 --mode 1920x1200 --pos 0x640 --rotate right --output HDMI-2 --off --output DP-2 --mode 2560x1600 --pos 1200x0 --rotate right

error: pathspec '.config/screenlayout/plex.sh' did not match any file(s) known to git


Rename external init build script

Rename external init build script

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Kittyhacker101-Software/KatOS.git/'


Create zsh-complete-behaviour.zsh

Create zsh-complete-behaviour.zsh

# {{{ File header ##############################################################
#                                                                              #
# File informations:                                                           #
# - Name:    zsh-complete-behaviour.zsh                                        #
# - Summary: Definition of the ZSH completion behaviour.                       #
# - Authors:                                                                   #
#   - Alessandro Molari <molari.alessandro@gmail.com> (alem0lars)              #
#                                                                              #
# Project informations:                                                        #
#   - Homepage:        https://github.com/alem0lars/zsh-complete-behaviour     #
#   - Getting started: see README.md in the project root folder                #
#                                                                              #
# License: Apache v2.0 (see below)                                             #
#                                                                              #
################################################################################
#                                                                              #
# Licensed to the Apache Software Foundation (ASF) under one 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.                                               #
#                                                                              #
################################################################################

# {{{ Init.

# Load and initialize the completion system ignoring insecure directories.
autoload -Uz compinit && compinit -i

# }}}

# {{{ Options.

setopt COMPLETE_IN_WORD # Complete from both ends of a word.
setopt ALWAYS_TO_END    # Move cursor to the end of a completed word.
setopt PATH_DIRS        # Perform path search even on cmd names with slashes.
setopt AUTO_MENU        # Show completion menu on a succesive tab press.
setopt AUTO_LIST        # Automatically list choices on ambiguous completion.
setopt AUTO_PARAM_SLASH # If completed param is a dir, add a trailing slash.
unsetopt MENU_COMPLETE  # Do not autoselect the first completion entry.
unsetopt FLOW_CONTROL   # Disable start/stop characters in shell editor.

# }}}

# {{{ Styles.

# Use caching to make completion for cammands such as dpkg and apt usable.
zstyle ':completion::complete:*' use-cache on
zstyle ':completion::complete:*' cache-path "${ZDOTDIR:-$HOME}/.zcompcache"

# Case-insensitive (all), partial-word, and then substring completion.
if zstyle -t ':custom:module:completion:*' case-sensitive; then
  zstyle ':completion:*' matcher-list 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
  setopt CASE_GLOB
else
  zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
  unsetopt CASE_GLOB
fi

# Group matches and describe.
zstyle ':completion:*:*:*:*:*' menu select
zstyle ':completion:*:matches' group 'yes'
zstyle ':completion:*:options' description 'yes'
zstyle ':completion:*:options' auto-description '%d'
zstyle ':completion:*:corrections' format ' %F{green}-- %d (errors: %e) --%f'
zstyle ':completion:*:descriptions' format ' %F{yellow}-- %d --%f'
zstyle ':completion:*:messages' format ' %F{purple} -- %d --%f'
zstyle ':completion:*:warnings' format ' %F{red}-- no matches found --%f'
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' format ' %F{yellow}-- %d --%f'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' verbose yes

# Fuzzy match mistyped completions.
zstyle ':completion:*' completer _complete _match _approximate
zstyle ':completion:*:match:*' original only
zstyle ':completion:*:approximate:*' max-errors 1 numeric

# Increase the number of errors based on the length of the typed word.
zstyle -e ':completion:*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'

# Don't complete unavailable commands.
zstyle ':completion:*:functions' ignored-patterns '(_*|pre(cmd|exec))'

# Array completion element sorting.
zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters

# Directories.
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories
zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand'
zstyle ':completion:*' squeeze-slashes true

# History.
zstyle ':completion:*:history-words' stop yes
zstyle ':completion:*:history-words' remove-all-dups yes
zstyle ':completion:*:history-words' list false
zstyle ':completion:*:history-words' menu yes

# Environmental variables.
zstyle ':completion::*:(-command-|export):*' fake-parameters ${${${_comps[(I)-value-*]#*,}%%,*}:#-*-}

# Populate hostname completion.
zstyle -e ':completion:*:hosts' hosts 'reply=(
  ${=${=${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) 2>/dev/null)"}%%[#| ]*}//\]:[0-9]*/ }//,/ }//\[/ }
  ${=${(f)"$(cat /etc/hosts(|)(N) <<(ypcat hosts 2>/dev/null))"}%%\#*}
  ${=${${${${(@M)${(f)"$(cat ~/.ssh/config 2>/dev/null)"}:#Host *}#Host }:#*\**}:#*\?*}}
)'

# Don't complete uninteresting users...
zstyle ':completion:*:*:*:users' ignored-patterns \
  adm amanda apache avahi beaglidx bin cacti canna clamav daemon \
  dbus distcache dovecot fax ftp games gdm gkrellmd gopher \
  hacluster haldaemon halt hsqldb ident junkbust ldap lp mail \
  mailman mailnull mldonkey mysql nagios \
  named netdump news nfsnobody nobody nscd ntp nut nx openvpn \
  operator pcap postfix postgres privoxy pulse pvm quagga radvd \
  rpc rpcuser rpm shutdown squid sshd sync uucp vcsa xfs '_*'

# ... unless we really want to.
zstyle '*' single-ignored show

# Ignore multiple entries.
zstyle ':completion:*:(rm|kill|diff):*' ignore-line other
zstyle ':completion:*:rm:*' file-patterns '*:all-files'

# {{{ Kill support.

zstyle ':completion:*:*:*:*:processes' command 'ps -u $USER -o pid,user,command -w'
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;36=0=01'
zstyle ':completion:*:*:kill:*' menu yes select
zstyle ':completion:*:*:kill:*' force-list always
zstyle ':completion:*:*:kill:*' insert-ids single

# }}}

# {{{ Man support.

zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*:manuals.(^1*)' insert-sections true

# }}}

# {{{ Media players support.

zstyle ':completion:*:*:mpg123:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories'
zstyle ':completion:*:*:mpg321:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories'
zstyle ':completion:*:*:ogg123:*' file-patterns '*.(ogg|OGG|flac):ogg\ files *(-/):directories'
zstyle ':completion:*:*:mocp:*' file-patterns '*.(wav|WAV|mp3|MP3|ogg|OGG|flac):ogg\ files *(-/):directories'

# }}}

# {{{ SSH/SCP/RSync support.

zstyle ':completion:*:(scp|rsync):*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
zstyle ':completion:*:(scp|rsync):*' group-order users files all-files hosts-domain hosts-host hosts-ipaddr
zstyle ':completion:*:ssh:*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
zstyle ':completion:*:ssh:*' group-order users hosts-domain hosts-host users hosts-ipaddr
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*(.|:)*' loopback ip6-loopback localhost ip6-localhost broadcasthost
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-domain' ignored-patterns '<->.<->.<->.<->' '^[-[:alnum:]]##(.[-[:alnum:]]##)##' '*@*'
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^(<->.<->.<->.<->|(|::)([[:xdigit:].]##:(#c,2))##(|%*))' '127.0.0.<->' '255.255.255.255' '::1' 'fe80::*'

# }}}

# {{{ Mutt support.

if [[ -s "$HOME/.mutt/aliases" ]]; then
  zstyle ':completion:*:*:mutt:*' menu yes select
  zstyle ':completion:*:mutt:*' users ${${${(f)"$(<"$HOME/.mutt/aliases")"}#alias[[:space:]]}%%[[:space:]]*}
fi

# }}}

# }}}

# vim: set filetype=zsh :

error: pathspec 'zsh-complete-behaviour.zsh' did not match any file(s) known to git


Add (generated) kops completion

Add (generated) kops completion

# Copyright 2016 The Kubernetes Authors.
#
# 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.

__kops_bash_source() {
	alias shopt=':'
	alias _expand=_bash_expand
	alias _complete=_bash_comp
	emulate -L sh
	setopt kshglob noshglob braceexpand
	source "$@"
}
__kops_type() {
	# -t is not supported by zsh
	if [ "$1" == "-t" ]; then
		shift
		# fake Bash 4 to disable "complete -o nospace". Instead
		# "compopt +-o nospace" is used in the code to toggle trailing
		# spaces. We don't support that, but leave trailing spaces on
		# all the time
		if [ "$1" = "__kops_compopt" ]; then
			echo builtin
			return 0
		fi
	fi
	type "$@"
}
__kops_compgen() {
	local completions w
	completions=( $(compgen "$@") ) || return $?
	# filter by given word as prefix
	while [[ "$1" = -* && "$1" != -- ]]; do
		shift
		shift
	done
	if [[ "$1" == -- ]]; then
		shift
	fi
	for w in "${completions[@]}"; do
		if [[ "${w}" = "$1"* ]]; then
			echo "${w}"
		fi
	done
}
__kops_compopt() {
	true # don't do anything. Not supported by bashcompinit in zsh
}
__kops_declare() {
	if [ "$1" == "-F" ]; then
		whence -w "$@"
	else
		builtin declare "$@"
	fi
}
__kops_ltrim_colon_completions()
{
	if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
		# Remove colon-word prefix from COMPREPLY items
		local colon_word=${1%${1##*:}}
		local i=${#COMPREPLY[*]}
		while [[ $((--i)) -ge 0 ]]; do
			COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
		done
	fi
}
__kops_get_comp_words_by_ref() {
	cur="${COMP_WORDS[COMP_CWORD]}"
	prev="${COMP_WORDS[${COMP_CWORD}-1]}"
	words=("${COMP_WORDS[@]}")
	cword=("${COMP_CWORD[@]}")
}
__kops_filedir() {
	local RET OLD_IFS w qw
	__debug "_filedir $@ cur=$cur"
	if [[ "$1" = \~* ]]; then
		# somehow does not work. Maybe, zsh does not call this at all
		eval echo "$1"
		return 0
	fi
	OLD_IFS="$IFS"
	IFS=$'\n'
	if [ "$1" = "-d" ]; then
		shift
		RET=( $(compgen -d) )
	else
		RET=( $(compgen -f) )
	fi
	IFS="$OLD_IFS"
	IFS="," __debug "RET=${RET[@]} len=${#RET[@]}"
	for w in ${RET[@]}; do
		if [[ ! "${w}" = "${cur}"* ]]; then
			continue
		fi
		if eval "[[ \"\${w}\" = *.$1 || -d \"\${w}\" ]]"; then
			qw="$(__kops_quote "${w}")"
			if [ -d "${w}" ]; then
				COMPREPLY+=("${qw}/")
			else
				COMPREPLY+=("${qw}")
			fi
		fi
	done
}
__kops_quote() {
    if [[ $1 == \'* || $1 == \"* ]]; then
        # Leave out first character
        printf %q "${1:1}"
    else
    	printf %q "$1"
    fi
}
autoload -U +X bashcompinit && bashcompinit
# use word boundary patterns for BSD or GNU sed
LWORD='[[:<:]]'
RWORD='[[:>:]]'
if sed --help 2>&1 | grep -q GNU; then
	LWORD='\<'
	RWORD='\>'
fi
__kops_convert_bash_to_zsh() {
	sed \
	-e 's/declare -F/whence -w/' \
	-e 's/_get_comp_words_by_ref "\$@"/_get_comp_words_by_ref "\$*"/' \
	-e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \
	-e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \
	-e 's/must_have_one_flag+=("\(--.*\)=")/must_have_one_flag+=("\1")/' \
	-e "s/${LWORD}_filedir${RWORD}/__kops_filedir/g" \
	-e "s/${LWORD}_get_comp_words_by_ref${RWORD}/__kops_get_comp_words_by_ref/g" \
	-e "s/${LWORD}__ltrim_colon_completions${RWORD}/__kops_ltrim_colon_completions/g" \
	-e "s/${LWORD}compgen${RWORD}/__kops_compgen/g" \
	-e "s/${LWORD}compopt${RWORD}/__kops_compopt/g" \
	-e "s/${LWORD}declare${RWORD}/__kops_declare/g" \
	-e "s/\\\$(type${RWORD}/\$(__kops_type/g" \
	<<'BASH_COMPLETION_EOF'
# bash completion for kops                                 -*- shell-script -*-

__debug()
{
    if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
        echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
    fi
}

# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
# _init_completion. This is a very minimal version of that function.
__my_init_completion()
{
    COMPREPLY=()
    _get_comp_words_by_ref "$@" cur prev words cword
}

__index_of_word()
{
    local w word=$1
    shift
    index=0
    for w in "$@"; do
        [[ $w = "$word" ]] && return
        index=$((index+1))
    done
    index=-1
}

__contains_word()
{
    local w word=$1; shift
    for w in "$@"; do
        [[ $w = "$word" ]] && return
    done
    return 1
}

__handle_reply()
{
    __debug "${FUNCNAME[0]}"
    case $cur in
        -*)
            if [[ $(type -t compopt) = "builtin" ]]; then
                compopt -o nospace
            fi
            local allflags
            if [ ${#must_have_one_flag[@]} -ne 0 ]; then
                allflags=("${must_have_one_flag[@]}")
            else
                allflags=("${flags[*]} ${two_word_flags[*]}")
            fi
            COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
            if [[ $(type -t compopt) = "builtin" ]]; then
                [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
            fi

            # complete after --flag=abc
            if [[ $cur == *=* ]]; then
                if [[ $(type -t compopt) = "builtin" ]]; then
                    compopt +o nospace
                fi

                local index flag
                flag="${cur%%=*}"
                __index_of_word "${flag}" "${flags_with_completion[@]}"
                if [[ ${index} -ge 0 ]]; then
                    COMPREPLY=()
                    PREFIX=""
                    cur="${cur#*=}"
                    ${flags_completion[${index}]}
                    if [ -n "${ZSH_VERSION}" ]; then
                        # zfs completion needs --flag= prefix
                        eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
                    fi
                fi
            fi
            return 0;
            ;;
    esac

    # check if we are handling a flag with special work handling
    local index
    __index_of_word "${prev}" "${flags_with_completion[@]}"
    if [[ ${index} -ge 0 ]]; then
        ${flags_completion[${index}]}
        return
    fi

    # we are parsing a flag and don't have a special handler, no completion
    if [[ ${cur} != "${words[cword]}" ]]; then
        return
    fi

    local completions
    completions=("${commands[@]}")
    if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
        completions=("${must_have_one_noun[@]}")
    fi
    if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
        completions+=("${must_have_one_flag[@]}")
    fi
    COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )

    if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
        COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
    fi

    if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
        declare -F __custom_func >/dev/null && __custom_func
    fi

    __ltrim_colon_completions "$cur"
}

# The arguments should be in the form "ext1|ext2|extn"
__handle_filename_extension_flag()
{
    local ext="$1"
    _filedir "@(${ext})"
}

__handle_subdirs_in_dir_flag()
{
    local dir="$1"
    pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
}

__handle_flag()
{
    __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"

    # if a command required a flag, and we found it, unset must_have_one_flag()
    local flagname=${words[c]}
    local flagvalue
    # if the word contained an =
    if [[ ${words[c]} == *"="* ]]; then
        flagvalue=${flagname#*=} # take in as flagvalue after the =
        flagname=${flagname%%=*} # strip everything after the =
        flagname="${flagname}=" # but put the = back
    fi
    __debug "${FUNCNAME[0]}: looking for ${flagname}"
    if __contains_word "${flagname}" "${must_have_one_flag[@]}"; then
        must_have_one_flag=()
    fi

    # if you set a flag which only applies to this command, don't show subcommands
    if __contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
      commands=()
    fi

    # keep flag value with flagname as flaghash
    if [ -n "${flagvalue}" ] ; then
        flaghash[${flagname}]=${flagvalue}
    elif [ -n "${words[ $((c+1)) ]}" ] ; then
        flaghash[${flagname}]=${words[ $((c+1)) ]}
    else
        flaghash[${flagname}]="true" # pad "true" for bool flag
    fi

    # skip the argument to a two word flag
    if __contains_word "${words[c]}" "${two_word_flags[@]}"; then
        c=$((c+1))
        # if we are looking for a flags value, don't show commands
        if [[ $c -eq $cword ]]; then
            commands=()
        fi
    fi

    c=$((c+1))

}

__handle_noun()
{
    __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"

    if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
        must_have_one_noun=()
    elif __contains_word "${words[c]}" "${noun_aliases[@]}"; then
        must_have_one_noun=()
    fi

    nouns+=("${words[c]}")
    c=$((c+1))
}

__handle_command()
{
    __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"

    local next_command
    if [[ -n ${last_command} ]]; then
        next_command="_${last_command}_${words[c]//:/__}"
    else
        if [[ $c -eq 0 ]]; then
            next_command="_$(basename "${words[c]//:/__}")"
        else
            next_command="_${words[c]//:/__}"
        fi
    fi
    c=$((c+1))
    __debug "${FUNCNAME[0]}: looking for ${next_command}"
    declare -F $next_command >/dev/null && $next_command
}

__handle_word()
{
    if [[ $c -ge $cword ]]; then
        __handle_reply
        return
    fi
    __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
    if [[ "${words[c]}" == -* ]]; then
        __handle_flag
    elif __contains_word "${words[c]}" "${commands[@]}"; then
        __handle_command
    elif [[ $c -eq 0 ]] && __contains_word "$(basename "${words[c]}")" "${commands[@]}"; then
        __handle_command
    else
        __handle_noun
    fi
    __handle_word
}

_kops_completion()
{
    last_command="kops_completion"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--shell=")
    local_nonpersistent_flags+=("--shell=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_create_cluster()
{
    last_command="kops_create_cluster"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--admin-access=")
    local_nonpersistent_flags+=("--admin-access=")
    flags+=("--api-loadbalancer-type=")
    local_nonpersistent_flags+=("--api-loadbalancer-type=")
    flags+=("--associate-public-ip")
    local_nonpersistent_flags+=("--associate-public-ip")
    flags+=("--authorization=")
    local_nonpersistent_flags+=("--authorization=")
    flags+=("--bastion")
    local_nonpersistent_flags+=("--bastion")
    flags+=("--channel=")
    local_nonpersistent_flags+=("--channel=")
    flags+=("--cloud=")
    local_nonpersistent_flags+=("--cloud=")
    flags+=("--cloud-labels=")
    local_nonpersistent_flags+=("--cloud-labels=")
    flags+=("--dns=")
    local_nonpersistent_flags+=("--dns=")
    flags+=("--dns-zone=")
    local_nonpersistent_flags+=("--dns-zone=")
    flags+=("--encrypt-etcd-storage")
    local_nonpersistent_flags+=("--encrypt-etcd-storage")
    flags+=("--image=")
    local_nonpersistent_flags+=("--image=")
    flags+=("--kubernetes-version=")
    local_nonpersistent_flags+=("--kubernetes-version=")
    flags+=("--master-count=")
    local_nonpersistent_flags+=("--master-count=")
    flags+=("--master-security-groups=")
    local_nonpersistent_flags+=("--master-security-groups=")
    flags+=("--master-size=")
    local_nonpersistent_flags+=("--master-size=")
    flags+=("--master-tenancy=")
    local_nonpersistent_flags+=("--master-tenancy=")
    flags+=("--master-volume-size=")
    local_nonpersistent_flags+=("--master-volume-size=")
    flags+=("--master-zones=")
    local_nonpersistent_flags+=("--master-zones=")
    flags+=("--model=")
    local_nonpersistent_flags+=("--model=")
    flags+=("--network-cidr=")
    local_nonpersistent_flags+=("--network-cidr=")
    flags+=("--networking=")
    local_nonpersistent_flags+=("--networking=")
    flags+=("--node-count=")
    local_nonpersistent_flags+=("--node-count=")
    flags+=("--node-security-groups=")
    local_nonpersistent_flags+=("--node-security-groups=")
    flags+=("--node-size=")
    local_nonpersistent_flags+=("--node-size=")
    flags+=("--node-tenancy=")
    local_nonpersistent_flags+=("--node-tenancy=")
    flags+=("--node-volume-size=")
    local_nonpersistent_flags+=("--node-volume-size=")
    flags+=("--out=")
    local_nonpersistent_flags+=("--out=")
    flags+=("--project=")
    local_nonpersistent_flags+=("--project=")
    flags+=("--ssh-access=")
    local_nonpersistent_flags+=("--ssh-access=")
    flags+=("--ssh-public-key=")
    local_nonpersistent_flags+=("--ssh-public-key=")
    flags+=("--target=")
    local_nonpersistent_flags+=("--target=")
    flags+=("--topology=")
    two_word_flags+=("-t")
    local_nonpersistent_flags+=("--topology=")
    flags+=("--vpc=")
    local_nonpersistent_flags+=("--vpc=")
    flags+=("--yes")
    local_nonpersistent_flags+=("--yes")
    flags+=("--zones=")
    local_nonpersistent_flags+=("--zones=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_create_instancegroup()
{
    last_command="kops_create_instancegroup"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--role=")
    local_nonpersistent_flags+=("--role=")
    flags+=("--subnet=")
    local_nonpersistent_flags+=("--subnet=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_create_secret_sshpublickey()
{
    last_command="kops_create_secret_sshpublickey"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--pubkey=")
    two_word_flags+=("-i")
    local_nonpersistent_flags+=("--pubkey=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_create_secret()
{
    last_command="kops_create_secret"
    commands=()
    commands+=("sshpublickey")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_create()
{
    last_command="kops_create"
    commands=()
    commands+=("cluster")
    commands+=("instancegroup")
    commands+=("secret")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--filename=")
    two_word_flags+=("-f")
    local_nonpersistent_flags+=("--filename=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_flag+=("--filename=")
    must_have_one_flag+=("-f")
    must_have_one_noun=()
    noun_aliases=()
}

_kops_delete_cluster()
{
    last_command="kops_delete_cluster"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--external")
    local_nonpersistent_flags+=("--external")
    flags+=("--region=")
    local_nonpersistent_flags+=("--region=")
    flags+=("--unregister")
    local_nonpersistent_flags+=("--unregister")
    flags+=("--yes")
    flags+=("-y")
    local_nonpersistent_flags+=("--yes")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_delete_instancegroup()
{
    last_command="kops_delete_instancegroup"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--yes")
    flags+=("-y")
    local_nonpersistent_flags+=("--yes")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_delete_secret()
{
    last_command="kops_delete_secret"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_delete()
{
    last_command="kops_delete"
    commands=()
    commands+=("cluster")
    commands+=("instancegroup")
    commands+=("secret")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--filename=")
    two_word_flags+=("-f")
    local_nonpersistent_flags+=("--filename=")
    flags+=("--yes")
    flags+=("-y")
    local_nonpersistent_flags+=("--yes")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_flag+=("--filename=")
    must_have_one_flag+=("-f")
    must_have_one_noun=()
    noun_aliases=()
}

_kops_describe_secrets()
{
    last_command="kops_describe_secrets"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--type=")
    local_nonpersistent_flags+=("--type=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_describe()
{
    last_command="kops_describe"
    commands=()
    commands+=("secrets")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_edit_cluster()
{
    last_command="kops_edit_cluster"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_edit_federation()
{
    last_command="kops_edit_federation"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_edit_instancegroup()
{
    last_command="kops_edit_instancegroup"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_edit()
{
    last_command="kops_edit"
    commands=()
    commands+=("cluster")
    commands+=("federation")
    commands+=("instancegroup")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_export_kubecfg()
{
    last_command="kops_export_kubecfg"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_export()
{
    last_command="kops_export"
    commands=()
    commands+=("kubecfg")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_get_clusters()
{
    last_command="kops_get_clusters"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--full")
    local_nonpersistent_flags+=("--full")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--output=")
    two_word_flags+=("-o")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_get_federations()
{
    last_command="kops_get_federations"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--output=")
    two_word_flags+=("-o")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_get_instancegroups()
{
    last_command="kops_get_instancegroups"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--output=")
    two_word_flags+=("-o")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_get_secrets()
{
    last_command="kops_get_secrets"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--type=")
    local_nonpersistent_flags+=("--type=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--output=")
    two_word_flags+=("-o")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_get()
{
    last_command="kops_get"
    commands=()
    commands+=("clusters")
    commands+=("federations")
    commands+=("instancegroups")
    commands+=("secrets")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--output=")
    two_word_flags+=("-o")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_import_cluster()
{
    last_command="kops_import_cluster"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--region=")
    local_nonpersistent_flags+=("--region=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_import()
{
    last_command="kops_import"
    commands=()
    commands+=("cluster")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_replace()
{
    last_command="kops_replace"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--filename=")
    two_word_flags+=("-f")
    local_nonpersistent_flags+=("--filename=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_flag+=("--filename=")
    must_have_one_flag+=("-f")
    must_have_one_noun=()
    noun_aliases=()
}

_kops_rolling-update_cluster()
{
    last_command="kops_rolling-update_cluster"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--bastion-interval=")
    local_nonpersistent_flags+=("--bastion-interval=")
    flags+=("--cloudonly")
    local_nonpersistent_flags+=("--cloudonly")
    flags+=("--force")
    local_nonpersistent_flags+=("--force")
    flags+=("--instance-group=")
    local_nonpersistent_flags+=("--instance-group=")
    flags+=("--master-interval=")
    local_nonpersistent_flags+=("--master-interval=")
    flags+=("--node-interval=")
    local_nonpersistent_flags+=("--node-interval=")
    flags+=("--yes")
    local_nonpersistent_flags+=("--yes")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_rolling-update()
{
    last_command="kops_rolling-update"
    commands=()
    commands+=("cluster")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_toolbox_convert-imported()
{
    last_command="kops_toolbox_convert-imported"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--channel=")
    local_nonpersistent_flags+=("--channel=")
    flags+=("--newname=")
    local_nonpersistent_flags+=("--newname=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_toolbox_dump()
{
    last_command="kops_toolbox_dump"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--output=")
    two_word_flags+=("-o")
    local_nonpersistent_flags+=("--output=")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_toolbox()
{
    last_command="kops_toolbox"
    commands=()
    commands+=("convert-imported")
    commands+=("dump")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_update_cluster()
{
    last_command="kops_update_cluster"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--create-kube-config")
    local_nonpersistent_flags+=("--create-kube-config")
    flags+=("--model=")
    local_nonpersistent_flags+=("--model=")
    flags+=("--out=")
    local_nonpersistent_flags+=("--out=")
    flags+=("--phase=")
    local_nonpersistent_flags+=("--phase=")
    flags+=("--ssh-public-key=")
    local_nonpersistent_flags+=("--ssh-public-key=")
    flags+=("--target=")
    local_nonpersistent_flags+=("--target=")
    flags+=("--yes")
    local_nonpersistent_flags+=("--yes")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_update_federation()
{
    last_command="kops_update_federation"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_update()
{
    last_command="kops_update"
    commands=()
    commands+=("cluster")
    commands+=("federation")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_upgrade_cluster()
{
    last_command="kops_upgrade_cluster"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--channel=")
    local_nonpersistent_flags+=("--channel=")
    flags+=("--yes")
    local_nonpersistent_flags+=("--yes")
    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_upgrade()
{
    last_command="kops_upgrade"
    commands=()
    commands+=("cluster")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_validate_cluster()
{
    last_command="kops_validate_cluster"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_validate()
{
    last_command="kops_validate"
    commands=()
    commands+=("cluster")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops_version()
{
    last_command="kops_version"
    commands=()

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

_kops()
{
    last_command="kops"
    commands=()
    commands+=("completion")
    commands+=("create")
    commands+=("delete")
    commands+=("describe")
    commands+=("edit")
    commands+=("export")
    commands+=("get")
    commands+=("import")
    commands+=("replace")
    commands+=("rolling-update")
    commands+=("toolbox")
    commands+=("update")
    commands+=("upgrade")
    commands+=("validate")
    commands+=("version")

    flags=()
    two_word_flags=()
    local_nonpersistent_flags=()
    flags_with_completion=()
    flags_completion=()

    flags+=("--alsologtostderr")
    flags+=("--config=")
    flags+=("--log_backtrace_at=")
    flags+=("--log_dir=")
    flags+=("--logtostderr")
    flags+=("--name=")
    flags+=("--state=")
    flags+=("--stderrthreshold=")
    flags+=("--v=")
    two_word_flags+=("-v")
    flags+=("--vmodule=")

    must_have_one_flag=()
    must_have_one_noun=()
    noun_aliases=()
}

__start_kops()
{
    local cur prev words cword
    declare -A flaghash 2>/dev/null || :
    if declare -F _init_completion >/dev/null 2>&1; then
        _init_completion -s || return
    else
        __my_init_completion -n "=" || return
    fi

    local c=0
    local flags=()
    local two_word_flags=()
    local local_nonpersistent_flags=()
    local flags_with_completion=()
    local flags_completion=()
    local commands=("kops")
    local must_have_one_flag=()
    local must_have_one_noun=()
    local last_command
    local nouns=()

    __handle_word
}

if [[ $(type -t compopt) = "builtin" ]]; then
    complete -o default -F __start_kops kops
else
    complete -o default -o nospace -F __start_kops kops
fi

# ex: ts=4 sw=4 et filetype=sh

BASH_COMPLETION_EOF
}
__kops_bash_source <(__kops_convert_bash_to_zsh)

error: pathspec 'zsh/99_kops-completion.zsh' did not match any file(s) known to git


Implement an interoperability test for fetch-pack/upload-pack

The next patches will extend the pack protocol. This test assures that this
extension is compatible to earlier versions of git-fetch-pack/git-upload-pack.

All you need to do to take advantage of this test, is to install older
known-to-be-working binaries in the path as "old-git-fetch-pack" and
"old-git-upload-pack".

Note that the warning when testing with old-git-fetch-pack is to be
expected (it just says that the old version was not taking advantage
of all the information which the server sent).

Signed-off-by: Johannes Schindelin <b4cf3b77c95aaa57254d96e276bf14cfc9472402@gmx.de>
Signed-off-by: Junio C Hamano <dc50d1021234060e53ec42a77d526afa2fe07479@cox.net>

#!/bin/sh
#
# Copyright (c) 2005 Johannes Schindelin
#

# Test that the current fetch-pack/upload-pack plays nicely with
# an old counterpart

cd $(dirname $0) || exit 1

tmp=$(mktemp tmp-XXXX)

retval=0

if [ -z "$1" ]; then
	list="fetch upload"
else
	list="$@"
fi

for i in $list; do
	case "$i" in
	fetch) pgm="old-git-fetch-pack"; replace="$pgm";;
	upload) pgm="old-git-upload-pack"; replace="git-fetch-pack --exec=$pgm";;
	both) pgm="old-git-upload-pack"; replace="old-git-fetch-pack --exec=$pgm";;
	esac

	if which $pgm; then
		echo "Testing with $pgm"
		sed -e "s/git-fetch-pack/$replace/g" \
			-e "s/# old fails/warn/" < t5500-fetch-pack.sh > $tmp

		sh $tmp || retval=$?
		rm $tmp

		test $retval != 0 && exit $retval
	else
		echo "Skipping test for $i, since I cannot find $pgm"
	fi
done

exit 0

error: pathspec 't/t5501-old-fetch-and-upload.sh' did not match any file(s) known to git


01_environments.sh: +neovim in node

01_environments.sh: +neovim in node

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/vitorgalvao/dotfiles.git/'