Skip to content

Commit 1241756

Browse files
committed
bake: add unixtimestampparse function
Signed-off-by: CrazyMax <[email protected]>
1 parent 8df6fc5 commit 1241756

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

bake/hclparser/stdlib.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ var stdlibFunctions = []funcDef{
122122
{name: "trimspace", fn: stdlib.TrimSpaceFunc},
123123
{name: "trimsuffix", fn: stdlib.TrimSuffixFunc},
124124
{name: "try", fn: tryfunc.TryFunc, descriptionAlt: `Variadic function that tries to evaluate all of is arguments in sequence until one succeeds, in which case it returns that result, or returns an error if none of them succeed.`},
125+
{name: "unixtimestampparse", factory: unixtimestampParseFunc},
125126
{name: "upper", fn: stdlib.UpperFunc},
126127
{name: "urlencode", fn: encoding.URLEncodeFunc, descriptionAlt: `Applies URL encoding to a given string.`},
127128
{name: "uuidv4", fn: uuid.V4Func, descriptionAlt: `Generates and returns a Type-4 UUID in the standard hexadecimal string format.`},
@@ -311,6 +312,59 @@ func rfc3339ParseFunc() function.Function {
311312
})
312313
}
313314

315+
// unixtimestampParseFunc, given a unix timestamp integer, will parse and
316+
// return an object representation of that date and time
317+
//
318+
// This function is similar to the `unix_timestamp_parse` function in Terraform:
319+
// https://registry.terraform.io/providers/hashicorp/time/latest/docs/functions/unix_timestamp_parse
320+
func unixtimestampParseFunc() function.Function {
321+
return function.New(&function.Spec{
322+
Description: `Given a unix timestamp integer, will parse and return an object representation of that date and time. A unix timestamp is the number of seconds elapsed since January 1, 1970 UTC.`,
323+
Params: []function.Parameter{
324+
{
325+
Name: "unix_timestamp",
326+
Description: "Unix Timestamp integer to parse",
327+
Type: cty.Number,
328+
},
329+
},
330+
Type: function.StaticReturnType(cty.Object(map[string]cty.Type{
331+
"year": cty.Number,
332+
"year_day": cty.Number,
333+
"day": cty.Number,
334+
"month": cty.Number,
335+
"month_name": cty.String,
336+
"weekday": cty.Number,
337+
"weekday_name": cty.String,
338+
"hour": cty.Number,
339+
"minute": cty.Number,
340+
"second": cty.Number,
341+
"rfc3339": cty.String,
342+
"iso_year": cty.Number,
343+
"iso_week": cty.Number,
344+
})),
345+
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
346+
ts, _ := args[0].AsBigFloat().Int64()
347+
unixTime := time.Unix(ts, 0).UTC()
348+
isoYear, isoWeek := unixTime.ISOWeek()
349+
return cty.ObjectVal(map[string]cty.Value{
350+
"year": cty.NumberIntVal(int64(unixTime.Year())),
351+
"year_day": cty.NumberIntVal(int64(unixTime.YearDay())),
352+
"day": cty.NumberIntVal(int64(unixTime.Day())),
353+
"month": cty.NumberIntVal(int64(unixTime.Month())),
354+
"month_name": cty.StringVal(unixTime.Month().String()),
355+
"weekday": cty.NumberIntVal(int64(unixTime.Weekday())),
356+
"weekday_name": cty.StringVal(unixTime.Weekday().String()),
357+
"hour": cty.NumberIntVal(int64(unixTime.Hour())),
358+
"minute": cty.NumberIntVal(int64(unixTime.Minute())),
359+
"second": cty.NumberIntVal(int64(unixTime.Second())),
360+
"rfc3339": cty.StringVal(unixTime.Format(time.RFC3339)),
361+
"iso_year": cty.NumberIntVal(int64(isoYear)),
362+
"iso_week": cty.NumberIntVal(int64(isoWeek)),
363+
}), nil
364+
},
365+
})
366+
}
367+
314368
func Stdlib() map[string]function.Function {
315369
funcs := make(map[string]function.Function, len(stdlibFunctions))
316370
for _, v := range stdlibFunctions {

bake/hclparser/stdlib_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,29 @@ func TestRfc3339ParseFunc(t *testing.T) {
226226
_, err = fn.Call([]cty.Value{cty.StringVal("not-a-date")})
227227
require.Error(t, err)
228228
}
229+
230+
func TestUnixTimestampParseFunc(t *testing.T) {
231+
fn := unixtimestampParseFunc()
232+
input := cty.NumberIntVal(1690328596)
233+
got, err := fn.Call([]cty.Value{input})
234+
require.NoError(t, err)
235+
236+
expected := map[string]cty.Value{
237+
"year": cty.NumberIntVal(2023),
238+
"year_day": cty.NumberIntVal(206),
239+
"day": cty.NumberIntVal(25),
240+
"month": cty.NumberIntVal(7),
241+
"month_name": cty.StringVal("July"),
242+
"weekday": cty.NumberIntVal(2),
243+
"weekday_name": cty.StringVal("Tuesday"),
244+
"hour": cty.NumberIntVal(23),
245+
"minute": cty.NumberIntVal(43),
246+
"second": cty.NumberIntVal(16),
247+
"rfc3339": cty.StringVal("2023-07-25T23:43:16Z"),
248+
"iso_year": cty.NumberIntVal(2023),
249+
"iso_week": cty.NumberIntVal(30),
250+
}
251+
for k, v := range expected {
252+
require.True(t, got.GetAttr(k).RawEquals(v), "field %s: got %v, want %v", k, got.GetAttr(k), v)
253+
}
254+
}

docs/bake-stdlib.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ title: Bake standard library functions
103103
| `trimspace` | Removes any consecutive space characters (as defined by Unicode) from the start and end of the given string. |
104104
| `trimsuffix` | Removes the given suffix from the start of the given string, if present. |
105105
| `try` | Variadic function that tries to evaluate all of is arguments in sequence until one succeeds, in which case it returns that result, or returns an error if none of them succeed. |
106+
| `unixtimestampparse` | Given a unix timestamp integer, will parse and return an object representation of that date and time. A unix timestamp is the number of seconds elapsed since January 1, 1970 UTC. |
106107
| `upper` | Returns the given string with all Unicode letters translated to their uppercase equivalents. |
107108
| `urlencode` | Applies URL encoding to a given string. |
108109
| `uuidv4` | Generates and returns a Type-4 UUID in the standard hexadecimal string format. |

0 commit comments

Comments
 (0)