{"id":36865588,"url":"https://github.com/gen0cide/renum","last_synced_at":"2026-01-12T14:53:34.535Z","repository":{"id":57517082,"uuid":"203839405","full_name":"gen0cide/renum","owner":"gen0cide","description":"Go utility to generate idiomatic Go enums with a diverse set of features and options.","archived":false,"fork":false,"pushed_at":"2023-07-26T16:26:29.000Z","size":209,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-15T10:53:55.399Z","etag":null,"topics":["cli","codegen","enums","errors","go","godoc"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gen0cide.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2019-08-22T17:10:09.000Z","updated_at":"2024-12-12T05:19:43.000Z","dependencies_parsed_at":"2024-06-20T09:24:23.951Z","dependency_job_id":"f1832f88-b915-449d-a677-67bd09b3fba8","html_url":"https://github.com/gen0cide/renum","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/gen0cide/renum","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen0cide%2Frenum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen0cide%2Frenum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen0cide%2Frenum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen0cide%2Frenum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gen0cide","download_url":"https://codeload.github.com/gen0cide/renum/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gen0cide%2Frenum/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28340411,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cli","codegen","enums","errors","go","godoc"],"created_at":"2026-01-12T14:53:33.811Z","updated_at":"2026-01-12T14:53:34.525Z","avatar_url":"https://github.com/gen0cide.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# renum - strongly typed Go enums\n\n## Overview [![GoDoc](https://godoc.org/github.com/gen0cide/renum?status.svg)](https://godoc.org/github.com/gen0cide/renum) [![Sourcegraph](https://sourcegraph.com/github.com/gen0cide/renum/-/badge.svg)](https://sourcegraph.com/github.com/gen0cide/renum?badge)\n\nGo package that provides a rich, descriptive interface for developers to use in order to allow enums to cross package boundries without loosing important details and metadata.\n\nAlso a CLI utility to generate idiomatic Go enums with a diverse set of features and options (that allow you to easily satisfy the `renum` interface ^.^)\n\n*NOTE: This library is in it's early stage, so I wouldn't call it production stable yet. But any PRs and comments are welcome!*\n\n## Background\n\nGo's language, while expressive, has shortcomings around propogation of type information with commonly used code. A great example of this is the [error](https://golang.org/pkg/errors/) interface that's built into the language.\n\nWhile Go lets you define custom error types (`*os.PathError` is one example), generally developers end up simply using the standard `errors.New` to generate a type that satisfies `error`, but is basically a string containing whatever you passed to `New()`.\n\nAs Go (rightly) attempts to force you to handle your errors, it often involves passing errors around, with the expectation that the caller likely  wants to make decisions about what to do. This is an incredibly powerful paradigm, and why I fully support **not** including constructs like exception handling into the runtime.\n\nAn example of this occurred for myself recently with the [github.com/masterzen/winrm](https://github.com/masterzen/winrm) package. I was using it to make WinRM connections to a Windows host, but I kept getting an error relating to response header timeouts. Is this happening within `winrm` or `net/http` or `net`? The only way to answer that question was to print the error to the console and begin grepping through source trees, looking for string literals that use those words.\n\nWhile generically this system is cheap, efficient, and allows broad adoption - it begins to age when working with large, complex codebases where error propagation becomes a lot of manual logging of error messages, with human review consuming considerable time. Forgetting how much `return nil, errors.New(\"this is bad\")` you see, typically this is the \"idiomatic\" way to define error types in Go:\n\n```go\nvar (\n  // ErrUnauthorized is thrown when a request is not authorized to perform a function.\n  ErrUnauthorized = errors.New(\"request unauthorized\")\n\n  // ErrInvalidSQLQuery is thrown when the provided SQL query was not a valid SQL expression.\n  ErrInvalidSQLQuery = errors.New(\"invalid sql query\")\n)\n```\n\nThis creats code that is easy to read and now is comparable (even type comparable), hear me out. Imagine a situation where this is printed to a log. You'd see a message of \"requested unauthorized\". What happens though when another package does this:\n\n```go\nreturn nil, errors.New(\"request unauthorized\")\n```\n\n### Solution\n\n`renum` aims to solve this by allow users define \"constant\" (types that don't change after compilation) types that conform to a more machine friendly and descriptive interface. While errors are a great use case, they certainly aren't the **only** paradigm where this benefits. The interface aims to push users not to write these type definitions by hand, but to generate them with codegen. You certainly could write a type that satisfies `renum.Enum` or `renum.Error`, but after seeing how easy it is to generate, I think you'll gladly let the `renum` utility do the heavy lifting :smiley:\n\nSimply define your types in in YAML:\n\n```yaml\n# Enum configuration\ngo:\n  name: ErrorCode\n  package_name: lib\n  package_path: github.com/gen0cide/renum/example/lib\nplugins:\n  error: true\n  text: true\n  json: true\n  yaml: true\n  sql: true\n  description: true\nvalues:\n  - name: unauthorized\n    message: The request was unauthorized.\n    comment: Unauthorized is thrown when the request action cannot be taken.\n    description: This error is used to signify that the request was made by an *authenticated* requester, but that requester is not authorized to perform the requested action.\n  - name: invalid_sql_query\n    message: The provided query was not valid SQL.\n    comment: InvalidSQLQuery is thrown when a user supplied SQL query is not valid.\n    description: This error often means the caller should perform further validation in order to locate situations where they're taking unsanitized input from users and interpolating that value directly into the SQL query.\n\n\n```\n\nand use the `renum generate` command in order to codegen a much better error paradigm:\n\n```sh\n$ renum -c error_code.yaml generate -o .\n[✓] parsed configuration\n[✓] initialized generator\n[✓] generated Go code\n[✓] successfully wrote code to generated_error_codes.go\n$\n```\n\nAnd if you opened up `generated_error_codes.go`, you'd see something that looks like this:\n\n```go\n// ErrorCode is a generated type alias for the ErrorCode enum.\ntype ErrorCode int\n\nconst (\n  // ErrorCodeUnknown is an enum value for type ErrorCode.\n  // ErrorCodeUnknown is the default value for enum type ErrorCode. It is meant to be a placeholder and default for unknown values.\n  // This value is a default placeholder for any unknown type for the lib.ErrorCode enum.\n  ErrorCodeUnknown ErrorCode = iota\n\n  // ErrorCodeUnauthorized is an enum value for type ErrorCode.\n  // Unauthorized is thrown when the request action cannot be taken.\n  // This error is used to signify that the request was made by an *authenticated* requester, but that requester is not authorized to perform the requested action.\n  ErrorCodeUnauthorized\n\n  // ErrorCodeInvalidSQLQuery is an enum value for type ErrorCode.\n  // InvalidSQLQuery is thrown when a user supplied SQL query is not valid.\n  // This error often means the caller should perform further validation in order to locate situations where they're taking unsanitized input from users and interpolating that value directly into the SQL query.\n  ErrorCodeInvalidSQLQuery\n\n// ... more code below\n```\n\nTo demonstrate how this is now a much richer error interface, I've created a small example program that shows how this now looks to the human eye. I've pasted the output of the example program to demonstrate what features you now have:\n\n```sh\n$ go run main.go\n[+] renum.Coder interface\n[✓] Code() = 2\n\n[+] renum.Namespacer interface\n[✓] Namespace() = github.com.gen0cide.renum.cmd.renum.example.lib\n[✓]      Path() = github.com.gen0cide.renum.cmd.renum.example.lib.error_code_invalid_sql_query\n\n[+] renum.Typer interface\n[✓]        Kind() = lib.ErrorCodeInvalidSQLQuery\n[✓]      Source() = github.com/gen0cide/renum/cmd/renum/example/lib.ErrorCodeInvalidSQLQuery\n[✓] PackageName() = lib\n[✓]  ImportPath() = github.com/gen0cide/renum/cmd/renum/example/lib\n\n[+] renum.Descriptioner interface\n[✓] Description() = This error often means the caller should perform further validation in order to locate situations where they're taking unsanitized input from users and interpolating that value directly into the SQL query.\n\n[+] fmt.Stringer interface\n[✓] String() = invalid_sql_query\n\n[+] error interface\n[✓] Error() = github.com.gen0cide.renum.cmd.renum.example.lib.error_code_invalid_sql_query (2): The provided query was not valid SQL.\n$\n```\n\nWe've effectively created a situation where errors are isolated into their namespace - they have identity, lineage, descriptive information, and satisfy the interface correctly. And of course, great [Godocs](https://godoc.org/github.com/gen0cide/renum/example/lib). This is the power of strongly typed enums in Go.\n\n## Generating Enums w/ CLI\n\nTo install the CLI:\n\n```sh\ngo get github.com/gen0cide/renum/cmd/renum\n```\n\n### YAML Configuration Format\n\nAn example and YAML configuration file outlining all options can be found in the `config_spec.yaml` file inside this repo.\n\n### Example\n\nBelow shows an example of how you can write your enums in YAML, then with the renum codegen tool, generate your Go code. The example files can be found in the examples folder of the CLI.\n\n```sh\n# write your YAML configuration file...\n$ renum -c error_code.yaml generate\n[✓] parsed configuration\n[✓] initialized generator\n[✓] generated Go code\n[✓] successfully wrote code to generated_error_codes.go\n$\n```\n\n## Library\n\nTo use the interfaces, simply install the library with:\n\n```sh\ngo get github.com/gen0cide/renum\n```\n\n## Inspiration / Prior Works\n\nBoth [go-enum](https://github.com/abice/go-enum) and [enumer](https://github.com/alvaroloes/enumer) do very similar things, but have some shortcomings. Both of them rely on AST parsing - meaning if your code is not parsable due to errors, you cannot generate your enums. Secondly, they don't provide easy mechanisms to enrich your types with additional methods and functionality.\n\nThis project started as a fork of `go-enum`, but ended up on it's own trajectory given the number of interfaces I wanted the enums to be able to implement. Their work is great and I think they have their uses, but were too limited to implement the strict paradigm of `renum`.\n\n## Author\n\n* \u003chttps://github.com/gen0cide\u003e\n* \u003chttps://twitter.com/alexlevinson\u003e\n* \u003chttps://www.linkedin.com/in/alexlevinson/\u003e\n\n## Shoutouts\n\n* mbm\n* davehughes\n* ychen\n* emperorcow\n* m0\n* vyrus001\n* hecfblog\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgen0cide%2Frenum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgen0cide%2Frenum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgen0cide%2Frenum/lists"}