Skip to content

Commit

Permalink
docs: move reference into its own section
Browse files Browse the repository at this point in the history
  • Loading branch information
creativeprojects committed Jul 5, 2024
1 parent ffffabf commit a2e5870
Show file tree
Hide file tree
Showing 22 changed files with 751 additions and 474 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ status.json

# documentation
/docs/content/configuration/reference/index.md
/docs/content/reference/**/*.md
/docs/static/jsonschema
/public
.hugo_build.lock
Expand Down
96 changes: 0 additions & 96 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,22 @@ package main

import (
"crypto/rand"
_ "embed"
"encoding/base64"
"errors"
"fmt"
"io"
"regexp"
"slices"
"sort"
"strconv"
"strings"

"github.com/creativeprojects/clog"
"github.com/creativeprojects/resticprofile/config"
"github.com/creativeprojects/resticprofile/config/jsonschema"
"github.com/creativeprojects/resticprofile/constants"
"github.com/creativeprojects/resticprofile/platform"
"github.com/creativeprojects/resticprofile/remote"
"github.com/creativeprojects/resticprofile/restic"
"github.com/creativeprojects/resticprofile/schedule"
"github.com/creativeprojects/resticprofile/term"
"github.com/creativeprojects/resticprofile/util/templates"
"github.com/creativeprojects/resticprofile/win"
"golang.org/x/exp/maps"
)
Expand Down Expand Up @@ -201,97 +196,6 @@ func completeCommand(output io.Writer, ctx commandContext) error {
return nil
}

//go:embed contrib/completion/bash-completion.sh
var bashCompletionScript string

//go:embed contrib/completion/zsh-completion.sh
var zshCompletionScript string

func generateCommand(output io.Writer, ctx commandContext) (err error) {
args := ctx.request.arguments
// enforce no-log
logger := clog.GetDefaultLogger()
handler := logger.GetHandler()
logger.SetHandler(clog.NewDiscardHandler())

if slices.Contains(args, "--bash-completion") {
_, err = fmt.Fprintln(output, bashCompletionScript)
} else if slices.Contains(args, "--config-reference") {
err = generateConfigReference(output, args[slices.Index(args, "--config-reference")+1:])
} else if slices.Contains(args, "--json-schema") {
err = generateJsonSchema(output, args[slices.Index(args, "--json-schema")+1:])
} else if slices.Contains(args, "--random-key") {
ctx.flags.resticArgs = args[slices.Index(args, "--random-key"):]
err = randomKey(output, ctx)
} else if slices.Contains(args, "--zsh-completion") {
_, err = fmt.Fprintln(output, zshCompletionScript)
} else {
err = fmt.Errorf("nothing to generate for: %s", strings.Join(args, ", "))
}

if err != nil {
logger.SetHandler(handler)
}
return
}

//go:embed contrib/templates/config-reference.gomd
var configReferenceTemplate string

func generateConfigReference(output io.Writer, args []string) (err error) {
resticVersion := restic.AnyVersion
if slices.Contains(args, "--version") {
args = args[slices.Index(args, "--version"):]
if len(args) > 1 {
resticVersion = args[1]
args = args[2:]
}
}

data := config.NewTemplateInfoData(resticVersion)
tpl := templates.New("config-reference", data.GetFuncs())

if len(args) > 0 {
tpl, err = tpl.ParseFiles(args...)
} else {
tpl, err = tpl.Parse(configReferenceTemplate)
}

if err != nil {
err = fmt.Errorf("parsing failed: %w", err)
} else {
err = tpl.Execute(output, data)
}
return
}

func generateJsonSchema(output io.Writer, args []string) (err error) {
resticVersion := restic.AnyVersion
if slices.Contains(args, "--version") {
args = args[slices.Index(args, "--version"):]
if len(args) > 1 {
resticVersion = args[1]
args = args[2:]
}
}

version := config.Version02
if len(args) > 0 && args[0] == "v1" {
version = config.Version01
}

return jsonschema.WriteJsonSchema(version, resticVersion, output)
}

