diff --git a/cmd/docs.go b/cmd/docs.go index 9b8490766..61ea45d2e 100644 --- a/cmd/docs.go +++ b/cmd/docs.go @@ -5,6 +5,7 @@ import ( "os/exec" "runtime" + "github.com/fatih/color" "github.com/spf13/cobra" u "github.com/cloudposse/atmos/pkg/utils" @@ -39,6 +40,8 @@ var docsCmd = &cobra.Command{ if err != nil { u.LogErrorAndExit(err) } + + u.PrintMessageInColor("Opened browser window with Atmos documentation\n", color.New(color.FgGreen)) }, } diff --git a/cmd/root.go b/cmd/root.go index 70db70e8b..267874a89 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -20,7 +20,7 @@ import ( // RootCmd represents the base command when called without any subcommands var RootCmd = &cobra.Command{ Use: "atmos", - Short: "Universal Tool for DevOps and Cloud Automation", + Short: "Automated Terraform Management & Orchestration Software", Long: `Atmos is a universal tool for DevOps and cloud automation used for provisioning, managing and orchestrating workflows across various toolchains`, PreRun: func(cmd *cobra.Command, args []string) { }, @@ -100,6 +100,15 @@ func init() { func initConfig() { styles := boa.DefaultStyles() + styles.Border.BorderTop(false) + styles.Border.BorderBottom(false) + styles.Border.BorderLeft(false) + styles.Border.BorderRight(false) + styles.Title.BorderTop(false) + styles.Title.BorderBottom(false) + styles.Title.BorderLeft(false) + styles.Title.BorderRight(false) + b := boa.New(boa.WithStyles(styles)) RootCmd.SetUsageFunc(b.UsageFunc) diff --git a/cmd/version.go b/cmd/version.go index 27097b24a..5851373a8 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -26,14 +26,15 @@ var versionCmd = &cobra.Command{ u.LogErrorAndExit(err) } - u.PrintMessage(fmt.Sprintf("\U0001F47D Atmos %s on %s/%s", Version, runtime.GOOS, runtime.GOARCH)) + currentRelease := strings.TrimPrefix(Version, "v") + + u.PrintMessage(fmt.Sprintf("\U0001F47D Atmos %s on %s/%s", currentRelease, runtime.GOOS, runtime.GOARCH)) fmt.Println() // Check for the latest Atmos release on GitHub latestReleaseTag, err := u.GetLatestGitHubRepoRelease("cloudposse", "atmos") if err == nil && latestReleaseTag != "" { latestRelease := strings.TrimPrefix(latestReleaseTag, "v") - currentRelease := strings.TrimPrefix(Version, "v") if latestRelease != currentRelease { printMessageToUpgradeToAtmosLatestRelease(latestRelease) } diff --git a/examples/quick-start-advanced/Dockerfile b/examples/quick-start-advanced/Dockerfile index a0409b789..d49108fbd 100644 --- a/examples/quick-start-advanced/Dockerfile +++ b/examples/quick-start-advanced/Dockerfile @@ -1,15 +1,15 @@ # Geodesic: https://github.com/cloudposse/geodesic/ -ARG GEODESIC_VERSION=2.11.3 +ARG GEODESIC_VERSION=3.0.0 ARG GEODESIC_OS=debian # Atmos # https://atmos.tools/ # https://github.com/cloudposse/atmos # https://github.com/cloudposse/atmos/releases -ARG ATMOS_VERSION=1.84.0 +ARG ATMOS_VERSION=1.85.0 # Terraform: https://github.com/hashicorp/terraform/releases -ARG TF_VERSION=1.9.1 +ARG TF_VERSION=1.9.2 FROM cloudposse/geodesic:${GEODESIC_VERSION}-${GEODESIC_OS} diff --git a/go.mod b/go.mod index 3efd951cb..23c7ea5b1 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,8 @@ require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.26.6 - github.com/charmbracelet/lipgloss v0.11.1 + github.com/charmbracelet/glamour v0.7.0 + github.com/charmbracelet/lipgloss v0.12.1 github.com/elewis787/boa v0.1.2 github.com/fatih/color v1.17.0 github.com/go-git/go-git/v5 v5.12.0 @@ -33,13 +34,13 @@ require ( github.com/open-policy-agent/opa v0.66.0 github.com/otiai10/copy v1.14.0 github.com/pkg/errors v0.9.1 - github.com/samber/lo v1.44.0 + github.com/samber/lo v1.46.0 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - github.com/zclconf/go-cty v1.14.4 + github.com/zclconf/go-cty v1.15.0 gopkg.in/yaml.v2 v2.4.0 mvdan.cc/sh/v3 v3.8.0 ) @@ -60,6 +61,7 @@ require ( github.com/Shopify/ejson v1.3.3 // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect + github.com/alecthomas/chroma/v2 v2.8.0 // indirect github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect @@ -86,13 +88,14 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.16.6 // indirect github.com/aws/smithy-go v1.11.2 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 // indirect github.com/cenkalti/backoff/v3 v3.2.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chainguard-dev/git-urls v1.0.2 // indirect - github.com/charmbracelet/x/ansi v0.1.3 // indirect + github.com/charmbracelet/x/ansi v0.1.4 // indirect github.com/charmbracelet/x/input v0.1.2 // indirect github.com/charmbracelet/x/term v0.1.1 // indirect github.com/charmbracelet/x/windows v0.1.2 // indirect @@ -130,6 +133,7 @@ require ( github.com/google/wire v0.5.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.3 // indirect + github.com/gorilla/css v1.0.0 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gosimple/slug v1.12.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect @@ -172,6 +176,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/microcosm-cc/bluemonday v1.0.25 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect @@ -184,6 +189,7 @@ require ( github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/oklog/run v1.1.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect @@ -218,6 +224,8 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/yashtewari/glob-intersection v0.2.0 // indirect + github.com/yuin/goldmark v1.5.4 // indirect + github.com/yuin/goldmark-emoji v1.0.2 // indirect github.com/zealic/xignore v0.3.3 // indirect go.etcd.io/bbolt v1.3.10 // indirect go.opencensus.io v0.24.0 // indirect diff --git a/go.sum b/go.sum index 488f39484..500122600 100644 --- a/go.sum +++ b/go.sum @@ -265,8 +265,14 @@ github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXva github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink= +github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s= +github.com/alecthomas/chroma/v2 v2.8.0 h1:w9WJUjFFmHHB2e8mRpL9jjy3alYDlU0QLDezj1xE264= +github.com/alecthomas/chroma/v2 v2.8.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -359,6 +365,8 @@ github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE= github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -389,10 +397,12 @@ github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/ github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqpzOLN2zq1s= github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk= -github.com/charmbracelet/lipgloss v0.11.1 h1:a8KgVPHa7kOoP95vm2tQQrjD2AKhbWmfr4uJ2RW6kNk= -github.com/charmbracelet/lipgloss v0.11.1/go.mod h1:beLlcmkF7MWA+5UrKKIRo/VJ21xGXr7YJ9miWfdMRIU= -github.com/charmbracelet/x/ansi v0.1.3 h1:RBh/eleNWML5R524mjUF0yVRePTwqN9tPtV+DPgO5Lw= -github.com/charmbracelet/x/ansi v0.1.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/glamour v0.7.0 h1:2BtKGZ4iVJCDfMF229EzbeR1QRKLWztO9dMtjmqZSng= +github.com/charmbracelet/glamour v0.7.0/go.mod h1:jUMh5MeihljJPQbJ/wf4ldw2+yBP59+ctV36jASy7ps= +github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs= +github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8= +github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= +github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/input v0.1.2 h1:QJAZr33eOhDowkkEQ24rsJy4Llxlm+fRDf/cQrmqJa0= github.com/charmbracelet/x/input v0.1.2/go.mod h1:LGBim0maUY4Pitjn/4fHnuXb4KirU3DODsyuHuXdOyA= github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI= @@ -700,6 +710,8 @@ github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBH github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -814,6 +826,8 @@ github.com/hashicorp/vault/sdk v0.5.0/go.mod h1:UJZHlfwj7qUJG8g22CuxUgkdJouFrBNv github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -954,10 +968,13 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= +github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= @@ -1008,6 +1025,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/open-policy-agent/opa v0.66.0 h1:DbrvfJQja0FBRcPOB3Z/BOckocN+M4ApNWyNhSRJt0w= @@ -1089,8 +1108,8 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= -github.com/samber/lo v1.44.0 h1:5il56KxRE+GHsm1IR+sZ/6J42NODigFiqCWpSc2dybA= -github.com/samber/lo v1.44.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= +github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -1183,10 +1202,15 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= -github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU= +github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s= +github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= github.com/zealic/xignore v0.3.3 h1:EpLXUgZY/JEzFkTc+Y/VYypzXtNz+MSOMVCGW5Q4CKQ= diff --git a/internal/exec/help.go b/internal/exec/help.go index bd168c6fa..bf0dedc0c 100644 --- a/internal/exec/help.go +++ b/internal/exec/help.go @@ -1,117 +1,63 @@ package exec import ( + _ "embed" "fmt" + tui "github.com/cloudposse/atmos/internal/tui/help" "github.com/cloudposse/atmos/pkg/schema" - u "github.com/cloudposse/atmos/pkg/utils" ) +//go:embed help_docs/atmos_terraform_help.md +var atmosTerraformHelp string + +//go:embed help_docs/atmos_helmfile_help.md +var atmosHelmfileHelp string + +//go:embed help_docs/atmos_terraform_clean_help.md +var atmosTerraformCleanHelp string + +//go:embed help_docs/atmos_terraform_deploy_help.md +var atmosTerraformDeployHelp string + +//go:embed help_docs/atmos_terraform_shell_help.md +var atmosTerraformShellHelp string + +//go:embed help_docs/atmos_terraform_workspace_help.md +var atmosTerraformWorkspaceHelp string + // processHelp processes help commands func processHelp(componentType string, command string) error { cliConfig := schema.CliConfiguration{} + var content string if len(command) == 0 { - u.PrintMessage(fmt.Sprintf("'atmos' supports all native '%s' commands.\n", componentType)) - u.PrintMessage("In addition, the 'component' argument and 'stack' flag are required to generate the variables and backend config for the component in the stack.\n") - u.PrintMessage(fmt.Sprintf("atmos %s -s [options]", componentType)) - u.PrintMessage(fmt.Sprintf("atmos %s --stack [options]", componentType)) - if componentType == "terraform" { - u.PrintMessage("\nAdditions and differences from native terraform:") - u.PrintMessage(" - before executing other 'terraform' commands, 'atmos' runs 'terraform init'") - u.PrintMessage(" - you can skip over atmos calling 'terraform init' if you know your project is already in a good working state by using " + - "the '--skip-init' flag like so 'atmos terraform -s --skip-init") - u.PrintMessage(" - 'atmos terraform deploy' command executes 'terraform apply -auto-approve' (sets the '-auto-approve' flag when running 'terraform apply')") - u.PrintMessage(" - 'atmos terraform deploy' command supports '--deploy-run-init=true/false' flag to enable/disable running 'terraform init' " + - "before executing the command") - u.PrintMessage(" - 'atmos terraform apply' and 'atmos terraform deploy' commands support '--from-plan' flag. If the flag is specified, " + - "the commands will use the planfile previously generated by 'atmos terraform plan' command instead of generating a new planfile") - u.PrintMessage(" - 'atmos terraform apply' and 'atmos terraform deploy' commands commands support '--planfile' flag to specify the path " + - "to a planfile. The '--planfile' flag should be used instead of the planfile argument in the native 'terraform apply ' command") - u.PrintMessage(" - 'atmos terraform clean' command deletes the '.terraform' folder, '.terraform.lock.hcl' lock file, " + - "and the previously generated 'planfile', 'varfile' and 'backend.tf.json' file for the specified component and stack. " + - "Use --skip-lock-file flag to skip deleting the lock file.") - u.PrintMessage(" - 'atmos terraform workspace' command first runs 'terraform init -reconfigure', then 'terraform workspace select', " + - "and if the workspace was not created before, it then runs 'terraform workspace new'") - u.PrintMessage(" - 'atmos terraform import' command searches for 'region' in the variables for the specified component and stack, " + - "and if it finds it, sets 'AWS_REGION=' ENV var before executing the command") - u.PrintMessage(" - 'atmos terraform generate backend' command generates a backend config file for an 'atmos' component in a stack") - u.PrintMessage(" - 'atmos terraform generate backends' command generates backend config files for all 'atmos' components in all stacks") - u.PrintMessage(" - 'atmos terraform generate varfile' command generates a varfile for an 'atmos' component in a stack") - u.PrintMessage(" - 'atmos terraform generate varfiles' command generates varfiles for all 'atmos' components in all stacks") - u.PrintMessage(" - 'atmos terraform shell' command configures an environment for an 'atmos' component in a stack and starts a new shell " + - "allowing executing all native terraform commands inside the shell without using atmos-specific arguments and flags") - u.PrintMessage(" - double-dash '--' can be used to signify the end of the options for Atmos and the start of the additional " + - "native arguments and flags for the 'terraform' commands. " + - "For example: atmos terraform plan -s -- -refresh=false -lock=false") + content = atmosTerraformHelp } - if componentType == "helmfile" { - u.PrintMessage("\nAdditions and differences from native helmfile:") - u.PrintMessage(" - 'atmos helmfile generate varfile' command generates a varfile for the component in the stack") - u.PrintMessage(" - 'atmos helmfile' commands support '[global options]' using the command-line flag '--global-options'. " + - "Usage: atmos helmfile -s [command options] [arguments] --global-options=\"--no-color --namespace=test\"") - u.PrintMessage(" - before executing the 'helmfile' commands, 'atmos' runs 'aws eks update-kubeconfig' to read kubeconfig from " + - "the EKS cluster and use it to authenticate with the cluster. This can be disabled in 'atmos.yaml' CLI config " + - "by setting 'components.helmfile.use_eks' to 'false'") - u.PrintMessage(" - double-dash '--' can be used to signify the end of the options for Atmos and the start of the additional " + - "native arguments and flags for the 'helmfile' commands") - } - - fmt.Println() - err := ExecuteShellCommand(cliConfig, componentType, []string{"--help"}, "", nil, false, "") - if err != nil { - return err + content = atmosHelmfileHelp } - } else if componentType == "terraform" && command == "clean" { - u.PrintMessage("\n'atmos terraform clean' command deletes the following folders and files from the component's directory:\n\n" + - " - '.terraform' folder\n" + - " - folder that the 'TF_DATA_DIR' ENV var points to\n" + - " - '.terraform.lock.hcl' file\n" + - " - generated varfile for the component in the stack\n" + - " - generated planfile for the component in the stack\n" + - " - generated 'backend.tf.json' file\n\n" + - "Usage: atmos terraform clean -s \n\n" + - "Use '--skip-lock-file' flag to skip deleting the lock file.\n\n" + - "For more details refer to https://atmos.tools/cli/commands/terraform/clean\n") + content = atmosTerraformCleanHelp } else if componentType == "terraform" && command == "deploy" { - u.PrintMessage("\n'atmos terraform deploy' command executes 'terraform apply -auto-approve' on an Atmos component in an Atmos stack.\n\n" + - "Usage: atmos terraform deploy -s \n\n" + - "The command automatically sets '-auto-approve' flag when running 'terraform apply'.\n\n" + - "It supports '--deploy-run-init=true|false' flag to enable/disable running terraform init before executing the command.\n\n" + - "It supports '--from-plan' flag. If the flag is specified, the command will use the planfile previously generated by 'atmos terraform plan' " + - "command instead of generating a new planfile.\nNote that in this case, the planfile name is in the format supported by Atmos and is " + - "saved to the component's folder.\n\n" + - "It supports '--planfile' flag to specify the path to a planfile.\nThe '--planfile' flag should be used instead of the 'planfile' " + - "argument in the native 'terraform apply ' command.\n\n" + - "For more details refer to https://atmos.tools/cli/commands/terraform/deploy\n") + content = atmosTerraformDeployHelp } else if componentType == "terraform" && command == "shell" { - u.PrintMessage("\n'atmos terraform shell' command starts a new SHELL configured with the environment for an Atmos component " + - "in a Stack to allow executing all native terraform commands\ninside the shell without using the atmos-specific arguments and flags.\n\n" + - "Usage: atmos terraform shell -s \n\n" + - "The command does the following:\n\n" + - " - Processes the stack config files, generates the required variables for the Atmos component in the stack, and writes them to a file in the component's folder\n" + - " - Generates a backend config file for the Atmos component in the stack and writes it to a file in the component's folder (or as specified by the Atmos configuration setting)\n" + - " - Creates a Terraform workspace for the component in the stack\n" + - " - Drops the user into a separate shell (process) with all the required paths and ENV vars set\n" + - " - Inside the shell, the user can execute all Terraform commands using the native syntax\n\n" + - "For more details refer to https://atmos.tools/cli/commands/terraform/shell\n") + content = atmosTerraformShellHelp } else if componentType == "terraform" && command == "workspace" { - u.PrintMessage("\n'atmos terraform workspace' command calculates the Terraform workspace for an Atmos component,\n" + - "and then executes 'terraform init -reconfigure' and selects the Terraform workspace by executing the 'terraform workspace select' command.\n" + - "If the workspace does not exist, the command creates it by executing the 'terraform workspace new' command.\n\n" + - "Usage: atmos terraform workspace -s \n\n" + - "For more details refer to https://atmos.tools/cli/commands/terraform/workspace\n") + content = atmosTerraformWorkspaceHelp } else { - u.PrintMessage(fmt.Sprintf("'atmos' supports native '%s %s' command with all the options, arguments and flags.\n", componentType, command)) - u.PrintMessage("In addition, 'component' and 'stack' are required in order to generate variables for the component in the stack.\n") - u.PrintMessage(fmt.Sprintf("atmos %s %s -s [options]", componentType, command)) - u.PrintMessage(fmt.Sprintf("atmos %s %s --stack [options]", componentType, command)) + // Execute `--help` for the native terraform and Helmfile commands + err := ExecuteShellCommand(cliConfig, componentType, []string{command, "--help"}, "", nil, false, "") + if err != nil { + return err + } + } + // Start the help UI + if content != "" { + _, err := tui.Execute(content) fmt.Println() - err := ExecuteShellCommand(cliConfig, componentType, []string{command, "--help"}, "", nil, false, "") if err != nil { return err } diff --git a/internal/exec/help_docs/atmos_helmfile_help.md b/internal/exec/help_docs/atmos_helmfile_help.md new file mode 100644 index 000000000..819e6b501 --- /dev/null +++ b/internal/exec/help_docs/atmos_helmfile_help.md @@ -0,0 +1,24 @@ +# Atmos Helmfile Help + +Check out the [Atmos Helmfile CLI documentation](https://atmos.tools/cli/commands/helmfile/usage). + +Atmos supports all Helmfile commands and options described in +the [Helmfile docs](https://helmfile.readthedocs.io/en/latest). + +__NOTE:__ Execute `helmfile --help` to see help for the Helmfile CLI commands. + +In addition, the `component` argument and `stack` flag are required to generate the variables and backend config for the component in the stack. +For example: `atmos helmfile diff eks/echo-server --stack plat-ue2-prod` + +
+ +## Additions and differences from native Helmfile + +- `atmos helmfile generate varfile` command generates a varfile for the component in the stack +
+- `atmos helmfile` commands support `[global options]` using the command-line flag `--global-options`. + Usage: `atmos helmfile [command] [component] -s [stack] [command options] [arguments] --global-options="--no-color --namespace=test"` +
+- before executing the `helmfile` commands, Atmos runs the `aws eks update-kubeconfig` command to read kubeconfig from the EKS cluster and use it to authenticate with the cluster. This can be disabled in `atmos.yaml` CLI config by setting the `components.helmfile.use_eks` attribute to `false` +
+- double-dash `--` can be used to signify the end of the options for Atmos and the start of the additional native arguments and flags for the Helmfile commands diff --git a/internal/exec/help_docs/atmos_terraform_clean_help.md b/internal/exec/help_docs/atmos_terraform_clean_help.md new file mode 100644 index 000000000..c31e6b728 --- /dev/null +++ b/internal/exec/help_docs/atmos_terraform_clean_help.md @@ -0,0 +1,25 @@ +# atmos terraform clean + +Check out the ['atmos terraform clean' documentation](https://atmos.tools/cli/commands/terraform/clean). + +## Description + +`atmos terraform clean` command deletes the following folders and files from the component's directory: + +- `.terraform` folder +
+- folder that the `TF_DATA_DIR` ENV var points to +
+- generated `varfile` for the component in the stack +
+- generated `planfile` for the component in the stack +
+- generated `backend.tf.json` file + +Use the `--skip-lock-file` flag to skip deleting the lock file. + +## Examples + +`atmos terraform clean vpc --stack plat-ue2-dev` + +`atmos terraform clean vpc -s plat-ue2-prod --skip-lock-file` diff --git a/internal/exec/help_docs/atmos_terraform_deploy_help.md b/internal/exec/help_docs/atmos_terraform_deploy_help.md new file mode 100644 index 000000000..5dccc9e16 --- /dev/null +++ b/internal/exec/help_docs/atmos_terraform_deploy_help.md @@ -0,0 +1,28 @@ +# atmos terraform deploy + +Check out the ['atmos terraform deploy' documentation](https://atmos.tools/cli/commands/terraform/deploy). + +## Description + +`atmos terraform deploy` command executes `terraform apply -auto-approve` on an Atmos component in a stack. + +## Flags + +- `--deploy-run-init=true|false` - run `terraform init` before executing the command +
+- `--from-plan` - if the flag is passed, the command will use the planfile previously generated by `atmos terraform plan` command instead of generating a new `planfile`. +
+- `--planfile` - specify the path to a planfile. The `--planfile` flag should be used instead of the `PLAN` argument in the native `terraform apply [PLAN]` command +
+ +## Examples + +`atmos terraform deploy vpc-flow-logs-bucket --stack plat-ue2-dev` + +`atmos terraform deploy vpc -s plat-ue2-dev` + +`atmos terraform deploy vpc -s plat-ue2-prod --from-plan` + +`atmos terraform deploy vpc -s plat-ue2-prod --planfile [PLAN]` + +`atmos terraform deploy vpc -s plat-ue2-staging --deploy-run-init=false` diff --git a/internal/exec/help_docs/atmos_terraform_help.md b/internal/exec/help_docs/atmos_terraform_help.md new file mode 100644 index 000000000..21b539a52 --- /dev/null +++ b/internal/exec/help_docs/atmos_terraform_help.md @@ -0,0 +1,46 @@ +# Atmos Terraform Help + +Check out the [Atmos Terraform CLI documentation](https://atmos.tools/cli/commands/terraform/usage). + +Atmos supports all Terraform commands and options described in +the [Terraform CLI docs](https://www.terraform.io/cli/commands). + +__NOTE:__ Execute `terraform --help` to see help for the Terraform CLI commands. + +In addition, the `component` argument and `stack` flag are required to generate the variables and backend config +for the component in the stack. For example: `atmos terraform apply vpc --stack plat-ue2-prod` + +
+ +## Additions and differences from native Terraform + +- Before executing other `terraform` commands, Atmos runs `terraform init` +
+- You can skip over Atmos calling `terraform init` if you know your project is already in a good working state by using the `--skip-init` flag. For example: `atmos terraform plan vpc -s plat-ue2-prod --skip-init` +
+- `atmos terraform deploy` command executes `terraform apply -auto-approve` (sets the `-auto-approve` flag when running `terraform apply`) +
+- `atmos terraform deploy` command supports the `--deploy-run-init` flag to enable/disable running `terraform init` before executing the command +
+- `atmos terraform apply` and `atmos terraform deploy` commands support `--from-plan` flag. If the flag is specified, the commands will use the `planfile` previously generated by the `atmos terraform plan` command instead of generating a new `planfile` +
+- `atmos terraform apply` and `atmos terraform deploy` commands support the `--planfile` flag to specify the path to a planfile. The `--planfile` flag should be used instead of the `PLAN` argument in the native `terraform apply [PLAN]` command +
+- `atmos terraform clean` command deletes the `.terraform` folder, `.terraform.lock.hcl` lock file, and the previously generated `planfile`, `varfile` and `backend.tf.json` file for the specified component and stack. Use the `--skip-lock-file`' flag to skip deleting the lock file +
+- `atmos terraform workspace` command first runs `terraform init -reconfigure`, then `terraform workspace select`, and if the workspace was not created before, it then runs `terraform workspace new` +
+- `atmos terraform import` command searches for the `region` in the variables for the specified component and stack, and if it finds it, sets `AWS_REGION` ENV var before executing the command +
+- `atmos terraform generate backend` command generates a backend config file for a component in a stack +
+- `atmos terraform generate backends` command generates backend config files for all Atmos components in all stacks +
+- `atmos terraform generate varfile` command generates a varfile for a component in a stack +
+- `atmos terraform generate varfiles` command generates varfiles for all Atmos components in all stacks +
+- `atmos terraform shell` command configures an environment for a component in a stack and starts a new shell, allowing executing all native terraform commands inside the shell without using Atmos-specific arguments and flags +
+- double-dash `--` can be used to signify the end of the options for Atmos and the start of the additional native arguments and flags for the Terraform commands. + For example: `atmos terraform plan vpc -s plat-ue2-prod -- -refresh=false -lock=false` diff --git a/internal/exec/help_docs/atmos_terraform_shell_help.md b/internal/exec/help_docs/atmos_terraform_shell_help.md new file mode 100644 index 000000000..942dbef7b --- /dev/null +++ b/internal/exec/help_docs/atmos_terraform_shell_help.md @@ -0,0 +1,27 @@ +# atmos terraform shell + +Check out the ['atmos terraform shell' documentation](https://atmos.tools/cli/commands/terraform/shell). + +## Description + +`atmos terraform shell` command starts a new SHELL configured with the environment for an Atmos component in a stack +to allow executing all native Terraform commands inside the shell without using the Atmos-specific arguments and flags. + +The command does the following: + +- Processes the stack config files, generates the variables for the Atmos component in the stack, and writes them to a file in the component's folder +
+- Generates a backend config for the Atmos component in the stack and writes it to a file in the component's folder +
+- Creates a Terraform workspace for the component in the stack +
+- Drops the user into a separate shell (process) with all the required paths and ENV variables set +
+- Inside the shell, the user can execute all Terraform commands using the native syntax +
+ +## Examples + +`atmos terraform shell vpc-flow-logs-bucket --stack plat-ue2-prod` + +`atmos terraform shell vpc -s plat-ue2-dev` diff --git a/internal/exec/help_docs/atmos_terraform_workspace_help.md b/internal/exec/help_docs/atmos_terraform_workspace_help.md new file mode 100644 index 000000000..584040e9f --- /dev/null +++ b/internal/exec/help_docs/atmos_terraform_workspace_help.md @@ -0,0 +1,17 @@ +# atmos terraform workspace + +Check out the ['atmos terraform workspace' documentation](https://atmos.tools/cli/commands/terraform/workspace). + +## Description + +`atmos terraform workspace` command calculates the Terraform workspace for an Atmos component in a stack, then +executes `terraform init -reconfigure` and selects the Terraform workspace by executing the `terraform workspace +select` command. + +If the workspace does not exist, the command creates it by executing the `terraform workspace new` command. + +## Examples + +`atmos terraform workspace vpc-flow-logs-bucket --stack plat-ue2-prod` + +`atmos terraform workspace vpc -s plat-ue2-dev` diff --git a/internal/exec/template_utils.go b/internal/exec/template_utils.go index ae1ca2d30..82da86f92 100644 --- a/internal/exec/template_utils.go +++ b/internal/exec/template_utils.go @@ -21,8 +21,17 @@ import ( ) // ProcessTmpl parses and executes Go templates -func ProcessTmpl(tmplName string, tmplValue string, tmplData any, ignoreMissingTemplateValues bool) (string, error) { - funcs := lo.Assign(FuncMap(context.TODO(), &data.Data{}), sprig.FuncMap()) +func ProcessTmpl( + tmplName string, + tmplValue string, + tmplData any, + ignoreMissingTemplateValues bool, +) (string, error) { + d := data.Data{} + ctx := context.TODO() + + // Add Gomplate, Sprig and Atmos template functions + funcs := lo.Assign(gomplate.CreateFuncs(ctx, &d), sprig.FuncMap(), FuncMap(ctx, &d)) t, err := template.New(tmplName).Funcs(funcs).Parse(tmplValue) if err != nil { diff --git a/internal/tui/components/code_view/main.go b/internal/tui/components/code_view/main.go index 0719eeda4..23eb358c4 100644 --- a/internal/tui/components/code_view/main.go +++ b/internal/tui/components/code_view/main.go @@ -1,11 +1,11 @@ package code_view import ( - u "github.com/cloudposse/atmos/internal/tui/utils" - "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + + u "github.com/cloudposse/atmos/internal/tui/utils" ) type Model struct { diff --git a/internal/tui/help/model.go b/internal/tui/help/model.go new file mode 100644 index 000000000..55a5a8d51 --- /dev/null +++ b/internal/tui/help/model.go @@ -0,0 +1,82 @@ +package help + +import ( + "github.com/charmbracelet/bubbles/viewport" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/glamour" + "github.com/charmbracelet/lipgloss" +) + +var helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).Render + +type App struct { + viewport viewport.Model +} + +func NewApp(content string) (*App, error) { + const width = 90 + const height = 30 + + vp := viewport.New(width, height) + vp.Style = lipgloss.NewStyle(). + BorderStyle(lipgloss.RoundedBorder()). + BorderForeground(lipgloss.Color("62")). + PaddingRight(2) + + renderer, err := glamour.NewTermRenderer( + glamour.WithAutoStyle(), + glamour.WithWordWrap(width-4), + glamour.WithEmoji(), + glamour.WithStyles(atmosHelpStyleConfig), + ) + if err != nil { + return nil, err + } + + str, err := renderer.Render(content) + if err != nil { + return nil, err + } + + vp.SetContent(str) + + return &App{ + viewport: vp, + }, nil +} + +func (app App) Init() tea.Cmd { + return nil +} + +func (app App) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "q", "ctrl+c", "esc": + return app, tea.Quit + default: + var cmd tea.Cmd + app.viewport, cmd = app.viewport.Update(msg) + return app, cmd + } + case tea.MouseMsg: + if msg.Button == tea.MouseButtonWheelUp { + app.viewport.LineUp(1) + } + if msg.Button == tea.MouseButtonWheelDown { + app.viewport.LineDown(1) + } + return app, nil + default: + return app, nil + } +} + +func (app App) View() string { + return app.viewport.View() + app.helpView() +} + +func (app App) helpView() string { + return helpStyle("\n ↑/↓/mouse wheel - navigate esc/q/ctrl+c - quit\n") +} diff --git a/internal/tui/help/styles.go b/internal/tui/help/styles.go new file mode 100644 index 000000000..4f6db21e5 --- /dev/null +++ b/internal/tui/help/styles.go @@ -0,0 +1,247 @@ +package help + +import "github.com/charmbracelet/glamour/ansi" + +func boolPtr(b bool) *bool { return &b } +func stringPtr(s string) *string { return &s } +func uintPtr(u uint) *uint { return &u } + +const ( + defaultListIndent = 2 + defaultMargin = 2 +) + +var ( + atmosHelpStyleConfig = ansi.StyleConfig{ + Document: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + BlockPrefix: "\n", + BlockSuffix: "\n", + Color: stringPtr("252"), + }, + Margin: uintPtr(defaultMargin), + }, + BlockQuote: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Color: stringPtr("#f1fa8c"), + Italic: boolPtr(true), + }, + Indent: uintPtr(1), + IndentToken: stringPtr("│ "), + }, + List: ansi.StyleList{ + LevelIndent: defaultListIndent, + }, + Heading: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + BlockSuffix: "\n", + Color: stringPtr("39"), + Bold: boolPtr(true), + }, + }, + H1: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: " ", + Suffix: " ", + Color: stringPtr("228"), + BackgroundColor: stringPtr("63"), + Bold: boolPtr(true), + }, + }, + H2: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: " ", + Suffix: " ", + Color: stringPtr("228"), + BackgroundColor: stringPtr("63"), + Bold: boolPtr(true), + }, + }, + H3: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: " ", + Suffix: " ", + Color: stringPtr("228"), + BackgroundColor: stringPtr("63"), + Bold: boolPtr(true), + }, + }, + H4: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: " ", + Suffix: " ", + Color: stringPtr("228"), + BackgroundColor: stringPtr("63"), + Bold: boolPtr(true), + }, + }, + H5: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: " ", + Suffix: " ", + Color: stringPtr("228"), + BackgroundColor: stringPtr("63"), + Bold: boolPtr(true), + }, + }, + H6: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: " ", + Suffix: " ", + Color: stringPtr("228"), + BackgroundColor: stringPtr("63"), + Bold: boolPtr(false), + }, + }, + Strikethrough: ansi.StylePrimitive{ + CrossedOut: boolPtr(true), + }, + Emph: ansi.StylePrimitive{ + Italic: boolPtr(true), + }, + Strong: ansi.StylePrimitive{ + Bold: boolPtr(true), + }, + HorizontalRule: ansi.StylePrimitive{ + Color: stringPtr("240"), + Format: "\n--------\n", + }, + Item: ansi.StylePrimitive{ + BlockPrefix: "• ", + }, + Enumeration: ansi.StylePrimitive{ + BlockPrefix: ". ", + }, + Task: ansi.StyleTask{ + StylePrimitive: ansi.StylePrimitive{}, + Ticked: "[✓] ", + Unticked: "[ ] ", + }, + Link: ansi.StylePrimitive{ + Color: stringPtr("30"), + Underline: boolPtr(true), + }, + LinkText: ansi.StylePrimitive{ + Color: stringPtr("35"), + Bold: boolPtr(true), + }, + Image: ansi.StylePrimitive{ + Color: stringPtr("212"), + Underline: boolPtr(true), + }, + ImageText: ansi.StylePrimitive{ + Color: stringPtr("243"), + Format: "Image: {{.text}} →", + }, + Code: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: "", + Suffix: "", + Color: stringPtr("#3ec1d5"), + BackgroundColor: stringPtr("0"), + }, + }, + CodeBlock: ansi.StyleCodeBlock{ + StyleBlock: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Color: stringPtr("244"), + }, + Margin: uintPtr(defaultMargin), + }, + Chroma: &ansi.Chroma{ + Text: ansi.StylePrimitive{ + Color: stringPtr("#C4C4C4"), + }, + Error: ansi.StylePrimitive{ + Color: stringPtr("#F1F1F1"), + BackgroundColor: stringPtr("#F05B5B"), + }, + Comment: ansi.StylePrimitive{ + Color: stringPtr("#676767"), + }, + CommentPreproc: ansi.StylePrimitive{ + Color: stringPtr("#FF875F"), + }, + Keyword: ansi.StylePrimitive{ + Color: stringPtr("#00AAFF"), + }, + KeywordReserved: ansi.StylePrimitive{ + Color: stringPtr("#FF5FD2"), + }, + KeywordNamespace: ansi.StylePrimitive{ + Color: stringPtr("#FF5F87"), + }, + KeywordType: ansi.StylePrimitive{ + Color: stringPtr("#6E6ED8"), + }, + Operator: ansi.StylePrimitive{ + Color: stringPtr("#EF8080"), + }, + Punctuation: ansi.StylePrimitive{ + Color: stringPtr("#E8E8A8"), + }, + Name: ansi.StylePrimitive{ + Color: stringPtr("#C4C4C4"), + }, + NameBuiltin: ansi.StylePrimitive{ + Color: stringPtr("#FF8EC7"), + }, + NameTag: ansi.StylePrimitive{ + Color: stringPtr("#B083EA"), + }, + NameAttribute: ansi.StylePrimitive{ + Color: stringPtr("#7A7AE6"), + }, + NameClass: ansi.StylePrimitive{ + Color: stringPtr("#F1F1F1"), + Underline: boolPtr(true), + Bold: boolPtr(true), + }, + NameDecorator: ansi.StylePrimitive{ + Color: stringPtr("#FFFF87"), + }, + NameFunction: ansi.StylePrimitive{ + Color: stringPtr("#00D787"), + }, + LiteralNumber: ansi.StylePrimitive{ + Color: stringPtr("#6EEFC0"), + }, + LiteralString: ansi.StylePrimitive{ + Color: stringPtr("#C69669"), + }, + LiteralStringEscape: ansi.StylePrimitive{ + Color: stringPtr("#AFFFD7"), + }, + GenericDeleted: ansi.StylePrimitive{ + Color: stringPtr("#FD5B5B"), + }, + GenericEmph: ansi.StylePrimitive{ + Italic: boolPtr(true), + }, + GenericInserted: ansi.StylePrimitive{ + Color: stringPtr("#00D787"), + }, + GenericStrong: ansi.StylePrimitive{ + Bold: boolPtr(true), + }, + GenericSubheading: ansi.StylePrimitive{ + Color: stringPtr("#777777"), + }, + Background: ansi.StylePrimitive{ + BackgroundColor: stringPtr("#373737"), + }, + }, + }, + Table: ansi.StyleTable{ + StyleBlock: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{}, + }, + CenterSeparator: stringPtr("┼"), + ColumnSeparator: stringPtr("│"), + RowSeparator: stringPtr("─"), + }, + DefinitionDescription: ansi.StylePrimitive{ + BlockPrefix: "\n🠶 ", + }, + } +) diff --git a/internal/tui/help/tui.go b/internal/tui/help/tui.go new file mode 100644 index 000000000..3128039fe --- /dev/null +++ b/internal/tui/help/tui.go @@ -0,0 +1,22 @@ +package help + +import ( + tea "github.com/charmbracelet/bubbletea" +) + +// Execute starts the help TUI +func Execute(content string) (*App, error) { + app, err := NewApp(content) + if err != nil { + return nil, err + } + + p := tea.NewProgram(app, tea.WithMouseCellMotion()) + + _, err = p.Run() + if err != nil { + return nil, err + } + + return app, nil +} diff --git a/internal/tui/workflow/tui.go b/internal/tui/workflow/tui.go index b00f95678..8fa983ca1 100644 --- a/internal/tui/workflow/tui.go +++ b/internal/tui/workflow/tui.go @@ -1,10 +1,10 @@ package workflow import ( - "github.com/cloudposse/atmos/pkg/schema" - tea "github.com/charmbracelet/bubbletea" mouseZone "github.com/lrstanley/bubblezone" + + "github.com/cloudposse/atmos/pkg/schema" ) // Execute starts the TUI app and returns the selected items from the views diff --git a/website/docs/cli/commands/helmfile/usage.mdx b/website/docs/cli/commands/helmfile/usage.mdx index c36df0991..4429d4e21 100644 --- a/website/docs/cli/commands/helmfile/usage.mdx +++ b/website/docs/cli/commands/helmfile/usage.mdx @@ -47,6 +47,12 @@ In addition, the `component` argument and `stack` flag are required to generate Run `atmos helmfile --help` to see all the available options ::: +
+ +![`atmos helmfile --help` command](/img/cli/help/atmos-helmfile-help-command.png) + +
+ ## Examples ```shell diff --git a/website/docs/cli/commands/terraform/terraform-clean.mdx b/website/docs/cli/commands/terraform/terraform-clean.mdx index 5b7937bea..f01f16713 100644 --- a/website/docs/cli/commands/terraform/terraform-clean.mdx +++ b/website/docs/cli/commands/terraform/terraform-clean.mdx @@ -27,6 +27,12 @@ atmos terraform clean -s [--skip-lock-file] Run `atmos terraform clean --help` to see all the available options ::: +
+ +![`atmos terraform clean --help` command](/img/cli/help/atmos-terraform-clean-help-command.png) + +
+ ## Examples ```shell diff --git a/website/docs/cli/commands/terraform/terraform-deploy.mdx b/website/docs/cli/commands/terraform/terraform-deploy.mdx index 8eb8181b6..df5fc1083 100644 --- a/website/docs/cli/commands/terraform/terraform-deploy.mdx +++ b/website/docs/cli/commands/terraform/terraform-deploy.mdx @@ -41,6 +41,12 @@ See [all flags](#flags). Run `atmos terraform deploy --help` to see all the available options ::: +
+ +![`atmos terraform deploy --help` command](/img/cli/help/atmos-terraform-deploy-help-command.png) + +
+ ## Examples ### Simple Example @@ -95,7 +101,7 @@ atmos terraform deploy test/test-component-override-3 -s tenant1-ue2-dev :::note The `atmos terraform deploy` command supports all native `terraform apply` options described -in [Terraform apply options](https://developer.hashicorp.com/terraform/cli/commands/apply#apply-options), with the exception that a planfile argument +in [Terraform apply options](https://developer.hashicorp.com/terraform/cli/commands/apply#apply-options), with the exception that the `PLAN` argument can't be provided on the command line. To use a previously generated planfile, use the `--from-plan` or `--planfile` command-line flags ::: diff --git a/website/docs/cli/commands/terraform/terraform-shell.mdx b/website/docs/cli/commands/terraform/terraform-shell.mdx index 7fe8d7609..166671cec 100644 --- a/website/docs/cli/commands/terraform/terraform-shell.mdx +++ b/website/docs/cli/commands/terraform/terraform-shell.mdx @@ -3,13 +3,15 @@ title: atmos terraform shell sidebar_label: shell sidebar_class_name: command id: shell -description: This command starts a new `SHELL` configured with the environment for an Atmos component in a stack to allow execution of all native terraform commands inside the shell without using any atmos-specific arguments and flags. This may by helpful to debug a component without going through Atmos. +description: This command starts a new `SHELL` configured with the environment for an Atmos component in a stack to allow execution of all native Terraform commands inside the shell without using any Atmos-specific arguments and flags. This may be helpful to debug a component without going through Atmos. --- import Screengrab from '@site/src/components/Screengrab' :::note Purpose -This command starts a new `SHELL` configured with the environment for an Atmos component in a Stack to allow executing all native terraform commands -inside the shell without using any atmos-specific arguments and flags. +This command starts a new `SHELL` configured with the environment for an Atmos component in a stack to allow executing all native Terraform commands +inside the shell without using any Atmos-specific arguments and flags. + +This may be helpful to debug a component without going through Atmos. ::: @@ -43,6 +45,12 @@ The command does the following: Run `atmos terraform shell --help` to see all the available options ::: +
+ +![`atmos terraform shell --help` command](/img/cli/help/atmos-terraform-shell-help-command.png) + +
+ ## Examples ```shell diff --git a/website/docs/cli/commands/terraform/usage.mdx b/website/docs/cli/commands/terraform/usage.mdx index 096909fee..c23271e0b 100644 --- a/website/docs/cli/commands/terraform/usage.mdx +++ b/website/docs/cli/commands/terraform/usage.mdx @@ -88,6 +88,12 @@ HCL-based domain-specific language and its interpreter. Atmos works with [OpenTo Run `atmos terraform --help` to see all the available options ::: +
+ +![`atmos terraform --help` command](/img/cli/help/atmos-terraform-help-command.png) + +
+ ## Examples ```shell diff --git a/website/docs/integrations/atlantis.mdx b/website/docs/integrations/atlantis.mdx index 406ca475f..c216e5dba 100644 --- a/website/docs/integrations/atlantis.mdx +++ b/website/docs/integrations/atlantis.mdx @@ -673,7 +673,7 @@ on: branches: [ main ] env: - ATMOS_VERSION: 1.84.0 + ATMOS_VERSION: 1.85.0 ATMOS_CLI_CONFIG_PATH: ./ jobs: diff --git a/website/docs/integrations/github-actions/setup-atmos.mdx b/website/docs/integrations/github-actions/setup-atmos.mdx index f4fafa29e..5912b7dc6 100644 --- a/website/docs/integrations/github-actions/setup-atmos.mdx +++ b/website/docs/integrations/github-actions/setup-atmos.mdx @@ -33,6 +33,6 @@ jobs: uses: cloudposse/github-action-setup-atmos with: # Make sure to pin to the latest version of atmos - atmos_version: 1.84.0 + atmos_version: 1.85.0 ``` diff --git a/website/static/img/cli/help/atmos-helmfile-help-command.png b/website/static/img/cli/help/atmos-helmfile-help-command.png new file mode 100644 index 000000000..570bec001 Binary files /dev/null and b/website/static/img/cli/help/atmos-helmfile-help-command.png differ diff --git a/website/static/img/cli/help/atmos-terraform-clean-help-command.png b/website/static/img/cli/help/atmos-terraform-clean-help-command.png new file mode 100644 index 000000000..58d953f3c Binary files /dev/null and b/website/static/img/cli/help/atmos-terraform-clean-help-command.png differ diff --git a/website/static/img/cli/help/atmos-terraform-deploy-help-command.png b/website/static/img/cli/help/atmos-terraform-deploy-help-command.png new file mode 100644 index 000000000..ac834299c Binary files /dev/null and b/website/static/img/cli/help/atmos-terraform-deploy-help-command.png differ diff --git a/website/static/img/cli/help/atmos-terraform-help-command.png b/website/static/img/cli/help/atmos-terraform-help-command.png new file mode 100644 index 000000000..d50748aa6 Binary files /dev/null and b/website/static/img/cli/help/atmos-terraform-help-command.png differ diff --git a/website/static/img/cli/help/atmos-terraform-shell-help-command.png b/website/static/img/cli/help/atmos-terraform-shell-help-command.png new file mode 100644 index 000000000..618005a87 Binary files /dev/null and b/website/static/img/cli/help/atmos-terraform-shell-help-command.png differ