sbsv2/raptor/python/plugins/filter_copyfile.py
branchfix
changeset 547 9fe7d0ab0f8f
parent 537 164e587fef9f
child 549 d633be326c9f
equal deleted inserted replaced
546:e6381a1f4952 547:9fe7d0ab0f8f
     1 #
     1 #
     2 # Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 # Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 # All rights reserved.
     3 # All rights reserved.
     4 # This component and the accompanying materials are made available
     4 # This component and the accompanying materials are made available
     5 # under the terms of the License "Eclipse Public License v1.0"
     5 # under the terms of the License "Eclipse Public License v1.0"
     6 # which accompanies this distribution, and is available
     6 # which accompanies this distribution, and is available
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
    13 #
    13 #
    14 # Description: 
    14 # Description: 
    15 # Filter class for copying files in serial in python. This
    15 # Filter class for copying files in serial in python. This
    16 # is important in cluster builds where file copying is 
    16 # is important in cluster builds where file copying is 
    17 # very inefficient.  
    17 # very inefficient.  
    18 # The one-to-many <copy> tag is searched for and copy
    18 # The one-to-many <finalcopy> tag is searched for and copy
    19 # instructions are built up in a hash table.
    19 # instructions are built up in a hash table.
    20 # <copy source='sourcefilename'>destfilename1 destfilename2 . . . .destfilenameN</copy>
    20 # <finalcopy source='sourcefilename'>destfilename1 destfilename2 . . . .destfilenameN</copy>
    21 # destinations must be full filenames not directories.
    21 # destinations must be full filenames not directories.
    22 #
    22 #
    23 # This filter monitors build progress
    23 # This filter monitors build progress
    24 # via the <progress> tags and flushes copies as build 
    24 # via the <progress> tags and flushes copies as build 
    25 # stages end (e.g. after resource so resources are ready for the next stage)
    25 # stages end (e.g. after resource so resources are ready for the next stage)
    30 import tempfile
    30 import tempfile
    31 import filter_interface
    31 import filter_interface
    32 import shutil
    32 import shutil
    33 import generic_path
    33 import generic_path
    34 import stat
    34 import stat
       
    35 from raptor_utilities import copyfile
    35 
    36 
    36 class FilterCopyFile(filter_interface.Filter):
    37 class FilterCopyFile(filter_interface.Filter):
    37 	
    38 	
    38 	def open(self, params):
    39 	def open(self, params):
    39 		"initialise"
    40 		"initialise"
    47 	
    48 	
    48 	def write(self, text):
    49 	def write(self, text):
    49 		"process some log text"
    50 		"process some log text"
    50 		
    51 		
    51 		for line in text.splitlines():
    52 		for line in text.splitlines():
    52 			if line.startswith("<copy"):
    53 			if line.startswith("<finalcopy"):
    53 				source_start=line.find("source='")
    54 				source_start = line.find("source='")
    54 				source=line[source_start+8:line.find("'", source_start+8)]
    55 				source = line[source_start+8:line.find("'", source_start+8)]
    55 				destinations = line[line.find(">",source_start)+1:line.find("</copy>")].split(" ")
    56 				destinations = line[line.find(">",source_start)+1:line.find("</finalcopy>")].split(" ")
    56 
    57 
    57 				if source in self.files:
    58 				if source in self.files:
    58 					self.files[source].update(destinations)
    59 					self.files[source].update(destinations)
    59 				else:
    60 				else:
    60 					self.files[source] = set(destinations)
    61 					self.files[source] = set(destinations)
    61 			elif line.startswith("<progress:end object_type='makefile' task='build'"):
    62 			elif line.startswith("<progress:end object_type='makefile' task='build'"):
    62 				self.flushcopies() # perform copies at end of each invocation of the make engine
    63 				self.flushcopies() # perform copies at end of each invocation of the make engine
    63 						  # to ensure dependencies are in place for the next one.
    64 						   # to ensure dependencies are in place for the next one.
    64 				
    65 				
    65 		return self.ok
    66 		return self.ok
    66 	
    67 	
    67 	
    68 	
    68 	def summary(self):
    69 	def summary(self):
    70 		self.flushcopies()
    71 		self.flushcopies()
    71 		return self.ok
    72 		return self.ok
    72 
    73 
    73 	def flushcopies(self):
    74 	def flushcopies(self):
    74 		for source in self.files.keys():
    75 		for source in self.files.keys():
    75 			#print "<debug>self.files %s</debug>" % self.files[source]
       
    76 			for dest in self.files[source]:
    76 			for dest in self.files[source]:
    77 				self.copyfile(source, dest)
    77 				copyfile(source, dest)
    78 		self.files = {}
    78 		self.files = {}
    79 		
    79 		
    80 
    80 
    81 
    81 
    82 	def close(self):
    82 	def close(self):
    83 		"nop"
    83 		"nop"
    84 		
    84 		
    85 
    85 
    86 		return self.ok
    86 		return self.ok
    87 
    87 
    88 	def copyfile(self, _source, _destination):
       
    89 		"""Copy the source file to the destination file (create a directory
       
    90 		   to copy into if it does not exist). Don't copy if the destination
       
    91 		   file exists and has an equal or newer modification time."""
       
    92 		source = generic_path.Path(str(_source).replace('%20',' '))
       
    93 		destination = generic_path.Path(str(_destination).replace('%20',' '))
       
    94 		dest_str = str(destination)
       
    95 		source_str = str(source)
       
    96 
       
    97 		try:
       
    98 
       
    99 
       
   100 			destDir = destination.Dir()
       
   101 			if not destDir.isDir():
       
   102 				os.makedirs(str(destDir))
       
   103 				shutil.copyfile(source_str, dest_str)
       
   104 				return 
       
   105 
       
   106 			# Destination file exists so we have to think about updating it
       
   107 			sourceMTime = 0
       
   108 			destMTime = 0
       
   109 			sourceStat = 0
       
   110 			try:
       
   111 				sourceStat = os.stat(source_str)
       
   112 				sourceMTime = sourceStat[stat.ST_MTIME]
       
   113 				destMTime = os.stat(dest_str)[stat.ST_MTIME]
       
   114 			except OSError, e:
       
   115 				if sourceMTime == 0:
       
   116 					message = "Source of copyfile does not exist:  " + str(source)
       
   117 					print message
       
   118 
       
   119 			if destMTime == 0 or destMTime < sourceMTime:
       
   120 				if os.path.exists(dest_str):
       
   121 					os.chmod(dest_str,stat.S_IREAD | stat.S_IWRITE)
       
   122 				shutil.copyfile(source_str, dest_str)
       
   123 
       
   124 				# Ensure that the destination file remains executable if the source was also:
       
   125 				os.chmod(dest_str,sourceStat[stat.ST_MODE] | stat.S_IREAD | stat.S_IWRITE | stat.S_IWGRP ) 
       
   126 
       
   127 
       
   128 		except Exception,e:
       
   129 			message = "Could not export " + source_str + " to " + dest_str + " : " + str(e)
       
   130 
       
   131 		return 
       
   132 	
       
   133 # the end				
    88 # the end				
   134 
    89