// build generates data from source files. func (w *walker) build(srcs []*source) (*Package, error) { // Set created time. w.pdoc.Created = time.Now().UTC() // Add source files to walker, I skipped references here. w.srcs = make(map[string]*source) for _, src := range srcs { if strings.HasSuffix(src.name, ".go") { w.srcs[src.name] = src } else if src.name == "doc_zh.md" { // Multi-language documentation. w.mldocs[src.name] = src } } // Check number of source files. if len(w.srcs) == 0 { // No source file. return w.pdoc, nil } w.fset = token.NewFileSet() // Find the package and associated files. ctxt := build.Context{ GOOS: runtime.GOOS, GOARCH: runtime.GOARCH, CgoEnabled: true, JoinPath: path.Join, IsAbsPath: path.IsAbs, SplitPathList: func(list string) []string { return strings.Split(list, ":") }, IsDir: func(path string) bool { panic("unexpected") }, HasSubdir: func(root, dir string) (rel string, ok bool) { panic("unexpected") }, ReadDir: func(dir string) (fi []os.FileInfo, err error) { return w.readDir(dir) }, OpenFile: func(path string) (r io.ReadCloser, err error) { return w.openFile(path) }, Compiler: "gc", } bpkg, err := ctxt.ImportDir(w.pdoc.ImportPath, 0) // Continue if there are no Go source files; we still want the directory info. if _, nogo := err.(*build.NoGoError); err != nil && !nogo { return w.pdoc, errors.New("doc.walker.build(): " + err.Error()) } // Parse the Go files files := make(map[string]*ast.File) for _, name := range append(bpkg.GoFiles, bpkg.CgoFiles...) { file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments) if err != nil { beego.Error("doc.walker.build():", err) continue } w.pdoc.Files = append(w.pdoc.Files, name) //w.pdoc.SourceSize += len(w.srcs[name].data) files[name] = file } apkg, _ := ast.NewPackage(w.fset, files, simpleImporter, nil) // Find examples in the test files. /*for _, name := range append(bpkg.TestGoFiles, bpkg.XTestGoFiles...) { file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments) if err != nil { w.pdoc.Errors = append(w.pdoc.Errors, err.Error()) continue } w.pdoc.TestFiles = append(w.pdoc.TestFiles, &File{Name: name, URL: w.srcs[name].browseURL}) w.pdoc.TestSourceSize += len(w.srcs[name].data) w.examples = append(w.examples, doc.Examples(file)...) }*/ //w.vetPackage(apkg) mode := doc.Mode(0) if w.pdoc.ImportPath == "builtin" { mode |= doc.AllDecls } pdoc := doc.New(apkg, w.pdoc.ImportPath, mode) w.pdoc.Doc = strings.TrimRight(pdoc.Doc, " \t\n\r") w.pdoc.Synopsis = utils.Synopsis(w.pdoc.Doc) //w.pdoc.Examples = w.getExamples("") //w.pdoc.IsCmd = bpkg.IsCommand() w.pdoc.GOOS = ctxt.GOOS w.pdoc.GOARCH = ctxt.GOARCH w.srcLines = make(map[string][]string) w.pdoc.Consts = w.values(pdoc.Consts) w.pdoc.Funcs = w.funcs(pdoc.Funcs) w.pdoc.Types = w.types(pdoc.Types) w.pdoc.Vars = w.values(pdoc.Vars) //w.pdoc.Notes = w.notes(pdoc.Notes) w.pdoc.Imports = bpkg.Imports w.pdoc.TestImports = bpkg.TestImports //w.pdoc.XTestImports = bpkg.XTestImports beego.Info("doc.walker.build(", pdoc.ImportPath, "), Goroutine #", runtime.NumGoroutine()) return w.pdoc, err }
// build generates data from source files. func (w *walker) build(srcs []*source) (*Package, error) { // Set created time. w.pdoc.Created = time.Now().UTC() // Add source files to walker, I skipped references here. w.srcs = make(map[string]*source) for _, src := range srcs { if strings.HasSuffix(src.name, ".go") { w.srcs[src.name] = src } else if strings.HasPrefix(strings.ToLower(src.name), "readme") { // Readme. w.pdoc.Doc = string(src.data) if len(w.pdoc.Doc) > 0 { if w.pdoc.Doc[0] == '\n' { w.pdoc.Doc = w.pdoc.Doc[1:] } // Remove title and `==========`. w.pdoc.Doc = w.pdoc.Doc[strings.Index(w.pdoc.Doc, "\n")+1:] if len(w.pdoc.Doc) == 0 { continue } if w.pdoc.Doc[0] == '=' { w.pdoc.Doc = w.pdoc.Doc[strings.Index(w.pdoc.Doc, "\n")+1:] } // Find all picture path of build system. for _, m := range buildPicPattern.FindAllString(w.pdoc.Doc, -1) { start := strings.Index(m, "http") end := strings.Index(m, ")") if (start > -1) && (end > -1) && (start < end) { picPath := m[start:end] w.pdoc.Doc = strings.Replace(w.pdoc.Doc, m, "![]("+picPath+")", 1) } } w.pdoc.Doc = string(blackfriday.MarkdownCommon([]byte(w.pdoc.Doc))) w.pdoc.Doc = strings.Replace(w.pdoc.Doc, "h3>", "h5>", -1) w.pdoc.Doc = strings.Replace(w.pdoc.Doc, "h2>", "h4>", -1) w.pdoc.Doc = strings.Replace(w.pdoc.Doc, "h1>", "h3>", -1) w.pdoc.Doc = strings.Replace(w.pdoc.Doc, "<center>", "", -1) w.pdoc.Doc = strings.Replace(w.pdoc.Doc, "</center>", "", -1) w.pdoc.Doc = "<div style='display:block; padding: 3px; border:1px solid #4F4F4F;'>" + w.pdoc.Doc + "</div>" } } } w.fset = token.NewFileSet() // Find the package and associated files. ctxt := build.Context{ GOOS: runtime.GOOS, GOARCH: runtime.GOARCH, CgoEnabled: true, JoinPath: path.Join, IsAbsPath: path.IsAbs, SplitPathList: func(list string) []string { return strings.Split(list, ":") }, IsDir: func(path string) bool { panic("unexpected") }, HasSubdir: func(root, dir string) (rel string, ok bool) { panic("unexpected") }, ReadDir: func(dir string) (fi []os.FileInfo, err error) { return w.readDir(dir) }, OpenFile: func(path string) (r io.ReadCloser, err error) { return w.openFile(path) }, Compiler: "gc", } bpkg, err := ctxt.ImportDir(w.pdoc.ImportPath, 0) // Continue if there are no Go source files; we still want the directory info. _, nogo := err.(*build.NoGoError) if err != nil { if nogo { err = nil beego.Info("doc.walker.build(): No Go Source file.") } else { return w.pdoc, errors.New("doc.walker.build(): " + err.Error()) } } // Parse the Go files files := make(map[string]*ast.File) for _, name := range append(bpkg.GoFiles, bpkg.CgoFiles...) { file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments) if err != nil { beego.Error("doc.walker.build().[parse go files]:", err) continue } w.pdoc.Files = append(w.pdoc.Files, name) //w.pdoc.SourceSize += len(w.srcs[name].data) files[name] = file } apkg, _ := ast.NewPackage(w.fset, files, simpleImporter, nil) // Find examples in the test files. // for _, name := range append(bpkg.TestGoFiles, bpkg.XTestGoFiles...) { // file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments) // if err != nil { // beego.Error("doc.walker.build().[find examples]:", err) // continue // } // //w.pdoc.TestFiles = append(w.pdoc.TestFiles, &File{Name: name, URL: w.srcs[name].browseURL}) // //w.pdoc.TestSourceSize += len(w.srcs[name].data) // w.examples = append(w.examples, doc.Examples(file)...) // } //w.vetPackage(apkg) mode := doc.Mode(0) if w.pdoc.ImportPath == "builtin" { mode |= doc.AllDecls } pdoc := doc.New(apkg, w.pdoc.ImportPath, mode) w.pdoc.Synopsis = utils.Synopsis(pdoc.Doc) pdoc.Doc = strings.TrimRight(pdoc.Doc, " \t\n\r") var buf bytes.Buffer doc.ToHTML(&buf, pdoc.Doc, nil) w.pdoc.Doc = w.pdoc.Doc + "<br />" + buf.String() w.pdoc.Doc = strings.Replace(w.pdoc.Doc, "<p>", "<p><b>", 1) w.pdoc.Doc = strings.Replace(w.pdoc.Doc, "</p>", "</b></p>", 1) w.pdoc.Doc = base32.StdEncoding.EncodeToString([]byte(w.pdoc.Doc)) //w.pdoc.Examples = w.getExamples("") //w.pdoc.IsCmd = bpkg.IsCommand() w.pdoc.GOOS = ctxt.GOOS w.pdoc.GOARCH = ctxt.GOARCH w.srcLines = make(map[string][]string) w.pdoc.Consts = w.values(pdoc.Consts) w.pdoc.Funcs = w.funcs(pdoc.Funcs) w.pdoc.Types = w.types(pdoc.Types) w.pdoc.Vars = w.values(pdoc.Vars) //w.pdoc.Notes = w.notes(pdoc.Notes) w.pdoc.Imports = bpkg.Imports w.pdoc.TestImports = bpkg.TestImports //w.pdoc.XTestImports = bpkg.XTestImports beego.Info("doc.walker.build(", pdoc.ImportPath, "), Goroutine #", runtime.NumGoroutine()) return w.pdoc, err }
// build generates data from source files. func (w *walker) build(srcs []*source) (*Package, error) { // Set created time. w.pdoc.Created = time.Now().UTC() // Add source files to walker, I skipped references here. w.srcs = make(map[string]*source) for _, src := range srcs { srcName := strings.ToLower(src.name) // For readme comparation. switch { case strings.HasSuffix(src.name, ".go"): w.srcs[src.name] = src case len(w.pdoc.Tag) > 0: continue // Only save latest readme. case strings.HasPrefix(srcName, "readme_zh") || strings.HasPrefix(srcName, "readme_cn"): models.SavePkgDoc(w.pdoc.ImportPath, "zh", src.data) case strings.HasPrefix(srcName, "readme"): models.SavePkgDoc(w.pdoc.ImportPath, "en", src.data) } } w.fset = token.NewFileSet() // Find the package and associated files. ctxt := build.Context{ GOOS: runtime.GOOS, GOARCH: runtime.GOARCH, CgoEnabled: true, JoinPath: path.Join, IsAbsPath: path.IsAbs, SplitPathList: func(list string) []string { return strings.Split(list, ":") }, IsDir: func(path string) bool { panic("unexpected") }, HasSubdir: func(root, dir string) (rel string, ok bool) { panic("unexpected") }, ReadDir: func(dir string) (fi []os.FileInfo, err error) { return w.readDir(dir) }, OpenFile: func(path string) (r io.ReadCloser, err error) { return w.openFile(path) }, Compiler: "gc", } bpkg, err := ctxt.ImportDir(w.pdoc.ImportPath, 0) // Continue if there are no Go source files; we still want the directory info. _, nogo := err.(*build.NoGoError) if err != nil { if nogo { err = nil beego.Info("doc.walker.build -> No Go Source file") } else { return w.pdoc, errors.New("doc.walker.build -> " + err.Error()) } } // Parse the Go files files := make(map[string]*ast.File) for _, name := range append(bpkg.GoFiles, bpkg.CgoFiles...) { file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments) if err != nil { beego.Error("doc.walker.build -> parse go files:", err) continue } w.pdoc.Files = append(w.pdoc.Files, name) //w.pdoc.SourceSize += len(w.srcs[name].data) files[name] = file } apkg, _ := ast.NewPackage(w.fset, files, simpleImporter, nil) // Find examples in the test files. for _, name := range append(bpkg.TestGoFiles, bpkg.XTestGoFiles...) { file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments) if err != nil { beego.Error("doc.walker.build -> find examples:", err) continue } //w.pdoc.TestFiles = append(w.pdoc.TestFiles, &File{Name: name, URL: w.srcs[name].browseURL}) //w.pdoc.TestSourceSize += len(w.srcs[name].data) w.examples = append(w.examples, doc.Examples(file)...) } //w.vetPackage(apkg) mode := doc.Mode(0) if w.pdoc.ImportPath == "builtin" { mode |= doc.AllDecls } pdoc := doc.New(apkg, w.pdoc.ImportPath, mode) w.pdoc.Synopsis = utils.Synopsis(pdoc.Doc) pdoc.Doc = strings.TrimRight(pdoc.Doc, " \t\n\r") var buf bytes.Buffer doc.ToHTML(&buf, pdoc.Doc, nil) w.pdoc.Doc = w.pdoc.Doc + "<br />" + buf.String() w.pdoc.Doc = strings.Replace(w.pdoc.Doc, "<p>", "<p><b>", 1) w.pdoc.Doc = strings.Replace(w.pdoc.Doc, "</p>", "</b></p>", 1) w.pdoc.Doc = base32.StdEncoding.EncodeToString([]byte(w.pdoc.Doc)) w.pdoc.Examples = w.getExamples("") w.pdoc.IsCmd = bpkg.IsCommand() w.srcLines = make(map[string][]string) w.pdoc.Consts = w.values(pdoc.Consts) w.pdoc.Funcs = w.funcs(pdoc.Funcs) w.pdoc.Types = w.types(pdoc.Types) w.pdoc.Vars = w.values(pdoc.Vars) //w.pdoc.Notes = w.notes(pdoc.Notes) w.pdoc.Imports = bpkg.Imports w.pdoc.TestImports = bpkg.TestImports //w.pdoc.XTestImports = bpkg.XTestImports beego.Info("doc.walker.build(", pdoc.ImportPath, "), Goroutine #", runtime.NumGoroutine()) return w.pdoc, err }