Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(632)

Side by Side Diff: src/cmd/godoc/godoc.go

Issue 6453094: code review 6453094: godoc: adjust import path for directories with multiple... (Closed)
Patch Set: diff -r 307fafbc2d6f https://code.google.com/p/go Created 12 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/godoc/package.txt ('k') | src/cmd/godoc/main.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package main 5 package main
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "encoding/json" 9 "encoding/json"
10 "flag" 10 "flag"
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 func remoteSearchURL(query string, html bool) string { 803 func remoteSearchURL(query string, html bool) string {
804 s := "/search?m=text&q=" 804 s := "/search?m=text&q="
805 if html { 805 if html {
806 s = "/search?q=" 806 s = "/search?q="
807 } 807 }
808 return s + url.QueryEscape(query) 808 return s + url.QueryEscape(query)
809 } 809 }
810 810
811 type PageInfo struct { 811 type PageInfo struct {
812 Dirname string // directory containing the package 812 Dirname string // directory containing the package
813 PList []string // list of package names found
814 FSet *token.FileSet // corresponding file set 813 FSet *token.FileSet // corresponding file set
815 PAst *ast.File // nil if no single AST with package exports 814 PAst *ast.File // nil if no single AST with package exports
816 PDoc *doc.Package // nil if no single package documentation 815 PDoc *doc.Package // nil if no single package documentation
817 Examples []*doc.Example // nil if no example code 816 Examples []*doc.Example // nil if no example code
818 Dirs *DirList // nil if no directory information 817 Dirs *DirList // nil if no directory information
819 DirTime time.Time // directory time stamp 818 DirTime time.Time // directory time stamp
820 DirFlat bool // if set, show directory in a flat (non-indente d) manner 819 DirFlat bool // if set, show directory in a flat (non-indente d) manner
821 IsPkg bool // false if this is not documenting a real packa ge 820 IsPkg bool // false if this is not documenting a real packa ge
822 Err error // I/O error or nil 821 Err error // I/O error or nil
823 } 822 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 } 868 }
870 869
871 // getPageInfo returns the PageInfo for a package directory abspath. If the 870 // getPageInfo returns the PageInfo for a package directory abspath. If the
872 // parameter genAST is set, an AST containing only the package exports is 871 // parameter genAST is set, an AST containing only the package exports is
873 // computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc) 872 // computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc)
874 // is extracted from the AST. If there is no corresponding package in the 873 // is extracted from the AST. If there is no corresponding package in the
875 // directory, PageInfo.PAst and PageInfo.PDoc are nil. If there are no sub- 874 // directory, PageInfo.PAst and PageInfo.PDoc are nil. If there are no sub-
876 // directories, PageInfo.Dirs is nil. If a directory read error occurred, 875 // directories, PageInfo.Dirs is nil. If a directory read error occurred,
877 // PageInfo.Err is set to the respective error but the error is not logged. 876 // PageInfo.Err is set to the respective error but the error is not logged.
878 // 877 //
879 func (h *docServer) getPageInfo(abspath, relpath, pkgname string, mode PageInfoM ode) PageInfo { 878 func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) Page Info {
880 var pkgFiles []string 879 var pkgFiles []string
881 880
882 » // If we're showing the default package, restrict to the ones 881 » // Restrict to the package files
883 // that would be used when building the package on this 882 // that would be used when building the package on this
884 // system. This makes sure that if there are separate 883 // system. This makes sure that if there are separate
885 // implementations for, say, Windows vs Unix, we don't 884 // implementations for, say, Windows vs Unix, we don't
886 // jumble them all together. 885 // jumble them all together.
887 » if pkgname == "" { 886 » // Note: Uses current binary's GOOS/GOARCH.
888 » » // Note: Uses current binary's GOOS/GOARCH. 887 » // To use different pair, such as if we allowed the user
889 » » // To use different pair, such as if we allowed the user 888 » // to choose, set ctxt.GOOS and ctxt.GOARCH before
890 » » // to choose, set ctxt.GOOS and ctxt.GOARCH before 889 » // calling ctxt.ScanDir.
891 » » // calling ctxt.ScanDir. 890 » ctxt := build.Default
892 » » ctxt := build.Default 891 » ctxt.IsAbsPath = pathpkg.IsAbs
893 » » ctxt.IsAbsPath = pathpkg.IsAbs 892 » ctxt.ReadDir = fsReadDir
894 » » ctxt.ReadDir = fsReadDir 893 » ctxt.OpenFile = fsOpenFile
895 » » ctxt.OpenFile = fsOpenFile 894 » if dir, err := ctxt.ImportDir(abspath, 0); err == nil {
896 » » dir, err := ctxt.ImportDir(abspath, 0) 895 » » pkgFiles = append(dir.GoFiles, dir.CgoFiles...)
897 » » if err == nil {
898 » » » pkgFiles = append(dir.GoFiles, dir.CgoFiles...)
899 » » }
900 } 896 }
901 897
902 // filter function to select the desired .go files 898 // filter function to select the desired .go files
903 filter := func(d os.FileInfo) bool { 899 filter := func(d os.FileInfo) bool {
904 // Only Go files. 900 // Only Go files.
905 if !isPkgFile(d) { 901 if !isPkgFile(d) {
906 return false 902 return false
907 } 903 }
908 // If we are looking at cmd documentation, only accept 904 // If we are looking at cmd documentation, only accept
909 // the special fakePkgFile containing the documentation. 905 // the special fakePkgFile containing the documentation.
910 if !h.isPkg { 906 if !h.isPkg {
911 return d.Name() == fakePkgFile 907 return d.Name() == fakePkgFile
912 } 908 }
913 // Also restrict file list to pkgFiles. 909 // Also restrict file list to pkgFiles.
914 return pkgFiles == nil || inList(d.Name(), pkgFiles) 910 return pkgFiles == nil || inList(d.Name(), pkgFiles)
915 } 911 }
916 912
917 // get package ASTs 913 // get package ASTs
918 fset := token.NewFileSet() 914 fset := token.NewFileSet()
919 pkgs, err := parseDir(fset, abspath, filter) 915 pkgs, err := parseDir(fset, abspath, filter)
920 » if err != nil && pkgs == nil { 916 » if err != nil {
921 » » // only report directory read errors, ignore parse errors
922 » » // (may be able to extract partial package information)
923 return PageInfo{Dirname: abspath, Err: err} 917 return PageInfo{Dirname: abspath, Err: err}
924 } 918 }
925 919
926 // select package 920 // select package
927 var pkg *ast.Package // selected package 921 var pkg *ast.Package // selected package
928 var plist []string // list of other package (names), if any
929 if len(pkgs) == 1 { 922 if len(pkgs) == 1 {
930 // Exactly one package - select it. 923 // Exactly one package - select it.
931 for _, p := range pkgs { 924 for _, p := range pkgs {
932 pkg = p 925 pkg = p
933 } 926 }
934 927
935 } else if len(pkgs) > 1 { 928 } else if len(pkgs) > 1 {
936 » » // Multiple packages - select the best matching package: The 929 » » // More than one package - report an error.
937 » » // 1st choice is the package with pkgname, the 2nd choice is 930 » » var buf bytes.Buffer
938 » » // the package with dirname, and the 3rd choice is a package 931 » » for _, p := range pkgs {
939 » » // that is not called "main" if there is exactly one such 932 » » » if buf.Len() > 0 {
940 » » // package. Otherwise, don't select a package. 933 » » » » fmt.Fprintf(&buf, ", ")
941 » » dirpath, dirname := pathpkg.Split(abspath) 934 » » » }
942 935 » » » fmt.Fprintf(&buf, p.Name)
943 » » // If the dirname is "go" we might be in a sub-directory for
944 » » // .go files - use the outer directory name instead for better
945 » » // results.
946 » » if dirname == "go" {
947 » » » _, dirname = pathpkg.Split(pathpkg.Clean(dirpath))
948 } 936 }
949 937 » » return PageInfo{
950 » » var choice3 *ast.Package 938 » » » Dirname: abspath,
951 » loop: 939 » » » Err: fmt.Errorf("%s contains more than one package: %s", abspath, buf.Bytes()),
952 » » for _, p := range pkgs {
953 » » » switch {
954 » » » case p.Name == pkgname:
955 » » » » pkg = p
956 » » » » break loop // 1st choice; we are done
957 » » » case p.Name == dirname:
958 » » » » pkg = p // 2nd choice
959 » » » case p.Name != "main":
960 » » » » choice3 = p
961 » » » }
962 } 940 }
963 if pkg == nil && len(pkgs) == 2 {
964 pkg = choice3
965 }
966
967 // Compute the list of other packages
968 // (excluding the selected package, if any).
969 plist = make([]string, len(pkgs))
970 i := 0
971 for name := range pkgs {
972 if pkg == nil || name != pkg.Name {
973 plist[i] = name
974 i++
975 }
976 }
977 plist = plist[0:i]
978 sort.Strings(plist)
979 } 941 }
980 942
981 // get examples from *_test.go files 943 // get examples from *_test.go files
982 var examples []*doc.Example 944 var examples []*doc.Example
983 filter = func(d os.FileInfo) bool { 945 filter = func(d os.FileInfo) bool {
984 return isGoFile(d) && strings.HasSuffix(d.Name(), "_test.go") 946 return isGoFile(d) && strings.HasSuffix(d.Name(), "_test.go")
985 } 947 }
986 if testpkgs, err := parseDir(fset, abspath, filter); err != nil { 948 if testpkgs, err := parseDir(fset, abspath, filter); err != nil {
987 log.Println("parsing test files:", err) 949 log.Println("parsing test files:", err)
988 } else { 950 } else {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 // no directory tree present (too early after startup or 996 // no directory tree present (too early after startup or
1035 // command-line mode); compute one level for this page 997 // command-line mode); compute one level for this page
1036 // note: cannot use path filter here because in general 998 // note: cannot use path filter here because in general
1037 // it doesn't contain the fsTree path 999 // it doesn't contain the fsTree path
1038 dir = newDirectory(abspath, 1) 1000 dir = newDirectory(abspath, 1)
1039 timestamp = time.Now() 1001 timestamp = time.Now()
1040 } 1002 }
1041 1003
1042 return PageInfo{ 1004 return PageInfo{
1043 Dirname: abspath, 1005 Dirname: abspath,
1044 PList: plist,
1045 FSet: fset, 1006 FSet: fset,
1046 PAst: past, 1007 PAst: past,
1047 PDoc: pdoc, 1008 PDoc: pdoc,
1048 Examples: examples, 1009 Examples: examples,
1049 Dirs: dir.listing(true), 1010 Dirs: dir.listing(true),
1050 DirTime: timestamp, 1011 DirTime: timestamp,
1051 DirFlat: mode&flatDir != 0, 1012 DirFlat: mode&flatDir != 0,
1052 IsPkg: h.isPkg, 1013 IsPkg: h.isPkg,
1053 Err: nil, 1014 Err: nil,
1054 } 1015 }
1055 } 1016 }
1056 1017
1057 func (h *docServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { 1018 func (h *docServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
1058 if redirect(w, r) { 1019 if redirect(w, r) {
1059 return 1020 return
1060 } 1021 }
1061 1022
1062 relpath := pathpkg.Clean(r.URL.Path[len(h.pattern):]) 1023 relpath := pathpkg.Clean(r.URL.Path[len(h.pattern):])
1063 abspath := pathpkg.Join(h.fsRoot, relpath) 1024 abspath := pathpkg.Join(h.fsRoot, relpath)
1064 mode := getPageInfoMode(r) 1025 mode := getPageInfoMode(r)
1065 if relpath == builtinPkgPath { 1026 if relpath == builtinPkgPath {
1066 mode = noFiltering 1027 mode = noFiltering
1067 } 1028 }
1068 » info := h.getPageInfo(abspath, relpath, r.FormValue("p"), mode) 1029 » info := h.getPageInfo(abspath, relpath, mode)
1069 if info.Err != nil { 1030 if info.Err != nil {
1070 log.Print(info.Err) 1031 log.Print(info.Err)
1071 serveError(w, r, relpath, info.Err) 1032 serveError(w, r, relpath, info.Err)
1072 return 1033 return
1073 } 1034 }
1074 1035
1075 if mode&noHtml != 0 { 1036 if mode&noHtml != 0 {
1076 serveText(w, applyTemplate(packageText, "packageText", info)) 1037 serveText(w, applyTemplate(packageText, "packageText", info))
1077 return 1038 return
1078 } 1039 }
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 updateIndex() 1401 updateIndex()
1441 } 1402 }
1442 delay := 60 * time.Second // by default, try every 60s 1403 delay := 60 * time.Second // by default, try every 60s
1443 if *testDir != "" { 1404 if *testDir != "" {
1444 // in test mode, try once a second for fast startup 1405 // in test mode, try once a second for fast startup
1445 delay = 1 * time.Second 1406 delay = 1 * time.Second
1446 } 1407 }
1447 time.Sleep(delay) 1408 time.Sleep(delay)
1448 } 1409 }
1449 } 1410 }
OLDNEW
« no previous file with comments | « lib/godoc/package.txt ('k') | src/cmd/godoc/main.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b