-
Notifications
You must be signed in to change notification settings - Fork 1k
Conversation
eb7f1b4
to
c77daf6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is exactly what I was thinking! 👍
You are doing the right thing for testing the individual imports, we just need tests in the base importer for any warnings/skips we are doing there too.
If we can add a test for the root analyzer to handle a missing/bad config file (just pick 1 like glide), then that is adequate. If that isn't easy/straightforward, let's add that to the integration tests in https://github.com/golang/dep/tree/master/cmd/dep/testdata/harness_tests/init/glide to make sure that dep falls back to doing a standard import when the config is not loadable.
Don't worry about a "allowed number of errors" check or treating warnings as errors for now. I'd like to see this in action first, and we can consider those separately. I'm not sure either will be necessary yet.
internal/importers/base/importer.go
Outdated
@@ -132,7 +132,11 @@ func (i *Importer) loadPackages(packages []ImportedPackage) ([]importedProject, | |||
for _, pkg := range packages { | |||
pr, err := i.SourceManager.DeduceProjectRoot(pkg.Name) | |||
if err != nil { | |||
return nil, errors.Wrapf(err, "Cannot determine the project root for %s", pkg.Name) | |||
i.Logger.Printf( | |||
" Warning: Cannot determine the project root for %s: %s\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make it clear that we are skipping this project.
" Warning: Skipping project. Cannot determine ..."
internal/importers/glide/importer.go
Outdated
@@ -147,7 +152,8 @@ 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: Invalid glide configuration: Name is required") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make it clear that we are skipping (though yeah there's not much to show):
" Warning: Skipping package. Invalid glide configuration..."
internal/importers/glide/importer.go
Outdated
@@ -172,7 +178,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: Invalid glide lock: Name is required") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about skipping as above.
@@ -125,7 +125,7 @@ func TestGlideConfig_Convert(t *testing.T) { | |||
}, | |||
glideLock{}, | |||
importertest.TestCase{ | |||
WantConvertErr: true, | |||
WantWarning: "Warning: Invalid glide configuration: Name is required", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is exactly how we should test these changes. 👍
internal/importers/glock/importer.go
Outdated
@@ -79,14 +80,19 @@ func (g *Importer) load(projectDir string) error { | |||
for scanner.Scan() { | |||
pkg, err := parseGlockLine(scanner.Text()) | |||
if err != nil { | |||
return err | |||
g.Logger.Printf(" Warning: Unable to parse line: %s\n", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include the word "Skipping" in this somewhere.
} | ||
if pkg == nil { | ||
continue | ||
} | ||
g.packages = append(g.packages, *pkg) | ||
} | ||
|
||
if err := scanner.Err(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something that you introduced? Or am I just missing where it was moved from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw that it was present in the importer for vndr
which uses a scanner
as well:
dep/internal/importers/vndr/importer.go
Lines 78 to 80 in d9ce240
if scanner.Err() != nil { | |
return errors.Wrapf(err, "unable to read %s", vndrFile(dir)) | |
} |
I figured that either it should be present in both locations or neither. And logging a warning for an error seemed better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! I was just curious where it came from but now I see it in vndr. 👍
internal/importers/glock/importer.go
Outdated
} | ||
|
||
if pkg.revision == "" { | ||
return nil, nil, errors.New("invalid glock configuration, revision is required") | ||
g.Logger.Printf( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since glock only provides revisions, if it's empty we should skip and continue to the next project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand. If the revision isn't present we would just not have the LockHint
. Isn't it better to still add the package? I would also need to do these changes in a few other places where I continue with importing the package even though the contraint/lock hint could not be resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
glock is unique because it doesn't provide a ConstraintHint or Source, just the LockHint. So if the imported config have a LockHint, then there's no point it continuing. Dep doesn't add "empty constraints" to the manifest during import, and the normal solve step will add the project to the lock if needed, so when the LockHint, ConstraintHint and Source are empty, it's a no-op.
The other tools may still have a ConstraintHint or Source, which is why we don't stop as soon as we know that the LockHint is empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. I looked through the rest of the importers and the same scenario applies to govend
as well:
dep/internal/importers/govend/importer.go
Lines 100 to 109 in c77daf6
if pkg.Revision == "" { | |
g.Logger.Printf( | |
" Warning: Invalid govend configuration, rev not found for Path %q\n", pkg.Path, | |
) | |
} | |
ip := base.ImportedPackage{ | |
Name: pkg.Path, | |
LockHint: pkg.Revision, | |
} |
Additionally, I do have a concern regarding this because the warning might be misleading. Like me, the user might also be confused by Skipping package..
. How about changing the warning to something like Warning: Skipping import with empty constraints. The solve step will add the dependency to the lock if needed.
? too long?
internal/importers/vndr/importer.go
Outdated
} | ||
defer f.Close() | ||
|
||
scanner := bufio.NewScanner(f) | ||
for scanner.Scan() { | ||
pkg, err := parseVndrLine(scanner.Text()) | ||
if err != nil { | ||
return errors.Wrapf(err, "unable to parse line") | ||
v.Logger.Printf(" Warning: Unable to parse line: %s\n", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include the word "skipping" in the warning.
@@ -75,25 +78,27 @@ func (v *Importer) loadVndrFile(dir string) error { | |||
v.packages = append(v.packages, *pkg) | |||
} | |||
|
|||
if scanner.Err() != nil { | |||
return errors.Wrapf(err, "unable to read %s", vndrFile(dir)) | |||
if err := scanner.Err(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make it clear that we are ignoring the errors found.
" Warning: Ignoring errors found while parsing %s..."
@@ -132,7 +132,11 @@ func (i *Importer) loadPackages(packages []ImportedPackage) ([]importedProject, | |||
for _, pkg := range packages { | |||
pr, err := i.SourceManager.DeduceProjectRoot(pkg.Name) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
internal/importers/base/importer.go
Outdated
version = nil | ||
i.Logger.Println(err) | ||
if isTag, version, err = i.isTag(pc.Ident, prj.LockHint); err != nil { | ||
i.Logger.Printf( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was looking to test this and from what I can tell, an error would be returned only if the package did not exist(or network errs but we aren't really testing for that). Perhaps it might be more appropriate to skip the project on encountering an error here?
@carolynvs I have pushed some commits which should address the feedback you had given. Other than that, I have the following questions which I mentioned in code comments above:
|
I like your warning better, go with it. 👍
In general anywhere that we used to return an error should now skip to the next project. So let's skip if that function returns an error. |
internal/importers/glide/importer.go
Outdated
@@ -152,7 +152,9 @@ func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { | |||
for _, pkg := range append(g.glideConfig.Imports, g.glideConfig.TestImports...) { | |||
// Validate | |||
if pkg.Name == "" { | |||
g.Logger.Println(" Warning: Invalid glide configuration: Name is required") | |||
g.Logger.Println( | |||
" Warning: Skipping package. Invalid glide configuration, Name is required", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should all say "Skipping project", not package.
5f45022
to
57a5d17
Compare
- root_analyzer.go: Log a warning on encountering an unrecoverable error during import of external config and proceed with the import for other packages. Do not return error from private func `importManifestAndLock`. internal/importers: - base/importer.go: - `loadPackages`: Do not return error. If `SourceManager.DeduceProjectRoot` fails to determine the project root, log a warning and continue with the rest of the imported packages. - `ImportPackages`: Do not return error. When constraint resolution from the lock hint fails, only log a warning. - Importer implementations: - Return an error from `Import` only for catastrophic failures(ex: yaml parsing failed). - `load`: Make it more error tolerant. Log warnings only for any of the following scenarios: - When and if a lock file, separate from the dependency file is present, like, in the case of glide, and parsing fails. Continue with the import as if the lock file was not present. - If import packages are parsed line by line like in the case of glock, and one of the line could not be parsed. - `convert`: Do not return an error. Log warnings only for any of the following scenarios: - Expected field, such as `package` for an entry in `glide.yaml>imports` is not present. - Package was specified but the contraint could not be found.
Address feedback from @carolynvs
- internal/importers/base/importer_test.go: - Check for warning when an invalid project is present whose project root cannot be parsed. - Check for warning when lock hint cannot be resolved correctly and the constraint cannot be applied. - Integration test for malformed external config(glide.yaml)
- {package => project} - Improve warning message when no constraint is found for the package being imported.
57a5d17
to
4c9c06d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfecto! ✨
Yay 🎉 and thanks for all the help! |
What does this do / why do we need it?
This makes the import process much more error tolerant. In case of a catastrophic failure, a warning is logged and the root analyzer gives up on importing the external config but only for that directory. On the other hand, for less serious errors such as failure to load
glide.lock
etc., no error is returned and only a warning is logged.What should your reviewer look out for in this PR?
Is the approach in the correct direction? There's still work left to be done but I would like to get some early feedback.
Do you need help or clarification on anything?
Which issue(s) does this PR fix?
fixes #1315
Code changelog
import of external config and proceed with the import for other packages.
Do not return error from private func
importManifestAndLock
.internal/importers
:loadPackages
: Do not return error. IfSourceManager.DeduceProjectRoot
fails to determine the project root, log a warning and continue with the
rest of the imported packages.
ImportPackages
: Do not return error. When constraint resolution from thelock hint fails, only log a warning.
Import
only for catastrophic failures(ex: yamlparsing failed).
load
: Make it more error tolerant. Log warnings only for any of thefollowing scenarios:
like, in the case of glide, and parsing fails. Continue with the import
as if the lock file was not present.
and one of the line could not be parsed.
convert
: Do not return an error. Log warnings only for any of thefollowing scenarios:
package
for an entry inglide.yaml>imports
is not present.
tests
:internal/importers/base/importer_test.go
:cannot be parsed.
constraint cannot be applied.
TODO: