Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CLI flag --dry-run for no file output #71

Merged
merged 1 commit into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### Features

* Adds CLI flag `--strict` to break with an error instead of warnings (#68)
* Adds CLI flag `--dry-run` to run without file output (#71)
* Checks package re-exports, giving warning or error on fail (#68)
* Allows for cross-refs to aliases in modules and structs (#69)

Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,18 @@ Usage:
modo OUT-PATH [flags]

Examples:
modo docs -i docs.json # from a file
modo docs -i docs.json # from a file
mojo doc ./src | modo docs # from 'mojo doc'

Flags:
-i, --input string 'mojo doc' JSON file to process. Reads from STDIN if not specified.
-i, --input string 'mojo doc' JSON file to process. Reads from STDIN if not specified.
-f, --format string Output format. One of (plain|mdbook|hugo). (default "plain")
-e, --exports Process according to 'Exports:' sections in packages.
--short-links Render shortened link labels, stripping packages and modules.
--case-insensitive Build for systems that are not case-sensitive regarding file names.
--case-insensitive Build for systems that are not case-sensitive regarding file names.
Appends hyphen (-) to capitalized file names.
-s, --strict Strict mode. Errors instead of warnings.
--strict Strict mode. Errors instead of warnings.
--dry-run Dry-run without any file output.
-t, --templates strings Optional directories with templates for (partial) overwrite.
See folder assets/templates in the repository.
-h, --help help for modo
Expand Down
23 changes: 22 additions & 1 deletion document/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ import (
"text/template"
)

type Config struct {
InputFile string
OutputDir string
TemplateDirs []string
UseExports bool
ShortLinks bool
CaseInsensitive bool
Strict bool
DryRun bool
}

type Processor struct {
Config *Config
Template *template.Template
Expand All @@ -26,7 +37,7 @@ func NewProcessor(docs *Docs, f Formatter, t *template.Template, config *Config)
})
}

func NewProcessorWithWriter(docs *Docs, f Formatter, t *template.Template, config *Config, writer func(text, file string) error) *Processor {
func NewProcessorWithWriter(docs *Docs, f Formatter, t *template.Template, config *Config, writer func(file, text string) error) *Processor {
return &Processor{
Config: config,
Template: t,
Expand Down Expand Up @@ -86,3 +97,13 @@ func (proc *Processor) addElementPath(elPath, filePath []string, kind string, is
proc.allPaths[strings.Join(elPath, ".")] = true
_, _ = filePath, kind
}

func (proc *Processor) mkDirs(path string) error {
if proc.Config.DryRun {
return nil
}
if err := os.MkdirAll(path, os.ModePerm); err != nil && !os.IsExist(err) {
return err
}
return nil
}
45 changes: 24 additions & 21 deletions document/render.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package document

import (
"fmt"
"io/fs"
"os"
"path"
Expand All @@ -11,26 +12,35 @@ import (
"github.com/mlange-42/modo/assets"
)

type Config struct {
OutputDir string
TemplateDirs []string
UseExports bool
ShortLinks bool
CaseSensitive bool
Strict bool
}

func Render(docs *Docs, config *Config, form Formatter) error {
t, err := loadTemplates(form, config.TemplateDirs...)
if err != nil {
return err
}
proc := NewProcessor(docs, form, t, config)
return renderWith(config, proc)
if !config.DryRun {
proc := NewProcessor(docs, form, t, config)
return renderWith(config, proc)
}

files := []string{}
proc := NewProcessorWithWriter(docs, form, t, config, func(file, text string) error {
files = append(files, file)
return nil
})
err = renderWith(config, proc)
if err != nil {
return err
}

fmt.Println("Dry-run. Would write these files:")
for _, f := range files {
fmt.Println(f)
}
return nil
}

func renderWith(config *Config, proc *Processor) error {
caseSensitiveSystem = config.CaseSensitive
caseSensitiveSystem = !config.CaseInsensitive
if err := proc.PrepareDocs(); err != nil {
return err
}
Expand Down Expand Up @@ -58,7 +68,7 @@ func renderElement(data interface {
func renderPackage(p *Package, dir []string, proc *Processor) error {
newDir := appendNew(dir, p.GetFileName())
pkgPath := path.Join(newDir...)
if err := mkDirs(pkgPath); err != nil {
if err := proc.mkDirs(pkgPath); err != nil {
return err
}

Expand Down Expand Up @@ -97,7 +107,7 @@ func renderPackage(p *Package, dir []string, proc *Processor) error {

func renderModule(mod *Module, dir []string, proc *Processor) error {
newDir := appendNew(dir, mod.GetFileName())
if err := mkDirs(path.Join(newDir...)); err != nil {
if err := proc.mkDirs(path.Join(newDir...)); err != nil {
return err
}

Expand Down Expand Up @@ -210,10 +220,3 @@ func linkAndWrite(text string, dir []string, modElems int, kind string, proc *Pr
}
return proc.WriteFile(outFile, text)
}

func mkDirs(path string) error {
if err := os.MkdirAll(path, os.ModePerm); err != nil && !os.IsExist(err) {
return err
}
return nil
}
28 changes: 19 additions & 9 deletions format/mdbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ func (f *MdBookFormatter) WriteAuxiliary(p *document.Package, dir string, proc *
if err := f.writeSummary(p, dir, proc); err != nil {
return err
}
if err := f.writeToml(p, dir, proc.Template); err != nil {
if err := f.writeToml(p, dir, proc); err != nil {
return err
}
if err := f.writeCss(dir); err != nil {
if err := f.writeCss(dir, proc); err != nil {
return err
}
return nil
Expand Down Expand Up @@ -62,6 +62,9 @@ func (f *MdBookFormatter) writeSummary(p *document.Package, dir string, proc *do
return err
}
summaryPath := path.Join(dir, p.GetFileName(), "SUMMARY.md")
if proc.Config.DryRun {
return nil
}
if err := os.WriteFile(summaryPath, []byte(summary), 0666); err != nil {
return err
}
Expand Down Expand Up @@ -205,11 +208,14 @@ func (f *MdBookFormatter) renderModuleMember(mem document.Named, pathStr string,
return nil
}

func (f *MdBookFormatter) writeToml(p *document.Package, dir string, t *template.Template) error {
toml, err := f.renderToml(p, t)
func (f *MdBookFormatter) writeToml(p *document.Package, dir string, proc *document.Processor) error {
toml, err := f.renderToml(p, proc.Template)
if err != nil {
return err
}
if proc.Config.DryRun {
return nil
}
tomlPath := path.Join(dir, "book.toml")
if err := os.WriteFile(tomlPath, []byte(toml), 0666); err != nil {
return err
Expand All @@ -225,17 +231,21 @@ func (f *MdBookFormatter) renderToml(p *document.Package, t *template.Template)
return b.String(), nil
}

func (f *MdBookFormatter) writeCss(dir string) error {
func (f *MdBookFormatter) writeCss(dir string, proc *document.Processor) error {
cssDir := path.Join(dir, "css")
if err := os.MkdirAll(cssDir, os.ModePerm); err != nil && !os.IsExist(err) {
return err
if !proc.Config.DryRun {
if err := os.MkdirAll(cssDir, os.ModePerm); err != nil && !os.IsExist(err) {
return err
}
}
css, err := fs.ReadFile(assets.CSS, "css/mdbook.css")
if err != nil {
return err
}
if err := os.WriteFile(path.Join(cssDir, "custom.css"), css, 0666); err != nil {
return err
if !proc.Config.DryRun {
if err := os.WriteFile(path.Join(cssDir, "custom.css"), css, 0666); err != nil {
return err
}
}
return nil
}
50 changes: 17 additions & 33 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,9 @@ func main() {
fmt.Printf("Completed in %.1fms 🧯\n", float64(time.Since(start).Microseconds())/1000.0)
}

type args struct {
file string
renderFormat string
caseInsensitive bool
useExports bool
shortLinks bool
strict bool
outDir string
templateDirs []string
}

func rootCommand() *cobra.Command {
var cliArgs args
var cliArgs document.Config
var renderFormat string

root := &cobra.Command{
Use: "modo OUT-PATH",
Expand All @@ -46,18 +36,19 @@ Modo generates Markdown for static site generators (SSGs) from 'mojo doc' JSON o
Args: cobra.ExactArgs(1),
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
cliArgs.outDir = args[0]
return run(&cliArgs)
cliArgs.OutputDir = args[0]
return run(&cliArgs, renderFormat)
},
}

root.Flags().StringVarP(&cliArgs.file, "input", "i", "", "'mojo doc' JSON file to process. Reads from STDIN if not specified.")
root.Flags().StringVarP(&cliArgs.renderFormat, "format", "f", "plain", "Output format. One of (plain|mdbook|hugo).")
root.Flags().BoolVarP(&cliArgs.useExports, "exports", "e", false, "Process according to 'Exports:' sections in packages.")
root.Flags().BoolVar(&cliArgs.shortLinks, "short-links", false, "Render shortened link labels, stripping packages and modules.")
root.Flags().BoolVar(&cliArgs.caseInsensitive, "case-insensitive", false, "Build for systems that are not case-sensitive regarding file names.\nAppends hyphen (-) to capitalized file names.")
root.Flags().BoolVarP(&cliArgs.strict, "strict", "s", false, "Strict mode. Errors instead of warnings.")
root.Flags().StringSliceVarP(&cliArgs.templateDirs, "templates", "t", []string{}, "Optional directories with templates for (partial) overwrite.\nSee folder assets/templates in the repository.")
root.Flags().StringVarP(&cliArgs.InputFile, "input", "i", "", "'mojo doc' JSON file to process. Reads from STDIN if not specified.")
root.Flags().StringVarP(&renderFormat, "format", "f", "plain", "Output format. One of (plain|mdbook|hugo).")
root.Flags().BoolVarP(&cliArgs.UseExports, "exports", "e", false, "Process according to 'Exports:' sections in packages.")
root.Flags().BoolVar(&cliArgs.ShortLinks, "short-links", false, "Render shortened link labels, stripping packages and modules.")
root.Flags().BoolVar(&cliArgs.CaseInsensitive, "case-insensitive", false, "Build for systems that are not case-sensitive regarding file names.\nAppends hyphen (-) to capitalized file names.")
root.Flags().BoolVar(&cliArgs.Strict, "strict", false, "Strict mode. Errors instead of warnings.")
root.Flags().BoolVar(&cliArgs.DryRun, "dry-run", false, "Dry-run without any file output.")
root.Flags().StringSliceVarP(&cliArgs.TemplateDirs, "templates", "t", []string{}, "Optional directories with templates for (partial) overwrite.\nSee folder assets/templates in the repository.")

root.Flags().SortFlags = false
root.MarkFlagFilename("input", "json")
Expand All @@ -66,29 +57,22 @@ Modo generates Markdown for static site generators (SSGs) from 'mojo doc' JSON o
return root
}

func run(args *args) error {
if args.outDir == "" {
func run(args *document.Config, renderFormat string) error {
if args.OutputDir == "" {
return fmt.Errorf("no output path given")
}

docs, err := readDocs(args.file)
docs, err := readDocs(args.InputFile)
if err != nil {
return err
}

rFormat, err := format.GetFormat(args.renderFormat)
rFormat, err := format.GetFormat(renderFormat)
if err != nil {
return err
}
formatter := format.GetFormatter(rFormat)
err = formatter.Render(docs, &document.Config{
OutputDir: args.outDir,
TemplateDirs: args.templateDirs,
UseExports: args.useExports,
ShortLinks: args.shortLinks,
CaseSensitive: !args.caseInsensitive,
Strict: args.strict,
})
err = formatter.Render(docs, args)
if err != nil {
return err
}
Expand Down
Loading