Beispiel #1
0
func TestMakeFnIncludeFile_BasicRule(t *testing.T) {
	templateRules := template.Rules{}
	templateRules.Attach(func(path []interface{}, node interface{}) (interface{}, interface{}) {
		key := interface{}(nil)
		if len(path) > 0 {
			key = path[len(path)-1]
		}

		if key == "content" {
			return key, interface{}("replaced")
		}

		return key, node
	})

	fs := mapfs.New(map[string]string{"a": "{\"content\": 1}"})
	fnIncludeFile := MakeFnIncludeFile(fs, &templateRules)
	input := interface{}(map[string]interface{}{
		"Fn::IncludeFile": "/a",
	})

	expected := interface{}(map[string]interface{}{"content": "replaced"})
	newKey, newNode := fnIncludeFile([]interface{}{"x", "y"}, input)
	if newKey != "y" {
		t.Fatalf("FnIncludeFile modified the path (%v instead of %v)", newKey, "y")
	}

	if !reflect.DeepEqual(newNode, expected) {
		t.Fatalf("FnIncludeFile did not return the expected result (%#v instead of %#v)", newNode, expected)
	}
}
Beispiel #2
0
func fsMapHandler() types.RequestHandler {
	var fileHandler = http.FileServer(httpfs.New(mapfs.New(fsmap)))
	return types.RequestHandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		fileHandler.ServeHTTP(w, r)
	})

}
Beispiel #3
0
func TestNewNameSpace(t *testing.T) {

	// We will mount this filesystem under /fs1
	mount := mapfs.New(map[string]string{"fs1file": "abcdefgh"})

	// Existing process. This should give error on Stat("/")
	t1 := vfs.NameSpace{}
	t1.Bind("/fs1", mount, "/", vfs.BindReplace)

	// using NewNameSpace. This should work fine.
	t2 := emptyvfs.NewNameSpace()
	t2.Bind("/fs1", mount, "/", vfs.BindReplace)

	testcases := map[string][]bool{
		"/":            []bool{false, true},
		"/fs1":         []bool{true, true},
		"/fs1/fs1file": []bool{true, true},
	}

	fss := []vfs.FileSystem{t1, t2}

	for j, fs := range fss {
		for k, v := range testcases {
			_, err := fs.Stat(k)
			result := err == nil
			if result != v[j] {
				t.Errorf("fs: %d, testcase: %s, want: %v, got: %v, err: %s", j, k, v[j], result, err)
			}
		}
	}
}
Beispiel #4
0
func TestReadOnly(t *testing.T) {
	m := map[string]string{"x": "y"}
	rfs := mapfs.New(m)
	wfs := ReadOnly(rfs)

	if _, err := rfs.Stat("/x"); err != nil {
		t.Error(err)
	}

	_, err := wfs.Create("/y")
	if want := (&os.PathError{"create", "/y", ErrReadOnly}); !reflect.DeepEqual(err, want) {
		t.Errorf("Create: got err %v, want %v", err, want)
	}

	err = wfs.Mkdir("/y")
	if want := (&os.PathError{"mkdir", "/y", ErrReadOnly}); !reflect.DeepEqual(err, want) {
		t.Errorf("Mkdir: got err %v, want %v", err, want)
	}

	err = wfs.Remove("/y")
	if want := (&os.PathError{"remove", "/y", ErrReadOnly}); !reflect.DeepEqual(err, want) {
		t.Errorf("Remove: got err %v, want %v", err, want)
	}

}
Beispiel #5
0
func ExampleWalk() {
	var fs http.FileSystem = httpfs.New(mapfs.New(map[string]string{
		"zzz-last-file.txt":   "It should be visited last.",
		"a-file.txt":          "It has stuff.",
		"another-file.txt":    "Also stuff.",
		"folderA/entry-A.txt": "Alpha.",
		"folderA/entry-B.txt": "Beta.",
	}))

	walkFn := func(path string, fi os.FileInfo, err error) error {
		if err != nil {
			log.Printf("can't stat file %s: %v\n", path, err)
			return nil
		}
		fmt.Println(path)
		return nil
	}

	err := vfsutil.Walk(fs, "/", walkFn)
	if err != nil {
		panic(err)
	}

	// Output:
	// /
	// /a-file.txt
	// /another-file.txt
	// /folderA
	// /folderA/entry-A.txt
	// /folderA/entry-B.txt
	// /zzz-last-file.txt
}
Beispiel #6
0
func Example() {
	fs0 := httpfs.New(mapfs.New(map[string]string{
		"zzz-last-file.txt":   "It should be visited last.",
		"a-file.txt":          "It has stuff.",
		"another-file.txt":    "Also stuff.",
		"folderA/entry-A.txt": "Alpha.",
		"folderA/entry-B.txt": "Beta.",
	}))
	fs1 := httpfs.New(mapfs.New(map[string]string{
		"sample-file.txt":                "This file compresses well. Blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah!",
		"not-worth-compressing-file.txt": "Its normal contents are here.",
		"folderA/file1.txt":              "Stuff 1.",
		"folderA/file2.txt":              "Stuff 2.",
		"folderB/folderC/file3.txt":      "Stuff C-3.",
	}))

	fs := union.New(map[string]http.FileSystem{
		"/fs0": fs0,
		"/fs1": fs1,
	})

	err := vfsutil.Walk(fs, "/", walk)
	if err != nil {
		panic(err)
	}

	// Output:
	// /
	// /fs0
	// /fs0/a-file.txt
	// /fs0/another-file.txt
	// /fs0/folderA
	// /fs0/folderA/entry-A.txt
	// /fs0/folderA/entry-B.txt
	// /fs0/zzz-last-file.txt
	// /fs1
	// /fs1/folderA
	// /fs1/folderA/file1.txt
	// /fs1/folderA/file2.txt
	// /fs1/folderB
	// /fs1/folderB/folderC
	// /fs1/folderB/folderC/file3.txt
	// /fs1/not-worth-compressing-file.txt
	// /fs1/sample-file.txt
}
Beispiel #7
0
func init() {
	enforceHosts = !appengine.IsDevAppServer()
	playEnabled = true

	log.Println("initializing godoc ...")
	log.Printf(".zip file   = %s", zipFilename)
	log.Printf(".zip GOROOT = %s", zipGoroot)
	log.Printf("index files = %s", indexFilenames)

	goroot := path.Join("/", zipGoroot) // fsHttp paths are relative to '/'

	// read .zip file and set up file systems
	const zipfile = zipFilename
	rc, err := zip.OpenReader(zipfile)
	if err != nil {
		log.Fatalf("%s: %s\n", zipfile, err)
	}
	// rc is never closed (app running forever)
	fs.Bind("/", zipfs.New(rc, zipFilename), goroot, vfs.BindReplace)
	fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)

	corpus := godoc.NewCorpus(fs)
	corpus.Verbose = false
	corpus.MaxResults = 10000 // matches flag default in main.go
	corpus.IndexEnabled = true
	corpus.IndexFiles = indexFilenames
	if err := corpus.Init(); err != nil {
		log.Fatal(err)
	}
	corpus.IndexDirectory = indexDirectoryDefault
	go corpus.RunIndexer()

	pres = godoc.NewPresentation(corpus)
	pres.TabWidth = 8
	pres.ShowPlayground = true
	pres.ShowExamples = true
	pres.DeclLinks = true
	pres.NotesRx = regexp.MustCompile("BUG")

	readTemplates(pres, true)

	mux := registerHandlers(pres)
	dl.RegisterHandlers(mux)
	short.RegisterHandlers(mux)

	// Register /compile and /share handlers against the default serve mux
	// so that other app modules can make plain HTTP requests to those
	// hosts. (For reasons, HTTPS communication between modules is broken.)
	proxy.RegisterHandlers(http.DefaultServeMux)

	log.Println("godoc initialization complete")
}
Beispiel #8
0
func main() {
	server, err := blog.NewServer(cfg)
	if err != nil {
		log.Fatal(err)
	}

	http.Handle("/", server)
	http.Handle("/lib/godoc/", http.StripPrefix("/lib/godoc/",
		http.FileServer(httpfs.New(mapfs.New(static.Files))),
	))

	log.Fatal(http.ListenAndServe(":3999", nil))
}
Beispiel #9
0
// NewTestShell builds a test shell, notionally at path, with a set of files available
// to it built from the files map. Note that relative paths in the map are
// considered wrt the path
func NewTestShell(path string, files map[string]string) (*TestShell, error) {
	ts := TestShell{
		CmdsF: blissfulSuccess,
		Sh: Sh{
			Cwd: path,
			Env: os.Environ(),
		},
	}
	fs := make(map[string]string)
	for n, c := range files {
		fs[strings.TrimPrefix(ts.Abs(n), "/")] = c
	}
	ts.FS = mapfs.New(fs)
	return &ts, nil
}
Beispiel #10
0
// Map returns a new FileSystem from the provided map. Map keys should be
// forward slash-separated pathnames and not contain a leading slash.
func Map(m map[string]string) FileSystem {
	fs := mapFS{
		m:          m,
		dirs:       map[string]struct{}{"": struct{}{}},
		FileSystem: mapfs.New(m),
	}

	// Create initial dirs.
	for path := range m {
		if err := MkdirAll(fs, filepath.Dir(path)); err != nil {
			panic(err.Error())
		}
	}

	return fs
}
Beispiel #11
0
func newCorpus(t *testing.T) *Corpus {
	c := NewCorpus(mapfs.New(map[string]string{
		"src/foo/foo.go": `// Package foo is an example.
package foo

import "bar"

const Pi = 3.1415

var Foos []Foo

// Foo is stuff.
type Foo struct{}

func New() *Foo {
   return new(Foo)
}
`,
		"src/bar/bar.go": `// Package bar is another example to test races.
package bar
`,
		"src/other/bar/bar.go": `// Package bar is another bar package.
package bar
func X() {}
`,
		"src/skip/skip.go": `// Package skip should be skipped.
package skip
func Skip() {}
`,
		"src/bar/readme.txt": `Whitelisted text file.
`,
		"src/bar/baz.zzz": `Text file not whitelisted.
`,
	}))
	c.IndexEnabled = true
	c.IndexDirectory = func(dir string) bool {
		return !strings.Contains(dir, "skip")
	}

	if err := c.Init(); err != nil {
		t.Fatal(err)
	}
	return c
}
Beispiel #12
0
func init() {
	playEnabled = true

	log.Println("initializing godoc ...")
	log.Printf(".zip file   = %s", zipFilename)
	log.Printf(".zip GOROOT = %s", zipGoroot)
	log.Printf("index files = %s", indexFilenames)

	goroot := path.Join("/", zipGoroot) // fsHttp paths are relative to '/'

	// read .zip file and set up file systems
	const zipfile = zipFilename
	rc, err := zip.OpenReader(zipfile)
	if err != nil {
		log.Fatalf("%s: %s\n", zipfile, err)
	}
	// rc is never closed (app running forever)
	fs.Bind("/", zipfs.New(rc, zipFilename), goroot, vfs.BindReplace)
	fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)

	corpus := godoc.NewCorpus(fs)
	corpus.Verbose = false
	corpus.MaxResults = 10000 // matches flag default in main.go
	corpus.IndexEnabled = true
	corpus.IndexFiles = indexFilenames
	if err := corpus.Init(); err != nil {
		log.Fatal(err)
	}
	corpus.IndexDirectory = indexDirectoryDefault
	go corpus.RunIndexer()

	pres = godoc.NewPresentation(corpus)
	pres.TabWidth = 8
	pres.ShowPlayground = true
	pres.ShowExamples = true
	pres.DeclLinks = true
	pres.NotesRx = regexp.MustCompile("BUG")

	readTemplates(pres, true)
	registerHandlers(pres)

	log.Println("godoc initialization complete")
}
Beispiel #13
0
func main() {
	var fs http.FileSystem = httpfs.New(mapfs.New(map[string]string{
		"sample-file.txt":                "This file compresses well. Blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah!",
		"not-worth-compressing-file.txt": "Its normal contents are here.",
		"folderA/file1.txt":              "Stuff in /folderA/file1.txt.",
		"folderA/file2.txt":              "Stuff in /folderA/file2.txt.",
		"folderB/folderC/file3.txt":      "Stuff in /folderB/folderC/file3.txt.",
		// TODO: Empty folder somehow?
		//"folder-empty/":                  "",
	}))

	err := vfsgen.Generate(fs, vfsgen.Options{
		Filename:    "test_vfsdata_test.go",
		PackageName: "test_test",
	})
	if err != nil {
		log.Fatalln(err)
	}
}
Beispiel #14
0
// loadFS reads the zip file of Go source code and binds.
func loadFS() {
	// Load GOROOT (in zip file)
	rsc, err := asset.Open(gorootZipFile) // asset file, never closed.
	if err != nil {
		panic(err)
	}
	offset, err := rsc.Seek(0, os.SEEK_END)
	if err != nil {
		panic(err)
	}
	if _, err = rsc.Seek(0, os.SEEK_SET); err != nil {
		panic(err)
	}
	r, err := zip.NewReader(&readerAt{wrapped: rsc}, offset)
	if err != nil {
		panic(err)
	}

	fs.Bind("/", newZipFS(r, gorootZipFile), "/go", vfs.BindReplace)

	// static files for godoc.
	fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)
}
Beispiel #15
0
// This file was automatically generated based on the contents of *.tmpl
// If you need to update this file, change the contents of those files
// (or add new ones) and run 'go generate'

