feat: add recipes#362
Draft
nieomylnieja wants to merge 28 commits into
Draft
Conversation
This commit introduces jq filtering capabilities to the `sloctl` tool, enabling users to query and manipulate output data using jq syntax. Key changes include: - Integration of the `gojq` library for parsing and evaluating jq expressions. - Addition of a new `ExpressionRunner` component to handle jq queries and output formatting. - Updates to the `GetCmd` structure to include jq-related functionality. - Modifications to the `printObjects` method to support conditional jq evaluation. - Enhancements to the JSON printer to handle scalar values more effectively. - Comprehensive unit tests for the jq functionality, covering various scenarios and edge cases. - A new BATS test to validate jq filtering in the `get project` command. These changes improve the flexibility and usability of the tool, allowing users to extract specific data from complex outputs.
The `jq` flag in the `ExpressionRunner` has been updated to include an alias `-q` for better usability. This change ensures users can use either `--jq` or `-q` to specify their query expressions. Additionally, the test suite has been updated to validate the functionality of both flag variants. The test for the `jq` filter now iterates over both `--jq` and `-q` aliases, ensuring consistent behavior and output for both options.
The SLO filtering and counting commands have been updated to use `--jq` directly with `sloctl`, simplifying the syntax and improving readability. This change removes the dependency on external tools like `yq` and streamlines the process for users.
- Updated `EvaluateAndPrint` in `jq.go` to return the evaluated value directly instead of the error object, ensuring better handling of halt errors with nil values. - Modified `jsonScalarToString` in `json.go` to use `-1` precision for float formatting, allowing for more accurate representation of floating-point numbers without unnecessary truncation. - Added new test cases in `printer_test.go` to validate the updated float formatting behavior and ensure proper handling of various scalar values, including integers, floats with no decimals, and large decimal floats.
Enhanced the `jsonScalarToString` method in the JSON printer to handle integer inputs. Previously, the method only supported string and float64 types. Now, integers are converted to their string representation using `strconv.Itoa`.
This commit removes the direct dependency on the `jq` package from the `GetCmd` structure and integrates its functionality into the `Printer` component. The `Printer` now handles `jq` expression evaluation internally, simplifying the `GetCmd` implementation and reducing redundancy. Key changes: - Removed `jq.ExpressionRunner` from `GetCmd` and its initialization. - Integrated `jq.ExpressionRunner` into the `Printer` component, allowing `Printer` to evaluate and print `jq` expressions directly. - Updated `Printer` to initialize and manage `jq.ExpressionRunner` internally. - Refactored `jq` package to return an iterator for evaluated results, enabling better integration with `Printer`. - Adjusted tests to reflect the new design, removing mock printer tests and adding iterator-based result collection. This refactor improves modularity and encapsulation, ensuring that `jq` functionality is centralized within the `Printer` component.
This commit introduces several changes to improve code clarity and consistency:
- In `internal/jq/jq.go`, the error handling logic in `EvaluateAndPrint` was updated to yield the correct value (`v`) instead of the error (`err`) in certain cases.
- Adjusted the `collectResults` function in `internal/jq/jq_test.go` to use `iter.Seq2[any, error]` directly, aligning with the updated type usage. Removed the `nolint: prealloc` directive for clarity.
- Modified the `internal/printer/printer_test.go` to ensure the expected output for a `nil` scalar in JSON format is an empty string, improving test accuracy.
- Replaced the `interface{}` type with `any` in the `doRequest` method of `internal/replay.go` for better readability and adherence to Go's modern type conventions.
Refined the description of the jq flag to better clarify its purpose. The new description emphasizes its role in filtering command results using jq expressions, replacing the previous phrasing that focused on selecting values from the response.
This update introduces a new feature allowing users to define and execute custom recipes in the sloctl CLI. Recipes are user-defined commands that can be configured via a YAML file. The implementation includes: - A new `recipes` command added to the root CLI, enabling users to run custom recipes. - Validation rules for recipes, ensuring proper configuration and preventing conflicts (e.g., disallowing simultaneous use of `jq` in both the recipe property and arguments). - Support for displaying recipe definitions using the `--show-definition` flag. - Dynamic loading of recipes from a configurable path, defaulting to `sloctl-recipes.yaml` in the Nobl9 SDK configuration directory. - Enhanced error handling and validation for recipe arguments. Additionally, the `Execute` function in the root command has been refactored to return errors instead of directly exiting, improving testability and error propagation.
This commit introduces a new feature for managing and executing built-in recipes in the application. It includes the following changes: 1. Added a new YAML file (`builtin_recipes.yaml`) to define built-in recipes with their descriptions, arguments, examples, and validators. 2. Enhanced the `recipes.go` file to support commands for listing, adding, and removing recipes. Recipes are grouped into categories for better organization. 3. Implemented functionality to read and save recipes from a configuration file, with support for both JSON and YAML formats. 4. Introduced helper functions for handling recipe configuration paths and temporary file creation for safe updates. 5. Updated the command structure to include recipe-specific commands dynamically based on the defined recipes. These changes provide a flexible and extensible framework for managing recipes, enabling users to execute predefined tasks efficiently.
This commit introduces a custom YAML encoder to replace the default encoding logic. The new encoder is implemented in the `yamlenc` package and provides enhanced control over YAML formatting and serialization. Key changes include: - Replacing the use of `goccy/go-yaml`'s default `Marshal` and `NewEncoder` methods with a custom encoder. - Adding a `yamlenc.NewEncoder` function that configures the encoder with specific options, such as sequence indentation and literal style for multiline strings. - Introducing a custom marshaler for `json.Number` to ensure integers are not converted to floats during JSON-to-YAML transformations. The changes affect the `yamlPrinter` implementation in `internal/printer/yaml.go` and the recipe handling logic in `internal/recipes.go`. The new encoder is also used for temporary file writing in the recipes workflow.
This commit introduces a `RecipesCmd` struct to encapsulate the recipes logic and associated printer. The changes include: - Adding a `RecipesCmd` struct that holds the recipes and a printer instance. - Refactoring the `NewRecipesCmd` function to use the `RecipesCmd` struct for managing recipes-related commands. - Moving the logic for listing, adding, deleting, and running recipes into methods of the `RecipesCmd` struct (`ListRecipes`, `AddRecipe`, `DeleteRecipes`, and `RunRecipe`). - Updating the `Validators` field in the `Recipe` struct to use the `omitzero` tag for better JSON serialization. These changes improve the modularity and maintainability of the code by grouping related functionality into a dedicated struct.
- Introduced a new `jsonbuffer` package to encapsulate JSON buffer detection logic, replacing the inline `isJSONBuffer` function. - Updated `ExpressionRunner` to use value receivers instead of pointers, improving consistency and simplifying usage. - Enhanced `Printer` with a `WithOutput` method for easier output redirection and refactored format validation using the `slices` package. - Removed the unused `add` command from the recipes module, simplifying the command structure. - Added comprehensive unit tests for the `jsonbuffer` package to ensure robust JSON detection.
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a recipes feature to sloctl that allows users to define, share, and execute custom command templates. The implementation includes built-in recipes for common operations like fetching object names and filtering SLOs by data source type.
Key changes:
- Added
sloctl recipescommand with subcommands for listing, removing, and running recipes - Implemented recipe configuration system with YAML/JSON storage support
- Created reusable YAML encoder utility for consistent formatting
- Refactored error handling in main execution flow
Reviewed Changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/recipes.go | Core recipes functionality with command handling, validation, and execution logic |
| internal/yamlenc/encoder.go | New YAML encoder utility with custom number marshaling for consistent output |
| internal/jsonbuffer/json.go | Utility for detecting JSON vs YAML content in buffers |
| internal/printer/yaml.go | Updated to use new YAML encoder for consistent formatting |
| internal/root.go | Added recipes command to CLI and refactored Execute() error handling |
| cmd/sloctl/main.go | Updated main function to handle Execute() errors properly |
Modified the argument validation logic in the `recipesArgFunc` function to permit additional arguments beyond the required ones. Previously, the function enforced an exact match between the number of provided and required arguments. Now, it ensures that the number of provided arguments is at least equal to the number of required arguments.
…ies and redundant logic Removed the `manifest` and `sdk` dependencies as they were no longer used in the `yamlPrinter` implementation. Simplified the `Print` method by eliminating the type switch logic, which was redundant, and directly using the `yamlenc.Encoder` for encoding the content.
Adds a RunE handler to the 'recipes' command to display a clear error message and usage when an unknown recipe is invoked. This commit also introduces comprehensive unit tests for the 'recipes' command, covering listing, removing, and argument validation. Additionally, unit tests are added for the internal 'yamlenc' package's encoder to ensure correct YAML serialization, especially for JSON numbers and nested structures.
Extract default recipes config path logic into a dedicated function and use a constant for the environment variable. Update the `recipes` command's long description to clarify config path usage. Improve unit tests for `recipes remove` and config handling by making them more isolated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Currently there's a lot of ways floating around for scripting with sloctl, even in the sloctl README.md we have a short "recipes" section.
Wouldn't it be nice to have a curated list of such recipes available in sloctl itself? Or have custom ones! Or share them with others!
I got you, let's define some
sloctl recipes😄Summary
Example recipe in YAML format:
Related changes
List related changes from other PRs (if any).
Testing
Release Notes
If this change should be part of the Release Notes,
replace this entire paragraph with 1-3 sentences about the changes.
Otherwise, you MUST remove this section entirely.
Does this PR contain any breaking changes?
If so, add
## Breaking Changesheader and list the introduced changes there.