buildframework/helium/sf/python/pythoncore/lib/archive/scanners.py
changeset 587 85df38eb4012
child 628 7c4a911dc066
equal deleted inserted replaced
217:0f5e3a7fb6af 587:85df38eb4012
       
     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