fileboy/fileboy.go

230 lines
4.6 KiB
Go
Raw Normal View History

2018-09-10 08:23:27 +00:00
package main
import (
"fmt"
"gopkg.in/fsnotify/fsnotify.v1"
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
"math/rand"
"os"
"path"
2019-04-01 08:44:16 +00:00
"strconv"
2019-01-08 07:49:21 +00:00
"strings"
2018-09-10 08:23:27 +00:00
"time"
)
const (
Version = 1
2019-01-19 09:10:07 +00:00
PreError = "ERROR:"
PreWarn = "Warn:"
2018-09-10 08:23:27 +00:00
)
var (
2019-01-03 02:27:04 +00:00
projectFolder = "."
2018-09-10 08:23:27 +00:00
cfg *FileGirl
watcher *fsnotify.Watcher
2018-12-30 07:14:14 +00:00
taskMan *TaskMan
2018-09-10 08:23:27 +00:00
)
2019-01-03 01:56:26 +00:00
type changedFile struct {
2018-09-19 03:26:57 +00:00
Name string
Changed int64
2018-09-19 03:26:57 +00:00
Ext string
2018-09-10 08:23:27 +00:00
}
func parseConfig() {
cfg = new(FileGirl)
fc, err := ioutil.ReadFile(projectFolder + "/filegirl.yaml")
if err != nil {
2019-04-03 10:04:07 +00:00
log.Println(PreError, "the filegirl.yaml file in", projectFolder, "is not exist! ", err)
fmt.Print(firstRunHelp)
log.Fatalln("fileboy unable to run.")
2018-09-10 08:23:27 +00:00
}
err = yaml.Unmarshal(fc, cfg)
if err != nil {
2019-01-19 09:10:07 +00:00
log.Panicln(PreError, "parsed filegirl.yaml failed: ", err)
2018-09-10 08:23:27 +00:00
}
if cfg.Core.Version > Version {
2019-01-19 09:10:07 +00:00
log.Panicln(PreError, "current fileboy support max version : ", Version)
2018-09-10 08:23:27 +00:00
}
2019-04-01 08:18:01 +00:00
// init map
2019-04-01 07:32:27 +00:00
cfg.Monitor.TypesMap = map[string]bool{}
2019-04-01 08:18:01 +00:00
cfg.Monitor.IncludeDirsMap = map[string]bool{}
cfg.Monitor.ExceptDirsMap = map[string]bool{}
// convert to map
2019-04-01 07:32:27 +00:00
for _, v := range cfg.Monitor.Types {
cfg.Monitor.TypesMap[v] = true
}
2018-09-10 08:23:27 +00:00
log.Println(cfg)
}
func eventDispatcher(event fsnotify.Event) {
ext := path.Ext(event.Name)
if len(cfg.Monitor.Types) > 0 &&
2019-04-01 07:32:27 +00:00
!keyInMonitorTypesMap(".*", cfg) &&
!keyInMonitorTypesMap(ext, cfg) {
2018-09-10 08:23:27 +00:00
return
}
switch event.Op {
2019-01-03 02:07:24 +00:00
case
fsnotify.Write,
fsnotify.Rename:
2019-01-03 02:13:08 +00:00
log.Println("EVENT", event.Op.String(), ":", event.Name)
2019-01-03 01:56:26 +00:00
taskMan.Put(&changedFile{
2019-04-04 02:46:52 +00:00
Name: relativePath(projectFolder, event.Name),
Changed: time.Now().UnixNano(),
2018-09-19 03:26:57 +00:00
Ext: ext,
})
2018-09-10 08:23:27 +00:00
case fsnotify.Remove:
2019-01-03 02:07:24 +00:00
case fsnotify.Create:
2018-09-10 08:23:27 +00:00
}
}
func addWatcher() {
2018-09-19 02:03:42 +00:00
log.Println("collecting directory information...")
2019-04-03 10:04:07 +00:00
dirsMap := map[string]bool{
projectFolder: true,
}
2019-04-01 08:18:01 +00:00
for _, dir := range cfg.Monitor.IncludeDirs {
darr := dirParse2Array(dir)
2018-09-10 08:23:27 +00:00
if len(darr) < 1 || len(darr) > 2 {
2019-04-01 08:18:01 +00:00
log.Fatalln(PreError, "filegirl section monitor dirs is error. ", dir)
2018-09-10 08:23:27 +00:00
}
2019-01-08 07:49:21 +00:00
if strings.HasPrefix(darr[0], "/") {
2019-04-01 08:18:01 +00:00
log.Fatalln(PreError, "dirs must be relative paths ! err path:", dir)
2019-01-08 07:49:21 +00:00
}
2018-09-10 08:23:27 +00:00
if darr[0] == "." {
if len(darr) == 2 && darr[1] == "*" {
2019-04-01 08:18:01 +00:00
// The highest priority
dirsMap = map[string]bool{
projectFolder: true,
}
2018-09-10 08:23:27 +00:00
listFile(projectFolder, func(d string) {
2019-04-01 08:18:01 +00:00
dirsMap[d] = true
2018-09-10 08:23:27 +00:00
})
2019-04-01 08:18:01 +00:00
break
2018-09-10 08:23:27 +00:00
} else {
2019-04-01 08:18:01 +00:00
dirsMap[projectFolder] = true
2018-09-10 08:23:27 +00:00
}
} else {
md := projectFolder + "/" + darr[0]
2019-04-01 08:18:01 +00:00
dirsMap[md] = true
2018-09-10 08:23:27 +00:00
if len(darr) == 2 && darr[1] == "*" {
listFile(md, func(d string) {
2019-04-01 08:18:01 +00:00
dirsMap[d] = true
2018-09-10 08:23:27 +00:00
})
}
}
}
2019-04-01 08:18:01 +00:00
for _, dir := range cfg.Monitor.ExceptDirs {
if dir == "." {
log.Fatalln(PreError, "exceptDirs must is not project root path ! err path:", dir)
}
p := projectFolder + "/" + dir
delete(dirsMap, p)
2018-09-10 08:23:27 +00:00
listFile(p, func(d string) {
2019-04-01 08:18:01 +00:00
delete(dirsMap, d)
2018-09-10 08:23:27 +00:00
})
}
2019-04-01 08:18:01 +00:00
for dir := range dirsMap {
2018-09-10 08:23:27 +00:00
log.Println("watcher add -> ", dir)
err := watcher.Add(dir)
if err != nil {
log.Fatalln(err)
}
}
2019-04-01 08:44:16 +00:00
log.Println("total monitored dirs: " + strconv.Itoa(len(dirsMap)))
2018-09-10 08:23:27 +00:00
log.Println("fileboy is ready.")
2019-04-02 10:37:46 +00:00
cfg.Monitor.DirsMap = dirsMap
2018-09-10 08:23:27 +00:00
}
func initWatcher() {
var err error
2019-04-03 10:04:07 +00:00
if watcher != nil {
_ = watcher.Close()
}
2018-09-10 08:23:27 +00:00
watcher, err = fsnotify.NewWatcher()
if err != nil {
log.Fatalln(err)
}
2019-01-02 11:07:52 +00:00
taskMan = newTaskMan(cfg.Command.DelayMillSecond, cfg.Notifier.CallUrl)
2018-09-10 08:23:27 +00:00
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
eventDispatcher(event)
case err, ok := <-watcher.Errors:
if !ok {
return
}
2019-01-19 09:10:07 +00:00
log.Println(PreError, err)
2018-09-10 08:23:27 +00:00
}
}
}()
addWatcher()
}
func parseArgs() {
2019-04-03 10:04:07 +00:00
switch len(os.Args) {
case 1:
parseConfig()
done := make(chan bool)
2018-09-10 08:23:27 +00:00
initWatcher()
2019-04-03 10:04:07 +00:00
defer watcher.Close()
<-done
2018-09-10 08:23:27 +00:00
return
2019-04-03 10:04:07 +00:00
case 2:
2018-09-10 08:23:27 +00:00
c := os.Args[1]
switch c {
case "init":
err := ioutil.WriteFile(projectFolder+"/filegirl.yaml", []byte(exampleFileGirl), 0644)
if err != nil {
2019-01-19 09:10:07 +00:00
log.Println(PreError, "error create filegirl.yaml config! ", err)
2018-09-10 08:23:27 +00:00
return
}
log.Println("create filegirl.yaml ok")
return
case "exec":
parseConfig()
2019-01-03 01:56:26 +00:00
newTaskMan(0, cfg.Notifier.CallUrl).run(new(changedFile))
2018-09-10 08:23:27 +00:00
return
2018-12-30 07:59:38 +00:00
case "version", "v", "-v", "--version":
fmt.Println(versionDesc)
2018-09-10 08:23:27 +00:00
default:
fmt.Print(helpStr)
}
return
2019-04-03 10:04:07 +00:00
default:
log.Fatalln("Unknown parameters, use `fileboy help` show help info.")
2018-09-10 08:23:27 +00:00
}
}
func show() {
fmt.Print(logo)
rand.Seed(time.Now().UnixNano())
2018-12-30 07:59:38 +00:00
fmt.Println(englishSay[rand.Intn(len(englishSay))])
fmt.Println("")
fmt.Println(statement)
2018-09-10 08:23:27 +00:00
}
func main() {
log.SetPrefix("[FileBoy]: ")
log.SetFlags(2)
show()
var err error
projectFolder, err = os.Getwd()
if err != nil {
log.Fatalln(err)
}
parseArgs()
}