Skip to content

Commit c720e41

Browse files
committed
chore: some cleanup and commenting
Signed-off-by: Brian McGee <[email protected]>
1 parent 2eaf999 commit c720e41

File tree

1 file changed

+91
-56
lines changed

1 file changed

+91
-56
lines changed

Diff for: cli/format.go

+91-56
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ func (f *Format) Run() (err error) {
6464
pipelines = make(map[string]*format.Pipeline)
6565
formatters = make(map[string]*format.Formatter)
6666

67+
// iterate the formatters in lexicographical order
6768
for _, name := range cfg.Names {
69+
// init formatter
6870
formatterCfg := cfg.Formatters[name]
6971
formatter, err := format.NewFormatter(name, Cli.TreeRoot, formatterCfg, globalExcludes)
7072
if errors.Is(err, format.ErrCommandNotFound) && Cli.AllowMissingFormatter {
@@ -74,8 +76,12 @@ func (f *Format) Run() (err error) {
7476
return fmt.Errorf("%w: failed to initialise formatter: %v", err, name)
7577
}
7678

79+
// store formatter by name
7780
formatters[name] = formatter
7881

82+
// If no pipeline is configured, we add the formatter to a nominal pipeline of size 1 with the key being the
83+
// formatter's name. If a pipeline is configured, we add the formatter to a pipeline keyed by
84+
// 'p:<pipeline_name>' in which it is sorted by priority.
7985
if formatterCfg.Pipeline == "" {
8086
pipeline := format.Pipeline{}
8187
pipeline.Add(formatter)
@@ -110,17 +116,17 @@ func (f *Format) Run() (err error) {
110116
// initialise stats collection
111117
stats.Init()
112118

113-
// create some groups for concurrent processing and control flow
119+
// create an overall error group for executing high level tasks concurrently
114120
eg, ctx := errgroup.WithContext(ctx)
115121

116-
// create a channel for paths to be processed
117-
// we use a multiple of batch size here to allow for greater concurrency
122+
// create a channel for files needing to be processed
123+
// we use a multiple of batch size here as a rudimentary concurrency optimization based on the host machine
118124
filesCh = make(chan *walk.File, BatchSize*runtime.NumCPU())
119125

120-
// create a channel for tracking paths that have been processed
126+
// create a channel for files that have been processed
121127
processedCh = make(chan *walk.File, cap(filesCh))
122128

123-
// start concurrent processing tasks
129+
// start concurrent processing tasks in reverse order
124130
eg.Go(updateCache(ctx))
125131
eg.Go(applyFormatters(ctx))
126132
eg.Go(walkFilesystem(ctx))
@@ -129,15 +135,70 @@ func (f *Format) Run() (err error) {
129135
return eg.Wait()
130136
}
131137

138+
func updateCache(ctx context.Context) func() error {
139+
return func() error {
140+
// used to batch updates for more efficient txs
141+
batch := make([]*walk.File, 0, BatchSize)
142+
143+
// apply a batch
144+
processBatch := func() error {
145+
if err := cache.Update(batch); err != nil {
146+
return err
147+
}
148+
batch = batch[:0]
149+
return nil
150+
}
151+
152+
LOOP:
153+
for {
154+
select {
155+
// detect ctx cancellation
156+
case <-ctx.Done():
157+
return ctx.Err()
158+
// respond to processed files
159+
case file, ok := <-processedCh:
160+
if !ok {
161+
// channel has been closed, no further files to process
162+
break LOOP
163+
}
164+
// append to batch and process if we have enough
165+
batch = append(batch, file)
166+
if len(batch) == BatchSize {
167+
if err := processBatch(); err != nil {
168+
return err
169+
}
170+
}
171+
}
172+
}
173+
174+
// final flush
175+
if err := processBatch(); err != nil {
176+
return err
177+
}
178+
179+
// if fail on change has been enabled, check that no files were actually formatted, throwing an error if so
180+
if Cli.FailOnChange && stats.Value(stats.Formatted) != 0 {
181+
return ErrFailOnChange
182+
}
183+
184+
// print stats to stdout
185+
stats.Print()
186+
187+
return nil
188+
}
189+
}
190+
132191
func walkFilesystem(ctx context.Context) func() error {
133192
return func() error {
134193
paths := Cli.Paths
135194

195+
// we read paths from stdin if the cli flag has been set and no paths were provided as cli args
136196
if len(paths) == 0 && Cli.Stdin {
137197

198+
// determine the current working directory
138199
cwd, err := os.Getwd()
139200
if err != nil {
140-
return fmt.Errorf("%w: failed to determine current working directory", err)
201+
return fmt.Errorf("failed to determine current working directory: %w", err)
141202
}
142203

143204
// read in all the paths
@@ -149,17 +210,21 @@ func walkFilesystem(ctx context.Context) func() error {
149210
path = filepath.Join(cwd, path)
150211
}
151212

213+
// append the fully qualified path to our paths list
152214
paths = append(paths, path)
153215
}
154216
}
155217

218+
// create a filesystem walker
156219
walker, err := walk.New(Cli.Walk, Cli.TreeRoot, paths)
157220
if err != nil {
158221
return fmt.Errorf("failed to create walker: %w", err)
159222
}
160223

224+
// close the files channel when we're done walking the file system
161225
defer close(filesCh)
162226

227+
// if no cache has been configured, we invoke the walker directly
163228
if Cli.NoCache {
164229
return walker.Walk(ctx, func(file *walk.File, err error) error {
165230
select {
@@ -177,76 +242,42 @@ func walkFilesystem(ctx context.Context) func() error {
177242
})
178243
}
179244

245+
// otherwise we pass the walker to the cache and have it generate files for processing based on whether or not
246+
// they have been added/changed since the last invocation
180247
if err = cache.ChangeSet(ctx, walker, filesCh); err != nil {
181248
return fmt.Errorf("failed to generate change set: %w", err)
182249
}
183250
return nil
184251
}
185252
}
186253

187-
func updateCache(ctx context.Context) func() error {
188-
return func() error {
189-
batch := make([]*walk.File, 0, BatchSize)
190-
191-
processBatch := func() error {
192-
if err := cache.Update(batch); err != nil {
193-
return err
194-
}
195-
batch = batch[:0]
196-
return nil
197-
}
198-
199-
LOOP:
200-
for {
201-
select {
202-
case <-ctx.Done():
203-
return ctx.Err()
204-
case path, ok := <-processedCh:
205-
if !ok {
206-
break LOOP
207-
}
208-
batch = append(batch, path)
209-
if len(batch) == BatchSize {
210-
if err := processBatch(); err != nil {
211-
return err
212-
}
213-
}
214-
}
215-
}
216-
217-
// final flush
218-
if err := processBatch(); err != nil {
219-
return err
220-
}
221-
222-
if Cli.FailOnChange && stats.Value(stats.Formatted) != 0 {
223-
return ErrFailOnChange
224-
}
225-
226-
stats.Print()
227-
return nil
228-
}
229-
}
230-
231254
func applyFormatters(ctx context.Context) func() error {
255+
// create our own errgroup for concurrent formatting tasks
232256
fg, ctx := errgroup.WithContext(ctx)
257+
258+
// pre-initialise batches keyed by pipeline
233259
batches := make(map[string][]*walk.File)
260+
for key := range pipelines {
261+
batches[key] = make([]*walk.File, 0, BatchSize)
262+
}
234263

264+
// for a given pipeline key, add the provided file to the current batch and trigger a format if the batch size has
265+
// been reached
235266
tryApply := func(key string, file *walk.File) {
236-
batch, ok := batches[key]
237-
if !ok {
238-
batch = make([]*walk.File, 0, BatchSize)
239-
}
240-
batch = append(batch, file)
241-
batches[key] = batch
267+
// append to batch
268+
batches[key] = append(batches[key], file)
242269

270+
// check if the batch is full
271+
batch := batches[key]
243272
if len(batch) == BatchSize {
273+
// get the pipeline
244274
pipeline := pipelines[key]
245275

246276
// copy the batch
247277
files := make([]*walk.File, len(batch))
248278
copy(files, batch)
249279

280+
// apply to the pipeline
250281
fg.Go(func() error {
251282
if err := pipeline.Apply(ctx, files); err != nil {
252283
return err
@@ -257,10 +288,12 @@ func applyFormatters(ctx context.Context) func() error {
257288
return nil
258289
})
259290

291+
// reset the batch
260292
batches[key] = batch[:0]
261293
}
262294
}
263295

296+
// format any partial batches
264297
flushBatches := func() {
265298
for key, pipeline := range pipelines {
266299

@@ -287,6 +320,7 @@ func applyFormatters(ctx context.Context) func() error {
287320
close(processedCh)
288321
}()
289322

323+
// iterate the files channel, checking if any pipeline wants it, and attempting to apply if so.
290324
for file := range filesCh {
291325
var matched bool
292326
for key, pipeline := range pipelines {
@@ -299,6 +333,7 @@ func applyFormatters(ctx context.Context) func() error {
299333
if matched {
300334
stats.Add(stats.Matched, 1)
301335
} else {
336+
// no match, so we send it direct to the processed channel
302337
processedCh <- file
303338
}
304339
}

0 commit comments

Comments
 (0)