11package walk
22
33import (
4- "bufio"
5- "context"
64 "fmt"
7- "io"
8- "os"
9- "os/exec"
10- "path/filepath"
115
12- "charm.land/log/v2"
136 "github.com/numtide/treefmt/v2/jujutsu"
147 "github.com/numtide/treefmt/v2/stats"
15- "golang.org/x/sync/errgroup"
168)
179
18- type JujutsuReader struct {
19- root string
20- path string
21-
22- log * log.Logger
23- stats * stats.Stats
24-
25- eg * errgroup.Group
26- scanner * bufio.Scanner
27- }
28-
29- func (j * JujutsuReader ) Read (ctx context.Context , files []* File ) (n int , err error ) {
30- // ensure we record how many files we traversed
31- defer func () {
32- j .stats .Add (stats .Traversed , n )
33- }()
34-
35- nextLine := func () string {
36- line := j .scanner .Text ()
37-
38- return line
39- }
40-
41- LOOP:
42-
43- for n < len (files ) {
44- select {
45- // exit early if the context was cancelled
46- case <- ctx .Done ():
47- return n , ctx .Err () //nolint:wrapcheck
48-
49- default :
50- // read the next file
51- if j .scanner .Scan () {
52- entry := nextLine ()
53-
54- path := filepath .Join (j .root , entry )
55-
56- j .log .Debugf ("processing file: %s" , path )
57-
58- info , err := os .Lstat (path )
59-
60- switch {
61- case os .IsNotExist (err ):
62- // the underlying file might have been removed
63- j .log .Warnf (
64- "Path %s is in the worktree but appears to have been removed from the filesystem" , path ,
65- )
66-
67- continue
68- case err != nil :
69- return n , fmt .Errorf ("failed to stat %s: %w" , path , err )
70- case info .Mode ()& os .ModeSymlink == os .ModeSymlink :
71- // we skip reporting symlinks stored in Jujutsu, they should
72- // point to local files which we would list anyway.
73- continue
74- }
75-
76- files [n ] = & File {
77- Path : path ,
78- RelPath : entry ,
79- Info : info ,
80- }
81-
82- n ++
83- } else {
84- // nothing more to read
85- err = io .EOF
86-
87- break LOOP
88- }
89- }
90- }
91-
92- return n , err
93- }
94-
95- func (j * JujutsuReader ) Close () error {
96- err := j .eg .Wait ()
97- if err != nil {
98- return fmt .Errorf ("failed to wait for jujutsu command to complete: %w" , err )
99- }
100-
101- return nil
102- }
10+ type JujutsuReader = PathStreamReader
10311
10412func NewJujutsuReader (
10513 root string ,
106- path string ,
14+ pathFilters [] string ,
10715 statz * stats.Stats ,
10816) (* JujutsuReader , error ) {
10917 // check if the root is a jujutsu repository
@@ -116,42 +24,13 @@ func NewJujutsuReader(
11624 return nil , fmt .Errorf ("%s is not a jujutsu repository" , root )
11725 }
11826
119- // create an errgroup for async list task
120- eg := & errgroup.Group {}
121-
122- // create a pipe to capture the command output
123- r , w := io .Pipe ()
124-
125- // create a command which will execute from root
12627 // --ignore-working-copy: Don't snapshot the working copy, and don't update it. This prevents that the user has to
12728 // enter a password for signing the commit. New files also won't be added to the index and not displayed in the
12829 // output.
129- // Add the subpath as a fileset displaying only files matching this prefix. If
130- // the subpath is empty ignore it since it interferes with the command
131- args := []string {"file" , "list" , "--ignore-working-copy" }
132- if path != "" {
133- args = append (args , path )
134- }
135-
136- // create the jj command
137- cmd := exec .CommandContext (context .Background (), "jj" , args ... )
138- cmd .Dir = root
139- cmd .Stdout = w
140-
141- // execute the command in the background
142- eg .Go (func () error {
143- return w .CloseWithError (cmd .Run ())
30+ return NewPathStreamReader (root , statz , PathStreamConfig {
31+ Name : "jujutsu" ,
32+ Command : "jj" ,
33+ Options : []string {"file" , "list" , "--ignore-working-copy" , "--" },
34+ PathFilters : pathFilters ,
14435 })
145-
146- // create a new scanner for reading the output
147- scanner := bufio .NewScanner (r )
148-
149- return & JujutsuReader {
150- eg : eg ,
151- root : root ,
152- path : path ,
153- stats : statz ,
154- scanner : scanner ,
155- log : log .WithPrefix ("walk | jujutsu" ),
156- }, nil
15736}
0 commit comments