Commit Graph

1058 Commits

Author SHA1 Message Date
Martin Atkins
30da06ec3f hclpack: Implement UnwrapExpression for our expressions
This allows the static analysis functions in the main HCL package to dig
through our wrapper to get the native expression object needed for most
analyses.

For example, this allows an expression with a native expression source
type whose source contains valid tuple constructor syntax to be used with
hcl.ExprList.
2018-11-11 08:34:44 -08:00
Martin Atkins
06d5709118 hclpack: Support literal JSON as an additional expression syntax
hclpack can potentially be used as an intermediary to more easily bring
non-HCL input into the HCL API, and so allowing a literal value in JSON
format as an expression type means that such a transcoder doesn't need to
worry about formatting values it encounters using HCL syntax and can
instead just encode directly to JSON, but at the expense of then not being
able to use the full expression/template syntax.
2018-11-11 08:26:37 -08:00
Martin Atkins
309e278914 hclpack: Implement JSON marshaling (but not unmarshaling, yet) 2018-11-11 03:25:19 +00:00
Martin Atkins
ed7453e277 hclpack: PackNativeFile to get a packed version of a native syntax file
This is a straightforward way to get a hclpack.Body in the common case
where the input is already native syntax source code. Since the native
syntax is unambiguous about structure, the whole structure can be packed
in a single pass with no further information.
2018-11-11 00:40:31 +00:00
Martin Atkins
227ba9e86b hclpack: Start of definitions for JSON marshaling/unmarshaling
This is not yet complete.
2018-11-10 10:29:32 -08:00
Martin Atkins
5e07d8e1f9 hclpack: New package for wire representations of hcl bodies
In most applications it's possible to fully evaluate configuration at the
beginning and work only with resolved values after that, but in some
unusual cases it's necessary to split parsing and decoding between two
separate processes connected by a pipe or network connection.

hclpack is intended to provide compact wire formats for sending bodies
over the network such that they can be decoded and evaluated and get the
same results. This is not something that can happen fully automatically
because a hcl.Body is an abstract node rather than a physical construct,
and so access to the original source code is required to construct such
a representation, and to interpret any source ranges that emerged from
the final evaluation.
2018-11-10 09:36:26 -08:00
Martin Atkins
0a1bd51123 hclsyntax: "Arguments" instead of "attributes" in diagnostics
To reduce confusion with object attributes, we switched a while back to
using the term "argument" to refer to the key/value pairs in a body, but
these diagnostic messages were not updated.
2018-11-10 08:40:13 -08:00
Paul Tyng
9aa28a1a0b
Merge pull request #53 from hashicorp/pt/edges_from_hcl1
Add additional comment test cases
2018-11-06 18:06:04 -05:00
Martin Atkins
917fbe66e7 hclwrite: Expression.RenameVariablePrefix
This function serves the use-case of surgically renaming references to
variables in an existing file without disturbing other tokens.
2018-11-04 04:17:03 +00:00
Martin Atkins
0c14f1e3f6 hclwrite: Implement Body.SetAttributeTraversal 2018-11-04 02:09:35 +00:00
Martin Atkins
1b9738a196 gohcl: EncodeIntoBody and EncodeAsBlock functions
These are wrappers around the lower-level hclwrite package that are able
to reverse a subset of the behavior of the Decode functions to populate
an hclwrite DOM.

They are not fully symmetrical with DecodeBody because that function can
leave certain parts of the configuration in its opaque form for later
decoding, and these encode functions don't have enough information to
repack that abstract/opaque form into new source code.