package main

import "golang.org/x/tools/godoc/vfs/mapfs"

var Templates = mapfs.New(map[string]string{
	`ssl-config.tmpl`: "[ req ]\nprompt = no\ndistinguished_name=req_distinguished_name\nx509_extensions = va_c3\nencrypt_key = no\ndefault_keyfile=testing.key\ndefault_md = sha256\n\n[ va_c3 ]\nbasicConstraints=critical,CA:true,pathlen:1\n{{range . -}}\nsubjectAltName = IP:{{.}}\n{{end}}\n[ req_distinguished_name ]\nCN=registry.test\n",
})
Beispiel #16
0
func NewMapFS(m map[string]string) *MapFS {
	return &MapFS{mapfs.New(m)}
}
Beispiel #17
0
func main() {
	flag.Usage = usage
	flag.Parse()

	playEnabled = *showPlayground

	// Check usage: either server and no args, command line and args, or index creation mode
	if (*httpAddr != "" || *urlFlag != "") != (flag.NArg() == 0) && !*writeIndex {
		usage()
	}

	var fsGate chan bool
	fsGate = make(chan bool, 20)

	// Determine file system to use.
	if *zipfile == "" {
		// use file system of underlying OS
		rootfs := gatefs.New(vfs.OS(*goroot), fsGate)
		fs.Bind("/", rootfs, "/", vfs.BindReplace)
	} else {
		// use file system specified via .zip file (path separator must be '/')
		rc, err := zip.OpenReader(*zipfile)
		if err != nil {
			log.Fatalf("%s: %s\n", *zipfile, err)
		}
		defer rc.Close() // be nice (e.g., -writeIndex mode)
		fs.Bind("/", zipfs.New(rc, *zipfile), *goroot, vfs.BindReplace)
	}
	if *templateDir != "" {
		fs.Bind("/lib/godoc", vfs.OS(*templateDir), "/", vfs.BindBefore)
	} else {
		fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)
	}

	// Bind $GOPATH trees into Go root.
	for _, p := range filepath.SplitList(build.Default.GOPATH) {
		fs.Bind("/src", gatefs.New(vfs.OS(p), fsGate), "/src", vfs.BindAfter)
	}

	httpMode := *httpAddr != ""

	var typeAnalysis, pointerAnalysis bool
	if *analysisFlag != "" {
		for _, a := range strings.Split(*analysisFlag, ",") {
			switch a {
			case "type":
				typeAnalysis = true
			case "pointer":
				pointerAnalysis = true
			default:
				log.Fatalf("unknown analysis: %s", a)
			}
		}
	}

	corpus := godoc.NewCorpus(fs)
	corpus.Verbose = *verbose
	corpus.MaxResults = *maxResults
	corpus.IndexEnabled = *indexEnabled && httpMode
	if *maxResults == 0 {
		corpus.IndexFullText = false
	}
	corpus.IndexFiles = *indexFiles
	corpus.IndexDirectory = indexDirectoryDefault
	corpus.IndexThrottle = *indexThrottle
	corpus.IndexInterval = *indexInterval
	if *writeIndex {
		corpus.IndexThrottle = 1.0
		corpus.IndexEnabled = true
	}
	if *writeIndex || httpMode || *urlFlag != "" {
		if err := corpus.Init(); err != nil {
			log.Fatal(err)
		}
	}

	pres = godoc.NewPresentation(corpus)
	pres.TabWidth = *tabWidth
	pres.ShowTimestamps = *showTimestamps
	pres.ShowPlayground = *showPlayground
	pres.ShowExamples = *showExamples
	pres.DeclLinks = *declLinks
	pres.SrcMode = *srcMode
	pres.HTMLMode = *html
	if *notesRx != "" {
		pres.NotesRx = regexp.MustCompile(*notesRx)
	}

	readTemplates(pres, httpMode || *urlFlag != "")
	registerHandlers(pres)

	if *writeIndex {
		// Write search index and exit.
		if *indexFiles == "" {
			log.Fatal("no index file specified")
		}

		log.Println("initialize file systems")
		*verbose = true // want to see what happens

		corpus.UpdateIndex()

		log.Println("writing index file", *indexFiles)
		f, err := os.Create(*indexFiles)
		if err != nil {
			log.Fatal(err)
		}
		index, _ := corpus.CurrentIndex()
		_, err = index.WriteTo(f)
		if err != nil {
			log.Fatal(err)
		}

		log.Println("done")
		return
	}

	// Print content that would be served at the URL *urlFlag.
	if *urlFlag != "" {
		handleURLFlag()
		return
	}

	if httpMode {
		// HTTP server mode.
		var handler http.Handler = http.DefaultServeMux
		if *verbose {
			log.Printf("Go Documentation Server")
			log.Printf("version = %s", runtime.Version())
			log.Printf("address = %s", *httpAddr)
			log.Printf("goroot = %s", *goroot)
			log.Printf("tabwidth = %d", *tabWidth)
			switch {
			case !*indexEnabled:
				log.Print("search index disabled")
			case *maxResults > 0:
				log.Printf("full text index enabled (maxresults = %d)", *maxResults)
			default:
				log.Print("identifier search index enabled")
			}
			fs.Fprint(os.Stderr)
			handler = loggingHandler(handler)
		}

		// Initialize search index.
		if *indexEnabled {
			go corpus.RunIndexer()
		}

		// Start type/pointer analysis.
		if typeAnalysis || pointerAnalysis {
			go analysis.Run(pointerAnalysis, &corpus.Analysis)
		}

		// Start http server.
		if err := http.ListenAndServe(*httpAddr, handler); err != nil {
			log.Fatalf("ListenAndServe %s: %v", *httpAddr, err)
		}

		return
	}

	if *query {
		handleRemoteSearch()
		return
	}

	if err := godoc.CommandLine(os.Stdout, fs, pres, flag.Args()); err != nil {
		log.Print(err)
	}
}
Beispiel #18
0
// mapFS creates a compatible vfs.FileSystem from a map.
func mapFS(m map[string]string) vfs.FileSystem { return prefixVFS{mapfs.New(m)} }
Beispiel #19
0
func Example() {
	walk := func(path string, fi os.FileInfo, err error) error {
		if err != nil {
			log.Printf("can't stat file %s: %v\n", path, err)
			return nil
		}
		fmt.Println(path)
		return nil
	}

	fs := httpfs.New(mapfs.New(map[string]string{
		"zzz-last-file.txt":                "It should be visited last.",
		"a-file.txt":                       "It has stuff.",
		"another-file.txt":                 "Also stuff.",
		"some-file.html":                   "<html>and stuff</html>",
		"folderA/entry-A.txt":              "Alpha.",
		"folderA/entry-B.txt":              "Beta.",
		"folderA/main.go":                  "package main\n",
		"folderA/folder-to-skip/many.txt":  "Entire folder can be skipped.",
		"folderA/folder-to-skip/files.txt": "Entire folder can be skipped.",
		"folder-to-skip":                   "This is a file, not a folder, and shouldn't be skipped.",
	}))

	ignore := func(fi os.FileInfo, _ string) bool {
		return pathpkg.Ext(fi.Name()) == ".go" || pathpkg.Ext(fi.Name()) == ".html" ||
			(fi.IsDir() && fi.Name() == "folder-to-skip")
	}

	fs = filter.NewIgnore(fs, ignore)

	err := vfsutil.Walk(fs, "/", walk)
	if err != nil {
		panic(err)
	}

	fmt.Println()

	// This file should be filtered out, even if accessed directly.
	_, err = fs.Open("/folderA/main.go")
	fmt.Println("os.IsNotExist(err):", os.IsNotExist(err))
	fmt.Println(err)

	fmt.Println()

	// This folder should be filtered out, even if accessed directly.
	_, err = fs.Open("/folderA/folder-to-skip")
	fmt.Println("os.IsNotExist(err):", os.IsNotExist(err))
	fmt.Println(err)

	fmt.Println()

	// This file should not be filtered out.
	f, err := fs.Open("/folder-to-skip")
	if err != nil {
		panic(err)
	}
	io.Copy(os.Stdout, f)
	f.Close()

	// Output:
	// /
	// /a-file.txt
	// /another-file.txt
	// /folder-to-skip
	// /folderA
	// /folderA/entry-A.txt
	// /folderA/entry-B.txt
	// /zzz-last-file.txt
	//
	// os.IsNotExist(err): true
	// open /folderA/main.go: file does not exist
	//
	// os.IsNotExist(err): true
	// open /folderA/folder-to-skip: file does not exist
	//
	// This is a file, not a folder, and shouldn't be skipped.
}
Beispiel #20
0
//MapSS is a convenience function to return a StaticServer based on a map
//mapping forward slash separated filepaths to strings. The paths cannot have
//a leading slash. This is implemented via a godoc virtual file system.
//Use errorHandlers to provide custom http.HandlerFunc to handle http.StatusNotFound
//and http.StatusInternalServerError or provide nil to use default implementation
//If a log.Logger is provided (ie. not nil), StaticServer does verbose logging
func MapSS(fs map[string]string, errorHandlers map[int]http.HandlerFunc, logger *log.Logger) StaticServer {
	return VFSStaticServer(mapfs.New(fs), errorHandlers, logger)
}
Beispiel #21
0
	if err != nil {
		t.Errorf("FileSystem.Stat returned error: %v", err)
	}

	if !called {
		t.Fatal("!called")
	}

	if !reflect.DeepEqual(e, want) {
		t.Errorf("FileSystem.Get returned %+v, want %+v", e, want)
	}
}

