From b6b3d7da9f756856218429a23a73ff091425bfa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ximo=20Cuadros?= Date: Sun, 29 Mar 2020 21:19:52 +0200 Subject: [PATCH] documentation: some examples, links review and gh-actions --- _documentation/_index.md | 4 +- _documentation/github-action.md | 69 ++++++++++- _documentation/starlark/_index.md | 6 +- _documentation/starlark/built-in-methods.md | 8 +- _documentation/starlark/data-types.md | 115 +++++++++--------- _documentation/starlark/expressions.md | 6 +- _documentation/starlark/lexical-elements.md | 2 +- .../starlark/name-binding-and-variables.md | 2 +- _documentation/starlark/value-concepts.md | 4 +- starlark/types/doc.go | 6 +- starlark/types/evaluate.go | 3 + starlark/types/examples_test.go | 4 + starlark/types/provider_test.go | 4 +- .../types/testdata/examples/evaluable.star | 3 + .../types/testdata/examples/evaluate.star | 9 ++ 15 files changed, 167 insertions(+), 78 deletions(-) create mode 100644 starlark/types/testdata/examples/evaluable.star create mode 100644 starlark/types/testdata/examples/evaluate.star diff --git a/_documentation/_index.md b/_documentation/_index.md index c19bd89..301075a 100644 --- a/_documentation/_index.md +++ b/_documentation/_index.md @@ -5,7 +5,7 @@ weight: 1 ## AsCode - Terraform Alternative Syntax -**AsCode** is a tool to define infrastructure as code using the [Starlark](https://github.com/google/starlark-go/blob/master/doc/spec.md) language on top of Ter[Terraform](https://github.com/hashicorp/terraform)raform. It allows to describe your infrastructure using an expressive language in Terraform without writing a single line of HCL, meanwhile, you have the complete ecosystem of [providers](https://www.terraform.io/docs/providers/index.html) +**AsCode** is a tool to define infrastructure as code using the [Starlark](https://github.com/google/starlark-go/blob/master/doc/spec.md) language on top of [Terraform](https://github.com/hashicorp/terraform). It allows to describe your infrastructure using an expressive language in Terraform without writing a single line of HCL, meanwhile, you have the complete ecosystem of [providers](https://www.terraform.io/docs/providers/index.html) ### Why? @@ -13,4 +13,4 @@ Terraform is a great tool, with support for almost everything you can imagine, m ### What is Starlark? -> Starlark is a dialect of Python intended for use as a configuration language. A Starlark interpreter is typically embedded within a larger application, and this application may define additional domain-specific functions and data types beyond those provided by the core language. For example, Starlark is embedded within (and was originally developed for) the Bazel build tool, and Bazel's build language is based on Starlark. \ No newline at end of file +Starlark is a dialect of Python intended for use as a configuration language. A Starlark interpreter is typically embedded within a larger application, and this application may define additional domain-specific functions and data types beyond those provided by the core language. For example, Starlark is embedded within (and was originally developed for) the Bazel build tool, and Bazel's build language is based on Starlark. \ No newline at end of file diff --git a/_documentation/github-action.md b/_documentation/github-action.md index 2db0a85..34c3cda 100644 --- a/_documentation/github-action.md +++ b/_documentation/github-action.md @@ -3,4 +3,71 @@ title: 'GitHub Action' weight: 40 --- -TODO \ No newline at end of file +AsCode Github Action allows to execute AsCode `run` command in response to a GitHub event such as updating a pull request or pushing a new commit on a specific branch. + +This used in combination with the [Terraform GitHub Actions](https://www.terraform.io/docs/github-actions/getting-started.html) allows to execute the different terraform commands `init`, `plan` and `apply` inside of a [GitHub Workflow](https://help.github.com/en/actions/configuring-and-managing-workflows). + +## Parameters + +| Parameter | **Mandatory**/**Optional** | Description | +| --------- | -------- | ----------- | +| file | **Mandatory** | Starlark file to execute. Default value: `main.star` | +| hcl | **Mandatory** | HCL output file. Default value: `generated.tf` | + +## Recommended Workflow + + +```yaml +name: 'Terraform & AsCode' +on: + push: + branches: + - master + pull_request: + +jobs: + terraform: + name: 'Deploy' + runs-on: ubuntu-latest + env: + TF_VERSION: latest + TF_WORKING_DIR: . + steps: + - name: 'Checkout' + uses: actions/checkout@master + + - name: 'AsCode Run' + uses: mcuadros/ascode@gh-action + + - name: 'Terraform Init' + uses: hashicorp/terraform-github-actions@master + with: + tf_actions_version: ${{ env.TF_VERSION }} + tf_actions_subcommand: 'init' + tf_actions_working_dir: ${{ env.TF_WORKING_DIR }} + tf_actions_comment: true + + - name: 'Terraform Validate' + uses: hashicorp/terraform-github-actions@master + with: + tf_actions_version: ${{ env.TF_VERSION }} + tf_actions_subcommand: 'validate' + tf_actions_working_dir: ${{ env.TF_WORKING_DIR }} + tf_actions_comment: true + + - name: 'Terraform Plan' + uses: hashicorp/terraform-github-actions@master + with: + tf_actions_version: ${{ env.TF_VERSION }} + tf_actions_subcommand: 'plan' + tf_actions_working_dir: ${{ env.TF_WORKING_DIR }} + tf_actions_comment: true + + - name: 'Terraform Apply' + uses: hashicorp/terraform-github-actions@master + if: github.event_name == 'push' + with: + tf_actions_version: ${{ env.TF_VERSION }} + tf_actions_subcommand: 'apply' + tf_actions_working_dir: ${{ env.TF_WORKING_DIR }} +``` \ No newline at end of file diff --git a/_documentation/starlark/_index.md b/_documentation/starlark/_index.md index 3907f81..d1fc143 100644 --- a/_documentation/starlark/_index.md +++ b/_documentation/starlark/_index.md @@ -9,15 +9,15 @@ application, and this application may define additional domain-specific functions and data types beyond those provided by the core language. For example, Starlark is embedded within (and was originally developed for) the [Bazel build tool](https://bazel.build), -and [Bazel's build language](https://docs.bazel.build/versions/master/starlark/language.html) is based on Starlark. +and [Bazel's build language](https://docs.bazel.build/versions/2.0.0/skylark/language.html) is based on Starlark. This document describes the Go implementation of Starlark at go.starlark.net/starlark. The language it defines is similar but not identical to -[the Java-based implementation](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/starlark/Starlark.java) +[the Java-based implementation](https://github.com/bazelbuild/starlark) used by Bazel. We identify places where their behaviors differ, and an -[appendix](#dialect-differences) provides a summary of those +[appendix](/docs/starlark/dialect-differences/) provides a summary of those differences. We plan to converge both implementations on a single specification. diff --git a/_documentation/starlark/built-in-methods.md b/_documentation/starlark/built-in-methods.md index becb297..03f4930 100644 --- a/_documentation/starlark/built-in-methods.md +++ b/_documentation/starlark/built-in-methods.md @@ -7,7 +7,7 @@ toc: true ## Overview This section lists the methods of built-in types. Methods are selected -using [dot expressions](#dot-expressions). +using [dot expressions](/docs/starlark/expressions/#dot-expressions). For example, strings have a `count` method that counts occurrences of a substring; `"banana".count("a")` yields `3`. @@ -193,7 +193,7 @@ The optional `start` and `end` parameters restrict the portion of list L that is inspected. If provided and not `None`, they must be list indices of type `int`. If an index is negative, `len(L)` is effectively added to it, then if the index is outside the range `[0:len(L)]`, the -nearest value within that range is used; see [Indexing](#indexing). +nearest value within that range is used; see [Indexing](/docs/starlark/value-concepts/#indexing). `index` fails if `x` is not found in L, or if `start` or `end` is not a valid index (`int` or `None`). @@ -328,7 +328,7 @@ See also: `string·codepoints`. `S.count(sub[, start[, end]])` returns the number of occcurences of `sub` within the string S, or, if the optional substring indices `start` and `end` are provided, within the designated substring of S. -They are interpreted according to Starlark's [indexing conventions](#indexing). +They are interpreted according to Starlark's [indexing conventions](/docs/starlark/value-concepts/#indexing). ```python "hello, world!".count("o") # 2 @@ -359,7 +359,7 @@ occurrence of the substring `sub` within S. If either or both of `start` or `end` are specified, they specify a subrange of S to which the search should be restricted. -They are interpreted according to Starlark's [indexing conventions](#indexing). +They are interpreted according to Starlark's [indexing conventions](/docs/starlark/value-concepts/#indexing). If no occurrence is found, `found` returns -1. diff --git a/_documentation/starlark/data-types.md b/_documentation/starlark/data-types.md index ee62b84..16ea054 100644 --- a/_documentation/starlark/data-types.md +++ b/_documentation/starlark/data-types.md @@ -39,7 +39,7 @@ expression `str(x)`, or to a Boolean truth value using the expression `bool(x)`. Other operations apply only to certain types. For example, the indexing operation `a[i]` works only with strings, lists, and tuples, and any application-defined types that are _indexable_. -The [_value concepts_](#value-concepts) section explains the groupings of +The [_value concepts_](/docs/starlark/value-concepts/) section explains the groupings of types by the operators they support. @@ -48,14 +48,14 @@ types by the operators they support. `None` is a distinguished value used to indicate the absence of any other value. For example, the result of a call to a function that contains no return statement is `None`. -`None` is equal only to itself. Its [type](#type) is `"NoneType"`. +`None` is equal only to itself. Its [type](/docs/starlark/built-in-constants-and-functions/#type) is `"NoneType"`. The truth value of `None` is `False`. ## Booleans There are two Boolean values, `True` and `False`, representing the -truth or falsehood of a predicate. The [type](#type) of a Boolean is `"bool"`. +truth or falsehood of a predicate. The [type](/docs/starlark/built-in-constants-and-functions/#type) of a Boolean is `"bool"`. Boolean values are typically used as conditions in `if`-statements, although any Starlark value used as a condition is implicitly @@ -79,7 +79,7 @@ else: ## Integers -The Starlark integer type represents integers. Its [type](#type) is `"int"`. +The Starlark integer type represents integers. Its [type](/docs/starlark/built-in-constants-and-functions/#type) is `"int"`. Integers may be positive or negative, and arbitrarily large. Integer arithmetic is exact. @@ -129,7 +129,7 @@ The Java implementation currently supports only signed 32-bit integers. ## Floating-point numbers The Starlark floating-point data type represents an IEEE 754 -double-precision floating-point number. Its [type](#type) is `"float"`. +double-precision floating-point number. Its [type](/docs/starlark/built-in-constants-and-functions/#type) is `"float"`. Arithmetic on floats using the `+`, `-`, `*`, `/`, `//`, and `%` operators follows the IEE 754 standard. @@ -183,7 +183,7 @@ The Java implementation does not yet support floating-point numbers. ## Strings A string represents an immutable sequence of bytes. -The [type](#type) of a string is `"string"`. +The [type](/docs/starlark/built-in-constants-and-functions/#type) of a string is `"string"`. Strings can represent arbitrary binary data, including zero bytes, but most strings contain text, encoded by convention using UTF-8. @@ -217,39 +217,39 @@ non-empty. Strings have several built-in methods: -* [`capitalize`](#string·capitalize) -* [`codepoint_ords`](#string·codepoint_ords) -* [`codepoints`](#string·codepoints) -* [`count`](#string·count) -* [`elem_ords`](#string·elem_ords) -* [`elems`](#string·elems) -* [`endswith`](#string·endswith) -* [`find`](#string·find) -* [`format`](#string·format) -* [`index`](#string·index) -* [`isalnum`](#string·isalnum) -* [`isalpha`](#string·isalpha) -* [`isdigit`](#string·isdigit) -* [`islower`](#string·islower) -* [`isspace`](#string·isspace) -* [`istitle`](#string·istitle) -* [`isupper`](#string·isupper) -* [`join`](#string·join) -* [`lower`](#string·lower) -* [`lstrip`](#string·lstrip) -* [`partition`](#string·partition) -* [`replace`](#string·replace) -* [`rfind`](#string·rfind) -* [`rindex`](#string·rindex) -* [`rpartition`](#string·rpartition) -* [`rsplit`](#string·rsplit) -* [`rstrip`](#string·rstrip) -* [`split`](#string·split) -* [`splitlines`](#string·splitlines) -* [`startswith`](#string·startswith) -* [`strip`](#string·strip) -* [`title`](#string·title) -* [`upper`](#string·upper) +* [`capitalize`](/docs/starlark/built-in-methods/#stringcapitalize) +* [`codepoint_ords`](/docs/starlark/built-in-methods/#stringcodepoint_ords) +* [`codepoints`](/docs/starlark/built-in-methods/#stringcodepoints) +* [`count`](/docs/starlark/built-in-methods/#stringcount) +* [`elem_ords`](/docs/starlark/built-in-methods/#stringelem_ords) +* [`elems`](/docs/starlark/built-in-methods/#stringelems) +* [`endswith`](/docs/starlark/built-in-methods/#stringendswith) +* [`find`](/docs/starlark/built-in-methods/#stringfind) +* [`format`](/docs/starlark/built-in-methods/#stringformat) +* [`index`](/docs/starlark/built-in-methods/#stringindex) +* [`isalnum`](/docs/starlark/built-in-methods/#stringisalnum) +* [`isalpha`](/docs/starlark/built-in-methods/#stringisalpha) +* [`isdigit`](/docs/starlark/built-in-methods/#stringisdigit) +* [`islower`](/docs/starlark/built-in-methods/#stringislower) +* [`isspace`](/docs/starlark/built-in-methods/#stringisspace) +* [`istitle`](/docs/starlark/built-in-methods/#stringistitle) +* [`isupper`](/docs/starlark/built-in-methods/#stringisupper) +* [`join`](/docs/starlark/built-in-methods/#stringjoin) +* [`lower`](/docs/starlark/built-in-methods/#stringlower) +* [`lstrip`](/docs/starlark/built-in-methods/#stringlstrip) +* [`partition`](/docs/starlark/built-in-methods/#stringpartition) +* [`replace`](/docs/starlark/built-in-methods/#stringreplace) +* [`rfind`](/docs/starlark/built-in-methods/#stringrfind) +* [`rindex`](/docs/starlark/built-in-methods/#stringrindex) +* [`rpartition`](/docs/starlark/built-in-methods/#stringrpartition) +* [`rsplit`](/docs/starlark/built-in-methods/#stringrsplit) +* [`rstrip`](/docs/starlark/built-in-methods/#stringrstrip) +* [`split`](/docs/starlark/built-in-methods/#stringsplit) +* [`splitlines`](/docs/starlark/built-in-methods/#stringsplitlines) +* [`startswith`](/docs/starlark/built-in-methods/#stringstartswith) +* [`strip`](/docs/starlark/built-in-methods/#stringstrip) +* [`title`](/docs/starlark/built-in-methods/#stringtitle) +* [`upper`](/docs/starlark/built-in-methods/#stringupper) Implementation note: The type of a string element varies across implementations. @@ -316,13 +316,13 @@ result of some expression applied to each element of another sequence. A list value has these methods: -* [`append`](#list·append) -* [`clear`](#list·clear) -* [`extend`](#list·extend) -* [`index`](#list·index) -* [`insert`](#list·insert) -* [`pop`](#list·pop) -* [`remove`](#list·remove) +* [`append`](/docs/starlark/built-in-methods/#listappend) +* [`clear`](/docs/starlark/built-in-methods/#listclear) +* [`extend`](/docs/starlark/built-in-methods/#listextend) +* [`index`](/docs/starlark/built-in-methods/#listindex) +* [`insert`](/docs/starlark/built-in-methods/#listinsert) +* [`pop`](/docs/starlark/built-in-methods/#listpop) +* [`remove`](/docs/starlark/built-in-methods/#listremove) ## Tuples @@ -470,15 +470,15 @@ two dictionaries with `<`. A dictionary value has these methods: -* [`clear`](#dict·clear) -* [`get`](#dict·get) -* [`items`](#dict·items) -* [`keys`](#dict·keys) -* [`pop`](#dict·pop) -* [`popitem`](#dict·popitem) -* [`setdefault`](#dict·setdefault) -* [`update`](#dict·update) -* [`values`](#dict·values) +* [`clear`](/docs/starlark/built-in-methods/#dictclear) +* [`get`](/docs/starlark/built-in-methods/#dictget) +* [`items`](/docs/starlark/built-in-methods/#dictitems) +* [`keys`](/docs/starlark/built-in-methods/#dictkeys) +* [`pop`](/docs/starlark/built-in-methods/#dictpop) +* [`popitem`](/docs/starlark/built-in-methods/#dictpopitem) +* [`setdefault`](/docs/starlark/built-in-methods/#dictsetdefault) +* [`update`](/docs/starlark/built-in-methods/#dictupdate) +* [`values`](/docs/starlark/built-in-methods/#dictvalues) ## Sets @@ -729,7 +729,7 @@ Turing complete unless the `-recursion` flag is specified. A built-in function is a function or method implemented in Go by the interpreter or the application into which the interpreter is embedded. -The [type](#type) of a built-in function is `"builtin_function_or_method"`. +The [type](/docs/starlark/built-in-constants-and-functions/#type) of a built-in function is `"builtin_function_or_method"`. Implementation note: The Java implementation of `type(x)` returns `"function"` for all functions, whether built in or defined in Starlark, @@ -737,8 +737,7 @@ even though applications distinguish these two types. A built-in function value used in a Boolean context is always considered true. -Many built-in functions are predeclared in the environment -(see [Name Resolution](#name-resolution)). +Many built-in functions are predeclared in the environment. Some built-in functions such as `len` are _universal_, that is, available to all Starlark programs. The host application may predeclare additional built-in functions diff --git a/_documentation/starlark/expressions.md b/_documentation/starlark/expressions.md index b21c06a..2d78b54 100644 --- a/_documentation/starlark/expressions.md +++ b/_documentation/starlark/expressions.md @@ -138,7 +138,7 @@ Examples: The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. -Only [hashable](#hashing) values may be used as the keys of a dictionary. +Only [hashable](/docs/starlark/value-concepts/#hashing) values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, sets, and lists; a tuple is hashable only if its elements are hashable. @@ -680,11 +680,11 @@ A method call such as `filename.endswith(".star")` is the composition of two operations, `m = filename.endswith` and `m(".star")`. The first, a dot operation, yields a _bound method_, a function value that pairs a receiver value (the `filename` string) with a choice of -method ([string·endswith](#string·endswith)). +method ([string·endswith](/docs/starlark/built-in-methods/#stringendswith)). Only built-in or application-defined types may have methods. -See [Functions](#functions) for an explanation of function parameter passing. +See [Functions](/docs/starlark/data-types/#functions) for an explanation of function parameter passing. ## Dot expressions diff --git a/_documentation/starlark/lexical-elements.md b/_documentation/starlark/lexical-elements.md index 2a13e24..8f88ab9 100644 --- a/_documentation/starlark/lexical-elements.md +++ b/_documentation/starlark/lexical-elements.md @@ -6,7 +6,7 @@ weight: 2 A Starlark program consists of one or more modules. Each module is defined by a single UTF-8-encoded text file. -A complete grammar of Starlark can be found in [grammar.txt](../syntax/grammar.txt). +A complete grammar of Starlark can be found in [grammar.txt](https://github.com/google/starlark-go/blob/master/syntax/grammar.txt). That grammar is presented piecemeal throughout this document in boxes such as this one, which explains the notation: diff --git a/_documentation/starlark/name-binding-and-variables.md b/_documentation/starlark/name-binding-and-variables.md index 4d4ac9b..19fb66c 100644 --- a/_documentation/starlark/name-binding-and-variables.md +++ b/_documentation/starlark/name-binding-and-variables.md @@ -184,6 +184,6 @@ omission can be worked around by using a list of a single element.) A name appearing after a dot, such as `split` in `get_filename().split('/')`, is not resolved statically. -The [dot expression](#dot-expressions) `.split` is a dynamic operation +The [dot expression](/docs/starlark/expressions/#dot-expressions) `.split` is a dynamic operation on the value returned by `get_filename()`. diff --git a/_documentation/starlark/value-concepts.md b/_documentation/starlark/value-concepts.md index 6ae9153..747af7e 100644 --- a/_documentation/starlark/value-concepts.md +++ b/_documentation/starlark/value-concepts.md @@ -6,7 +6,7 @@ toc: true ## Overview -Starlark has eleven core [data types](#data-types). An application +Starlark has eleven core [data types](/docs/starlark/data-types/). An application that embeds the Starlark intepreter may define additional types that behave like Starlark values. All values, whether core or application-defined, implement a few basic behaviors: @@ -112,7 +112,7 @@ Thus `("localhost", 80)` is hashable but `([127, 0, 0, 1], 80)` is not. Values of the types `function` and `builtin_function_or_method` are also hashable. Although functions are not necessarily immutable, as they may be closures that refer to mutable variables, instances of these types -are compared by reference identity (see [Comparisons](#comparisons)), +are compared by reference identity (see [Comparisons](/docs/starlark/expressions/#comparisons)), so their hash values are derived from their identity. diff --git a/starlark/types/doc.go b/starlark/types/doc.go index e0fa3cd..952bde0 100644 --- a/starlark/types/doc.go +++ b/starlark/types/doc.go @@ -1,6 +1,8 @@ package types // outline: types +// builtin package represents the predefined, Terraform domain-specific, +// functions and types in the scope of any thread of AsCode. This means +// that is not required to use the `load` statement, and any of the function +// can be called without any prefix. // path: built-in - - diff --git a/starlark/types/evaluate.go b/starlark/types/evaluate.go index a5e1750..86c1a18 100644 --- a/starlark/types/evaluate.go +++ b/starlark/types/evaluate.go @@ -15,6 +15,9 @@ import ( // evaluate(filename, predeclared=None) dict // Evaluates a Starlark file and returns its global context. Kwargs may // be used to set predeclared. +// examples: +// evaluable.star +// evaluate.star // params: // filename string // Name of the file to execute. diff --git a/starlark/types/examples_test.go b/starlark/types/examples_test.go index fe21c5c..62502a4 100644 --- a/starlark/types/examples_test.go +++ b/starlark/types/examples_test.go @@ -25,6 +25,10 @@ func TestExamples(t *testing.T) { assert.NoError(t, err) for _, test := range tests { + if test == "evaluable.star" { + continue + } + doTestExample(t, test) } } diff --git a/starlark/types/provider_test.go b/starlark/types/provider_test.go index 06fce1e..fbd4bfa 100644 --- a/starlark/types/provider_test.go +++ b/starlark/types/provider_test.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "log" stdos "os" + "path/filepath" "testing" "github.com/mcuadros/ascode/starlark/module/os" @@ -64,11 +65,12 @@ func doTest(t *testing.T, filename string) { func doTestPrint(t *testing.T, filename string, print func(*starlark.Thread, string)) { id = 0 + dir, _ := filepath.Split(filename) pm := &terraform.PluginManager{".providers"} log.SetOutput(ioutil.Discard) thread := &starlark.Thread{Load: load, Print: print} - thread.SetLocal("base_path", "testdata") + thread.SetLocal("base_path", dir) thread.SetLocal(PluginManagerLocal, pm) test.SetReporter(thread, t) diff --git a/starlark/types/testdata/examples/evaluable.star b/starlark/types/testdata/examples/evaluable.star new file mode 100644 index 0000000..2426138 --- /dev/null +++ b/starlark/types/testdata/examples/evaluable.star @@ -0,0 +1,3 @@ +# evaluable.star file +print("Print from evaluable.star: '%s'" % foo) +bar="bar" \ No newline at end of file diff --git a/starlark/types/testdata/examples/evaluate.star b/starlark/types/testdata/examples/evaluate.star new file mode 100644 index 0000000..28c2b2e --- /dev/null +++ b/starlark/types/testdata/examples/evaluate.star @@ -0,0 +1,9 @@ +# Evaluate execute the given file, with the given context, in this case `foo` +values = evaluate("evaluable.star", foo="foo") + +# The context it's a module, in this case contains the key `bar` +print("Print from main: '%s'" % values.bar) + +# Output: +# Print from evaluable.star: 'foo' +# Print from main: 'bar'