11/*
2- * Copyright (C) 2018-2024 smart-doc
2+ * Copyright (C) 2018-2025 smart-doc
33 *
44 * Licensed to the Apache Software Foundation (ASF) under one
55 * or more contributor license agreements. See the NOTICE file
3434import com .ly .doc .model .grpc .GrpcApiDoc ;
3535import com .ly .doc .model .grpc .GrpcJavaMethod ;
3636import com .ly .doc .model .grpc .ProtoInfo ;
37- import com .ly .doc .model .grpc .proto .*;
37+ import com .ly .doc .model .grpc .proto .EnumDefinition ;
38+ import com .ly .doc .model .grpc .proto .EnumValue ;
39+ import com .ly .doc .model .grpc .proto .Message ;
40+ import com .ly .doc .model .grpc .proto .MessageField ;
41+ import com .ly .doc .model .grpc .proto .ProtoJson ;
42+ import com .ly .doc .model .grpc .proto .Service ;
43+ import com .ly .doc .model .grpc .proto .ServiceMethod ;
3844import com .ly .doc .utils .DocUtil ;
3945import com .power .common .util .FileUtil ;
4046import com .thoughtworks .qdox .model .JavaClass ;
4147
42- import java .io .*;
48+ import java .io .BufferedReader ;
49+ import java .io .File ;
50+ import java .io .IOException ;
51+ import java .io .InputStream ;
52+ import java .io .InputStreamReader ;
4353import java .nio .file .Files ;
4454import java .nio .file .Path ;
4555import java .nio .file .Paths ;
4656import java .nio .file .StandardCopyOption ;
4757import java .nio .file .attribute .PosixFilePermissions ;
48- import java .util .*;
58+ import java .util .ArrayList ;
59+ import java .util .Collection ;
60+ import java .util .Collections ;
61+ import java .util .HashSet ;
62+ import java .util .List ;
63+ import java .util .Map ;
64+ import java .util .Objects ;
65+ import java .util .Set ;
4966import java .util .concurrent .atomic .AtomicInteger ;
5067import java .util .function .Consumer ;
5168import java .util .function .Function ;
@@ -344,7 +361,8 @@ private void executeCommand(List<String> command, ProtoInfo protoInfo) {
344361 try {
345362 Process process = processBuilder .start ();
346363
347- StreamGobbler outputGobbler = new StreamGobbler (process .getInputStream (), log ::warning );
364+ StreamGobbler outputGobbler = new StreamGobbler (process .getInputStream (),
365+ line -> log .warning ("[protoc] " + line ));
348366 Thread outputThread = new Thread (outputGobbler );
349367 outputThread .start ();
350368
@@ -354,7 +372,7 @@ private void executeCommand(List<String> command, ProtoInfo protoInfo) {
354372 outputThread .join ();
355373
356374 if (exitCode != 0 ) {
357- log .warning ("Error executing command for files" );
375+ log .warning ("protoc command failed with exit code: " + exitCode );
358376 }
359377 }
360378 catch (IOException | InterruptedException e ) {
@@ -370,23 +388,75 @@ private void executeCommand(List<String> command, ProtoInfo protoInfo) {
370388 */
371389 private List <String > buildProtocCommand (Set <String > protoFiles , ProtoInfo protoInfo ) {
372390 List <String > command = new ArrayList <>();
373- command .add (protoInfo .getProtocPath ());
374- command .add ("--proto_path=" + String .join (";" , this .getUniqueParentDirectories (protoFiles )));
375- command .add ("--doc_out=" + protoInfo .getTargetJsonDirectoryPath ());
391+
392+ // Add the protoc executable (using absolute path)
393+ command .add (Paths .get (protoInfo .getProtocPath ()).toAbsolutePath ().toString ());
394+
395+ // Calculate the common root directory for all .proto files
396+ Set <String > commonRoots = this .getUniqueParentDirectories (protoFiles );
397+ if (commonRoots .isEmpty ()) {
398+ log .warning ("No common root directory found for proto files." );
399+ return Collections .emptyList ();
400+ }
401+ String commonRootPath = commonRoots .iterator ().next ();
402+
403+ // Set --proto_path to the common root directory
404+ command .add ("--proto_path=" + commonRootPath );
405+
406+ // Set output options
407+ command .add ("--doc_out=" + Paths .get (protoInfo .getTargetJsonDirectoryPath ()).toAbsolutePath ());
376408 command .add ("--doc_opt=json," + protoInfo .getJsonName ());
377- command .addAll (protoFiles );
378- command .add ("--plugin=protoc-gen-doc=" + protoInfo .getProtocGenDocPath ());
409+
410+ // Set the plugin path (using absolute path)
411+ command .add ("--plugin=protoc-gen-doc=" + Paths .get (protoInfo .getProtocGenDocPath ()).toAbsolutePath ());
412+
413+ // Add the absolute paths of the .proto files
414+ for (String filePath : protoFiles ) {
415+ Path file = Paths .get (filePath ).toAbsolutePath ().normalize ();
416+ command .add (file .toString ());
417+ }
418+
379419 return command ;
380420 }
381421
382422 /**
383- * Get the unique parent directories of the given set of files.
384- * @param files The set of files.
385- * @return The set of unique parent directories.
423+ * Get the unique parent directories of the given set of files. This method finds the
424+ * deepest common ancestor directory among all proto files.
425+ * @param files The set of .proto file paths.
426+ * @return The set containing the common root directory path.
386427 */
387428 private Set <String > getUniqueParentDirectories (Set <String > files ) {
429+ if (files .isEmpty ()) {
430+ return Collections .emptySet ();
431+ }
432+
433+ // Convert all paths to Path objects
434+ List <Path > filePaths = files .stream ()
435+ .map (Paths ::get )
436+ .map (Path ::toAbsolutePath )
437+ .map (Path ::normalize )
438+ .collect (Collectors .toList ());
439+
440+ // Use the first path as the initial common root
441+ Path commonRoot = filePaths .get (0 );
442+
443+ // Compare with all other paths, gradually shorten commonRoot until it is a prefix
444+ // of all paths
445+ for (Path path : filePaths ) {
446+ while (!path .startsWith (commonRoot )) {
447+ commonRoot = commonRoot .getParent ();
448+ if (commonRoot == null ) {
449+ // If we've gone up to null, there's no common parent, return the root
450+ // of the path
451+ commonRoot = path .getRoot ();
452+ break ;
453+ }
454+ }
455+ }
456+
457+ // Return the found common root directory
388458 Set <String > directories = new HashSet <>();
389- files . forEach ( file -> directories .add (new File ( file ). getParent () ));
459+ directories .add (commonRoot . toString ( ));
390460 return directories ;
391461 }
392462
0 commit comments