Ejemplo n.º 1
0
func main() {
	flag.Usage = usage
	flag.Parse()

	// Check usage
	if flag.NArg() == 0 {
		usage()
	}

	// use file system of underlying OS
	fs.Bind("/", vfs.OS(*goroot), "/", vfs.BindReplace)

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

	corpus := godoc.NewCorpus(fs)
	corpus.Verbose = *verbose

	pres = godoc.NewPresentation(corpus)
	pres.TabWidth = *tabWidth
	pres.ShowTimestamps = *showTimestamps
	pres.ShowPlayground = *showPlayground
	pres.ShowExamples = *showExamples
	pres.DeclLinks = *declLinks
	pres.SrcMode = false
	pres.HTMLMode = false

	readTemplates(pres, false)

	if err := godoc.CommandLine(os.Stdout, fs, pres, flag.Args()); err != nil {
		log.Print(err)
	}
}
Ejemplo n.º 2
0
// Init initialize the translations environment.
func Init(goRoot, goTranslations, goZipFile, goTemplateDir, goPath string) {
	if goZipFile != "" {
		rc, err := zip.OpenReader(goZipFile)
		if err != nil {
			log.Fatalf("local: %s: %s\n", goZipFile, err)
		}

		defaultRootFS = getNameSpace(zipfs.New(rc, goZipFile), goRoot)
		defaultDocFS = getNameSpace(defaultRootFS, "/doc")
		defaultBlogFS = getNameSpace(defaultRootFS, "/blog")
		if goTranslations != "" && goTranslations != Default {
			defaultLocalFS = getNameSpace(defaultRootFS, "/"+goTranslations)
		} else {
			defaultLocalFS = getNameSpace(defaultRootFS, "/"+Default)
		}
	} else {
		if goRoot != "" && goRoot != runtime.GOROOT() {
			defaultRootFS = getNameSpace(vfs.OS(goRoot), "/")
			defaultDocFS = getNameSpace(defaultRootFS, "/doc")
			defaultBlogFS = getNameSpace(defaultRootFS, "/blog")
			if goTranslations == "" || goTranslations == Default {
				defaultLocalFS = getNameSpace(defaultRootFS, "/"+Default)
			}
		}
		if goTranslations != "" && goTranslations != Default {
			defaultLocalFS = getNameSpace(vfs.OS(goTranslations), "/")
		}

		if goTemplateDir != "" {
			defaultStaticFS = getNameSpace(vfs.OS(goTemplateDir), "/")
		}

		// Bind $GOPATH trees into Go root.
		for _, p := range filepath.SplitList(goPath) {
			defaultRootFS.Bind("/src", vfs.OS(p), "/src", vfs.BindAfter)
		}

		// Prefer content from go.blog repository if present.
		if _, err := defaultBlogFS.Lstat("/"); err != nil {
			const blogRepo = "golang.org/x/blog"
			if pkg, err := build.Import(blogRepo, "", build.FindOnly); err == nil {
				defaultBlogFS = getNameSpace(defaultRootFS, pkg.Dir)
			}
		}
	}

}
Ejemplo n.º 3
0
// paths determines the paths to use.
//
// If we are passed an operating system path like . or ./foo or /foo/bar or c:\mysrc,
// we need to map that path somewhere in the fs name space so that routines
// like getPageInfo will see it.  We use the arbitrarily-chosen virtual path "/target"
// for this.  That is, if we get passed a directory like the above, we map that
// directory so that getPageInfo sees it as /target.
// Returns the absolute and relative paths.
func paths(fs vfs.NameSpace, pres *Presentation, path string) (string, string) {
	if filepath.IsAbs(path) {
		fs.Bind(target, vfs.OS(path), "/", vfs.BindReplace)
		return target, target
	}
	if build.IsLocalImport(path) {
		cwd, _ := os.Getwd() // ignore errors
		path = filepath.Join(cwd, path)
		fs.Bind(target, vfs.OS(path), "/", vfs.BindReplace)
		return target, target
	}
	if bp, _ := build.Import(path, "", build.FindOnly); bp.Dir != "" && bp.ImportPath != "" {
		fs.Bind(target, vfs.OS(bp.Dir), "/", vfs.BindReplace)
		return target, bp.ImportPath
	}
	return pathpkg.Join(pres.PkgFSRoot(), path), path
}
Ejemplo n.º 4
0
func OSPerm(root string, filePerm, dirPerm os.FileMode) FileSystem {
	return &osFS{
		root:       root,
		filePerm:   filePerm,
		dirPerm:    dirPerm,
		FileSystem: vfs.OS(root),
	}
}
Ejemplo n.º 5
0
func TestReadJSONFileNotFound(t *testing.T) {
	err := readJSONFile("doesnotexist", struct{}{})
	if !os.IsNotExist(err) {
		t.Errorf("Expected does not exist error, got %v", err)
	}
	wd, err := os.Getwd()
	if err != nil {
		t.Fatal(err)
	}
	err = readJSONFileFS(vfs.OS(wd), "doesnotexist", struct{}{})
	if !os.IsNotExist(err) {
		t.Errorf("Expected does not exist error (VFS), got %v", err)
	}
}
Ejemplo n.º 6
0
func TestReadJSONFileEmpty(t *testing.T) {
	f, err := ioutil.TempFile("", "read-json")
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()
	defer os.Remove(f.Name())
	err = readJSONFile(f.Name(), struct{}{})
	if err != errEmptyJSONFile {
		t.Errorf("Expected empty JSON file error, got %v", err)
	}
	fs := vfs.OS(filepath.Dir(f.Name()))
	err = readJSONFileFS(fs, filepath.Base(f.Name()), struct{}{})
	if err != errEmptyJSONFile {
		t.Errorf("Expected empty JSON file error (VFS), got %v", err)
	}
}
Ejemplo n.º 7
0
func TestReadJSONFile(t *testing.T) {
	f, err := ioutil.TempFile("", "read-json")
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()
	defer os.Remove(f.Name())

	// Test valid decode.
	type msg struct{ A, B int }
	in := msg{5, 3}
	err = json.NewEncoder(f).Encode(in)
	if err != nil {
		t.Fatal(err)
	}
	out := new(msg)
	err = readJSONFile(f.Name(), out)
	if err != nil {
		t.Fatal(err)
	}
	if in != *out {
		t.Errorf("Read JSON file %+v, expected %+v", out, in)
	}
	fs := vfs.OS(filepath.Dir(f.Name()))
	outFS := new(msg)
	err = readJSONFileFS(fs, filepath.Base(f.Name()), outFS)
	if err != nil {
		t.Fatal(err)
	}
	if in != *outFS {
		t.Errorf("Read JSON file %+v (VFS), expected %+v", outFS, in)
	}

	// Test invalid decode.
	err = readJSONFile(f.Name(), &struct{ A, B bool }{})
	if err == nil {
		t.Error("Expected error because of invalid decode")
	}
	err = readJSONFileFS(fs, filepath.Base(f.Name()), &struct{ A, B bool }{})
	if err == nil {
		t.Error("Expected erorr because of invalid decode (VFS)")
	}
}
Ejemplo n.º 8
0
Archivo: main.go Proyecto: 2722/lantern
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)
	}
}
Ejemplo n.º 9
0
	"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 {
