{"id":51592988,"url":"https://github.com/donseba/go-doc","last_synced_at":"2026-07-11T16:01:52.041Z","repository":{"id":367059112,"uuid":"895234569","full_name":"donseba/go-doc","owner":"donseba","description":"code highlighting and completion in golang templates","archived":false,"fork":false,"pushed_at":"2026-07-02T20:13:35.000Z","size":4875,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-07-02T20:20:01.296Z","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/donseba.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"donseba","patreon":null,"open_collective":null,"ko_fi":"donseba","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"donseba","thanks_dev":null,"custom":null}},"created_at":"2024-11-27T20:13:34.000Z","updated_at":"2026-07-02T18:31:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/donseba/go-doc","commit_stats":null,"previous_names":["donseba/go-doc"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/donseba/go-doc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-doc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-doc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-doc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-doc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/donseba","download_url":"https://codeload.github.com/donseba/go-doc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/donseba%2Fgo-doc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35367446,"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-07-11T02:00:05.354Z","response_time":104,"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":[],"created_at":"2026-07-11T16:01:50.814Z","updated_at":"2026-07-11T16:01:52.024Z","avatar_url":"https://github.com/donseba.png","language":"Go","funding_links":["https://github.com/sponsors/donseba","https://ko-fi.com/donseba","https://buymeacoffee.com/donseba"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./assets/go-doc-logo.png\" alt=\"go-doc\" width=\"420\"\u003e\n\u003c/p\u003e\n\n`go-doc` brings typed editor tooling to Go templates.\n\nIt reads lightweight typed-root annotations, `@dot`, `@func`, `@gen`, and project-defined\nannotations in `.gohtml`, `.tmpl`, and `.html` templates, scans exported Go\nstructs and functions in your module, and serves that knowledge to editors\nthrough a small Language Server Protocol server.\n\n```gotemplate\n{{/*\n@model Page github.com/example/app.Page\n*/}}\n\n\u003ch1\u003e{{ Page.Title }}\u003c/h1\u003e\n\n{{ range Page.Items }}\n    \u003ca href=\"/items/{{ .ID }}\"\u003e{{ .Label }}\u003c/a\u003e\n{{ end }}\n```\n\nWith that contract in place, editors can complete fields, validate unknown\nmembers, understand `range` dot context, show hover information, and navigate\nback to Go source.\n\nThis is a two-way contract, not magic. The annotation is the template-side\nentrance: it tells go-doc and the editor that `Page` should be an\n`github.com/example/app.Page`. Your application still provides the runtime\nexit: it must register a `Page` accessor before parsing, for example through\nthe optional `renderer`, or through equivalent application glue.\n\nPlain `html/template` dot execution is different. If you call\n`tmpl.Execute(w, page)`, the template receives `page` as `.`, so the matching\ncontract is `@dot`, not `@model`.\n\n## Why\n\nGo templates are intentionally simple at runtime, but that usually means the\neditor has no idea what `{{ .Title }}` or `{{ Page.Items }}` refers to.\n\n`go-doc` keeps runtime behavior unchanged. Your application still owns template\nparsing, execution, routing, rendering, and data. `go-doc` only adds a typed\ncontract that editors and tools can understand.\n\n## Features\n\n- Typeahead for typed roots, built-in\n  and custom template functions, exported fields, and exported methods.\n- Dot-context completion inside `range` and `with` blocks.\n- Diagnostics for unknown typed roots, fields, invalid `range` sources, and bad\n  function calls.\n- Include checks for `template`, `block`, same-file `define`, and cross-file\n  child templates that declare `@dot`.\n- Quick fixes for creating missing model structs and adding missing struct\n  fields from template diagnostics.\n- Hover and go-to-definition for typed root types, fields, methods, functions, and\n  template includes.\n- Semantic highlighting for typed root types, typed root names,\n  built-in functions, custom functions, fields, and methods.\n- A shared LSP core used by GoLand, VS Code, Sublime Text, Vim, and Neovim.\n- Optional `.go-doc/index.json` generation for CI, debugging, and tool\n  interoperability.\n\n## Install\n\nInstall the CLI:\n\n```bash\ngo install github.com/donseba/go-doc@latest\n```\n\nInstall the experimental helper generator when using `@gen`:\n\n```bash\ngo install github.com/donseba/go-doc/cmd/godoc-exp-gen@latest\n```\n\nThen install the editor package you use from the release assets.\n\nOn Windows, the GoLand and VS Code integrations run the long-lived language\nserver from a temporary copy of `go-doc.exe`. That keeps `go install\ngithub.com/donseba/go-doc@latest` able to replace the installed binary while the\neditor is open. Restart the LSP/editor to pick up the newly installed version.\nThe editor status commands show both the installed CLI version and the active\nLSP copy version.\n\n| Editor | Package |\n| --- | --- |\n| GoLand | `go-doc-goland-plugin-*.zip` |\n| VS Code | `go-doc-vscode-*.vsix` |\n| Sublime Text | `go-doc-sublime-*.sublime-package` |\n| Vim | `go-doc-vim-*.zip` |\n| Neovim | `go-doc-neovim-*.zip` |\n\n## Quick Start\n\nUse the model in a template:\n\n```gotemplate\n{{/*\n@model Todo github.com/example/app.Todo\n*/}}\n\n\u003carticle\u003e\n    \u003ch2\u003e{{ Todo.Title }}\u003c/h2\u003e\n    \u003cp\u003e{{ Todo.Priority }}\u003c/p\u003e\n\u003c/article\u003e\n```\n\nThe declared model name is the template accessor. `@model Todo ...` is used as\n`{{ Todo.Title }}`. At runtime, that accessor must exist. The optional renderer\ncreates it by matching the declared type to a Go value and adding a template\nfunction named `Todo` before parsing. Without that runtime registration,\n`html/template` has no built-in idea what `Todo` means.\n\nCapitalized model names are recommended because they read like Go types and\navoid common template helper names, but lowercase names are not forbidden.\ngo-doc reports a diagnostic when a model name collides with a built-in,\nconfigured, or local template function, because the same identifier cannot\nreliably be both a model accessor and a function in `html/template`.\n\nUse `@dot` when the template is rendered with dot set to one value, such as a\ntable row or card:\n\n```gotemplate\n{{/* @dot github.com/example/app.User */}}\n\u003ctr\u003e\n    \u003ctd\u003e{{ .Name }}\u003c/td\u003e\n    \u003ctd\u003e{{ .Status }}\u003c/td\u003e\n\u003c/tr\u003e\n```\n\nUse `@dot` for normal `tmpl.Execute(w, value)` templates where the value is\navailable as `.`:\n\n```gotemplate\n{{/* @dot github.com/example/app.Page */}}\n\u003ch1\u003e{{ .Title }}\u003c/h1\u003e\n```\n\nWhen a parent calls that child with `{{ template \"user_row.gohtml\" . }}`,\ngo-doc checks that the passed value matches the child `@dot` contract. The same\ncheck applies to named `define` sections and `block` calls.\n\nUse `@func` for custom helpers that are local to one template:\n\n```gotemplate\n{{/*\n@func userByID github.com/example/app.UserByID\n*/}}\n\n{{ (userByID 2).Name }}\n```\n\nFor helpers available everywhere, prefer `.go-doc/config.json` so you do not\nrepeat the same `@func` declarations across templates.\n\nConfigured helpers are still a two-way road. The config teaches go-doc what the\neditor should expect, but your Go application must still register the actual\nfunction in the `html/template.FuncMap`.\n\nFor simple one-signature helpers, `functions` is enough:\n\n```json\n{\n  \"functions\": {\n    \"formatDate\": \"github.com/example/app.FormatDate\"\n  }\n}\n```\n\n### Global FuncMaps\n\nFor projects that already collect helpers in a Go `template.FuncMap`, go-doc can\nread direct static FuncMap literals instead of making you repeat every helper in\n`functions`.\n\nFor small projects, annotate the FuncMap:\n\n```go\n//go-doc:funcmap\nfunc TemplateFuncs() template.FuncMap {\n    return template.FuncMap{\n        \"asset\": Asset,\n    }\n}\n```\n\nVariables work too:\n\n```go\n//go-doc:funcmap\nvar TemplateFuncs = template.FuncMap{\n    \"asset\": Asset,\n}\n```\n\nFor larger projects, prefer explicit config:\n\n```json\n{\n  \"functionMaps\": [\n    \"github.com/example/app.TemplateFuncs\"\n  ]\n}\n```\n\n`functionMaps` and `//go-doc:funcmap` are statically analyzed. go-doc does not\nexecute Go code or use reflection. For v1, use direct composite literals such as\n`template.FuncMap{...}`, `map[string]any{...}`, or\n`map[string]interface{}{...}`. Dynamic construction is reported as unsupported:\n\n```go\nfunc TemplateFuncs() template.FuncMap {\n    fm := template.FuncMap{}\n    fm[\"asset\"] = Asset\n    return fm\n}\n```\n\nFunction sources are merged from broadest to most explicit:\n\n```text\nbuilt-ins \u003c annotated funcmaps \u003c config.functionMaps \u003c config.functions \u003c local @func\n```\n\nFor helpers with multiple accepted call forms, use `templateFunctions`:\n\n```json\n{\n  \"templateFunctions\": [\n    {\n      \"name\": \"async\",\n      \"path\": \"github.com/donseba/go-partial/templatefunctions.Async\",\n      \"signatures\": [\n        \"func(endpoint string, params ...any) html/template.HTML\",\n        \"func(interaction github.com/donseba/go-partial.Interaction) html/template.HTML\"\n      ]\n    }\n  ]\n}\n```\n\nIf `signatures` is omitted, go-doc reads `//go-doc:sig` comments from the\nfunction at `path`. Configured template function packages are loaded directly,\nso this also works for helper packages that live in dependencies:\n\n```go\n//go-doc:sig func(endpoint string, params ...any) html/template.HTML\n//go-doc:sig func(interaction github.com/donseba/go-partial.Interaction) html/template.HTML\nfunc Async() {}\n```\n\nRequest-scoped helpers that are installed as closures can put `//go-doc:sig`\ndirectly above the FuncMap assignment. go-doc infers the template function name\nfrom the static string key:\n\n```go\n//go-doc:sig func() *net/url.URL\nfuncs[\"url\"] = func() *url.URL {\n    return state.URL\n}\n```\n\nAny non-special annotation with a name and type becomes a typed root: a named\nvalue that go-doc can complete, validate, hover, and navigate. `@model` is the\nrecommended convention for page or fragment data. `@symbol`, `@component`,\n`@interaction`, or your own project vocabulary work the same way when they\ndeclare a type:\n\n```gotemplate\n{{/*\n@symbol LikesPoll github.com/example/app.Interaction\n*/}}\n\n{{ LikesPoll.ID }}\n```\n\nEvery typed root is still a two-way contract. The annotation tells go-doc the\nexpected type, but your runtime must still register the actual template accessor\nor function that makes `LikesPoll` available. The annotation word is vocabulary,\nnot a different engine path.\n\nAny custom annotation with an explicit type is accepted by default:\n\n```gotemplate\n{{/*\n@component Button github.com/example/ui.Button\n@interaction LikesPoll github.com/donseba/go-partial.Interaction\n*/}}\n```\n\nProjects can define shorter symbol annotations in `.go-doc/config.json`. This\nlets framework packages expose their own vocabulary without hard-coding it into\ngo-doc, and it lets stricter teams decide which annotation names are allowed:\n\n```json\n{\n  \"symbolAnnotations\": [\n    {\n      \"name\": \"interaction\",\n      \"type\": \"github.com/donseba/go-partial.Interaction\"\n    },\n    {\n      \"name\": \"component\"\n    }\n  ]\n}\n```\n\nWith that configuration, templates can write:\n\n```gotemplate\n{{/*\n@interaction LikesPoll\n@component Button github.com/example/ui.Button\n*/}}\n```\n\n`@interaction LikesPoll` gets the configured default type. `@component Button`\nrequires an explicit type because its config entry has no default type. These\naliases behave like normal typed roots after parsing. `@func` remains the right\nannotation for callable helpers, because it carries function signatures, arity\nchecks, argument checks, pipelines, and return types.\n\nBy default, custom annotation names are open. `@jimmy Button\ngithub.com/example/ui.Button` is valid because it includes an explicit type. Set\n`symbolStrictMode: true` when you want go-doc to warn about unconfigured custom\nannotation names. In strict mode, only entries listed in `symbolAnnotations`\nare accepted as custom typed-root annotations.\n\n## Configuration\n\nNo `.go-doc` folder is required. By default, `go-doc` finds the nearest\n`go.mod`, scans that module in memory, skips `vendor`, and does not write\n`.go-doc/index.json`.\n\nThe default configuration is:\n\n```json\n{\n  \"enabled\": true,\n  \"include\": [\"/\"],\n  \"exclude\": [\"vendor\"],\n  \"providers\": [],\n  \"functions\": {},\n  \"functionMaps\": [],\n  \"discover\": {\n    \"functionMaps\": true,\n    \"providers\": true,\n    \"signatures\": true\n  },\n  \"templateFunctions\": [],\n  \"symbolAnnotations\": [],\n  \"symbolStrictMode\": false,\n  \"writeIndex\": false\n}\n```\n\nAdd `.go-doc/config.json` only when a project needs to change those defaults:\n\n```json\n{\n  \"enabled\": true,\n  \"include\": [\"/\"],\n  \"exclude\": [\"vendor\", \"tmp\", \"internal/generated\"],\n  \"providers\": [\n    \"github.com/donseba/go-partial\",\n    \"github.com/donseba/go-partial/exp/...\"\n  ],\n  \"writeIndex\": false,\n  \"functions\": {\n    \"asset\": \"github.com/example/app.Asset\",\n    \"formatDate\": \"github.com/example/app.FormatDate\"\n  },\n  \"functionMaps\": [\n    \"github.com/example/app.TemplateFuncs\"\n  ],\n  \"discover\": {\n    \"functionMaps\": true,\n    \"providers\": true,\n    \"signatures\": true\n  },\n  \"templateFunctions\": [\n    {\n      \"name\": \"async\",\n      \"path\": \"github.com/donseba/go-partial/templatefunctions.Async\"\n    }\n  ],\n  \"symbolAnnotations\": [\n    {\n      \"name\": \"component\"\n    }\n  ],\n  \"symbolStrictMode\": false\n}\n```\n\nEntries are module-relative paths. `/` means the module root. Excludes win over\nincludes. `enabled: false` disables go-doc for the project while leaving the\neditor plugin installed. `functions` describes helpers that are available in every template so\nthe language server can complete and validate them without repeating `@func` in\neach file. `functionMaps` describes whole static Go FuncMap declarations whose\nstring-keyed entries should be available in every template. `discover.functionMaps`\ndefaults to `true` and enables scanning included Go files for\n`//go-doc:funcmap` annotations. `providers` lists dependency or framework\npackages whose go-doc annotations should be indexed without scanning every\ndependency. Provider entries use Go package patterns: `github.com/acme/ui`\nloads one package, while `github.com/acme/ui/...` loads that subtree.\nSmall projects can also declare providers in included Go files:\n\n```go\n// go-doc:provider \"github.com/donseba/go-partial\"\n// go-doc:provider \"github.com/donseba/go-partial/exp/...\"\n```\n\n`discover.providers` controls `//go-doc:provider` scanning and\n`discover.signatures` controls `//go-doc:sig` scanning. Both default to `true`.\n`templateFunctions` is the richer form for\nhelpers that need multiple signatures or use `//go-doc:sig` comments as their\nsource of truth. `//go-doc:sig` can annotate a named Go function or a closure\nassignment such as `funcs[\"url\"] = func(...) { ... }`.\n`symbolAnnotations` describes custom annotation names that produce typed roots.\nUse this for framework concepts such as `@interaction`, `@component`,\nor any project-specific template value that should be completed and navigated\nlike a named root value but is not a callable function. `symbolStrictMode` defaults to\n`false`; when set to `true`, unconfigured custom annotation names are reported as\ntypos even if they include an explicit type.\n\n`writeIndex` controls editor auto-indexing. Keep it `false` unless you want editor\nadapters to maintain `.go-doc/index.json` after file changes. Even when it is\nfalse, the language server still builds an in-memory index and all editor\nfeatures continue to work.\n\n## Optional Index File\n\nThe generated index is an optional artifact, not the project root marker.\n`go-doc` uses `go.mod` to find the module root.\n\nCreate the file explicitly when you want a concrete artifact for CI, debugging,\nor other tools:\n\n```bash\ngo-doc index -o .go-doc/index.json .\n```\n\n`go-doc index` only writes an index when at least one template declares a typed\ncontract, or when `.go-doc/config.json` declares global template functions. If\nno typed template surface exists, the command exits successfully without\ncreating `.go-doc/index.json`.\n\n## Commands\n\n```bash\ngo-doc types [-query Todo] [root]\ngo-doc templates [root]\ngo-doc index [-o .go-doc/index.json] [root]\ngo-doc lsp [root]\n```\n\n## Language Server\n\n`go-doc lsp` starts a Language Server Protocol server over stdio. It is the\nshared implementation used by all editor packages.\n\nThe server builds an in-memory index from the module root by default. It reads\n`.go-doc/index.json` only when `.go-doc/config.json` opts into `\"writeIndex\": true`.\nCompletion, diagnostics, hover, go-to-definition, semantic tokens, and include\nchecks still work without a `.go-doc` folder.\n\n## Experimental Generation\n\n`@gen` explores generated helper namespaces for templates:\n\n```gotemplate\n{{/*\n@gen time github.com/example/app/internal/timefuncs\n@gen money github.com/example/app/internal/moneyfuncs\n*/}}\n\n{{ time.Format Page.GeneratedAt \"15:04:05\" }}\n{{ money.EUR .MonthlyCents }}\n```\n\nThis is not a runtime import. The generator writes ordinary Go code that exposes\na normal `template.FuncMap`, and the editor understands the generated namespace\nthrough the same LSP index.\n\nKeep the source helpers in ordinary application packages and generate one small\nbridge package:\n\n```text\ninternal/timefuncs/timefuncs.go\ninternal/moneyfuncs/moneyfuncs.go\n\ngen/gen.go\n```\n\n```bash\ngodoc-exp-gen \\\n  -package gen \\\n  -out gen/gen.go\n```\n\nRegister the generated helpers before parsing:\n\n```go\ntmpl := template.New(\"page.gohtml\").Funcs(gen.FuncMap())\n```\n\nThat FuncMap only provides helper namespaces. Named typed roots such as `Page` still\nneed the renderer or equivalent application glue described below.\n\nSee [README_gen.md](./README_gen.md) and [examples/exp-gen](./examples/exp-gen)\nfor the full explanation.\n\n## Runtime Integration\n\n`go-doc` does not require a framework. It does not execute your templates or\nchange how your application renders HTML.\n\nFor projects that want annotated typed-root names available during ordinary\n`html/template` parsing, the repository includes a small `renderer` package. It\ncan scan the same template declarations, match them to the Go values you pass,\nand register the declared typed-root accessors before parsing:\n\nThink of `@model` as a tunnel. The template declares the entrance:\n\n```gotemplate\n{{/* @model Page github.com/example/app.Page */}}\n\u003ch1\u003e{{ Page.Title }}\u003c/h1\u003e\n```\n\nThe renderer creates the exit by registering a template function named `Page`\nthat returns the matching Go value:\n\nCreate one renderer for a template set. Use `renderer.Development` while\nediting templates, or `renderer.Production` when you want contracts scanned once\nat startup:\n\n```go\nviews, err := renderer.New(renderer.Config{\n    Mode:  renderer.Development,\n    Files: []string{\"templates/page.gohtml\"},\n    Funcs: template.FuncMap{\n        \"asset\":      app.Asset,\n        \"formatDate\": app.FormatDate,\n    },\n})\n```\n\nThe render path stays the same in both modes:\n\n```go\ntmpl := template.New(\"page.gohtml\")\nerr := views.Register(tmpl, page)\n_, err = tmpl.ParseFiles(\"templates/page.gohtml\")\n```\n\nIf `views.Register` is omitted, `Page.Title` is not valid plain\n`html/template` syntax. Use `@dot` and `.Title` instead when executing directly\nwith `tmpl.Execute(w, page)`.\n\n`Config.Funcs` is the runtime counterpart to `.go-doc/config.json` functions:\nthe config teaches editors about globally available helpers, while the renderer\nregisters the real Go functions with `html/template`.\n\nDevelopment mode re-reads `@model` declarations on each `Register` call, so\ntemplate-side renames are picked up without restarting. Production mode reads\nthe declarations once in `renderer.New`, avoiding repeated file reads and\nkeeping the render path predictable.\n\nThe standalone example in `examples/standalone` shows this without depending on\n`go-partial`.\n\nThe todo example in `examples/todo` shows a small multi-template setup with a\nmain shell, todo list, and todo detail template.\n\nThe symbols example in `examples/symbols` shows configured symbol annotations\nsuch as `@interaction` and `@component`, plus the runtime `FuncMap` that makes\nthose names available to `html/template`.\n\n## Local Development\n\nThis repository includes a `Taskfile.yml` for common local commands.\n\nInstall Task first:\n\n```bash\ngo install github.com/go-task/task/v3/cmd/task@latest\n```\n\nUseful tasks:\n\n```bash\ntask doctor\ntask install:tools\ntask test\ntask build:goland\ntask build:vscode\ntask build:sublime\ntask build:vim\ntask build:neovim\ntask dist\n```\n\n`task install:tools` can install the local development toolchain for your\nplatform. On Windows it uses Scoop to install Go, Node.js, JDK 17, and Gradle.\nOn macOS it uses Homebrew.\n\n## Release Assets\n\nBuild outputs are collected locally in `dist`.\n\nRelease archives contain editor packages only. The CLI is distributed through:\n\n```bash\ngo install github.com/donseba/go-doc@latest\ngo install github.com/donseba/go-doc/cmd/godoc-exp-gen@latest\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonseba%2Fgo-doc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdonseba%2Fgo-doc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonseba%2Fgo-doc/lists"}