diff options
Diffstat (limited to 'android/neverallow.go')
| -rw-r--r-- | android/neverallow.go | 76 |
1 files changed, 53 insertions, 23 deletions
diff --git a/android/neverallow.go b/android/neverallow.go index 034861958..4bb3e57b5 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -15,6 +15,7 @@ package android import ( + "fmt" "path/filepath" "reflect" "regexp" @@ -372,6 +373,20 @@ type ruleProperty struct { matcher ValueMatcher } +func (r *ruleProperty) String() string { + return fmt.Sprintf("%q matches: %s", strings.Join(r.fields, "."), r.matcher) +} + +type ruleProperties []ruleProperty + +func (r ruleProperties) String() string { + var s []string + for _, r := range r { + s = append(s, r.String()) + } + return strings.Join(s, " ") +} + // A NeverAllow rule. type Rule interface { In(path ...string) Rule @@ -413,8 +428,8 @@ type rule struct { moduleTypes []string unlessModuleTypes []string - props []ruleProperty - unlessProps []ruleProperty + props ruleProperties + unlessProps ruleProperties onlyBootclasspathJar bool } @@ -424,16 +439,19 @@ func NeverAllow() Rule { return &rule{directDeps: make(map[string]bool)} } +// In adds path(s) where this rule applies. func (r *rule) In(path ...string) Rule { r.paths = append(r.paths, cleanPaths(path)...) return r } +// NotIn adds path(s) to that this rule does not apply to. func (r *rule) NotIn(path ...string) Rule { r.unlessPaths = append(r.unlessPaths, cleanPaths(path)...) return r } +// InDirectDeps adds dep(s) that are not allowed with this rule. func (r *rule) InDirectDeps(deps ...string) Rule { for _, d := range deps { r.directDeps[d] = true @@ -441,25 +459,30 @@ func (r *rule) InDirectDeps(deps ...string) Rule { return r } +// WithOsClass adds osClass(es) that this rule applies to. func (r *rule) WithOsClass(osClasses ...OsClass) Rule { r.osClasses = append(r.osClasses, osClasses...) return r } +// ModuleType adds type(s) that this rule applies to. func (r *rule) ModuleType(types ...string) Rule { r.moduleTypes = append(r.moduleTypes, types...) return r } +// NotModuleType adds type(s) that this rule does not apply to.. func (r *rule) NotModuleType(types ...string) Rule { r.unlessModuleTypes = append(r.unlessModuleTypes, types...) return r } +// With specifies property/value combinations that are restricted for this rule. func (r *rule) With(properties, value string) Rule { return r.WithMatcher(properties, selectMatcher(value)) } +// WithMatcher specifies property/matcher combinations that are restricted for this rule. func (r *rule) WithMatcher(properties string, matcher ValueMatcher) Rule { r.props = append(r.props, ruleProperty{ fields: fieldNamesForProperties(properties), @@ -468,10 +491,12 @@ func (r *rule) WithMatcher(properties string, matcher ValueMatcher) Rule { return r } +// Without specifies property/value combinations that this rule does not apply to. func (r *rule) Without(properties, value string) Rule { return r.WithoutMatcher(properties, selectMatcher(value)) } +// Without specifies property/matcher combinations that this rule does not apply to. func (r *rule) WithoutMatcher(properties string, matcher ValueMatcher) Rule { r.unlessProps = append(r.unlessProps, ruleProperty{ fields: fieldNamesForProperties(properties), @@ -487,49 +512,54 @@ func selectMatcher(expected string) ValueMatcher { return &equalMatcher{expected: expected} } +// Because specifies a reason for this rule. func (r *rule) Because(reason string) Rule { r.reason = reason return r } +// BootclasspathJar whether this rule only applies to Jars in the Bootclasspath func (r *rule) BootclasspathJar() Rule { r.onlyBootclasspathJar = true return r } func (r *rule) String() string { - s := "neverallow" - for _, v := range r.paths { - s += " dir:" + v + "*" + s := []string{"neverallow requirements. Not allowed:"} + if len(r.paths) > 0 { + s = append(s, fmt.Sprintf("in dirs: %q", r.paths)) } - for _, v := range r.unlessPaths { - s += " -dir:" + v + "*" + if len(r.moduleTypes) > 0 { + s = append(s, fmt.Sprintf("module types: %q", r.moduleTypes)) } - for _, v := range r.moduleTypes { - s += " type:" + v + if len(r.props) > 0 { + s = append(s, fmt.Sprintf("properties matching: %s", r.props)) } - for _, v := range r.unlessModuleTypes { - s += " -type:" + v + if len(r.directDeps) > 0 { + s = append(s, fmt.Sprintf("dep(s): %q", SortedStringKeys(r.directDeps))) } - for _, v := range r.props { - s += " " + strings.Join(v.fields, ".") + v.matcher.String() + if len(r.osClasses) > 0 { + s = append(s, fmt.Sprintf("os class(es): %q", r.osClasses)) } - for _, v := range r.unlessProps { - s += " -" + strings.Join(v.fields, ".") + v.matcher.String() + if r.onlyBootclasspathJar { + s = append(s, "in bootclasspath jar") } - for k := range r.directDeps { - s += " deps:" + k + if len(r.unlessPaths) > 0 { + s = append(s, fmt.Sprintf("EXCEPT in dirs: %q", r.unlessPaths)) } - for _, v := range r.osClasses { - s += " os:" + v.String() + if len(r.unlessModuleTypes) > 0 { + s = append(s, fmt.Sprintf("EXCEPT module types: %q", r.unlessModuleTypes)) } - if r.onlyBootclasspathJar { - s += " inBcp" + if len(r.unlessProps) > 0 { + s = append(s, fmt.Sprintf("EXCEPT properties matching: %q", r.unlessProps)) } if len(r.reason) != 0 { - s += " which is restricted because " + r.reason + s = append(s, " which is restricted because "+r.reason) + } + if len(s) == 1 { + s[0] = "neverallow requirements (empty)" } - return s + return strings.Join(s, "\n\t") } func (r *rule) appliesToPath(dir string) bool { |