mirror of
https://github.com/foomo/sesamy-cli.git
synced 2025-10-16 12:35:36 +00:00
feat: add open & diff command
This commit is contained in:
parent
c6f5292df3
commit
5fdd26d867
23
cmd/diff.go
Normal file
23
cmd/diff.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"github.com/foomo/sesamy-cli/cmd/diff"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewDiff represents the diff command
|
||||||
|
func NewDiff(l *slog.Logger) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "diff",
|
||||||
|
Short: "Print Google Tag Manager container status diff",
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(
|
||||||
|
diff.NewWeb(l),
|
||||||
|
diff.NewServer(l),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
396
cmd/diff/diff.go
Normal file
396
cmd/diff/diff.go
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
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 != "deleted" {
|
||||||
|
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 != "deleted" {
|
||||||
|
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 != "deleted" {
|
||||||
|
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 != "deleted" {
|
||||||
|
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 != "deleted" {
|
||||||
|
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 != "deleted" {
|
||||||
|
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 != "deleted" {
|
||||||
|
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 != "deleted" {
|
||||||
|
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 != "deleted" {
|
||||||
|
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...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
68
cmd/diff/server.go
Normal file
68
cmd/diff/server.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package diff
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||||
|
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||||
|
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewServer represents the server command
|
||||||
|
func NewServer(l *slog.Logger) *cobra.Command {
|
||||||
|
c := viper.New()
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "server",
|
||||||
|
Short: "Print Google Tag Manager Server Container status diff",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
l.Info("☕ Retrieving Server Container status")
|
||||||
|
|
||||||
|
cfg, err := pkgcmd.ReadConfig(l, c, cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tm, err := tagmanager.New(
|
||||||
|
cmd.Context(),
|
||||||
|
l,
|
||||||
|
cfg.GoogleTagManager.AccountID,
|
||||||
|
cfg.GoogleTagManager.ServerContainer,
|
||||||
|
tagmanager.WithRequestQuota(cfg.GoogleAPI.RequestQuota),
|
||||||
|
tagmanager.WithClientOptions(cfg.GoogleAPI.GetClientOption()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tm.EnsureWorkspaceID(cmd.Context()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := diff(cmd.Context(), l, tm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.GetBool("raw") {
|
||||||
|
out = utils.Highlight(out)
|
||||||
|
}
|
||||||
|
_, err = fmt.Println(out)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flags := cmd.Flags()
|
||||||
|
|
||||||
|
flags.Bool("raw", false, "print raw output")
|
||||||
|
_ = c.BindPFlag("raw", flags.Lookup("raw"))
|
||||||
|
|
||||||
|
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||||
|
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
68
cmd/diff/web.go
Normal file
68
cmd/diff/web.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package diff
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||||
|
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||||
|
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewWeb represents the web command
|
||||||
|
func NewWeb(l *slog.Logger) *cobra.Command {
|
||||||
|
c := viper.New()
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "web",
|
||||||
|
Short: "Print Google Tag Manager Web Container status diff",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
l.Info("☕ Retrieving Web Container status")
|
||||||
|
|
||||||
|
cfg, err := pkgcmd.ReadConfig(l, c, cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tm, err := tagmanager.New(
|
||||||
|
cmd.Context(),
|
||||||
|
l,
|
||||||
|
cfg.GoogleTagManager.AccountID,
|
||||||
|
cfg.GoogleTagManager.WebContainer,
|
||||||
|
tagmanager.WithRequestQuota(cfg.GoogleAPI.RequestQuota),
|
||||||
|
tagmanager.WithClientOptions(cfg.GoogleAPI.GetClientOption()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tm.EnsureWorkspaceID(cmd.Context()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := diff(cmd.Context(), l, tm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.GetBool("raw") {
|
||||||
|
out = utils.Highlight(out)
|
||||||
|
}
|
||||||
|
_, err = fmt.Println(out)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flags := cmd.Flags()
|
||||||
|
|
||||||
|
flags.Bool("raw", false, "print raw output")
|
||||||
|
_ = c.BindPFlag("raw", flags.Lookup("raw"))
|
||||||
|
|
||||||
|
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||||
|
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
@ -5,42 +5,34 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alecthomas/chroma/quick"
|
|
||||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||||
"github.com/itchyny/json2yaml"
|
"github.com/itchyny/json2yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
func dump(i interface{ MarshalJSON() ([]byte, error) }, err error) error {
|
func dump(i interface{ MarshalJSON() ([]byte, error) }, err error) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
out, err := i.MarshalJSON()
|
out, err := i.MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
// if err := json.Indent(ret, out, "", " "); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// fmt.Println(ret.String())
|
|
||||||
var output strings.Builder
|
var output strings.Builder
|
||||||
if err := json2yaml.Convert(&output, bytes.NewBuffer(out)); err != nil {
|
if err := json2yaml.Convert(&output, bytes.NewBuffer(out)); err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
// fmt.Print(output.String())
|
return output.String(), nil
|
||||||
return quick.Highlight(os.Stdout, output.String(), "yaml", "terminal", "monokai")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func list(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, resource string) error {
|
func list(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, resource string) (string, error) {
|
||||||
switch resource {
|
switch resource {
|
||||||
case "environments":
|
case "environments":
|
||||||
return dump(tm.Service().Accounts.Containers.Environments.List(tm.ContainerPath()).Context(ctx).Do())
|
return dump(tm.Service().Accounts.Containers.Environments.List(tm.ContainerPath()).Context(ctx).Do())
|
||||||
case "workspaces":
|
case "workspaces":
|
||||||
return dump(tm.Service().Accounts.Containers.Workspaces.List(tm.ContainerPath()).Context(ctx).Do())
|
return dump(tm.Service().Accounts.Containers.Workspaces.List(tm.ContainerPath()).Context(ctx).Do())
|
||||||
case "status":
|
|
||||||
return dump(tm.Service().Accounts.Containers.Workspaces.GetStatus(tm.WorkspacePath()).Context(ctx).Do())
|
|
||||||
case "clients":
|
case "clients":
|
||||||
return dump(tm.Service().Accounts.Containers.Workspaces.Clients.List(tm.WorkspacePath()).Context(ctx).Do())
|
return dump(tm.Service().Accounts.Containers.Workspaces.Clients.List(tm.WorkspacePath()).Context(ctx).Do())
|
||||||
case "tags":
|
case "tags":
|
||||||
@ -56,13 +48,14 @@ func list(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, resour
|
|||||||
case "templates-data":
|
case "templates-data":
|
||||||
r, err := tm.Service().Accounts.Containers.Workspaces.Templates.List(tm.WorkspacePath()).Context(ctx).Do()
|
r, err := tm.Service().Accounts.Containers.Workspaces.Templates.List(tm.WorkspacePath()).Context(ctx).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
|
var ret strings.Builder
|
||||||
for _, template := range r.Template {
|
for _, template := range r.Template {
|
||||||
l.Info("---- Template data: " + template.Name + " ----------------------")
|
ret.WriteString("---- Template data: " + template.Name + " ----------------------\n")
|
||||||
fmt.Println(template.TemplateData)
|
ret.WriteString(template.TemplateData + "\n")
|
||||||
}
|
}
|
||||||
return nil
|
return ret.String(), nil
|
||||||
case "gtag-config":
|
case "gtag-config":
|
||||||
return dump(tm.Service().Accounts.Containers.Workspaces.GtagConfig.List(tm.WorkspacePath()).Context(ctx).Do())
|
return dump(tm.Service().Accounts.Containers.Workspaces.GtagConfig.List(tm.WorkspacePath()).Context(ctx).Do())
|
||||||
case "triggers":
|
case "triggers":
|
||||||
@ -72,6 +65,6 @@ func list(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, resour
|
|||||||
case "zones":
|
case "zones":
|
||||||
return dump(tm.Service().Accounts.Containers.Workspaces.Zones.List(tm.WorkspacePath()).Context(ctx).Do())
|
return dump(tm.Service().Accounts.Containers.Workspaces.Zones.List(tm.WorkspacePath()).Context(ctx).Do())
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown resource %s", resource)
|
return "", fmt.Errorf("unknown resource %s", resource)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
package list
|
package list
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||||
|
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
@ -58,12 +60,24 @@ func NewServer(l *slog.Logger) *cobra.Command {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return list(cmd.Context(), l, tm, resource)
|
out, err := list(cmd.Context(), l, tm, resource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.GetBool("raw") {
|
||||||
|
out = utils.Highlight(out)
|
||||||
|
}
|
||||||
|
_, err = fmt.Println(out)
|
||||||
|
return err
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
|
||||||
|
flags.Bool("raw", false, "print raw output")
|
||||||
|
_ = c.BindPFlag("raw", flags.Lookup("raw"))
|
||||||
|
|
||||||
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||||
_ = c.BindPFlag("config", flags.Lookup("config"))
|
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
package list
|
package list
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||||
|
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
@ -57,12 +59,24 @@ func NewWeb(l *slog.Logger) *cobra.Command {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return list(cmd.Context(), l, tm, resource)
|
out, err := list(cmd.Context(), l, tm, resource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.GetBool("raw") {
|
||||||
|
out = utils.Highlight(out)
|
||||||
|
}
|
||||||
|
_, err = fmt.Println(out)
|
||||||
|
return err
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
|
||||||
|
flags.Bool("raw", false, "print raw output")
|
||||||
|
_ = c.BindPFlag("raw", flags.Lookup("raw"))
|
||||||
|
|
||||||
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||||
_ = c.BindPFlag("config", flags.Lookup("config"))
|
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||||
|
|
||||||
|
|||||||
70
cmd/open.go
Normal file
70
cmd/open.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||||
|
"github.com/pkg/browser"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewOpen represents the open command
|
||||||
|
func NewOpen(l *slog.Logger) *cobra.Command {
|
||||||
|
c := viper.New()
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "open",
|
||||||
|
Short: "Open links in the browser",
|
||||||
|
Args: cobra.OnlyValidArgs,
|
||||||
|
ValidArgs: []cobra.Completion{
|
||||||
|
"ga",
|
||||||
|
"gtm-web",
|
||||||
|
"gtm-server",
|
||||||
|
},
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
cfg, err := pkgcmd.ReadConfig(l, c, cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var url string
|
||||||
|
switch args[0] {
|
||||||
|
case "ga":
|
||||||
|
if cfg.GoogleAnalytics.PropertyID == "" {
|
||||||
|
return fmt.Errorf("missing Google Analytics Property ID")
|
||||||
|
}
|
||||||
|
url = fmt.Sprintf(
|
||||||
|
"https://analytics.google.com/analytics/web/#/p%s/",
|
||||||
|
cfg.GoogleAnalytics.PropertyID,
|
||||||
|
)
|
||||||
|
case "gtm-web":
|
||||||
|
url = fmt.Sprintf(
|
||||||
|
"https://tagmanager.google.com/#/container/accounts/%s/containers/%s/",
|
||||||
|
cfg.GoogleTagManager.AccountID,
|
||||||
|
cfg.GoogleTagManager.WebContainer.ContainerID,
|
||||||
|
)
|
||||||
|
case "gtm-server":
|
||||||
|
url = fmt.Sprintf(
|
||||||
|
"https://tagmanager.google.com/#/container/accounts/%s/containers/%s/",
|
||||||
|
cfg.GoogleTagManager.AccountID,
|
||||||
|
cfg.GoogleTagManager.ServerContainer.ContainerID,
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid container type: %s", args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Info("↗ Navigating to Google Tag Manager Container: " + url)
|
||||||
|
|
||||||
|
return browser.OpenURL(url)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flags := cmd.Flags()
|
||||||
|
|
||||||
|
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||||
|
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
3
go.mod
3
go.mod
@ -16,10 +16,12 @@ require (
|
|||||||
github.com/knadh/koanf/providers/file v1.2.0
|
github.com/knadh/koanf/providers/file v1.2.0
|
||||||
github.com/knadh/koanf/providers/rawbytes v1.0.0
|
github.com/knadh/koanf/providers/rawbytes v1.0.0
|
||||||
github.com/knadh/koanf/v2 v2.2.0
|
github.com/knadh/koanf/v2 v2.2.0
|
||||||
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pterm/pterm v0.12.80
|
github.com/pterm/pterm v0.12.80
|
||||||
github.com/spf13/cobra v1.9.1
|
github.com/spf13/cobra v1.9.1
|
||||||
github.com/spf13/viper v1.20.1
|
github.com/spf13/viper v1.20.1
|
||||||
|
github.com/sters/yaml-diff v1.4.1
|
||||||
github.com/stoewer/go-strcase v1.3.0
|
github.com/stoewer/go-strcase v1.3.0
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/wissance/stringFormatter v1.4.1
|
github.com/wissance/stringFormatter v1.4.1
|
||||||
@ -45,6 +47,7 @@ require (
|
|||||||
github.com/go-logr/logr v1.4.2 // indirect
|
github.com/go-logr/logr v1.4.2 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||||
|
github.com/goccy/go-yaml v1.15.6 // indirect
|
||||||
github.com/google/s2a-go v0.1.9 // indirect
|
github.com/google/s2a-go v0.1.9 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||||
|
|||||||
6
go.sum
6
go.sum
@ -66,6 +66,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
|||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
||||||
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||||
|
github.com/goccy/go-yaml v1.15.6 h1:gy5kf1yjMia3/c3wWD+u1z3lU5XlhpT8FZGaLJU9cOA=
|
||||||
|
github.com/goccy/go-yaml v1.15.6/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
@ -129,6 +131,8 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
|
|||||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||||
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||||
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
@ -165,6 +169,8 @@ github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
|||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
|
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
|
||||||
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
|
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
|
||||||
|
github.com/sters/yaml-diff v1.4.1 h1:0W3jnFKCu8/DV7nh2aXSDA2VVfxfHu2+qdh81CuFmZo=
|
||||||
|
github.com/sters/yaml-diff v1.4.1/go.mod h1:K286Xp2z+aGkok7z9k3zXcq0ZsrDaDp7/wyGwFjM9Y8=
|
||||||
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
||||||
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
|
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
|||||||
2
main.go
2
main.go
@ -19,6 +19,8 @@ func main() {
|
|||||||
root.AddCommand(
|
root.AddCommand(
|
||||||
cmd.NewConfig(l),
|
cmd.NewConfig(l),
|
||||||
cmd.NewList(l),
|
cmd.NewList(l),
|
||||||
|
cmd.NewDiff(l),
|
||||||
|
cmd.NewOpen(l),
|
||||||
cmd.NewProvision(l),
|
cmd.NewProvision(l),
|
||||||
cmd.NewTags(l),
|
cmd.NewTags(l),
|
||||||
cmd.NewTypeScript(l),
|
cmd.NewTypeScript(l),
|
||||||
|
|||||||
@ -7,6 +7,10 @@ import (
|
|||||||
type GoogleAnalytics struct {
|
type GoogleAnalytics struct {
|
||||||
// Enable provider
|
// Enable provider
|
||||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||||
|
// Google Analytics account id
|
||||||
|
AccountID string `json:"accountId" yaml:"accountId"`
|
||||||
|
// Google Analytics property id
|
||||||
|
PropertyID string `json:"propertyId" yaml:"propertyId"`
|
||||||
// Google Consent settings
|
// Google Consent settings
|
||||||
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
|
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
|
||||||
// GTag.js override configuration
|
// GTag.js override configuration
|
||||||
|
|||||||
98
pkg/utils/highlight.go
Normal file
98
pkg/utils/highlight.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/alecthomas/chroma"
|
||||||
|
"github.com/alecthomas/chroma/formatters"
|
||||||
|
"github.com/alecthomas/chroma/lexers"
|
||||||
|
"github.com/alecthomas/chroma/styles"
|
||||||
|
"github.com/pterm/pterm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Highlight(source string) string {
|
||||||
|
out := &numberWriter{
|
||||||
|
w: bytes.NewBufferString(""),
|
||||||
|
currentLine: 1,
|
||||||
|
}
|
||||||
|
// Determine lexer.
|
||||||
|
l := lexers.Get("yaml")
|
||||||
|
if l == nil {
|
||||||
|
l = lexers.Analyse(source)
|
||||||
|
}
|
||||||
|
if l == nil {
|
||||||
|
l = lexers.Fallback
|
||||||
|
}
|
||||||
|
l = chroma.Coalesce(l)
|
||||||
|
|
||||||
|
// Determine formatter.
|
||||||
|
f := formatters.Get("terminal256")
|
||||||
|
if f == nil {
|
||||||
|
f = formatters.Fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine style.
|
||||||
|
s := styles.Get("monokai")
|
||||||
|
if s == nil {
|
||||||
|
s = styles.Fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
it, err := l.Tokenise(nil, source)
|
||||||
|
if err != nil {
|
||||||
|
pterm.Error.Println(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = f.Format(out, s, it); err != nil {
|
||||||
|
pterm.Error.Println(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.w.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
type numberWriter struct {
|
||||||
|
w *bytes.Buffer
|
||||||
|
currentLine uint64
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *numberWriter) Write(p []byte) (int, error) {
|
||||||
|
// Early return.
|
||||||
|
// Can't calculate the line numbers until the line breaks are made, so store them all in a buffer.
|
||||||
|
if !bytes.Contains(p, []byte{'\n'}) {
|
||||||
|
w.buf = append(w.buf, p...)
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
original = p
|
||||||
|
tokenLen uint
|
||||||
|
)
|
||||||
|
for i, c := range original {
|
||||||
|
tokenLen++
|
||||||
|
if c != '\n' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
token := p[:tokenLen]
|
||||||
|
p = original[i+1:]
|
||||||
|
tokenLen = 0
|
||||||
|
|
||||||
|
format := "%4d |\t%s%s"
|
||||||
|
if w.currentLine > 9999 {
|
||||||
|
format = "%d |\t%s%s"
|
||||||
|
}
|
||||||
|
format = "\033[34m" + format + "\033[0m"
|
||||||
|
|
||||||
|
if _, err := fmt.Fprintf(w.w, format, w.currentLine, string(w.buf), string(token)); err != nil {
|
||||||
|
return i + 1, err
|
||||||
|
}
|
||||||
|
w.buf = w.buf[:0]
|
||||||
|
w.currentLine++
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(p) > 0 {
|
||||||
|
w.buf = append(w.buf, p...)
|
||||||
|
}
|
||||||
|
return len(original), nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user