• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlange-42 / modo / 13250273603

10 Feb 2025 08:57PM CUT coverage: 74.172% (+0.008%) from 74.164%
13250273603

push

github

web-flow
Handle trailing slash in remote URL (#223)

3 of 3 new or added lines in 1 file covered. (100.0%)

2375 of 3202 relevant lines covered (74.17%)

48.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.15
/internal/cmd/build.go
1
package cmd
2

3
import (
4
        "fmt"
5
        "os"
6
        "time"
7

8
        "github.com/mlange-42/modo/internal/document"
9
        "github.com/mlange-42/modo/internal/format"
10
        "github.com/spf13/cobra"
11
        "github.com/spf13/viper"
12
)
13

14
func buildCommand(stopWatch chan struct{}) (*cobra.Command, error) {
5✔
15
        v := viper.New()
5✔
16
        var config string
5✔
17
        var watch bool
5✔
18

5✔
19
        var cwd string
5✔
20

5✔
21
        root := &cobra.Command{
5✔
22
                Use:   "build [PATH]",
5✔
23
                Short: "Build documentation from 'mojo doc' JSON",
5✔
24
                Long: `Build documentation from 'mojo doc' JSON.
5✔
25

5✔
26
Builds based on the 'modo.yaml' file in the current directory if no path is given.
5✔
27
The flags listed below overwrite the settings from that file.
5✔
28

5✔
29
Complete documentation at https://mlange-42.github.io/modo/`,
5✔
30
                Example: `  modo init hugo                 # set up a project, e.g. for Hugo
5✔
31
  modo build                     # build the docs`,
5✔
32
                Args:         cobra.MaximumNArgs(1),
5✔
33
                SilenceUsage: true,
5✔
34
                PreRunE: func(cmd *cobra.Command, args []string) error {
8✔
35
                        var err error
3✔
36
                        if err = checkConfigFile(config); err != nil {
3✔
37
                                return err
×
38
                        }
×
39
                        if cwd, err = mountProject(v, config, args); err != nil {
3✔
40
                                return err
×
41
                        }
×
42
                        return nil
3✔
43
                },
44
                RunE: func(cmd *cobra.Command, args []string) error {
3✔
45
                        defer func() {
6✔
46
                                if err := os.Chdir(cwd); err != nil {
3✔
47
                                        fmt.Println(err)
×
48
                                }
×
49
                        }()
50

51
                        start := time.Now()
3✔
52

3✔
53
                        cliArgs, err := document.ConfigFromViper(v)
3✔
54
                        if err != nil {
3✔
55
                                return err
×
56
                        }
×
57
                        if err := runBuild(cliArgs); err != nil {
3✔
58
                                return err
×
59
                        }
×
60
                        if watch {
4✔
61
                                return watchAndRun(cliArgs, runBuild, stopWatch)
1✔
62
                        }
1✔
63

64
                        fmt.Printf("Completed in %.1fms 🧯\n", float64(time.Since(start).Microseconds())/1000.0)
2✔
65
                        return nil
2✔
66
                },
67
        }
68

69
        root.Flags().StringVarP(&config, "config", "c", defaultConfigFile, "Config file in the working directory to use")
5✔
70
        root.Flags().StringSliceP("input", "i", []string{}, "'mojo doc' JSON file to process. Reads from STDIN if not specified.\nIf a single directory is given, it is processed recursively")
5✔
71
        root.Flags().StringP("output", "o", "", "Output folder for generated Markdown files")
5✔
72
        root.Flags().StringP("tests", "t", "", "Target folder to extract doctests for 'mojo test'.\nSee also command 'modo test' (default no doctests)")
5✔
73
        root.Flags().StringP("format", "f", "plain", "Output format. One of (plain|mdbook|hugo)")
5✔
74
        root.Flags().BoolP("exports", "e", false, "Process according to 'Exports:' sections in packages")
5✔
75
        root.Flags().BoolP("short-links", "s", false, "Render shortened link labels, stripping packages and modules")
5✔
76
        root.Flags().BoolP("report-missing", "M", false, "Report missing docstings and coverage")
5✔
77
        root.Flags().BoolP("case-insensitive", "C", false, "Build for systems that are not case-sensitive regarding file names.\nAppends hyphen (-) to capitalized file names")
5✔
78
        root.Flags().BoolP("strict", "S", false, "Strict mode. Errors instead of warnings")
5✔
79
        root.Flags().BoolP("dry-run", "D", false, "Dry-run without any file output. Disables post-processing scripts")
5✔
80
        root.Flags().BoolP("bare", "B", false, "Don't run pre- and post-processing scripts")
5✔
81
        root.Flags().BoolVarP(&watch, "watch", "W", false, "Re-run on changes of sources and documentation files.\nDisables post-processing scripts after running them once")
5✔
82
        root.Flags().StringSliceP("templates", "T", []string{}, "Optional directories with templates for (partial) overwrite.\nSee folder assets/templates in the repository")
5✔
83

5✔
84
        root.Flags().SortFlags = false
5✔
85
        root.MarkFlagFilename("config", "yaml")
5✔
86
        root.MarkFlagFilename("input", "json")
5✔
87
        root.MarkFlagDirname("output")
5✔
88
        root.MarkFlagDirname("tests")
5✔
89
        root.MarkFlagDirname("templates")
5✔
90

5✔
91
        err := bindFlags(v, root.Flags())
5✔
92
        if err != nil {
5✔
93
                return nil, err
×
94
        }
×
95
        return root, nil
5✔
96
}
97

98
func runBuild(args *document.Config) error {
3✔
99
        if args.OutputDir == "" {
3✔
100
                return fmt.Errorf("no output path given")
×
101
        }
×
102

103
        if !args.Bare {
6✔
104
                if err := runPreBuildCommands(args); err != nil {
3✔
105
                        return err
×
106
                }
×
107
        }
108

109
        formatter, err := format.GetFormatter(args.RenderFormat)
3✔
110
        if err != nil {
3✔
111
                return err
×
112
        }
×
113

114
        if err := runFilesOrDir(runBuildOnce, args, formatter); err != nil {
3✔
115
                return err
×
116
        }
×
117

118
        if !args.Bare && !args.DryRun {
6✔
119
                if err := runPostBuildCommands(args); err != nil {
3✔
120
                        return err
×
121
                }
×
122
        }
123

124
        return nil
3✔
125
}
126

127
func runBuildOnce(file string, args *document.Config, form document.Formatter, subdir string, isFile, isDir bool) error {
6✔
128
        if isDir {
9✔
129
                if err := document.ExtractTestsMarkdown(args, form, file, true); err != nil {
3✔
130
                        return err
×
131
                }
×
132
                return runDir(file, args, form, runBuildOnce)
3✔
133
        }
134
        docs, err := readDocs(file)
3✔
135
        if err != nil {
3✔
136
                return err
×
137
        }
×
138
        err = document.Render(docs, args, form, subdir)
3✔
139
        if err != nil {
3✔
140
                return err
×
141
        }
×
142
        return nil
3✔
143
}
144

145
func runPreBuildCommands(cfg *document.Config) error {
3✔
146
        if err := runCommands(cfg.PreRun); err != nil {
3✔
147
                return commandError("pre-run", err)
×
148
        }
×
149
        if err := runCommands(cfg.PreBuild); err != nil {
3✔
150
                return commandError("pre-build", err)
×
151
        }
×
152
        if cfg.TestOutput != "" {
6✔
153
                if err := runCommands(cfg.PreTest); err != nil {
3✔
154
                        return commandError("pre-test", err)
×
155
                }
×
156
        }
157
        return nil
3✔
158
}
159

160
func runPostBuildCommands(cfg *document.Config) error {
3✔
161
        if cfg.TestOutput != "" {
6✔
162
                if err := runCommands(cfg.PostTest); err != nil {
3✔
163
                        return commandError("post-test", err)
×
164
                }
×
165
        }
166
        if err := runCommands(cfg.PostBuild); err != nil {
3✔
167
                return commandError("post-build", err)
×
168
        }
×
169
        if err := runCommands(cfg.PostRun); err != nil {
3✔
170
                return commandError("post-run", err)
×
171
        }
×
172
        return nil
3✔
173
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc