Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colorize Atmos Describe Commands when TTY attached #907

Merged
merged 8 commits into from
Jan 6, 2025
Merged

Conversation

Cerebrovinny
Copy link
Collaborator

@Cerebrovinny Cerebrovinny commented Jan 3, 2025

what

Colorize output when we attach TTY

Before:
Screenshot 2025-01-03 at 16 15 15
Screenshot 2025-01-03 at 16 15 43

After
Example 1
Screenshot 2025-01-03 at 16 17 55

Example 2
Screenshot 2025-01-03 at 16 19 04

references

https://github.com/alecthomas/chroma

Summary by CodeRabbit

  • New Features

    • Added terminal configuration options for syntax highlighting.
    • Introduced customizable settings for YAML and JSON output display.
    • Enabled line numbers, color schemes, and pagination for terminal output.
  • Documentation

    • Created comprehensive documentation for terminal configuration settings.
    • Explained syntax highlighting options and usage in Atmos CLI.

Copy link

mergify bot commented Jan 3, 2025

Important

Cloud Posse Engineering Team Review Required

This pull request modifies files that require Cloud Posse's review. Please be patient, and a core maintainer will review your changes.

To expedite this process, reach out to us on Slack in the #pr-reviews channel.

@osterman osterman added the minor New features that do not break anything label Jan 3, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 3, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 3, 2025
@Cerebrovinny Cerebrovinny marked this pull request as ready for review January 3, 2025 22:32
@Cerebrovinny Cerebrovinny requested a review from a team as a code owner January 3, 2025 22:32
Copy link
Contributor

coderabbitai bot commented Jan 3, 2025

📝 Walkthrough

Walkthrough

This pull request introduces comprehensive syntax highlighting capabilities for the Atmos CLI, enhancing terminal output readability. The changes span multiple files, including configuration schema, utility functions, and documentation. The implementation utilizes the Chroma library to provide configurable syntax highlighting for YAML and JSON outputs, with customizable options like lexer, style, and formatting.

Changes

File Change Summary
atmos.yaml Added new terminal section with syntax_highlighting configuration
pkg/config/config.go Enhanced defaultCliConfig with new Settings field for terminal configurations
pkg/schema/schema.go Restructured configuration types; added TerminalSettings and SyntaxHighlightingSettings
pkg/utils/highlight_utils.go New utility for syntax highlighting with configurable settings
pkg/utils/json_utils.go Modified PrintAsJSON to support configuration-based highlighting
pkg/utils/yaml_utils.go Updated PrintAsYAML with highlighting capabilities
website/docs/cli/configuration/terminal.mdx New documentation for terminal configuration options

Assessment against linked issues

Objective Addressed Explanation
Colorize output when TTY attached [DEV-2876]
Support configurable highlighting options [DEV-2876]
Fallback to plain text when piped [DEV-2876]

Possibly related PRs

  • Glamorous implementation #853: The changes in this PR introduce a new terminal section in atmos.yaml that includes parameters for terminal output, which aligns with the main PR's addition of a terminal subsection under settings in the same configuration file. Both PRs enhance the configuration options related to terminal settings.

Suggested reviewers

  • osterman
  • aknysh
  • Gowiem

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or @auto-summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @auto-title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
pkg/utils/yaml_utils.go (1)

44-50: Consider logging highlight errors
You are silently falling back to plain YAML on errors. Logging the error could help troubleshooting.

 if err != nil {
+   LogWarning(fmt.Sprintf("Highlight error: %v", err))
    PrintMessage(y)
    return nil
 }
pkg/schema/schema.go (1)

45-52: SyntaxHighlightingSettings structure
Comprehensive fields. Consider if some fields might evolve into their own sub-struct for more flexibility.

pkg/utils/json_utils.go (1)

36-43: Fallback to plain JSON
Using plain text on highlight errors matches the YAML approach. Consider logging these errors.

 if err != nil {
+   LogWarning(fmt.Sprintf("Highlight error: %v", err))
    PrintMessage(prettyJSON.String())
    return nil
 }
website/docs/cli/configuration/terminal.mdx (4)

23-41: Consider adding environment variable override information.

