diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index e381c96..b73fc2c 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,4 +1,2 @@ -github: - - jtprogru - - t0pep0 +github: [ "jtprogru", "t0pep0" ] diff --git a/.github/RELEASE-TEMPLATE.md b/.github/RELEASE-TEMPLATE.md index 99c6d3c..cf16c56 100644 --- a/.github/RELEASE-TEMPLATE.md +++ b/.github/RELEASE-TEMPLATE.md @@ -1,3 +1,4 @@ -# Announcements +# Release name -* First announcement +- First feature +- Second feature diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e39e907..1250902 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,9 @@ on: - push: - branches: [main] + workflow_run: + workflows: [ "GolangCI-lint" ] + branches: [ main ] + types: + - completed pull_request: branches: [main] @@ -11,38 +14,20 @@ defaults: shell: bash jobs: - lint: - name: Lint files - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v2.4.0 - - uses: actions/setup-go@v2 - with: - go-version: '1.16.4' - - name: golangci-lint - uses: golangci/golangci-lint-action@v2.5.2 - with: - version: latest - build: name: Build binary runs-on: 'ubuntu-latest' - needs: lint strategy: matrix: goosarch: - 'darwin/amd64' - - 'darwin/arm64' - - 'linux/386' - 'linux/amd64' - - 'linux/arm' - - 'linux/arm64' steps: - name: Checkout code uses: actions/checkout@v2.4.0 - uses: actions/setup-go@v2 with: - go-version: '1.17.3' + go-version: '1.17' - name: Get OS and arch info run: | @@ -63,6 +48,6 @@ jobs: with: body_path: ".github/RELEASE-TEMPLATE.md" draft: true - files: ${{env.BINARY_NAME}} + files: ${{ env.BINARY_NAME }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 0000000..659db33 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,30 @@ +on: + push: + paths: + - "go.sum" + - "go.mod" + - "**.go" + - ".github/workflows/golangci-lint.yml" + - ".golangci.yml" + pull_request: + paths: + - "go.sum" + - "go.mod" + - "**.go" + - ".github/workflows/golangci-lint.yml" + - ".golangci.yml" + +name: GolangCI-lint + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Lint + uses: golangci/golangci-lint-action@v2 + with: + version: v1.42.0 diff --git a/README.md b/README.md index 749d5f3..0b1b392 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,17 @@ # go-monkill [![Go Reference](https://pkg.go.dev/badge/github.com/jtprogru/go-monkill.svg)](https://pkg.go.dev/github.com/jtprogru/go-monkill) +[![GolangCI-lint](https://github.com/jtprogru/go-monkill/actions/workflows/golangci-lint.yml/badge.svg)](https://github.com/jtprogru/go-monkill/actions/workflows/golangci-lint.yml) [![build](https://github.com/jtprogru/go-monkill/actions/workflows/build.yml/badge.svg)](https://github.com/jtprogru/go-monkill/actions/workflows/build.yml) [![publish](https://github.com/jtprogru/go-monkill/actions/workflows/publish.yml/badge.svg)](https://github.com/jtprogru/go-monkill/actions/workflows/publish.yml) [![GitHub stars](https://img.shields.io/github/stars/jtprogru/go-monkill.svg)](https://github.com/jtprogru/go-monkill/stargazers) [![GitHub issues](https://img.shields.io/github/issues-raw/jtprogru/go-monkill)](https://github.com/jtprogru/go-monkill/issues) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/jtprogru/go-monkill)](https://github.com/jtprogru/go-monkill/releases/latest) -![GitHub](https://img.shields.io/github/license/jtprogru/go-monkill) -![Linux](https://img.shields.io/badge/-Linux-grey?logo=linux) +[![Go report](https://goreportcard.com/badge/github.com/jtprogru/go-monkill)](https://goreportcard.com/report/github.com/jtprogru/go-monkill) +[![GitHub](https://img.shields.io/github/license/jtprogru/go-monkill)](LICENSE) +[![Linux](https://img.shields.io/badge/-Linux-grey?logo=linux)](https://en.wikipedia.org/wiki/Linux) [![Donate](https://img.shields.io/badge/-Donate-yellow?logo=paypal)](https://paypal.me/jtprogru) +[![LoC](https://tokei.rs/b1/github/jtprogru/go-monkill)](https://github.com/jtprogru/go-monkill) A very simple utility that allows you to run the desired command or script as soon as a certain process with a known PID completes correctly or with an error. diff --git a/cmd/root.go b/cmd/root.go index 1e34110..f930418 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,12 +1,16 @@ +// Package cmd contains all commands + package cmd import ( "github.com/spf13/cobra" ) -const Version string = "v0.1.1" +// Version of release +const Version string = "v0.2.0" -// rootCmd represents the base command when called without any subcommands +// rootCmd – default root command +// rootCmd show help message var rootCmd = &cobra.Command{ Use: "monkill", Short: "Monkill for watching a process will finish or be killed", diff --git a/cmd/version.go b/cmd/version.go index b053900..a91e55e 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -1,3 +1,5 @@ +// Package cmd contains all commands + package cmd import ( @@ -6,7 +8,7 @@ import ( "github.com/spf13/cobra" ) -// versionCmd represents the version command +// versionCmd – show current version of this package var versionCmd = &cobra.Command{ Use: "version", Short: "Print the version number of monkill", diff --git a/cmd/watch.go b/cmd/watch.go index 7773455..61838bb 100644 --- a/cmd/watch.go +++ b/cmd/watch.go @@ -1,3 +1,5 @@ +// Package cmd contains all commands + package cmd import ( @@ -9,7 +11,8 @@ import ( "github.com/spf13/cobra" ) -// watchCmd represents the watch command +// watchCmd – run watch func +// var watchCmd = &cobra.Command{ Use: "watch", Short: "A brief description of your command", @@ -17,33 +20,50 @@ var watchCmd = &cobra.Command{ For example: -go-monkill watch --pid=12345 --command="ping jtprog.ru -c 4"" +go-monkill watch --pid 12345 --command "ping jtprog.ru -c 4" `, RunE: func(cmd *cobra.Command, args []string) error { l := zerolog.New(os.Stderr) - return watcher(WatcherConfig.pid, WatcherConfig.command, waiter.Waiter{}, executor.Executor{}, l) + l.Level(zerolog.TraceLevel) + return watcher(WatcherConfig.pid, WatcherConfig.command, WatcherConfig.timeout, waiter.Waiter{}, executor.Executor{}, l) }, } +// Verbose flag +//var Verbose bool + +// defaultPid is -1 for +var defaultPid int = -1 + +// defaultTimeOut is 250 milliseconds +var defaultTimeOut int64 = 250 + // WatcherConfig provides config for watcher var WatcherConfig struct { pid int // Specified PID for process command string // Specified command for running + timeout int64 // Specified timeout for sleep } // Add command watchCmd to rootCmd // // &WatcherConfig pid as PID for monitoring – defined in flag --pid // &WatcherConfig command as command for running - defined in flag --command +// &WatcherConfig timeout as timeout for check process - defined in flag --timeout func init() { rootCmd.AddCommand(watchCmd) - watchCmd.PersistentFlags().IntVar(&WatcherConfig.pid, "pid", -1, "PID for watching") + // TODO: Implement verbose log output by flag --verbose + // rootCmd.InheritedFlags().BoolVar(&Verbose, "verbose", false, "Enable debug logging") + // TODO: Implement output to logfile by flag --logfile + // rootCmd.InheritedFlags().StringVar(&WatcherConfig.logfile, "logfile", "/tmp/go-monkill.log", "Enable debug logging") + watchCmd.PersistentFlags().IntVar(&WatcherConfig.pid, "pid", defaultPid, "PID for watching") watchCmd.PersistentFlags().StringVar(&WatcherConfig.command, "command", "ping jtprog.ru -c 2", "Command for running") + watchCmd.PersistentFlags().Int64Var(&WatcherConfig.timeout, "timeout", defaultTimeOut, "Set timeout for check status of process") } -// Waiter interface +// Waiter interface for monitor process PID every timeout milliseconds type Waiter interface { - Wait(pid int) (<-chan struct{}, error) + Wait(pid int, timeout int64) (<-chan struct{}, error) } // Executor interface @@ -51,9 +71,13 @@ type Executor interface { Exec(command string) error } -func watcher(pid int, command string, w Waiter, e Executor, l zerolog.Logger) error { +// watcher – run Waiter.Wait +// &WatcherConfig pid as PID for monitoring – defined in flag --pid +// &WatcherConfig command as command for running - defined in flag --command +// &WatcherConfig timeout as timeout for watch - defined in flag --timeout +func watcher(pid int, command string, timeout int64, w Waiter, e Executor, l zerolog.Logger) error { l.Info().Int("pid", pid).Str("command", command).Msg("Arguments readed") - ch, err := w.Wait(pid) + ch, err := w.Wait(pid, timeout) if err != nil { l.Error().Err(err).Msg("Break execution. Error on watch process") return err diff --git a/main.go b/main.go index 5824225..2c3d2e4 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,11 @@ +// Package go-monkill +// A very simple utility that allows you to run the desired command or script +// as soon as a certain process with a known PID completes correctly or with an error. +// +// For example: +// +// go-monkill watch --pid 12345 --command "ping jtprog.ru -c 4" + package main import "github.com/jtprogru/go-monkill/cmd" diff --git a/pkg/executor/executor.go b/pkg/executor/executor.go index ec7b614..a52d164 100644 --- a/pkg/executor/executor.go +++ b/pkg/executor/executor.go @@ -10,7 +10,8 @@ import ( // Executor struct type Executor struct{} -// Exec for running Executor with command +// Exec - running Executor with command (i.e.: "ping jtprog.ru -c 4" ) +// TODO: Implement verbose logging for output func (e Executor) Exec(command string) error { cmds := strings.Split(command, " ") if len(cmds) == 0 { diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index b4e0b8b..fb9d917 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -1,12 +1,17 @@ package waiter -import "github.com/mitchellh/go-ps" +import ( + "github.com/mitchellh/go-ps" + "time" +) // Waiter struct type Waiter struct{} -// Wait monitor process with defined PID -func (w Waiter) Wait(pid int) (<-chan struct{}, error) { +// Wait find process with defined PID and wait for process will finish or be killed. +// Checking the liveliness of the process occurs with a timeout delay. +// The timeout is set in milliseconds. +func (w Waiter) Wait(pid int, timeout int64) (<-chan struct{}, error) { _, err := ps.FindProcess(pid) if err != nil { return nil, err @@ -17,6 +22,7 @@ func (w Waiter) Wait(pid int) (<-chan struct{}, error) { if pc, _ := ps.FindProcess(pid); pc == nil { out <- struct{}{} } + time.Sleep(time.Duration(timeout) / time.Second) } }() return out, nil