{"id":21689642,"url":"https://github.com/schraf/codegen","last_synced_at":"2026-04-13T14:01:34.368Z","repository":{"id":231454052,"uuid":"330525656","full_name":"schraf/codegen","owner":"schraf","description":"generic code generation tool","archived":false,"fork":false,"pushed_at":"2026-01-27T13:57:02.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-28T01:02:59.983Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/schraf.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-01-18T01:39:43.000Z","updated_at":"2026-01-27T13:58:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"6aac5fd6-1cf9-45eb-a9b9-d0a55410d6b9","html_url":"https://github.com/schraf/codegen","commit_stats":null,"previous_names":["schraf/codegen"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/schraf/codegen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schraf%2Fcodegen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schraf%2Fcodegen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schraf%2Fcodegen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schraf%2Fcodegen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schraf","download_url":"https://codeload.github.com/schraf/codegen/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schraf%2Fcodegen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31755536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T13:27:56.013Z","status":"ssl_error","status_checked_at":"2026-04-13T13:21:23.512Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":[],"created_at":"2024-11-25T17:27:04.455Z","updated_at":"2026-04-13T14:01:34.361Z","avatar_url":"https://github.com/schraf.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Codegen\n\nA simple, template-based code generation tool written in Go. It uses Go's built-in `html/template` package to generate any kind of text-based file from JSON data sources.\n\n## How it Works\n\nThe tool is driven by a `project.json` file (or any other name passed as an argument) that defines the code generation tasks. This file specifies:\n\n-   **Includes:** A list of reusable, shared template files.\n-   **Outputs:** A list of files to generate, each with its own main template, input data file, and output path.\n\n## Usage\n\n1.  Create a `project.json` file to define your code generation tasks.\n2.  Run the tool, passing the project file as an argument.\n\n```bash\ngo run ./cmd/main.go project.json\n```\n\n## The `project.json` Format\n\nThe project file has two main sections: `includes` and `outputs`.\n\n-   `includes`: An array of strings, where each string is a path to a template file that can be included and reused in other templates. These are parsed first.\n-   `outputs`: An array of objects, where each object defines a file to be generated.\n\n### Output Object Structure\n\nEach object in the `outputs` array has the following properties:\n\n-   `template`: The path to the main template file for this output.\n-   `input`: The path to the JSON file containing the data to be used in the template.\n-   `output`: The path where the generated file will be saved.\n\n### Example `project.json`\n\n```json\n{\n  \"includes\": [\n    \"templates/helpers.tmpl\"\n  ],\n  \"outputs\": [\n    {\n      \"template\": \"templates/service.go.tmpl\",\n      \"input\": \"data/user_service.json\",\n      \"output\": \"gen/user_service.go\"\n    }\n  ]\n}\n```\n\n## Template Functions\n\nThe engine includes a wide variety of built-in functions that you can use in your templates.\n\n### String Case Conversions\n\nThese are especially useful for converting variable names between different conventions:\n\n| Function | Example Usage | Result for \"user_id\" |\n| :--- | :--- | :--- |\n| `toCamelCase` | `{{.Name \\| toCamelCase}}` | `userId` |\n| `toPascalCase` | `{{.Name \\| toPascalCase}}` | `UserId` |\n| `toSnakeCase` | `{{.Name \\| toSnakeCase}}` | `user_id` |\n| `toKebabCase` | `{{.Name \\| toKebabCase}}` | `user-id` |\n| `toScreamingSnake` | `{{.Name \\| toScreamingSnake}}` | `USER_ID` |\n| `toScreamingKebab` | `{{.Name \\| toScreamingKebab}}` | `USER-ID` |\n| `toDotCase` | `{{.Name \\| toDotCase}}` | `user.id` |\n| `toPathCase` | `{{.Name \\| toPathCase}}` | `user/id` |\n| `toLower` | `{{.Name \\| toLower}}` | `user_id` |\n| `toUpper` | `{{.Name \\| toUpper}}` | `USER_ID` |\n| `capitalize` | `{{.Name \\| capitalize}}` | `User_id` |\n\n*Note: The case conversion functions are smart and can handle inputs in snake_case, camelCase, PascalCase, kebab-case, or mixed cases seamlessly.*\n\n### String Manipulation\n\n| Function | Example Usage | Description |\n| :--- | :--- | :--- |\n| `trimSpace` | `{{.Name \\| trimSpace}}` | Removes leading and trailing white space. |\n| `trimPrefix` | `{{.Name \\| trimPrefix \"user_\"}}` | Removes the specified prefix. |\n| `trimSuffix` | `{{.Name \\| trimSuffix \"_id\"}}` | Removes the specified suffix. |\n| `hasPrefix` | `{{hasPrefix \"user_\" .Name}}` | Checks if a string starts with a prefix. |\n| `hasSuffix` | `{{hasSuffix \"_id\" .Name}}` | Checks if a string ends with a suffix. |\n| `contains` | `{{contains \"id\" .Name}}` | Checks if a string contains a substring. |\n| `replace` | `{{replace .Name \"old\" \"new\"}}` | Replaces all occurrences of a substring. |\n| `split` | `{{split .Name \",\"}}` | Splits a string into an array of strings. |\n| `join` | `{{join .List \",\"}}` | Joins an array of strings into a single string. |\n| `indent` | `{{.Content \\| indent 4}}` | Indents each non-empty line with 4 spaces. |\n| `indentTab` | `{{.Content \\| indentTab 2}}` | Indents each non-empty line with 2 tabs. |\n| `regexMatch` | `{{regexMatch \"^[a-z]+$\" .Name}}` | Reports whether the string matches the regex. |\n| `regexReplace` | `{{regexReplace \"a+\" \"b\" .Name}}` | Replaces regex matches in a string. |\n\n### Math \u0026 Numeric\n\n| Function | Example Usage | Result |\n| :--- | :--- | :--- |\n| `add` | `{{add 1 2}}` | `3` |\n| `sub` | `{{sub 5 2}}` | `3` |\n| `mul` | `{{mul 2 3}}` | `6` |\n| `div` | `{{div 6 2}}` | `3` |\n| `mod` | `{{mod 7 3}}` | `1` |\n| `hexString` | `{{hexString 255}}` | `\"ff\"` |\n\n### File \u0026 System Utilities\n\n| Function | Example Usage | Description |\n| :--- | :--- | :--- |\n| `fileSize` | `{{fileSize \"path/to/file\"}}` | Returns the file size in bytes. |\n| `readFile` | `{{readFile \"path/to/file\"}}` | Reads and returns the file contents as a string. |\n| `env` | `{{env \"USER\"}}` | Retrieves the value of an environment variable. |\n\n### Encoding \u0026 Hashing\n\n| Function | Example Usage | Description |\n| :--- | :--- | :--- |\n| `hash` | `{{hash \"my string\"}}` | Returns the xxHash 64-bit digest of the string. |\n| `fileHash` | `{{fileHash \"path/to/file\"}}` | Returns the xxHash 64-bit digest of the file contents. |\n| `base64Encode` | `{{base64Encode \"data\"}}` | Returns the base64 encoding of the string. |\n| `base64Decode` | `{{base64Decode \"ZGF0YQ==\"}}` | Decodes a base64 encoded string. |\n\n### General Utilities\n\n| Function | Example Usage | Description |\n| :--- | :--- | :--- |\n| `default` | `{{.Name \\| default \"unnamed\"}}` | Returns the default value if the input is considered empty. |\n| `seq` | `{{seq 1 10 2}}` | Generates a sequence of integers for iterating (e.g. `[1, 3, 5, 7, 9]`). |\n\n## Example\n\nLet's say you want to generate a simple Go struct.\n\n### 1. Project File\n\n**`project.json`**\n```json\n{\n  \"includes\": [],\n  \"outputs\": [\n    {\n      \"template\": \"struct.tmpl\",\n      \"input\": \"struct_data.json\",\n      \"output\": \"person.go\"\n    }\n  ]\n}\n```\n\n### 2. Input Data\n\n**`struct_data.json`**\n```json\n{\n  \"PackageName\": \"main\",\n  \"StructName\": \"Person\",\n  \"Fields\": [\n    { \"Name\": \"Name\", \"Type\": \"string\" },\n    { \"Name\": \"Age\", \"Type\": \"int\" }\n  ]\n}\n```\n\n### 3. Template File\n\n**`struct.tmpl`**\n```go-template\n// Code generated by codegen. DO NOT EDIT.\npackage {{.PackageName}}\n\ntype {{.StructName}} struct {\n{{- range .Fields}}\n    {{.Name}} {{.Type}}\n{{- end}}\n}\n```\n\n### 4. Run the tool\n\n```bash\ngo run ./cmd/main.go project.json\n```\n\n### 5. Generated Output\n\n**`person.go`**\n```go\n// Code generated by codegen. DO NOT EDIT.\npackage main\n\ntype Person struct {\n    Name string\n    Age int\n}\n```\n\n## Building from Source\n\n### Prerequisites\n\n-   [Go](https://golang.org/doc/install) (version 1.24 or later)\n\n### Build Command\n\nTo build the executable, run:\n```bash\ngo build -o codegen ./cmd/main.go\n```\nYou can then run the tool directly: `./codegen project.json`.\n\n### Makefile\n\nA `Makefile` is provided with common targets:\n\n-   `make build`: Build the project.\n-   `make test`: Run tests.\n-   `make vet`: Vet the Go source code for issues.\n-   `make fmt`: Format the Go source code.\n-   `make all`: Run `deps`, `vet`, and `test`.\n\n## Using with CMake\n\nYou can integrate `codegen` into your C/C++ projects using the provided `cmake/codegen.cmake` module.\n\n### 1. Include the module\n\nCopy `cmake/codegen.cmake` to your project and include it in your `CMakeLists.txt`:\n\n```cmake\ninclude(cmake/codegen.cmake)\n```\n\n### 2. Initialize the tool\n\nCall `codegen_init` with a specific Git tag or branch to download and build the `codegen` tool:\n\n```cmake\ncodegen_init(main)\n```\n\n### 3. Generate code for a target\n\nUse `codegen_project` to link a `project.json` file to your target. This will automatically run the generation tool during the build process and add the generated files to your target's source list.\n\n```cmake\nadd_executable(my_app main.c)\n\ncodegen_project(my_app\n    PROJECT_FILE \"codegen_project.json\"\n    OUTPUTS \"generated_source.c\" \"generated_header.h\"\n    DEPENDS \"templates/template.tmpl\" \"data/data.json\"\n)\n```\n\n- `PROJECT_FILE`: The path to your `codegen` project configuration.\n- `OUTPUTS`: The list of files that `codegen` will generate.\n- `DEPENDS`: (Optional) Additional files that should trigger a re-generation if modified (e.g., templates or data files).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschraf%2Fcodegen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschraf%2Fcodegen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschraf%2Fcodegen/lists"}