feat(Phase 1): sidebar visible, version in header, index categories, MAN 0.78rem, nav injection in 04 script
This commit is contained in:
@@ -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)
|
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)
|
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+"_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_create.md"), buildCreateParamsPage(spec, navCreate, version))
|
||||||
WriteFile(filepath.Join(docsDir, base+"_params_modify.md"), buildModifyParamsPage(spec, navModify))
|
WriteFile(filepath.Join(docsDir, base+"_params_modify.md"), buildModifyParamsPage(spec, navModify, version))
|
||||||
WriteFile(filepath.Join(docsDir, base+"_outputs.md"), buildOutputsPage(spec, navOutputs))
|
WriteFile(filepath.Join(docsDir, base+"_outputs.md"), buildOutputsPage(spec, navOutputs, version))
|
||||||
WriteFile(filepath.Join(docsDir, base+"_ops.md"), buildOpsPage(spec, navOps, docsDir))
|
WriteFile(filepath.Join(docsDir, base+"_ops.md"), buildOpsPage(spec, navOps, version, docsDir))
|
||||||
WriteFile(filepath.Join(docsDir, base+"_params.md"), buildParamsLandingPage(spec, navManual))
|
WriteFile(filepath.Join(docsDir, base+"_params.md"), buildParamsLandingPage(spec, navManual, version))
|
||||||
|
|
||||||
for _, srName := range CollectSubresources(spec) {
|
for _, srName := range CollectSubresources(spec) {
|
||||||
srBase := fmt.Sprintf("%s_%s", base, Slug(srName))
|
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)",
|
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)
|
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))
|
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) {
|
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
|
var b bytes.Buffer
|
||||||
b.WriteString("# Ресурсы провайдера\n\n")
|
b.WriteString("# Ресурсы провайдера\n\n")
|
||||||
|
|
||||||
|
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("| ID | Ресурс | Описание |\n")
|
||||||
b.WriteString("|-----|--------|----------|\n")
|
b.WriteString("|-----|--------|----------|\n")
|
||||||
for _, spec := range specs {
|
for _, spec := range svcs {
|
||||||
resName := "nubes_" + spec.Name
|
resName := "nubes_" + spec.Name
|
||||||
link := fmt.Sprintf("[%s](%s.md)", resName, spec.Name)
|
link := fmt.Sprintf("[%s](%s.md)", resName, spec.Name)
|
||||||
descr := strings.ReplaceAll(spec.ServiceDisplayName, "|", "\\|")
|
descr := strings.ReplaceAll(spec.ServiceDisplayName, "|", "\\|")
|
||||||
b.WriteString(fmt.Sprintf("| %d | %s | %s |\n", spec.ServiceID, link, descr))
|
b.WriteString(fmt.Sprintf("| %d | %s | %s |\n", spec.ServiceID, link, descr))
|
||||||
}
|
}
|
||||||
|
b.WriteString("\n")
|
||||||
|
}
|
||||||
|
|
||||||
outPath := filepath.Join(docsDir, "index.md")
|
outPath := filepath.Join(docsDir, "index.md")
|
||||||
if err := os.WriteFile(outPath, b.Bytes(), 0o644); err != nil {
|
if err := os.WriteFile(outPath, b.Bytes(), 0o644); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Warning: failed to write index.md: %v\n", err)
|
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 =====
|
// ===== internal helpers =====
|
||||||
|
|
||||||
func buildHeader(spec types.ServiceSpec, nav string) string {
|
func buildHeader(spec types.ServiceSpec, nav string, version string) string {
|
||||||
name := spec.ServiceDisplayName
|
name := spec.ServiceDisplayName
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = spec.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
|
var b strings.Builder
|
||||||
b.WriteString(buildHeader(spec, nav))
|
b.WriteString(buildHeader(spec, nav, version))
|
||||||
b.WriteString("## MAN\n\n")
|
b.WriteString("## MAN\n\n")
|
||||||
man := strings.TrimSpace(spec.ServiceMan)
|
man := strings.TrimSpace(spec.ServiceMan)
|
||||||
if man == "" {
|
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 {
|
func buildExamplePage(spec types.ServiceSpec, nav string, version string, apiEndpoint string, providerSource string) string {
|
||||||
var b strings.Builder
|
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(fmt.Sprintf("## Minimal example — only required parameters\n\n"))
|
||||||
b.WriteString("```hcl\n")
|
b.WriteString("```hcl\n")
|
||||||
b.WriteString(minimalExampleBlock(spec, version, apiEndpoint, providerSource))
|
b.WriteString(minimalExampleBlock(spec, version, apiEndpoint, providerSource))
|
||||||
@@ -281,9 +298,9 @@ func minimalExampleBlock(spec types.ServiceSpec, version string, apiEndpoint str
|
|||||||
return b.String()
|
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
|
var b strings.Builder
|
||||||
b.WriteString(buildHeader(spec, nav))
|
b.WriteString(buildHeader(spec, nav, version))
|
||||||
b.WriteString("## Create params\n\n")
|
b.WriteString("## Create params\n\n")
|
||||||
createParams := FindParams(spec.Operations, "create")
|
createParams := FindParams(spec.Operations, "create")
|
||||||
requiredParams, defaultParams := SplitParams(createParams)
|
requiredParams, defaultParams := SplitParams(createParams)
|
||||||
@@ -322,18 +339,18 @@ func buildCreateParamsPage(spec types.ServiceSpec, nav string) string {
|
|||||||
return b.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
|
var b strings.Builder
|
||||||
b.WriteString(buildHeader(spec, nav))
|
b.WriteString(buildHeader(spec, nav, version))
|
||||||
b.WriteString("## Modify params\n\n")
|
b.WriteString("## Modify params\n\n")
|
||||||
modifyParams := FindParams(spec.Operations, "modify")
|
modifyParams := FindParams(spec.Operations, "modify")
|
||||||
b.WriteString(renderModifyTable(modifyParams))
|
b.WriteString(renderModifyTable(modifyParams))
|
||||||
return b.String()
|
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
|
var b strings.Builder
|
||||||
b.WriteString(buildHeader(spec, nav))
|
b.WriteString(buildHeader(spec, nav, version))
|
||||||
b.WriteString("## Output params\n\n")
|
b.WriteString("## Output params\n\n")
|
||||||
if len(spec.Outputs.Params) == 0 {
|
if len(spec.Outputs.Params) == 0 {
|
||||||
b.WriteString("None.\n")
|
b.WriteString("None.\n")
|
||||||
@@ -406,9 +423,9 @@ func containsString(values []string, target string) bool {
|
|||||||
return false
|
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
|
var b strings.Builder
|
||||||
b.WriteString(buildHeader(spec, nav))
|
b.WriteString(buildHeader(spec, nav, version))
|
||||||
b.WriteString("## Operations\n\n")
|
b.WriteString("## Operations\n\n")
|
||||||
for _, op := range spec.Operations {
|
for _, op := range spec.Operations {
|
||||||
name := op.Name
|
name := op.Name
|
||||||
@@ -454,16 +471,16 @@ func buildOpsPage(spec types.ServiceSpec, nav string, docsDir string) string {
|
|||||||
return b.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
|
var b strings.Builder
|
||||||
b.WriteString(buildHeader(spec, nav))
|
b.WriteString(buildHeader(spec, nav, version))
|
||||||
b.WriteString("## Parameters\n\n")
|
b.WriteString("## Parameters\n\n")
|
||||||
b.WriteString(fmt.Sprintf("- [Create params](%s_params_create.md)\n", spec.Name))
|
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))
|
b.WriteString(fmt.Sprintf("- [Modify params](%s_params_modify.md)\n", spec.Name))
|
||||||
return b.String()
|
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
|
var b strings.Builder
|
||||||
srResourceName := fmt.Sprintf("nubes_%s_%s", spec.Name, Slug(srName))
|
srResourceName := fmt.Sprintf("nubes_%s_%s", spec.Name, Slug(srName))
|
||||||
b.WriteString(fmt.Sprintf("# Resource %s\n\n", srResourceName))
|
b.WriteString(fmt.Sprintf("# Resource %s\n\n", srResourceName))
|
||||||
|
|||||||
@@ -158,9 +158,19 @@ load_s3cfg_registry() {
|
|||||||
|
|
||||||
TMP_CFG="${ROOT_DIR}/.mkdocs.tmp.yml"
|
TMP_CFG="${ROOT_DIR}/.mkdocs.tmp.yml"
|
||||||
export ROOT_DIR
|
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'
|
python3 - <<'PY'
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import yaml
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
registry_host = os.environ["REGISTRY_HOST"]
|
registry_host = os.environ["REGISTRY_HOST"]
|
||||||
@@ -185,6 +195,23 @@ if docs_dir:
|
|||||||
else:
|
else:
|
||||||
text += f"\ndocs_dir: {docs_dir}\n"
|
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")
|
(root_dir / ".mkdocs.tmp.yml").write_text(text, encoding="utf-8")
|
||||||
PY
|
PY
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,7 @@
|
|||||||
line-height: 1.35;
|
line-height: 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resource pages: no sidebars, normal scrolling */
|
/* Resource pages: right sidebar (TOC) hidden, left sidebar visible */
|
||||||
.md-sidebar--primary {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-sidebar--secondary {
|
.md-sidebar--secondary {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
@@ -48,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.md-typeset .man-content {
|
.md-typeset .man-content {
|
||||||
font-size: 0.62rem;
|
font-size: 0.78rem;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user