From 5e566ba8ae75cc6ae30c9ff4739301ce5f8f8afa Mon Sep 17 00:00:00 2001
From: Rod Vagg <rod@vagg.org>
Date: Mon, 6 Jan 2025 14:53:56 +1100
Subject: [PATCH] feat: generate default configs for docs without compiled
 binaries

---
 .github/workflows/check.yml                   |  2 -
 Makefile                                      |  8 +--
 documentation/en/cli-lotus-miner.md           | 20 +++---
 documentation/en/default-lotus-config.toml    |  1 -
 .../en/default-lotus-miner-config.toml        |  1 -
 .../misc/Building_a_network_skeleton.md       |  2 +-
 documentation/misc/RELEASE_ISSUE_TEMPLATE.md  |  4 +-
 scripts/docsgen-cli/main.go                   | 71 +++++++++++++++++--
 8 files changed, 79 insertions(+), 30 deletions(-)

diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 32b63360fc5..5a3c788de5b 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -35,8 +35,6 @@ jobs:
       - run: git diff --exit-code
       - run: make docsgen-cli
       - run: git diff --exit-code
-      - run: make docsgen-config
-      - run: git diff --exit-code
   check-lint:
     name: Check (lint-all)
     runs-on: ubuntu-latest
diff --git a/Makefile b/Makefile
index c80ed3f8da2..4c622d12855 100644
--- a/Makefile
+++ b/Makefile
@@ -339,7 +339,7 @@ fiximports:
 
 gen: actors-code-gen type-gen cfgdoc-gen docsgen api-gen
 	$(GOCC) run ./scripts/fiximports
-	@echo ">>> IF YOU'VE MODIFIED THE CLI OR CONFIG, REMEMBER TO ALSO RUN 'make docsgen-cli' and/or 'make docsgen-config'"
+	@echo ">>> IF YOU'VE MODIFIED THE CLI OR CONFIG, REMEMBER TO ALSO RUN 'make docsgen-cli'"
 .PHONY: gen
 
 jen: gen
@@ -352,12 +352,6 @@ docsgen-cli:
 	$(GOCC) run ./scripts/docsgen-cli
 .PHONY: docsgen-cli
 
-# Compiled lotus and lotus-miner are required to generate the default config files
-docsgen-config: lotus lotus-miner
-	./lotus config default > documentation/en/default-lotus-config.toml
-	./lotus-miner config default > documentation/en/default-lotus-miner-config.toml
-.PHONY: docsgen-config
-
 print-%:
 	@echo $*=$($*)
 
diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md
index 250df6b94e2..da3913a14a1 100644
--- a/documentation/en/cli-lotus-miner.md
+++ b/documentation/en/cli-lotus-miner.md
@@ -1397,10 +1397,10 @@ OPTIONS:
 
 ```
 NAME:
-   lotus auth create-token - Create token
+   lotus-miner auth create-token - Create token
 
 USAGE:
-   lotus auth create-token [command options] [arguments...]
+   lotus-miner auth create-token [command options] [arguments...]
 
 OPTIONS:
    --perm value  permission to assign to the token, one of: read, write, sign, admin
@@ -1411,10 +1411,10 @@ OPTIONS:
 
 ```
 NAME:
-   lotus auth api-info - Get token with API info required to connect to this node
+   lotus-miner auth api-info - Get token with API info required to connect to this node
 
 USAGE:
-   lotus auth api-info [command options] [arguments...]
+   lotus-miner auth api-info [command options] [arguments...]
 
 OPTIONS:
    --perm value  permission to assign to the token, one of: read, write, sign, admin
@@ -1444,10 +1444,10 @@ OPTIONS:
 
 ```
 NAME:
-   lotus log list - List log systems
+   lotus-miner log list - List log systems
 
 USAGE:
-   lotus log list [command options] [arguments...]
+   lotus-miner log list [command options] [arguments...]
 
 OPTIONS:
    --help, -h  show help
@@ -1457,10 +1457,10 @@ OPTIONS:
 
 ```
 NAME:
