// Fetches all the sources specified by config, storing them in the given cache. func FetchSources(config *Config, cache Cache) []error { sources := config.Sources() sc := make(chan string) ec := make(chan error) var errors []error go func() { for err := range ec { errors = append(errors, err) } }() var wg sync.WaitGroup wg.Add(len(sources)) // Concurrently fetch, up to a maximum concurrency limit. for i := 0; i < math.MinInt(fetchLimit, len(sources)); i++ { go func() { for source := range sc { defer wg.Done() err := fetch(source, cache) if err != nil { ec <- errwrap.Wrapf(fmt.Sprintf("Error fetching %s: {{err}}", source), err) } } }() } go func() { for _, source := range sources { sc <- source } close(sc) }() wg.Wait() close(ec) return errors }
// Runs all the transforms for each Output specified in config. Sources are read // from the given cache. Transforms are loaded from transforms. Transformed // outputs are written to outputs. func Process(config *Config, cache Cache, transforms Transforms, outputs Outputs) []error { oc := make(chan Output) ec := make(chan error) var errors []error go func() { for err := range ec { errors = append(errors, err) } }() var wg sync.WaitGroup wg.Add(len(config.Outputs)) // Process outputs, up to a maximum concurrency limit. for i := 0; i < math.MinInt(processLimit, len(config.Outputs)); i++ { go func() { for output := range oc { defer wg.Done() err := processOutput(output, cache, transforms, outputs) if err != nil { ec <- errwrap.Wrapf(fmt.Sprintf("Error processing %s: {{err}}", output.Name), err) } } }() } go func() { for _, output := range config.Outputs { oc <- output } close(oc) }() wg.Wait() close(ec) return errors }
// lineIndexSpan returns line indicies that are spanned by the selection. func (cp *CaretPosition) lineIndexSpan() (first, last int) { min := intmath.MinInt(cp.caretPosition.lineIndex, cp.selectionPosition.lineIndex) max := intmath.MaxInt(cp.caretPosition.lineIndex, cp.selectionPosition.lineIndex) return min, max }