Move doc-comment logic to the config pkg
This commit is contained in:
parent
97f5bb66c7
commit
8b1f19e94c
@ -1,13 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/filecoin-project/lotus/node/repo"
|
"github.com/filecoin-project/lotus/node/repo"
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -35,19 +30,7 @@ var configDefaultCmd = &cli.Command{
|
|||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
c := config.DefaultFullNode()
|
c := config.DefaultFullNode()
|
||||||
|
|
||||||
if cctx.Bool("no-comment") {
|
cb, err := config.ConfigUpdate(c, nil, !cctx.Bool("no-comment"))
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
_, _ = buf.WriteString("# Default config:\n")
|
|
||||||
e := toml.NewEncoder(buf)
|
|
||||||
if err := e.Encode(c); err != nil {
|
|
||||||
return xerrors.Errorf("encoding default config: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(buf.String())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
cb, err := config.ConfigComment(c)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -99,64 +82,12 @@ var configUpdateCmd = &cli.Command{
|
|||||||
|
|
||||||
cfgDef := config.DefaultFullNode()
|
cfgDef := config.DefaultFullNode()
|
||||||
|
|
||||||
var nodeStr, defStr string
|
updated, err := config.ConfigUpdate(cfgNode, cfgDef, !cctx.Bool("no-comment"))
|
||||||
{
|
if err != nil {
|
||||||
buf := new(bytes.Buffer)
|
return err
|
||||||
e := toml.NewEncoder(buf)
|
|
||||||
if err := e.Encode(cfgDef); err != nil {
|
|
||||||
return xerrors.Errorf("encoding default config: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defStr = buf.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
fmt.Print(string(updated))
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
e := toml.NewEncoder(buf)
|
|
||||||
if err := e.Encode(cfgNode); err != nil {
|
|
||||||
return xerrors.Errorf("encoding node config: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeStr = buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
if !cctx.Bool("no-comment") {
|
|
||||||
defLines := strings.Split(defStr, "\n")
|
|
||||||
defaults := map[string]struct{}{}
|
|
||||||
for i := range defLines {
|
|
||||||
l := strings.TrimSpace(defLines[i])
|
|
||||||
if len(l) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if l[0] == '#' || l[0] == '[' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
defaults[l] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeLines := strings.Split(nodeStr, "\n")
|
|
||||||
for i := range nodeLines {
|
|
||||||
if _, found := defaults[strings.TrimSpace(nodeLines[i])]; found {
|
|
||||||
nodeLines[i] = "#" + nodeLines[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeStr = strings.Join(nodeLines, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// sanity-check that the updated config parses the same way as the current one
|
|
||||||
{
|
|
||||||
cfgUpdated, err := config.FromReader(strings.NewReader(nodeStr), config.DefaultFullNode())
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("parsing updated config: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(cfgNode, cfgUpdated) {
|
|
||||||
return xerrors.Errorf("updated config didn't match current config")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(nodeStr)
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ var Doc = map[string][]DocField{
|
|||||||
{
|
{
|
||||||
Name: "ListenAddress",
|
Name: "ListenAddress",
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Comment: ``,
|
Comment: `Binding address for the Lotus API`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "RemoteListenAddress",
|
Name: "RemoteListenAddress",
|
||||||
|
@ -5,6 +5,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/kelseyhightower/envconfig"
|
"github.com/kelseyhightower/envconfig"
|
||||||
@ -42,15 +46,121 @@ func FromReader(reader io.Reader, def interface{}) (interface{}, error) {
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConfigComment(t interface{}) ([]byte, error) {
|
func ConfigUpdate(cfgCur, cfgDef interface{}, comment bool) ([]byte, error) {
|
||||||
buf := new(bytes.Buffer)
|
var nodeStr, defStr string
|
||||||
_, _ = buf.WriteString("# Default config:\n")
|
if cfgDef != nil {
|
||||||
e := toml.NewEncoder(buf)
|
buf := new(bytes.Buffer)
|
||||||
if err := e.Encode(t); err != nil {
|
e := toml.NewEncoder(buf)
|
||||||
return nil, xerrors.Errorf("encoding config: %w", err)
|
if err := e.Encode(cfgDef); err != nil {
|
||||||
|
return nil, xerrors.Errorf("encoding default config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defStr = buf.String()
|
||||||
}
|
}
|
||||||
b := buf.Bytes()
|
|
||||||
b = bytes.ReplaceAll(b, []byte("\n"), []byte("\n#"))
|
{
|
||||||
b = bytes.ReplaceAll(b, []byte("#["), []byte("["))
|
buf := new(bytes.Buffer)
|
||||||
return b, nil
|
e := toml.NewEncoder(buf)
|
||||||
|
if err := e.Encode(cfgCur); err != nil {
|
||||||
|
return nil, xerrors.Errorf("encoding node config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeStr = buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
if comment {
|
||||||
|
// create a map of default lines so we can comment those out later
|
||||||
|
defLines := strings.Split(defStr, "\n")
|
||||||
|
defaults := map[string]struct{}{}
|
||||||
|
for i := range defLines {
|
||||||
|
l := strings.TrimSpace(defLines[i])
|
||||||
|
if len(l) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if l[0] == '#' || l[0] == '[' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
defaults[l] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeLines := strings.Split(nodeStr, "\n")
|
||||||
|
var outLines []string
|
||||||
|
|
||||||
|
sectionRx := regexp.MustCompile(`[\[.]([^.]+)]`)
|
||||||
|
var section string
|
||||||
|
|
||||||
|
for i, line := range nodeLines {
|
||||||
|
// if this is a section, track it
|
||||||
|
trimmed := strings.TrimSpace(line)
|
||||||
|
if len(trimmed) > 0 {
|
||||||
|
if trimmed[0] == '[' {
|
||||||
|
m := sectionRx.FindSubmatch([]byte(trimmed))
|
||||||
|
if len(m) != 2 {
|
||||||
|
return nil, xerrors.Errorf("section didn't match (line %d)", i)
|
||||||
|
}
|
||||||
|
section = string(m[1])
|
||||||
|
|
||||||
|
// never comment sections
|
||||||
|
outLines = append(outLines, line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pad := strings.Repeat(" ", len(line) - len(strings.TrimLeftFunc(line, unicode.IsSpace)))
|
||||||
|
|
||||||
|
// see if we have docs for this field
|
||||||
|
{
|
||||||
|
lf := strings.Fields(line)
|
||||||
|
if len(lf) > 1 {
|
||||||
|
var doc *DocField
|
||||||
|
for _, df := range Doc[section] {
|
||||||
|
if df.Name == lf[0] {
|
||||||
|
doc = &df
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if doc != nil {
|
||||||
|
// found docfield, emit doc comment
|
||||||
|
if len(doc.Comment) > 0 {
|
||||||
|
for _, docLine := range strings.Split(doc.Comment, "\n") {
|
||||||
|
outLines = append(outLines, pad + "# " + docLine)
|
||||||
|
}
|
||||||
|
outLines = append(outLines, pad + "#")
|
||||||
|
}
|
||||||
|
|
||||||
|
outLines = append(outLines, pad + "# type: " + doc.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is the same line in the default config, comment it out it output
|
||||||
|
if _, found := defaults[strings.TrimSpace(nodeLines[i])]; (cfgDef == nil || found) && len(line) > 0 {
|
||||||
|
line = pad + "#" + line[len(pad):]
|
||||||
|
outLines = append(outLines, line, "")
|
||||||
|
} else {
|
||||||
|
outLines = append(outLines, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeStr = strings.Join(outLines, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity-check that the updated config parses the same way as the current one
|
||||||
|
if cfgDef != nil {
|
||||||
|
cfgUpdated, err := FromReader(strings.NewReader(nodeStr), cfgDef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("parsing updated config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(cfgCur, cfgUpdated) {
|
||||||
|
return nil, xerrors.Errorf("updated config didn't match current config")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return []byte(nodeStr), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfigComment(t interface{}) ([]byte, error) {
|
||||||
|
return ConfigUpdate(t, nil, true)
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,7 @@ type MinerAddressConfig struct {
|
|||||||
|
|
||||||
// API contains configs for API endpoint
|
// API contains configs for API endpoint
|
||||||
type API struct {
|
type API struct {
|
||||||
|
// Binding address for the Lotus API
|
||||||
ListenAddress string
|
ListenAddress string
|
||||||
RemoteListenAddress string
|
RemoteListenAddress string
|
||||||
Timeout Duration
|
Timeout Duration
|
||||||
|
Loading…
Reference in New Issue
Block a user