Skip to content
This repository has been archived by the owner on Sep 9, 2020. It is now read-only.

make importers error tolerant #1474

Merged
merged 6 commits into from
Jan 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ IMPROVEMENTS:
* Skip empty constraints during import ([#1414](https://github.com/golang/dep/pull/1349))
* Handle errors when writing status output ([#1420](https://github.com/golang/dep/pull/1420))
* Add constraint for locked projects in `status`. (#962)
* Make external config importers error tolerant. ([#1315](https://github.com/golang/dep/pull/1315))

# v0.3.2

Expand Down
21 changes: 11 additions & 10 deletions cmd/dep/root_analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ func newRootAnalyzer(skipTools bool, ctx *dep.Ctx, directDeps map[string]bool, s

func (a *rootAnalyzer) InitializeRootManifestAndLock(dir string, pr gps.ProjectRoot) (rootM *dep.Manifest, rootL *dep.Lock, err error) {
if !a.skipTools {
rootM, rootL, err = a.importManifestAndLock(dir, pr, false)
if err != nil {
return
}
rootM, rootL = a.importManifestAndLock(dir, pr, false)
}

if rootM == nil {
Expand Down Expand Up @@ -106,7 +103,7 @@ func (a *rootAnalyzer) cacheDeps(pr gps.ProjectRoot) error {
return nil
}

func (a *rootAnalyzer) importManifestAndLock(dir string, pr gps.ProjectRoot, suppressLogs bool) (*dep.Manifest, *dep.Lock, error) {
func (a *rootAnalyzer) importManifestAndLock(dir string, pr gps.ProjectRoot, suppressLogs bool) (*dep.Manifest, *dep.Lock) {
logger := a.ctx.Err
if suppressLogs {
logger = log.New(ioutil.Discard, "", 0)
Expand All @@ -117,16 +114,20 @@ func (a *rootAnalyzer) importManifestAndLock(dir string, pr gps.ProjectRoot, sup
a.ctx.Err.Printf("Importing configuration from %s. These are only initial constraints, and are further refined during the solve process.", i.Name())
m, l, err := i.Import(dir, pr)
if err != nil {
return nil, nil, err
a.ctx.Err.Printf(
"Warning: Encountered an unrecoverable error while trying to import %s config from %q: %s",
i.Name(), dir, err,
)
break
}
a.removeTransitiveDependencies(m)
return m, l, err
return m, l
}
}

var emptyManifest = dep.NewManifest()

return emptyManifest, nil, nil
return emptyManifest, nil
}

func (a *rootAnalyzer) removeTransitiveDependencies(m *dep.Manifest) {
Expand All @@ -151,14 +152,14 @@ func (a *rootAnalyzer) DeriveManifestAndLock(dir string, pr gps.ProjectRoot) (gp
// The assignment back to an interface prevents interface-based nil checks from failing later
var manifest gps.Manifest = gps.SimpleManifest{}
var lock gps.Lock
im, il, err := a.importManifestAndLock(dir, pr, true)
im, il := a.importManifestAndLock(dir, pr, true)
if im != nil {
manifest = im
}
if il != nil {
lock = il
}
return manifest, lock, err
return manifest, lock, nil
}

return gps.SimpleManifest{}, nil, nil
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Ignore glide config if glide.yaml is malformed and cannot be parsed correctly.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

[[constraint]]
name = "github.com/sdboyer/deptestdos"
version = "2.0.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'package: github.com/golang/notexist
homepage: http://example.com
license: MIT
owners:
- name: Sam Boyer
email: [email protected]
homepage: http://sdboyer.io
ignore:
- github.com/sdboyer/dep-test
excludeDirs:
- samples
import:
- package: github.com/sdboyer/deptest # This is a transitive dep and will be ignored
repo: https://github.com/sdboyer/deptest.git
vcs: git
version: v1.0.0
- package: github.com/sdboyer/deptestdos
version: v2.0.0
testImport:
- package: github.com/golang/lint
16 changes: 16 additions & 0 deletions cmd/dep/testdata/harness_tests/init/glide/case4/initial/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
"fmt"

"github.com/sdboyer/deptestdos"
)

func main() {
var x deptestdos.Bar
fmt.Println(x)
}
14 changes: 14 additions & 0 deletions cmd/dep/testdata/harness_tests/init/glide/case4/testcase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"commands": [
["init", "-no-examples"]
],
"error-expected": "",
"gopath-initial": {
"github.com/sdboyer/deptest": "3f4c3bea144e112a69bbe5d8d01c1b09a544253f",
"github.com/sdboyer/deptestdos": "5c607206be5decd28e6263ffffdcee067266015e"
},
"vendor-final": [
"github.com/sdboyer/deptest",
"github.com/sdboyer/deptestdos"
]
}
27 changes: 15 additions & 12 deletions internal/importers/base/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ type importedProject struct {
}

// loadPackages consolidates all package references into a set of project roots.
func (i *Importer) loadPackages(packages []ImportedPackage) ([]importedProject, error) {
func (i *Importer) loadPackages(packages []ImportedPackage) []importedProject {
// preserve the original order of the packages so that messages that
// are printed as they are processed are in a consistent order.
orderedProjects := make([]importedProject, 0, len(packages))
Expand All @@ -132,7 +132,11 @@ func (i *Importer) loadPackages(packages []ImportedPackage) ([]importedProject,
for _, pkg := range packages {
pr, err := i.SourceManager.DeduceProjectRoot(pkg.Name)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carolynvs When does SourceManager.DeduceProjectRoot return an error? I tried passing a package path which does not exist but that did not return an error.

Copy link
Contributor Author

@sudo-suhas sudo-suhas Dec 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

invalid-project works. Let me know if you want me to use something else.

if err != nil {
return nil, errors.Wrapf(err, "Cannot determine the project root for %s", pkg.Name)
i.Logger.Printf(
" Warning: Skipping project. Cannot determine the project root for %s: %s\n",
pkg.Name, err,
)
continue
}
pkg.Name = string(pr)

Expand All @@ -159,7 +163,7 @@ func (i *Importer) loadPackages(packages []ImportedPackage) ([]importedProject,
}
}

return orderedProjects, nil
return orderedProjects
}

// ImportPackages loads imported packages into the manifest and lock.
Expand All @@ -173,11 +177,8 @@ func (i *Importer) loadPackages(packages []ImportedPackage) ([]importedProject,
// * Revision constraints are ignored.
// * Versions that don't satisfy the constraint, drop the constraint.
// * Untagged revisions ignore non-branch constraint hints.
func (i *Importer) ImportPackages(packages []ImportedPackage, defaultConstraintFromLock bool) (err error) {
projects, err := i.loadPackages(packages)
if err != nil {
return err
}
func (i *Importer) ImportPackages(packages []ImportedPackage, defaultConstraintFromLock bool) {
projects := i.loadPackages(packages)

for _, prj := range projects {
source := prj.Source
Expand All @@ -201,6 +202,7 @@ func (i *Importer) ImportPackages(packages []ImportedPackage, defaultConstraintF
},
}

var err error
pc.Constraint, err = i.SourceManager.InferConstraint(prj.ConstraintHint, pc.Ident)
if err != nil {
pc.Constraint = gps.Any()
Expand All @@ -212,9 +214,12 @@ func (i *Importer) ImportPackages(packages []ImportedPackage, defaultConstraintF
// Determine if the lock hint is a revision or tag
isTag, version, err = i.isTag(pc.Ident, prj.LockHint)
if err != nil {
return err
i.Logger.Printf(
" Warning: Skipping project. Unable to apply constraint %q for %v: %s\n",
prj.LockHint, pc.Ident, err,
)
continue
}

// If the hint is a revision, check if it is tagged
if !isTag {
revision := gps.Revision(prj.LockHint)
Expand Down Expand Up @@ -270,8 +275,6 @@ func (i *Importer) ImportPackages(packages []ImportedPackage, defaultConstraintF
fb.NewLockedProjectFeedback(lp, fb.DepTypeImported).LogFeedback(i.Logger)
}
}

return nil
}

// isConstraintPinned returns if a constraint is pinned to a specific revision.
Expand Down
33 changes: 30 additions & 3 deletions internal/importers/base/importer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package base

import (
"fmt"
"log"
"testing"

Expand Down Expand Up @@ -399,16 +400,42 @@ func TestBaseImporter_ImportProjects(t *testing.T) {
},
},
},
"invalid project root": {
importertest.TestCase{
WantSourceRepo: "",
WantWarning: "Warning: Skipping project. Cannot determine the project root for invalid-project",
},
[]ImportedPackage{
{
Name: "invalid-project",
},
},
},
"nonexistent project": {
importertest.TestCase{
WantSourceRepo: "",
WantWarning: fmt.Sprintf(
"Warning: Skipping project. Unable to apply constraint %q for %s",
importertest.V1Tag, importertest.NonexistentPrj,
),
},
[]ImportedPackage{
{
Name: importertest.NonexistentPrj,
LockHint: importertest.V1Tag,
},
},
},
}

for name, tc := range testcases {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
err := tc.Execute(t, func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock, error) {
err := tc.Execute(t, func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock) {
i := NewImporter(logger, true, sm)
convertErr := i.ImportPackages(tc.projects, tc.DefaultConstraintFromLock)
return i.Manifest, i.Lock, convertErr
i.ImportPackages(tc.projects, tc.DefaultConstraintFromLock)
return i.Manifest, i.Lock
})
if err != nil {
t.Fatalf("%#v", err)
Expand Down
32 changes: 19 additions & 13 deletions internal/importers/glide/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,13 @@ func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.L
return nil, nil, err
}

return g.convert(pr)
m, l := g.convert(pr)
return m, l, nil
}

// load the glide configuration files.
// load the glide configuration files. Failure to load `glide.yaml` is considered
// unrecoverable and an error is returned for it. But if there is any error while trying
// to load the lock file, only a warning is logged.
func (g *Importer) load(projectDir string) error {
g.Logger.Println("Detected glide configuration files...")
y := filepath.Join(projectDir, glideYamlName)
Expand All @@ -113,24 +116,26 @@ func (g *Importer) load(projectDir string) error {
if g.Verbose {
g.Logger.Printf(" Loading %s", l)
}
g.lockFound = true
lb, err := ioutil.ReadFile(l)
if err != nil {
return errors.Wrapf(err, "unable to read %s", l)
g.Logger.Printf(" Warning: Ignoring lock file. Unable to read %s: %s\n", l, err)
return nil
}
lock := glideLock{}
err = yaml.Unmarshal(lb, &lock)
if err != nil {
return errors.Wrapf(err, "unable to parse %s", l)
g.Logger.Printf(" Warning: Ignoring lock file. Unable to parse %s: %s\n", l, err)
return nil
}
g.lockFound = true
g.glideLock = lock
}

return nil
}

// convert the glide configuration files into dep configuration files.
func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) {
projectName := string(pr)

task := bytes.NewBufferString("Converting from glide.yaml")
Expand All @@ -147,7 +152,10 @@ func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error)
for _, pkg := range append(g.glideConfig.Imports, g.glideConfig.TestImports...) {
// Validate
if pkg.Name == "" {
return nil, nil, errors.New("invalid glide configuration: Name is required")
g.Logger.Println(
" Warning: Skipping project. Invalid glide configuration, Name is required",
)
continue
}

// Warn
Expand All @@ -172,7 +180,8 @@ func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error)
for _, pkg := range append(g.glideLock.Imports, g.glideLock.TestImports...) {
// Validate
if pkg.Name == "" {
return nil, nil, errors.New("invalid glide lock: Name is required")
g.Logger.Println(" Warning: Skipping project. Invalid glide lock, Name is required")
continue
}

ip := base.ImportedPackage{
Expand All @@ -183,10 +192,7 @@ func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error)
packages = append(packages, ip)
}

err := g.ImportPackages(packages, false)
if err != nil {
return nil, nil, errors.Wrap(err, "invalid glide configuration")
}
g.ImportPackages(packages, false)

// Ignores
g.Manifest.Ignored = append(g.Manifest.Ignored, g.glideConfig.Ignores...)
Expand All @@ -201,5 +207,5 @@ func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error)
}
}

return g.Manifest, g.Lock, nil
return g.Manifest, g.Lock
}
4 changes: 2 additions & 2 deletions internal/importers/glide/importer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func TestGlideConfig_Convert(t *testing.T) {
},
glideLock{},
importertest.TestCase{
WantConvertErr: true,
WantWarning: "Warning: Skipping project. Invalid glide configuration, Name is required",
},
},
"warn unused os field": {
Expand Down Expand Up @@ -160,7 +160,7 @@ func TestGlideConfig_Convert(t *testing.T) {
name := name
testCase := testCase
t.Run(name, func(t *testing.T) {
err := testCase.Execute(t, func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock, error) {
err := testCase.Execute(t, func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock) {
g := NewImporter(logger, true, sm)
g.glideConfig = testCase.yaml
g.glideLock = testCase.lock
Expand Down
Loading