Files
leanote/cmd/leanote_revel/util.go

177 lines
4.7 KiB
Go
Raw Normal View History

2017-11-30 20:11:10 +08:00
// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
// Revel Framework source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.
package main
import (
"archive/tar"
"compress/gzip"
"fmt"
"go/build"
"io"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/revel/revel"
)
// LoggedError is wrapper to differentiate logged panics from unexpected ones.
type LoggedError struct{ error }
func panicOnError(err error, msg string) {
if revErr, ok := err.(*revel.Error); (ok && revErr != nil) || (!ok && err != nil) {
fmt.Fprintf(os.Stderr, "Abort: %s: %s\n", msg, err)
panic(LoggedError{err})
}
}
func mustCopyFile(destFilename, srcFilename string) {
destFile, err := os.Create(destFilename)
panicOnError(err, "Failed to create file "+destFilename)
srcFile, err := os.Open(srcFilename)
panicOnError(err, "Failed to open file "+srcFilename)
_, err = io.Copy(destFile, srcFile)
panicOnError(err,
fmt.Sprintf("Failed to copy data from %s to %s", srcFile.Name(), destFile.Name()))
err = destFile.Close()
panicOnError(err, "Failed to close file "+destFile.Name())
err = srcFile.Close()
panicOnError(err, "Failed to close file "+srcFile.Name())
}
func mustRenderTemplate(destPath, srcPath string, data map[string]interface{}) {
tmpl, err := template.ParseFiles(srcPath)
panicOnError(err, "Failed to parse template "+srcPath)
f, err := os.Create(destPath)
panicOnError(err, "Failed to create "+destPath)
err = tmpl.Execute(f, data)
panicOnError(err, "Failed to render template "+srcPath)
err = f.Close()
panicOnError(err, "Failed to close "+f.Name())
}
func mustChmod(filename string, mode os.FileMode) {
err := os.Chmod(filename, mode)
panicOnError(err, fmt.Sprintf("Failed to chmod %d %q", mode, filename))
}
// copyDir copies a directory tree over to a new directory. Any files ending in
// ".template" are treated as a Go template and rendered using the given data.
// Additionally, the trailing ".template" is stripped from the file name.
// Also, dot files and dot directories are skipped.
func mustCopyDir(destDir, srcDir string, data map[string]interface{}) error {
return revel.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
// Get the relative path from the source base, and the corresponding path in
// the dest directory.
relSrcPath := strings.TrimLeft(srcPath[len(srcDir):], string(os.PathSeparator))
destPath := filepath.Join(destDir, relSrcPath)
// Skip dot files and dot directories.
if strings.HasPrefix(relSrcPath, ".") {
if info.IsDir() {
return filepath.SkipDir
}
return nil
}
// Create a subdirectory if necessary.
if info.IsDir() {
err := os.MkdirAll(filepath.Join(destDir, relSrcPath), 0777)
if !os.IsExist(err) {
panicOnError(err, "Failed to create directory")
}
return nil
}
// If this file ends in ".template", render it as a template.
if strings.HasSuffix(relSrcPath, ".template") {
mustRenderTemplate(destPath[:len(destPath)-len(".template")], srcPath, data)
return nil
}
// Else, just copy it over.
mustCopyFile(destPath, srcPath)
return nil
})
}
func mustTarGzDir(destFilename, srcDir string) string {
zipFile, err := os.Create(destFilename)
panicOnError(err, "Failed to create archive")
defer func() {
_ = zipFile.Close()
}()
gzipWriter := gzip.NewWriter(zipFile)
defer func() {
_ = gzipWriter.Close()
}()
tarWriter := tar.NewWriter(gzipWriter)
defer func() {
_ = tarWriter.Close()
}()
_ = revel.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
srcFile, err := os.Open(srcPath)
panicOnError(err, "Failed to read source file")
defer func() {
_ = srcFile.Close()
}()
err = tarWriter.WriteHeader(&tar.Header{
Name: strings.TrimLeft(srcPath[len(srcDir):], string(os.PathSeparator)),
Size: info.Size(),
Mode: int64(info.Mode()),
ModTime: info.ModTime(),
})
panicOnError(err, "Failed to write tar entry header")
_, err = io.Copy(tarWriter, srcFile)
panicOnError(err, "Failed to copy")
return nil
})
return zipFile.Name()
}
func exists(filename string) bool {
_, err := os.Stat(filename)
return err == nil
}
// empty returns true if the given directory is empty.
// the directory must exist.
func empty(dirname string) bool {
dir, err := os.Open(dirname)
if err != nil {
errorf("error opening directory: %s", err)
}
defer func() {
_ = dir.Close()
}()
results, _ := dir.Readdir(1)
return len(results) == 0
}
func importPathFromCurrentDir() string {
pwd, _ := os.Getwd()
importPath, _ := filepath.Rel(filepath.Join(build.Default.GOPATH, "src"), pwd)
return filepath.ToSlash(importPath)
}