Skip to content

Commit 92905a8

Browse files
committed
bake: support unix output in formattimestamp
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
1 parent 2798e13 commit 92905a8

3 files changed

Lines changed: 139 additions & 111 deletions

File tree

bake/hclparser/stdlib.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"path"
99
"path/filepath"
1010
"runtime"
11+
"strconv"
1112
"strings"
1213
"time"
1314

@@ -286,7 +287,7 @@ func semvercmpFunc() function.Function {
286287
// formatdate.
287288
func formatTimestampFunc() function.Function {
288289
return function.New(&function.Spec{
289-
Description: `Formats a timestamp string in RFC 3339 syntax or a unix timestamp integer into another timestamp in some other machine-oriented time syntax, as described in the format string.`,
290+
Description: `Formats a timestamp string in RFC 3339 syntax or a unix timestamp integer into another timestamp in some other machine-oriented time syntax, as described in the format string. The special format string "X" returns the unix timestamp in seconds.`,
290291
Params: []function.Parameter{
291292
{
292293
Name: "format",
@@ -299,14 +300,25 @@ func formatTimestampFunc() function.Function {
299300
},
300301
Type: function.StaticReturnType(cty.String),
301302
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
303+
formatStr := args[0].AsString()
302304
switch args[1].Type() {
303305
case cty.String:
306+
if formatStr == "X" {
307+
t, err := time.Parse(time.RFC3339, args[1].AsString())
308+
if err != nil {
309+
return cty.DynamicVal, function.NewArgErrorf(1, "timestamp string must be RFC3339")
310+
}
311+
return cty.StringVal(strconv.FormatInt(t.Unix(), 10)), nil
312+
}
304313
return stdlib.FormatDateFunc.Call([]cty.Value{args[0], args[1]})
305314
case cty.Number:
306315
t, err := unixTimestampValue(args[1])
307316
if err != nil {
308317
return cty.DynamicVal, function.NewArgError(1, err)
309318
}
319+
if formatStr == "X" {
320+
return cty.StringVal(strconv.FormatInt(t.Unix(), 10)), nil
321+
}
310322
return stdlib.FormatDateFunc.Call([]cty.Value{args[0], cty.StringVal(t.Format(time.RFC3339))})
311323
default:
312324
return cty.DynamicVal, function.NewArgErrorf(1, "must be a string timestamp or a unix timestamp number")

bake/hclparser/stdlib_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,16 @@ func TestFormatTimestampFunc(t *testing.T) {
353353
wantErr bool
354354
}
355355
tests := map[string]testCase{
356+
"unix format from rfc3339 string": {
357+
format: cty.StringVal("X"),
358+
input: cty.StringVal("2015-10-21T00:00:00Z"),
359+
want: cty.StringVal("1445385600"),
360+
},
361+
"unix format from unix timestamp input": {
362+
format: cty.StringVal("X"),
363+
input: cty.NumberIntVal(1445385600),
364+
want: cty.StringVal("1445385600"),
365+
},
356366
"rfc3339 string input": {
357367
format: cty.StringVal("YYYY-MM-DD"),
358368
input: cty.StringVal("2025-09-16T12:00:00Z"),
@@ -378,6 +388,11 @@ func TestFormatTimestampFunc(t *testing.T) {
378388
input: cty.StringVal("0"),
379389
wantErr: true,
380390
},
391+
"invalid string input for unix format": {
392+
format: cty.StringVal("X"),
393+
input: cty.StringVal("0"),
394+
wantErr: true,
395+
},
381396
}
382397

383398
for name, test := range tests {

0 commit comments

Comments
 (0)