diff --git a/cmd/catalog-importer/cmd/sync.go b/cmd/catalog-importer/cmd/sync.go index ec13c8c..2ab3bc0 100644 --- a/cmd/catalog-importer/cmd/sync.go +++ b/cmd/catalog-importer/cmd/sync.go @@ -341,14 +341,14 @@ func (opt *SyncOptions) Run(ctx context.Context, logger kitlog.Logger, cfg *conf OUT("\n ↻ %s", outputType.TypeName) // Filter source for each of the output types - entries, err := output.Collect(ctx, outputType, sourcedEntries, logger) + entries, err := output.Collect(ctx, logger, outputType, sourcedEntries) if err != nil { return errors.Wrap(err, fmt.Sprintf("outputs.%d (type_name='%s')", idx, outputType.TypeName)) } OUT(" ✔ Building entries... (found %d entries matching filters)", len(entries)) // Marshal entries using the JS expressions. - entryModels, err := output.MarshalEntries(ctx, outputType, entries, logger) + entryModels, err := output.MarshalEntries(ctx, logger, outputType, entries) if err != nil { return errors.Wrap(err, fmt.Sprintf("outputs.%d (type_name='%s')", idx, outputType.TypeName)) } diff --git a/expr/js_eval.go b/expr/js_eval.go index b665dfc..f6275dd 100644 --- a/expr/js_eval.go +++ b/expr/js_eval.go @@ -30,7 +30,7 @@ func init() { // EvaluateJavascript can evaluate a source Javascript program having set the given // subject into the `$` variable. -func EvaluateJavascript(ctx context.Context, source string, subject any, logger kitlog.Logger) (result otto.Value, err error) { +func EvaluateJavascript(ctx context.Context, logger kitlog.Logger, source string, subject any) (result otto.Value, err error) { var halted bool defer func() { if caught := recover(); caught != nil { @@ -78,8 +78,8 @@ func EvaluateJavascript(ctx context.Context, source string, subject any, logger } -func EvaluateArray[ReturnType any](ctx context.Context, source string, subject any, logger kitlog.Logger) ([]ReturnType, error) { - result, err := EvaluateJavascript(ctx, source, subject, logger) +func EvaluateArray[ReturnType any](ctx context.Context, logger kitlog.Logger, source string, subject any) ([]ReturnType, error) { + result, err := EvaluateJavascript(ctx, logger, source, subject) if err != nil { return nil, errors.Wrap(err, "evaluating array value") } @@ -115,7 +115,7 @@ func EvaluateArray[ReturnType any](ctx context.Context, source string, subject a // Now parse each nested value and return the final slice. resultValues := []ReturnType{} for _, evaluatedValue := range evaluatedValues { - resultValue, err := EvaluateResultType[ReturnType](ctx, source, evaluatedValue) + resultValue, err := EvaluateResultType[ReturnType](ctx, logger, source, evaluatedValue) if err != nil { return nil, nil } @@ -127,9 +127,9 @@ func EvaluateArray[ReturnType any](ctx context.Context, source string, subject a return resultValues, nil } -func EvaluateSingleValue[ReturnType any](ctx context.Context, source string, subject any, logger kitlog.Logger) (*ReturnType, error) { +func EvaluateSingleValue[ReturnType any](ctx context.Context, logger kitlog.Logger, source string, subject any) (*ReturnType, error) { var emptyResult *ReturnType - result, err := EvaluateJavascript(ctx, source, subject, logger) + result, err := EvaluateJavascript(ctx, logger, source, subject) if err != nil { return emptyResult, errors.Wrap(err, "evaluating single value") } @@ -137,7 +137,7 @@ func EvaluateSingleValue[ReturnType any](ctx context.Context, source string, sub return nil, nil } - resultValue, err := EvaluateResultType[ReturnType](ctx, source, result) + resultValue, err := EvaluateResultType[ReturnType](ctx, logger, source, result) if err != nil { return nil, err } @@ -145,7 +145,7 @@ func EvaluateSingleValue[ReturnType any](ctx context.Context, source string, sub return resultValue, nil } -func EvaluateResultType[ReturnType any](ctx context.Context, source string, result otto.Value) (*ReturnType, error) { +func EvaluateResultType[ReturnType any](ctx context.Context, logger kitlog.Logger, source string, result otto.Value) (*ReturnType, error) { var resultValue *ReturnType switch { case result.IsBoolean(): @@ -217,7 +217,7 @@ func EvaluateResultType[ReturnType any](ctx context.Context, source string, resu return resultValue, nil case isArray(result): - fmt.Fprintf(os.Stdout, "\n Source %s evaluates to an array. Assuming this is handled separately\n", source) + logger.Log("\n Source %s evaluates to an array. Assuming this is handled separately\n", source) return resultValue, nil default: diff --git a/expr/js_eval_test.go b/expr/js_eval_test.go index 836519a..611acd5 100644 --- a/expr/js_eval_test.go +++ b/expr/js_eval_test.go @@ -44,41 +44,41 @@ var _ = Describe("Javascript evaluation", func() { When("parsing attribute sources", func() { It("returns the correct top-level attribute", func() { topLevelSrc := "$.name" - evaluatedResult, err := EvaluateSingleValue[string](ctx, topLevelSrc, sourceEntry, logger) + evaluatedResult, err := EvaluateSingleValue[string](ctx, logger, topLevelSrc, sourceEntry) Expect(err).NotTo(HaveOccurred()) Expect(*evaluatedResult).To(Equal(sourceEntry["name"])) }) It("returns a bool as expected", func() { topLevelSrc := "$.important" - evaluatedResult, err := EvaluateSingleValue[bool](ctx, topLevelSrc, sourceEntry, logger) + evaluatedResult, err := EvaluateSingleValue[bool](ctx, logger, topLevelSrc, sourceEntry) Expect(err).NotTo(HaveOccurred()) Expect(*evaluatedResult).To(Equal(sourceEntry["important"])) }) It("returns a number as expected", func() { topLevelSrc := "$.importance_score" - evaluatedResult, err := EvaluateSingleValue[int](ctx, topLevelSrc, sourceEntry, logger) + evaluatedResult, err := EvaluateSingleValue[int](ctx, logger, topLevelSrc, sourceEntry) Expect(err).NotTo(HaveOccurred()) Expect(*evaluatedResult).To(Equal(sourceEntry["importance_score"])) }) It("returns a string as expected", func() { topLevelSrc := "$.description" - evaluatedResult, err := EvaluateSingleValue[string](ctx, topLevelSrc, sourceEntry, logger) + evaluatedResult, err := EvaluateSingleValue[string](ctx, logger, topLevelSrc, sourceEntry) Expect(err).NotTo(HaveOccurred()) Expect(*evaluatedResult).To(Equal(sourceEntry["description"])) }) It("does not parse a value if given the wrong type", func() { topLevelSrc := "$.description" - _, err := EvaluateSingleValue[int](ctx, topLevelSrc, sourceEntry, logger) + _, err := EvaluateSingleValue[int](ctx, logger, topLevelSrc, sourceEntry) Expect(err).To(HaveOccurred(), "could not convert result of string to int") }) It("returns nil if the type is not supported", func() { topLevelSrc := "$.metadata" - evaluatedResult, err := EvaluateSingleValue[string](ctx, topLevelSrc, sourceEntry, logger) + evaluatedResult, err := EvaluateSingleValue[string](ctx, logger, topLevelSrc, sourceEntry) Expect(err).NotTo(HaveOccurred()) Expect(evaluatedResult).To(BeNil()) }) @@ -86,21 +86,21 @@ var _ = Describe("Javascript evaluation", func() { It("manipulates string values as expected", func() { topLevelSrc := "$.name.replace('Component', 'Replacement')" - evaluatedResult, err := EvaluateSingleValue[string](ctx, topLevelSrc, sourceEntry, logger) + evaluatedResult, err := EvaluateSingleValue[string](ctx, logger, topLevelSrc, sourceEntry) Expect(err).NotTo(HaveOccurred()) Expect(*evaluatedResult).To(Equal("Replacement name")) }) It("parses nested values as expected", func() { topLevelSrc := "$.metadata.namespace" - evaluatedResult, err := EvaluateSingleValue[string](ctx, topLevelSrc, sourceEntry, logger) + evaluatedResult, err := EvaluateSingleValue[string](ctx, logger, topLevelSrc, sourceEntry) Expect(err).NotTo(HaveOccurred()) Expect(*evaluatedResult).To(Equal(sourceEntry["metadata"].(map[string]any)["namespace"])) }) It("handles possible null values with _.get", func() { nestedSrc := "_.get($.metadata, \"badKey\", \"default value\")" - evaluatedResult, err := EvaluateSingleValue[string](ctx, nestedSrc, sourceEntry, logger) + evaluatedResult, err := EvaluateSingleValue[string](ctx, logger, nestedSrc, sourceEntry) Expect(err).NotTo(HaveOccurred()) Expect(*evaluatedResult).To(Equal("default value")) }) @@ -111,14 +111,14 @@ var _ = Describe("Javascript evaluation", func() { entryName, ok := sourceEntryWithArray["name"].(string) Expect(ok).To(BeTrue()) expectedResult := []string{entryName} - evaluatedResult, err := EvaluateArray[string](ctx, topLevelSrc, sourceEntryWithArray, logger) + evaluatedResult, err := EvaluateArray[string](ctx, logger, topLevelSrc, sourceEntryWithArray) Expect(err).NotTo(HaveOccurred()) Expect(evaluatedResult).To(Equal(expectedResult)) }) It("works as expected when given actual array input", func() { topLevelSrc := "$.domains" - evaluatedResult, err := EvaluateArray[string](ctx, topLevelSrc, sourceEntryWithArray, logger) + evaluatedResult, err := EvaluateArray[string](ctx, logger, topLevelSrc, sourceEntryWithArray) Expect(err).NotTo(HaveOccurred()) Expect(evaluatedResult).To(Equal(sourceEntryWithArray["domains"])) }) @@ -127,14 +127,14 @@ var _ = Describe("Javascript evaluation", func() { When("sending invalid source javascript", func() { It("returns nothing if I send a key that isn't present on the entry", func() { topLevelSrc := "$.ghostkey" - evaluatedResult, err := EvaluateSingleValue[string](ctx, topLevelSrc, sourceEntry, logger) + evaluatedResult, err := EvaluateSingleValue[string](ctx, logger, topLevelSrc, sourceEntry) Expect(err).NotTo(HaveOccurred()) Expect(evaluatedResult).To(BeNil()) }) It("returns nil if my JS is invalid", func() { topLevelSrc := "$badKey" - evaluatedResult, err := EvaluateArray[string](ctx, topLevelSrc, sourceEntryWithArray, logger) + evaluatedResult, err := EvaluateArray[string](ctx, logger, topLevelSrc, sourceEntryWithArray) Expect(err).NotTo(HaveOccurred()) // Expecting an array with an empty string here, as that is the empty state for this function Expect(evaluatedResult).To(BeNil()) diff --git a/output/collect.go b/output/collect.go index c1e65c1..91f0cc2 100644 --- a/output/collect.go +++ b/output/collect.go @@ -11,7 +11,7 @@ import ( // Collect filters the list of entries against the source filter on the output, returning // a list of all entries which pass the filter. -func Collect(ctx context.Context, output *Output, entries []source.Entry, logger kitlog.Logger) ([]source.Entry, error) { +func Collect(ctx context.Context, logger kitlog.Logger, output *Output, entries []source.Entry) ([]source.Entry, error) { if !output.Source.Filter.Valid { return entries, nil // no-op, the filter is blank } @@ -20,7 +20,7 @@ func Collect(ctx context.Context, output *Output, entries []source.Entry, logger filteredEntries := []source.Entry{} for _, entry := range entries { - result, err := expr.EvaluateSingleValue[bool](ctx, src, entry, logger) + result, err := expr.EvaluateSingleValue[bool](ctx, logger, src, entry) if err != nil { return nil, errors.Wrap(err, "evaluating filter for entry") } diff --git a/output/marshal.go b/output/marshal.go index ec83a02..467348b 100644 --- a/output/marshal.go +++ b/output/marshal.go @@ -87,7 +87,7 @@ func MarshalType(output *Output) (base *CatalogTypeModel, enumTypes []*CatalogTy // // The majority of the work comes from compiling and evaluating the JS expressions that // marshal the catalog entries from source. -func MarshalEntries(ctx context.Context, output *Output, entries []source.Entry, logger kitlog.Logger) ([]*CatalogEntryModel, error) { +func MarshalEntries(ctx context.Context, logger kitlog.Logger, output *Output, entries []source.Entry) ([]*CatalogEntryModel, error) { nameSource := output.Source.Name externalIDSource := output.Source.ExternalID aliasesSource := output.Source.Aliases @@ -108,12 +108,12 @@ func MarshalEntries(ctx context.Context, output *Output, entries []source.Entry, catalogEntryModels := []*CatalogEntryModel{} for _, entry := range entries { - name, err := expr.EvaluateSingleValue[string](ctx, nameSource, entry, logger) + name, err := expr.EvaluateSingleValue[string](ctx, logger, nameSource, entry) if err != nil { return nil, errors.Wrap(err, "evaluating entry name") } - externalID, err := expr.EvaluateSingleValue[string](ctx, externalIDSource, entry, logger) + externalID, err := expr.EvaluateSingleValue[string](ctx, logger, externalIDSource, entry) if err != nil { return nil, errors.Wrap(err, "evaluating entry external ID") } @@ -121,7 +121,7 @@ func MarshalEntries(ctx context.Context, output *Output, entries []source.Entry, var rank *int if rankSource := output.Source.Rank; rankSource.Valid && rankSource.String != "" { var err error - rank, err = expr.EvaluateSingleValue[int](ctx, rankSource.String, entry, logger) + rank, err = expr.EvaluateSingleValue[int](ctx, logger, rankSource.String, entry) if err != nil { return nil, errors.Wrap(err, "evaluating entry rank") } @@ -132,12 +132,12 @@ func MarshalEntries(ctx context.Context, output *Output, entries []source.Entry, aliases := []string{} for idx, aliasSource := range aliasesSource { toAdd := []string{} - alias, err := expr.EvaluateSingleValue[string](ctx, aliasSource, entry, logger) + alias, err := expr.EvaluateSingleValue[string](ctx, logger, aliasSource, entry) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("aliases.%d: evaluating entry alias", idx)) } if alias == nil { - aliasArray, arrayErr := expr.EvaluateArray[string](ctx, aliasSource, entry, logger) + aliasArray, arrayErr := expr.EvaluateArray[string](ctx, logger, aliasSource, entry) if arrayErr != nil { return nil, errors.Wrap(err, fmt.Sprintf("aliases.%d: evaluating entry alias", idx)) } @@ -161,7 +161,7 @@ func MarshalEntries(ctx context.Context, output *Output, entries []source.Entry, binding := client.CatalogAttributeBindingPayloadV2{} if attributeByID[attributeID].Array { - valueLiterals, err := expr.EvaluateArray[any](ctx, src, entry, logger) + valueLiterals, err := expr.EvaluateArray[any](ctx, logger, src, entry) if err != nil { return catalogEntryModels, errors.Wrap(err, "evaluating attribute") } @@ -251,7 +251,7 @@ func evaluateEntryWithAttributeType(ctx context.Context, src string, entry map[s } func evaluateEntryWithType[ReturnType any](ctx context.Context, src string, entry map[string]any, logger kitlog.Logger) (*string, error) { - literal, err := expr.EvaluateSingleValue[ReturnType](ctx, src, entry, logger) + literal, err := expr.EvaluateSingleValue[ReturnType](ctx, logger, src, entry) if err != nil { return nil, err } diff --git a/output/marshal_test.go b/output/marshal_test.go index 763a559..c804053 100644 --- a/output/marshal_test.go +++ b/output/marshal_test.go @@ -50,7 +50,7 @@ var _ = Describe("Marshalling data", func() { entries := []source.Entry{sourceEntry} - res, err := MarshalEntries(ctx, catalogTypeOutput, entries, logger) + res, err := MarshalEntries(ctx, logger, catalogTypeOutput, entries) expectedAliasResult := []string{"aliasInAnArray", "anotherAliasInAnArray"} Expect(err).NotTo(HaveOccurred()) @@ -68,7 +68,7 @@ var _ = Describe("Marshalling data", func() { "aliases": "singleAlias", } entries := []source.Entry{sourceEntry} - res, err := MarshalEntries(ctx, catalogTypeOutput, entries, logger) + res, err := MarshalEntries(ctx, logger, catalogTypeOutput, entries) expectedAliasResult := []string{"singleAlias"} Expect(err).NotTo(HaveOccurred()) Expect(res[0].Aliases).To(Equal(expectedAliasResult)) @@ -99,7 +99,7 @@ var _ = Describe("Marshalling data", func() { "description": "A super important component. A structurally integral component tbh.", } entries := []source.Entry{sourceEntry} - res, err := MarshalEntries(ctx, catalogTypeOutput, entries, logger) + res, err := MarshalEntries(ctx, logger, catalogTypeOutput, entries) Expect(err).NotTo(HaveOccurred()) Expect(res[0].AttributeValues).To(BeEmpty()) })