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
« 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.
16import os 1ah
17import sys 1ah
19from .. import context, robotapi, utils 1ah
20from ..utils.versioncomparator import cmp_versions 1ah
21from .iteminfo import _XMLKeywordContent 1ah
24class SpecInitializer(object): 1ah
26 def __init__(self, directories=None): 1ah
27 self._directories = directories or [] 1a./:;=?@[]^_`{|}BoprstC
28 self._directories.append(context.LIBRARY_XML_DIRECTORY) 1a./:;=?@[]^_`{|}BoprstC
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
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
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
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
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
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
73 def _find_from_pythonpath(self, name): 1ah
74 return utils.find_from_pythonpath(name + '.xml') 1aljicbdefgopmnk
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 []
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
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
106def _is_library_by_path(path): 1ah
107 return path.lower().endswith(('.py', '.java', '.class', '/', os.sep)) 1aDEluvwFGHjIxiyJKLMNOPQRSTUVWXYZ0123456789!#qzc$%'()*+bdeAfgB,mnk-
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
124def _get_library_name(name): 1ah
125 if os.path.exists(name):
126 return name
127 return name.replace(' ', '')
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