Coverage for src/robotide/spec/xmlreaders.py: 64%

92 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-06 10:40 +0100

1# Copyright 2008-2015 Nokia Networks 

2# Copyright 2016- Robot Framework Foundation 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

13# See the License for the specific language governing permissions and 

14# limitations under the License. 

15 

16import os 1ah

17import sys 1ah

18 

19from .. import context, robotapi, utils 1ah

20from ..utils.versioncomparator import cmp_versions 1ah

21from .iteminfo import _XMLKeywordContent 1ah

22 

23 

24class SpecInitializer(object): 1ah

25 

26 def __init__(self, directories=None): 1ah

27 self._directories = directories or [] 1a./:;=?@[]^_`{|}BoprstC

28 self._directories.append(context.LIBRARY_XML_DIRECTORY) 1a./:;=?@[]^_`{|}BoprstC

29 

30 def init_from_spec(self, name): 1ah

31 specfile = self._find_from_pythonpath(name) or \ 1aljicbdefgoprstCmnk

32 self._find_from_library_xml_directories(name) 

33 return self._init_from_specfile(specfile, name) 1aljicbdefgoprstCmnk

34 

35 def _find_from_library_xml_directories(self, name): 1ah

36 for directory in self._directories: 1aljicbdefgrstnk

37 path = self._find_from_library_xml_directory(directory, name) 1aljicbdefgrstnk

38 if path: 1aljicbdefgrstnk

39 return path 1rs

40 return None 1aljicbdefgtnk

41 

42 def _find_from_library_xml_directory(self, directory, name): 1ah

43 current_xml_file = None 1aljicbdefgnk

44 for xml_file in self._list_xml_files_in(directory): 44 ↛ 45line 44 didn't jump to line 45 because the loop on line 44 never started1aljicbdefgnk

45 name_from_xml = get_name_from_xml(xml_file) 

46 if name_from_xml == name: 

47 current_xml_file = self._get_newest_xml_file( 

48 xml_file, current_xml_file) 

49 return current_xml_file 1aljicbdefgnk

50 

51 def _get_newest_xml_file(self, xml_file, current_xml_file): 1ah

52 version1 = self._get_version(xml_file) 

53 version2 = self._get_version(current_xml_file) 

54 if cmp_versions(version1, version2) == 1: 

55 return xml_file 

56 return current_xml_file 

57 

58 @staticmethod 1ah

59 def _get_version(xml_file): 1ah

60 try: 

61 return utils.ET.parse(xml_file).getroot().find('version').text 

62 except Exception as e: 

63 print(e) 

64 return None 

65 

66 @staticmethod 1ah

67 def _list_xml_files_in(directory): 1ah

68 for filename in os.listdir(directory): 68 ↛ 69line 68 didn't jump to line 69 because the loop on line 68 never started1aljicbdefgnk

69 path = os.path.join(directory, filename) 

70 if path.endswith('.xml') and os.path.isfile(path): 

71 yield path 

72 

73 def _find_from_pythonpath(self, name): 1ah

74 return utils.find_from_pythonpath(name + '.xml') 1aljicbdefgopmnk

75 

76 def _init_from_specfile(self, specfile, name): 1ah

77 if not specfile: 1aljicbdefgopmnk

78 return [] 1aljicbdefgnk

79 try: 1acbegopm

80 return _parse_xml(specfile, name) 1acbegopm

81 except Exception as e: 

82 # DEBUG: which exception to catch? 

83 print(e) 

84 return [] 

85 

86 

87def _parse_xml(file, name): 1ah

88 root = utils.ET.parse(file).getroot() 1acbegopm

89 if root.tag != 'keywordspec': 89 ↛ 91line 89 didn't jump to line 91 because the condition on line 89 was never true1acbegopm

90 # DEBUG: XML validation errors should be logged 

91 return [], '' 

92 kw_nodes = root.findall('keywords/kw') + root.findall('kw') 1acbegopm

93 source_type = root.get('type') 1acbegopm

94 doc_format = root.get('format') 1acbegopm

95 if source_type == 'resource': 95 ↛ 96line 95 didn't jump to line 96 because the condition on line 95 was never true1acbegopm

96 source_type += ' file' 

97 return [_XMLKeywordContent(node, name, source_type, doc_format) for node in kw_nodes] 1acbegopm

98 

99 

100def get_path(name, basedir): 1ah

101 if not _is_library_by_path(name): 1aDEluvwFGHjIxiyJKLMNOPQRSTUVWXYZ0123456789!#qzc$%'()*+bdeAfgB,mnk-

102 return name.replace(' ', '') 1aDElFGHIJKLMNOPQRSTUVWXYZ0123456789!#qc$%'()*+bdefgB,mn-

103 return _resolve_path(name.replace('/', os.sep), basedir) 1auvwjxiyqzbdAfk

104 

105 

106def _is_library_by_path(path): 1ah

107 return path.lower().endswith(('.py', '.java', '.class', '/', os.sep)) 1aDEluvwFGHjIxiyJKLMNOPQRSTUVWXYZ0123456789!#qzc$%'()*+bdeAfgB,mnk-

108 

109 

110def _resolve_path(path, basedir): 1ah

111 for base in [basedir] + sys.path: 1auvwjxiyqzbdAfk

112 if not (base and os.path.isdir(base)): 1auvwjxiyqzbdAfk

113 continue 1iqbdf

114 ret = os.path.join(base, path) 1auvwjxiyqzbdAfk

115 if os.path.isfile(ret): 1auvwjxiyqzbdAfk

116 return ret 1auvwjxyqzbdAfk

117 if os.path.isdir(ret) and \ 117 ↛ 119line 117 didn't jump to line 119 because the condition on line 117 was never true1aiqbdf

118 os.path.isfile(os.path.join(ret, '__init__.py')): 

119 return ret 

120 return None 1aiqbdf

121 # DEBUG raise robotapi.DataError 

122 

123 

124def _get_library_name(name): 1ah

125 if os.path.exists(name): 

126 return name 

127 return name.replace(' ', '') 

128 

129 

130def get_name_from_xml(path): 1ah

131 try: 

132 root = utils.ET.parse(path).getroot() 

133 name = root.get('name') 

134 return name 

135 except Exception as e: 

136 print(e) 

137 return None