While the configuration example is clear, adding information about corresponding environment variables would help users who prefer environment-based configuration.

Add environment variable information like this:

 settings:
   terminal:
     syntax_highlighting:
-      enabled: true         # Enable/disable syntax highlighting
+      enabled: true         # Enable/disable syntax highlighting (ATMOS_TERMINAL_SYNTAX_HIGHLIGHTING_ENABLED)

63-73: Enhance style options documentation, brave documenter!

The style options section could benefit from more comprehensive information about available themes and their use cases.

Consider expanding the style options section like this:

     Color scheme for syntax highlighting. Available options include:
     <ul>
-      <li>`vim`</li>
-      <li>`monokai`</li>
-      <li>`github`</li>
-      <li>`dracula`</li>
+      <li>`vim` - Classic Vim-like highlighting</li>
+      <li>`monokai` - High contrast theme, great for dark backgrounds</li>
+      <li>`github` - GitHub's syntax highlighting theme</li>
+      <li>`dracula` - Dark theme optimized for readability</li>
       <li>And many other standard styles</li>

90-109: Add example outputs for better clarity.

Consider showing example outputs to help users understand what to expect when using these commands.

Add example outputs like this:

 # Display config in YAML format with syntax highlighting
 atmos describe config -f yaml
+
+# Example output:
+# settings:
+#   terminal:
+#     syntax_highlighting:
+#       enabled: true

133-135: Add performance considerations for theme selection.

Consider adding a note about performance implications of different themes, especially in large outputs.

Add performance note like this:

 ## Supported Themes
 