func sortedProfileKeys(data map[string]*config.Profile) []string {
keys := make([]string, 0, len(data))
for key := range data {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}

func showProfile(output io.Writer, ctx commandContext) error {
c := ctx.config
flags := ctx.flags
Expand Down
9 changes: 9 additions & 0 deletions commands_display.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,15 @@ func displayGroups(output io.Writer, configuration *config.Config, flags command
out("\n")
}

func sortedProfileKeys(data map[string]*config.Profile) []string {
keys := make([]string, 0, len(data))
for key := range data {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}

// lineLengthWriter limits the max line length, adding line breaks ('\n') as needed.
// the writer detects the right most column (consecutive whitespace) and aligns content if possible.
type lineLengthWriter struct {
Expand Down
180 changes: 180 additions & 0 deletions commands_generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package main

import (
"embed"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"slices"
"strings"
"text/template"

"github.com/creativeprojects/clog"
"github.com/creativeprojects/resticprofile/config"
"github.com/creativeprojects/resticprofile/config/jsonschema"
"github.com/creativeprojects/resticprofile/restic"
"github.com/creativeprojects/resticprofile/util/templates"
)

//go:embed contrib/completion/bash-completion.sh
var bashCompletionScript string

//go:embed contrib/completion/zsh-completion.sh
var zshCompletionScript string

func generateCommand(output io.Writer, ctx commandContext) (err error) {
args := ctx.request.arguments
// enforce no-log
logger := clog.GetDefaultLogger()
handler := logger.GetHandler()
logger.SetHandler(clog.NewDiscardHandler())

if slices.Contains(args, "--bash-completion") {
_, err = fmt.Fprintln(output, bashCompletionScript)
} else if slices.Contains(args, "--config-reference") {
err = generateConfigReference(output, args[slices.Index(args, "--config-reference")+1:])
} else if slices.Contains(args, "--json-schema") {
err = generateJsonSchema(output, args[slices.Index(args, "--json-schema")+1:])
} else if slices.Contains(args, "--random-key") {
ctx.flags.resticArgs = args[slices.Index(args, "--random-key"):]
err = randomKey(output, ctx)
} else if slices.Contains(args, "--zsh-completion") {
_, err = fmt.Fprintln(output, zshCompletionScript)
} else {
err = fmt.Errorf("nothing to generate for: %s", strings.Join(args, ", "))
}

if err != nil {
logger.SetHandler(handler)
}
return
}

//go:embed contrib/templates/*
var configReferenceTemplates embed.FS

func generateConfigReference(output io.Writer, args []string) error {
resticVersion := restic.AnyVersion
if slices.Contains(args, "--version") {
args = args[slices.Index(args, "--version"):]
if len(args) > 1 {
resticVersion = args[1]
args = args[2:]
}
}

data := config.NewTemplateInfoData(resticVersion)
tpl := templates.New("config-reference", data.GetFuncs())
templates, err := fs.Sub(configReferenceTemplates, "contrib/templates")
if err != nil {
return fmt.Errorf("cannot load templates: %w", err)
}

if len(args) > 0 {
tpl, err = tpl.ParseFiles(args...)
} else {
tpl, err = tpl.ParseFS(templates, "*.gomd")
}

if err != nil {
return fmt.Errorf("parsing failed: %w", err)
}

staticPages := []struct {
templateName string
fileName string
}{
{"reference.gomd", "_index.md"},
{"global.gomd", "global.md"},
{"profile.gomd", "profile/_index.md"},
{"nested.gomd", "nested/_index.md"},
{"groups.gomd", "groups.md"},
{"value-types.gomd", "value-types.md"},
{"json-schema.gomd", "json-schema.md"},
}

for _, staticPage := range staticPages {
fmt.Fprintf(output, "generating %s...\n", staticPage.templateName)
err = generatePage(tpl, data, staticPage.fileName, staticPage.templateName)
if err != nil {
return fmt.Errorf("unable to generate page %s: %w", staticPage.fileName, err)
}
}

weight := 1
for _, profileSection := range data.ProfileSections() {
fmt.Fprintf(output, "generating profile section %s (weight %d)...\n", profileSection.Name(), weight)
sectionData := SectionInfoData{
DefaultData: data.DefaultData,
Section: profileSection,
Weight: weight,
}
err = generatePage(tpl, sectionData, filepath.Join("profile", profileSection.Name()+".md"), "profile.sub-section.gomd")
if err != nil {
return fmt.Errorf("unable to generate profile section %s: %w", profileSection.Name(), err)
}
weight++
}

weight = 1
for _, nestedSection := range data.NestedSections() {
fmt.Fprintf(output, "generating nested section %s (weight %d)...\n", nestedSection.Name(), weight)
sectionData := SectionInfoData{
DefaultData: data.DefaultData,
Section: nestedSection,
Weight: weight,
}
err = generatePage(tpl, sectionData, filepath.Join("nested", nestedSection.Name()+".md"), "profile.nested-section.gomd")
if err != nil {
return fmt.Errorf("unable to generate nested section %s: %w", nestedSection.Name(), err)
}
weight++
}
return nil
}

func generatePage(tpl *template.Template, data any, fileName, templateName string) error {
fullname := filepath.Join("docs/content/reference", fileName)
err := os.MkdirAll(filepath.Dir(fullname), 0o755)
if err != nil {
return fmt.Errorf("cannot create directory: %w", err)
}
file, err := os.Create(fullname)
if err != nil {
return fmt.Errorf("cannot open file: %w", err)
}
defer file.Close()

err = tpl.ExecuteTemplate(file, templateName, data)
if err != nil {
return fmt.Errorf("cannot execute template: %w", err)
}
return nil
}

func generateJsonSchema(output io.Writer, args []string) (err error) {
resticVersion := restic.AnyVersion
if slices.Contains(args, "--version") {
args = args[slices.Index(args, "--version"):]
if len(args) > 1 {
resticVersion = args[1]
args = args[2:]
}
}

version := config.Version02
if len(args) > 0 && args[0] == "v1" {
version = config.Version01
}

return jsonschema.WriteJsonSchema(version, resticVersion, output)
}

// SectionInfoData is used as data for go templates that render profile section references
type SectionInfoData struct {
templates.DefaultData
Section config.SectionInfo
Weight int
}
Loading

0 comments on commit a2e5870

Please sign in to comment.