var testGetFileWithOptionsFS = mapfs.New(map[string]string{
	"a/b/c/z.txt": "file z.txt in a/b/c",
	"d/e.txt":     "e in folder d",
	"f.txt":       "f",
	"g/h.txt":     "h in folder g",
})
var zeroTimestamp = pbtypes.Timestamp{Seconds: -62135596800} // Equivalent to time.Time{}.

func TestGetFileWithOptions(t *testing.T) {
	want := []*TreeEntry{
		{
			Name:    "a",
			Type:    DirEntry,
			ModTime: zeroTimestamp,
			Entries: nil,
		},
		{
			Name:    "d",
			Type:    DirEntry,
Beispiel #22
0
func TestCommandLine(t *testing.T) {
	cleanup := setupGoroot(t)
	defer cleanup()
	mfs := mapfs.New(map[string]string{
		"src/bar/bar.go": `// Package bar is an example.
package bar
`,
		"src/foo/foo.go": `// Package foo.
package foo

// First function is first.
func First() {
}

// Second function is second.
func Second() {
}
`,
		"src/gen/gen.go": `// Package gen
package gen

//line notgen.go:3
// F doc //line 1 should appear
// line 2 should appear
func F()
//line foo.go:100`, // no newline on end to check corner cases!
		"src/vet/vet.go": `// Package vet
package vet
`,
		"src/cmd/go/doc.go": `// The go command
package main
`,
		"src/cmd/gofmt/doc.go": `// The gofmt command
package main
`,
		"src/cmd/vet/vet.go": `// The vet command
package main
`,
	})
	fs := make(vfs.NameSpace)
	fs.Bind("/", mfs, "/", vfs.BindReplace)
	c := NewCorpus(fs)
	p := &Presentation{Corpus: c}
	p.cmdHandler = handlerServer{
		p:       p,
		c:       c,
		pattern: "/cmd/",
		fsRoot:  "/src/cmd",
	}
	p.pkgHandler = handlerServer{
		p:       p,
		c:       c,
		pattern: "/pkg/",
		fsRoot:  "/src",
		exclude: []string{"/src/cmd"},
	}
	p.initFuncMap()
	p.PackageText = template.Must(template.New("PackageText").Funcs(p.FuncMap()).Parse(`{{$info := .}}{{$filtered := .IsFiltered}}{{if $filtered}}{{range .PAst}}{{range .Decls}}{{node $info .}}{{end}}{{end}}{{else}}{{with .PAst}}{{range $filename, $ast := .}}{{$filename}}:
{{node $ $ast}}{{end}}{{end}}{{end}}{{with .PDoc}}{{if $.IsMain}}COMMAND {{.Doc}}{{else}}PACKAGE {{.Doc}}{{end}}{{with .Funcs}}
{{range .}}{{node $ .Decl}}
{{comment_text .Doc "    " "\t"}}{{end}}{{end}}{{end}}`))

	for _, tc := range []struct {
		desc string
		args []string
		exp  string
		err  bool
	}{
		{
			desc: "standard package",
			args: []string{"fmt"},
			exp:  "PACKAGE Package fmt implements formatted I/O.\n",
		},
		{
			desc: "package",
			args: []string{"bar"},
			exp:  "PACKAGE Package bar is an example.\n",
		},
		{
			desc: "package w. filter",
			args: []string{"foo", "First"},
			exp:  "PACKAGE \nfunc First()\n    First function is first.\n",
		},
		{
			desc: "package w. bad filter",
			args: []string{"foo", "DNE"},
			exp:  "PACKAGE ",
		},
		{
			desc: "source mode",
			args: []string{"src/bar"},
			exp:  "bar/bar.go:\n// Package bar is an example.\npackage bar\n",
		},
		{
			desc: "source mode w. filter",
			args: []string{"src/foo", "Second"},
			exp:  "// Second function is second.\nfunc Second() {\n}",
		},
		{
			desc: "package w. //line comments",
			args: []string{"gen", "F"},
			exp:  "PACKAGE \nfunc F()\n    F doc //line 1 should appear line 2 should appear\n",
		},
		{
			desc: "command",
			args: []string{"go"},
			exp:  "COMMAND The go command\n",
		},
		{
			desc: "forced command",
			args: []string{"cmd/gofmt"},
			exp:  "COMMAND The gofmt command\n",
		},
		{
			desc: "bad arg",
			args: []string{"doesnotexist"},
			err:  true,
		},
		{
			desc: "both command and package",
			args: []string{"vet"},
			exp:  "use 'godoc cmd/vet' for documentation on the vet command \n\nPACKAGE Package vet\n",
		},
		{
			desc: "root directory",
			args: []string{"/"},
			exp:  "",
		},
	} {
		w := new(bytes.Buffer)
		err := CommandLine(w, fs, p, tc.args)
		if got, want := w.String(), tc.exp; got != want || tc.err == (err == nil) {
			t.Errorf("%s: CommandLine(%v) = %q (%v); want %q (%v)",
				tc.desc, tc.args, got, err, want, tc.err)
		}
	}
}
Beispiel #23
0
// This file was automatically generated based on the contents of *.tmpl
// If you need to update this file, change the contents of those files
// (or add new ones) and run 'go generate'

package swaggering

import "golang.org/x/tools/godoc/vfs/mapfs"

var Templates = mapfs.New(map[string]string{
	`api.tmpl`: "package {{.BasePackageName}}\n\nimport \"{{.PackageImportName}}/dtos\"\n\n{{range .Operations}}\n  {{template \"operation\" .}}\n{{end}}\n",
	`model.tmpl`: "package dtos\n\nimport (\n  \"fmt\"\n  \"io\"\n\n  \"github.com/opentable/swaggering\"\n)\n\n{{range $enum := .Enums}}\ntype {{$enum.Name}} string\n\nconst (\n  {{- range $value := $enum.Values}}\n  {{$enum.Name}}{{$value}} {{$enum.Name}} = \"{{$value}}\"\n  {{- end}}\n)\n{{end}}\n\ntype {{.GoName}} struct {\n  present map[string]bool\n{{range $name, $prop := .Properties}}\n  {{if $prop.GoTypeInvalid}}// {{end -}}\n  {{.GoName}} {{.GoTypePrefix}}\n  {{- if ne $.GoPackage .GoPackage}}{{.GoPackage}}\n    {{- if ne .GoPackage \"\" }}.{{end -}}\n  {{end -}}\n  {{.GoBaseType}} `json:\"{{$prop.SwaggerName}}\n  {{- if eq $prop.GoBaseType \"string\" -}}\n  ,omitempty\n  {{- end -}}\n  \"`\n{{end}}\n}\n\nfunc (self *{{.GoName}}) Populate(jsonReader io.ReadCloser) (err error) {\n	return swaggering.ReadPopulate(jsonReader, self)\n}\n\nfunc (self *{{.GoName}}) Absorb(other swaggering.DTO) error {\n  if like, ok := other.(*{{.GoName}}); ok {\n    *self = *like\n    return nil\n  }\n  return fmt.Errorf(\"A {{.GoName}} cannot copy the values from %#v\", other)\n}\n\nfunc (self *{{.GoName}}) MarshalJSON() ([]byte, error) {\n  return swaggering.MarshalJSON(self)\n}\n\nfunc (self *{{.GoName}}) FormatText() string {\n	return swaggering.FormatText(self)\n}\n\nfunc (self *{{.GoName}}) FormatJSON() string {\n	return swaggering.FormatJSON(self)\n}\n\nfunc (self *{{.GoName}}) FieldsPresent() []string {\n  return swaggering.PresenceFromMap(self.present)\n}\n\nfunc (self *{{.GoName}}) SetField(name string, value interface{}) error {\n  if self.present == nil {\n    self.present = make(map[string]bool)\n  }\n  switch name {\n  default:\n    return fmt.Errorf(\"No such field %s on {{.GoName}}\", name)\n  {{range $name, $prop := .Properties}}\n    {{ if not $prop.GoTypeInvalid }}\n    case \"{{$prop.SwaggerName}}\", \"{{$prop.GoName}}\":\n    v, ok := value.(\n      {{- .GoTypePrefix}}\n      {{- if ne $.GoPackage .GoPackage}}{{.GoPackage}}\n        {{- if ne .GoPackage \"\" }}.{{end -}}\n      {{end }} {{.GoBaseType -}}\n      )\n      if ok {\n        self.{{$prop.GoName}} = v\n        self.present[\"{{$prop.SwaggerName}}\"] = true\n        return nil\n      } else {\n        return fmt.Errorf(\"Field {{$prop.SwaggerName}}/{{$prop.GoName}}: value %v(%T) couldn't be cast to type {{$prop.GoTypePrefix}}{{$prop.GoBaseType}}\", value, value)\n      }\n    {{end}}\n  {{end}}\n  }\n}\n\nfunc (self *{{.GoName}}) GetField(name string) (interface{}, error) {\n  switch name {\n  default:\n    return nil, fmt.Errorf(\"No such field %s on {{.GoName}}\", name)\n  {{range $name, $prop := .Properties}}\n    {{ if not $prop.GoTypeInvalid }}\n    case \"{{$prop.SwaggerName}}\", \"{{$prop.GoName}}\":\n    if self.present != nil {\n      if _, ok := self.present[\"{{$prop.SwaggerName}}\"]; ok {\n        return self.{{$prop.GoName}}, nil\n      }\n    }\n    return nil, fmt.Errorf(\"Field {{$prop.GoName}} no set on {{.GoName}} %+v\", self)\n    {{end}}\n  {{end}}\n  }\n}\n\nfunc (self *{{.GoName}}) ClearField(name string) error {\n  if self.present == nil {\n    self.present = make(map[string]bool)\n  }\n  switch name {\n  default:\n    return fmt.Errorf(\"No such field %s on {{.GoName}}\", name)\n  {{range $name, $prop := .Properties}}\n    {{ if not $prop.GoTypeInvalid }}\n  case \"{{$prop.SwaggerName}}\", \"{{$prop.GoName}}\":\n    self.present[\"{{$prop.SwaggerName}}\"] = false\n    {{end}}\n  {{end}}\n  }\n\n  return nil\n}\n\nfunc (self *{{.GoName}}) LoadMap(from map[string]interface{}) error {\n  return swaggering.LoadMapIntoDTO(from, self)\n}\n\ntype {{.GoName}}List []*{{.GoName}}\n\nfunc (self *{{.GoName}}List) Absorb(other swaggering.DTO) error {\n  if like, ok := other.(*{{.GoName}}List); ok {\n    *self = *like\n    return nil\n  }\n  return fmt.Errorf(\"A {{.GoName}}List cannot copy the values from %#v\", other)\n}\n\n\nfunc (list *{{.GoName}}List) Populate(jsonReader io.ReadCloser) (err error) {\n	return swaggering.ReadPopulate(jsonReader, list)\n}\n\nfunc (list *{{.GoName}}List) FormatText() string {\n	text := []byte{}\n	for _, dto := range *list {\n		text = append(text, (*dto).FormatText()...)\n		text = append(text, \"\\n\"...)\n	}\n	return string(text)\n}\n\nfunc (list *{{.GoName}}List) FormatJSON() string {\n	return swaggering.FormatJSON(list)\n}\n",
	`operation.tmpl`: "{{- if not .GoTypeInvalid -}}\nfunc (client *Client) {{.GoMethodName}}(\n{{- range .Parameters -}}\n{{.Name}} {{template \"type\" . -}}\n, {{end -}}\n) ({{ if not (eq .GoBaseType \"\") -}}\nresponse {{template \"type\" . -}}\n, {{end}} err error) {\n	pathParamMap := map[string]interface{}{\n		{{range .Parameters -}}\n		{{if eq \"path\" .ParamType -}}\n		  \"{{.Name}}\": {{.Name}},\n	  {{- end }}\n		{{- end }}\n	}\n\n  queryParamMap := map[string]interface{}{\n		{{range .Parameters -}}\n		{{if eq \"query\" .ParamType -}}\n		  \"{{.Name}}\": {{.Name}},\n	  {{- end }}\n		{{- end }}\n	}\n\n	{{if .DTORequest -}}\n	{{if .MakesResult}}\n    response = make({{- template \"type\" . -}}, 0)\n		err = client.DTORequest(&response, \"{{.Method}}\", \"{{.Path}}\", pathParamMap, queryParamMap\n		{{- if .HasBody -}}\n		, body\n		{{- end -}})\n	{{else}}\n    response = new({{.GoPackage}}\n    {{- if ne .GoPackage \"\"}}.{{end -}}\n    {{.GoBaseType}})\n		err = client.DTORequest(response, \"{{.Method}}\", \"{{.Path}}\", pathParamMap, queryParamMap\n		{{- if .HasBody -}}\n		, body\n		{{- end -}})\n	{{end}}\n	{{else if (eq .GoBaseType \"\")}}\n	_, err = client.Request(\"{{.Method}}\", \"{{.Path}}\", pathParamMap, queryParamMap\n	{{- if .HasBody -}}\n	, body\n  {{- end -}})\n	{{else if eq .GoBaseType \"string\"}}\n	resBody, err := client.Request(\"{{.Method}}\", \"{{.Path}}\", pathParamMap, queryParamMap\n	{{- if .HasBody -}}\n	, body\n  {{- end -}})\n	readBuf := bytes.Buffer{}\n	readBuf.ReadFrom(resBody)\n	response = string(readBuf.Bytes())\n	{{- end}}\n	return\n}\n{{end}}\n",
	`type.tmpl`: "{{.GoTypePrefix -}}\n{{if ne .GoPackage \"\"}}{{.GoPackage}}.{{end -}}\n{{.GoBaseType -}}\n",
})
	"golang.org/x/tools/godoc/static"
	"golang.org/x/tools/godoc/vfs"
	"golang.org/x/tools/godoc/vfs/mapfs"
	"golang.org/x/tools/godoc/vfs/zipfs"
)

// Default is the translations dir.
const (
	Default = "translations" // $(RootFS)/translations
)

var (
	defaultGodocGoos                 = getGodocGoos()
	defaultGodocGoarch               = getGodocGoarch()
	defaultRootFS      vfs.NameSpace = getNameSpace(vfs.OS(runtime.GOROOT()), "/")
	defaultStaticFS    vfs.NameSpace = getNameSpace(mapfs.New(static.Files), "/")
	defaultDocFS       vfs.NameSpace = getNameSpace(defaultRootFS, "/doc")
	defaultBlogFS      vfs.NameSpace = getNameSpace(defaultRootFS, "/blog")
	defaultLocalFS     vfs.NameSpace = getNameSpace(defaultRootFS, "/"+Default)
	defaultTranslater  Translater    = new(localTranslater)
)

func getGodocGoos() string {
	if v := strings.TrimSpace(os.Getenv("GOOS")); v != "" {
		return v
	}
	return runtime.GOOS
}

func getGodocGoarch() string {
	if v := strings.TrimSpace(os.Getenv("GOARCH")); v != "" {
func testMakeFnIncludeFileRaw(files map[string]string) template.Rule {
	fs := mapfs.New(files)
	return MakeFnIncludeFileRaw(fs)
}
Beispiel #26
0
func testMakeFnFindFile(files map[string]string) template.Rule {
	fs := mapfs.New(files)
	return MakeFnFindFile(fs)
}
Beispiel #27
0
func fsMapHandler(fsmap map[string]string) http.HandlerFunc {
	return func(wr http.ResponseWriter, req *http.Request) {
		wr.Header().Add("Expires", time.Now().Add(time.Hour).Format(time.RFC1123))
		http.FileServer(httpfs.New(mapfs.New(fsmap))).ServeHTTP(wr, req)
	}
}