mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-06-05 05:20:34 +00:00
Refactoring: move query tree to deb package.
This commit is contained in:
+12
-12
@@ -14,7 +14,7 @@ type parser struct {
|
||||
err error // error stored while parsing
|
||||
}
|
||||
|
||||
func parse(input *lexer) (PackageQuery, error) {
|
||||
func parse(input *lexer) (deb.PackageQuery, error) {
|
||||
p := &parser{
|
||||
name: input.name,
|
||||
input: input,
|
||||
@@ -27,7 +27,7 @@ func parse(input *lexer) (PackageQuery, error) {
|
||||
}
|
||||
|
||||
// Entry into parser
|
||||
func (p *parser) parse() PackageQuery {
|
||||
func (p *parser) parse() deb.PackageQuery {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
p.err = fmt.Errorf("parsing failed: %s", r)
|
||||
@@ -42,36 +42,36 @@ func (p *parser) parse() PackageQuery {
|
||||
}
|
||||
|
||||
// Query := A | A '|' Query
|
||||
func (p *parser) Query() PackageQuery {
|
||||
func (p *parser) Query() deb.PackageQuery {
|
||||
q := p.A()
|
||||
if p.input.Current().typ == itemOr {
|
||||
p.input.Consume()
|
||||
return &OrQuery{L: q, R: p.Query()}
|
||||
return &deb.OrQuery{L: q, R: p.Query()}
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
// A := B | B ',' A
|
||||
func (p *parser) A() PackageQuery {
|
||||
func (p *parser) A() deb.PackageQuery {
|
||||
q := p.B()
|
||||
if p.input.Current().typ == itemAnd {
|
||||
p.input.Consume()
|
||||
return &AndQuery{L: q, R: p.A()}
|
||||
return &deb.AndQuery{L: q, R: p.A()}
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
// B := C | '!' B
|
||||
func (p *parser) B() PackageQuery {
|
||||
func (p *parser) B() deb.PackageQuery {
|
||||
if p.input.Current().typ == itemNot {
|
||||
p.input.Consume()
|
||||
return &NotQuery{Q: p.B()}
|
||||
return &deb.NotQuery{Q: p.B()}
|
||||
}
|
||||
return p.C()
|
||||
}
|
||||
|
||||
// C := '(' Query ')' | D
|
||||
func (p *parser) C() PackageQuery {
|
||||
func (p *parser) C() deb.PackageQuery {
|
||||
if p.input.Current().typ == itemLeftParen {
|
||||
p.input.Consume()
|
||||
q := p.Query()
|
||||
@@ -108,7 +108,7 @@ func operatorToRelation(operator itemType) int {
|
||||
|
||||
// D := <field> <condition>
|
||||
// field := <package-name> | <field> | $special_field
|
||||
func (p *parser) D() PackageQuery {
|
||||
func (p *parser) D() deb.PackageQuery {
|
||||
if p.input.Current().typ != itemString {
|
||||
panic(fmt.Sprintf("unexpected token %s: expecting field or package name", p.input.Current()))
|
||||
}
|
||||
@@ -121,11 +121,11 @@ func (p *parser) D() PackageQuery {
|
||||
r, _ := utf8.DecodeRuneInString(field)
|
||||
if strings.HasPrefix(field, "$") || unicode.IsUpper(r) {
|
||||
// special field or regular field
|
||||
return &FieldQuery{Field: field, Relation: operatorToRelation(operator), Value: value}
|
||||
return &deb.FieldQuery{Field: field, Relation: operatorToRelation(operator), Value: value}
|
||||
}
|
||||
|
||||
// regular dependency-like query
|
||||
return &DependencyQuery{Dep: deb.Dependency{Pkg: field, Relation: operatorToRelation(operator), Version: value}}
|
||||
return &deb.DependencyQuery{Dep: deb.Dependency{Pkg: field, Relation: operatorToRelation(operator), Version: value}}
|
||||
}
|
||||
|
||||
// condition := '(' <operator> value ')' |
|
||||
|
||||
@@ -15,30 +15,30 @@ func (s *SyntaxSuite) TestParsing(c *C) {
|
||||
q, err := parse(l)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Check(q.(*AndQuery).L, DeepEquals, &DependencyQuery{Dep: deb.Dependency{Pkg: "package", Relation: deb.VersionLess, Version: "1.3"}})
|
||||
c.Check(q.(*AndQuery).R, DeepEquals, &FieldQuery{Field: "$Source"})
|
||||
c.Check(q.(*deb.AndQuery).L, DeepEquals, &deb.DependencyQuery{Dep: deb.Dependency{Pkg: "package", Relation: deb.VersionLess, Version: "1.3"}})
|
||||
c.Check(q.(*deb.AndQuery).R, DeepEquals, &deb.FieldQuery{Field: "$Source"})
|
||||
|
||||
l, _ = lex("query", "package (1.3), Name (lala) | !$Source")
|
||||
q, err = parse(l)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Check(q.(*OrQuery).L.(*AndQuery).L, DeepEquals, &DependencyQuery{Dep: deb.Dependency{Pkg: "package", Relation: deb.VersionEqual, Version: "1.3"}})
|
||||
c.Check(q.(*OrQuery).L.(*AndQuery).R, DeepEquals, &FieldQuery{Field: "Name", Relation: deb.VersionEqual, Value: "lala"})
|
||||
c.Check(q.(*OrQuery).R.(*NotQuery).Q, DeepEquals, &FieldQuery{Field: "$Source"})
|
||||
c.Check(q.(*deb.OrQuery).L.(*deb.AndQuery).L, DeepEquals, &deb.DependencyQuery{Dep: deb.Dependency{Pkg: "package", Relation: deb.VersionEqual, Version: "1.3"}})
|
||||
c.Check(q.(*deb.OrQuery).L.(*deb.AndQuery).R, DeepEquals, &deb.FieldQuery{Field: "Name", Relation: deb.VersionEqual, Value: "lala"})
|
||||
c.Check(q.(*deb.OrQuery).R.(*deb.NotQuery).Q, DeepEquals, &deb.FieldQuery{Field: "$Source"})
|
||||
|
||||
l, _ = lex("query", "package, ((!(Name | $Source (~ a.*))))")
|
||||
q, err = parse(l)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Check(q.(*AndQuery).L, DeepEquals, &DependencyQuery{Dep: deb.Dependency{Pkg: "package", Relation: deb.VersionDontCare}})
|
||||
c.Check(q.(*AndQuery).R.(*NotQuery).Q.(*OrQuery).L, DeepEquals, &FieldQuery{Field: "Name", Relation: deb.VersionDontCare})
|
||||
c.Check(q.(*AndQuery).R.(*NotQuery).Q.(*OrQuery).R, DeepEquals, &FieldQuery{Field: "$Source", Relation: deb.VersionRegexp, Value: "a.*"})
|
||||
c.Check(q.(*deb.AndQuery).L, DeepEquals, &deb.DependencyQuery{Dep: deb.Dependency{Pkg: "package", Relation: deb.VersionDontCare}})
|
||||
c.Check(q.(*deb.AndQuery).R.(*deb.NotQuery).Q.(*deb.OrQuery).L, DeepEquals, &deb.FieldQuery{Field: "Name", Relation: deb.VersionDontCare})
|
||||
c.Check(q.(*deb.AndQuery).R.(*deb.NotQuery).Q.(*deb.OrQuery).R, DeepEquals, &deb.FieldQuery{Field: "$Source", Relation: deb.VersionRegexp, Value: "a.*"})
|
||||
|
||||
l, _ = lex("query", "package (> 5.3.7)")
|
||||
q, err = parse(l)
|
||||
|
||||
c.Assert(err, IsNil)
|
||||
c.Check(q, DeepEquals, &DependencyQuery{Dep: deb.Dependency{Pkg: "package", Relation: deb.VersionGreaterOrEqual, Version: "5.3.7"}})
|
||||
c.Check(q, DeepEquals, &deb.DependencyQuery{Dep: deb.Dependency{Pkg: "package", Relation: deb.VersionGreaterOrEqual, Version: "5.3.7"}})
|
||||
}
|
||||
|
||||
func (s *SyntaxSuite) TestParsingErrors(c *C) {
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"github.com/smira/aptly/deb"
|
||||
)
|
||||
|
||||
// PackageQuery is interface of predicate on Package
|
||||
type PackageQuery interface {
|
||||
Matches(pkg *deb.Package) bool
|
||||
}
|
||||
|
||||
// OrQuery is L | R
|
||||
type OrQuery struct {
|
||||
L, R PackageQuery
|
||||
}
|
||||
|
||||
// AndQuery is L , R
|
||||
type AndQuery struct {
|
||||
L, R PackageQuery
|
||||
}
|
||||
|
||||
// NotQuery is ! Q
|
||||
type NotQuery struct {
|
||||
Q PackageQuery
|
||||
}
|
||||
|
||||
// FieldQuery is generic request against field
|
||||
type FieldQuery struct {
|
||||
Field string
|
||||
Relation int
|
||||
Value string
|
||||
}
|
||||
|
||||
// DependencyQuery is generic Debian-dependency like query
|
||||
type DependencyQuery struct {
|
||||
Dep deb.Dependency
|
||||
}
|
||||
|
||||
// Matches if any of L, R matches
|
||||
func (q *OrQuery) Matches(pkg *deb.Package) bool {
|
||||
return q.L.Matches(pkg) || q.R.Matches(pkg)
|
||||
}
|
||||
|
||||
// Matches if both of L, R matches
|
||||
func (q *AndQuery) Matches(pkg *deb.Package) bool {
|
||||
return q.L.Matches(pkg) && q.R.Matches(pkg)
|
||||
}
|
||||
|
||||
// Matches if not matches
|
||||
func (q *NotQuery) Matches(pkg *deb.Package) bool {
|
||||
return !q.Q.Matches(pkg)
|
||||
}
|
||||
|
||||
// Matches on generic field
|
||||
func (q *FieldQuery) Matches(pkg *deb.Package) bool {
|
||||
panic("not implemented yet")
|
||||
}
|
||||
|
||||
// Matches on dependency condition
|
||||
func (q *DependencyQuery) Matches(pkg *deb.Package) bool {
|
||||
return pkg.MatchesDependency(q.Dep)
|
||||
}
|
||||
Reference in New Issue
Block a user