{"id":45455211,"url":"https://github.com/gdvalle/bbcue","last_synced_at":"2026-05-29T08:02:46.372Z","repository":{"id":339888634,"uuid":"1158216057","full_name":"gdvalle/bbcue","owner":"gdvalle","description":"An experimental way to use CUE","archived":false,"fork":false,"pushed_at":"2026-05-22T06:46:13.000Z","size":12833,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T15:09:50.788Z","etag":null,"topics":["cue","cuelang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gdvalle.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":"2026-02-15T01:23:51.000Z","updated_at":"2026-05-22T06:45:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"1702b856-8d27-4700-840d-3778c49e4587","html_url":"https://github.com/gdvalle/bbcue","commit_stats":null,"previous_names":["gdvalle/bbcue"],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/gdvalle/bbcue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdvalle%2Fbbcue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdvalle%2Fbbcue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdvalle%2Fbbcue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdvalle%2Fbbcue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gdvalle","download_url":"https://codeload.github.com/gdvalle/bbcue/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gdvalle%2Fbbcue/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33642318,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"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":["cue","cuelang"],"created_at":"2026-02-22T06:07:48.024Z","updated_at":"2026-05-29T08:02:46.366Z","avatar_url":"https://github.com/gdvalle.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- Code examples are extracted from txtar integration tests. --\u003e\n\u003c!-- To regenerate: go run ./internal/genreadme --\u003e\n\n# bbcue\n\n**bbcue** turns [CUE](https://cuelang.org) into a low-boilerplate config file generator. Drop a `bb.cue` file in any directory, run `bbcue`, and get JSON, YAML, TOML, or plain text files, with full access to CUE's type system, imports, and a subset of tool tasks.\n\nIt's basically an opinionated wrapper with a predefined `cue cmd` task to write config out by convention, without having to recall the `cue export` and `cue import` syntax.\n\n## Install\n\nDownload a prebuilt binary from the [Releases page](https://github.com/gdvalle/bbcue/releases).\n\nOr, install with Go:\n\n```sh\ngo install github.com/gdvalle/bbcue/cmd/bbcue@latest\n```\n\n## Quick start\n\nIf you have existing config, import it into `bb.cue`:\n```sh\nbbcue import config.yaml\n```\n\nOr, create `bb.cue` yourself:\n\n```cue\nbbcue: \"config.yaml\": {\n\tcontent: {\n\t\tdatabase: {\n\t\t\thost: \"localhost\"\n\t\t\tport: 5432\n\t\t}\n\t}\n}\n```\n\nRun `bbcue`:\n\n```sh\n$ bbcue\n. -\u003e config.yaml\nwrote 1 file(s) from 1 source(s) in 1ms\n\n```\n\nOut comes `config.yaml`:\n\n```yaml\n# Generated by bbcue. DO NOT EDIT.\n\ndatabase:\n  host: localhost\n  port: 5432\n```\n\nNow you can take advantage of CUE features incrementally.\n\n## How it works\n\nbbcue recursively finds `bb.cue` files starting from the current directory. Each file defines a `bbcue` struct whose keys are output filenames and whose values describe the content to write.\n\nThe output format is inferred from the file extension (`.json`, `.yaml`/`.yml`, `.toml`, `.txt`) or set explicitly with a `format` field.\n\n\n### Multiple outputs\n\nA single `bb.cue` can produce multiple files:\n\n```cue\nbbcue: \"a.json\": {\n\tcontent: { x: 1 }\n}\nbbcue: \"b.yaml\": {\n\tcontent: { y: 2 }\n}\nbbcue: \"c.toml\": {\n\tcontent: { z: 3 }\n}\n```\n\n## Tool tasks\n\nbbcue reimplements a subset of [CUE tool imports](https://pkg.go.dev/cuelang.org/go/pkg/tool). See [API docs](https://pkg.go.dev/cuelang.org/go/pkg/tool).\n(We reimplement because these are not public APIs).\n* `exec.Run`\n* `file.*`\n* `http.Do`\n* `os.Environ`\n* `os.Getenv`\n\nNote these are powerful tools that break the hermetic seal around CUE evaluation and are typically isolated to CUE `_tool`-suffixed files.\n\nFor the tools that interact with the filesystem, they execute relative to the directory containing the `bb.cue` file, regardless of where `bbcue` was invoked.\n\n### Reading files with `tool/file`\n\nRead a file's contents and embed it in the output:\n\n```cue\nimport \"tool/file\"\n\nreadMe: file.Read \u0026 {\n\tfilename: \"input.txt\"\n\tcontents: string\n}\n\nbbcue: \"result.json\": {\n\tcontent: {\n\t\tdata: readMe.contents\n\t}\n}\n```\n\n### Running commands with `tool/exec`\n\nCapture command output:\n\n```cue\nimport \"tool/exec\"\n\nrun: exec.Run \u0026 {\n\tcmd: [\"echo\", \"hello world\"]\n\tstdout: string\n}\n\nbbcue: \"result.json\": {\n\tcontent: {\n\t\tmessage: run.stdout\n\t}\n}\n```\n\nHandle commands that might fail with `mustSucceed: false`:\n\n```cue\nimport \"tool/exec\"\n\nrun: exec.Run \u0026 {\n\tcmd: [\"false\"]\n\tmustSucceed: false\n\tstdout: string\n}\n\nbbcue: \"result.json\": {\n\tcontent: {\n\t\tok: run.success\n\t}\n}\n```\n\n### Reading environment variables with `tool/os`\n\nRead specific variables with `os.Getenv`:\n\n```cue\nimport \"tool/os\"\n\ngetenv: os.Getenv \u0026 {\n\tBBCUE_TEST_VAR: string\n}\n\nbbcue: \"result.json\": {\n\tcontent: {\n\t\tval: getenv.BBCUE_TEST_VAR\n\t}\n}\n```\n\nOr read from the full environment with `os.Environ`:\n\n```cue\nimport \"tool/os\"\n\nenviron: os.Environ\n\nbbcue: \"result.json\": {\n\tcontent: {\n\t\tval: environ.BBCUE_ENV_TEST\n\t}\n}\n```\n\n## CUE packages and schemas\n\nAll `.cue` files in a directory are loaded together, so you can split schemas and values across files using CUE packages.\n\nbbcue strictly scopes evaluation to the directory containing the `bb.cue` file (it does not automatically unify with parent directories). However, it does walk parent directories to discover `cue.mod` roots for import resolution.\n\n```cue\n// schema.cue\npackage bb\n\n#Config: {\n\thost: string\n\tport: int\n}\n```\n\n```cue\n// bb.cue\npackage bb\n\nbbcue: \"config.json\": {\n\tcontent: #Config \u0026 {\n\t\thost: \"localhost\"\n\t\tport: 5432\n\t}\n}\n```\n\n## Importing data files\n\nThe `import` subcommand converts existing JSON, YAML, and TOML files into `bb.cue` entries:\n\n```sh\nbbcue import config.json settings.yaml\n```\n\nThis appends entries to (or creates) `bb.cue` in the current directory. Each file becomes a field under the `bbcue` struct, keyed by filename and wrapped in a `content` field:\n\n```cue\nbbcue: \"config.json\": content: {\n\thost: \"localhost\"\n\tport: 5432\n}\nbbcue: \"settings.yaml\": content: {\n\tkey: \"value\"\n}\n```\n\nIf `bb.cue` already contains an entry for a filename, that file is skipped with a warning. Multi-document YAML files are not supported.\n\n## CLI usage\n\nbbcue uses subcommands. When invoked without a subcommand, `gen` is the default.\n\n```\nbbcue \u003ccommand\u003e [flags] [args...]\n```\n\n| Flag | Description |\n|------|-------------|\n| `--version`, `-v` | Print version and build information |\n| `--help`, `-h` | Show usage |\n\n### `cue` (passthrough)\n\nRun the embedded CUE interpreter. All arguments, flags, and environment variables are passed directly to the standard CUE CLI.\n\n```sh\nbbcue cue version\n```\n\n### `gen` (default)\n\nDiscover `bb.cue` files and write configured outputs.\n\n```\nbbcue [gen] [flags] [paths...]\n```\n\nWith no arguments, bbcue checks the current directory for a `bb.cue` file.\n\n| Flag | Description |\n|------|-------------|\n| `--recurse`, `-r` | Recurse into subdirectories |\n| `--no-recurse`, `-R` | Do not recurse (default; overrides `-r` if both given) |\n| `--version`, `-v` | Print version and build information |\n\nWhen paths are specified:\n- **Directories** are used as roots (checked directly by default, or recursed with `-r`)\n- **Files** use their parent directory as the root\n\n### `import`\n\nImport data files (JSON, YAML, TOML) as CUE values into `bb.cue`.\n\n```\nbbcue import \u003cfiles...\u003e\n```\n\n### `fmt`\n\nFormat CUE files. \n\n```\nbbcue fmt [flags] [files...]\n```\n\nWith no arguments, bbcue discovers and formats all `.cue` files in the current directory (and subdirectories if recurse is enabled). Files are always simplified.\n\n| Flag | Description |\n|------|-------------|\n| `--recurse`, `-r` | Recurse into subdirectories |\n| `--no-recurse`, `-R` | Do not recurse (default; overrides `-r` if both given) |\n\nExample:\n\n```cue\n// Before\npackage   example\nbbcue:  \"output.txt\": { content: \"hello\" }\n```\n\n```cue\n// After\npackage example\n\nbbcue: \"output.txt\": content: \"hello\"\n```\n\n### Examples\n\n```sh\n# Generate from current directory\nbbcue\n\n# Recursively generate from current directory\nbbcue -r\n\n# Recursively generate from specific directories\nbbcue gen -r ./services ./infra\n\n# Import data files\nbbcue import config.json settings.yaml\n\n# Print version\nbbcue --version\n```\n\n## Directory skipping\n\nWhen recursing, bbcue automatically skips:\n\n- Directories starting with `.`\n- `node_modules`\n- `cue.mod`\n\n## Path safety\n\nOutput paths are validated to stay within the `bb.cue` file's directory. Absolute paths and `../` traversal are rejected.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgdvalle%2Fbbcue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgdvalle%2Fbbcue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgdvalle%2Fbbcue/lists"}