mesh/delivery merged: source.main moved to novox/mesh-catalog@da29f77b1081
mesh/check being carried to 94dab6863523 on da29f77b1081 | from 5a4ac4991395
79 lines
2.6 KiB
Go
79 lines
2.6 KiB
Go
// Package nobinaries refuses a compiled program under modules/ (issue 1577): it is build output, made by the module's build step,
|
|
// and `go build` in a module's folder writes one beside go.mod where `git add -A` takes it.
|
|
package nobinaries
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// Kind says what executable format the first bytes of a file are, or "" when they are none.
|
|
func Kind(head []byte) string {
|
|
switch {
|
|
case bytes.HasPrefix(head, []byte("\x7fELF")):
|
|
return "ELF"
|
|
case bytes.HasPrefix(head, []byte("MZ")):
|
|
return "PE"
|
|
case bytes.HasPrefix(head, []byte{0xcf, 0xfa, 0xed, 0xfe}), bytes.HasPrefix(head, []byte{0xce, 0xfa, 0xed, 0xfe}),
|
|
bytes.HasPrefix(head, []byte{0xfe, 0xed, 0xfa, 0xcf}), bytes.HasPrefix(head, []byte{0xfe, 0xed, 0xfa, 0xce}),
|
|
bytes.HasPrefix(head, []byte{0xca, 0xfe, 0xba, 0xbe}) && len(head) >= 8 && head[7] < 0x20 && head[6] == 0 && head[5] == 0 && head[4] == 0:
|
|
return "Mach-O"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Files are the files of the catalogue's root that the change holds under modules/: the tracked ones when the root is a git
|
|
// checkout (an ignored binary a local build left is not the change's), else every file there.
|
|
func Files(root string) ([]string, error) {
|
|
cmd := exec.Command("git", "-C", root, "ls-files", "-z", "--", "modules")
|
|
if out, err := cmd.Output(); err == nil && len(out) > 0 {
|
|
var files []string
|
|
for _, f := range strings.Split(strings.TrimRight(string(out), "\x00"), "\x00") {
|
|
if _, err := os.Lstat(filepath.Join(root, f)); err == nil { // a file the change deletes is not there
|
|
files = append(files, f)
|
|
}
|
|
}
|
|
return files, nil
|
|
}
|
|
var files []string
|
|
err := filepath.WalkDir(filepath.Join(root, "modules"), func(p string, d os.DirEntry, err error) error {
|
|
if err != nil || d.IsDir() || !d.Type().IsRegular() {
|
|
return err
|
|
}
|
|
rel, _ := filepath.Rel(root, p)
|
|
files = append(files, rel)
|
|
return nil
|
|
})
|
|
return files, err
|
|
}
|
|
|
|
// Find names each file of files (paths from root) that is a compiled program, with its format.
|
|
func Find(root string, files []string) ([]string, error) {
|
|
var found []string
|
|
for _, f := range files {
|
|
p := filepath.Join(root, f)
|
|
if st, err := os.Lstat(p); err != nil || !st.Mode().IsRegular() {
|
|
continue
|
|
}
|
|
fh, err := os.Open(p)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
head := make([]byte, 8)
|
|
n, err := io.ReadFull(fh, head)
|
|
fh.Close()
|
|
if err != nil && err != io.ErrUnexpectedEOF && err != io.EOF {
|
|
return nil, err
|
|
}
|
|
if k := Kind(head[:n]); k != "" {
|
|
found = append(found, fmt.Sprintf("%s (%s)", f, k))
|
|
}
|
|
}
|
|
return found, nil
|
|
}
|