Compare commits
No commits in common. "c24e8086e9863408801c50f9f2b567565b961852" and "e169778c82dc699acfa14d38aa747a7d1cb2e0c2" have entirely different histories.
c24e8086e9
...
e169778c82
@ -1,3 +0,0 @@
|
|||||||
## v0.6.1 - 2025-01-04
|
|
||||||
### Fixed
|
|
||||||
* Hooks now run explicitly after the command executes. Fixed panic due to improper logic.
|
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,2 @@
|
|||||||
|
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
.codegpt
|
|
@ -6,10 +6,6 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
|||||||
and is generated by [Changie](https://github.com/miniscruff/changie).
|
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||||
|
|
||||||
|
|
||||||
## v0.6.1 - 2025-01-04
|
|
||||||
### Fixed
|
|
||||||
* Hooks now run explicitly after the command executes. Fixed panic due to improper logic.
|
|
||||||
|
|
||||||
## v0.6.0 - 2025-01-04
|
## v0.6.0 - 2025-01-04
|
||||||
### Added
|
### Added
|
||||||
* Command Type Package - allows one to perform package operations [docs](https://backy.cybershell.xyz/config/packages/)
|
* Command Type Package - allows one to perform package operations [docs](https://backy.cybershell.xyz/config/packages/)
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
const versionStr = "0.6.1"
|
const versionStr = "0.6.0"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
versionCmd = &cobra.Command{
|
versionCmd = &cobra.Command{
|
||||||
|
@ -144,123 +144,115 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
|
|||||||
return outputArr, nil
|
return outputArr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, results chan<- CmdResult, opts *ConfigOpts) {
|
// cmdListWorker
|
||||||
|
func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, results chan<- string, opts *ConfigOpts) {
|
||||||
|
// iterate over list to run
|
||||||
|
res := CmdListResults{}
|
||||||
for list := range jobs {
|
for list := range jobs {
|
||||||
fieldsMap := map[string]interface{}{"list": list.Name}
|
fieldsMap := make(map[string]interface{})
|
||||||
|
fieldsMap["list"] = list.Name
|
||||||
var cmdLogger zerolog.Logger
|
var cmdLogger zerolog.Logger
|
||||||
var cmdsRan []string
|
|
||||||
var outStructArr []outStruct
|
var count int // count of how many commands have been executed
|
||||||
var hasError bool // Tracks if any command in the list failed
|
var cmdsRan []string // store the commands that have been executed
|
||||||
|
var outStructArr []outStruct // stores output messages
|
||||||
|
|
||||||
for _, cmd := range list.Order {
|
for _, cmd := range list.Order {
|
||||||
|
|
||||||
|
currentCmd := opts.Cmds[cmd].Name
|
||||||
|
|
||||||
|
fieldsMap["cmd"] = opts.Cmds[cmd].Name
|
||||||
cmdToRun := opts.Cmds[cmd]
|
cmdToRun := opts.Cmds[cmd]
|
||||||
currentCmd := cmdToRun.Name
|
|
||||||
fieldsMap["cmd"] = currentCmd
|
|
||||||
cmdLogger = cmdToRun.GenerateLogger(opts)
|
cmdLogger = cmdToRun.GenerateLogger(opts)
|
||||||
cmdLogger.Info().Fields(fieldsMap).Send()
|
cmdLogger.Info().Fields(fieldsMap).Send()
|
||||||
|
|
||||||
outputArr, runErr := cmdToRun.RunCmd(cmdLogger, opts)
|
outputArr, runOutErr := cmdToRun.RunCmd(cmdLogger, opts)
|
||||||
|
|
||||||
|
if list.NotifyConfig != nil {
|
||||||
|
|
||||||
|
// check if the command output should be included
|
||||||
|
if cmdToRun.GetOutput || list.GetOutput {
|
||||||
|
outputStruct := outStruct{
|
||||||
|
CmdName: cmdToRun.Name,
|
||||||
|
CmdExecuted: currentCmd,
|
||||||
|
Output: outputArr,
|
||||||
|
}
|
||||||
|
|
||||||
|
outStructArr = append(outStructArr, outputStruct)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
if runOutErr != nil {
|
||||||
|
res.ErrCmd = cmd
|
||||||
|
if list.NotifyConfig != nil {
|
||||||
|
var errMsg bytes.Buffer
|
||||||
|
errStruct := make(map[string]interface{})
|
||||||
|
|
||||||
|
errStruct["listName"] = list.Name
|
||||||
|
errStruct["Command"] = currentCmd
|
||||||
|
errStruct["Cmd"] = cmd
|
||||||
|
errStruct["Args"] = opts.Cmds[cmd].Args
|
||||||
|
errStruct["Err"] = runOutErr
|
||||||
|
errStruct["CmdsRan"] = cmdsRan
|
||||||
|
errStruct["Output"] = outputArr
|
||||||
|
|
||||||
|
errStruct["CmdOutput"] = outStructArr
|
||||||
|
|
||||||
|
tmpErr := msgTemps.err.Execute(&errMsg, errStruct)
|
||||||
|
|
||||||
|
if tmpErr != nil {
|
||||||
|
cmdLogger.Err(tmpErr).Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
notifySendErr := list.NotifyConfig.Send(context.Background(), fmt.Sprintf("List %s failed", list.Name), errMsg.String())
|
||||||
|
|
||||||
|
if notifySendErr != nil {
|
||||||
|
cmdLogger.Err(notifySendErr).Send()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdLogger.Err(runOutErr).Send()
|
||||||
|
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
|
||||||
cmdsRan = append(cmdsRan, cmd)
|
cmdsRan = append(cmdsRan, cmd)
|
||||||
|
|
||||||
if runErr != nil {
|
if count == len(list.Order) {
|
||||||
|
var successMsg bytes.Buffer
|
||||||
|
|
||||||
// Log the error and send a failed result
|
// if notification config is not nil, and NotifyOnSuccess is true or GetOuput is true,
|
||||||
cmdLogger.Err(runErr).Send()
|
// then send notification
|
||||||
results <- CmdResult{CmdName: cmd, ListName: list.Name, Error: runErr}
|
if list.NotifyConfig != nil && (list.NotifyOnSuccess || list.GetOutput) {
|
||||||
|
successStruct := make(map[string]interface{})
|
||||||
|
|
||||||
// Execute error hooks for the failed command
|
successStruct["listName"] = list.Name
|
||||||
cmdToRun.ExecuteHooks("error", opts)
|
successStruct["CmdsRan"] = cmdsRan
|
||||||
|
|
||||||
// Notify failure
|
successStruct["CmdOutput"] = outStructArr
|
||||||
if list.NotifyConfig != nil {
|
|
||||||
notifyError(cmdLogger, msgTemps, list, cmdsRan, outStructArr, runErr, cmdToRun, opts)
|
tmpErr := msgTemps.success.Execute(&successMsg, successStruct)
|
||||||
}
|
|
||||||
hasError = true
|
if tmpErr != nil {
|
||||||
|
cmdLogger.Err(tmpErr).Send()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect output if required
|
err := list.NotifyConfig.Send(context.Background(), fmt.Sprintf("List %s succeeded", list.Name), successMsg.String())
|
||||||
if list.GetOutput || cmdToRun.GetOutput {
|
|
||||||
outStructArr = append(outStructArr, outStruct{
|
if err != nil {
|
||||||
CmdName: currentCmd,
|
cmdLogger.Err(err).Send()
|
||||||
CmdExecuted: currentCmd,
|
|
||||||
Output: outputArr,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify success if no errors occurred
|
|
||||||
if !hasError && list.NotifyConfig != nil && (list.NotifyOnSuccess || list.GetOutput) {
|
|
||||||
notifySuccess(cmdLogger, msgTemps, list, cmdsRan, outStructArr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute success and final hooks for all commands
|
|
||||||
for _, cmd := range list.Order {
|
|
||||||
cmdToRun := opts.Cmds[cmd]
|
|
||||||
|
|
||||||
// Execute success hooks if the command succeeded
|
|
||||||
if !hasError || cmdsRanContains(cmd, cmdsRan) {
|
|
||||||
cmdToRun.ExecuteHooks("success", opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute final hooks for every command
|
|
||||||
cmdToRun.ExecuteHooks("final", opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the final result for the list
|
|
||||||
if hasError {
|
|
||||||
results <- CmdResult{CmdName: cmdsRan[len(cmdsRan)-1], ListName: list.Name, Error: fmt.Errorf("list execution failed")}
|
|
||||||
} else {
|
|
||||||
results <- CmdResult{CmdName: cmdsRan[len(cmdsRan)-1], ListName: list.Name, Error: nil}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to check if a command is in the list of executed commands
|
results <- res.ErrCmd
|
||||||
func cmdsRanContains(cmd string, cmdsRan []string) bool {
|
|
||||||
for _, c := range cmdsRan {
|
|
||||||
if c == cmd {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to notify errors
|
|
||||||
func notifyError(logger zerolog.Logger, templates *msgTemplates, list *CmdList, cmdsRan []string, outStructArr []outStruct, err error, cmd *Command, opts *ConfigOpts) {
|
|
||||||
errStruct := map[string]interface{}{
|
|
||||||
"listName": list.Name,
|
|
||||||
"CmdsRan": cmdsRan,
|
|
||||||
"CmdOutput": outStructArr,
|
|
||||||
"Err": err,
|
|
||||||
"Command": cmd.Name,
|
|
||||||
"Args": cmd.Args,
|
|
||||||
}
|
|
||||||
var errMsg bytes.Buffer
|
|
||||||
if e := templates.err.Execute(&errMsg, errStruct); e != nil {
|
|
||||||
logger.Err(e).Send()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if e := list.NotifyConfig.Send(context.Background(), fmt.Sprintf("List %s failed", list.Name), errMsg.String()); e != nil {
|
|
||||||
logger.Err(e).Send()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper to notify success
|
|
||||||
func notifySuccess(logger zerolog.Logger, templates *msgTemplates, list *CmdList, cmdsRan []string, outStructArr []outStruct) {
|
|
||||||
successStruct := map[string]interface{}{
|
|
||||||
"listName": list.Name,
|
|
||||||
"CmdsRan": cmdsRan,
|
|
||||||
"CmdOutput": outStructArr,
|
|
||||||
}
|
|
||||||
var successMsg bytes.Buffer
|
|
||||||
if e := templates.success.Execute(&successMsg, successStruct); e != nil {
|
|
||||||
logger.Err(e).Send()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if e := list.NotifyConfig.Send(context.Background(), fmt.Sprintf("List %s succeeded", list.Name), successMsg.String()); e != nil {
|
|
||||||
logger.Err(e).Send()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunListConfig runs a command list from the ConfigFile.
|
// RunListConfig runs a command list from the ConfigFile.
|
||||||
@ -271,40 +263,51 @@ func (opts *ConfigOpts) RunListConfig(cron string) {
|
|||||||
}
|
}
|
||||||
configListsLen := len(opts.CmdConfigLists)
|
configListsLen := len(opts.CmdConfigLists)
|
||||||
listChan := make(chan *CmdList, configListsLen)
|
listChan := make(chan *CmdList, configListsLen)
|
||||||
results := make(chan CmdResult, configListsLen)
|
results := make(chan string)
|
||||||
|
|
||||||
// Start workers
|
// This starts up list workers, initially blocked
|
||||||
|
// because there are no jobs yet.
|
||||||
for w := 1; w <= configListsLen; w++ {
|
for w := 1; w <= configListsLen; w++ {
|
||||||
go cmdListWorker(mTemps, listChan, results, opts)
|
go cmdListWorker(mTemps, listChan, results, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enqueue jobs
|
|
||||||
for listName, cmdConfig := range opts.CmdConfigLists {
|
for listName, cmdConfig := range opts.CmdConfigLists {
|
||||||
if cmdConfig.Name == "" {
|
if cmdConfig.Name == "" {
|
||||||
cmdConfig.Name = listName
|
cmdConfig.Name = listName
|
||||||
}
|
}
|
||||||
if cron == "" || cron == cmdConfig.Cron {
|
if cron != "" {
|
||||||
|
if cron == cmdConfig.Cron {
|
||||||
|
listChan <- cmdConfig
|
||||||
|
}
|
||||||
|
} else {
|
||||||
listChan <- cmdConfig
|
listChan <- cmdConfig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(listChan)
|
close(listChan)
|
||||||
|
|
||||||
// Process results
|
|
||||||
for a := 1; a <= configListsLen; a++ {
|
for a := 1; a <= configListsLen; a++ {
|
||||||
result := <-results
|
l := <-results
|
||||||
opts.Logger.Debug().Msgf("Processing result for list %s, command %s", result.ListName, result.CmdName)
|
|
||||||
|
opts.Logger.Debug().Msg(l)
|
||||||
|
|
||||||
|
if l != "" {
|
||||||
|
// execute error hooks
|
||||||
|
opts.Logger.Debug().Msg("hooks are working")
|
||||||
|
opts.Cmds[l].ExecuteHooks("error", opts)
|
||||||
|
} else {
|
||||||
|
// execute success hooks
|
||||||
|
opts.Cmds[l].ExecuteHooks("success", opts)
|
||||||
|
|
||||||
// Process final hooks for the list (already handled in worker)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// execute final hooks
|
||||||
|
opts.Cmds[l].ExecuteHooks("final", opts)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
opts.closeHostConnections()
|
opts.closeHostConnections()
|
||||||
}
|
}
|
||||||
|
|
||||||
type CmdResult struct {
|
|
||||||
CmdName string // Name of the command executed
|
|
||||||
ListName string // Name of the command list
|
|
||||||
Error error // Error encountered, if any
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *ConfigOpts) ExecuteCmds(opts *ConfigOpts) {
|
func (config *ConfigOpts) ExecuteCmds(opts *ConfigOpts) {
|
||||||
for _, cmd := range opts.executeCmds {
|
for _, cmd := range opts.executeCmds {
|
||||||
cmdToRun := opts.Cmds[cmd]
|
cmdToRun := opts.Cmds[cmd]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user