patch.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package v2
  2. import (
  3. "context"
  4. "fmt"
  5. "strings"
  6. jsonpatch "github.com/evanphx/json-patch"
  7. "github.com/porter-dev/api-contracts/generated/go/helpers"
  8. porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"
  9. "github.com/porter-dev/porter/internal/telemetry"
  10. )
  11. // PatchApp applies a set of JSON patch operations to an app proto and returns the modified proto
  12. func PatchApp(ctx context.Context, app *porterv1.PorterApp, ops []PatchOperation) (*porterv1.PorterApp, error) {
  13. ctx, span := telemetry.NewSpan(ctx, "v2-patch-app")
  14. defer span.End()
  15. var patchedApp *porterv1.PorterApp
  16. if app == nil {
  17. return patchedApp, telemetry.Error(ctx, span, nil, "no app provided")
  18. }
  19. by, err := helpers.MarshalContractObject(ctx, app)
  20. if err != nil {
  21. return patchedApp, telemetry.Error(ctx, span, err, "failed to marshal app")
  22. }
  23. var opStrs []string
  24. for _, op := range ops {
  25. opAsJSON, err := op.String()
  26. if err != nil {
  27. return patchedApp, telemetry.Error(ctx, span, err, "failed to convert patch operation to string")
  28. }
  29. opStrs = append(opStrs, fmt.Sprintf("\t%s", opAsJSON))
  30. }
  31. patchJson := fmt.Sprintf("[\n%s\n]", strings.Join(opStrs, ",\n"))
  32. telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "patch-json", Value: patchJson})
  33. patch, err := jsonpatch.DecodePatch([]byte(patchJson))
  34. if err != nil {
  35. return patchedApp, telemetry.Error(ctx, span, err, "failed to decode patch")
  36. }
  37. modified, err := patch.Apply(by)
  38. if err != nil {
  39. return patchedApp, telemetry.Error(ctx, span, err, "failed to apply patch")
  40. }
  41. patchedApp = &porterv1.PorterApp{}
  42. err = helpers.UnmarshalContractObject(modified, patchedApp)
  43. if err != nil {
  44. return patchedApp, telemetry.Error(ctx, span, err, "failed to unmarshal patched app")
  45. }
  46. return patchedApp, nil
  47. }