In practice we expect that callers using complex techniques like partial
decoding will also use more complex techniques with the hclwrite API
directly, since they will need to coordinate partial _encoding_ of data
that has been portioned off into separate structures, which gohcl is not
equipped to do itself.
2018-11-04 01:16:51 +00:00
Martin Atkins
8cca983bca hclwrite: Support for creating new blocks and clearing bodies 2018-11-04 01:13:13 +00:00
Martin Atkins
361186aad0 hclwrite: Recast TestRoundupCreate as an example
Since the goal of this is to be somewhat realistic of what a caller might
do, we might as well also include it in the godoc examples.
2018-11-03 21:20:10 +00:00
Martin Atkins
17ff23300f hclwrite: NewEmptyFile function
This completes the minimal functionality for creating a new file from
scratch, rather than modifying an existing one. This is illustrated by
a new test TestRoundupCreate that uses the API to create a new file in a
similar way to how a calling application might.
2018-11-03 20:45:25 +00:00
Martin Atkins
a44a287724 hclwrite: Make File and Tokens implement io.WriterTo
There isn't any strong reason for this -- they don't implement io.Reader
and so can't be used in places where a Reader+WriterTo is expected, like
io.Copy -- but go lint thinks that anything called WriteTo with an
io.Writer argument is an attempt to implement WriterTo and so this just
shuts up the linter.
2018-11-03 20:19:56 +00:00
Martin Atkins
fd915f557d hclwrite: Rename Body.AppendBlock to AppendNewBlock
Since this function implicitly creates a new body, this name is more
appropriate and leaves the name "AppendBlock" open for a later method to
append an _existing_ block, such as when moving a block from one file
to another.
2018-11-03 19:54:56 +00:00
Martin Atkins
379d277e2b hcl/hclsyntax: Fix invalid block parsing test
Invalid blocks now have empty bodies rather than nil bodies, to avoid the
need to callers to specially handle nils here when they are doing analysis
of a partially-invalid file.
2018-11-03 19:49:14 +00:00
Martin Atkins
57c6d75eb8 hclwrite: Body.AppendBlock
This method allows a caller to generate a nested block within a body.
Since a nested block has its own content body, this now allows for deep
structures to be generated.
2018-11-03 09:21:43 -07:00
Martin Atkins
98352801f3 go mod tidy 2018-11-03 09:21:43 -07:00
Martin Atkins
04d1413613 hclwrite: Split Attribute and Block into their own source files
These will grow to have significant logic of their own, so hiding them at
the end of the Body file makes things harder to read.
2018-11-03 09:21:43 -07:00
Paul Tyng
9928b942bb
Add missing module 2018-10-31 12:26:27 -04:00
Paul Tyng
e8e85f5edd
Add additional comment test cases
Some of these fail in HCL1 fmt
2018-10-31 12:25:12 -04:00
Martin Atkins
3e4b7e0eb2 hclsyntax: If nested block doesn't parse, produce empty body
Our usual rule for parse errors is to return a valid-but-incomplete object
along with error diagnostics. This was violating that rule by returning
a nil child body, which callers do not expect to deal with.

Instead, we'll return an *empty* body, so that callers who use the partial
result for careful analyses can still process the block header, without
needing to guard against the body being nil.
2018-10-01 14:06:26 -07:00
Martin Atkins
cce5ae6cc5 hclsyntax: Remove hclsyntax.Transform
This was always a bit of an outlier here because the rest of the API is
intentionally designed to encourage treating AST nodes as immutable.

Although the transforming walkers were functionally correct, they were
causing false positives in the race detector if two walks run concurrently.

We may later introduce something similar to this in the hclwrite package,
where the AST nodes are explicitly mutable.
2018-09-26 07:38:54 -07:00
Radek Simko
3f1c5474d4 hclsyntax: Add test for idx'd func outputs 2018-09-25 10:55:40 -07:00
Martin Atkins
983c83c156 hclsyntax: Some tests for Walk
These tests are not yet comprehensive, but at least cover some normal
cases and some cases that have some trickier behavior.
2018-09-25 08:25:42 -07:00
Martin Atkins
e1e97716f5 hclsyntax: RelativeTraversalExpr walkChildNodes implementation
Unlike ScopeTraversalExpr, this node type _does_ have an expression as its
source and so it must include that expression in an AST walk.
2018-09-25 08:25:42 -07:00
Martin Atkins
2933fec4da hclsyntax: Walk must call Walker.Exit before returning 2018-09-25 08:25:42 -07:00
Radek Simko
ffb8e97eb7
Merge pull request #49 from hashicorp/t-hclsyntax-fix
hclsyntax: Add test for 'func()[idx]' syntax
2018-09-21 18:02:03 +01:00
Radek Simko
ef3dcd77da
hclsyntax: Add test for parsing of idx'd function calls 2018-09-21 16:13:21 +01:00
Radek Simko
def7e926c9
hclsyntax: Fix incorrect positions in tests 2018-09-21 12:04:32 +01:00
Phillip T. George
65a6292f01 Allow strings "true", "false", "1" and "0" to be used where booleans are expected
There is precedent for allowing strings containing digits where numbers are expected,
and so this extends that to also allow for boolean values to be given as strings.

