pkger/pkging/pkgdiff/differ.go

140 lines
1.9 KiB
Go
Raw Permalink Normal View History

2019-10-16 21:40:31 +03:00
package pkgdiff
import (
"io/ioutil"
"os"
"strings"
"github.com/google/go-cmp/cmp"
"github.com/markbates/pkger/pkging/mem"
"github.com/markbates/pkger/pkging/stdos"
)
const (
BYTE = 1 << (10 * iota)
KILOBYTE
MEGABYTE
GIGABYTE
TERABYTE
PETABYTE
EXABYTE
)
type Differ struct {
A *stdos.Pkger
}
func (d Differ) File(p string) (string, error) {
f, err := d.A.Open(p)
if err != nil {
return "", err
}
info, err := f.Stat()
if err != nil {
return "", err
}
b, err := ioutil.ReadAll(f)
if err != nil {
return "", err
}
if _, err := f.Seek(0, 0); err != nil {
return "", err
}
df := diffFile{
Info: info,
Body: b,
}
adiff, err := df.Bytes()
if err != nil {
return "", err
}
m, err := mem.New(d.A.Here)
if err != nil {
return "", err
}
if err := m.Add(f); err != nil {
return "", err
}
if err := f.Close(); err != nil {
return "", err
}
me, err := m.MarshalEmbed()
if err != nil {
return "", err
}
m, err = mem.UnmarshalEmbed(me)
if err != nil {
return "", err
}
bf, err := m.Open(p)
if err != nil {
return "", err
}
info, err = bf.Stat()
if err != nil {
return "", err
}
b, err = ioutil.ReadAll(bf)
if err != nil {
return "", err
}
if err := bf.Close(); err != nil {
return "", err
}
df = diffFile{
Info: info,
Body: b,
}
bdiff, err := df.Bytes()
if err != nil {
return "", err
}
return strings.TrimSpace(cmp.Diff(adiff, bdiff)), nil
}
func (d Differ) Dir(p string) ([]string, error) {
var diffs []string
err := d.A.Walk(p, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
if info.Size() > MEGABYTE {
return nil
}
res, err := d.File(path)
if err != nil {
return err
}
if len(res) > 0 {
diffs = append(diffs, res)
}
return nil
})
if err != nil {
return nil, err
}
return diffs, nil
}