mirror of
https://github.com/fatedier/frp.git
synced 2026-03-23 16:38:23 +08:00
using glide
This commit is contained in:
203
vendor/github.com/rakyll/statik/statik.go
generated
vendored
Normal file
203
vendor/github.com/rakyll/statik/statik.go
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package contains a program that generates code to register
|
||||
// a directory and its contents as zip data for statik file system.
|
||||
package main
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
namePackage = "statik"
|
||||
nameSourceFile = "statik.go"
|
||||
)
|
||||
|
||||
var (
|
||||
flagSrc = flag.String("src", path.Join(".", "public"), "The path of the source directory.")
|
||||
flagDest = flag.String("dest", ".", "The destination path of the generated package.")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
file, err := generateSource(*flagSrc)
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
|
||||
destDir := path.Join(*flagDest, namePackage)
|
||||
err = os.MkdirAll(destDir, 0755)
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
|
||||
err = rename(file.Name(), path.Join(destDir, nameSourceFile))
|
||||
if err != nil {
|
||||
exitWithError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// rename tries to os.Rename, but fall backs to copying from src
|
||||
// to dest and unlink the source if os.Rename fails.
|
||||
func rename(src, dest string) error {
|
||||
// Try to rename generated source.
|
||||
if err := os.Rename(src, dest); err == nil {
|
||||
return nil
|
||||
}
|
||||
// If the rename failed (might do so due to temporary file residing on a
|
||||
// different device), try to copy byte by byte.
|
||||
rc, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
rc.Close()
|
||||
os.Remove(src) // ignore the error, source is in tmp.
|
||||
}()
|
||||
|
||||
if _, err = os.Stat(dest); !os.IsNotExist(err) {
|
||||
return fmt.Errorf("file %q already exists", dest)
|
||||
}
|
||||
|
||||
wc, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer wc.Close()
|
||||
|
||||
if _, err = io.Copy(wc, rc); err != nil {
|
||||
// Delete remains of failed copy attempt.
|
||||
os.Remove(dest)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Walks on the source path and generates source code
|
||||
// that contains source directory's contents as zip contents.
|
||||
// Generates source registers generated zip contents data to
|
||||
// be read by the statik/fs HTTP file system.
|
||||
func generateSource(srcPath string) (file *os.File, err error) {
|
||||
var (
|
||||
buffer bytes.Buffer
|
||||
zipWriter io.Writer
|
||||
)
|
||||
|
||||
zipWriter = &buffer
|
||||
f, err := ioutil.TempFile("", namePackage)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
zipWriter = io.MultiWriter(zipWriter, f)
|
||||
defer f.Close()
|
||||
|
||||
w := zip.NewWriter(zipWriter)
|
||||
if err = filepath.Walk(srcPath, func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Ignore directories and hidden files.
|
||||
// No entry is needed for directories in a zip file.
|
||||
// Each file is represented with a path, no directory
|
||||
// entities are required to build the hierarchy.
|
||||
if fi.IsDir() || strings.HasPrefix(fi.Name(), ".") {
|
||||
return nil
|
||||
}
|
||||
relPath, err := filepath.Rel(srcPath, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fHeader, err := zip.FileInfoHeader(fi)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fHeader.Name = filepath.ToSlash(relPath)
|
||||
f, err := w.CreateHeader(fHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.Write(b)
|
||||
return err
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
if err = w.Close(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// then embed it as a quoted string
|
||||
var qb bytes.Buffer
|
||||
fmt.Fprintf(&qb, `package %s
|
||||
|
||||
import (
|
||||
"github.com/rakyll/statik/fs"
|
||||
)
|
||||
|
||||
func init() {
|
||||
data := "`, namePackage)
|
||||
FprintZipData(&qb, buffer.Bytes())
|
||||
fmt.Fprint(&qb, `"
|
||||
fs.Register(data)
|
||||
}
|
||||
`)
|
||||
|
||||
if err = ioutil.WriteFile(f.Name(), qb.Bytes(), 0644); err != nil {
|
||||
return
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// Converts zip binary contents to a string literal.
|
||||
func FprintZipData(dest *bytes.Buffer, zipData []byte) {
|
||||
for _, b := range zipData {
|
||||
if b == '\n' {
|
||||
dest.WriteString(`\n`)
|
||||
continue
|
||||
}
|
||||
if b == '\\' {
|
||||
dest.WriteString(`\\`)
|
||||
continue
|
||||
}
|
||||
if b == '"' {
|
||||
dest.WriteString(`\"`)
|
||||
continue
|
||||
}
|
||||
if (b >= 32 && b <= 126) || b == '\t' {
|
||||
dest.WriteByte(b)
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(dest, "\\x%02x", b)
|
||||
}
|
||||
}
|
||||
|
||||
// Prints out the error message and exists with a non-success signal.
|
||||
func exitWithError(err error) {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
Reference in New Issue
Block a user