Skip to content

Commit

Permalink
Introduce gopkginSource, plus its maybe
Browse files Browse the repository at this point in the history
gopkginSource are basically thin wrappers around a gitSource. The main
difference is that the gopkginSource performs filtering on the versions
that come through according to the constraint stated in the import path
URL.

This violates both name uniqueness and name/version orthogonality, but
there's not really a ton we can do - we have to at least somewhat
respect the guidelines that gopkg.in set up, as they represent valid
user intent.
  • Loading branch information
sdboyer committed Sep 28, 2016
1 parent 4cd1286 commit 581b3c9
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 5 deletions.
13 changes: 11 additions & 2 deletions deduce.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/url"
"path"
"regexp"
"strconv"
"strings"
)

Expand Down Expand Up @@ -256,7 +257,7 @@ func (m gopkginDeducer) deduceSource(p string, u *url.URL) (maybeSource, error)

// Putting a scheme on gopkg.in would be really weird, disallow it
if u.Scheme != "" {
return nil, fmt.Errorf("Specifying alternate schemes on gopkg.in imports is not permitted")
return nil, fmt.Errorf("specifying alternate schemes on gopkg.in imports is not permitted")
}

// gopkg.in is always backed by github
Expand All @@ -267,6 +268,11 @@ func (m gopkginDeducer) deduceSource(p string, u *url.URL) (maybeSource, error)
} else {
u.Path = path.Join(v[2], v[3])
}
major, err := strconv.ParseInt(v[4][1:], 10, 64)
if err != nil {
// this should only be reachable if there's an error in the regex
return nil, fmt.Errorf("could not parse %q as a gopkg.in major version", v[4][1:])
}

mb := make(maybeSources, len(gitSchemes))
for k, scheme := range gitSchemes {
Expand All @@ -275,7 +281,10 @@ func (m gopkginDeducer) deduceSource(p string, u *url.URL) (maybeSource, error)
u2.User = url.User("git")
}
u2.Scheme = scheme
mb[k] = maybeGitSource{url: &u2}
mb[k] = maybeGopkginSource{
url: &u2,
major: major,
}
}

return mb, nil
Expand Down
44 changes: 44 additions & 0 deletions maybe_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import (
"github.com/Masterminds/vcs"
)

// A maybeSource represents a set of information that, given some
// typically-expensive network effort, could be transformed into a proper source.
//
// Wrapping these up as their own type kills two birds with one stone:
//
// * Allows control over when deduction logic triggers network activity
// * Makes it easy to attempt multiple URLs for a given import path
type maybeSource interface {
try(cachedir string, an ProjectAnalyzer) (source, string, error)
}
Expand Down Expand Up @@ -84,6 +91,43 @@ func (m maybeGitSource) try(cachedir string, an ProjectAnalyzer) (source, string
return src, ustr, nil
}

type maybeGopkginSource struct {
url *url.URL
major int64
}

func (m maybeGopkginSource) try(cachedir string, an ProjectAnalyzer) (source, string, error) {
ustr := m.url.String()
path := filepath.Join(cachedir, "sources", sanitizer.Replace(ustr))
r, err := vcs.NewGitRepo(ustr, path)
if err != nil {
return nil, "", err
}

src := &gopkginSource{
gitSource: gitSource{
baseVCSSource: baseVCSSource{
an: an,
dc: newMetaCache(),
crepo: &repo{
r: r,
rpath: path,
},
},
},
major: m.major,
}

src.baseVCSSource.lvfunc = src.listVersions

_, err = src.listVersions()
if err != nil {
return nil, "", err
}

return src, ustr, nil
}

type maybeBzrSource struct {
url *url.URL
}
Expand Down
12 changes: 9 additions & 3 deletions vcs_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ func (s *gopkginSource) listVersions() (vlist []Version, err error) {
}

// Apply gopkg.in's filtering rules
vlist := make([]Version, len(ovlist))
vlist = make([]Version, len(ovlist))
k := 0
var dbranch int // index of branch to be marked default
var bsv *semver.Version
Expand All @@ -300,7 +300,9 @@ func (s *gopkginSource) listVersions() (vlist []Version, err error) {
case branchVersion:
// The semver lib isn't exactly the same as gopkg.in's logic, but
// it's close enough that it's probably fine to use. We can be more
// exact if real problems crop up.
// exact if real problems crop up. The most obvious vector for
// problems is that we totally ignore the "unstable" designation
// right now.
sv, err := semver.NewVersion(tv.name)
if err != nil || sv.Major() != s.major {
// not a semver-shaped branch name at all, or not the same major
Expand All @@ -326,7 +328,11 @@ func (s *gopkginSource) listVersions() (vlist []Version, err error) {

vlist = vlist[:k]
if bsv != nil {
vlist[dbranch].(versionPair).v.(branchVersion).isDefault = true
dbv := vlist[dbranch].(versionPair)
vlist[dbranch] = branchVersion{
name: dbv.v.(branchVersion).name,
isDefault: true,
}.Is(dbv.r)
}

// Process the filtered version data into the cache
Expand Down

0 comments on commit 581b3c9

Please sign in to comment.