PackageManager just because
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
3.0 KiB

package Filesystem
import (
"bytes"
"crypto/sha1"
"encoding/gob"
"encoding/hex"
"errors"
"fmt"
"hash"
"io"
"os"
"path/filepath"
)
var (
// TODO: Where do I put this
Data string
)
type Package struct {
Name string
Version string
}
type FileObject struct {
FileMode os.FileMode
Size int64
Package Package
Ref string
Sha1 []byte
}
type ByName []Package
func (f FileObject) IsLink() bool {
return f.FileMode&os.ModeSymlink != 0
}
func (f FileObject) objFile() string {
return filepath.Join(f.objDir(), hex.EncodeToString(f.Sha1))
}
func (f FileObject) objDir() string {
return filepath.Join(Data, hex.EncodeToString(f.Sha1[:2]))
}
func (f FileObject) Reset(dst string) error {
var e error
if f.IsLink() {
_, e = os.Lstat(dst)
if !os.IsNotExist(e) {
e = os.Remove(dst)
if e != nil {
return e
}
}
e = os.Symlink(f.Ref, dst)
if e != nil {
return e
}
return nil
}
f.cp(f.objFile(), dst)
e = os.Chmod(dst, f.FileMode)
if e != nil {
return e
}
return nil
}
func (f FileObject) Stov(src string) error {
var e error
if f.IsLink() {
return nil
}
e = os.MkdirAll(f.objDir(), 0744)
if e != nil {
return e
}
f.cp(src, f.objFile())
return nil
}
func (f FileObject) cp(src string, dst string) error {
var (
srcFile, dstFile *os.File
e error
)
fmt.Println("cp ", src, dst)
srcFile, e = os.Open(src)
if e != nil {
return e
}
defer srcFile.Close()
dstFile, e = os.Create(dst)
if e != nil {
return e
}
defer dstFile.Close()
_, e = io.Copy(dstFile, srcFile)
if e != nil {
return e
}
return dstFile.Sync()
}
func (f FileObject) IsDifferent(fn FileObject) error {
if f.FileMode != fn.FileMode {
return errors.New("Mode does not match")
}
if f.IsLink() {
if f.Ref != fn.Ref {
return errors.New("Ref does not match")
}
return nil
}
if f.Size != fn.Size {
return errors.New("Size does not match")
}
if bytes.Compare(f.Sha1, fn.Sha1) != 0 {
return errors.New("Sha1 does not match")
}
return nil
}
func CreateFileObject(f string) (FileObject, error) {
var (
sha1Hash hash.Hash = sha1.New()
fo FileObject
fi os.FileInfo
file *os.File
e error
)
fi, e = os.Lstat(f)
if e != nil {
return fo, e
}
fo = FileObject{
FileMode: fi.Mode(),
Size: fi.Size(),
}
if fo.IsLink() {
fo.Ref, e = os.Readlink(f)
if e != nil {
return fo, e
}
return fo, nil
}
file, e = os.Open(f)
if e != nil {
return fo, e
}
defer file.Close()
io.Copy(sha1Hash, file)
fo.Sha1 = sha1Hash.Sum(nil)
return fo, nil
}
func (f FileObject) ToBytes() ([]byte, error) {
var (
encoder *gob.Encoder
buf bytes.Buffer
e error
)
encoder = gob.NewEncoder(&buf)
e = encoder.Encode(f)
return buf.Bytes(), e
}
func FromBytes(v []byte) (FileObject, error) {
var (
buf *bytes.Buffer
decoder *gob.Decoder
fo FileObject
e error
)
buf = bytes.NewBuffer(v)
decoder = gob.NewDecoder(buf)
e = decoder.Decode(&fo)
if e != nil {
return fo, e
}
return fo, nil
}