-Atmos supports a wide range of themes for syntax highlighting. You can find the full list of supported themes [here](https://xyproto.github.io/splash/docs/).
+Atmos supports a wide range of themes for syntax highlighting. You can find the full list of supported themes [here](https://xyproto.github.io/splash/docs/). Note that some themes may have different performance characteristics when highlighting large outputs.
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2763512 and 8ae2aad.

📒 Files selected for processing (7)
  • atmos.yaml (1 hunks)
  • pkg/config/config.go (4 hunks)
  • pkg/schema/schema.go (2 hunks)
  • pkg/utils/highlight_utils.go (1 hunks)
  • pkg/utils/json_utils.go (1 hunks)
  • pkg/utils/yaml_utils.go (1 hunks)
  • website/docs/cli/configuration/terminal.mdx (1 hunks)
🔇 Additional comments (18)
pkg/utils/yaml_utils.go (1)

34-43: Check fallback for non-AtmosConfiguration data
These lines gracefully handle AtmosConfiguration types. For other data types, the code proceeds without highlighting. If you want to highlight any arbitrary data, consider a separate fallback.

pkg/config/config.go (4)

91-105: Default syntax highlighting config
This default configuration looks helpful. Confirm that this aligns with all project needs before proceeding.


129-139: Confirmed loading defaults
Loading defaultCliConfig as a base config is consistent and clear.


292-316: Selective overriding
The logic for partial initialization of Settings fields is neat. Good approach for layering config.


429-479: Preserving nested values
These lines smartly preserve nested settings in Viper when merging. Consider adding tests for corner cases with deeply nested fields.

pkg/schema/schema.go (5)

19-19: Pointer for Settings
Switching to *AtmosSettings is a good move for optional configuration sections.


40-42: SyntaxHighlightOptions
Straightforward struct for advanced formatting.


54-56: TerminalSettings struct
Allows expansion for future terminal-oriented features.


58-65: Unified Settings struct
Centralizing advanced options, including docs and terminal, improves clarity.


67-67: Type alias
The alias ensures prior references to AtmosSettings remain valid. Verify reflection-based code if present.

pkg/utils/highlight_utils.go (5)

18-30: DefaultHighlightSettings
A straightforward default featuring the “dracula” style. Nice for consistent theming.


32-71: GetHighlightSettings
This method robustly ensures defaults. The fallback steps are well arranged.


73-86: HighlightCode
Checks TTY presence, preventing formatting outside interactive terminals. Good approach.


88-137: HighlightCodeWithConfig
Smartly fetches config-based settings. The fallback to lexers/styles is handy.


139-160: HighlightWriter
A helpful abstraction for streaming highlights. This will keep I/O code tidy.

pkg/utils/json_utils.go (1)

27-35: Atmos config type check
Extracting AtmosConfiguration here is consistent with yaml_utils.go. Good synergy.

website/docs/cli/configuration/terminal.mdx (1)

1-21: Strong documentation structure, warrior!

The documentation is well-organized with clear sections, imported components, and key points that effectively guide users through the terminal settings.

atmos.yaml (1)

318-327: Strong configuration structure, but consider adding validation!

The terminal settings configuration is well-structured and aligns perfectly with the documentation. However, consider adding validation rules to ensure valid values for lexer, formatter, and style.

Let's verify the supported values:

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 3, 2025
Copy link

mergify bot commented Jan 4, 2025

💥 This pull request now has conflicts. Could you fix it @Cerebrovinny? 🙏

@mergify mergify bot added the conflict This PR has conflicts label Jan 4, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (9)
pkg/utils/json_utils.go (1)

36-41: Consider extracting common highlighting logic.

The error handling and highlighting logic is duplicated between JSON and YAML utils.

Consider extracting the common highlighting logic into a shared helper function:

+func highlightWithFallback(content string, config schema.AtmosConfiguration) {
+    highlighted, err := HighlightCodeWithConfig(content, config)
+    if err != nil {
+        PrintMessage(content)
+        return nil
+    }
+    PrintMessage(highlighted)
+    return nil
+}
website/docs/cli/configuration/terminal.mdx (2)

32-40: Consider adding validation constraints.

The configuration example would benefit from comments indicating any validation constraints for these settings (e.g., allowed values for lexer, formatter, style).


133-135: Consider adding theme preview information.

While linking to the full list of themes is helpful, consider adding a few screenshots of popular themes to help users make an informed choice.

pkg/utils/highlight_utils.go (4)

18-30: LGTM! Consider adding documentation for the style options.

The default settings are well-chosen. The Dracula style provides good contrast for terminal output.

Consider adding a code comment listing the available styles from Chroma (e.g., "monokai", "github", etc.) to help users customize their experience.


73-86: Consider adding context and buffer cleanup.

While the implementation is functional, it could be improved:

  1. Add context.Context parameter for cancellation support
  2. Consider using bufpool for buffer reuse in high-throughput scenarios

Example improvement:

-func HighlightCode(code string, lexerName string, style string) (string, error) {
+func HighlightCode(ctx context.Context, code string, lexerName string, style string) (string, error) {
     if !term.IsTerminal(int(os.Stdout.Fd())) {
         return code, nil
     }
 
-    var buf bytes.Buffer
+    buf := bufPool.Get().(*bytes.Buffer)
+    buf.Reset()
+    defer bufPool.Put(buf)
     
+    // Check context before expensive operation
+    select {
+    case <-ctx.Done():
+        return "", ctx.Err()
+    default:
+    }
     
     err := quick.Highlight(&buf, code, lexerName, "terminal", style)

88-137: Enhance error handling and add context support.

The implementation is solid but could be improved:

  1. Add context support for cancellation
  2. Wrap errors with more context
  3. Consider using buffer pool

Example improvement:

-func HighlightCodeWithConfig(code string, config schema.AtmosConfiguration) (string, error) {
+func HighlightCodeWithConfig(ctx context.Context, code string, config schema.AtmosConfiguration) (string, error) {
     if !term.IsTerminal(int(os.Stdout.Fd())) {
         return code, nil
     }
 
     settings := GetHighlightSettings(config)
     if !settings.Enabled {
         return code, nil
     }
 
+    select {
+    case <-ctx.Done():
+        return "", ctx.Err()
+    default:
+    }
 
     // Get lexer
     lexer := lexers.Get(settings.Lexer)
     if lexer == nil {
         lexer = lexers.Fallback
     }
 
     iterator, err := lexer.Tokenise(nil, code)
     if err != nil {
-        return code, err
+        return code, fmt.Errorf("failed to tokenize code with lexer %s: %w", settings.Lexer, err)
     }

153-160: Improve error handling in Write method.

Consider these enhancements:

  1. Add context support
  2. Preserve original error from writer.Write

Example improvement:

-func (h *HighlightWriter) Write(p []byte) (n int, err error) {
+func (h *HighlightWriter) Write(ctx context.Context, p []byte) (n int, err error) {
-    highlighted, err := HighlightCodeWithConfig(string(p), h.config)
+    highlighted, err := HighlightCodeWithConfig(ctx, string(p), h.config)
     if err != nil {
         return 0, err
     }
-    return h.writer.Write([]byte(highlighted))
+    n, err = h.writer.Write([]byte(highlighted))
+    if err != nil {
+        return n, fmt.Errorf("failed to write highlighted code: %w", err)
+    }
+    return n, nil
}
pkg/config/config.go (1)

429-479: Simplify configuration merging logic.

The current implementation is verbose and hard to maintain. Consider using a recursive merge function or a configuration merging library.

Example approach using a recursive merge function:

func mergeConfigs(dst, src map[string]interface{}) {
    for key, srcVal := range src {
        if dstVal, exists := dst[key]; exists {
            if srcMap, isSrcMap := srcVal.(map[string]interface{}); isSrcMap {
                if dstMap, isDstMap := dstVal.(map[string]interface{}); isDstMap {
                    mergeConfigs(dstMap, srcMap)
                    continue
                }
            }
        }
        dst[key] = srcVal
    }
}

Then use it in processConfigFile:

-    // Complex nested handling
-    if settingsMap, ok := value.(map[string]interface{}); ok {
-        if terminalMap, ok := settingsMap["terminal"].(map[string]interface{}); ok {
-            // ... many nested if statements
-        }
-    }
+    settings := fileViper.AllSettings()
+    mergeConfigs(v.AllSettings(), settings)
pkg/schema/schema.go (1)

72-79: LGTM! Well-organized settings structure.

The Settings struct provides a clean and logical organization of various configuration options. The use of optional fields with pointers allows for flexible configuration while maintaining clarity.

Consider adding validation tags (like validate:"required") for any fields that should be mandatory in the future.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae2aad and f9f91f8.

📒 Files selected for processing (7)
  • atmos.yaml (1 hunks)
  • pkg/config/config.go (4 hunks)
  • pkg/schema/schema.go (2 hunks)
  • pkg/utils/highlight_utils.go (1 hunks)
  • pkg/utils/json_utils.go (1 hunks)
  • pkg/utils/yaml_utils.go (1 hunks)
  • website/docs/cli/configuration/terminal.mdx (1 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/config.go

92-92: cannot use &schema.TerminalSettings{…} (value of type *schema.TerminalSettings) as schema.Terminal value in struct literal

(typecheck)


297-297: invalid operation: atmosConfig.Settings.Terminal == nil (mismatched types schema.Terminal and untyped nil)

(typecheck)


299-299: atmosConfig.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)

(typecheck)


300-300: atmosConfig.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)

(typecheck)


303-303: atmosConfig.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)

(typecheck)

🪛 GitHub Check: Build (macos-latest, macos)
pkg/utils/highlight_utils.go

[failure] 40-40:
invalid operation: config.Settings.Terminal == nil (mismatched types schema.Terminal and untyped nil)


[failure] 41-41:
cannot use &schema.TerminalSettings{…} (value of type *schema.TerminalSettings) as schema.Terminal value in assignment


[failure] 46-46:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)


[failure] 47-47:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)


[failure] 51-51:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)

🪛 GitHub Check: Build (ubuntu-latest, linux)
pkg/utils/highlight_utils.go

[failure] 40-40:
invalid operation: config.Settings.Terminal == nil (mismatched types schema.Terminal and untyped nil)


[failure] 41-41:
cannot use &schema.TerminalSettings{…} (value of type *schema.TerminalSettings) as schema.Terminal value in assignment


[failure] 46-46:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)


[failure] 47-47:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)


