package scanner import ( "fmt" store "git.entr0py.de/garionion/murphy/store" "github.com/karrick/godirwalk" "github.com/mehdioa/nlog" "github.com/oriser/regroup" "io/ioutil" "path" "strings" "time" ) type Scanner struct { TargetPath string LastChange time.Time Created time.Time ProjectName string Logger *nlog.Logger } func NewScanner(target, projectName string, createdAt time.Time, logger *nlog.Logger) *Scanner { projectLogger := logger.New("Scanner", nlog.Data{"Project": projectName,}) scanner := &Scanner{TargetPath: target, Created: createdAt, ProjectName: projectName, Logger: logger} projectLogger.Infof("Scanning %s", projectName) err := godirwalk.Walk(target, &godirwalk.Options{ Callback: func(osPathname string, de *godirwalk.Dirent) error { // Following string operation is not most performant way // of doing this, but common enough to warrant a simple // example here: if strings.Contains(osPathname, ".git") { return godirwalk.SkipThis } fmt.Printf("%s %s\n", de.ModeType(), osPathname) return nil }, Unsorted: true, // (optional) set true for faster yet non-deterministic enumeration (see godoc) }) if err != nil { projectLogger.Errorf("Error scanning %s: %s", projectName, err) } return scanner } func InitScanner(s *store.Store, sourcePath string) { s.Logger.Infof("Initializing scanner") scanners := map[string]*Scanner{} RootScanner(sourcePath, scanners, s.Logger) } func RootScanner(rootPath string, scanners map[string]*Scanner, logger *nlog.Logger) { resorts, err := ioutil.ReadDir(rootPath) if err != nil { logger.Errorf("Error reading directory %s: %v", rootPath, err) return } re := regroup.MustCompile(`(?P\d{4}-\d{2}-\d{2})_(?P.*$)`) for _, r := range resorts { if r.IsDir() && r.Name()[0] != '.' { resort := path.Join(rootPath, r.Name()) logger.Debugf("Found directory: %s", resort) projects, err := ioutil.ReadDir(resort) if err != nil { logger.Errorf("Error reading directory %s: %v", projects, err) return } for _, p := range projects { if p.IsDir() { _, mapContainsProject := scanners[p.Name()] if mapContainsProject { continue } projectPath := path.Join(resort, p.Name()) matches, err := re.Groups(p.Name()) if err != nil { logger.Debugf("Failed to Match %s: %v", p.Name(), err) continue } logger.Debugf("Matches: %+v", matches) if len(matches) != 0 { createdAtString := matches["date"] projectName := matches["name"] logger.Infof("Found project: %s", projectName) createdAt, err := time.Parse("2006-01-02", createdAtString) if err != nil { logger.Errorf("Failed to parse date %s: %v, skipping %s", createdAtString, err, p.Name()) } scanner := NewScanner(projectPath, projectName, createdAt, logger) scanners[p.Name()] = scanner } else { logger.Debugf("Ignoring Directory %s", projectPath) } } } } } }