Skip to content

Commit

Permalink
feat: hooks (#51)
Browse files Browse the repository at this point in the history
* refactor(internal/config/output.go): Improve handling of empty fields in ConfigVersion struct

- Updated loop logic to handle cases when fields are empty
- Removed unnecessary code block for handling reflected type
- Added function getAllFieldNames() to retrieve all field names of a given type
- Modified loop to iterate over all fields and assign values based on their presence in the reflected value
- Implemented check to ensure that the field exists before proceeding with assignment
- Updated test cases to cover the changes made

This commit refactors the handling of empty fields in the ConfigVersion struct, improving its functionality and readability. The modifications also increase the maintainability of the code by eliminating unnecessary repetition and adding a helper function for retrieving all field names of a given type.

* feat(version): Add run hook function to run commands by events

* feat(internal/cmd/bump.go): Implement post-bump, pre-changelog, and post-changelog script execution and changelog generation

* Add handling for running pre-changelog scripts before generating a changelog
* Modify the code to run post-changelog scripts after updating the changelog
* Update the function to apply the changelog and handle errors appropriately
* Implement post-bump script execution and error handling

This commit includes modifications to the internal/cmd/bump.go file, where changes have been made to run pre-changelog scripts before generating a changelog, implement post-changelog script execution and error handling after updating the changelog, and apply the changelog with proper error handling. Additionally, this commit includes running post-bump scripts and error handling for any issues that may arise during their execution.

* docs(README.md): version files and hooks configuration

- Implemented hooks for pre-bump, post-bump, pre-changelog and post-changelog processes in root directory
  • Loading branch information
sergiotejon authored Nov 8, 2024
1 parent d2f7a0e commit 67abbf9
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 29 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,38 @@ The `version` and `commit` fields are managed by Gommitizen. The `version_files`

`version_files` is a list of strings. Each string contains the path of the file and the name of the variable that contains the version. The path and the name of the variable are separated by a colon (`:`). The path is relative to the root of the project. Tha name of the variable can be replace by a regular expression to find the version in the file (remember to scape the special characters and group the version part of the expression with parentheses like in the example).

### Hooks

Example:

```json
{
"version": "0.18.1",
"commit": "72929b90547b8527e22e402b6784e0c7f5812428",
"version_files": [
"Chart.yaml:version",
"other-version.txt:version",
"a-file-that-need-a-regex.txt:^version=([0-9]+\\.[0-9]+\\.[0-9]+)$"
],
"prefix": "my-prj",
"hooks": {
"pre-bump": "echo 'pre-bump hook'",
"post-bump": "echo 'post-bump hook'",
"post-changelog": "echo 'post-changelog hook'",
"pre-changelog": "echo 'pre-changelog hook'"
}
}
```

There are four hooks available:

- `pre-bump`: Runs before the bump process.
- `post-bump`: Runs after the bump process.
- `pre-changelog`: Runs before the changelog generation.
- `post-changelog`: Runs after the changelog generation.

The hooks are shell commands that are executed in the root of the project. These are all optional fields.

## Development

To run the project in development mode, run:
Expand Down
25 changes: 25 additions & 0 deletions internal/cmd/bump.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ func bumpByConfig(configVersionPath string, createChangelog bool, incrementType

// If the file has been modified, update the version
if incrementType != "none" {
// Running pre-bump scripts
err = config.RunHook("pre-bump")
if err != nil {
return []string{}, "", fmt.Errorf("pre bump scripts: %s", err)
}

newVersion, newVersionStr, err := bumpmanager.IncrementVersion(config.Version, incrementType)
if err != nil {
return []string{}, "", fmt.Errorf("increment version: %s", err)
Expand All @@ -125,12 +131,31 @@ func bumpByConfig(configVersionPath string, createChangelog bool, incrementType
return []string{}, "", fmt.Errorf("update version: %s", err)
}

// Running post-bump scripts
err = config.RunHook("post-bump")
if err != nil {
return []string{}, "", fmt.Errorf("post bump scripts: %s", err)
}

if createChangelog {
// Running pre-changelog scripts
err = config.RunHook("pre-changelog")
if err != nil {
return []string{}, "", fmt.Errorf("pre changelog scripts: %s", err)
}

slog.Info("Generating changelog...")
changelogFilePath, err := changelog.Apply(config.GetDirPath(), config.Version, cvCommits)
if err != nil {
return []string{}, "", fmt.Errorf("update changelog: %s", err)
}
modifiedFiles = append(modifiedFiles, changelogFilePath)

// Running post-changelog scripts
err = config.RunHook("post-changelog")
if err != nil {
return []string{}, "", fmt.Errorf("post changelog scripts: %s", err)
}
}

slog.Info("Commit messages:")
Expand Down
49 changes: 24 additions & 25 deletions internal/config/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"reflect"
"strings"

"gopkg.in/yaml.v3"
)
Expand Down Expand Up @@ -72,38 +73,28 @@ func configVersionFilter(configVersions []*ConfigVersion, fields []string, outpu
cvw := ConfigVersionWrapper{
DirPath: configVersion.GetDirPath(),
FilePath: configVersion.GetFilePath(),
ConfigVersion: make(map[string]interface{}, 0),
ConfigVersion: make(map[string]interface{}),
}

val := reflect.ValueOf(configVersion).Elem()
typ := val.Type()

if len(fields) > 0 {
for _, field := range fields {
xField, ok := typ.FieldByName(field)
if !ok {
continue // Si el campo no existe, pasamos al siguiente
}
xValue := val.FieldByName(field)
if xValue.IsValid() && xValue.CanInterface() {
xTag := xField.Tag.Get(outputFormat)
if xTag == "" {
xTag = field
}
cvw.ConfigVersion[xTag] = xValue.Interface()
}
if len(fields) == 0 {
fields = getAllFieldNames(typ)
}

for _, field := range fields {
xField, ok := typ.FieldByName(field)
if !ok {
continue
}
} else {
for i := 0; i < val.NumField(); i++ {
xField := typ.Field(i)
xValue := val.Field(i)
if xValue.IsValid() && xValue.CanInterface() {
xTag := xField.Tag.Get(outputFormat)
if xTag == "" {
xTag = xField.Name
}
cvw.ConfigVersion[xTag] = xValue.Interface()
xValue := val.FieldByName(field)
if xValue.IsValid() && xValue.CanInterface() {
xTag := strings.Split(xField.Tag.Get(outputFormat), ",")[0]
if xTag == "" {
xTag = field
}
cvw.ConfigVersion[xTag] = xValue.Interface()
}
}

Expand All @@ -112,3 +103,11 @@ func configVersionFilter(configVersions []*ConfigVersion, fields []string, outpu

return wrapper
}

func getAllFieldNames(typ reflect.Type) []string {
var fields []string
for i := 0; i < typ.NumField(); i++ {
fields = append(fields, typ.Field(i).Name)
}
return fields
}
28 changes: 24 additions & 4 deletions internal/config/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"log/slog"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
Expand All @@ -14,10 +15,11 @@ import (
type ConfigVersion struct {
dirPath string

Version string `json:"version" yaml:"version" plain:"version"`
Commit string `json:"commit" yaml:"commit" plain:"commit"`
VersionFiles []string `json:"version_files" yaml:"version_files" plain:"version_files"`
TagPrefix string `json:"tag_prefix" yaml:"tag_prefix" plain:"tag_prefix"`
Version string `json:"version" yaml:"version" plain:"version"`
Commit string `json:"commit" yaml:"commit" plain:"commit"`
VersionFiles []string `json:"version_files" yaml:"version_files" plain:"version_files"`
TagPrefix string `json:"tag_prefix" yaml:"tag_prefix" plain:"tag_prefix"`
Hooks map[string]string `json:"hooks,omitempty" yaml:"hooks,omitempty"`
}

func NewConfigVersion(dirPath string, version string, commit string, tagPrefix string) *ConfigVersion {
Expand Down Expand Up @@ -81,6 +83,24 @@ func (v ConfigVersion) GetTagVersion() string {
return v.Version
}

func (v *ConfigVersion) RunHook(hookName string) error {
hook, ok := v.Hooks[hookName]
if !ok {
slog.Debug(fmt.Sprintf("hook %s not found", hookName))
return nil
}

output, err := exec.Command("bash", "-c", hook).CombinedOutput()
if err != nil {
return fmt.Errorf("run hook %s: %v", hookName, err)
}

// TODO: Pretty log info with colors
slog.Info(fmt.Sprintf("\n\033[32mHook %s output:\n%s\033[0m", hookName, string(output)))

return nil
}

func (v *ConfigVersion) UpdateVersion(newVersion string, lastCommit string) ([]string, error) {
modifiedFiles := make([]string, 0)

Expand Down

0 comments on commit 67abbf9

Please sign in to comment.