feat(Phase 1): sidebar visible, version in header, index categories, MAN 0.78rem, nav injection in 04 script

This commit is contained in:
“Naeel”
2026-08-10 13:38:35 +04:00
parent 21b92f4631
commit 195f153860
3 changed files with 77 additions and 37 deletions
@@ -29,19 +29,19 @@ func ResourceDocs(docsDir string, spec types.ServiceSpec, version string, apiEnd
navOps := fmt.Sprintf("[Manual](%s.md) · [Create params](%s_params_create.md) · [Modify params](%s_params_modify.md) · [Output params](%s_outputs.md) · **Operations** · [Example](%s_example.md)", base, base, base, base, base)
navExample := fmt.Sprintf("[Manual](%s.md) · [Create params](%s_params_create.md) · [Modify params](%s_params_modify.md) · [Output params](%s_outputs.md) · [Operations](%s_ops.md) · **Example**", base, base, base, base, base)
WriteFile(filepath.Join(docsDir, base+".md"), buildManualPage(spec, navManual))
WriteFile(filepath.Join(docsDir, base+".md"), buildManualPage(spec, navManual, version))
WriteFile(filepath.Join(docsDir, base+"_example.md"), buildExamplePage(spec, navExample, version, apiEndpoint, providerSource))
WriteFile(filepath.Join(docsDir, base+"_params_create.md"), buildCreateParamsPage(spec, navCreate))
WriteFile(filepath.Join(docsDir, base+"_params_modify.md"), buildModifyParamsPage(spec, navModify))
WriteFile(filepath.Join(docsDir, base+"_outputs.md"), buildOutputsPage(spec, navOutputs))
WriteFile(filepath.Join(docsDir, base+"_ops.md"), buildOpsPage(spec, navOps, docsDir))
WriteFile(filepath.Join(docsDir, base+"_params.md"), buildParamsLandingPage(spec, navManual))
WriteFile(filepath.Join(docsDir, base+"_params_create.md"), buildCreateParamsPage(spec, navCreate, version))
WriteFile(filepath.Join(docsDir, base+"_params_modify.md"), buildModifyParamsPage(spec, navModify, version))
WriteFile(filepath.Join(docsDir, base+"_outputs.md"), buildOutputsPage(spec, navOutputs, version))
WriteFile(filepath.Join(docsDir, base+"_ops.md"), buildOpsPage(spec, navOps, version, docsDir))
WriteFile(filepath.Join(docsDir, base+"_params.md"), buildParamsLandingPage(spec, navManual, version))
for _, srName := range CollectSubresources(spec) {
srBase := fmt.Sprintf("%s_%s", base, Slug(srName))
srNav := fmt.Sprintf("[%s (основной)](%s.md) | [Operations](%s_ops.md) | [%s](%s.md) | [Example](%s_example.md)",
spec.ServiceDisplayName, base, base, Capitalize(srName), srBase, srBase)
WriteFile(filepath.Join(docsDir, srBase+".md"), buildSubresourcePage(spec, srName, srNav))
WriteFile(filepath.Join(docsDir, srBase+".md"), buildSubresourcePage(spec, srName, srNav, version))
WriteFile(filepath.Join(docsDir, srBase+"_example.md"), buildSubresourceExamplePage(spec, srName, srNav, version, apiEndpoint, providerSource))
}
}
@@ -69,18 +69,35 @@ func WriteFile(path, content string) {
}
}
// IndexMD генерирует index.md.
// IndexMD генерирует index.md с группировкой по категориям.
func IndexMD(docsDir string, specs []types.ServiceSpec) {
catMap := map[string][]types.ServiceSpec{}
for _, s := range specs {
cat := serviceCategory(s.Name)
catMap[cat] = append(catMap[cat], s)
}
var b bytes.Buffer
b.WriteString("# Ресурсы провайдера\n\n")
b.WriteString("| ID | Ресурс | Описание |\n")
b.WriteString("|-----|--------|----------|\n")
for _, spec := range specs {
resName := "nubes_" + spec.Name
link := fmt.Sprintf("[%s](%s.md)", resName, spec.Name)
descr := strings.ReplaceAll(spec.ServiceDisplayName, "|", "\\|")
b.WriteString(fmt.Sprintf("| %d | %s | %s |\n", spec.ServiceID, link, descr))
order := []string{"Базы данных", "Очереди", "Хранилище", "K8s", "VMware", "Приложения", "Сеть", "Другие"}
for _, cat := range order {
svcs := catMap[cat]
if len(svcs) == 0 {
continue
}
b.WriteString(fmt.Sprintf("## %s\n\n", cat))
b.WriteString("| ID | Ресурс | Описание |\n")
b.WriteString("|-----|--------|----------|\n")
for _, spec := range svcs {
resName := "nubes_" + spec.Name
link := fmt.Sprintf("[%s](%s.md)", resName, spec.Name)
descr := strings.ReplaceAll(spec.ServiceDisplayName, "|", "\\|")
b.WriteString(fmt.Sprintf("| %d | %s | %s |\n", spec.ServiceID, link, descr))
}
b.WriteString("\n")
}
outPath := filepath.Join(docsDir, "index.md")
if err := os.WriteFile(outPath, b.Bytes(), 0o644); err != nil {
fmt.Fprintf(os.Stderr, "Warning: failed to write index.md: %v\n", err)
@@ -123,17 +140,17 @@ func FindSubresourceParams(ops []types.OperationSpec, srName, action string) []t
// ===== internal helpers =====
func buildHeader(spec types.ServiceSpec, nav string) string {
func buildHeader(spec types.ServiceSpec, nav string, version string) string {
name := spec.ServiceDisplayName
if name == "" {
name = spec.Name
}
return fmt.Sprintf("# Resource nubes_%s · Service ID: %d · Service Name: %s\n\n%s\n\n", spec.Name, spec.ServiceID, name, nav)
return fmt.Sprintf("# Resource nubes_%s · v%s · Service ID: %d · Service Name: %s\n\n%s\n\n", spec.Name, version, spec.ServiceID, name, nav)
}
func buildManualPage(spec types.ServiceSpec, nav string) string {
func buildManualPage(spec types.ServiceSpec, nav string, version string) string {
var b strings.Builder
b.WriteString(buildHeader(spec, nav))
b.WriteString(buildHeader(spec, nav, version))
b.WriteString("## MAN\n\n")
man := strings.TrimSpace(spec.ServiceMan)
if man == "" {
@@ -186,7 +203,7 @@ func htmlToMarkdown(s string) string {
func buildExamplePage(spec types.ServiceSpec, nav string, version string, apiEndpoint string, providerSource string) string {
var b strings.Builder
b.WriteString(buildHeader(spec, nav))
b.WriteString(buildHeader(spec, nav, version))
b.WriteString(fmt.Sprintf("## Minimal example — only required parameters\n\n"))
b.WriteString("```hcl\n")
b.WriteString(minimalExampleBlock(spec, version, apiEndpoint, providerSource))
@@ -281,9 +298,9 @@ func minimalExampleBlock(spec types.ServiceSpec, version string, apiEndpoint str
return b.String()
}
func buildCreateParamsPage(spec types.ServiceSpec, nav string) string {
func buildCreateParamsPage(spec types.ServiceSpec, nav string, version string) string {
var b strings.Builder
b.WriteString(buildHeader(spec, nav))
b.WriteString(buildHeader(spec, nav, version))
b.WriteString("## Create params\n\n")
createParams := FindParams(spec.Operations, "create")
requiredParams, defaultParams := SplitParams(createParams)
@@ -322,18 +339,18 @@ func buildCreateParamsPage(spec types.ServiceSpec, nav string) string {
return b.String()
}
func buildModifyParamsPage(spec types.ServiceSpec, nav string) string {
func buildModifyParamsPage(spec types.ServiceSpec, nav string, version string) string {
var b strings.Builder
b.WriteString(buildHeader(spec, nav))
b.WriteString(buildHeader(spec, nav, version))
b.WriteString("## Modify params\n\n")
modifyParams := FindParams(spec.Operations, "modify")
b.WriteString(renderModifyTable(modifyParams))
return b.String()
}
func buildOutputsPage(spec types.ServiceSpec, nav string) string {
func buildOutputsPage(spec types.ServiceSpec, nav string, version string) string {
var b strings.Builder
b.WriteString(buildHeader(spec, nav))
b.WriteString(buildHeader(spec, nav, version))
b.WriteString("## Output params\n\n")
if len(spec.Outputs.Params) == 0 {
b.WriteString("None.\n")
@@ -406,9 +423,9 @@ func containsString(values []string, target string) bool {
return false
}
func buildOpsPage(spec types.ServiceSpec, nav string, docsDir string) string {
func buildOpsPage(spec types.ServiceSpec, nav string, version string, docsDir string) string {
var b strings.Builder
b.WriteString(buildHeader(spec, nav))
b.WriteString(buildHeader(spec, nav, version))
b.WriteString("## Operations\n\n")
for _, op := range spec.Operations {
name := op.Name
@@ -454,16 +471,16 @@ func buildOpsPage(spec types.ServiceSpec, nav string, docsDir string) string {
return b.String()
}
func buildParamsLandingPage(spec types.ServiceSpec, nav string) string {
func buildParamsLandingPage(spec types.ServiceSpec, nav string, version string) string {
var b strings.Builder
b.WriteString(buildHeader(spec, nav))
b.WriteString(buildHeader(spec, nav, version))
b.WriteString("## Parameters\n\n")
b.WriteString(fmt.Sprintf("- [Create params](%s_params_create.md)\n", spec.Name))
b.WriteString(fmt.Sprintf("- [Modify params](%s_params_modify.md)\n", spec.Name))
return b.String()
}
func buildSubresourcePage(spec types.ServiceSpec, srName string, nav string) string {
func buildSubresourcePage(spec types.ServiceSpec, srName string, nav string, version string) string {
var b strings.Builder
srResourceName := fmt.Sprintf("nubes_%s_%s", spec.Name, Slug(srName))
b.WriteString(fmt.Sprintf("# Resource %s\n\n", srResourceName))
@@ -158,9 +158,19 @@ load_s3cfg_registry() {
TMP_CFG="${ROOT_DIR}/.mkdocs.tmp.yml"
export ROOT_DIR
# Copy 30_registry assets into docs dir so guides/nav work when docs_dir is external
if [[ -n "${MKDOCS_DOCS_DIR:-}" ]]; then
if [[ -d "${ROOT_DIR}/docs/30_registry" ]]; then
mkdir -p "${MKDOCS_DOCS_DIR}/30_registry"
cp -r "${ROOT_DIR}/docs/30_registry/"* "${MKDOCS_DOCS_DIR}/30_registry/" 2>/dev/null || true
fi
fi
python3 - <<'PY'
import os
import re
import yaml
from pathlib import Path
registry_host = os.environ["REGISTRY_HOST"]
@@ -185,6 +195,23 @@ if docs_dir:
else:
text += f"\ndocs_dir: {docs_dir}\n"
# Inject resources_nav from _nav_fragment.yml into nav section
docs_dir_path = Path(docs_dir) if docs_dir else None
nav_fragment_path = docs_dir_path / "_nav_fragment.yml" if docs_dir_path else None
if nav_fragment_path and nav_fragment_path.exists():
config = yaml.safe_load(text)
fragment = yaml.safe_load(nav_fragment_path.read_text(encoding="utf-8"))
resources_nav = fragment.get("resources_nav", [])
if resources_nav:
nav = config.get("nav", [])
for i, item in enumerate(nav):
if isinstance(item, dict) and "Ресурсы" in item:
# Replace "Ресурсы" children with generated categories
item["Ресурсы"] = resources_nav
break
config["nav"] = nav
text = yaml.dump(config, allow_unicode=True, default_flow_style=False, sort_keys=False)
(root_dir / ".mkdocs.tmp.yml").write_text(text, encoding="utf-8")
PY
+2 -6
View File
@@ -18,11 +18,7 @@
line-height: 1.35;
}
/* Resource pages: no sidebars, normal scrolling */
.md-sidebar--primary {
display: none !important;
}
/* Resource pages: right sidebar (TOC) hidden, left sidebar visible */
.md-sidebar--secondary {
display: none !important;
}
@@ -48,7 +44,7 @@
}
.md-typeset .man-content {
font-size: 0.62rem;
font-size: 0.78rem;
line-height: 1.4;
}