Masterminds / vcs

VCS Repo management through a common interface in Go
Other
195 stars 60 forks source link

`file:` URLs aren't supported #50

Closed pburkholder closed 7 years ago

pburkholder commented 8 years ago

Maybe I'm doing it wrong, but I expected something like this to work:

package main

import (
  "github.com/Masterminds/vcs"
  "io/ioutil"
  "fmt"
)

func main() {
//remote := "https://github.com/Masterminds/vcs"  // works
remote := "file:///Users/pburkholder/tmp/vcs" // panics
local, _ := ioutil.TempDir("", "go-vcs")
fmt.Println(local)

repo, _ := vcs.NewRepo(remote, local)
// Returns: instance of GitRepo

repo.Vcs()
// Returns Git as this is a Git repo

err := repo.Get()
// Pulls down a repo, or a checkout in the case of SVN, and returns an
// error if that didn't happen successfully.
if err != nil {
    fmt.Println(err)
    }

    err = repo.UpdateVersion("master")
    // Checkouts out a specific version. In most cases this can be a commit
    // id,
    // branch, or tag.
    if err != nil {
        fmt.Println(err)
    }
}

but I get

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0xb0 pc=0x21d7]

goroutine 1 [running]:
panic(0x3c2c60, 0xc82000a0f0)
    /usr/local/Cellar/go/1.6.2/libexec/src/runtime/panic.go:481 +0x3e6
main.main()
    /Users/pburkholder/tmp/t/t.go:18 +0x197
exit status 2

For a downstream project I'd find it useful to reference repositories by local filesystem paths, so that this package works similarly to:

git clone file:///Users/pburkholder/tmp/vcs
# and
git clone https://github.com/Masterminds/vcs

Thanks, Peter

mattfarina commented 8 years ago

I have an idea of what the problem is.

remote := "file:///Users/pburkholder/tmp/vcs" // panics
local, _ := ioutil.TempDir("", "go-vcs")
fmt.Println(local)

repo, _ := vcs.NewRepo(remote, local)
// Returns: instance of GitRepo

repo.Vcs()

This last line is line 18 in your snippet which is where the nil panic happens. An error was returned.

vcs.NewRepo tries to detect the type. It can't detect the type from file:///Users/pburkholder/tmp/vcs.

There are two options here. First, if you know it's git you can use vcs.NewGitRepo instead. If you know it's another type there are constructors for those types as well.

If you have a good suggestion on detecting the type from a file path, such as your example, i'd be interested in hearing it or reviewing a pull request.

mattfarina commented 8 years ago

@sdboyer I'm considering adding auto-detection for file:// paths. How would this impact gps work? Would it be useful?

sdboyer commented 8 years ago

@mattfarina i don't think it would directly impact, because gps has its own multi-layered logic that receives input paths and decides how to actually source them in.

i do still need to implement analogous logic for this, though, in order to get that mirrors support in. So even if gps doesn't use this directly, i'll do a "little bit of copying" and take advantage of it :)

sdboyer commented 8 years ago

reflecting a little more, i'm sure it would be possible to write a func that, given a file:// path, figures out the type of repo and returns the appropriate object. if that's what you've got in mind, then i think gps could use that directly.

it might only be useful, though, if it's fully separated from vcs.NewRepo(). i'd need to make more concrete plans about how gps handles this before i could really say with certainty, though.

cescoferraro commented 8 years ago

@mattfarina is there a way to easily detect the current folder as a remote? It would be great for https://github.com/dnephin/dobi/issues/40

mattfarina commented 7 years ago

PR in #58. Release coming soon.