-   lotus log set-level - Set log level
+   lotus-miner log set-level - Set log level
 
 USAGE:
-   lotus log set-level [command options] [level]
+   lotus-miner log set-level [command options] [level]
 
 DESCRIPTION:
    Set the log level for logging systems:
@@ -1491,10 +1491,10 @@ OPTIONS:
 
 ```
 NAME:
-   lotus log alerts - Get alert states
+   lotus-miner log alerts - Get alert states
 
 USAGE:
-   lotus log alerts [command options] [arguments...]
+   lotus-miner log alerts [command options] [arguments...]
 
 OPTIONS:
    --all       get all (active and inactive) alerts (default: false)
diff --git a/documentation/en/default-lotus-config.toml b/documentation/en/default-lotus-config.toml
index 41bc082da38..1a915593edb 100644
--- a/documentation/en/default-lotus-config.toml
+++ b/documentation/en/default-lotus-config.toml
@@ -377,4 +377,3 @@
   # env var: LOTUS_FAULTREPORTER_CONSENSUSFAULTREPORTERADDRESS
   #ConsensusFaultReporterAddress = ""
 
-
diff --git a/documentation/en/default-lotus-miner-config.toml b/documentation/en/default-lotus-miner-config.toml
index aaf58fec1cb..e03f9579af9 100644
--- a/documentation/en/default-lotus-miner-config.toml
+++ b/documentation/en/default-lotus-miner-config.toml
@@ -650,4 +650,3 @@
   # env var: LOTUS_HARMONYDB_PORT
   #Port = "5433"
 
-
diff --git a/documentation/misc/Building_a_network_skeleton.md b/documentation/misc/Building_a_network_skeleton.md
index 1c6637fcba1..1fae76b923b 100644
--- a/documentation/misc/Building_a_network_skeleton.md
+++ b/documentation/misc/Building_a_network_skeleton.md
@@ -248,7 +248,7 @@ Note: one only needs to update `filecion-ffi`'s dependency on `go-state-types` w
 
 11. Run `make gen`.
 
-12. Run `make docsgen-cli docsgen-config`.
+12. Run `make docsgen-cli`.
 
 And you're done! These are all the steps necessary to create a network upgrade skeleton that you will be able to run in a local devnet, and creates a basis where you can start testing new FIPs. When running a local developer network from this Lotus branch, bringing in all it dependencies, you should be able to:
 
diff --git a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md
index 0507b55ea16..75cb5032fa4 100644
--- a/documentation/misc/RELEASE_ISSUE_TEMPLATE.md
+++ b/documentation/misc/RELEASE_ISSUE_TEMPLATE.md
@@ -78,7 +78,7 @@
 <!--{{  if contains "Miner" .Type}}-->
       - Ensure to update `MinerBuildVersion`
 <!--{{  end}}-->
-   - [ ] Run `make gen && make docsgen-cli docsgen-config` before committing changes.
+   - [ ] Run `make gen && make docsgen-cli` before committing changes.
    - [ ] Update the CHANGELOG
      - [ ] Change the `UNRELEASED` section header to `UNRELEASED v{{.Tag}}`
      - [ ] Set the `UNRELEASED v{{.Tag}}` section's content to be "_See https://github.com/filecoin-project/lotus/blob/release/v{{.Tag}}/CHANGELOG.md_"
@@ -118,7 +118,7 @@
 <!--  {{if contains "Miner" $.Type}}-->
     - Ensure to update `MinerBuildVersion`
 <!--  {{end}}-->
-- [ ] Run `make gen && make docsgen-cli docsgen-config` to generate documentation
+- [ ] Run `make gen && make docsgen-cli` to generate documentation
 - [ ] Create a draft PR with title `build: release Lotus {{$.Type}} v{{$.Tag}}{{$tagSuffix}}`
    - Link to PR:
    - Opening a PR will trigger a CI run that will build assets, create a draft GitHub release, and attach the assets.
diff --git a/scripts/docsgen-cli/main.go b/scripts/docsgen-cli/main.go
index fd557efb47b..e6e562e7790 100644
--- a/scripts/docsgen-cli/main.go
+++ b/scripts/docsgen-cli/main.go
@@ -3,12 +3,14 @@ package main
 import (
 	"fmt"
 	"os"
+	"path/filepath"
 
 	"github.com/urfave/cli/v2"
 
 	"github.com/filecoin-project/lotus/cli/lotus"
 	"github.com/filecoin-project/lotus/cli/miner"
 	"github.com/filecoin-project/lotus/cli/worker"
+	"github.com/filecoin-project/lotus/node/config"
 )
 
 const (
@@ -45,6 +47,22 @@ func main() {
 		os.Exit(1)
 	}
 
+	cliApps := loadCLIApps()
+
+	fmt.Println("Generating CLI documentation...")
+	failed := generateCLIDocumentation(cliApps)
+
+	fmt.Println("Generating default config files...")
+	failed = generateDefaultConfigs() || failed
+
+	if failed {
+		fmt.Println("Documentation generation failed.")
+		os.Exit(1)
+	}
+	fmt.Println("Documentation generation complete.")
+}
+
+func loadCLIApps() map[string]*cli.App {
 	// Some help output is generated based on whether the output is a terminal or not. To make stable
 	// output text, we set Stdout to not be a terminal while we load the CLI apps and reset it
 	// before generating the documentation.
@@ -58,23 +76,64 @@ func main() {
 		"lotus-miner":  miner.App(),
 	}
 
-	w.Close()
+	_ = w.Close()
 	os.Stdout = stdout
 
-	fmt.Println("Generating CLI documentation...")
+	return cliApps
+}
 
+func generateCLIDocumentation(cliApps map[string]*cli.App) bool {
+	var failed bool
 	for name, app := range cliApps {
-		for _, cmd := range app.Commands {
-			cmd.HelpName = fmt.Sprintf("%s %s", app.HelpName, cmd.Name)
-		}
+		resetCommandHelpName(app)
 
 		generator := NewDocGenerator(outputDir, app)
 		if err := generator.Generate(name); err != nil {
 			fmt.Printf(" ❌ %s: %v\n", name, err)
+			failed = true
 			continue
 		}
 		fmt.Printf(" ✅ %s\n", name)
 	}
+	return failed
+}
 
-	fmt.Println("Documentation generation complete.")
+// resetCommandHelpName resets the HelpName of all commands to include the parent command names.
+// This is needed for the case where Commands are shared between apps.
+func resetCommandHelpName(app *cli.App) {
+	var fix func(cmds []*cli.Command, helpName string)
+	fix = func(cmds []*cli.Command, helpName string) {
+		for _, cmd := range cmds {
+			cmd.HelpName = fmt.Sprintf("%s %s", helpName, cmd.Name)
+			fix(cmd.Subcommands, cmd.HelpName)
+		}
+	}
+	fix(app.Commands, app.HelpName)
+}
+
+func generateDefaultConfigs() bool {
+	var failed bool
+	if err := generateDefaultConfig(config.DefaultFullNode(), "default-lotus-config.toml"); err != nil {
+		fmt.Printf(" ❌ %s: %v\n", "lotus", err)
+		failed = true
+	} else {
+		fmt.Printf(" ✅ %s\n", "lotus")
+	}
+
+	if err := generateDefaultConfig(config.DefaultStorageMiner(), "default-lotus-miner-config.toml"); err != nil {
+		fmt.Printf(" ❌ %s: %v\n", "lotus-miner", err)
+		failed = true
+	} else {
+		fmt.Printf(" ✅ %s\n", "lotus-miner")
+	}
+	return failed
+}
+
+func generateDefaultConfig(c interface{}, file string) error {
+	cb, err := config.ConfigUpdate(c, nil, config.Commented(true), config.DefaultKeepUncommented())
+	if err != nil {
+		return err
+	}
+	output := filepath.Join(outputDir, file)
+	return os.WriteFile(output, cb, 0644)
 }