|
1 #============================================================================ |
|
2 #Name : scanners.py |
|
3 #Part of : Helium |
|
4 |
|
5 #Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
6 #All rights reserved. |
|
7 #This component and the accompanying materials are made available |
|
8 #under the terms of the License "Eclipse Public License v1.0" |
|
9 #which accompanies this distribution, and is available |
|
10 #at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
11 # |
|
12 #Initial Contributors: |
|
13 #Nokia Corporation - initial contribution. |
|
14 # |
|
15 #Contributors: |
|
16 # |
|
17 #Description: |
|
18 #=============================================================================== |
|
19 |
|
20 """ Implementation of the available scanner for """ |
|
21 |
|
22 import os |
|
23 import fileutils |
|
24 import selectors |
|
25 import logging |
|
26 import codecs |
|
27 import pathaddition |
|
28 |
|
29 _logger = logging.getLogger('archive.scanners') |
|
30 _logger_abld = logging.getLogger('archive.scanners.abld') |
|
31 logging.basicConfig() |
|
32 #logger_abld.setLevel(logging.DEBUG) |
|
33 |
|
34 class Scanner(fileutils.AbstractScanner): |
|
35 """ Abstract class that represent and input source. """ |
|
36 |
|
37 def __init__(self, config): |
|
38 fileutils.AbstractScanner.__init__(self) |
|
39 self._config = config |
|
40 self.setup() |
|
41 |
|
42 def setup(self): |
|
43 """ Setting up the scanner. """ |
|
44 [self.add_include(inc) for inc in self._config.get_list('include', [])] |
|
45 [self.add_exclude(ex) for ex in self._config.get_list('exclude', [])] |
|
46 [self.add_exclude_file(ex) for ex in self._config.get_list('exclude_file', [])] |
|
47 [self.add_exclude_lst(filename) for filename in self._config.get_list('exclude.lst', [])] |
|
48 [self.add_filetype(filetype) for filetype in self._config.get_list('filetype', [])] |
|
49 [self.add_selector(selectors.get_selector(selector, self._config)) for selector in self._config.get_list('selector', [])] |
|
50 # To support old features. |
|
51 # TODO: inform customers and remove. |
|
52 if 'distribution.policy.s60' in self._config: |
|
53 self.add_selector(selectors.get_selector('distribution.policy.s60', self._config)) |
|
54 |
|
55 def add_exclude_lst(self, filename): |
|
56 """ Adding excludes from exclude list. """ |
|
57 if not os.path.exists(filename): |
|
58 raise Exception("Could not find '%s'." % filename) |
|
59 root_dir = os.path.normpath(self._config['root.dir']) |
|
60 flh = codecs.open(filename, 'r', 'utf-8') |
|
61 for line in flh: |
|
62 path = os.path.normpath(line.strip()) |
|
63 if os.path.splitdrive(root_dir)[0] != "": |
|
64 path = os.path.join(os.path.splitdrive(root_dir)[0], path) |
|
65 if fileutils.destinsrc(root_dir, path): |
|
66 pathrel = pathaddition.relative.abs2rel(path, root_dir) |
|
67 _logger.debug("pathrel: %s" % (pathrel)) |
|
68 self.add_exclude(pathrel) |
|
69 else: |
|
70 _logger.warning("path '%s' is not under '%s', ignoring." % (path, root_dir)) |
|
71 flh.close() |
|
72 |
|
73 def scan(self): |
|
74 """ Generator method that scan the relevant input source. |
|
75 This method need to be overloaded by the specialized class. |
|
76 return fullpath name |
|
77 """ |
|
78 raise NotImplementedError() |
|
79 |
|
80 |
|
81 class AbldWhatScanner(Scanner): |
|
82 """ Scanning the filesystem. """ |
|
83 |
|
84 def __init__(self, config): |
|
85 Scanner.__init__(self, config) |
|
86 self.root_dir = unicode(os.path.normpath(self._config['root.dir'])) |
|
87 |
|
88 def scan(self): |
|
89 """ |
|
90 Abld what commands. |
|
91 include property have not effect on the selection mechanism. |
|
92 """ |
|
93 os.environ["SYMBIANBUILD_DEPENDENCYOFF"] = "1" |
|
94 for path in self._config.get_list('abld.exportpath', []): |
|
95 _logger_abld.debug("abld.exportpath: %s" % path) |
|
96 if os.path.exists(os.path.join(self.root_dir, path, 'bld.inf')): |
|
97 os.chdir(os.path.join(self.root_dir, path)) |
|
98 os.popen('bldmake bldfiles -k') |
|
99 for result in self._scan_abld_what("abld export -what -k"): |
|
100 yield result |
|
101 |
|
102 for path in self._config.get_list('abld.buildpath', []): |
|
103 _logger_abld.debug("abld.buildpath: %s" % path) |
|
104 if os.path.exists(os.path.join(self.root_dir, path, 'bld.inf')): |
|
105 for type_ in self._config.get_list('abld.type', ['armv5']): |
|
106 os.environ["EPOCROOT"] = self._config.get('abld.epocroot','\\') |
|
107 os.environ["PATH"] = os.environ["EPOCROOT"] + "epoc32\\tools;" + os.environ["EPOCROOT"] + "epoc32\\gcc\\bin;" + os.environ["PATH"] |
|
108 _logger_abld.debug("abld.type: %s" % type_) |
|
109 os.chdir(os.path.join(self.root_dir, path)) |
|
110 os.popen("bldmake bldfiles -k") |
|
111 os.popen("abld makefile %s -k" % type_) |
|
112 for result in self._scan_abld_what("abld build -what %s" % type_): |
|
113 yield result |
|
114 |
|
115 def _run_cmd(self, cmd): |
|
116 """ Run command.""" |
|
117 _logger_abld.debug("command: %s" % cmd) |
|
118 process = os.popen(cmd) |
|
119 abld_output = process.read() |
|
120 err = process.close() |
|
121 return (err, abld_output) |
|
122 |
|
123 def _scan_abld_what(self, cmd): |
|
124 """ Abld what output parser.""" |
|
125 (_, abld_output) = self._run_cmd(cmd) |
|
126 _logger_abld.debug("abld_output: %s" % abld_output) |
|
127 for what_path in abld_output.split("\n"): |
|
128 what_path = what_path.strip() |
|
129 if (what_path.startswith('\\') or what_path.startswith('/')) and self.is_filetype(what_path) \ |
|
130 and not self.is_excluded(what_path) and self.is_selected(what_path): |
|
131 if os.path.exists(what_path): |
|
132 _logger_abld.debug("adding: %s" % what_path) |
|
133 yield what_path |
|
134 else: |
|
135 _logger.error("Could not find '%s'." % what_path) |
|
136 |
|
137 |
|
138 class FileSystemScanner(fileutils.FileScanner, Scanner): |
|
139 """ Scanning the filesystem. """ |
|
140 |
|
141 def __init__(self, config): |
|
142 fileutils.FileScanner.__init__(self, unicode(os.path.normpath(config['root.dir']))) |
|
143 Scanner.__init__(self, config) |
|
144 |
|
145 def scan(self): |
|
146 """ |
|
147 Implement the scanning of the filesystem. |
|
148 Actually delegate scanning of a directory to Filescanner. |
|
149 """ |
|
150 for path in fileutils.FileScanner.scan(self): |
|
151 yield path |
|
152 |
|
153 |
|
154 class InputFileScanner(fileutils.FileScanner, Scanner): |
|
155 """ Scanning the filesystem. """ |
|
156 |
|
157 def __init__(self, config): |
|
158 """ Initialisation. """ |
|
159 fileutils.FileScanner.__init__(self, unicode(os.path.normpath(config['root.dir']))) |
|
160 Scanner.__init__(self, config) |
|
161 |
|
162 def scan(self): |
|
163 """ |
|
164 :: |
|
165 |
|
166 <set name="scanners" value="input.file"/> |
|
167 <set name="root.dir" value="${build.drive}"/> |
|
168 <set name="input.files" value="file1.lst,file2.lst,file3.lst"/> |
|
169 <set name="exclude" value="epoc32/**/*.dll"/> |
|
170 """ |
|
171 for input_file in self._config.get_list('input.files', []): |
|
172 _logger.info("Include content from: %s" % input_file) |
|
173 handle = open(input_file, "r") |
|
174 for line in handle.readlines(): |
|
175 path = os.path.join(self._config['root.dir'], line.strip()) |
|
176 if os.path.exists(path): |
|
177 if self.is_filetype(path) \ |
|
178 and not self.is_excluded(path) and self.is_selected(path): |
|
179 yield path |
|
180 else: |
|
181 _logger.info("File not found: %s" % path) |
|
182 handle.close() |
|
183 |
|
184 __scanners = {'default': FileSystemScanner, |
|
185 'input.file': InputFileScanner, |
|
186 'abld.what': AbldWhatScanner, |
|
187 } |
|
188 |
|
189 def get_scanners(names, config): |
|
190 """get scanners""" |
|
191 result = [] |
|
192 for name in names: |
|
193 if name in __scanners: |
|
194 result.append(__scanners[name](config)) |
|
195 else: |
|
196 raise Exception("ERROR: Could not find scanner '%s'." % name) |
|
197 return result |