[failure] 51-51:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)

🔇 Additional comments (11)
pkg/utils/yaml_utils.go (2)

34-42: LGTM! Robust type handling for AtmosConfiguration.

The type switch pattern effectively handles both value and pointer types, ensuring consistent behavior regardless of how the configuration is passed.


44-49: Well-implemented error handling with graceful fallback.

The code gracefully falls back to plain text output if highlighting fails, ensuring the user experience isn't disrupted.

pkg/utils/json_utils.go (1)

27-34: LGTM! Consistent implementation with YAML utils.

The type switch pattern matches the implementation in yaml_utils.go, maintaining consistency across the codebase.

website/docs/cli/configuration/terminal.mdx (2)

102-109: LGTM! Clear explanation of piping behavior.

The note about disabled syntax highlighting when piping is crucial for users to understand the behavior in different contexts.


1-135: Verify terminal detection implementation.

The documentation mentions that syntax highlighting is automatically disabled when piping, but we should verify the terminal detection implementation.

✅ Verification successful

Terminal detection implementation is properly handled

The codebase has robust terminal detection implementation that correctly handles piped output scenarios. Here's the key evidence:

  • Terminal detection is implemented using the standard term.IsTerminal() function to check if stdout is connected to a terminal:

    • pkg/utils/highlight_utils.go: Disables syntax highlighting when not connected to a terminal
    • cmd/docs.go: Adjusts output width based on terminal detection
    • internal/tui/templates/term/term_writer.go: Provides terminal-aware text wrapping
  • Color support is properly handled:

    • internal/tui/utils/utils.go: Checks terminal color support before applying styling
    • Uses supportscolor.Stdout().SupportsColor to detect color capabilities
  • Piped output is correctly detected:

    • pkg/utils/highlight_utils.go: Explicitly checks !term.IsTerminal(int(os.Stdout.Fd())) and returns plain text when piped
    • internal/tui/templates/term/term_writer.go: Falls back to basic writer when not connected to a terminal

The implementation aligns with the documentation's claim about automatically disabling syntax highlighting when output is piped.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify terminal detection implementation
# Search for terminal detection logic in the codebase

# Look for terminal detection code
rg -l "os\.(Stdout|Stderr)\..*TTY" --type go

# Look for specific terminal detection functions
ast-grep --pattern 'func $_(){ 
  $$$
  os.Stdout.$$$
  $$$
}'

Length of output: 111


Script:

#!/bin/bash
# Let's try different patterns to find terminal detection logic

# Search for terminal-related code using broader patterns
rg -i "isterm|istty|terminal" --type go -A 5

# Look for imports of terminal-related packages
rg "import.*term" --type go -A 5

# Search for specific terminal detection patterns
rg "os\.(Stdout|Stderr)" --type go -A 3

# Look for color/formatting related code which often involves terminal detection
rg "color.*term|term.*color" --type go -A 3

Length of output: 29844

pkg/utils/highlight_utils.go (2)

32-71: Well-structured defensive programming!

The function properly handles all nil cases and gracefully falls back to defaults.

🧰 Tools
🪛 GitHub Check: Build (macos-latest, macos)

[failure] 40-40:
invalid operation: config.Settings.Terminal == nil (mismatched types schema.Terminal and untyped nil)


[failure] 41-41:
cannot use &schema.TerminalSettings{…} (value of type *schema.TerminalSettings) as schema.Terminal value in assignment


[failure] 46-46:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)


[failure] 47-47:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)


[failure] 51-51:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)

🪛 GitHub Check: Build (ubuntu-latest, linux)

[failure] 40-40:
invalid operation: config.Settings.Terminal == nil (mismatched types schema.Terminal and untyped nil)


[failure] 41-41:
cannot use &schema.TerminalSettings{…} (value of type *schema.TerminalSettings) as schema.Terminal value in assignment


[failure] 46-46:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)


[failure] 47-47:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)


[failure] 51-51:
config.Settings.Terminal.SyntaxHighlighting undefined (type schema.Terminal has no field or method SyntaxHighlighting)


139-151: Clean implementation following Go idioms!

The struct and constructor are well-designed and follow Go best practices.

atmos.yaml (1)

318-327: 🛠️ Refactor suggestion

Consolidate duplicate terminal settings sections.

There are two terminal sections in the configuration. Consider merging them to avoid confusion.

Suggested structure:

 settings:
   terminal:
     syntax_highlighting:
       enabled: true
       lexer: yaml
       formatter: terminal
       style: dracula
       pager: true
       options:
         line_numbers: true
         wrap: false
-    max_width: 120
-    pager: true
-    timestamps: false
-    colors: true
-    unicode: true
+    display:
+      max_width: 120
+      timestamps: false
+      colors: true
+      unicode: true

Likely invalid or redundant comment.

pkg/schema/schema.go (3)

54-66: LGTM! Well-structured syntax highlighting configuration.

The new types provide a comprehensive and flexible configuration for syntax highlighting. The structure is clean, and the field names are descriptive and self-documenting.


68-70: LGTM! Clean terminal settings structure.

The TerminalSettings struct is well-designed with a clear single responsibility for managing terminal-specific configurations.


19-19: Verify handling of nil Settings pointer.

The change from value to pointer type for the Settings field is a breaking change. Ensure that all code paths handle the potential nil value appropriately.

✅ Verification successful

All code paths properly handle nil Settings field

The codebase shows proper handling of nil Settings field throughout. Here's the evidence:

  • In pkg/utils/highlight_utils.go, nil checks are performed before accessing Settings:

    if config.Settings.Terminal == nil {
      config.Settings.Terminal = &schema.TerminalSettings{...}
    }
  • In pkg/config/config.go, default values are assigned when Settings is nil:

    if atmosConfig.Settings.Terminal == nil {
      atmosConfig.Settings.Terminal = defaultCliConfig.Settings.Terminal
    }
  • In pkg/merge/merge.go, default values are set for uninitialized fields:

    if atmosConfig.Settings.ListMergeStrategy == "" {
      atmosConfig.Settings.ListMergeStrategy = ListMergeStrategyReplace
    }

The code consistently checks for nil pointers and provides appropriate defaults, making this a safe change.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for direct Settings field access that might not handle nil
ast-grep --pattern 'AtmosConfiguration { $$$ Settings $$$ }'

# Search for potential nil pointer dereferences
rg -A 2 '\.Settings\.' 

Length of output: 13395

pkg/config/config.go Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
pkg/schema/schema.go (2)

55-58: Consider adding field descriptions.

The SyntaxHighlightOptions struct would benefit from field documentation to explain the purpose of each option.

Add documentation comments:

 type SyntaxHighlightOptions struct {
+    // LineNumbers enables line number display in highlighted output
     LineNumbers bool `yaml:"line_numbers" json:"line_numbers" mapstructure:"line_numbers"`
+    // Wrap enables text wrapping in highlighted output
     Wrap        bool `yaml:"wrap" json:"wrap" mapstructure:"wrap"`
 }

78-84: Consider adding validation for list merge strategy.

The Settings struct includes a ListMergeStrategy field, but there's no indication of valid values.

Add an enum or constant for valid merge strategies:

// Valid list merge strategies
const (
    ListMergeStrategyOverwrite = "overwrite"
    ListMergeStrategyAppend    = "append"
    ListMergeStrategyPrepend   = "prepend"
)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9f91f8 and dddcdd3.

📒 Files selected for processing (1)
  • pkg/schema/schema.go (2 hunks)
🔇 Additional comments (4)
pkg/schema/schema.go (4)

19-19: LGTM! Pointer type change improves flexibility.

The change from AtmosSettings to *AtmosSettings allows for nil values, which is appropriate for optional settings.


49-53: LGTM! AtmosSettings struct updated with new fields.

The struct now includes terminal settings and maintains backward compatibility with existing fields.


69-76: LGTM! Well-structured terminal settings.

The TerminalSettings struct effectively combines basic terminal configuration with syntax highlighting settings.


60-67: Verify lexer and formatter compatibility.

The SyntaxHighlightingSettings struct introduces configuration for syntax highlighting. Ensure that:

  1. The lexer values are validated against supported Chroma lexers
  2. The formatter values are validated against supported Chroma formatters

Run this script to check Chroma's supported lexers and formatters:

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
pkg/schema/schema.go (2)

47-68: Consider adding field validation tags.

The terminal and syntax highlighting settings are well-structured, but consider adding validation tags for fields that need constraints:

  • max_width might need a minimum value
  • lexer, formatter, and style might need to be validated against a list of supported values

Example validation tags:

type TerminalSettings struct {
    MaxWidth           int                         `yaml:"max_width,omitempty" json:"max_width,omitempty" mapstructure:"max_width" validate:"omitempty,min=20"`
    // ... other fields ...
}

type SyntaxHighlightingSettings struct {
    Lexer     string                  `yaml:"lexer" json:"lexer" mapstructure:"lexer" validate:"required,oneof=yaml json go"`
    Formatter string                  `yaml:"formatter" json:"formatter" mapstructure:"formatter" validate:"required,oneof=terminal html"`
    Style     string                  `yaml:"style" json:"style" mapstructure:"style" validate:"required,oneof=monokai github dracula"`
    // ... other fields ...
}

70-76: Add GoDoc comments for the Settings struct.

The new Settings struct would benefit from documentation explaining its purpose and the significance of each field.

Add documentation like this:

// Settings represents the global configuration settings for Atmos.
// It combines various setting groups including dependencies, Spacelift integration,
// templates, and terminal configurations.
type Settings struct {
    // DependsOn defines component dependencies
    DependsOn         DependsOn         `yaml:"depends_on,omitempty" json:"depends_on,omitempty" mapstructure:"depends_on"`
    
    // Spacelift contains Spacelift-specific settings
    Spacelift         SettingsSpacelift `yaml:"spacelift,omitempty" json:"spacelift,omitempty" mapstructure:"spacelift"`
    
    // Templates defines template processing settings
    Templates         Templates         `yaml:"templates,omitempty" json:"templates,omitempty" mapstructure:"templates"`
    
    // ListMergeStrategy defines how lists are merged in configurations
    ListMergeStrategy string            `yaml:"list_merge_strategy,omitempty" json:"list_merge_strategy,omitempty"`
    
    // Terminal contains terminal-specific settings including syntax highlighting
    Terminal          *TerminalSettings `yaml:"terminal,omitempty" json:"terminal,omitempty" mapstructure:"terminal"`
    
    // Docs contains documentation generation settings
    Docs              *Docs             `yaml:"docs,omitempty" json:"docs,omitempty" mapstructure:"docs"`
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dddcdd3 and f9c0a9f.

📒 Files selected for processing (1)
  • pkg/schema/schema.go (2 hunks)
🔇 Additional comments (2)
pkg/schema/schema.go (2)

40-44: Clean and well-structured settings definition!

The AtmosSettings struct maintains good separation of concerns while making the terminal settings optional through the pointer type.


19-19: Verify handling of nil Settings field.

The change from AtmosSettings to *AtmosSettings is a breaking change. Ensure that all code paths handle potential nil values appropriately.

✅ Verification successful

Nil checks are properly implemented, warrior! The code is battle-ready.

The codebase shows proper defensive programming with comprehensive nil checks for the Settings field:

  • In pkg/utils/highlight_utils.go and pkg/config/config.go, there are explicit checks for config.Settings == nil
  • When Settings is nil, default values are properly assigned:
    if atmosConfig.Settings == nil {
        atmosConfig.Settings = defaultCliConfig.Settings
    }
  • Nested fields are also protected with nil checks:
    if config.Settings.Terminal == nil {
        config.Settings.Terminal = &schema.TerminalSettings{...}
    }
  • All direct accesses to Settings fields are guarded by conditional checks that ensure the parent objects exist

The code demonstrates robust defensive programming practices, making the pointer type change safe and well-handled throughout the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all direct accesses to the Settings field that might need nil checks

# Search for direct Settings field access
rg -A 2 "\.Settings\." pkg/

# Search for Settings assignments
rg -A 2 "\.Settings\s*=" pkg/

Length of output: 8069

@Cerebrovinny Cerebrovinny requested a review from osterman January 4, 2025 11:36
@aknysh aknysh merged commit 5d93ce1 into main Jan 6, 2025
42 of 45 checks passed
@aknysh aknysh deleted the DEV-2876/feat-tty branch January 6, 2025 17:42
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
minor New features that do not break anything
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants