// renderHTML 的调试模式 func renderHTMLPlus(docs *doc.Doc, opt *Options) error { app.Infoln("当前为模板调试模式,调试端口为:", opt.Port) app.Infoln("当前为模板调试模式,调试模板为:", opt.Template) p := buildHTMLPage(docs, opt) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // 获取分组名称 groupName := path.Base(r.URL.Path) if path.Ext(groupName) == htmlSuffix { groupName = strings.TrimSuffix(groupName, htmlSuffix) } // 存在该分组,则重新编译模板,并输出内容。 if group, found := p.Groups[groupName]; found { p.GroupName = groupName p.Group = group handleGroup(w, r, opt.Template, p) return } // 否则当作普通的文件请求 http.FileServer(http.Dir(opt.Template)).ServeHTTP(w, r) }) return http.ListenAndServe(opt.Port, nil) }
// 真正的程序入口,main 主要是作参数的处理。 func run() { start := time.Now() path, err := getConfigFile() if err != nil { app.Errorln(err) return } cfg, err := loadConfig(path) if err != nil { app.Errorln(err) return } // 比较版本号兼容问题 compatible, err := version.SemVerCompatible(app.Version, cfg.Version) if err != nil { app.Errorln(err) return } if !compatible { app.Errorln("当前程序与配置文件中指定的版本号不兼容") return } // 分析文档内容 docs := doc.New() wg := &sync.WaitGroup{} for _, opt := range cfg.Inputs { wg.Add(1) go func(o *input.Options) { if err := input.Parse(docs, o); err != nil { app.Errorln(err) } wg.Done() }(opt) } wg.Wait() if len(docs.Title) == 0 { docs.Title = app.DefaultTitle } // 输出内容 cfg.Output.Elapsed = time.Now().Sub(start) if err := output.Render(docs, cfg.Output); err != nil { app.Errorln(err) return } app.Infoln("完成!文档保存在", cfg.Output.Dir, "总用时", time.Now().Sub(start)) }
func main() { h := flag.Bool("h", false, "显示帮助信息") v := flag.Bool("v", false, "显示版本信息") l := flag.Bool("l", false, "显示所有支持的语言") g := flag.Bool("g", false, "在当前目录下创建一个默认的配置文件") pprofType := flag.String("pprof", "", "指定一种调试输出类型,可以为 cpu 或是 mem") flag.Usage = usage flag.Parse() switch { case *h: flag.Usage() return case *v: fmt.Fprintln(os.Stdout, app.Name, app.Version, "build with", runtime.Version()) return case *l: fmt.Fprintln(os.Stdout, "目前支持以下语言", input.Langs()) return case *g: path, err := getConfigFile() if err != nil { app.Errorln(err) return } if err = genConfigFile(path); err != nil { app.Errorln(err) return } app.Infoln("配置内容成功写入", path) return } // 指定了 pprof 参数 if len(*pprofType) > 0 { profile := filepath.Join("./", app.Profile) f, err := os.Create(profile) if err != nil { app.Errorln(err) return } defer func() { if err := f.Close(); err != nil { app.Errorln(err) return } app.Infoln("pprof 的相关参数已经写入到", profile) }() switch strings.ToLower(*pprofType) { case "mem": defer func() { if err = pprof.Lookup("heap").WriteTo(f, 1); err != nil { app.Errorln(err) } }() case "cpu": if err := pprof.StartCPUProfile(f); err != nil { app.Errorln(err) } defer pprof.StopCPUProfile() default: app.Errorln("无效的 pprof 参数") return } } run() }