Skip to content

Commit

Permalink
Merge branch 'main' into snapshotting
Browse files Browse the repository at this point in the history
  • Loading branch information
osterman authored Jan 16, 2025
2 parents 68dc2a5 + 20098bf commit c9e81da
Show file tree
Hide file tree
Showing 22 changed files with 556 additions and 58 deletions.
16 changes: 11 additions & 5 deletions atmos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,17 @@ settings:

# Terminal settings for displaying content
terminal:
max_width: 120 # Maximum width for terminal output
pager: true # Use pager for long output
timestamps: false # Show timestamps in logs
colors: true # Enable colored output
unicode: true # Use unicode characters
max_width: 120 # Maximum width for terminal output
pager: true # Pager setting for all terminal output
colors: true # Enable colored output
unicode: true # Use unicode characters

syntax_highlighting:
enabled: true
formatter: terminal # Output formatter (e.g., terminal, html)
theme: dracula # Highlighting theme
line_numbers: true # Display line numbers
wrap: false # Wrap long lines

# Markdown element styling
markdown:
Expand Down
8 changes: 4 additions & 4 deletions cmd/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ var docsCmd = &cobra.Command{
u.LogErrorAndExit(schema.AtmosConfiguration{}, err)
}

usePager := atmosConfig.Settings.Terminal.Pager
if !usePager && atmosConfig.Settings.Docs.Pagination {
usePager = atmosConfig.Settings.Docs.Pagination
pager := atmosConfig.Settings.Terminal.Pager
if !pager && atmosConfig.Settings.Docs.Pagination {
pager = atmosConfig.Settings.Docs.Pagination
u.LogWarning(atmosConfig, "'settings.docs.pagination' is deprecated and will be removed in a future version. Please use 'settings.terminal.pager' instead")
}

if err := u.DisplayDocs(componentDocs, usePager); err != nil {
if err := u.DisplayDocs(componentDocs, pager); err != nil {
u.LogErrorAndExit(schema.AtmosConfiguration{}, fmt.Errorf("failed to display documentation: %w", err))
}

Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/alecthomas/chroma v0.10.0
github.com/arsham/figurine v1.3.0
github.com/aws/aws-sdk-go-v2 v1.32.8
github.com/aws/aws-sdk-go-v2/config v1.28.9
github.com/aws/aws-sdk-go-v2/config v1.28.10
github.com/aws/aws-sdk-go-v2/service/ssm v1.56.4
github.com/bmatcuk/doublestar/v4 v4.7.1
github.com/charmbracelet/bubbles v0.20.0
Expand Down Expand Up @@ -86,7 +86,7 @@ require (
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aws/aws-sdk-go v1.44.206 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.50 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.51 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23 // indirect
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.14 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27 // indirect
Expand All @@ -100,7 +100,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/s3 v1.26.10 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.24.9 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.6 // indirect
github.com/aws/smithy-go v1.22.1 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -746,12 +746,12 @@ github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 h1:SdK4Ppk5IzLs64ZM
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1/go.mod h1:n8Bs1ElDD2wJ9kCRTczA83gYbBmjSwZp3umc6zF4EeM=
github.com/aws/aws-sdk-go-v2/config v1.15.3/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg=
github.com/aws/aws-sdk-go-v2/config v1.15.9/go.mod h1:rv/l/TbZo67kp99v/3Kb0qV6Fm1KEtKyruEV2GvVfgs=
github.com/aws/aws-sdk-go-v2/config v1.28.9 h1:7/P2J1MGkava+2c9Xlk7CTPTpGqFAOaM4874wJsGi4Q=
github.com/aws/aws-sdk-go-v2/config v1.28.9/go.mod h1:ce/HX8tHlIh4VTPaLz/aQIvA5+/rUghFy+nGMrXHQ9U=
github.com/aws/aws-sdk-go-v2/config v1.28.10 h1:fKODZHfqQu06pCzR69KJ3GuttraRJkhlC8g80RZ0Dfg=
github.com/aws/aws-sdk-go-v2/config v1.28.10/go.mod h1:PvdxRYZ5Um9QMq9PQ0zHHNdtKK+he2NHtFCUFMXWXeg=
github.com/aws/aws-sdk-go-v2/credentials v1.11.2/go.mod h1:j8YsY9TXTm31k4eFhspiQicfXPLZ0gYXA50i4gxPE8g=
github.com/aws/aws-sdk-go-v2/credentials v1.12.4/go.mod h1:7g+GGSp7xtR823o1jedxKmqRZGqLdoHQfI4eFasKKxs=
github.com/aws/aws-sdk-go-v2/credentials v1.17.50 h1:63pBzfU7EG4RbMMVRv4Hgm34cIaPXICCnHojKdPbTR0=
github.com/aws/aws-sdk-go-v2/credentials v1.17.50/go.mod h1:m5ThO5y87w0fiAHBt9cYXS5BVsebOeJEFCGUQeZZYLw=
github.com/aws/aws-sdk-go-v2/credentials v1.17.51 h1:F/9Sm6Y6k4LqDesZDPJCLxQGXNNHd/ZtJiWd0lCZKRk=
github.com/aws/aws-sdk-go-v2/credentials v1.17.51/go.mod h1:TKbzCHm43AoPyA+iLGGcruXd4AFhF8tOmLex2R9jWNQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.5/go.mod h1:WAPnuhG5IQ/i6DETFl5NmX3kKqCzw7aau9NHAGcm4QE=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23 h1:IBAoD/1d8A8/1aA8g4MBVtTRHhXRiNAgwdbo/xRM2DI=
Expand Down Expand Up @@ -804,8 +804,8 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8 h1:6dBT1Lz8fK11m22R+AqfRsFn
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8/go.mod h1:/kiBvRQXBc6xeJTYzhSdGvJ5vm1tjaDEjH+MSeRJnlY=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.6/go.mod h1:rP1rEOKAGZoXp4iGDxSXFvODAtXpm34Egf0lL0eshaQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.5 h1:URp6kw3vHAnuU9pgP4K1SohwWLDzgtqA/qgeBfgBxn0=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.5/go.mod h1:+8h7PZb3yY5ftmVLD7ocEoE98hdc8PoKS0H3wfx1dlc=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.6 h1:VwhTrsTuVn52an4mXx29PqRzs2Dvu921NpGk7y43tAM=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.6/go.mod h1:+8h7PZb3yY5ftmVLD7ocEoE98hdc8PoKS0H3wfx1dlc=
github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
Expand Down
2 changes: 1 addition & 1 deletion internal/exec/vendor_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func (m *modelVendor) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
version := grayColor.Render(version)
return m, tea.Sequence(
tea.Printf("%s %s %s", mark, pkg.name, version),
tea.Printf("%s %s %s %s", mark, pkg.name, version, errMsg),
tea.Quit,
)
}
Expand Down
11 changes: 10 additions & 1 deletion internal/exec/vendor_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,16 @@ func ReadAndProcessVendorConfigFile(
// Check if it's a directory
fileInfo, err := os.Stat(foundVendorConfigFile)
if err != nil {
return vendorConfig, false, "", err
if os.IsNotExist(err) {
// File does not exist
return vendorConfig, false, "", fmt.Errorf("Vendoring is not configured. To set up vendoring, please see https://atmos.tools/core-concepts/vendor/")
}
if os.IsPermission(err) {
// Permission error
return vendorConfig, false, "", fmt.Errorf("Permission denied when accessing '%s'. Please check the file permissions.", foundVendorConfigFile)
}
// Other errors
return vendorConfig, false, "", fmt.Errorf("An error occurred while accessing the vendoring configuration: %w", err)
}

var configFiles []string
Expand Down
6 changes: 3 additions & 3 deletions internal/tui/templates/templater.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ func SetCustomUsageFunc(cmd *cobra.Command) error {
return nil
}

// getTerminalWidth returns the width of the terminal, defaulting to 80 if it cannot be determined
func getTerminalWidth() int {
// GetTerminalWidth returns the width of the terminal, defaulting to 80 if it cannot be determined
func GetTerminalWidth() int {
defaultWidth := 80
screenWidth := defaultWidth

Expand All @@ -156,7 +156,7 @@ func getTerminalWidth() int {
// WrappedFlagUsages formats the flag usage string to fit within the terminal width
func WrappedFlagUsages(f *pflag.FlagSet) string {
var builder strings.Builder
width := getTerminalWidth()
width := GetTerminalWidth()
printer, err := NewHelpFlagPrinter(&builder, uint(width), f)
if err != nil {
// If we can't create the printer, return empty string
Expand Down
18 changes: 18 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/pkg/errors"
"github.com/spf13/viper"

"github.com/cloudposse/atmos/internal/tui/templates"
"github.com/cloudposse/atmos/pkg/schema"
"github.com/cloudposse/atmos/pkg/ui/theme"
u "github.com/cloudposse/atmos/pkg/utils"
Expand Down Expand Up @@ -53,6 +54,23 @@ var (
UseEKS: true,
},
},
Settings: schema.AtmosSettings{
ListMergeStrategy: "replace",
Terminal: schema.Terminal{
MaxWidth: templates.GetTerminalWidth(),
Pager: true,
Colors: true,
Unicode: true,
SyntaxHighlighting: schema.SyntaxHighlighting{
Enabled: true,
Formatter: "terminal",
Theme: "dracula",
HighlightedOutputPager: true,
LineNumbers: true,
Wrap: false,
},
},
},
Workflows: schema.Workflows{
BasePath: "stacks/workflows",
},
Expand Down
16 changes: 16 additions & 0 deletions pkg/config/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

"github.com/charmbracelet/log"
"github.com/cloudposse/atmos/pkg/logger"
"github.com/cloudposse/atmos/pkg/schema"
"github.com/cloudposse/atmos/pkg/store"
u "github.com/cloudposse/atmos/pkg/utils"
Expand Down Expand Up @@ -358,6 +359,11 @@ func processEnvVars(atmosConfig *schema.AtmosConfiguration) error {
logsLevel := os.Getenv("ATMOS_LOGS_LEVEL")
if len(logsLevel) > 0 {
u.LogTrace(*atmosConfig, fmt.Sprintf("Found ENV var ATMOS_LOGS_LEVEL=%s", logsLevel))
// Validate the log level before setting it
if _, err := logger.ParseLogLevel(logsLevel); err != nil {
return err
}
// Only set the log level if validation passes
atmosConfig.Logs.Level = logsLevel
}

Expand Down Expand Up @@ -396,6 +402,12 @@ func checkConfig(atmosConfig schema.AtmosConfiguration) error {
return errors.New("at least one path must be provided in 'stacks.included_paths' config or ATMOS_STACKS_INCLUDED_PATHS' ENV variable")
}

if len(atmosConfig.Logs.Level) > 0 {
if _, err := logger.ParseLogLevel(atmosConfig.Logs.Level); err != nil {
return err
}
}

return nil
}

Expand Down Expand Up @@ -473,6 +485,10 @@ func processCommandLineArgs(atmosConfig *schema.AtmosConfiguration, configAndSta
u.LogTrace(*atmosConfig, fmt.Sprintf("Using command line argument '%s' as path to Atmos JSON Schema", configAndStacksInfo.AtmosManifestJsonSchema))
}
if len(configAndStacksInfo.LogsLevel) > 0 {
if _, err := logger.ParseLogLevel(configAndStacksInfo.LogsLevel); err != nil {
return err
}
// Only set the log level if validation passes
atmosConfig.Logs.Level = configAndStacksInfo.LogsLevel
u.LogTrace(*atmosConfig, fmt.Sprintf("Using command line argument '%s=%s'", LogsLevelFlag, configAndStacksInfo.LogsLevel))
}
Expand Down
56 changes: 30 additions & 26 deletions pkg/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ const (
LogLevelWarning LogLevel = "Warning"
)

// logLevelOrder defines the order of log levels from most verbose to least verbose
var logLevelOrder = map[LogLevel]int{
LogLevelTrace: 0,
LogLevelDebug: 1,
LogLevelInfo: 2,
LogLevelWarning: 3,
LogLevelOff: 4,
}

type Logger struct {
LogLevel LogLevel
File string
Expand All @@ -45,18 +54,14 @@ func ParseLogLevel(logLevel string) (LogLevel, error) {
return LogLevelInfo, nil
}

switch LogLevel(logLevel) { // Convert logLevel to type LogLevel
case LogLevelTrace:
return LogLevelTrace, nil
case LogLevelDebug:
return LogLevelDebug, nil
case LogLevelInfo:
return LogLevelInfo, nil
case LogLevelWarning:
return LogLevelWarning, nil
default:
return LogLevelInfo, fmt.Errorf("invalid log level '%s'. Supported log levels are Trace, Debug, Info, Warning, Off", logLevel)
validLevels := []LogLevel{LogLevelTrace, LogLevelDebug, LogLevelInfo, LogLevelWarning, LogLevelOff}
for _, level := range validLevels {
if LogLevel(logLevel) == level {
return level, nil
}
}

return "", fmt.Errorf("Error: Invalid log level '%s'. Valid options are: %v", logLevel, validLevels)
}

func (l *Logger) log(logColor *color.Color, message string) {
Expand Down Expand Up @@ -104,7 +109,7 @@ func (l *Logger) SetLogLevel(logLevel LogLevel) error {
}

func (l *Logger) Error(err error) {
if err != nil {
if err != nil && l.LogLevel != LogLevelOff {
_, err2 := theme.Colors.Error.Fprintln(color.Error, err.Error()+"\n")
if err2 != nil {
color.Red("Error logging the error:")
Expand All @@ -115,35 +120,34 @@ func (l *Logger) Error(err error) {
}
}

// isLevelEnabled checks if a given log level should be enabled based on the logger's current level
func (l *Logger) isLevelEnabled(level LogLevel) bool {
if l.LogLevel == LogLevelOff {
return false
}
return logLevelOrder[level] >= logLevelOrder[l.LogLevel]
}

func (l *Logger) Trace(message string) {
if l.LogLevel == LogLevelTrace {
if l.isLevelEnabled(LogLevelTrace) {
l.log(theme.Colors.Info, message)
}
}

func (l *Logger) Debug(message string) {
if l.LogLevel == LogLevelTrace ||
l.LogLevel == LogLevelDebug {

if l.isLevelEnabled(LogLevelDebug) {
l.log(theme.Colors.Info, message)
}
}

func (l *Logger) Info(message string) {
if l.LogLevel == LogLevelTrace ||
l.LogLevel == LogLevelDebug ||
l.LogLevel == LogLevelInfo {

l.log(theme.Colors.Default, message)
if l.isLevelEnabled(LogLevelInfo) {
l.log(theme.Colors.Info, message)
}
}

func (l *Logger) Warning(message string) {
if l.LogLevel == LogLevelTrace ||
l.LogLevel == LogLevelDebug ||
l.LogLevel == LogLevelInfo ||
l.LogLevel == LogLevelWarning {

if l.isLevelEnabled(LogLevelWarning) {
l.log(theme.Colors.Warning, message)
}
}
20 changes: 15 additions & 5 deletions pkg/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,21 @@ type AtmosConfiguration struct {
}

type Terminal struct {
MaxWidth int `yaml:"max_width" json:"max_width" mapstructure:"max_width"`
Pager bool `yaml:"pager" json:"pager" mapstructure:"pager"`
Timestamps bool `yaml:"timestamps" json:"timestamps" mapstructure:"timestamps"`
Colors bool `yaml:"colors" json:"colors" mapstructure:"colors"`
Unicode bool `yaml:"unicode" json:"unicode" mapstructure:"unicode"`
MaxWidth int `yaml:"max_width" json:"max_width" mapstructure:"max_width"`
Pager bool `yaml:"pager" json:"pager" mapstructure:"pager"`
Colors bool `yaml:"colors" json:"colors" mapstructure:"colors"`
Unicode bool `yaml:"unicode" json:"unicode" mapstructure:"unicode"`
SyntaxHighlighting SyntaxHighlighting `yaml:"syntax_highlighting" json:"syntax_highlighting" mapstructure:"syntax_highlighting"`
}

type SyntaxHighlighting struct {
Enabled bool `yaml:"enabled" json:"enabled" mapstructure:"enabled"`
Lexer string `yaml:"lexer" json:"lexer" mapstructure:"lexer"`
Formatter string `yaml:"formatter" json:"formatter" mapstructure:"formatter"`
Theme string `yaml:"theme" json:"theme" mapstructure:"theme"`
HighlightedOutputPager bool `yaml:"pager" json:"pager" mapstructure:"pager"`
LineNumbers bool `yaml:"line_numbers" json:"line_numbers" mapstructure:"line_numbers"`
Wrap bool `yaml:"wrap" json:"wrap" mapstructure:"wrap"`
}

type AtmosSettings struct {
Expand Down
17 changes: 17 additions & 0 deletions pkg/utils/config_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package utils

import "github.com/cloudposse/atmos/pkg/schema"

// ExtractAtmosConfig extracts the Atmos configuration from any data type.
// It handles both direct AtmosConfiguration instances and pointers to AtmosConfiguration.
// If the data is neither, it returns an empty configuration.
func ExtractAtmosConfig(data any) schema.AtmosConfiguration {
switch v := data.(type) {
case schema.AtmosConfiguration:
return v
case *schema.AtmosConfiguration:
return *v
default:
return schema.AtmosConfiguration{}
}
}
Loading

0 comments on commit c9e81da

Please sign in to comment.