コード例 #1
0
ファイル: archive.py プロジェクト: xpybuild/xpybuild
	def run(self, context):
		mkdir(os.path.dirname(self.path))
		alreadyDone = set()
		with zipfile.ZipFile(normLongPath(self.path), 'w') as output:
			for (f, o) in self.inputs.resolveWithDestinations(context):
				# if we don't check for duplicate entries we'll end up creating an invalid zip
				if o in alreadyDone:
					dupsrc = ['"%s"'%src for (src, dest) in self.inputs.resolveWithDestinations(context) if dest == o]
					raise BuildException('Duplicate zip entry "%s" from: %s'%(o, ', '.join(dupsrc)))
				alreadyDone.add(o)
				# can't compress directory entries! (it messes up Java)
				output.write(normLongPath(f).rstrip('/\\'), o, zipfile.ZIP_STORED if isDirPath(f) else zipfile.ZIP_DEFLATED) 
コード例 #2
0
ファイル: archive.py プロジェクト: xpybuild/xpybuild
	def run(self, context):
		self.log.info('Cleaning existing files from %s', self.path)
		deleteDir(self.path)
		
		iswindows = IS_WINDOWS
		
		for a in self.archives:
			a_is_filteredarchivecontents = isinstance(a, FilteredArchiveContents)
			if a_is_filteredarchivecontents:
				items = [(a.getResolvedPath(context), '')]
			else:
				assert isinstance(a, BasePathSet)
				filteredMembers = None
				items = a.resolveWithDestinations(context)
			for (srcAbs, destRel) in items:
				if destRel and not isDirPath(destRel): destRel = os.path.dirname(destRel) # strip off the zip filename
				if '..' in destRel: raise Exception('This target does not permit destination paths to contain ".." relative path expressions')
					
				try:
					filesize = os.path.getsize(srcAbs)
				except Exception:
					filesize = 0
				
				self.log.info("Unpacking %s (%0.1f MB) to %s", os.path.basename(srcAbs), filesize/1024.0/1024, self.name+destRel)
				starttime = time.time()
				with self. __openArchive(srcAbs) as f:
					mkdir(self.path+destRel)
					if a_is_filteredarchivecontents and a.hasIncludeExcludeFilters():
						fullList = _getnames(f)
						if not fullList:
							raise BuildException('No files were found in archive "%s"'%(srcAbs))
						filteredMembers = [x for x in fullList if a.isIncluded(context, x)]
						self.log.info("Unpacking %d of %d members in %s", len(filteredMembers), len(fullList), os.path.basename(srcAbs))
						if not filteredMembers:
							raise BuildException('No files matching the specified include/exclude filters were found in archive "%s": %s'%(srcAbs,  a))
						if len(filteredMembers)==len(fullList):
							raise BuildException('No files were excluded from the unpacking operation by the specified filters (check filters are correct): %s'%a)
					else:
						filteredMembers = _getnames(f)
					# NB: some archive types want a list of string members, others want TarInfo objects etc, so 
					# if we support other archive types in future might need to do a bit of work here
					path = normLongPath(self.path+destRel)
					for m in filteredMembers:						
						if not isDirPath(m):
							info = _getinfo(f, m)
							if a_is_filteredarchivecontents:
								_setfilename(info, a.mapDestPath(context, _getfilename(info)))
							if iswindows: _setfilename(info, _getfilename(info).replace('/', '\\'))
							f.extract(info, path=path)
						else:
							# we should create empty directories too
							if a_is_filteredarchivecontents:
								m = a.mapDestPath(context, m).rstrip('/')

							m = path.rstrip('/\\')+'/'+m
							if iswindows: m = m.replace('/', '\\')
							mkdir(m)
							
				
				self.log.info("Completed unpacking %s (%0.1f MB) in %0.1f seconds", os.path.basename(srcAbs), filesize/1024.0/1024, (time.time()-starttime))
コード例 #3
0
    def updateStampFile(self):
        """
		.. private:: Not useful enough to be in the public API. 
		
		Assumes self.path is a stamp file that just needs creating / timestamp updating and does so """
        path = normLongPath(self.path)
        mkdir(os.path.dirname(path))
        with openForWrite(path, 'wb') as f:
            pass
コード例 #4
0
def jar(path, manifest, sourcedir, options, preserveManifestFormatting=False, update=False, outputHandler=None):
	""" Create a jar file containing a manifest and some other files

	@param path: jar file to create. Typically this file does not already exist, but if it does 
	then the specified files or manifest will be merged into it. 
	
	@param manifest: path to the manifest.mf file (or None to disable manifest entirely)

	@param sourcedir: the directory to pack everything from (this method may add extra files to this dir)

	@param options: options map. jar.options is a list of additional arguments

	@param preserveManifestFormatting: an advanced option that prevents that jar executable from 
	reformatting the specified manifest file to comply with Java conventions 
	(also prevents manifest merging if jar already exists)
	"""
	# work out if we need to create a parent directory
	dir = os.path.dirname(path)
	if dir and not os.path.exists(dir): mkdir(dir)
	# location of jar
	if options['java.home']:
		binary = os.path.join(options['java.home'], "bin/jar")
	else:
		binary = "jar"
	# build up arguments
	args = [binary]
	args.extend(options['jar.options'])

	if update:
		mode='-u'
	else:
		mode='-c'
	
	if not manifest: 
		args.extend([mode+"fM", path])
	elif preserveManifestFormatting:
		mkdir(sourcedir+'/META-INF')
		srcf = normLongPath(sourcedir+'/META-INF/manifest.mf')

		with open(manifest, 'rb') as s:
			with openForWrite(srcf, 'wb') as d:
				d.write(s.read())
		args.extend([mode+"f", path])
	else:
		args.extend([mode+"fm", path, manifest])

	if sourcedir: 
		args.extend(["-C", sourcedir, "."])


	# actually call jar
	call(args, outputHandler=outputHandler, timeout=options['process.timeout'])
コード例 #5
0
ファイル: writefile.py プロジェクト: xpybuild/xpybuild
    def run(self, context):
        contents = self._getContents(context)

        mkdir(os.path.dirname(self.path))
        path = normLongPath(self.path)
        with self.openFile(context,
                           path,
                           'wb' if isinstance(contents, bytes) else 'w',
                           encoding=self.__encoding) as f:
            f.write(contents)

        if self.__mode and not IS_WINDOWS:
            os.chmod(path, self.__mode)
        if self.__executable and not IS_WINDOWS:
            os.chmod(
                path, stat.S_IXOTH | stat.S_IXUSR | stat.S_IXGRP
                | os.stat(self.path).st_mode)
コード例 #6
0
    def run(self, context):
        self.log.info("Copying %s to %s", self.src, self.path)

        src = self.src.resolveWithDestinations(
            context)  #  a map of srcAbsolute: destRelative

        symlinks = self.options['Copy.symlinks']
        if isinstance(symlinks, str): symlinks = symlinks.lower() == 'true'
        assert symlinks in [True, False], repr(symlinks)

        # implicitly ensure parent of target exists, to keep things simple

        copied = 0
        if not isDirPath(self.name):
            # it's a simple file operation.
            if len(src) != 1:
                raise BuildException(
                    'Copy destination must be a directory (ending with "/") when multiple sources are specified (not: %s)'
                    % src)
            src, mappedDest = src[0]
            if isDirPath(src):
                raise BuildException(
                    'Copy source must be files (or PathSets) not directories: %s'
                    % src)
            mkdir(os.path.dirname(self.path))
            self._copyFile(
                context, src, self.path
            )  # we kindof have to ignore mappedDest here, since the target path already fully defines it
            if self.mode:
                os.chmod(self.path, self.mode)
            copied += 1
        else:
            lastDirCreated = None

            for (srcAbs, destRel) in src:
                srcAbs = normLongPath(srcAbs)
                dest = normLongPath(self.path + destRel)
                # there should not be any directories here only files from pathsets
                if '..' in destRel:
                    # to avoid people abusing this to copy files outside the dest directory!
                    raise Exception(
                        'This target does not permit destination paths to contain ".." relative path expressions'
                    )
                issymlink = symlinks and os.path.islink(srcAbs.rstrip(os.sep))

                if isDirPath(
                        srcAbs
                ) and not issymlink:  # allows creating of empty directories.
                    mkdir(dest)
                else:
                    #self.log.debug('Processing %s -> %s i.e. %s', srcAbs, destRel, dest)

                    if issymlink:  # this may be a directory path, and dirname will fail unless we strip off the /
                        dest = dest.rstrip(os.sep)

                    if not lastDirCreated or lastDirCreated != os.path.dirname(
                            dest):
                        lastDirCreated = os.path.dirname(dest)
                        self.log.debug('Creating intermediate dir %s',
                                       lastDirCreated)
                        mkdir(lastDirCreated)

                    try:
                        if issymlink:
                            os.symlink(os.readlink(srcAbs.rstrip(os.sep)),
                                       dest)
                        else:
                            self._copyFile(context, srcAbs, dest)
                            if self.mode:
                                os.chmod(dest, self.mode)
                    except Exception as e:
                        raise BuildException(
                            'Error copying from "%s" to "%s"' % (srcAbs, dest),
                            causedBy=True)

                    copied += 1

        self.log.info('Copied %d file(s) to %s', copied, self.path)
コード例 #7
0
ファイル: java.py プロジェクト: xpybuild/xpybuild
	def run(self, context):
		options = self.options

		# make sure temp dir exists
		mkdir(self.workDir)

		classes = os.path.join(self.workDir, "classes") # output dir for classes
		
		# create the classpath, sorting within PathSet (for determinism), but retaining original order of 
		# PathSet elements in the list
		classpath = os.pathsep.join(self.classpath.resolve(context)) 

		# compile everything
		mkdir(classes) # (need this for assembling other files to package later on, even if we don't do any javac)
		if self.compile:
			mkdir(self.getOption('javac.logs'))
			javac(classes, self.compile.resolve(context), classpath, options=options, logbasename=options.get('javac.logs')+'/'+targetNameToUniqueId(self.name), targetname=self.name, workDir=self.workDir)

		manifest = os.path.join(self.workDir, "MANIFEST.MF") # manifest file
	
		if isinstance(self.manifest, str):
			manifest = context.getFullPath(self.manifest, self.baseDir)
		elif self.manifest == None:
			manifest = None
		else: # generate one
			# rewrite property values in the manifest
			manifest_entries = {}
			for i in self.manifest:
				manifest_entries[i] = context.expandPropertyValues(self.manifest[i])
	
			# determine classpath for manifest
			classpath_entries = []
			
			if "Class-path" not in manifest_entries: # assuming it wasn't hardcoded, set it here
				for src, dest in self.classpath.resolveWithDestinations(context):
					# we definitely do want to support use of ".." in destinations here, it can be very useful
					classpath_entries.append(dest)
				assert isinstance(options['jar.manifest.classpathAppend'], list), options['jar.manifest.classpathAppend'] # must not be a string
				classpath_entries.extend(options['jar.manifest.classpathAppend'] or [])
				
				# need to always use / not \ for these to be valid
				classpath_entries = [p.replace(os.path.sep, '/').replace('\\', '/') for p in classpath_entries if p]
				
				if classpath_entries:
					manifest_entries["Class-path"] = " ".join(classpath_entries) # include the classpath from here
			if not manifest_entries.get('Class-path'): # suppress this element entirely if not needed, otherwise there would be no way to have an empty classpath
				manifest_entries.pop('Class-path','')
			
			# create the manifest file
			create_manifest(manifest, manifest_entries, options=options)

		# copy in the additional things to include
		for (src, dest) in self.package.resolveWithDestinations(context):
			if '..' in dest: raise Exception('This target does not permit packaged destination paths to contain ".." relative path expressions')
			mkdir(os.path.dirname(os.path.join(classes, dest)))
			destpath = normLongPath(classes+'/'+dest)
			srcpath = normLongPath(src)

			if os.path.isdir(srcpath):
				mkdir(destpath)
			else:
				with open(srcpath, 'rb') as s:
					with openForWrite(destpath, 'wb') as d:
						d.write(s.read())

		# create the jar
		jar(self.path, manifest, classes, options=options, preserveManifestFormatting=self.preserveManifestFormatting, 
			outputHandler=ProcessOutputHandler.create('jar', treatStdErrAsErrors=False,options=options))
コード例 #8
0
ファイル: archive.py プロジェクト: xpybuild/xpybuild
	def run(self, context):
		mkdir(os.path.dirname(self.path))
		with tarfile.open(normLongPath(self.path), 'w:gz') as output:
			for (f, o) in self.inputs.resolveWithDestinations(context):
				output.add(normLongPath(f).rstrip('/\\'), o)