initial import chains implementation

This commit is contained in:
Aaron Meihm 2015-08-03 13:45:11 -05:00
Родитель 36d040c3cb
Коммит f8914dce49
14 изменённых файлов: 174 добавлений и 1 удалений

19
src/scribe/chain.go Normal file
Просмотреть файл

@ -0,0 +1,19 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor:
// - Aaron Meihm ameihm@mozilla.com
package scribe
import (
"strings"
)
func hasChainVariables(arg string) bool {
if strings.Contains(arg, "${chain_root}") {
return true
}
return false
}

Просмотреть файл

@ -48,6 +48,11 @@ func (d *Document) GetTestIdentifiers() []string {
}
func (d *Document) prepareObjects() error {
// Mark any chain objects; these will be skipped during preparation
// as they are dependant on evaluation of the root object.
for i := range d.Objects {
d.Objects[i].markChain()
}
// Note that prepare() will return an error if something goes wrong
// but we don't propagate this back. Errors within object preparation
// are kept localized to the object, and are not considered fatal to
@ -55,6 +60,10 @@ func (d *Document) prepareObjects() error {
for i := range d.Objects {
d.Objects[i].prepare(d)
}
debugPrint("prepareObjects(): firing any import chains\n")
for i := range d.Objects {
d.Objects[i].fireChains(d)
}
return nil
}

Просмотреть файл

@ -13,6 +13,7 @@ import (
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
"regexp"
)
@ -23,6 +24,8 @@ type filecontent struct {
Expression string `json:"expression"`
Concat string `json:"concat"`
ImportChain []string `json:"import-chain"`
matches []contentMatch
}
@ -57,6 +60,46 @@ func (f *filecontent) validate() error {
return nil
}
func (f *filecontent) fireChains(d *Document) []evaluationCriteria {
if len(f.ImportChain) == 0 {
return nil
}
debugPrint("fireChains(): firing chains for filecontent object\n")
uids := make([]string, 0)
for _, x := range f.matches {
found := false
for _, y := range uids {
if x.path == y {
found = true
break
}
}
if found {
continue
}
uids = append(uids, x.path)
}
for _, x := range uids {
varlist := make([]variable, 0)
debugPrint("fireChains(): run for \"%v\"\n", x)
d, _ := path.Split(x)
newvar := variable{Key: "chain_root", Value: d}
varlist = append(varlist, newvar)
}
return nil
}
func (f *filecontent) mergeCriteria(c []evaluationCriteria) {
}
func (f *filecontent) isChain() bool {
if hasChainVariables(f.Path) {
return true
}
return false
}
func (f *filecontent) isModifier() bool {
return false
}

Просмотреть файл

@ -29,6 +29,17 @@ func (f *filename) isModifier() bool {
return false
}
func (f *filename) isChain() bool {
return false
}
func (f *filename) fireChains(d *Document) []evaluationCriteria {
return nil
}
func (f *filename) mergeCriteria(c []evaluationCriteria) {
}
func (f *filename) validate() error {
if len(f.Path) == 0 {
return fmt.Errorf("filename path must be set")

Просмотреть файл

@ -18,6 +18,7 @@ type object struct {
Package pkg `json:"package"`
Raw raw `json:"raw"`
isChain bool // True if object is part of an import chain.
prepared bool // True if object has been prepared.
err error // The last error condition encountered during preparation.
}
@ -25,8 +26,11 @@ type object struct {
type genericSource interface {
prepare() error
getCriteria() []evaluationCriteria
isChain() bool
expandVariables([]variable)
validate() error
mergeCriteria([]evaluationCriteria)
fireChains(*Document) []evaluationCriteria
}
func (o *object) validate(d *Document) error {
@ -44,6 +48,10 @@ func (o *object) validate(d *Document) error {
return nil
}
func (o *object) markChain() {
o.isChain = o.getSourceInterface().isChain()
}
func (o *object) getSourceInterface() genericSource {
if o.Package.Name != "" {
return &o.Package
@ -57,7 +65,16 @@ func (o *object) getSourceInterface() genericSource {
return nil
}
func (o *object) fireChains(d *Document) {
si := o.getSourceInterface()
si.mergeCriteria(si.fireChains(d))
}
func (o *object) prepare(d *Document) error {
if o.isChain {
debugPrint("prepare(): skipping chain object \"%v\"\n", o.Object)
return nil
}
if o.prepared {
return nil
}

Просмотреть файл

@ -25,6 +25,10 @@ func (p *pkg) isModifier() bool {
return false
}
func (p *pkg) isChain() bool {
return false
}
func (p *pkg) validate() error {
if len(p.Name) == 0 {
return fmt.Errorf("package must specify name")
@ -32,6 +36,13 @@ func (p *pkg) validate() error {
return nil
}
func (p *pkg) fireChains(d *Document) []evaluationCriteria {
return nil
}
func (p *pkg) mergeCriteria(c []evaluationCriteria) {
}
func (p *pkg) getCriteria() (ret []evaluationCriteria) {
for _, x := range p.pkgInfo {
n := evaluationCriteria{}

Просмотреть файл

@ -24,6 +24,17 @@ func (r *raw) isModifier() bool {
return false
}
func (r *raw) isChain() bool {
return false
}
func (r *raw) fireChains(d *Document) []evaluationCriteria {
return nil
}
func (r *raw) mergeCriteria(c []evaluationCriteria) {
}
func (r *raw) validate() error {
if len(r.Identifiers) == 0 {
return fmt.Errorf("at least one identifier must be present")

Просмотреть файл

@ -1,4 +1,4 @@
TESTDIRS = filecontent filename package concat raw evrtest
TESTDIRS = filecontent filename package concat raw import-chain evrtest
all:

Просмотреть файл

@ -0,0 +1 @@
var = (1, 5)

Просмотреть файл

@ -0,0 +1,13 @@
all:
runtests: test.json
ifndef SCRIBECMD
$(error SCRIBECMD is undefined, tests must be ran from the root of the repository)
endif
$(SCRIBECMD) -e -f test.json; \
test.json: test-template.json
cat test-template.json | sed 's,REPLACE_IN_MAKEFILE,$(shell pwd),' > test.json
clean:
rm -f test.json

Просмотреть файл

@ -0,0 +1 @@
var = (1, 5)

Просмотреть файл

@ -0,0 +1 @@
var = (1, 5)

Просмотреть файл

@ -0,0 +1 @@
minor = 8

Просмотреть файл

@ -0,0 +1,35 @@
{
"variables": [
{ "key": "root", "value": "REPLACE_IN_MAKEFILE" }
],
"objects": [
{
"object": "testfile0-combined",
"filecontent": {
"path": "${root}",
"file": "testfile0",
"expression": "var = \\((\\S+), (\\S+)\\)",
"concat": ".",
"import-chain": [ "testfile1-minor" ]
}
},
{
"object": "testfile1-minor",
"filecontent": {
"path": "${chain_root}",
"file": "testfile1",
"expression": "minor = (\\S+)"
}
}
],
"tests": [
{
"test": "testfile0-noop",
"expectedresult": true,
"object": "testfile0-combined"
}
]
}