99 "log"
1010 "os"
1111 "os/exec"
12- "path/filepath"
1312 "strings"
1413 "sync"
1514 "time"
@@ -91,64 +90,61 @@ func newPython3Parser(
9190 }
9291}
9392
94- // parseAll parses all provided Python files by consecutively calling p.parse.
95- func (p * python3Parser ) parseAll (pyFilepaths * treeset.Set ) (* treeset.Set , error ) {
96- allModules := treeset .NewWith (moduleComparator )
97- it := pyFilepaths .Iterator ()
98- for it .Next () {
99- modules , err := p .parse (it .Value ().(string ))
100- if err != nil {
101- return nil , err
102- }
103- modulesIt := modules .Iterator ()
104- for modulesIt .Next () {
105- allModules .Add (modulesIt .Value ())
106- }
107- }
108- return allModules , nil
93+ // parseSingle parses a single Python file and returns the extracted modules
94+ // from the import statements as well as the parsed comments.
95+ func (p * python3Parser ) parseSingle (pyFilename string ) (* treeset.Set , error ) {
96+ pyFilenames := treeset .NewWith (godsutils .StringComparator )
97+ pyFilenames .Add (pyFilename )
98+ return p .parse (pyFilenames )
10999}
110100
111- // parse parses a Python file and returns the extracted modules from the import
112- // statements. An error is raised if communicating with the long-lived Python
113- // parser over stdin and stdout fails.
114- func (p * python3Parser ) parse (pyFilepath string ) (* treeset.Set , error ) {
101+ // parse parses multiple Python files and returns the extracted modules from
102+ // the import statements as well as the parsed comments.
103+ func (p * python3Parser ) parse (pyFilenames * treeset.Set ) (* treeset.Set , error ) {
115104 parserMutex .Lock ()
116105 defer parserMutex .Unlock ()
117106
118107 modules := treeset .NewWith (moduleComparator )
119108
120- relFilepath := filepath .Join (p .relPackagePath , pyFilepath )
121- absFilepath := filepath .Join (p .repoRoot , relFilepath )
122- fmt .Fprintln (parserStdin , absFilepath )
109+ req := map [string ]interface {}{
110+ "repo_root" : p .repoRoot ,
111+ "rel_package_path" : p .relPackagePath ,
112+ "filenames" : pyFilenames .Values (),
113+ }
114+ encoder := json .NewEncoder (parserStdin )
115+ if err := encoder .Encode (& req ); err != nil {
116+ return nil , fmt .Errorf ("failed to parse: %w" , err )
117+ }
118+
123119 reader := bufio .NewReader (parserStdout )
124120 data , err := reader .ReadBytes (0 )
125121 if err != nil {
126- return nil , fmt .Errorf ("failed to parse %s : %w" , pyFilepath , err )
122+ return nil , fmt .Errorf ("failed to parse: %w" , err )
127123 }
128124 data = data [:len (data )- 1 ]
129- var res parserResponse
130- if err := json .Unmarshal (data , & res ); err != nil {
131- return nil , fmt .Errorf ("failed to parse %s : %w" , pyFilepath , err )
125+ var allRes [] parserResponse
126+ if err := json .Unmarshal (data , & allRes ); err != nil {
127+ return nil , fmt .Errorf ("failed to parse: %w" , err )
132128 }
133129
134- annotations := annotationsFromComments (res .Comments )
135-
136- for _ , m := range res .Modules {
137- // Check for ignored dependencies set via an annotation to the Python
138- // module.
139- if annotations .ignores (m .Name ) {
140- continue
141- }
130+ for _ , res := range allRes {
131+ annotations := annotationsFromComments (res .Comments )
142132
143- // Check for ignored dependencies set via a Gazelle directive in a BUILD
144- // file.
145- if p .ignoresDependency (m .Name ) {
146- continue
147- }
133+ for _ , m := range res .Modules {
134+ // Check for ignored dependencies set via an annotation to the Python
135+ // module.
136+ if annotations .ignores (m .Name ) {
137+ continue
138+ }
148139
149- m .Filepath = relFilepath
140+ // Check for ignored dependencies set via a Gazelle directive in a BUILD
141+ // file.
142+ if p .ignoresDependency (m .Name ) {
143+ continue
144+ }
150145
151- modules .Add (m )
146+ modules .Add (m )
147+ }
152148 }
153149
154150 return modules , nil
@@ -173,17 +169,7 @@ type module struct {
173169 // The line number where the import happened.
174170 LineNumber uint32 `json:"lineno"`
175171 // The path to the module file relative to the Bazel workspace root.
176- Filepath string
177- }
178-
179- // path returns the replaced dots with the os-specific path separator.
180- func (m * module ) path () string {
181- return filepath .Join (strings .Split (m .Name , "." )... )
182- }
183-
184- // bazelPath returns the replaced dots with forward slashes.
185- func (m * module ) bazelPath () string {
186- return strings .ReplaceAll (m .Name , "." , "/" )
172+ Filepath string `json:"filepath"`
187173}
188174
189175// moduleComparator compares modules by name.
0 commit comments