ktrysmt/go-bitbucket

Error when calling Repository.ListFiles

Opened this issue · 4 comments

Hello,

I'm trying to list files in my BitBucket repository but I get an error.

My module setup is:

go 1.16

require github.com/ktrysmt/go-bitbucket v0.9.9 // indirect

The test code is as follows:

(just change the "my" variables for your user, pass, owner, repo, etc.)

package lib

import (
	"fmt"
	"testing"
	"github.com/ktrysmt/go-bitbucket"
)

func Test(t *testing.T) {
	c := bitbucket.NewBasicAuth("myuser", "mypass")

	fmt.Println("List repos...")
	optr := &bitbucket.RepositoriesOptions{
		Owner: "myowner",
		Role:  "",
	}

	repos, err1 := c.Repositories.ListForAccount(optr)
	if err1 != nil {
		fmt.Println("Error listing repos:", err1)
		panic(err1)
	}
	fmt.Println("List number of repos:", repos.Size)

	for _, repo := range repos.Items {
		fmt.Println("List repo with name:", repo.Name)
	}

	repong6 := repos.Items[4] // a public repo to test

	fmt.Println("List files in repo:", repong6.Name, "...")
	optrf := &bitbucket.RepositoryFilesOptions{
		Owner:    "myowner",
		RepoSlug: "myslug",
		Ref:      "myref",
		Path:     "mypath",
	}

	files, err2 := repong6.ListFiles(optrf)
	if err2 != nil {
		fmt.Println("Error listing files:", err2)
		panic(err2)
	}
	fmt.Println("List number of files:", len(files))

	for _, file := range files {
		fmt.Println("List file with name:", file.Path)
	}
}

The error happens in the line:

files, err2 := repong6.ListFiles(optrf)

--- FAIL: Test (0.74s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x58 pc=0x60ccca]

goroutine 6 [running]:
testing.tRunner.func1.2(0x648a00, 0x88cb70)
        C:/Program Files/Go/src/testing/testing.go:1144 +0x345
testing.tRunner.func1(0xc00002d080)
        C:/Program Files/Go/src/testing/testing.go:1147 +0x4b6
panic(0x648a00, 0x88cb70)
        C:/Program Files/Go/src/runtime/panic.go:965 +0x1c7
github.com/ktrysmt/go-bitbucket.(*Client).requestUrl(0x0, 0xc0002bc420, 0x5f, 0x0, 0x0, 0x0, 0x5f, 0xc00014a180)
        C:/Users/dani/go/pkg/mod/github.com/ktrysmt/go-bitbucket@v0.9.9/client.go:376 +0x8a
github.com/ktrysmt/go-bitbucket.(*Repository).ListFiles(0xc00004fd00, 0xc00004fc60, 0xc00004fc30, 0x3, 0x3, 0x29, 0x0)
        C:/Users/dani/go/pkg/mod/github.com/ktrysmt/go-bitbucket@v0.9.9/repository.go:220 +0x17f
github.com/twopelu/hulk/lib.Test(0xc00002d080)
        D:/DANI/go/hulk/lib/lib_test.go:40 +0x4e6
testing.tRunner(0xc00002d080, 0x6b5f50)
        C:/Program Files/Go/src/testing/testing.go:1194 +0xef
created by testing.(*T).Run
        C:/Program Files/Go/src/testing/testing.go:1239 +0x2b3
exit status 2
FAIL    github.com/twopelu/hulk/lib     0.860s

I have checked that the options and the url are ok, and also that it works when called from the browser:

https://github.com/ktrysmt/go-bitbucket/blob/v0.9.9/repository.go#L220

https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D/%7Brepo_slug%7D/src

Example URL: https://api.bitbucket.org/2.0/repositories/myuser/myslug/src/myref/mypath

But when I call it from code it returns "invalid memory address or nil pointer dereference", any help please?

Many thanks,

Dani

Hmm, I will check the behavior. 🤔

Many thanks, just let me know if you need more info to reproduce the issue please.

Can it be because the client is never instantiated for the Repositories? I cant seem to find it in the code for creating the repository object, and if c *Client is not instantiated, then you get the null pointer exception:

func (r *Repository) buildContentsURL(ro *RepositoryFilesOptions) (string, error) {

 ...
	urlStr := r.c.requestUrl(filePath)
...
func decodeRepositories(reposResponse interface{}) (*RepositoriesRes, error) {
	reposResponseMap, ok := reposResponse.(map[string]interface{})
	if !ok {
		return nil, errors.New("Not a valid format")
	}

	repoArray := reposResponseMap["values"].([]interface{})
	var repos []Repository
	for _, repoEntry := range repoArray {
		var repo Repository
		err := mapstructure.Decode(repoEntry, &repo)
		if err == nil {
			repos = append(repos, repo)
		}
	}

And solution could be something like:

func (r *Repositories) decodeRepositories(reposResponse interface{}) (*RepositoriesRes, error) {
	reposResponseMap, ok := reposResponse.(map[string]interface{})
	if !ok {
		return nil, errors.New("Not a valid format")
	}

	repoArray := reposResponseMap["values"].([]interface{})
	var repos []Repository
	for _, repoEntry := range repoArray {
		repo :=  Repository {
			c: r.c,
		}
		err := mapstructure.Decode(repoEntry, &repo)
		if err == nil {
			repos = append(repos, repo)
		}
	}