Skip to content

Commit

Permalink
Merge pull request #206 from mbland/path-lib
Browse files Browse the repository at this point in the history
lib/path: Fix @go.canonicalize_path bugs, add @go.add_parent_dir_if_relative_path
  • Loading branch information
mbland authored Sep 4, 2017
2 parents 19403c9 + b43aeb3 commit 8f83587
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
38 changes: 36 additions & 2 deletions lib/path
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
# @go.canonicalize_path
# Removes all extra slashes from a path and resolves all relative components
#
# @go.add_parent_dir_if_relative_path
# Adds a parent dir to a relative path
#
# @go.walk_file_system
# Performs an operation on file system objects and recurses into directories
#
Expand All @@ -27,12 +30,17 @@
# path: Path to canonicalize
@go.canonicalize_path() {
@go.validate_identifier_or_die 'Canonicalized path result variable' "$1"
printf -v "$1" '%s' "$2/"

printf -v "$1" '%s' "${2}${2:+/}"

while [[ "${!1}" =~ //+ ]]; do
printf -v "$1" '%s' "${!1/"${BASH_REMATCH[0]}"//}"
done

while [[ "${!1}" =~ ^\./. ]]; do
printf -v "$1" '%s' "${!1#./}"
done

while [[ "${!1}" =~ /\./ ]]; do
printf -v "$1" '%s' "${!1/"${BASH_REMATCH[0]}"//}"
done
Expand All @@ -56,6 +64,32 @@
fi
}

# Adds a parent dir to a relative path
#
# If the path is absolute, the original path is assigned.
#
# Options:
# --parent: Parent dir to add to `path` (default `PWD`)
#
# Arguments:
# result_var_name: Name of the variable into which the result will be stored
# path: Path to make absolute if it's relative
@go.add_parent_dir_if_relative_path() {
local __gapdirp_parent="$PWD"

if [[ "$1" == '--parent' ]]; then
__gapdirp_parent="$2"
shift 2
fi
@go.validate_identifier_or_die 'Absolute path result variable' "$1"

if [[ "${2:0:1}" != '/' ]]; then
printf -v "$1" '%s/%s' "$__gapdirp_parent" "$2"
else
printf -v "$1" '%s' "$2"
fi
}

# Performs an operation on file system objects and recurses into directories
#
# Each call to `operation` receives a path to an existing file system object.
Expand All @@ -78,7 +112,7 @@
# Nonzero if the algorithm was terminated by a nonzero return from `operation`
@go.walk_file_system() {
local operation
local current
local current
local do_bfs
local bfs_queue=()

Expand Down
31 changes: 31 additions & 0 deletions tests/path-module/add-parent-dir-if-relative-path.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#! /usr/bin/env bats

load ../environment

setup() {
test_filter
@go.create_test_go_script \
'. "$_GO_USE_MODULES" "path"' \
'declare result' \
'@go.add_parent_dir_if_relative_path "$@"' \
'printf "%s\n" "$result"'
}

teardown() {
@go.remove_test_go_rootdir
}

@test "$SUITE: converts a relative path to an absolute path based on PWD" {
run "$TEST_GO_SCRIPT" 'result' 'foo'
assert_success "$TEST_GO_ROOTDIR/foo"
}

@test "$SUITE: adds a parent to a relative path" {
run "$TEST_GO_SCRIPT" --parent 'foo' 'result' 'bar'
assert_success 'foo/bar'
}

@test "$SUITE: leaves an absolute path unmodified" {
run "$TEST_GO_SCRIPT" --parent 'foo' 'result' '/bar/baz'
assert_success '/bar/baz'
}
22 changes: 21 additions & 1 deletion tests/path-module/canonicalize-path.bats
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ run_canonicalize_path() {
assert_success '/foo/bar/baz'
}

@test "$SUITE: leaves the empty path unchanged" {
run_canonicalize_path ''
assert_success ''
}

@test "$SUITE: leaves root path unchanged" {
run_canonicalize_path '/'
assert_success '/'
Expand Down Expand Up @@ -84,8 +89,23 @@ run_canonicalize_path() {
assert_success 'foo/bar/baz'
}

@test "$SUITE: resolves a leading relative self" {
run_canonicalize_path './foo/bar/baz'
assert_success 'foo/bar/baz'
}

@test "$SUITE: resolves a leading relative self before '..'" {
run_canonicalize_path './..'
assert_success '..'
}

@test "$SUITE: resolves a trailing relative self" {
run_canonicalize_path 'foo/bar/baz/.'
assert_success 'foo/bar/baz'
}

@test "$SUITE: resolves multiple relative selves" {
run_canonicalize_path 'foo/./bar/././baz/./././'
run_canonicalize_path 'foo/./bar/././baz/././.'
assert_success 'foo/bar/baz'
}

Expand Down

0 comments on commit 8f83587

Please sign in to comment.