|
|
- 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
- }
|