Skip to content

Commit

Permalink
lib/portability: Add @go.native_file_path_or_url
Browse files Browse the repository at this point in the history
Closes #187. Part of #186. Replaces `git_for_windows_native_path` and
updates the interface to print to a result variable rather than standard
output, avoiding a subshell when no conversion takes place.
  • Loading branch information
mbland committed Sep 2, 2017
1 parent dc8520f commit 1e84be2
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 33 deletions.
2 changes: 1 addition & 1 deletion lib/platform
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#! /bin/bash
#! /usr/bin/env bash
#
# Sets the `_GO_PLATFORM_*` family of environment variables
#
Expand Down
35 changes: 35 additions & 0 deletions lib/portability
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#! /usr/bin/env bash
#
# Functions to manage platform differences
#
# Exports:
# @go.native_file_path_or_url
# Converts a file system path or 'file://' URL to a platform-native path

. "$_GO_USE_MODULES" 'platform' 'validation'

# Converts a file system path or 'file://' URL to a platform-native path
#
# This is useful when passing file paths or URLs to native programs on Git for
# Windows, or validating the output of such programs, to ensure portability.
# The resulting path will contain forward slashes.
#
# Prints both converted and unconverted paths and URLs to the specified result
# variable.
#
# Arguments:
# result_var_name: Name of caller's variable in which to store the result
# path: File system path or 'file://' URL to convert
@go.native_file_path_or_url() {
local _gnp_protocol="${2%%://*}"
@go.validate_identifier_or_die 'Result variable name' "$1"

if [[ "$_GO_PLATFORM_ID" != 'msys-git' ]] ||
[[ "$_gnp_protocol" != "$2" && "$_gnp_protocol" != 'file' ]]; then
printf -v "$1" '%s' "$2"
elif [[ "$protocol" == 'file' ]]; then
printf -v "$1" 'file://%s' "$(cygpath -m "${2#file://}")"
else
printf -v "$1" '%s' "$(cygpath -m "$2")"
fi
}
6 changes: 2 additions & 4 deletions libexec/get.d/file
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,8 @@ [email protected]_file() {
if [[ "${url:0:1}" != '/' ]]; then
url="${PWD}/${url}"
fi
if [[ "$url" =~ ^/[^/]+ && -d "$BASH_REMATCH/Windows" ]]; then
url="${BASH_REMATCH}:/${url#$BASH_REMATCH/}"
fi
url="file://${url}"
. "$_GO_USE_MODULES" 'portability'
@go.native_file_path_or_url 'url' "file://${url}"
fi
[email protected]_file_impl "$download_dir" "$filename" "$url"
}
Expand Down
30 changes: 30 additions & 0 deletions tests/portability/native-file-path-or-url.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#! /usr/bin/env bats

load ../environment
load "$_GO_CORE_DIR/lib/portability"

@test "$SUITE: return unaltered path if _GO_PLATFORM_ID isn't msys-git" {
local result
_GO_PLATFORM_ID='foobar' @go.native_file_path_or_url 'result' '/foo/bar'
assert_equal '/foo/bar' "$result"
}

@test "$SUITE: return unaltered path if protocol isn't file://" {
local result
_GO_PLATFORM_ID='msys-git' \
@go.native_file_path_or_url 'result' 'https://mike-bland.com/'
assert_equal 'https://mike-bland.com/' "$result"
}

@test "$SUITE: return updated file system path" {
skip_if_system_missing 'cygpath'
_GO_PLATFORM_ID='msys-git' @go.native_file_path_or_url 'result' '/foo/bar'
assert_equal "$(cygpath -m '/foo/bar')" "$result"
}

@test "$SUITE: return updated file:// URL" {
skip_if_system_missing 'cygpath'
_GO_PLATFORM_ID='msys-git' \
@go.native_file_path_or_url 'result' 'file:///foo/bar'
assert_equal "file://$(cygpath -m '/foo/bar')" "$result"
}
31 changes: 3 additions & 28 deletions tests/template.bats
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#! /usr/bin/env bats

load environment
load "$_GO_CORE_DIR/lib/portability"

# By default, the test will try to clone its own repo to avoid flakiness due to
# an external dependency. However, doing so causes a failure on Travis, since it
Expand Down Expand Up @@ -42,9 +43,8 @@ CLONE_DIR=
setup() {
test_filter
export GO_SCRIPT_BASH_{VERSION,REPO_URL,DOWNLOAD_URL}
NATIVE_LOCAL_URL="$(git_for_windows_native_path "$LOCAL_DOWNLOAD_URL")"
CLONE_DIR="$(git_for_windows_native_path "$TEST_GO_SCRIPTS_DIR")"
CLONE_DIR+='/go-script-bash'
@go.native_file_path_or_url 'NATIVE_LOCAL_URL' "$LOCAL_DOWNLOAD_URL"
@go.native_file_path_or_url 'CLONE_DIR' "$TEST_GO_SCRIPTS_DIR/go-script-bash"
EXPECTED_URL="$FULL_DOWNLOAD_URL"

if [[ -z "$TEST_USE_REAL_URL" ]]; then
Expand Down Expand Up @@ -75,31 +75,6 @@ assert_go_core_unpacked() {
restore_bats_shell_options "$result"
}

# Converts a Unix path or 'file://' URL to a Git for Windows native path.
#
# This is useful when passing file paths or URLs to native programs on Git for
# Windows, or validating the output of such programs, to ensure portability.
# The resulting path will contain forward slashes.
#
# Prints both converted and unconverted paths and URLs to standard output.
#
# Arguments:
# path: Path or 'file://' URL to convert
git_for_windows_native_path() {
local path="$1"
local protocol="${path%%://*}"

if [[ ! "$(git --version)" =~ windows ]] ||
[[ "$protocol" != "$path" && "$protocol" != 'file' ]]; then
printf '%s' "$path"
elif [[ "$protocol" == 'file' ]]; then
printf 'file://'
cygpath -m "${path#file://}"
else
cygpath -m "$path"
fi
}

# This mimics the tarball provided by GitHub.
#
# This could probably become a general-purpose utility one day.
Expand Down

0 comments on commit 1e84be2

Please sign in to comment.