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

1 from __future__ import annotations

2

3 import os

4

5 from circular_deps.resolvers.base import PathResolver

6

7

8 class 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