Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- [ ] I have performed a self-review of my code
- [ ] I have commented my code in hard-to-understand areas
- [ ] I have added unit tests for my code
- [ ] I have made corresponding changes to the documentation

## Description
Expand All @@ -18,6 +19,7 @@
- [ ] New feature
- [ ] Refactor
- [ ] Breaking change
- [ ] Test
- [ ] Documentation change

## Test environment
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,22 @@ jobs:
sudo apt -y update
sudo apt -y install zsh fish shellcheck
fi
curl -s https://bashunit.typeddevs.com/install.sh | bash -s beta
- name: Show version
run: |
bash --version; echo
zsh --version; echo
fish --version; echo
shellcheck --version; echo
lib/bashunit --version; echo
- name: Shellcheck
run: shellcheck forgit.plugin.sh bin/git-forgit

- name: Unit tests
run: lib/bashunit .

- name: Test bash
run: bash forgit.plugin.sh

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
._zinit/
*.zwc
lib/
104 changes: 65 additions & 39 deletions bin/git-forgit
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,7 @@
# This gives users the choice to set aliases inside of their git config instead
# of their shell config if they prefer.

# Check if fzf is installed
installed_fzf_version=$(fzf --version 2>/dev/null | awk '{print $1}')
if [[ -z "$installed_fzf_version" ]]; then
echo "fzf is not installed. Please install fzf first."
exit 1
fi

# Check fzf version
required_fzf_version="0.49.0"
higher_fzf_version=$(printf '%s\n' "$required_fzf_version" "$installed_fzf_version" | sort -V | tail -n1)
if [[ "$higher_fzf_version" != "$installed_fzf_version" ]]; then
echo "fzf version $required_fzf_version or higher is required. You have $installed_fzf_version."
exit 1
fi

# Set shell for fzf preview commands
SHELL="$(which bash)"
export SHELL

# Get absolute forgit path
FORGIT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)/$(basename -- "${BASH_SOURCE[0]}")
REQUIRED_FZF_VERSION="0.49.0"

FORGIT_FZF_DEFAULT_OPTS="
$FZF_DEFAULT_OPTS
Expand Down Expand Up @@ -252,6 +232,14 @@ _forgit_reflog() {
return $fzf_exit_code
}

_forgit_remove_status_from_diff_line() {
# Remove the status prefix from a diff line, e.g.
# [M] somefile
# becomes
# somefile
sed 's/^[[:space:]]*\[[A-Z0-9]*\][[:space:]]*//'
}

_forgit_get_files_from_diff_line() {
# Construct a null-terminated list of the filenames
# The input looks like one of these lines:
Expand All @@ -264,13 +252,13 @@ _forgit_get_files_from_diff_line() {
# oldfile\0
# We have to do a two-step sed -> tr pipe because OSX's sed implementation does
# not support the null-character directly.
sed 's/^[[:space:]]*\[[A-Z0-9]*\][[:space:]]*//' | sed 's/ -> /\n/' | tr '\n' '\0'
_forgit_remove_status_from_diff_line | sed 's/ -> /\n/' | tr '\n' '\0'
}

_forgit_get_single_file_from_diff_line() {
# Similar to the function above, but only gets a single file from a single line
# Gets the new name of renamed files
sed 's/^[[:space:]]*\[[A-Z0-9]*\][[:space:]]*//' | sed 's/.*-> //'
_forgit_remove_status_from_diff_line | sed 's/.*-> //'
}

_forgit_exec_diff() {
Expand Down Expand Up @@ -1185,7 +1173,54 @@ _forgit_paths_list() {
find "$path" -name "*$ext" -print |sed -e "s#$ext\$##" -e 's#.*/##' -e '/^$/d' | sort -fu
}

public_commands=(
check_prequisites() {
local installed_fzf_version
local higher_fzf_version

# Check if fzf is installed
installed_fzf_version=$(fzf --version 2>/dev/null | awk '{print $1}')
if [[ -z "$installed_fzf_version" ]]; then
echo "fzf is not installed. Please install fzf first."
exit 1
fi

# Check fzf version
higher_fzf_version=$(printf '%s\n' "$REQUIRED_FZF_VERSION" "$installed_fzf_version" | sort -V | tail -n1)
if [[ "$higher_fzf_version" != "$installed_fzf_version" ]]; then
echo "fzf version $REQUIRED_FZF_VERSION or higher is required. You have $installed_fzf_version."
exit 1
fi
}

main() {
local cmd="$1"
shift

check_prequisites

# Set shell for fzf preview commands
SHELL="$(which bash)"
export SHELL

# Get absolute forgit path
FORGIT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)/$(basename -- "${BASH_SOURCE[0]}")

# shellcheck disable=SC2076
if [[ ! " ${PUBLIC_COMMANDS[*]} " =~ " ${cmd} " ]] && [[ ! " ${PRIVATE_COMMANDS[*]} " =~ " ${cmd} " ]]; then
if [[ -z "$cmd" ]]; then
printf "forgit: missing command\n\n"
else
printf "forgit: '%s' is not a valid forgit command.\n\n" "$cmd"
fi
printf "The following commands are supported:\n"
printf "\t%s\n" "${PUBLIC_COMMANDS[@]}"
exit 1
fi

_forgit_"${cmd}" "$@"
}

PUBLIC_COMMANDS=(
"add"
"attributes"
"blame"
Expand All @@ -1212,7 +1247,7 @@ public_commands=(
"stash_push"
)

private_commands=(
PRIVATE_COMMANDS=(
"add_preview"
"blame_preview"
"branch_preview"
Expand Down Expand Up @@ -1243,19 +1278,10 @@ private_commands=(
"pager"
)

cmd="$1"
shift

# shellcheck disable=SC2076
if [[ ! " ${public_commands[*]} " =~ " ${cmd} " ]] && [[ ! " ${private_commands[*]} " =~ " ${cmd} " ]]; then
if [[ -z "$cmd" ]]; then
printf "forgit: missing command\n\n"
else
printf "forgit: '%s' is not a valid forgit command.\n\n" "$cmd"
fi
printf "The following commands are supported:\n"
printf "\t%s\n" "${public_commands[@]}"
exit 1
# Check if the script is being sourced. This is necessary for unit tests where
# we do not want to execute the main function.
if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
return 0
fi

_forgit_"${cmd}" "$@"
main "${@}"
45 changes: 45 additions & 0 deletions tests/fzf.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

function test_exit_when_fzf_is_not_installed() {
# Error code 127 = "command not found"
mock fzf "return 127"

output=$(bin/git-forgit)

assert_general_error
assert_contains "fzf is not installed" "$output"
}

# @data_provider fzf_versions_below_required_version
function test_exit_when_fzf_version_is_below_required_version() {
mock "fzf" "echo '$1'"

output=$(bin/git-forgit)

assert_general_error
assert_contains "fzf version 0.49.0 or higher is required" "$output"
}

function fzf_versions_below_required_version() {
echo "0.0.2"
echo "0.5.0"
echo "0.30.0"
echo "0.48.9"
}

# @data_provider fzf_versions_satisfying_required_version
function test_pass_when_fzf_version_satisfies_required_version() {
mock "fzf" "echo '$1'"

output=$(bin/git-forgit)

assert_general_error
assert_contains "missing command" "$output"
}

function fzf_versions_satisfying_required_version() {
echo "0.49.0"
echo "0.49.1"
echo "0.80.0"
echo "1.1.0"
}
33 changes: 33 additions & 0 deletions tests/helper-functions.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash

function set_up_before_script() {
source bin/git-forgit
}

# @data_provider provider_diff_lines
function test_forgit_get_files_from_diff_line() {
local -r input="$1"
shift
local -r expected=("$@")
local -a actual=()
local i

while IFS= read -r line; do
actual+=( "$line" )
done < <( echo -n "$input" | _forgit_get_files_from_diff_line | xargs -0 -n 1 echo )

# Compare array sizes
assert_same "${#expected[@]}" "${#actual[@]}"

# Compare array elements
for i in "${!expected[@]}"; do
assert_same "${expected[i]}" "${actual[i]}"
done
}

function provider_diff_lines() {
data_set "[A] newfile" "newfile"
data_set "[D] oldfile with spaces" "oldfile with spaces"
data_set "[R100] file -> another file" "file" "another file"
data_set "[M] \"file with\ttab.txt\"" "\"file with\ttab.txt\""
}