Ejemplo n.º 10
0
	"golang.org/x/tools/godoc/static"
	"golang.org/x/tools/godoc/vfs"
	"golang.org/x/tools/godoc/vfs/httpfs"
	"golang.org/x/tools/godoc/vfs/mapfs"

	"github.com/chai2010/golangdoc/blog"
)

const (
	hostname = "blog.golang.org"
)

var cfg = blog.Config{
	Hostname:     hostname,
	RootFS:       vfs.OS(path.Join(runtime.GOROOT(), `/translations/blog/zh_CN`)),
	ContentPath:  "content",
	TemplatePath: "template",
	BaseURL:      "//" + hostname,
	GodocURL:     "//golang.org",
	HomeArticles: 5,  // articles to display on the home page
	FeedArticles: 10, // articles to include in Atom and JSON feeds
	PlayEnabled:  true,
	FeedTitle:    "The Go Programming Language Blog",
}

func main() {
	server, err := blog.NewServer(cfg)
	if err != nil {
		log.Fatal(err)
	}
Ejemplo n.º 11
0
func main() {
	templateRules := template.Rules{}
	inputParameters := NewInputsFlag(&templateRules)
	var templateFilename string
	var outputWhat OutputWhatFlag

	flag.StringVar(&templateFilename,
		"template", "-",
		"CloudFormation Template to process")

	flag.Var(&inputParameters,
		"parameters",
		"File to use of input parameters (can be specified multiple times)")

	flag.Var(&outputWhat,
		"output",
		"What to output after processing the Template")

	flag.Parse()

	var jsonStream io.Reader
	var err error

	if templateFilename == "-" {
		jsonStream = os.Stdin
	} else if jsonStream, err = os.Open(templateFilename); err != nil {
		panic(err)
	}

	dec := json.NewDecoder(jsonStream)
	t := make(map[string]interface{})
	if err := dec.Decode(&t); err != nil {
		panic(err)
	}

	sources := fallbackmap.FallbackMap{}
	stack := deepstack.DeepStack{}

	sources.Attach(inputParameters.Get())
	sources.Attach(deepalias.DeepAlias{&stack})
	sources.Attach(deepcloudformationoutputs.NewDeepCloudFormationOutputs("eu-west-1"))
	sources.Attach(deepcloudformationresources.NewDeepCloudFormationResources("eu-west-1"))

	stack.Push(&sources)

	templateRules.AttachEarly(rules.ExcludeComments)
	templateRules.AttachEarly(rules.MakeFnFor(&stack, &templateRules))
	templateRules.AttachEarly(rules.MakeFnWith(&stack, &templateRules))
	templateRules.Attach(rules.FnAdd)
	templateRules.Attach(rules.FnIf)
	templateRules.Attach(rules.FnAnd)
	templateRules.Attach(rules.FnOr)
	templateRules.Attach(rules.FnNot)
	templateRules.Attach(rules.FnEquals)
	templateRules.Attach(rules.FnConcat)
	templateRules.Attach(rules.FnFromEntries)
	templateRules.Attach(rules.FnHasKey)
	templateRules.Attach(rules.FnJoin)
	templateRules.Attach(rules.FnKeys)
	templateRules.Attach(rules.FnLength)
	templateRules.Attach(rules.FnMerge)
	templateRules.Attach(rules.FnMergeDeep)
	templateRules.Attach(rules.FnMod)
	templateRules.Attach(rules.FnSplit)
	templateRules.Attach(rules.FnToEntries)
	templateRules.Attach(rules.FnUnique)
	templateRules.Attach(rules.MakeFnGetAtt(&stack, &templateRules))
	templateRules.Attach(rules.MakeRef(&stack, &templateRules))
	templateRules.Attach(rules.MakeFnHasRef(&stack))
	templateRules.Attach(rules.MakeFnIncludeFile(vfs.OS("/"), &templateRules))
	templateRules.Attach(rules.MakeFnIncludeFileRaw(vfs.OS("/")))
	templateRules.Attach(rules.ReduceConditions)

	// First Pass (to collect Parameter names)
	processed := template.Process(t, &templateRules)

	parameterRefs := map[string]interface{}{}
	if processedMap, ok := processed.(map[string]interface{}); ok {
		if processedParameters, ok := processedMap["Parameters"]; ok {
			if processedParametersMap, ok := processedParameters.(map[string]interface{}); ok {
				for parameterName, _ := range processedParametersMap {
					parameterRefs[parameterName] = map[string]interface{}{
						"ParamRef": parameterName,
					}
				}
			}
		}
	}

	stack.Push(fallbackmap.DeepMap(parameterRefs))
	templateRules.Attach(func(path []interface{}, node interface{}) (interface{}, interface{}) {
		key := interface{}(nil)
		if len(path) > 0 {
			key = path[len(path)-1]
		}

		if nodeMap, ok := node.(map[string]interface{}); !ok || len(nodeMap) != 1 {
			return key, node //passthru
		}

		if refName, ok := node.(map[string]interface{})["ParamRef"]; ok {
			return key, interface{}(map[string]interface{}{"Ref": interface{}(refName)})
		}

		return key, node
	})
	processed = template.Process(t, &templateRules)
	stack.PopDiscard()

	switch outputWhat.Get().what {
	case OutputTemplate:
		enc := json.NewEncoder(os.Stdout)
		enc.Encode(processed)
	case OutputCredentials:
		credentials := []interface{}{}
		credentialMap := make(map[string]interface{})
		for _, input := range inputParameters.Sources() {
			if !outputWhat.Get().hasKey || outputWhat.Get().key == input.filename {
				credentialMap = template.Process(input.data, &templateRules).(map[string]interface{})
				credentialMap["$comment"] = map[string]interface{}{"filename": input.filename}
				credentials = append(credentials, credentialMap)
			}
		}

		if len(credentials) == 0 && outputWhat.Get().hasKey {
			panic(fmt.Errorf("No parameters file '%s' was input", outputWhat.Get().key))
		}

		enc := json.NewEncoder(os.Stdout)
		if len(credentials) == 1 {
			enc.Encode(credentials[0])
		} else {
			enc.Encode(credentials)
		}
	case OutputParameters:
		parameters := []cloudformation.Parameter{}

		for name, _ := range parameterRefs {
			value, ok := sources.Get([]string{name})
			if !ok {
				continue
			}

			value = template.Process(value, &templateRules)

			parameters = append(parameters, func(name string, value interface{}) cloudformation.Parameter {
				stringval := fmt.Sprintf("%s", value)
				boolval := false
				return cloudformation.Parameter{
					ParameterKey:     &name,
					ParameterValue:   &stringval,
					UsePreviousValue: &boolval,
				}
			}(name, value))
		}

		enc := json.NewEncoder(os.Stdout)
		enc.Encode(parameters)
	}
}
Ejemplo n.º 12
0
//OSSS is a convenience function to return a StaticServer based on the
//OS file system by creating a Godoc virtual file system on the Root Folder
//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 OSSS(root string, errorHandlers map[int]http.HandlerFunc, logger *log.Logger) StaticServer {
	return VFSStaticServer(vfs.OS(root), errorHandlers, logger)
}
Ejemplo n.º 13
0
func getLocalRootNS(rootfs vfs.NameSpace) vfs.NameSpace {
	if s := os.Getenv("GODOC_LOCAL_ROOT"); s != "" {
		return getNameSpace(vfs.OS(s), "/")
	}
	return getNameSpace(defaultRootFS, "/"+Default)
}