{"id":13619447,"url":"https://github.com/kokizzu/goproc","last_synced_at":"2025-08-29T03:32:58.764Z","repository":{"id":57521890,"uuid":"252402762","full_name":"kokizzu/goproc","owner":"kokizzu","description":"simple process manager helper library","archived":false,"fork":false,"pushed_at":"2024-12-12T09:32:04.000Z","size":102,"stargazers_count":25,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-23T03:32:57.828Z","etag":null,"topics":["go","golang","process-manager"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kokizzu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-04-02T08:50:00.000Z","updated_at":"2024-12-12T09:32:05.000Z","dependencies_parsed_at":"2024-05-13T14:28:59.653Z","dependency_job_id":"6a836d84-04fa-4481-9407-282be387cbc4","html_url":"https://github.com/kokizzu/goproc","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/kokizzu/goproc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokizzu%2Fgoproc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokizzu%2Fgoproc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokizzu%2Fgoproc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokizzu%2Fgoproc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kokizzu","download_url":"https://codeload.github.com/kokizzu/goproc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokizzu%2Fgoproc/sbom","scorecard":{"id":566187,"data":{"date":"2025-08-11","repo":{"name":"github.com/kokizzu/goproc","commit":"b89ecfd479a6b70a57a175b9e44d0287b8f848e7"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: goCommand not pinned by hash: pullpush.sh:16","Info:   0 out of   1 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T15:02:24.816Z","repository_id":57521890,"created_at":"2025-08-20T15:02:24.816Z","updated_at":"2025-08-20T15:02:24.816Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272619441,"owners_count":24965415,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","process-manager"],"created_at":"2024-08-01T21:00:40.931Z","updated_at":"2025-08-29T03:32:58.733Z","avatar_url":"https://github.com/kokizzu.png","language":"Go","funding_links":[],"categories":["G"],"sub_categories":[],"readme":"# goproc\n\n**NOTE**: versions before `v1.4502.2114` are deleted because it have goroutine leaks.\n\nSimple process manager helper library, features:\n\n* start processes `.AddCommand(Cmd)` and `.Start(cmdId)` or `.StartAll()`, with environment variables `Cmd.Env=[]string{}` and `Cmd.InheritEnv=true` \n* stop them; `.Kill(cmdId)` or `.Cleanup()` to kill all process\n* restart them when they crash; using `Cmd.RestartDelayMs=1000` (=1s, default is 0) and `Cmd.MaxRestart=5` (restart 5x if process ended/crashed)\n* relay termination signals; `.Signal(cmdId, os.Kill)`\n* read their stdout and stderr; `Cmd.OnStdout`, `Cmd.OnStdErr` callback\n* ability to stop processes when main processes are SIGKILL'ed: `.Cleanup()` called automatically when main process killed;\n* configurable backoff strategy for restarts; you can use `Cmd.OnRestart` callback to return random delay or implement your own exponential backoff, setting this callback will render `Cmd.RestartDelayMs` unusable\n* `Cmd.OnExit` callback when no more restart reached, you can call `.Start(cmdId)` manually again after this\n* `Cmd.OnProcessCompleted` callback each time program completed once (before restarting if MaxRestart not yet reached)\n* `Cmd.StartDelayMs=1000` (=1s, default is 0) for delaying start, in milliseconds\n* `Cmd.UseChannelApi=true`, if enabled, you can receive from channels: `Cmd.StderrChannel`, `Cmd.OnStdoutChannel`, `Cmd.ProcessCompletedChannel`, `Cmd.ExitChannel` \n* `Cmd.LastExecutionError` property to get last process execution error, check this [answer](//stackoverflow.com/questions/10385551/get-exit-code-go) to get the exit code\n* `Cmd.OnStateChanged` callback and `Cmd.StateChangedChannel` channel to track process state\n* should work on Linux, and probably MacOS and Windows (untested).\n* see [example/](//github.com/kokizzu/goproc/blob/master/example/main.go) for other usage example/demo;\n\n## Versioning\n\nversioning using this format 1.`(M+(YEAR-2021)*12)DD`.`HMM`,\nso for example v1.213.1549 means it was released at `2021-02-13 15:49`\n\n## Example\n\n```go\n\ndaemon := goproc.New()\n\ncmdId := daemon.AddCommand(\u0026goproc.Cmd{\n    Program: `sleep`, // program to run\n\tWorkDir: `/tmp`, // directory to run the program (optional)\n    Parameters: []string{`2`}, // command line arguments\n    MaxRestart: goproc.RestartForever, // default: NoRestart=0\n    OnStderr: func(cmd *goproc.Cmd, line string) error { // optional\n        fmt.Println(`OnStderr: `+line)\n        return nil\n    },\n    OnStdout: func(cmd *goproc.Cmd, line string) error { // optional\n        fmt.Println(`OnStdout: `+line)\n        return nil\n    },\n})\n\ndaemon.Start(cmdId) // use \"go\" keyword if you need non-blocking version\n// ^ by default will only run next command if previous command exited\n// if you want to run them in parralel, use daemon.StartParallel().Wait()\n\ndaemon.CommandString(cmdId) // returns \"sleep 2\"\n```\n\nAlternatively there's shortcut with `Run1` returns string `stdout` and `stderr`, `error`, and `exitCode`. Also there's `RunLines` returns `[]string` instead of `string`.\n\n## FAQ\n\nQ: Why not just channel? why callback?\n\nA: Because channel requires a consumer, or it would stuck/block if channel is full, while callback doesn't (this is why I add flag to activate the channel API). To the Percona reviewer that rejected me because I didn't use channel at the first time \"the whole thing is written in JavaScript translated to Go, not in Go. Technical task does not adhere to Go best practices which is what would expect from the candidate. One example was that the code is written in JS-like style (e.g. callback). Go code does not use callback like node.js for example\", well, jokes on you even `net/http.HandleFunc` uses callback XD\n\nQ: How to ignore error being printed?\n\nA: assign `Goproc.HasErrFunc` with `goproc.DiscardHasErr`, other option are: `L.IsError` (default), `goproc.LogHasErr` (uses log), `goproc.PrintHasErr` (uses fmt), or you can always create your own.\n\n## TODO\n\n* implement `.Pause` and `.Resume` API\n* comments and documentation in code;\n* continuous integration configuration;\n* integration tests;\n* unit tests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkokizzu%2Fgoproc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkokizzu%2Fgoproc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkokizzu%2Fgoproc/lists"}