From 38d20d46fe8bca0e70fb6664dcb247373a0624e2 Mon Sep 17 00:00:00 2001 From: Tim Shannon Date: Fri, 1 Apr 2016 21:23:11 +0000 Subject: [PATCH] Added polling for new project files --- cycle.go | 6 ++-- project.go | 89 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 75 insertions(+), 20 deletions(-) diff --git a/cycle.go b/cycle.go index 9f80866..61fd813 100644 --- a/cycle.go +++ b/cycle.go @@ -24,13 +24,13 @@ func (p *Project) errHandled(err error) bool { } if p.ds == nil { - log.Printf("Error in project %s: %s", p.id(), err) + log.Printf("Error in project %s: %s\n", p.id(), err) return true } defer func() { err = p.ds.Close() if err != nil { - log.Printf("Error closing the datastore for project %s: %s", p.id(), err) + log.Printf("Error closing the datastore for project %s: %s\n", p.id(), err) } p.ds = nil @@ -38,7 +38,7 @@ func (p *Project) errHandled(err error) bool { if p.version != "" { err = os.RemoveAll(p.verDir()) - log.Printf("Error deleting the version directory project %s version %s: %s", + log.Printf("Error deleting the version directory project %s version %s: %s\n", p.id(), p.version, err) } diff --git a/project.go b/project.go index 2709fba..2d5f217 100644 --- a/project.go +++ b/project.go @@ -6,6 +6,7 @@ package main import ( "encoding/json" + "log" "os" "path/filepath" "sync" @@ -28,6 +29,8 @@ const ( stageRelease = "release" ) +const projectFilePoll = 30 * time.Second + // Project is an ironsmith project that contains how to fetch, build, test, and release a project /* The project lifecycle goes like this, each step calling the next if successful @@ -114,9 +117,6 @@ var projects = projectList{ } func (p *projectList) load() error { - p.Lock() - defer p.Unlock() - dir, err := os.Open(filepath.Join(projectDir, enabledProjectDir)) defer func() { if cerr := dir.Close(); cerr != nil && err == nil { @@ -135,24 +135,13 @@ func (p *projectList) load() error { for i := range files { if !files[i].IsDir() && filepath.Ext(files[i].Name()) == ".json" { - prj := &Project{ - filename: files[i].Name(), - Name: files[i].Name(), - stage: stageLoad, - } - p.data[files[i].Name()] = prj - - prj.load() + p.add(files[i].Name()) } } - return nil -} + time.AfterFunc(projectFilePoll, startProjectLoader) -func (p *projectList) remove(name string) { - p.Lock() - delete(p.data, name) - p.Unlock() + return nil } func (p *projectList) exists(name string) bool { @@ -163,7 +152,73 @@ func (p *projectList) exists(name string) bool { return ok } +func (p *projectList) add(name string) { + p.Lock() + defer p.Unlock() + + prj := &Project{ + filename: name, + Name: name, + stage: stageLoad, + } + p.data[name] = prj + + go func() { + prj.load() + }() +} + +// removeMissing removes projects that are missing from the passed in list of names +func (p *projectList) removeMissing(names []string) { + p.Lock() + defer p.Unlock() + + for i := range p.data { + found := false + for k := range names { + if names[k] == i { + found = true + } + } + if !found { + delete(p.data, i) + } + } +} + // startProjectLoader polls for new projects func startProjectLoader() { + dir, err := os.Open(filepath.Join(projectDir, enabledProjectDir)) + defer func() { + if cerr := dir.Close(); cerr != nil && err == nil { + err = cerr + } + }() + if err != nil { + log.Printf("Error in startProjectLoader opening the filepath %s: %s\n", dir, err) + return + } + + files, err := dir.Readdir(0) + if err != nil { + log.Printf("Error in startProjectLoader reading the dir %s: %s\n", dir, err) + return + } + + names := make([]string, len(files)) + + for i := range files { + if !files[i].IsDir() && filepath.Ext(files[i].Name()) == ".json" { + names[i] = files[i].Name() + if !projects.exists(files[i].Name()) { + projects.add(files[i].Name()) + } + } + } + + //check for removed projects + projects.removeMissing(names) + + time.AfterFunc(projectFilePoll, startProjectLoader) }