docs/client/changelist/files_changelist.go

115 lines
2.3 KiB
Go

package changelist
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
"sort"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/uuid"
)
// FileChangelist stores all the changes as files
type FileChangelist struct {
dir string
}
// NewFileChangelist is a convenience method for returning FileChangeLists
func NewFileChangelist(dir string) (*FileChangelist, error) {
logrus.Debug("Making dir path: ", dir)
err := os.MkdirAll(dir, 0700)
if err != nil {
return nil, err
}
return &FileChangelist{dir: dir}, nil
}
// List returns a list of sorted changes
func (cl FileChangelist) List() []Change {
var changes []Change
dir, err := os.Open(cl.dir)
if err != nil {
return changes
}
defer dir.Close()
fileInfos, err := dir.Readdir(0)
if err != nil {
return changes
}
sort.Sort(fileChanges(fileInfos))
for _, f := range fileInfos {
if f.IsDir() {
continue
}
raw, err := ioutil.ReadFile(path.Join(cl.dir, f.Name()))
if err != nil {
logrus.Warn(err.Error())
continue
}
c := &TufChange{}
err = json.Unmarshal(raw, c)
if err != nil {
logrus.Warn(err.Error())
continue
}
changes = append(changes, c)
}
return changes
}
// Add adds a change to the file change list
func (cl FileChangelist) Add(c Change) error {
cJSON, err := json.Marshal(c)
if err != nil {
return err
}
filename := fmt.Sprintf("%020d_%s.change", time.Now().UnixNano(), uuid.Generate())
return ioutil.WriteFile(path.Join(cl.dir, filename), cJSON, 0644)
}
// Clear clears the change list
func (cl FileChangelist) Clear(archive string) error {
dir, err := os.Open(cl.dir)
if err != nil {
return err
}
defer dir.Close()
files, err := dir.Readdir(0)
if err != nil {
return err
}
for _, f := range files {
os.Remove(path.Join(cl.dir, f.Name()))
}
return nil
}
// Close is a no-op
func (cl FileChangelist) Close() error {
// Nothing to do here
return nil
}
type fileChanges []os.FileInfo
// Len returns the length of a file change list
func (cs fileChanges) Len() int {
return len(cs)
}
// Less compares the names of two different file changes
func (cs fileChanges) Less(i, j int) bool {
return cs[i].Name() < cs[j].Name()
}
// Swap swaps the position of two file changes
func (cs fileChanges) Swap(i, j int) {
tmp := cs[i]
cs[i] = cs[j]
cs[j] = tmp
}