Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
beaver
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
orus-io
beaver
Commits
ba018e474798
Commit
ba018e474798
authored
2 years ago
by
steeve.chailloux
Browse files
Options
Downloads
Patches
Plain Diff
improved hydrate function
can now hydrate multiline strings and/or raw yaml node
parent
977f0c7d0699
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
README.md
+1
-1
1 addition, 1 deletion
README.md
runner/config.go
+128
-12
128 additions, 12 deletions
runner/config.go
runner/config_test.go
+42
-1
42 additions, 1 deletion
runner/config_test.go
with
171 additions
and
14 deletions
README.md
+
1
−
1
View file @
ba018e47
#
Beaver
[
#
](
#
)
Beaver
```
____
...
...
This diff is collapsed.
Click to expand it.
runner/config.go
+
128
−
12
View file @
ba018e47
package
runner
import
(
"bytes"
"crypto/sha256"
"fmt"
"io"
...
...
@@ -16,7 +17,7 @@
// Variable ...
type
Variable
struct
{
Name
string
Value
string
Value
interface
{}
}
type
Sha
struct
{
...
...
@@ -422,8 +423,133 @@
return
files
}
func
hydrateString
(
input
string
,
output
io
.
Writer
,
variables
map
[
string
]
interface
{})
error
{
t
,
err
:=
fasttemplate
.
NewTemplate
(
input
,
"<["
,
"]>"
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"unexpected error when parsing template: %w"
,
err
)
}
s
,
err
:=
t
.
ExecuteFuncStringWithErr
(
func
(
w
io
.
Writer
,
tag
string
)
(
int
,
error
)
{
val
,
ok
:=
variables
[
tag
]
if
!
ok
{
return
0
,
fmt
.
Errorf
(
"tag not found: %s"
,
tag
)
}
switch
v
:=
val
.
(
type
)
{
case
string
:
return
w
.
Write
([]
byte
(
v
))
default
:
e
:=
yaml
.
NewEncoder
(
w
)
err
:=
e
.
Encode
(
val
)
return
0
,
err
}
})
if
err
!=
nil
{
return
err
}
if
_
,
err
:=
output
.
Write
([]
byte
(
s
));
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to template: %w"
,
err
)
}
return
nil
}
func
hydrateScalarNode
(
node
*
yaml
.
Node
,
variables
map
[
string
]
interface
{})
error
{
input
:=
node
.
Value
var
output
interface
{}
if
strings
.
HasPrefix
(
input
,
"<["
)
&&
strings
.
HasSuffix
(
input
,
"]>"
)
{
tag
:=
strings
.
Trim
(
input
,
"<[]>"
)
var
ok
bool
output
,
ok
=
variables
[
tag
]
if
!
ok
{
return
fmt
.
Errorf
(
"tag not found: %s"
,
tag
)
}
}
else
{
buf
:=
bytes
.
NewBufferString
(
""
)
if
err
:=
hydrateString
(
input
,
buf
,
variables
);
err
!=
nil
{
return
err
}
output
=
buf
.
String
()
}
// preserve comments
hc
:=
node
.
HeadComment
lc
:=
node
.
LineComment
fc
:=
node
.
FootComment
if
err
:=
node
.
Encode
(
output
);
err
!=
nil
{
return
err
}
node
.
HeadComment
=
hc
node
.
LineComment
=
lc
node
.
FootComment
=
fc
return
nil
}
func
hydrateYamlNodes
(
nodes
[]
*
yaml
.
Node
,
variables
map
[
string
]
interface
{})
error
{
for
_
,
node
:=
range
nodes
{
if
node
.
Kind
==
yaml
.
ScalarNode
{
if
err
:=
hydrateScalarNode
(
node
,
variables
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to parse scalar: %w"
,
err
)
}
}
else
{
if
err
:=
hydrateYamlNodes
(
node
.
Content
,
variables
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to hydrate content: %w"
,
err
)
}
}
}
return
nil
}
func
hydrateYaml
(
root
*
yaml
.
Node
,
variables
map
[
string
]
interface
{})
error
{
err
:=
hydrateYamlNodes
(
root
.
Content
,
variables
)
return
err
}
func
Hydrate
(
input
[]
byte
,
output
io
.
Writer
,
variables
map
[
string
]
interface
{})
error
{
documents
:=
bytes
.
Split
(
input
,
[]
byte
(
"---
\n
"
))
// yaml lib ignore leading '---'
// see: https://github.com/go-yaml/yaml/issues/749
// which is an issue for ytt value files
// this is why we loop over documents in the same file
for
i
,
doc
:=
range
documents
{
var
node
yaml
.
Node
if
err
:=
yaml
.
Unmarshal
(
doc
,
&
node
);
err
!=
nil
||
len
(
node
.
Content
)
==
0
{
// not a yaml template, fallback to raw template method
// ...maybe a ytt header or a frontmatter
template
:=
string
(
doc
)
if
err
:=
hydrateString
(
template
,
output
,
variables
);
err
!=
nil
{
return
err
}
}
else
{
// FIXME: do not call this method when hydrating only for sha,
// could be quite expensive
// yaml template method
err
:=
hydrateYaml
(
&
node
,
variables
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to hydrate yaml: %w"
,
err
)
}
o
,
err
:=
yaml
.
Marshal
(
node
.
Content
[
0
])
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to marshal yaml: %w"
,
err
)
}
_
,
err
=
output
.
Write
(
o
)
if
err
!=
nil
{
return
err
}
}
if
i
!=
len
(
documents
)
-
1
{
_
,
err
:=
output
.
Write
([]
byte
(
"---
\n
"
))
if
err
!=
nil
{
return
err
}
}
}
return
nil
}
func
hydrate
(
input
string
,
output
*
os
.
File
,
variables
map
[
string
]
interface
{})
error
{
byteTemplate
,
err
:=
os
.
ReadFile
(
input
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to read %s: %w"
,
input
,
err
)
}
...
...
@@ -425,19 +551,9 @@
func
hydrate
(
input
string
,
output
*
os
.
File
,
variables
map
[
string
]
interface
{})
error
{
byteTemplate
,
err
:=
os
.
ReadFile
(
input
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to read %s: %w"
,
input
,
err
)
}
template
:=
string
(
byteTemplate
)
t
,
err
:=
fasttemplate
.
NewTemplate
(
template
,
"<["
,
"]>"
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"unexpected error when parsing template: %w"
,
err
)
}
s
:=
t
.
ExecuteString
(
variables
)
if
_
,
err
:=
output
.
Write
([]
byte
(
s
));
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to template for %s: %w"
,
output
.
Name
(),
err
)
}
return
nil
return
Hydrate
(
byteTemplate
,
output
,
variables
)
}
func
hydrateFiles
(
tmpDir
string
,
variables
map
[
string
]
interface
{},
paths
[]
string
)
([]
string
,
error
)
{
...
...
This diff is collapsed.
Click to expand it.
runner/config_test.go
+
42
−
1
View file @
ba018e47
...
...
@@ -30,6 +30,47 @@
assert
.
Equal
(
t
,
"../vendor/ytt/odoo"
,
config
.
Charts
[
"odoo"
]
.
Path
)
}
func
TestHydrate
(
t
*
testing
.
T
)
{
rawVariables
:=
[]
byte
(
`
#@data/values
---
foo: |
a multi
line string
bar:
simple: interface
with:
- some
- content
baz: |
only one line in multiline mode
boo: a simple joke line
`
)
variables
:=
make
(
map
[
string
]
interface
{})
byteContent
:=
bytes
.
NewReader
(
rawVariables
)
decoder
:=
yaml
.
NewDecoder
(
byteContent
)
require
.
NoError
(
t
,
decoder
.
Decode
(
&
variables
))
input
:=
`
#@data/values
---
foo: <[foo]>
bar: <[bar]>
baz: <[baz]>
boo: <[boo]>
`
buf
:=
bytes
.
NewBufferString
(
""
)
require
.
NoError
(
t
,
runner
.
Hydrate
([]
byte
(
input
),
buf
,
variables
))
assert
.
Equal
(
t
,
string
(
rawVariables
),
buf
.
String
(),
)
}
func
TestYttBuildArgs
(
t
*
testing
.
T
)
{
tl
:=
testutils
.
NewTestLogger
(
t
)
testNS
:=
"environments/ns1"
...
...
@@ -100,7 +141,7 @@
}
func
TestSha
(
t
*
testing
.
T
)
{
shaValue
:=
"
2145bea9e32804c65d960e6d4af1c87f95ccc39fad7df5eec2f3925a193112ab
"
shaValue
:=
"
33935340f50ff18c3837c8cf42a423f6be96df7886723a3994a6018b0cc97e01
"
buildDir
:=
filepath
.
Join
(
shaFixtures
,
"build"
,
"example"
)
defer
func
()
{
require
.
NoError
(
t
,
runner
.
CleanDir
(
buildDir
))
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment