sesamy-cli/cmd/diff/diff.go
Kevin Franklin Kim df04a14c25
chore: add docker
2025-09-10 16:13:51 +02:00

401 lines
8.8 KiB
Go

package diff
import (
"bytes"
"context"
"log/slog"
"strings"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
"github.com/itchyny/json2yaml"
"github.com/sters/yaml-diff/yamldiff"
)
const ChangeStatusDeleted = "deleted"
func diff(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager) (string, error) {
l.Info("└ ⬇︎ Loading status")
s, err := tm.Service().Accounts.Containers.Workspaces.GetStatus(tm.WorkspacePath()).Context(ctx).Do()
if err != nil {
return "", err
} else if len(s.WorkspaceChange) == 0 {
return "", nil
}
l.Info("└ ⬇︎ Loading live version")
live, err := tm.Service().Accounts.Containers.Versions.Live(tm.ContainerPath()).Do()
if err != nil {
return "", err
}
var res []string
for _, entity := range s.WorkspaceChange {
switch {
case entity.Tag != nil:
res = append(res, " # Tag: "+entity.Tag.Name+" ("+entity.ChangeStatus+")\n")
// unset props
entity.Tag.Path = ""
entity.Tag.Fingerprint = ""
entity.Tag.WorkspaceId = ""
entity.Tag.TagManagerUrl = ""
var changed string
if entity.ChangeStatus != ChangeStatusDeleted {
changed, err = ToYalm(entity.Tag)
if err != nil {
return "", err
}
}
var original string
for _, value := range live.Tag {
if value.Name == entity.Tag.Name {
// unset props
value.Fingerprint = ""
original, err = ToYalm(value)
if err != nil {
return "", err
}
break
}
}
d, err := ToDiff(original, changed)
if err != nil {
return "", err
}
res = append(res, d...)
case entity.Folder != nil:
res = append(res, " # Folder: "+entity.Folder.Name+" ("+entity.ChangeStatus+")")
// unset props
entity.Folder.Path = ""
entity.Folder.Fingerprint = ""
entity.Folder.WorkspaceId = ""
entity.Folder.TagManagerUrl = ""
var changed string
if entity.ChangeStatus != ChangeStatusDeleted {
changed, err = ToYalm(entity.Folder)
if err != nil {
return "", err
}
}
var original string
for _, value := range live.Folder {
if value.Name == entity.Folder.Name {
// unset props
value.Fingerprint = ""
original, err = ToYalm(value)
if err != nil {
return "", err
}
break
}
}
d, err := ToDiff(original, changed)
if err != nil {
return "", err
}
res = append(res, d...)
case entity.Trigger != nil:
res = append(res, " # Trigger: "+entity.Trigger.Name+" ("+entity.ChangeStatus+")")
// unset props
entity.Trigger.Path = ""
entity.Trigger.Fingerprint = ""
entity.Trigger.WorkspaceId = ""
entity.Trigger.TagManagerUrl = ""
var changed string
if entity.ChangeStatus != ChangeStatusDeleted {
changed, err = ToYalm(entity.Trigger)
if err != nil {
return "", err
}
}
var original string
for _, value := range live.Trigger {
if value.Name == entity.Trigger.Name {
// unset props
value.Fingerprint = ""
original, err = ToYalm(value)
if err != nil {
return "", err
}
break
}
}
d, err := ToDiff(original, changed)
if err != nil {
return "", err
}
res = append(res, d...)
case entity.Variable != nil:
res = append(res, " # Variable: "+entity.Variable.Name+" ("+entity.ChangeStatus+")")
// unset props
entity.Variable.Path = ""
entity.Variable.Fingerprint = ""
entity.Variable.WorkspaceId = ""
entity.Variable.TagManagerUrl = ""
var changed string
if entity.ChangeStatus != ChangeStatusDeleted {
changed, err = ToYalm(entity.Variable)
if err != nil {
return "", err
}
}
var original string
for _, value := range live.Variable {
if value.Name == entity.Variable.Name {
// unset props
value.Fingerprint = ""
original, err = ToYalm(value)
if err != nil {
return "", err
}
break
}
}
d, err := ToDiff(original, changed)
if err != nil {
return "", err
}
res = append(res, d...)
case entity.Client != nil:
res = append(res, " # Client: "+entity.Client.Name+" ("+entity.ChangeStatus+")")
// unset props
entity.Client.Path = ""
entity.Client.Fingerprint = ""
entity.Client.WorkspaceId = ""
entity.Client.TagManagerUrl = ""
var changed string
if entity.ChangeStatus != ChangeStatusDeleted {
changed, err = ToYalm(entity.Client)
if err != nil {
return "", err
}
}
var original string
for _, value := range live.Client {
if value.Name == entity.Client.Name {
// unset props
value.Fingerprint = ""
original, err = ToYalm(value)
if err != nil {
return "", err
}
break
}
}
d, err := ToDiff(original, changed)
if err != nil {
return "", err
}
res = append(res, d...)
case entity.GtagConfig != nil:
res = append(res, " # GtagConfig: "+entity.GtagConfig.AccountId+" ("+entity.ChangeStatus+")")
// unset props
entity.GtagConfig.Path = ""
entity.GtagConfig.Fingerprint = ""
entity.GtagConfig.WorkspaceId = ""
entity.GtagConfig.TagManagerUrl = ""
var changed string
if entity.ChangeStatus != ChangeStatusDeleted {
changed, err = ToYalm(entity.GtagConfig)
if err != nil {
return "", err
}
}
var original string
for _, value := range live.GtagConfig {
if value.AccountId == entity.GtagConfig.AccountId {
// unset props
value.Fingerprint = ""
original, err = ToYalm(value)
if err != nil {
return "", err
}
break
}
}
d, err := ToDiff(original, changed)
if err != nil {
return "", err
}
res = append(res, d...)
case entity.BuiltInVariable != nil:
res = append(res, " # BuiltInVariable: "+entity.BuiltInVariable.Name+" ("+entity.ChangeStatus+")")
// unset props
entity.BuiltInVariable.Path = ""
entity.BuiltInVariable.WorkspaceId = ""
var changed string
if entity.ChangeStatus != ChangeStatusDeleted {
changed, err = ToYalm(entity.BuiltInVariable)
if err != nil {
return "", err
}
}
var original string
for _, value := range live.BuiltInVariable {
if value.Name == entity.BuiltInVariable.Name {
original, err = ToYalm(value)
if err != nil {
return "", err
}
break
}
}
d, err := ToDiff(original, changed)
if err != nil {
return "", err
}
res = append(res, d...)
case entity.CustomTemplate != nil:
res = append(res, " # CustomTemplate: "+entity.CustomTemplate.Name+" ("+entity.ChangeStatus+")")
// unset props
entity.CustomTemplate.Path = ""
entity.CustomTemplate.Fingerprint = ""
entity.CustomTemplate.WorkspaceId = ""
entity.CustomTemplate.TagManagerUrl = ""
var changed string
if entity.ChangeStatus != ChangeStatusDeleted {
changed, err = ToYalm(entity.CustomTemplate)
if err != nil {
return "", err
}
}
var original string
for _, value := range live.CustomTemplate {
if value.Name == entity.CustomTemplate.Name {
// unset props
value.Fingerprint = ""
original, err = ToYalm(value)
if err != nil {
return "", err
}
break
}
}
d, err := ToDiff(original, changed)
if err != nil {
return "", err
}
res = append(res, d...)
case entity.Transformation != nil:
res = append(res, " # Transformation: "+entity.Transformation.Name+" ("+entity.ChangeStatus+")")
// unset props
entity.Transformation.Path = ""
entity.Transformation.Fingerprint = ""
entity.Transformation.WorkspaceId = ""
entity.Transformation.TagManagerUrl = ""
var changed string
if entity.ChangeStatus != ChangeStatusDeleted {
changed, err = ToYalm(entity.Transformation)
if err != nil {
return "", err
}
}
var original string
for _, value := range live.Transformation {
if value.Name == entity.Transformation.Name {
// unset props
value.Fingerprint = ""
original, err = ToYalm(value)
if err != nil {
return "", err
}
break
}
}
d, err := ToDiff(original, changed)
if err != nil {
return "", err
}
res = append(res, d...)
default:
l.Warn("unknown entity type", "entity", entity)
}
}
return strings.Join(res, " ---\n"), nil
}
type Marshelable interface {
MarshalJSON() ([]byte, error)
}
func ToDiff(original, changed string) ([]string, error) {
yamls1, err := yamldiff.Load(original)
if err != nil {
return nil, err
}
yamls2, err := yamldiff.Load(changed)
if err != nil {
return nil, err
}
var ret []string
for _, d := range yamldiff.Do(yamls1, yamls2) {
if value := d.Dump(); len(value) > 4 {
ret = append(ret, value)
}
}
return ret, nil
}
func ToYalm(m Marshelable) (string, error) {
if m == nil {
return "", nil
}
out, err := m.MarshalJSON()
if err != nil {
return "", err
}
var ret bytes.Buffer
if err := json2yaml.Convert(&ret, bytes.NewBuffer(out)); err != nil {
return "", err
}
return ret.String(), nil
}