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

Wildcard ignores #1156

Merged
merged 12 commits into from
Oct 12, 2017
Merged

Wildcard ignores #1156

merged 12 commits into from
Oct 12, 2017

Conversation

darkowlzz
Copy link
Collaborator

What does this do / why do we need it?

Adds support for ignoring packages and subpackages using wildcard notation ("/*").

What should your reviewer look out for in this PR?

Implementation and tests. All the changes are in manifest, not touching gps.

Do you need help or clarification on anything?

Do we use "/*" or "/..." for this need?

Which issue(s) does this PR fix?

fixes #691

@sdboyer
Copy link
Member

sdboyer commented Sep 11, 2017

we definitely want /*, as the rules we're applying aren't the same as /....

this approach of doing it out in dep isn't going to work, unfortunately. at most, it helps us with the root project, but it doesn't do anything for dependencies. we've gotta handle this in the solver.

@sdboyer
Copy link
Member

sdboyer commented Sep 11, 2017

specifically, we'll need to introduce some new props, maybe a slice of strings, on the rootdata struct that hold the prefixes to exclude. then, everywhere that we currently check rd.ig in the solver...well, we can convert those to a new method, rootdata.isIgnored(path string), which should check both the literal rd.ig map and do a prefix-based exclusion check on each of the strings.

actually, no, not a slice. we'll want a trie, so that the prefix search is O(1) in the number of wildcard ignores specified by the root.

i'm musing on whether or not we want the ignores to be case-insensitive, in keeping with #1079. for now, let's assume no - not only is that easier, but i think it's more consistent with shell-globbing, and so will be less confusing for people.

@darkowlzz
Copy link
Collaborator Author

ah! right! didn't think of the dependencies. I'll try to implement it in the solver 😊

@darkowlzz
Copy link
Collaborator Author

darkowlzz commented Sep 12, 2017

Another attempt 😅
Removed the first commit of this PR which changed dep's manifest, but kept the ensure integration test which tested recursive ignore in the main project.

Copy link
Member

@sdboyer sdboyer left a comment

Choose a reason for hiding this comment

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

definitely looks like we're heading in the right direction!

)

// recursive ignore suffix
Copy link
Member

Choose a reason for hiding this comment

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

"recursive" isn't quite the right word to use for this, as it suggests a specific type of self-referential algorithm. better to just call these "wildcard ignores."

)

// recursive ignore suffix
const recIgnoreSuffix = "/*"
Copy link
Member

Choose a reason for hiding this comment

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

i don't see a reason why we actually have to restrict to immediately following a slash - i think our only criteria here is that the asterisk has to be the last character.

@@ -445,6 +450,15 @@ func (t PackageTree) ToReachMap(main, tests, backprop bool, ignore map[string]bo
ignore = make(map[string]bool)
}

// Create a radix tree for ignore prefixes
xt := radix.New()
Copy link
Member

Choose a reason for hiding this comment

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

this allocs because it returns a pointer, so let's defer creating the trie until the last possible moment - if we see something with the expected suffix.

@darkowlzz darkowlzz changed the title Recursive ignore Wildcard ignores Sep 13, 2017
@darkowlzz darkowlzz force-pushed the recursive-ignore branch 2 times, most recently from c768bc2 to 9e652ed Compare September 13, 2017 13:01
@darkowlzz
Copy link
Collaborator Author

  • Renamed to "wildcard" and changed "/" to "" only.
  • Create new radix tree only when wildcard suffix is found in ignore list.
  • Updated docs/Gopkg.toml.md with wildcard ignore.

Do we have any existing repo that could be used to test dependency package ignore?

if xt == nil {
xt = radix.New()
}
i = strings.TrimSuffix(i, wcIgnoreSuffix)
Copy link
Member

Choose a reason for hiding this comment

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

This ends up on the strings.HasSuffix() call. better to just do the trim operation ourselves.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You mean for cases like "github.com/x/someprefix-*-somesuffix"?
Like using regex match?

Copy link
Member

Choose a reason for hiding this comment

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

nope, i meant that this is the implementation of string.TrimSuffix():

func TrimSuffix(s, suffix string) string {
	if HasSuffix(s, suffix) {
		return s[:len(s)-len(suffix)]
	}
	return s
}

and the conditional has already been checked, so it's better to just do the s[:len(s)-len(suffix)] operation ourselves rather than calling strings.TrimSuffix(), as this method is processing-bound (possibly memory, possibly CPU), and this is within a loop, so easy microoptimizations like this are worth it.

@sdboyer
Copy link
Member

sdboyer commented Sep 26, 2017

so the PR as-is seems like it covers the essentials. now, i think, we need to do the harder work of thinking through the models and making sure that the edge cases are covered - especially the new ones that are induced by this.

here are a few i can think of:

  • i think a global ignore - "*" - should probably just not be allowed.
  • ineffectual ignores should be something we warn on, or at the very least do not include in hash inputs. that is, if github.com/foo* is ignored, then github.com/foo/bar* is ineffectual.
  • we should definitely have at least one more hash inputs test.
  • is there anywhere that we checks against ignored lists up in dep itself? perhaps on ensure -add. if so, they'll need to be updated. and we may need to add some new ones, though i'm not exactly sure what that would look like.

these are just what i can think of right now.

also, this change will probably entail us bumping the solver version. consequently, i may want to wait to merge it until just before we're ready to make the next release (which'll be v0.4.0), as otherwise we potentially create contention between team members who're chasing tip, vs. those using a release version.

@darkowlzz darkowlzz force-pushed the recursive-ignore branch 5 times, most recently from 68ac3c2 to 4f73e5f Compare September 28, 2017 12:01
@darkowlzz
Copy link
Collaborator Author

darkowlzz commented Sep 28, 2017

  • ignore global ignores
  • ignore ineffectual wildcard ignores
  • do not include ineffectual wildcard ignores in hash inputs
  • hash inputs test to verify exclusion of ineffectual wildcard ignores

is there anywhere that we checks against ignored lists up in dep itself? perhaps on ensure -add. if so, they'll need to be updated. and we may need to add some new ones, though i'm not exactly sure what that would look like.

@sdboyer Yes, right now we use IgnoredPackages only in ensure -add. But since this is passed to pkgtree.ToReachMap(), and ToReachMap() being aware of how to handle wildcards, there shouldn't be any issues.

I have a PR that uses IgnoredPackages but I think that can be avoided by using ToReachMap() and get package maps with all the ignoring rules applied.

@darkowlzz
Copy link
Collaborator Author

I went through both gps and dep, and found that most of the places where we care about ignoring use PackageTree.ToReachMap() with the ignored list passed to them to get a map of packages. So, no change would be required in those places.

SolveParameters.toRootdata() checks if a package is present in required as well as ignored. That needs to be changed to check the wildcard ignores too. Will add that in the next commit.


// Add wildcard ignores to ignore list.
if s.rd.igpfx != nil {
s.rd.igpfx.Walk(radix.WalkFn(func(s string, v interface{}) bool {
Copy link
Member

Choose a reason for hiding this comment

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

nit: it should be unnecessary to have the type conversion here - just passing the anonymous function with the correct signature is sufficient.

Copy link
Member

@sdboyer sdboyer left a comment

Choose a reason for hiding this comment

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

just the two nits then we can merge

@@ -16,8 +16,13 @@ import (
"strconv"
"strings"
"unicode"

radix "github.com/armon/go-radix"
Copy link
Member

Choose a reason for hiding this comment

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

the package name is already radix, so this is unnecessary.

@darkowlzz
Copy link
Collaborator Author

Excited for this 😃

Copy link
Collaborator

@ibrasho ibrasho left a comment

Choose a reason for hiding this comment

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

Just one question and then it LGTM.

// CreateIgnorePrefixTree takes a set of strings to be ignored and returns a
// trie consisting of strings prefixed with wildcard ignore suffix (*).
func CreateIgnorePrefixTree(ig map[string]bool) *radix.Tree {
var xt *radix.Tree
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not initialize a new tree here instead of checking for nil later on?

Copy link
Collaborator Author

@darkowlzz darkowlzz Oct 6, 2017

Choose a reason for hiding this comment

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

We had that earlier but then we decided to allocate memory only when we get a wildcard suffix. Refer #1156 (comment)

@sdboyer
Copy link
Member

sdboyer commented Oct 6, 2017

woohoo!

i think we should roll a release after this. speaking of, this is missing a CHANGELOG update :)

@sdboyer
Copy link
Member

sdboyer commented Oct 12, 2017

fix CHANGELOG conflict for this, and we're good to go on it

@googlebot
Copy link
Collaborator

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that they're okay with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this State. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

@sdboyer
Copy link
Member

sdboyer commented Oct 12, 2017

nvm, i just fixed it directly :)