Skip to content

Commit

Permalink
remove resultsFunc from the Executor interface
Browse files Browse the repository at this point in the history
  • Loading branch information
apenella committed Sep 3, 2023
1 parent d0cac1b commit 31c3110
Show file tree
Hide file tree
Showing 42 changed files with 1,044 additions and 316 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ If you would like to contribute code to go-ansible, please follow these steps:

1. Create a new branch for your changes.
2. Make your changes.
3. Submit a pull request.
3. Submit a pull request with a proper description of the introduced changes, features, etc.

Please ensure that your code adheres to our coding standards, that all tests pass before submitting a pull request, and you update the project [README](https://github.com/apenella/go-ansible/blob/master/README.md) and the [RELEASE_NOTES](https://github.com/apenella/go-ansible/blob/master/RELEASE_NOTES.md).

Expand Down
37 changes: 21 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Let's dive in and explore the capabilities of `go-ansible` together.
- [go-ansible](#go-ansible)
- [Install](#install)
- [Upgrade to 1.x](#upgrade-to-1x)
- [Upgrade to 2.x](#upgrade-to-2x)
- [Getting Started](#getting-started)
- [Usage Reference](#usage-reference)
- [Packages](#packages)
Expand Down Expand Up @@ -54,7 +55,11 @@ This command will fetch and install the latest version of `go-ansible`, ensuring

### Upgrade to 1.x

If you are currently using a `go-ansible` version prior to 1.0.0, it's important to note that there have been significant breaking changes introduced in version 1.0.0 and beyond. Before proceeding with the upgrade, we highly recommend reading the [changelog](https://github.com/apenella/go-ansible/blob/master/CHANGELOG.md) and the [upgrade guide](https://github.com/apenella/go-ansible/blob/master/docs/upgrade_guide_to_1.0.0.md) carefully. These resources provide detailed information on the changes and steps required for a smooth transition to the new version.
If you are currently using a `go-ansible` version prior to 1.0.0, it's important to note that there have been significant breaking changes introduced in version 1.0.0 and beyond. Before proceeding with the upgrade, we highly recommend reading the [changelog](https://github.com/apenella/go-ansible/blob/master/CHANGELOG.md) and the [upgrade guide](https://github.com/apenella/go-ansible/blob/master/docs/upgrade_guide_to_1.x.md) carefully. These resources provide detailed information on the changes and steps required for a smooth transition to the new version.

### Upgrade to 2.x

Versions 2.x introduced notorious changes since the major version 1. Among those changes, there are several breaking changes. The [upgrade guide](https://github.com/apenella/go-ansible/blob/master/docs/upgrade_guide_to_2.x.md) conveys the necessary information to migrate to version 2.x. Please thoroughly read that document and the changelog before upgrading from version 1.x to 2.x.

## Getting Started

Expand Down Expand Up @@ -167,9 +172,9 @@ An executor in `go-ansible` is a component that executes the command and retriev
The `Executor` interface requires the implementation of the `Execute` method with the following signature:
```go
// Executor interface is satisfied by those types which has a Execute(context.Context,[]string,stdoutcallback.StdoutCallbackResultsFunc,...ExecuteOptions)error method
// Executor interface is satisfied by those types which has a Execute(context.Context,[]string,...ExecuteOptions)error method
type Executor interface {
Execute(ctx context.Context, command []string, resultsFunc stdoutcallback.StdoutCallbackResultsFunc, options ...ExecuteOptions) error
Execute(ctx context.Context, command []string, options ...ExecuteOptions) error
}
```
Expand Down Expand Up @@ -214,7 +219,7 @@ func WithPrefix(prefix string) execute.ExecuteOptions {
}
}
func (e *MyExecutor) Execute(ctx context.Context, command []string, resultsFunc stdoutcallback.StdoutCallbackResultsFunc, options ...execute.ExecuteOptions) error {
func (e *MyExecutor) Execute(ctx context.Context, command []string, options ...execute.ExecuteOptions) error {
// It is possible to apply extra options when Execute is called
for _, opt := range options {
opt(e)
Expand Down Expand Up @@ -296,11 +301,11 @@ In `go-ansible`, you can define a specific stdout callback method by setting the
type StdoutCallbackResultsFunc func(context.Context, io.Reader, io.Writer, ...results.TransformerFunc) error
```
The functions to manage the output are defined in the `github.com/apenella/go-ansible/pkg/stdoutcallback/results` package. By utilizing these functions and defining a custom stdout callback, you can customize how the output of the execution.
The functions to manage the output are defined in the `github.com/apenella/go-ansible/pkg/stdoutcallback/results` package. By utilizing these functions and defining a custom stdout callback, you can customize the output of the execution.
#### Results
In the `github.com/apenella/go-ansible/pkg/stdoutcallback/results` package, there are different methods available to manage the outputs of Ansible commands.
In the `github.com/apenella/go-ansible/pkg/execute/result` package, there are different methods available to manage the outputs of Ansible commands.
##### Transformers
Expand All @@ -311,28 +316,28 @@ In `go-ansible`, a transformer is a function that enriches or updates the output
type TransformerFunc func(string) string
```
When the output is received from the executor, it is processed line by line, and the transformers are applied to each line. The `github.com/apenella/go-ansible/pkg/stdoutcallback/results` package provides a set of ready-to-use transformers, but you can also write custom transformers and set them through the executor.
When the output is received from the executor, it is processed line by line, and the transformers are applied to each line. The `github.com/apenella/go-ansible/pkg/execute/result/transformer` package provides a set of ready-to-use transformers, but you can also write custom transformers and set them through the executor.
Here are some examples of transformers available in the results package:
- [**Prepend**](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/transformer.go#L21): Adds a prefix string to each output line.
- [**Append**:](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/transformer.go#L28) Adds a suffix string to each output line.
- [**LogFormat**:](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/transformer.go#L35) Includes a date-time prefix to each output line.
- [**IgnoreMessage**:](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/transformer.go#L44) Ignores output lines based on the patterns provided as input parameters.
- **Prepend**: Adds a prefix string to each output line.
- **Append**: Adds a suffix string to each output line.
- **LogFormat**: Includes a date-time prefix to each output line.
- **IgnoreMessage**: Ignores output lines based on the patterns provided as input parameters.
##### Default
By default, the stdout callback results are managed by the [DefaultStdoutCallbackResults](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/DefaultResults.go#L14) method. This method handles the output by prepending the separator string `──` to each line when no transformer is defined. It also prepares all the transformers before invoking the worker function responsible for writing the output to the `io.Writer`.
By default, the execution results are managed by the `DefaultResults` struct, defined in the package `github.com/apenella/go-ansible/pkg/execute/result/default`. Its `Print` method handles the output by prepending the separator string `──` to each line when no transformer is defined. It also prepares all the transformers before invoking the worker function responsible for writing the output to the `io.Writer`.
The [DefaultStdoutCallbackResults](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/DefaultResults.go#L14) method ensures that the output is formatted correctly and provides a basic handling of the results when no specific transformers are applied.
The `Print` method ensures that the output is formatted correctly and provides basic handling of the results when no specific transformers are applied.
##### JSON
When the stdout callback method is set to `JSON` format, the output is managed by the [JSONStdoutCallbackResults](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/JSONResults.go#L151) method. This method prepares the worker output function to use the [IgnoreMessage](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/transformer.go#L44) transformer, which ignores any non-JSON lines. Other transformers are ignored, except for those specific to [JSONStdoutCallbackResults](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/JSONResults.go#L151).
Within the [JSONStdoutCallbackResults](https://github.com/apenella/go-ansible/blob/master/pkg/stdoutcallback/results/JSONResults.go#L151) function, there is an array called `skipPatterns` that contains matching expressions for lines that should be ignored. These patterns are used to skip specific lines that may not be relevant to the JSON output.
Here is an example of the skipPatterns array:
Here is an example of the `skipPatterns` array:
```go
skipPatterns := []string{
Expand Down Expand Up @@ -500,11 +505,11 @@ Here you have a list of examples:
## Contributing
Thank you for your interest in contributing to go-ansible! All contributions are welcome, whether they are bug reports, feature requests, or code contributions. Please read the contributor's guide [here](https://github.com/apenella/go-ansible/blob/master/CONTRIBUTING.md) to know more about how to contribute.
Thank you for your interest in contributing to go-ansible! All contributions are welcome, whether they are bug reports, feature requests, or code contributions. Please read the contributor's guide [here](https://github.com/apenella/go-ansible/blob/master/CONTRIBUTING.md) to learn more about how to contribute.
### Code Of Conduct
The `go-ansible` project is committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, disability, ethnicity, religion, or similar personal characteristic.
The `go-ansible` project is committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, disability, ethnicity, religion, or similar personal characteristics.
We expect all contributors, users, and community members to follow this code of conduct. This includes all interactions within the `go-ansible` community, whether online, in person, or otherwise.
Expand Down
21 changes: 13 additions & 8 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# Release notes

## v1.2.0
## v2.0.0

### Added

- Introducing the `github.com/apenella/go-ansible/pkg/vault` package, which enables variable encryption.
- Added the `github.com/apenella/go-ansible/pkg/vault/password/text` package for reading encryption passwords as plain text.
- Introduced the `github.com/apenella/go-ansible/pkg/vault/password/resolve` package, which helps in resolving an encryption password.
- Added the `github.com/apenella/go-ansible/pkg/vault/password/file` package for reading encryption passwords from a file.
- Introduced the `github.com/apenella/go-ansible/pkg/vault/password/envvars` package, allowing the reading of encryption passwords from an environment variable.
- Added the `github.com/apenella/go-ansible/pkg/vault/encrypt` package, which provides the ability to encrypt strings using the `https://github.com/sosedoff/ansible-vault-go` package.
- Included an example using `embed.FS`.
- New package `github.com/apenella/go-ansible/pkg/execute/executable/os/exec` to run external commands, which acts as a wrapper of `os.exec`.
- New package `github.com/apenella/go-ansible/pkg/execute/result/default` which provides the default component to print the execution results.
- New struct `ResultsOutputer` to print the execution results.

### Changed

- BREAKING CHANGES `Executor` interface has removed the `resultsFunc` argument.
- The package `github.com/apenella/go-ansible/pkg/stdoutcallback/result/transformer` has been moved to `github.com/apenella/go-ansible/pkg/execute/result/transformer`.

### Removed

- Removed the attribute `ShowDuration` in the struct DefaultExecute
File renamed without changes.
113 changes: 113 additions & 0 deletions docs/upgrade_guide_to_2.x.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Upgrade Guide to go-ansible 2.x

- [Upgrade Guide to go-ansible 2.x](#upgrade-guide-to-go-ansible-2x)
- [Overview](#overview)
- [Changes on the Executor interface](#changes-on-the-executor-interface)
- [Changes on the DefaultExecute struct](#changes-on-the-defaultexecute-struct)
- [Removed the ShowDuration attribute](#removed-the-showduration-attribute)
- [New attribute _Output_ for printing execution results](#new-attribute-output-for-printing-execution-results)
- [New attribute _Exec_ for running external commands](#new-attribute-exec-for-running-external-commands)
- [Packages Reorganization](#packages-reorganization)
- [github.com/apenella/go-ansible/pkg/stdoutcallback](#githubcomapenellago-ansiblepkgstdoutcallback)

## Overview

This document presents the changes introduced in go-ansible v2.0.0 and offers guidance for upgrading from go-ansible v1.x to v2.x.

## Changes on the Executor interface

The `Executor` interface has undergone a significant change in version v2.0.0 by removing the `resultsFunc` argument from the `Execute` method. This change constitutes a breaking change. In prior versions, the `Execute` method accepted an argument for `resultsFunc`, which represented the function responsible for handling and printing the execution's results. With the revised signature, the mechanism for printing the execution results is now anticipated to be an attribute of the executor.

If you defined a custom executor you need to adapt it by removing the `resultsFunc` argument, and defining the component that prints the execution's output in the struct. The section [Changes on the DefaultExecute struct](#changes-to-defaultexecute-struct) describes how the `DefaultExecutor` is provided with a new attribute that is responsible for printing the execution's output.

Here is the updated `Executor` interface:

```go
type Executor interface {
Execute(ctx context.Context, command []string, options ...ExecuteOptions) error
}
```

## Changes on the DefaultExecute struct

The `DefaultExecute` struct, functioning as the default executor in the `go-ansible` library, has introduced significant changes in version 2.0.0. The next sections describe how to adapt that component to version v2.0.0:

### Removed the ShowDuration attribute

The `DefaultExacute` has removed the attribute `ShowDuration`, as previously announced. Starting from version v2.0.0, to measure the duration of the execution you should utilize the `measure.ExecutiorTimeMeasurement` component.

For guidance on how to use the ExecutiorTimeMeasurement decorator component, please refer to the example [ansibleplaybook-time-measurement](https://github.com/apenella/go-ansible/blob/master/examples/ansibleplaybook-time-measurement/ansibleplaybook-time-measurement.go).

### New attribute _Output_ for printing execution results

Inside the `DefaultExecute` struct, the `Execute` method has undergone an update that removes the `resultsFunc` attribute. This attribute was previously of type `stdoutcallback.StdoutCallbackResultsFunc` and was responsible for printing the execution's output. Instead, a new attribute named `Output` has been introduced to the struct.

The `Output` attribute is of type `results.ResultsOutputer`, which represents an interface defined as follows:

```go
// OptionsFunc is a function that can be used to configure a ResultsOutputer struct
type OptionsFunc func(ResultsOutputer)

// ResultsOutputer is the interface that must implements an struct to print the execution results
type ResultsOutputer interface {
Print(ctx context.Context, reader io.Reader, writer io.Writer, options ...OptionsFunc) error
}
```

If the `Output` attribute is not explicitly specified within the `DefaultExecute` struct, the default behaviour uses the `DefaultResults` struct as the output mechanism. You can find this struct in the `github.com/apenella/go-ansible/pkg/execute/result/default` package, and it is responsible for handling the printing of execution output.

For further details on the DefaultResults struct, please refer to the section that discusses the package reorganization at [github.com/apenella/go-ansible/pkg/stdoutcallback](#githubcomapenellago-ansiblepkgstdoutcallback).

### New attribute _Exec_ for running external commands

In versions prior to v2.0.0, `DefaultResults` utilized the `os.exec` package to run external commands. However, in version v2.0.0, direct usage of `os.exec` has been replaced by the introduction of a new attribute called `Exec`. This attribute instantiates a component of type `Executabler`, responsible for executing external commands.

By default, if you do not explicitly define an `Exec` attribute, `DefaultExecute` uses the `Exec` struct to execute external commands, which is defined in the `github.com/apenella/go-ansible/pkg/execute/executable/os/exec package`.


The `Executabler` interface is defined as follows:

```go
// Executabler is an interface to run commands
type Executabler interface {
Command(name string, arg ...string) exec.Cmder
CommandContext(ctx context.Context, name string, arg ...string) exec.Cmder
}
```

The `exec.Cmder` type used on the `Executabler` interface is defined as:

```go
// Cmder is an interface to run a command
type Cmder interface {
CombinedOutput() ([]byte, error)
Environ() []string
Output() ([]byte, error)
Run() error
Start() error
StderrPipe() (io.ReadCloser, error)
StdinPipe() (io.WriteCloser, error)
StdoutPipe() (io.ReadCloser, error)
String() string
Wait() error
}
```

## Packages Reorganization

Version v2.0.0 introduces changes to the package structure, including some reorganization and removals. This section outlines the necessary steps to migrate from the older packages to the new ones.

### github.com/apenella/go-ansible/pkg/stdoutcallback

The `github.com/apenella/go-ansible/pkg/stdoutcallback/results` package suffered several changes in version v2.0.0. This section explains how to adapt your code to these changes.

Previously, this package contained various structs and functions, which have now been split and moved into new packages based on their responsibilities:

- The functions for transforming the output lines of the execution's results are now available in the `github.com/apenella/go-ansible/pkg/execute/result/transformer` package. To utilize these functions, import the `github.com/apenella/go-ansible/pkg/execute/result/transformer` package and update the corresponding functions (Prepend, Append, LogFormat, and IgnoreMessage) in your code to use the `transformer` package.

```go
// import "github.com/apenella/go-ansible/pkg/execute/result/transformer"
transformer.Prepend("Go-ansible example")
```

- The `github.com/apenella/go-ansible/pkg/execute/result/default` package introduces the `DefaultResults` struct, which takes over the functionality previously provided by the `DefaultStdoutCallbackResults` function, defined in the `github.com/apenella/go-ansible/pkg/stdoutcallback/results` package. As the `DefaultStdoutCallbackResults` function is no longer available, you should use the `DefaultResults` struct as the default mechanism for printing the output of the execution's results. Furthermore, the `DefaultExecutor` now employs the `DefaultResults` struct as the default component for printing the execution results.
4 changes: 2 additions & 2 deletions examples/ansibleplaybook-become/ansibleplaybook-become.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"context"

"github.com/apenella/go-ansible/pkg/execute"
"github.com/apenella/go-ansible/pkg/execute/result/transformer"
"github.com/apenella/go-ansible/pkg/options"
"github.com/apenella/go-ansible/pkg/playbook"
"github.com/apenella/go-ansible/pkg/stdoutcallback/results"
)

func main() {
Expand All @@ -32,7 +32,7 @@ func main() {
Exec: execute.NewDefaultExecute(
execute.WithEnvVar("ANSIBLE_FORCE_COLOR", "true"),
execute.WithTransformers(
results.Prepend("Go-ansible example with become"),
transformer.Prepend("Go-ansible example with become"),
),
),
}
Expand Down
Loading

0 comments on commit 31c3110

Please sign in to comment.