func tasksForPagesDir(dir string) ([]*pool.Task, error) { log.Debugf("Descending into pages directory: %v", dir) files, err := ioutil.ReadDir(singularity.PagesDir) if err != nil { return nil, err } var tasks []*pool.Task for _, fileInfo := range files { // be careful with closures in loops name := fileInfo.Name() if fileInfo.IsDir() { subtasks, err := tasksForPagesDir(dir + name) if err != nil { return nil, err } tasks = append(tasks, subtasks...) } else { tasks = append(tasks, pool.NewTask(func() error { return compilePage(dir, trimExtension(name)) })) } } return tasks, nil }
func tasksForArticles() ([]*pool.Task, error) { files, err := ioutil.ReadDir(singularity.ArticlesDir) if err != nil { return nil, err } var tasks []*pool.Task for _, fileInfo := range files { // be careful with closures in loops name := fileInfo.Name() if isHidden(name) { continue } tasks = append(tasks, pool.NewTask(func() error { return compileArticle(name) })) } return tasks, nil }
func TestRunTasks(t *testing.T) { conf.Concurrency = 3 // // Success case // tasks := []*pool.Task{ pool.NewTask(func() error { return nil }), pool.NewTask(func() error { return nil }), pool.NewTask(func() error { return nil }), } assert.Equal(t, true, runTasks(tasks)) // // Failure case (1 error) // tasks = []*pool.Task{ pool.NewTask(func() error { return nil }), pool.NewTask(func() error { return nil }), pool.NewTask(func() error { return fmt.Errorf("error") }), } assert.Equal(t, false, runTasks(tasks)) // // Failure case (11 errors) // // Here we'll exit with a "too many errors" message. // tasks = []*pool.Task{ pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), pool.NewTask(func() error { return fmt.Errorf("error") }), } assert.Equal(t, false, runTasks(tasks)) }
func main() { start := time.Now() defer func() { log.Infof("Built site in %v.", time.Now().Sub(start)) }() err := envdecode.Decode(&conf) if err != nil { log.Fatal(err) } singularity.InitLog(conf.Verbose) // This is where we stored "versioned" assets like compiled JS and CSS. // These assets have a release number that we can increment and by // extension quickly invalidate. versionedAssetsDir := path.Join(singularity.TargetDir, "assets", singularity.Release) err = singularity.CreateOutputDirs(singularity.TargetDir) if err != nil { log.Fatal(err) } var tasks []*pool.Task tasks = append(tasks, pool.NewTask(func() error { return linkFonts() })) tasks = append(tasks, pool.NewTask(func() error { return linkImages() })) tasks = append(tasks, pool.NewTask(func() error { return assets.CompileJavascripts( path.Join(singularity.AssetsDir, "javascripts"), path.Join(versionedAssetsDir, "app.js")) })) tasks = append(tasks, pool.NewTask(func() error { return assets.CompileStylesheets( path.Join(singularity.AssetsDir, "stylesheets"), path.Join(versionedAssetsDir, "app.css")) })) articleTasks, err := tasksForArticles() if err != nil { log.Fatal(err) } tasks = append(tasks, articleTasks...) pageTasks, err := tasksForPages() if err != nil { log.Fatal(err) } tasks = append(tasks, pageTasks...) if !runTasks(tasks) { os.Exit(1) } }