Skip to content

Commit 1e84be2

Browse files
committed
lib/portability: Add @go.native_file_path_or_url
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.
1 parent dc8520f commit 1e84be2

File tree

5 files changed

+71
-33
lines changed

5 files changed

+71
-33
lines changed

lib/platform

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#! /bin/bash
1+
#! /usr/bin/env bash
22
#
33
# Sets the `_GO_PLATFORM_*` family of environment variables
44
#

lib/portability

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#! /usr/bin/env bash
2+
#
3+
# Functions to manage platform differences
4+
#
5+
# Exports:
6+
# @go.native_file_path_or_url
7+
# Converts a file system path or 'file://' URL to a platform-native path
8+
9+
. "$_GO_USE_MODULES" 'platform' 'validation'
10+
11+
# Converts a file system path or 'file://' URL to a platform-native path
12+
#
13+
# This is useful when passing file paths or URLs to native programs on Git for
14+
# Windows, or validating the output of such programs, to ensure portability.
15+
# The resulting path will contain forward slashes.
16+
#
17+
# Prints both converted and unconverted paths and URLs to the specified result
18+
# variable.
19+
#
20+
# Arguments:
21+
# result_var_name: Name of caller's variable in which to store the result
22+
# path: File system path or 'file://' URL to convert
23+
@go.native_file_path_or_url() {
24+
local _gnp_protocol="${2%%://*}"
25+
@go.validate_identifier_or_die 'Result variable name' "$1"
26+
27+
if [[ "$_GO_PLATFORM_ID" != 'msys-git' ]] ||
28+
[[ "$_gnp_protocol" != "$2" && "$_gnp_protocol" != 'file' ]]; then
29+
printf -v "$1" '%s' "$2"
30+
elif [[ "$protocol" == 'file' ]]; then
31+
printf -v "$1" 'file://%s' "$(cygpath -m "${2#file://}")"
32+
else
33+
printf -v "$1" '%s' "$(cygpath -m "$2")"
34+
fi
35+
}

libexec/get.d/file

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,8 @@ _@go.get_file() {
206206
if [[ "${url:0:1}" != '/' ]]; then
207207
url="${PWD}/${url}"
208208
fi
209-
if [[ "$url" =~ ^/[^/]+ && -d "$BASH_REMATCH/Windows" ]]; then
210-
url="${BASH_REMATCH}:/${url#$BASH_REMATCH/}"
211-
fi
212-
url="file://${url}"
209+
. "$_GO_USE_MODULES" 'portability'
210+
@go.native_file_path_or_url 'url' "file://${url}"
213211
fi
214212
_@go.get_file_impl "$download_dir" "$filename" "$url"
215213
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#! /usr/bin/env bats
2+
3+
load ../environment
4+
load "$_GO_CORE_DIR/lib/portability"
5+
6+
@test "$SUITE: return unaltered path if _GO_PLATFORM_ID isn't msys-git" {
7+
local result
8+
_GO_PLATFORM_ID='foobar' @go.native_file_path_or_url 'result' '/foo/bar'
9+
assert_equal '/foo/bar' "$result"
10+
}
11+
12+
@test "$SUITE: return unaltered path if protocol isn't file://" {
13+
local result
14+
_GO_PLATFORM_ID='msys-git' \
15+
@go.native_file_path_or_url 'result' 'https://mike-bland.com/'
16+
assert_equal 'https://mike-bland.com/' "$result"
17+
}
18+
19+
@test "$SUITE: return updated file system path" {
20+
skip_if_system_missing 'cygpath'
21+
_GO_PLATFORM_ID='msys-git' @go.native_file_path_or_url 'result' '/foo/bar'
22+
assert_equal "$(cygpath -m '/foo/bar')" "$result"
23+
}
24+
25+
@test "$SUITE: return updated file:// URL" {
26+
skip_if_system_missing 'cygpath'
27+
_GO_PLATFORM_ID='msys-git' \
28+
@go.native_file_path_or_url 'result' 'file:///foo/bar'
29+
assert_equal "file://$(cygpath -m '/foo/bar')" "$result"
30+
}

tests/template.bats

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#! /usr/bin/env bats
22

33
load environment
4+
load "$_GO_CORE_DIR/lib/portability"
45

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

5050
if [[ -z "$TEST_USE_REAL_URL" ]]; then
@@ -75,31 +75,6 @@ assert_go_core_unpacked() {
7575
restore_bats_shell_options "$result"
7676
}
7777

78-
# Converts a Unix path or 'file://' URL to a Git for Windows native path.
79-
#
80-
# This is useful when passing file paths or URLs to native programs on Git for
81-
# Windows, or validating the output of such programs, to ensure portability.
82-
# The resulting path will contain forward slashes.
83-
#
84-
# Prints both converted and unconverted paths and URLs to standard output.
85-
#
86-
# Arguments:
87-
# path: Path or 'file://' URL to convert
88-
git_for_windows_native_path() {
89-
local path="$1"
90-
local protocol="${path%%://*}"
91-
92-
if [[ ! "$(git --version)" =~ windows ]] ||
93-
[[ "$protocol" != "$path" && "$protocol" != 'file' ]]; then
94-
printf '%s' "$path"
95-
elif [[ "$protocol" == 'file' ]]; then
96-
printf 'file://'
97-
cygpath -m "${path#file://}"
98-
else
99-
cygpath -m "$path"
100-
fi
101-
}
102-
10378
# This mimics the tarball provided by GitHub.
10479
#
10580
# This could probably become a general-purpose utility one day.

0 commit comments

Comments
 (0)