-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allows users to set a dependency mirror (#563)
- Loading branch information
1 parent
4e9c21d
commit 4c9f338
Showing
6 changed files
with
533 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package fakes | ||
|
||
import "sync" | ||
|
||
type MirrorResolver struct { | ||
FindDependencyMirrorCall struct { | ||
mutex sync.Mutex | ||
CallCount int | ||
Receives struct { | ||
Uri string | ||
PlatformDir string | ||
} | ||
Returns struct { | ||
String string | ||
Error error | ||
} | ||
Stub func(string, string) (string, error) | ||
} | ||
} | ||
|
||
func (f *MirrorResolver) FindDependencyMirror(param1 string, param2 string) (string, error) { | ||
f.FindDependencyMirrorCall.mutex.Lock() | ||
defer f.FindDependencyMirrorCall.mutex.Unlock() | ||
f.FindDependencyMirrorCall.CallCount++ | ||
f.FindDependencyMirrorCall.Receives.Uri = param1 | ||
f.FindDependencyMirrorCall.Receives.PlatformDir = param2 | ||
if f.FindDependencyMirrorCall.Stub != nil { | ||
return f.FindDependencyMirrorCall.Stub(param1, param2) | ||
} | ||
return f.FindDependencyMirrorCall.Returns.String, f.FindDependencyMirrorCall.Returns.Error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package internal | ||
|
||
import ( | ||
"fmt" | ||
"net/url" | ||
"os" | ||
"strings" | ||
) | ||
|
||
type DependencyMirrorResolver struct { | ||
bindingResolver BindingResolver | ||
} | ||
|
||
func NewDependencyMirrorResolver(bindingResolver BindingResolver) DependencyMirrorResolver { | ||
return DependencyMirrorResolver{ | ||
bindingResolver: bindingResolver, | ||
} | ||
} | ||
|
||
func formatAndVerifyMirror(mirror, uri string) (string, error) { | ||
mirrorURL, err := url.Parse(mirror) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
uriURL, err := url.Parse(uri) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
if mirrorURL.Scheme != "https" && mirrorURL.Scheme != "file" { | ||
return "", fmt.Errorf("invalid mirror scheme") | ||
} | ||
|
||
mirrorURL.Path = strings.Replace(mirrorURL.Path, "{originalHost}", uriURL.Host+uriURL.Path, 1) | ||
return mirrorURL.String(), nil | ||
} | ||
|
||
func (d DependencyMirrorResolver) FindDependencyMirror(uri, platformDir string) (string, error) { | ||
mirror, err := d.findMirrorFromEnv(uri) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
if mirror != "" { | ||
return formatAndVerifyMirror(mirror, uri) | ||
} | ||
|
||
mirror, err = d.findMirrorFromBinding(uri, platformDir) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
if mirror != "" { | ||
return formatAndVerifyMirror(mirror, uri) | ||
} | ||
|
||
return "", nil | ||
} | ||
|
||
func (d DependencyMirrorResolver) findMirrorFromEnv(uri string) (string, error) { | ||
const DefaultMirror = "BP_DEPENDENCY_MIRROR" | ||
const NonDefaultMirrorPrefix = "BP_DEPENDENCY_MIRROR_" | ||
mirrors := make(map[string]string) | ||
environmentVariables := os.Environ() | ||
for _, ev := range environmentVariables { | ||
pair := strings.SplitN(ev, "=", 2) | ||
key := pair[0] | ||
value := pair[1] | ||
|
||
if !strings.Contains(key, DefaultMirror) { | ||
continue | ||
} | ||
|
||
if key == DefaultMirror { | ||
mirrors["default"] = value | ||
continue | ||
} | ||
|
||
// convert key | ||
hostname := strings.SplitN(key, NonDefaultMirrorPrefix, 2)[1] | ||
hostname = strings.ReplaceAll(strings.ReplaceAll(hostname, "__", "-"), "_", ".") | ||
hostname = strings.ToLower(hostname) | ||
mirrors[hostname] = value | ||
|
||
if !strings.Contains(uri, hostname) { | ||
continue | ||
} | ||
|
||
return value, nil | ||
} | ||
|
||
if mirrorUri, ok := mirrors["default"]; ok { | ||
return mirrorUri, nil | ||
} | ||
|
||
return "", nil | ||
} | ||
|
||
func (d DependencyMirrorResolver) findMirrorFromBinding(uri, platformDir string) (string, error) { | ||
bindings, err := d.bindingResolver.Resolve("dependency-mirror", "", platformDir) | ||
if err != nil { | ||
return "", fmt.Errorf("failed to resolve 'dependency-mirror' binding: %w", err) | ||
} | ||
|
||
if len(bindings) > 1 { | ||
return "", fmt.Errorf("cannot have multiple bindings of type 'dependency-mirror'") | ||
} | ||
|
||
if len(bindings) == 0 { | ||
return "", nil | ||
} | ||
|
||
mirror := "" | ||
entries := bindings[0].Entries | ||
for hostname, entry := range entries { | ||
if hostname == "default" { | ||
mirror, err = entry.ReadString() | ||
if err != nil { | ||
return "", err | ||
} | ||
continue | ||
} | ||
|
||
if !strings.Contains(uri, hostname) { | ||
continue | ||
} | ||
|
||
mirror, err = entry.ReadString() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return mirror, nil | ||
} | ||
|
||
return mirror, nil | ||
} |
Oops, something went wrong.