This applies only to callers going through the decoder API. Direct access via the AST
will reflect exactly what was given in the input configuration.
2018-09-06 11:38:39 -07:00
Martin Atkins
864f97c8ab guide: A section on input file naming conventions 2018-09-05 08:26:29 -07:00
Martin Atkins
dc326dd882 guide: Update the main title to "HCL Config Language Toolkit"
"HCL Configuration Language" will feel redundant to anyone who thinks
they know what "HCL" is supposed to stand for, even though our docs don't
actually expand the abbreviation at all. This new version is also still
redundant with that interpretation, but at least it emphasizes that it's
a toolkit for creating configuration languages rather than a configuration
language in its own right.
2018-09-05 08:16:17 -07:00
Martin Atkins
e78fa0ded2 guide: Guide-type documentation for HCL 2018-09-05 08:10:27 -07:00
Martin Atkins
57c9a676d7 guide: The "Configuration Language Design" section 2018-09-05 08:08:11 -07:00
Martin Atkins
280771fe8a guide: Design Patterns for Complex Systems section 2018-08-31 22:01:43 -07:00
Martin Atkins
495dfc9487 guide: Low-level API section 2018-08-31 07:40:30 -07:00
Martin Atkins
d2e7762e9a guide: Expression Evaluation page content 2018-08-28 08:45:24 -07:00
Martin Atkins
50cdb5d614 guide: Stub out some more of the overall guide outline 2018-08-26 10:28:03 -07:00
Martin Atkins
b737ad87a3 guide: A section on dynamic decoding using hcldec 2018-08-26 10:03:28 -07:00
Martin Atkins
8cb6e5b959 Prepare to be a Go module 2018-08-25 17:51:36 -07:00
Martin Atkins
3b190b826e guide: Disable the autoapi extension
This extension isn't working well for Go, so we're not using it for now.
2018-08-25 17:06:04 -07:00
Martin Atkins
33120477c7 guide: When running in Read The Docs, get version from its environment
Git isn't available in the Read The Docs build, but we don't actually need
it there anyway because we are told the version number that Read The Docs
thinks it is building.
2018-08-25 17:01:35 -07:00
Martin Atkins
c6f6feed76 guide: Start of HCL usage guide
This is guide-style documentation to introduce the different parts of HCL,
as a complement to the reference documentation provided in godoc.
2018-08-25 16:36:05 -07:00
Martin Atkins
d754d5a269 hclwrite: Adjust token spacing automatically when writing
Although our underlying parse tree retains all of the token content, it
doesn't necessarily retain all of the spacing information under editing,
and so formatting on save ensures that we'll produce a canonical result
even if some edits have been applied that have changed the expected
alignment of objects, etc.
2018-08-25 12:15:40 -07:00
Martin Atkins
ed8144cda1 hcldec: BlockTupleSpec and BlockObjectSpec
When nested attributes are of type cty.DynamicPseudoType, a block spec
that is backed by a cty collection is annoying to use because it requires
all of the blocks to have homogenous types for such attributes.

These new specs are similar to BlockListSpec and BlockMapSpec
respectively, but permit each nested block result to have its own distinct
type.

In return for this flexibility, we lose the ability to predict the exact
type of the result: these specs must just indicate their type as being
cty.DynamicPseudoType themselves, since we need to know how many blocks
there are and what types are inside them before we can know our final
result type.
2018-08-22 12:31:30 -07:00
Martin Atkins
b82170e941 hcldec: Handle or forbid cty.DynamicPseudoType attributes in nested blocks
Our BlockList, BlockSet, and BlockMap specs all produce cty collection
values, which require all elements to have a homogeneous type. If the
nested spec contained an attribute of type cty.DynamicPseudoType, that
would create the risk of each element having a different type, which would
previously have caused decoding to panic.

Now we either handle this during decode (BlockList, BlockSet) or forbid
it outright (BlockMap) to prevent that crash. BlockMap could _potentially_
also handle this during decode, but that would require a more significant
reorganization of its implementation than I want to take on right now,
and decoding dynamically-typed values inside collections is an edge case
anyway.
2018-08-22 11:52:40 -07:00
Martin Atkins
d6049c2a04 Get ready to be a Go module
However, since this repository is only a temporary home for this module,
the go.mod file carries a warning to that effect. It will move to its more
permanent home as it transitions from experimental to released.
2018-08-17 19:07:38 -07:00
Martin Atkins
c79a9bd509 Beginnings of automated test suite for spec compliance.
The test cases are far from complete, but the mechanism is in place.
2018-08-12 18:23:14 -07:00