Skip to content

Instantly share code, notes, and snippets.

@surjikal
Created August 12, 2015 04:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save surjikal/b6b00fa1e1ae1187591b to your computer and use it in GitHub Desktop.
Save surjikal/b6b00fa1e1ae1187591b to your computer and use it in GitHub Desktop.
package main
import (
"path/filepath"
"os"
"flag"
"fmt"
"time"
)
type Set struct {
set map[string]bool
}
func NewSet() Set {
return Set{set:make(map[string]bool)}
}
func (self *Set) Add(key string) {
self.set[key] = true
}
func (self *Set) Remove(key string) {
delete(self.set, key)
}
func (self *Set) ToArray() (result []string) {
for key := range self.set {
result = append(result, key)
}
return result
}
func (self *Set) Without(other Set) Set {
result := NewSet()
for x := range self.set {
result.Add(x)
}
for x := range other.set {
result.Remove(x)
}
return result
}
type WalkResult struct {
timestamp time.Time
files Set
}
func NewWalkResult() WalkResult {
return WalkResult{files:NewSet()}
}
type DiffRecord struct {
filepath string
action string
timestamp time.Time
}
func (record DiffRecord) ToString() string {
timestamp := record.timestamp.UTC().Format("2006-01-02T15:04:05")
return fmt.Sprintf("%s\t%s\t%s", timestamp, record.action, record.filepath)
}
func interval(delay time.Duration, fn func()) chan bool {
stop := make(chan bool)
go func() {
for {
fn()
select {
case <-time.After(delay):
case <-stop:
return
}
}
}()
return stop
}
func mergeWalkResults(previous WalkResult, current WalkResult) (records []DiffRecord) {
timestamp := current.timestamp
added := current.files.Without(previous.files)
removed := previous.files.Without(current.files)
for _, key := range added.ToArray() {
record := DiffRecord{timestamp:timestamp, action:"add", filepath:key}
records = append(records, record)
}
for _, key := range removed.ToArray() {
record := DiffRecord{timestamp:timestamp, action:"del", filepath:key}
records = append(records, record)
}
return records
}
func walkDirectory(root string) (error, WalkResult) {
result := NewWalkResult()
result.timestamp = time.Now()
filepath.Walk(root, func(filepath string, info os.FileInfo, err error) error {
if filepath != root {
result.files.Add(filepath)
}
return nil
})
return nil, result
}
func main() {
flag.Parse()
root := flag.Arg(0)
previousWalkResult := NewWalkResult()
previousWalkResult.timestamp = time.Now()
stop := interval(time.Second, func() {
_, walkResult := walkDirectory(root)
records := mergeWalkResults(previousWalkResult, walkResult)
for _, record := range records {
fmt.Println(record.ToString())
}
previousWalkResult = walkResult
})
<-stop
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment