-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
2,283 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/bin/bash | ||
set -e | ||
|
||
cd "$( dirname "${BASH_SOURCE[0]}" )" | ||
rm ./bin/* >/dev/null 2>&1 || true | ||
go build -o ./bin/plugins ./cmd/plugins | ||
go build -o ./bin/ . | ||
./bin/weave-cli -path ./templates/ -plugins ./bin/plugins -document "test-document" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package main | ||
|
||
import ( | ||
"weave-cli/plugins" | ||
"weave-cli/plugins/content" | ||
"weave-cli/plugins/content/table" | ||
"weave-cli/plugins/content/text" | ||
"weave-cli/plugins/data" | ||
"weave-cli/plugins/data/plugin_a" | ||
"weave-cli/plugins/data/plugin_b" | ||
|
||
"github.com/hashicorp/go-plugin" | ||
) | ||
|
||
func main() { | ||
plugin.Serve(&plugin.ServeConfig{ | ||
HandshakeConfig: plugins.Handshake, | ||
Plugins: plugin.PluginSet{ | ||
"data.plugin_a": &data.GoPlugin{Impl: &plugin_a.Impl{}}, | ||
"data.plugin_b": &data.GoPlugin{Impl: &plugin_b.Impl{}}, | ||
"content.table": &content.GoPlugin{Impl: &table.Impl{}}, | ||
"content.text": &content.GoPlugin{Impl: &text.Impl{}}, | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/hashicorp/hcl/v2" | ||
"github.com/hashicorp/hcl/v2/gohcl" | ||
"github.com/hashicorp/hcl/v2/hclsyntax" | ||
) | ||
|
||
func (d *Decoder) Decode() (diag hcl.Diagnostics) { | ||
for i := range d.root.ContentBlocks { | ||
diag = diag.Extend(d.DecodeBlock(&d.root.ContentBlocks[i])) | ||
} | ||
for i := range d.root.DataBlocks { | ||
diag = diag.Extend(d.DecodeBlock(&d.root.DataBlocks[i])) | ||
} | ||
for i := range d.root.Documents { | ||
diag = diag.Extend(d.DecodeDocumnet(&d.root.Documents[i])) | ||
} | ||
return | ||
} | ||
|
||
func (d *Decoder) DecodeDocumnet(doc *Document) (diag hcl.Diagnostics) { | ||
for i := range doc.ContentBlocks { | ||
diag = diag.Extend(d.DecodeBlock(&doc.ContentBlocks[i])) | ||
} | ||
for i := range doc.DataBlocks { | ||
diag = diag.Extend(d.DecodeBlock(&doc.DataBlocks[i])) | ||
} | ||
return | ||
} | ||
|
||
func (d *Decoder) DecodeBlock(block Block) (diag hcl.Diagnostics) { | ||
extra := block.NewBlockExtra() | ||
|
||
diag = gohcl.DecodeBody(block.GetUnparsed(), nil, extra) | ||
|
||
if diag.HasErrors() { | ||
return | ||
} | ||
|
||
// deferring errors in attrs, they do not prevent us from parsing | ||
deferredDiags := block.DecodeNestedBlocks(d, extra) | ||
defer func() { | ||
diag = deferredDiags.Extend(diag) | ||
}() | ||
|
||
leftover := extra.GetUnparsed() | ||
attrs, attrDiags := leftover.JustAttributes() | ||
if attrDiags.HasErrors() { | ||
// TODO: messy hcl bug workaround, in some cases might silently ignore user's error | ||
attrDiags = nil | ||
body := leftover.(*hclsyntax.Body) | ||
for _, b := range body.Blocks { | ||
switch b.Type { | ||
case "meta", "content": | ||
continue | ||
default: | ||
attrDiags = attrDiags.Append(&hcl.Diagnostic{ | ||
Severity: hcl.DiagError, | ||
Summary: fmt.Sprintf("Unexpected %q block", b.Type), | ||
Detail: "Blocks are not allowed here.", | ||
Subject: &b.TypeRange, | ||
}) | ||
} | ||
} | ||
} | ||
|
||
deferredDiags = deferredDiags.Extend(attrDiags) | ||
*block.GetAttrs() = attrs | ||
|
||
trav, refDiag := traversalForExpr(extra.GetRef()) | ||
if *block.GetType() != "ref" { | ||
if len(trav) != 0 || len(refDiag) != 0 { | ||
diag = diag.Append(&hcl.Diagnostic{ | ||
Severity: hcl.DiagWarning, | ||
Summary: "Non-empty ref attribute", | ||
Detail: fmt.Sprintf( | ||
"Non-empty ref attribute found in block of type '%s'. It will be ignored. Block must have type 'ref' in order to use references", | ||
*block.GetType(), | ||
), | ||
Subject: extra.GetRef().Range().Ptr(), | ||
Expression: extra.GetRef(), | ||
}) | ||
} | ||
// validate block type | ||
plugins := d.plugins.ByKind(block.GetBlockKind()) | ||
if _, found := plugins.plugins[*block.GetType()]; !found { | ||
return diag.Append(&hcl.Diagnostic{ | ||
Severity: hcl.DiagWarning, | ||
Summary: fmt.Sprintf("Unknown %s block type", block.GetBlockKind()), | ||
Detail: fmt.Sprintf( | ||
"Unknown content block type '%s', valid block types: %s. Referencing or evaluating this block would cause an error", | ||
*block.GetType(), | ||
plugins.Names(), | ||
), | ||
// TODO: storing type as string doensn't allow good error here. Switch to Expression? | ||
Subject: block.GetUnparsed().MissingItemRange().Ptr(), | ||
}) | ||
} | ||
*block.GetDecoded() = true | ||
return | ||
} | ||
// handling ref | ||
diag = diag.Extend(refDiag) | ||
if diag.HasErrors() { | ||
return | ||
} | ||
if len(trav) == 0 { | ||
missingRef := &hcl.Diagnostic{ | ||
Severity: hcl.DiagError, | ||
} | ||
if extra.GetRef().Range().Empty() { | ||
missingRef.Summary = "Missing ref" | ||
missingRef.Detail = fmt.Sprintf("Block '%s %s' is of type 'ref', but the ref field is missing", block.GetBlockKind(), block.GetName()) | ||
missingRef.Subject = block.GetUnparsed().MissingItemRange().Ptr() | ||
} else { | ||
missingRef.Summary = "Empty ref" | ||
missingRef.Detail = fmt.Sprintf("Block '%s %s' is of type 'ref', but the ref field is empty", block.GetBlockKind(), block.GetName()) | ||
missingRef.Subject = extra.GetRef().Range().Ptr() | ||
missingRef.Expression = extra.GetRef() | ||
} | ||
return diag.Append(missingRef) | ||
} | ||
|
||
refTgt, travDiag := d.Traverse(trav) | ||
// annotate traverse diags | ||
for _, d := range travDiag { | ||
if d.Subject == nil { | ||
d.Subject = extra.GetRef().Range().Ptr() | ||
} else if d.Context == nil { | ||
d.Context = extra.GetRef().Range().Ptr() | ||
} | ||
if d.Expression == nil { | ||
d.Expression = extra.GetRef() | ||
} | ||
} | ||
diag = diag.Extend(travDiag) | ||
if diag.HasErrors() { | ||
return | ||
} | ||
diag = diag.Extend( | ||
block.UpdateFromRef(refTgt, extra.GetRef()), | ||
) | ||
if diag.HasErrors() { | ||
return | ||
} | ||
|
||
*block.GetDecoded() = true | ||
return | ||
} |
Oops, something went wrong.