зеркало из https://github.com/golang/tools.git
cmd/godoc: bake templates and scripts into godoc binary
Add godoc/vfs/mapfs package for serving baked files. Fixes golang/go#6010. R=golang-dev, bradfitz, r, arnehormann, rsc CC=golang-dev https://golang.org/cl/12978043
This commit is contained in:
Родитель
dfa65ded17
Коммит
562e4faeca
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
// Command bake takes a list of file names and writes a Go source file to
|
||||
// standard output that declares a map of string constants containing the input files.
|
||||
//
|
||||
// For example, the command
|
||||
// bake foo.html bar.txt
|
||||
// produces a source file in package main that declares the variable bakedFiles
|
||||
// that is a map with keys "foo.html" and "bar.txt" that contain the contents
|
||||
// of foo.html and bar.txt.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := bake(os.Args[1:]); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func bake(files []string) error {
|
||||
w := bufio.NewWriter(os.Stdout)
|
||||
fmt.Fprintf(w, "%v\n\npackage main\n\n", warning)
|
||||
fmt.Fprintf(w, "var bakedFiles = map[string]string{\n")
|
||||
for _, fn := range files {
|
||||
b, err := ioutil.ReadFile(fn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !utf8.Valid(b) {
|
||||
return fmt.Errorf("file %s is not valid UTF-8", fn)
|
||||
}
|
||||
fmt.Fprintf(w, "\t%q: `%s`,\n", filepath.Base(fn), sanitize(b))
|
||||
}
|
||||
fmt.Fprintln(w, "}")
|
||||
return w.Flush()
|
||||
}
|
||||
|
||||
// sanitize prepares a string as a raw string constant.
|
||||
func sanitize(b []byte) []byte {
|
||||
// Replace ` with `+"`"+`
|
||||
b = bytes.Replace(b, []byte("`"), []byte("`+\"`\"+`"), -1)
|
||||
|
||||
// Replace BOM with `+"\xEF\xBB\xBF"+`
|
||||
// (A BOM is valid UTF-8 but not permitted in Go source files.
|
||||
// I wouldn't bother handling this, but for some insane reason
|
||||
// jquery.js has a BOM somewhere in the middle.)
|
||||
return bytes.Replace(b, []byte("\xEF\xBB\xBF"), []byte("`+\"\\xEF\\xBB\\xBF\"+`"), -1)
|
||||
}
|
||||
|
||||
const warning = "// DO NOT EDIT ** This file was generated with the bake tool ** DO NOT EDIT //"
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright 2013 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
set -e
|
||||
|
||||
go run bake.go template/* | gofmt > template.go
|
||||
|
|
@ -50,6 +50,7 @@ import (
|
|||
|
||||
"code.google.com/p/go.tools/godoc"
|
||||
"code.google.com/p/go.tools/godoc/vfs"
|
||||
"code.google.com/p/go.tools/godoc/vfs/mapfs"
|
||||
"code.google.com/p/go.tools/godoc/vfs/zipfs"
|
||||
)
|
||||
|
||||
|
@ -196,13 +197,7 @@ func main() {
|
|||
if *templateDir != "" {
|
||||
fs.Bind("/lib/godoc", vfs.OS(*templateDir), "/", vfs.BindBefore)
|
||||
} else {
|
||||
// Read templates from go.tools repository; if not
|
||||
// found there, fall back on $GOROOT/lib/godoc
|
||||
// which will be present in binary distributions.
|
||||
pkg, err := build.Import(templatePath, "", build.FindOnly)
|
||||
if err == nil {
|
||||
fs.Bind("/lib/godoc", vfs.OS(pkg.Dir), "/", vfs.BindReplace)
|
||||
}
|
||||
fs.Bind("/lib/godoc", mapfs.New(bakedFiles), "/", vfs.BindReplace)
|
||||
}
|
||||
} else {
|
||||
// use file system specified via .zip file (path separator must be '/')
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,81 @@
|
|||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package mapfs file provides an implementation of the FileSystem
|
||||
// interface based on the contents of a map[string]string.
|
||||
package mapfs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.google.com/p/go.tools/godoc/vfs"
|
||||
)
|
||||
|
||||
func New(m map[string]string) vfs.FileSystem {
|
||||
return mapFS(m)
|
||||
}
|
||||
|
||||
// mapFS is the map based implementation of FileSystem
|
||||
type mapFS map[string]string
|
||||
|
||||
func (fs mapFS) String() string { return "mapfs" }
|
||||
|
||||
func (fs mapFS) Close() error { return nil }
|
||||
|
||||
func filename(p string) string {
|
||||
if len(p) > 0 && p[0] == '/' {
|
||||
p = p[1:]
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (fs mapFS) Open(p string) (vfs.ReadSeekCloser, error) {
|
||||
b, ok := fs[filename(p)]
|
||||
if !ok {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return nopCloser{strings.NewReader(b)}, nil
|
||||
}
|
||||
|
||||
func (fs mapFS) Lstat(p string) (os.FileInfo, error) {
|
||||
b, ok := fs[filename(p)]
|
||||
if !ok {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return mapFI{name: p, size: int64(len(b))}, nil
|
||||
}
|
||||
|
||||
func (fs mapFS) Stat(p string) (os.FileInfo, error) {
|
||||
return fs.Lstat(p)
|
||||
}
|
||||
|
||||
func (fs mapFS) ReadDir(p string) ([]os.FileInfo, error) {
|
||||
var list []os.FileInfo
|
||||
for fn, b := range fs {
|
||||
list = append(list, mapFI{name: fn, size: int64(len(b))})
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// mapFI is the map-based implementation of FileInfo.
|
||||
type mapFI struct {
|
||||
name string
|
||||
size int64
|
||||
}
|
||||
|
||||
func (fi mapFI) IsDir() bool { return false }
|
||||
func (fi mapFI) ModTime() time.Time { return time.Time{} }
|
||||
func (fi mapFI) Mode() os.FileMode { return 0444 }
|
||||
func (fi mapFI) Name() string { return fi.name }
|
||||
func (fi mapFI) Size() int64 { return fi.size }
|
||||
func (fi mapFI) Sys() interface{} { return nil }
|
||||
|
||||
type nopCloser struct {
|
||||
io.ReadSeeker
|
||||
}
|
||||
|
||||
func (nc nopCloser) Close() error { return nil }
|
Загрузка…
Ссылка в новой задаче