Skip to content

Commit

Permalink
refactor: use go-getter url
Browse files Browse the repository at this point in the history
  • Loading branch information
vmaerten committed Aug 12, 2024
1 parent 0ae2bc5 commit ce35f85
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 27 deletions.
8 changes: 3 additions & 5 deletions taskfile/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ func NewNode(
if err != nil {
return nil, err
}

switch scheme {
case "git":
node, err = NewGitNode(entrypoint, dir, insecure, opts...)
Expand All @@ -72,12 +71,11 @@ func NewNode(
}

func getScheme(uri string) (string, error) {
u, _ := giturls.Parse(uri)
u, err := giturls.Parse(uri)
if u == nil {
return "", nil
return "", err
}
u.Path = strings.TrimSuffix(u.Path, "/")
if strings.HasSuffix(u.Path, ".git") && (u.Scheme == "git" || u.Scheme == "ssh" || u.Scheme == "https" || u.Scheme == "http") {
if strings.HasSuffix(strings.Split(u.Path, "//")[0], ".git") && (u.Scheme == "git" || u.Scheme == "ssh" || u.Scheme == "https" || u.Scheme == "http") {
return "git", nil
}

Expand Down
16 changes: 12 additions & 4 deletions taskfile/node_git.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,17 @@ func NewGitNode(
if err != nil {
return nil, err
}
refQuery := u.Query().Get("ref")
ref, path := func() (string, string) {
x := strings.Split(refQuery, "//")

basePath, path := func() (string, string) {
x := strings.Split(u.Path, "//")
return x[0], x[1]
}()
ref := u.Query().Get("ref")

rawUrl := u.String()

u.RawQuery = ""
u.Path = basePath

if u.Scheme == "http" && !insecure {
return nil, &errors.TaskfileNotSecureError{URI: entrypoint}
Expand Down Expand Up @@ -74,6 +77,7 @@ func (node *GitNode) Read(_ context.Context) ([]byte, error) {
_, err := git.Clone(storer, fs, &git.CloneOptions{
URL: node.URL.String(),
ReferenceName: plumbing.ReferenceName(node.ref),
SingleBranch: true,
Depth: 1,
})
if err != nil {
Expand All @@ -94,7 +98,11 @@ func (node *GitNode) Read(_ context.Context) ([]byte, error) {

func (node *GitNode) ResolveEntrypoint(entrypoint string) (string, error) {
dir, _ := filepath.Split(node.path)
return fmt.Sprintf("%s?ref=%s//%s", node.URL, node.ref, filepath.Join(dir, entrypoint)), nil
resolvedEntrypoint := fmt.Sprintf("%s//%s", node.URL, filepath.Join(dir, entrypoint))
if node.ref != "" {
return fmt.Sprintf("%s//%s?ref=%s", resolvedEntrypoint, node.ref), nil
}
return resolvedEntrypoint, nil
}

func (node *GitNode) ResolveDir(dir string) (string, error) {
Expand Down
30 changes: 15 additions & 15 deletions taskfile/node_git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,67 +7,67 @@ import (
)

func TestGitNode_ssh(t *testing.T) {
node, err := NewGitNode("[email protected]:foo/bar.git?ref=main//Taskfile.yml", "", false)
node, err := NewGitNode("[email protected]:foo/bar.git//Taskfile.yml?ref=main", "", false)
assert.NoError(t, err)
assert.Equal(t, "main", node.ref)
assert.Equal(t, "Taskfile.yml", node.path)
assert.Equal(t, "ssh://[email protected]/foo/bar.git?ref=main//Taskfile.yml", node.rawUrl)
assert.Equal(t, "ssh://[email protected]/foo/bar.git//Taskfile.yml?ref=main", node.rawUrl)
assert.Equal(t, "ssh://[email protected]/foo/bar.git", node.URL.String())
entrypoint, err := node.ResolveEntrypoint("common.yml")
assert.NoError(t, err)
assert.Equal(t, "ssh://[email protected]/foo/bar.git?ref=main//common.yml", entrypoint)
assert.Equal(t, "ssh://[email protected]/foo/bar.git//common.yml?ref=main", entrypoint)
}

func TestGitNode_sshWithDir(t *testing.T) {
node, err := NewGitNode("[email protected]:foo/bar.git?ref=main//directory/Taskfile.yml", "", false)
node, err := NewGitNode("[email protected]:foo/bar.git//directory/Taskfile.yml?ref=main", "", false)
assert.NoError(t, err)
assert.Equal(t, "main", node.ref)
assert.Equal(t, "directory/Taskfile.yml", node.path)
assert.Equal(t, "ssh://[email protected]/foo/bar.git?ref=main//directory/Taskfile.yml", node.rawUrl)
assert.Equal(t, "ssh://[email protected]/foo/bar.git//directory/Taskfile.yml?ref=main", node.rawUrl)
assert.Equal(t, "ssh://[email protected]/foo/bar.git", node.URL.String())
entrypoint, err := node.ResolveEntrypoint("common.yml")
assert.NoError(t, err)
assert.Equal(t, "ssh://[email protected]/foo/bar.git?ref=main//directory/common.yml", entrypoint)
assert.Equal(t, "ssh://[email protected]/foo/bar.git//directory/common.yml?ref=main", entrypoint)
}

func TestGitNode_https(t *testing.T) {
node, err := NewGitNode("https://github.com/foo/bar.git?ref=main//Taskfile.yml", "", false)
node, err := NewGitNode("https://github.com/foo/bar.git//Taskfile.yml?ref=main", "", false)
assert.NoError(t, err)
assert.Equal(t, "main", node.ref)
assert.Equal(t, "Taskfile.yml", node.path)
assert.Equal(t, "https://github.com/foo/bar.git?ref=main//Taskfile.yml", node.rawUrl)
assert.Equal(t, "https://github.com/foo/bar.git//Taskfile.yml?ref=main", node.rawUrl)
assert.Equal(t, "https://github.com/foo/bar.git", node.URL.String())
entrypoint, err := node.ResolveEntrypoint("common.yml")
assert.NoError(t, err)
assert.Equal(t, "https://github.com/foo/bar.git?ref=main//common.yml", entrypoint)
assert.Equal(t, "https://github.com/foo/bar.git//common.yml?ref=main", entrypoint)
}

func TestGitNode_httpsWithDir(t *testing.T) {
node, err := NewGitNode("https://github.com/foo/bar.git?ref=main//directory/Taskfile.yml", "", false)
node, err := NewGitNode("https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", "", false)
assert.NoError(t, err)
assert.Equal(t, "main", node.ref)
assert.Equal(t, "directory/Taskfile.yml", node.path)
assert.Equal(t, "https://github.com/foo/bar.git?ref=main//directory/Taskfile.yml", node.rawUrl)
assert.Equal(t, "https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", node.rawUrl)
assert.Equal(t, "https://github.com/foo/bar.git", node.URL.String())
entrypoint, err := node.ResolveEntrypoint("common.yml")
assert.NoError(t, err)
assert.Equal(t, "https://github.com/foo/bar.git?ref=main//directory/common.yml", entrypoint)
assert.Equal(t, "https://github.com/foo/bar.git//directory/common.yml?ref=main", entrypoint)
}

func TestGitNode_FilenameAndDir(t *testing.T) {
node, err := NewGitNode("https://github.com/foo/bar.git?ref=main//directory/Taskfile.yml", "", false)
node, err := NewGitNode("https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", "", false)
assert.NoError(t, err)
filename, dir := node.FilenameAndLastDir()
assert.Equal(t, "Taskfile.yml", filename)
assert.Equal(t, "directory", dir)

node, err = NewGitNode("https://github.com/foo/bar.git?ref=main//Taskfile.yml", "", false)
node, err = NewGitNode("https://github.com/foo/bar.git//Taskfile.yml?ref=main", "", false)
assert.NoError(t, err)
filename, dir = node.FilenameAndLastDir()
assert.Equal(t, "Taskfile.yml", filename)
assert.Equal(t, ".", dir)

node, err = NewGitNode("https://github.com/foo/bar.git?ref=main//multiple/directory/Taskfile.yml", "", false)
node, err = NewGitNode("https://github.com/foo/bar.git//multiple/directory/Taskfile.yml?ref=main", "", false)
assert.NoError(t, err)
filename, dir = node.FilenameAndLastDir()
assert.Equal(t, "Taskfile.yml", filename)
Expand Down
7 changes: 4 additions & 3 deletions website/docs/experiments/remote_taskfiles.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ includes:

## Git nodes

You can also include a Taskfile from a Git node. We currently support ssh-style and http / https addresses like `[email protected]/foo/bar?ref=v1//Taskfiles.yml` and `https://example.com/foo/bar.git?ref=v1//Taskfiles.yml`.
You can also include a Taskfile from a Git node. We currently support ssh-style and http / https addresses like `[email protected]/foo/bar.git//Taskfiles.yml?ref=v1` and `https://example.com/foo/bar.git//Taskfiles.yml?ref=v1`.

You need to follow this pattern : `<baseUrl>.git?ref=<ref>//<path>`.
The `ref` parameter can be a branch name or a tag, and the `path` is the path to the Taskfile in the repository.
You need to follow this pattern : `<baseUrl>.git//<path>?ref=<ref>`.
The `ref` parameter, optional, can be a branch name or a tag, if not provided it'll pick up the default branch.
The `path` is the path to the Taskfile in the repository.

If you want to use the SSH protocol, you need to make sure that your ssh-agent has your private ssh keys added so that they can be used during authentication.

Expand Down

0 comments on commit ce35f85

Please sign in to comment.