-
-
Notifications
You must be signed in to change notification settings - Fork 329
/
file.go
85 lines (73 loc) · 2.51 KB
/
file.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright (c) 2016, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information
// Package fileutil contains code to work with shell files, also known
// as shell scripts.
package fileutil
import (
"io/fs"
"os"
"regexp"
"strings"
)
var (
shebangRe = regexp.MustCompile(`^#!\s?/(usr/)?bin/(env\s+)?(sh|bash|mksh|bats|zsh)(\s|$)`)
extRe = regexp.MustCompile(`\.(sh|bash|mksh|bats|zsh)$`)
)
// TODO: consider removing HasShebang in favor of Shebang in v4
// HasShebang reports whether bs begins with a valid shell shebang.
// It supports variations with /usr and env.
func HasShebang(bs []byte) bool {
return Shebang(bs) != ""
}
// Shebang parses a "#!" sequence from the beginning of the input bytes,
// and returns the shell that it points to.
//
// For instance, it returns "sh" for "#!/bin/sh",
// and "bash" for "#!/usr/bin/env bash".
func Shebang(bs []byte) string {
m := shebangRe.FindSubmatch(bs)
if m == nil {
return ""
}
return string(m[3])
}
// ScriptConfidence defines how likely a file is to be a shell script,
// from complete certainty that it is not one to complete certainty that
// it is one.
type ScriptConfidence int
const (
// ConfNotScript describes files which are definitely not shell scripts,
// such as non-regular files or files with a non-shell extension.
ConfNotScript ScriptConfidence = iota
// ConfIfShebang describes files which might be shell scripts, depending
// on the shebang line in the file's contents. Since CouldBeScript only
// works on os.FileInfo, the answer in this case can't be final.
ConfIfShebang
// ConfIsScript describes files which are definitely shell scripts,
// which are regular files with a valid shell extension.
ConfIsScript
)
// CouldBeScript is a shortcut for CouldBeScript2(fs.FileInfoToDirEntry(info)).
//
// Deprecated: prefer CouldBeScript2, which usually requires fewer syscalls.
func CouldBeScript(info os.FileInfo) ScriptConfidence {
return CouldBeScript2(fs.FileInfoToDirEntry(info))
}
// CouldBeScript2 reports how likely a directory entry is to be a shell script.
// It discards directories, symlinks, hidden files and files with non-shell
// extensions.
func CouldBeScript2(entry fs.DirEntry) ScriptConfidence {
name := entry.Name()
switch {
case entry.IsDir(), name[0] == '.':
return ConfNotScript
case entry.Type()&os.ModeSymlink != 0:
return ConfNotScript
case extRe.MatchString(name):
return ConfIsScript
case strings.IndexByte(name, '.') > 0:
return ConfNotScript // different extension
default:
return ConfIfShebang
}
}