pkg/preprocess/file.go (45 lines of code) (raw):

package preprocess import ( "bytes" "io" "os" "path/filepath" "strings" "github.com/pkg/errors" ) const peekLen = 64 // look at first N bytes to figure out if it has shebang // textExtensions is predefined list of script and text // file extensions. var textExtensions = []string{ ".sh", ".txt", ".py", ".pl", } // IsTextFile is a best effort to determine if a file // is a script file (with a known file extension) or a // file that starts with a shebang (!#) func IsTextFile(path string) (bool, error) { if hasTextExtension(path) { return true, nil } f, err := os.Open(path) if err != nil { return false, errors.Wrap(err, "failed to open file") } defer f.Close() b := make([]byte, peekLen) _, err = f.Read(b) if err != nil && err != io.EOF { return false, errors.Wrap(err, "failed to read file") } return hasShebang(b), nil } // hasShebang checks if provided file contents start with #! characters // once the BOM and space characters are trimmed from the beginning. func hasShebang(b []byte) bool { b = RemoveBOM(b) return bytes.HasPrefix(b, []byte{'#', '!'}) } // hasTextExtension is a best effort to determine if a // file's extension is incidator of a text or script contents. func hasTextExtension(path string) bool { ext := strings.ToLower(filepath.Ext(path)) for _, v := range textExtensions { if ext == v { return true } } return false }