Coverage for circular_deps / resolvers / go.py: 94%

51 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-08 15:04 -0800

1from __future__ import annotations 

2 

3import os 

4 

5from circular_deps.resolvers.base import PathResolver 

6 

7 

8class GoPathResolver(PathResolver): 

9 _STDLIB_PACKAGES = { 

10 "fmt", 

11 "os", 

12 "io", 

13 "net", 

14 "http", 

15 "strings", 

16 "bytes", 

17 "strconv", 

18 "math", 

19 "time", 

20 "encoding/json", 

21 "encoding/xml", 

22 "context", 

23 "sync", 

24 "log", 

25 "path/filepath", 

26 "path", 

27 } 

28 

29 def resolve(self, module, current_file, root_dir): 

30 if self._is_stdlib(module): 

31 return None 

32 

33 return self._resolve_local(module, current_file, root_dir) 

34 

35 def _is_stdlib(self, module): 

36 for pkg in self._STDLIB_PACKAGES: 

37 if module == pkg or module.startswith(pkg + "/"): 

38 return True 

39 return False 

40 

41 def _resolve_local(self, module, current_file, root_dir): 

42 module_path = module.replace("/", os.sep) 

43 current_dir = os.path.dirname(current_file) 

44 

45 target_path = os.path.join(root_dir, module_path) 

46 resolved = self._find_go_file(target_path, root_dir) 

47 if resolved: 

48 return resolved 

49 

50 parent_dir = os.path.dirname(current_dir) 

51 while parent_dir.startswith(root_dir): 

52 target_path = os.path.join(parent_dir, module_path) 

53 resolved = self._find_go_file(target_path, root_dir) 

54 if resolved: 

55 return resolved 

56 parent_dir = os.path.dirname(parent_dir) 

57 

58 return None 

59 

60 def _find_go_file(self, target_path, root_dir): 

61 if not os.path.exists(target_path): 

62 return None 

63 

64 if os.path.isfile(target_path) and target_path.endswith(".go"): 

65 return self._check_under_root(target_path, root_dir) 

66 

67 if os.path.isdir(target_path): 

68 go_files = [f for f in os.listdir(target_path) if f.endswith(".go")] 

69 if go_files: 

70 for go_file in go_files: 

71 file_path = os.path.join(target_path, go_file) 

72 if os.path.isfile(file_path): 

73 return self._check_under_root(file_path, root_dir) 

74 

75 go_file = target_path + ".go" 

76 if os.path.isfile(go_file): 

77 return self._check_under_root(go_file, root_dir) 

78 

79 return None 

80 

81 def _check_under_root(self, path, root_dir): 

82 abs_path = os.path.abspath(path) 

83 abs_root = os.path.abspath(root_dir) 

84 if abs_path.startswith(abs_root): 

85 return abs_path 

86 return None