* ./bootstrap:
- New: Complete rewrite of builCoriolis.py & merge with easyChams to provide a graphical interface. Asides to the GUI, when run in graphic mode all settings are kept from run to run. Meaning that once the initial setup is done, a user may completly forget where things are... The new tool is named <ccb> for 'Coriolis & Chams Builder'. The Builder is now a module, that is split into multiples files. The old buildCoriolis.py is kept for the time beeing to ensure a smooth transition.
This commit is contained in:
parent
ceda10e523
commit
b99ccda839
|
@ -7,6 +7,7 @@
|
|||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
print_cmake_module_path()
|
||||
|
||||
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
|
||||
|
@ -17,8 +18,12 @@
|
|||
OWNER_READ GROUP_READ WORLD_READ
|
||||
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
|
||||
|
||||
install(FILES buildCoriolis.py
|
||||
install(DIRECTORY builder
|
||||
DESTINATION ${PYTHON_SITE_PACKAGES} )
|
||||
|
||||
install(FILES ccb.py
|
||||
DESTINATION bin
|
||||
RENAME ccb
|
||||
PERMISSIONS OWNER_WRITE
|
||||
OWNER_READ GROUP_READ WORLD_READ
|
||||
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
|
||||
|
|
|
@ -29,6 +29,7 @@ projects = [ { 'name' : 'bootstrap'
|
|||
, "equinox"
|
||||
, "solstice"
|
||||
, "unicorn"
|
||||
, "testbench"
|
||||
#, "ispd"
|
||||
, "cumulus"
|
||||
, "stratus1"
|
||||
|
|
|
@ -1,831 +1,10 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import os.path
|
||||
import datetime
|
||||
import socket
|
||||
import subprocess
|
||||
import optparse
|
||||
|
||||
|
||||
class ErrorMessage ( Exception ):
|
||||
|
||||
def __init__ ( self, code, *arguments ):
|
||||
self._code = code
|
||||
self._errors = [ 'Malformed call to ErrorMessage()'
|
||||
, '%s' % str(arguments) ]
|
||||
|
||||
text = None
|
||||
if len(arguments) == 1:
|
||||
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
|
||||
else:
|
||||
self._errors = arguments[0]
|
||||
elif len(arguments) > 1:
|
||||
text = list(arguments)
|
||||
|
||||
if text:
|
||||
self._errors = []
|
||||
while len(text[0]) == 0: del text[0]
|
||||
|
||||
lstrip = 0
|
||||
if text[0].startswith('[ERROR]'): lstrip = 8
|
||||
|
||||
for line in text:
|
||||
if line[0:lstrip ] == ' '*lstrip or \
|
||||
line[0:lstrip-1] == '[ERROR]':
|
||||
self._errors += [ line[lstrip:] ]
|
||||
else:
|
||||
self._errors += [ line.lstrip() ]
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
if not isinstance(self._errors,list):
|
||||
return "[ERROR] %s" % self._errors
|
||||
|
||||
formatted = "\n"
|
||||
for i in range(len(self._errors)):
|
||||
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
|
||||
else: formatted += " %s" % self._errors[i]
|
||||
if i+1 < len(self._errors): formatted += "\n"
|
||||
return formatted
|
||||
|
||||
def addMessage ( self, message ):
|
||||
if not isinstance(self._errors,list):
|
||||
self._errors = [ self._errors ]
|
||||
if isinstance(message,list):
|
||||
for line in message:
|
||||
self._errors += [ line ]
|
||||
else:
|
||||
self._errors += [ message ]
|
||||
return
|
||||
|
||||
def terminate ( self ):
|
||||
print self
|
||||
sys.exit(self._code)
|
||||
|
||||
def _getCode ( self ): return self._code
|
||||
|
||||
code = property(_getCode)
|
||||
|
||||
|
||||
|
||||
class Project:
|
||||
|
||||
def __init__ ( self, name, tools, repository ):
|
||||
self._name = name
|
||||
self._tools = tools
|
||||
self._repository = repository
|
||||
self._actives = []
|
||||
return
|
||||
|
||||
def getName ( self ): return self._name
|
||||
def getTools ( self ): return self._tools
|
||||
def getRepository ( self ): return self._repository
|
||||
def getActives ( self ): return self._actives
|
||||
def hasTool ( self, tool ): return tool in self._tools
|
||||
|
||||
def desactivate ( self ):
|
||||
self._active = []
|
||||
return
|
||||
|
||||
def activateAll ( self ):
|
||||
self._actives = self._tools
|
||||
return
|
||||
|
||||
def activate ( self, tools ):
|
||||
# Build the ordered list.
|
||||
for tool in self._tools:
|
||||
if (tool in tools) and not (tool in self._actives):
|
||||
self._actives += [ tool ]
|
||||
# Find the tools not part of the project.
|
||||
rejecteds = []
|
||||
for tool in tools:
|
||||
if not (tool in self._tools) and (not tool in rejecteds):
|
||||
rejecteds += [ tool ]
|
||||
return rejecteds
|
||||
|
||||
|
||||
|
||||
class ProjectBuilder:
|
||||
|
||||
def __init__ ( self ):
|
||||
self._projects = []
|
||||
self._standalones = []
|
||||
self._svnTag = "x"
|
||||
self._svnMethod = None
|
||||
self._projectDir = 'coriolis-2.x'
|
||||
self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
|
||||
self._packageName = None
|
||||
self._packageVersion = None
|
||||
self._packageExcludes = []
|
||||
self._packageProject = []
|
||||
|
||||
self._quiet = False
|
||||
self._buildMode = "Release"
|
||||
self._rmBuild = False
|
||||
self._doBuild = True
|
||||
self._noCache = False
|
||||
self._enableShared = "ON"
|
||||
self._enableDoc = "OFF"
|
||||
self._checkDatabase = "OFF"
|
||||
self._checkDeterminism = "OFF"
|
||||
self._verboseMakefile = "OFF"
|
||||
self._libMode = "Shared"
|
||||
self._makeArguments = []
|
||||
self._environment = os.environ
|
||||
|
||||
self._guessOs ()
|
||||
self._updateSecondary ()
|
||||
return
|
||||
|
||||
|
||||
def __setattr__ ( self, attribute, value ):
|
||||
if attribute[0] == "_":
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute == "svnTag": self._svnTag = value
|
||||
elif attribute == "svnMethod": self._svnMethod = value
|
||||
elif attribute == "projectDir": self._projectDir = value
|
||||
elif attribute == "rootDir": self._rootDir = os.path.expanduser(value)
|
||||
elif attribute == "packageName": self._packageName = value
|
||||
elif attribute == "packageVersion": self._packageVersion = value
|
||||
elif attribute == "quiet": self._quiet = value
|
||||
elif attribute == "buildMode": self._buildMode = value
|
||||
elif attribute == "rmBuild": self._rmBuild = value
|
||||
elif attribute == "doBuild": self._doBuild = value
|
||||
elif attribute == "noCache": self._noCache = value
|
||||
elif attribute == "enableShared": self._enableShared = value
|
||||
elif attribute == "enableDoc": self._enableDoc = value
|
||||
elif attribute == "enableShared": self._enableShared = value
|
||||
elif attribute == "checkDatabase": self._checkDatabase = value
|
||||
elif attribute == "checkDeterminism": self._checkDeterminism = value
|
||||
elif attribute == "verboseMakefile": self._verboseMakefile = value
|
||||
elif attribute == "makeArguments": self._makeArguments = value.split ()
|
||||
elif attribute == "libMode": self._libMode = value
|
||||
self._updateSecondary ()
|
||||
return
|
||||
|
||||
|
||||
def _updateSecondary ( self ):
|
||||
#self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
|
||||
self._rpmbuildDir = os.path.join ( self._rootDir , "rpmbuild" )
|
||||
self._debbuildDir = os.path.join ( self._rootDir , "debbuild" )
|
||||
self._tmppathDir = os.path.join ( self._rpmbuildDir, "tmp" )
|
||||
self._tarballDir = os.path.join ( self._rootDir , "tarball" )
|
||||
self._archiveDir = os.path.join ( self._tarballDir , "%s-%s.%s" % (self._packageName
|
||||
,self._packageVersion
|
||||
,self._svnTag) )
|
||||
self._sourceDir = os.path.join ( self._rootDir , "src" )
|
||||
self._osDir = os.path.join ( self._rootDir
|
||||
, self._osType
|
||||
, "%s.%s" % (self._buildMode,self._libMode) )
|
||||
self._buildDir = os.path.join ( self._osDir, "build" )
|
||||
self._installDir = os.path.join ( self._osDir, "install" )
|
||||
|
||||
if self._enableShared == "ON": self._libMode = "Shared"
|
||||
else: self._libMode = "Static"
|
||||
|
||||
self._specFileIn = os.path.join ( self._sourceDir, "bootstrap", "%s.spec.in"%self._packageName )
|
||||
self._specFile = os.path.join ( self._sourceDir, "bootstrap", "%s.spec" %self._packageName )
|
||||
self._debianDir = os.path.join ( self._sourceDir, "bootstrap", "debian" )
|
||||
self._debChangelogIn = os.path.join ( self._debianDir, "changelog.in" )
|
||||
self._debChangelog = os.path.join ( self._debianDir, "changelog" )
|
||||
self._sourceTarBz2 = "%s-%s.%s.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
|
||||
self._binaryTarBz2 = "%s-binary-%s.%s-1.slsoc6.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
|
||||
self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName )
|
||||
return
|
||||
|
||||
|
||||
def _guessOs ( self ):
|
||||
self._libSuffix = None
|
||||
self._osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*")
|
||||
self._osSlsoc6x = re.compile (".*Linux.*el6.*")
|
||||
self._osSLSoC5x_64 = re.compile (".*Linux.*el5.*x86_64.*")
|
||||
self._osSLSoC5x = re.compile (".*Linux.*(el5|2.6.23.13.*SoC).*")
|
||||
self._osLinux_64 = re.compile (".*Linux.*x86_64.*")
|
||||
self._osLinux = re.compile (".*Linux.*")
|
||||
self._osFreeBSD8x_amd64 = re.compile (".*FreeBSD 8.*amd64.*")
|
||||
self._osFreeBSD8x_64 = re.compile (".*FreeBSD 8.*x86_64.*")
|
||||
self._osFreeBSD8x = re.compile (".*FreeBSD 8.*")
|
||||
self._osDarwin = re.compile (".*Darwin.*")
|
||||
|
||||
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
|
||||
lines = uname.stdout.readlines()
|
||||
|
||||
if self._osSlsoc6x_64.match(lines[0]):
|
||||
self._osType = "Linux.slsoc6x_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSlsoc6x .match(lines[0]): self._osType = "Linux.slsoc6x"
|
||||
elif self._osSLSoC5x_64.match(lines[0]):
|
||||
self._osType = "Linux.SLSoC5x_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSLSoC5x .match(lines[0]): self._osType = "Linux.SLSoC5x"
|
||||
elif self._osLinux_64 .match(lines[0]):
|
||||
self._osType = "Linux.x86_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osLinux .match(lines[0]): self._osType = "Linux.i386"
|
||||
elif self._osDarwin .match(lines[0]): self._osType = "Darwin"
|
||||
elif self._osFreeBSD8x_amd64.match(lines[0]):
|
||||
self._osType = "FreeBSD.8x.amd64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osFreeBSD8x_64.match(lines[0]):
|
||||
self._osType = "FreeBSD.8x.x86_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osFreeBSD8x .match(lines[0]): self._osType = "FreeBSD.8x.i386"
|
||||
else:
|
||||
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
|
||||
self._osType = uname.stdout.readlines()[0][:-1]
|
||||
|
||||
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
|
||||
print " (using: \"%s\")" % self._osType
|
||||
|
||||
return
|
||||
|
||||
|
||||
def _guessSvnTag ( self, project ):
|
||||
revisionPattern = re.compile ( r"^Revision:\s*(?P<revision>\d+)" )
|
||||
projectSvnDir = os.path.join ( self._svnMethod+project.getRepository() )
|
||||
|
||||
command = [ "svn", "info", projectSvnDir ]
|
||||
svnInfo = subprocess.Popen ( command, stdout=subprocess.PIPE )
|
||||
|
||||
for line in svnInfo.stdout.readlines():
|
||||
m = revisionPattern.match ( line )
|
||||
if m:
|
||||
self._svnTag = m.group("revision")
|
||||
print "Latest revision of project %s is %s." % (project.getName(),self._svnTag)
|
||||
self._updateSecondary ()
|
||||
return
|
||||
|
||||
print "[WARNING] Cannot guess revision for project \"%s\"." % project.getName()
|
||||
print " (using: \"x\")"
|
||||
return
|
||||
|
||||
|
||||
def _configure ( self, fileIn, file ):
|
||||
fdFileIn = open ( fileIn, "r" )
|
||||
fdFile = open ( file , "w" )
|
||||
|
||||
for line in fdFileIn.readlines():
|
||||
stable = False
|
||||
substituted0 = line
|
||||
|
||||
while not stable:
|
||||
substituted1 = re.sub ( r"@svntag@" , self._svnTag , substituted0 )
|
||||
substituted1 = re.sub ( r"@coriolisTop@", "/opt/coriolis2", substituted1 )
|
||||
if substituted0 == substituted1: stable = True
|
||||
else: substituted0 = substituted1
|
||||
|
||||
fdFile.write ( substituted0 )
|
||||
|
||||
fdFileIn.close ()
|
||||
fdFile.close ()
|
||||
return
|
||||
|
||||
|
||||
def _doSpec ( self ):
|
||||
self._configure ( self._specFileIn, self._specFile )
|
||||
return
|
||||
|
||||
|
||||
def _doDebChangelog ( self ):
|
||||
self._configure ( self._debChangelogIn, self._debChangelog )
|
||||
return
|
||||
|
||||
|
||||
def _execute ( self, command, error ):
|
||||
sys.stdout.flush ()
|
||||
sys.stderr.flush ()
|
||||
child = subprocess.Popen ( command, env=self._environment, stdout=None )
|
||||
(pid,status) = os.waitpid ( child.pid, 0 )
|
||||
status >>= 8
|
||||
if status != 0:
|
||||
ErrorMessage( status, "%s (status:%d)."%(error,status) ).terminate()
|
||||
return
|
||||
|
||||
|
||||
def _enableTool ( self, tool ):
|
||||
return
|
||||
|
||||
|
||||
def _build ( self, tool ):
|
||||
toolSourceDir = os.path.join ( self._sourceDir, tool )
|
||||
toolBuildDir = os.path.join ( self._buildDir , tool )
|
||||
# Supplied directly in the CMakeLists.txt.
|
||||
#cmakeModules = os.path.join ( self._installDir, "share", "cmake", "Modules" )
|
||||
|
||||
if not os.path.isdir(toolSourceDir):
|
||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
||||
return
|
||||
|
||||
if self._rmBuild:
|
||||
print "Removing tool build directory: \"%s\"." % toolBuildDir
|
||||
command = [ "/bin/rm", "-rf", toolBuildDir ]
|
||||
self._execute ( command, "Removing tool build directory" )
|
||||
|
||||
if not os.path.isdir(toolBuildDir):
|
||||
print "Creating tool build directory: \"%s\"." % toolBuildDir
|
||||
os.makedirs ( toolBuildDir )
|
||||
os.chdir ( toolBuildDir )
|
||||
|
||||
command = ["cmake", "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self._buildMode
|
||||
, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self._enableShared
|
||||
#, "-D", "CMAKE_MODULE_PATH:STRING=%s" % cmakeModules
|
||||
, toolSourceDir ]
|
||||
self._execute ( command, "First CMake failed" )
|
||||
|
||||
os.chdir ( toolBuildDir )
|
||||
if self._noCache:
|
||||
cmakeCache = os.path.join(toolBuildDir,"CMakeCache.txt")
|
||||
if os.path.isfile ( cmakeCache ): os.unlink ( cmakeCache )
|
||||
|
||||
command = ["cmake", "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self._buildMode
|
||||
, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self._enableShared
|
||||
, "-D", "BUILD_DOC:STRING=%s" % self._enableDoc
|
||||
, "-D", "CHECK_DATABASE:STRING=%s" % self._checkDatabase
|
||||
, "-D", "CHECK_DETERMINISM:STRING=%s" % self._checkDeterminism
|
||||
, "-D", "CMAKE_VERBOSE_MAKEFILE:STRING=%s" % self._verboseMakefile
|
||||
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self._installDir
|
||||
]
|
||||
if self._libSuffix:
|
||||
command += [ "-D", "LIB_SUFFIX:STRING=%s" % self._libSuffix ]
|
||||
command += [ toolSourceDir ]
|
||||
self._execute ( command, "Second CMake failed" )
|
||||
|
||||
if self._doBuild:
|
||||
command = [ "make" ]
|
||||
#command += [ "DESTDIR=%s" % self._installDir ]
|
||||
if self._enableDoc == "ON":
|
||||
#if tool == "crlcore" or tool == "stratus1":
|
||||
if tool == "stratus1":
|
||||
command += [ "dvi", "safepdf", "html" ]
|
||||
command += self._makeArguments
|
||||
print "Make command:", command
|
||||
sys.stdout.flush ()
|
||||
self._execute ( command, "Build failed" )
|
||||
return
|
||||
|
||||
|
||||
def _svnStatus ( self, tool ):
|
||||
toolSourceDir = os.path.join ( self._sourceDir , tool )
|
||||
if not os.path.isdir(toolSourceDir):
|
||||
if not self._quiet:
|
||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
||||
return
|
||||
os.chdir ( toolSourceDir )
|
||||
|
||||
print "Checking SVN status of tool: ", tool
|
||||
command = [ "svn", "status", "-u", "-q" ]
|
||||
self._execute ( command, "svn status -u -q" )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def _svnDiff ( self, tool ):
|
||||
toolSourceDir = os.path.join ( self._sourceDir , tool )
|
||||
if not os.path.isdir(toolSourceDir):
|
||||
if not self._quiet:
|
||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
||||
return
|
||||
os.chdir ( toolSourceDir )
|
||||
|
||||
print "Doing a SVN diff of tool: ", tool
|
||||
command = [ "svn", "diff" ]
|
||||
if self._svnTag != "x":
|
||||
command += [ "--revision", self._svnTag ]
|
||||
self._execute ( command, "svn diff %s" % tool )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def _svnUpdate ( self, tool ):
|
||||
toolSourceDir = os.path.join ( self._sourceDir , tool )
|
||||
if not os.path.isdir(toolSourceDir):
|
||||
if not self._quiet:
|
||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir)
|
||||
return
|
||||
os.chdir ( toolSourceDir )
|
||||
|
||||
print "Doing a SVN update of tool: ", tool
|
||||
command = [ "svn", "update" ]
|
||||
self._execute ( command, "svn update" )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def _svnCheckout ( self, tool ):
|
||||
project = self.getToolProject ( tool )
|
||||
if not project:
|
||||
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
|
||||
,"Cannot guess the SVN repository." )
|
||||
return
|
||||
if not project.getRepository ():
|
||||
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
|
||||
return
|
||||
|
||||
if not os.path.isdir(self._sourceDir):
|
||||
print ErrorMessage( 0, "Source directory <%s> doesn't exists. Creating."%self._sourceDir )
|
||||
os.makedirs( self._sourceDir )
|
||||
|
||||
toolSvnTrunkDir = os.path.join ( self._svnMethod+project.getRepository(), tool, "trunk" )
|
||||
os.chdir ( self._sourceDir )
|
||||
|
||||
print "Doing a SVN checkout of tool: ", tool
|
||||
command = [ "svn", "co", toolSvnTrunkDir, tool ]
|
||||
if self._svnTag != "x":
|
||||
command += [ "--revision", self._svnTag ]
|
||||
self._execute ( command, "svn checkout %s" % tool )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def _svnExport ( self, tool ):
|
||||
project = self.getToolProject ( tool )
|
||||
if not project:
|
||||
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
|
||||
, "Cannot guess the SVN repository.")
|
||||
return
|
||||
if not project.getRepository ():
|
||||
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
|
||||
return
|
||||
|
||||
toolSvnTrunkDir = os.path.join ( self._svnMethod+project.getRepository(), tool, "trunk" )
|
||||
|
||||
if not os.path.isdir ( self._archiveDir ):
|
||||
os.mkdir ( self._archiveDir )
|
||||
os.chdir ( self._archiveDir )
|
||||
|
||||
toolExportDir = os.path.join ( self._archiveDir, tool )
|
||||
if os.path.isdir ( toolExportDir ):
|
||||
print "Removing tool export (tarball) directory: \"%s\"." % toolExportDir
|
||||
command = [ "/bin/rm", "-r", toolExportDir ]
|
||||
self._execute ( command, "Removing tool export (tarball) directory" )
|
||||
|
||||
print "Doing a SVN export of tool: ", tool
|
||||
command = [ "svn", "export", toolSvnTrunkDir, toolExportDir ]
|
||||
if self._svnTag != "x":
|
||||
command += [ "--revision", self._svnTag ]
|
||||
self._execute ( command, "svn export %s" % toolExportDir )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def getProject ( self, name ):
|
||||
for project in self._projects:
|
||||
if project.getName() == name:
|
||||
return project
|
||||
return None
|
||||
|
||||
|
||||
def getToolProject ( self, name ):
|
||||
for project in self._projects:
|
||||
if project.hasTool(name):
|
||||
return project
|
||||
return None
|
||||
|
||||
|
||||
def register ( self, project ):
|
||||
for registered in self._projects:
|
||||
if registered.getName() == project.getName():
|
||||
print ErrorMessage( 0, "Project \"%s\" is already registered (ignored)." )
|
||||
return
|
||||
self._projects += [ project ]
|
||||
return
|
||||
|
||||
|
||||
def _setEnvironment ( self, systemVariable, userVariable ):
|
||||
if not self._environment.has_key(systemVariable) or self._environment[systemVariable] == "":
|
||||
if not self._environment.has_key(userVariable) or self._environment[userVariable] == "" :
|
||||
self._environment[ systemVariable ] = self._installDir
|
||||
print "[WARNING] Neither <%s> nor <%s> environment variables are sets." \
|
||||
% (systemVariable,userVariable)
|
||||
print " Setting <%s> to <%s>." % (systemVariable,self._installDir)
|
||||
else:
|
||||
self._environment[ systemVariable ] = self._environment[ userVariable ]
|
||||
|
||||
if not self._quiet:
|
||||
print "Setting <%s> to <%s>." % (systemVariable,self._environment[systemVariable])
|
||||
if self._environment.has_key(userVariable):
|
||||
print "Transmitting <%s> as <%s>." % (userVariable,self._environment[userVariable])
|
||||
return
|
||||
|
||||
|
||||
def _commandTemplate ( self, tools, projects, command ):
|
||||
# Set or guess the various projects TOP environment variables.
|
||||
for project in self._projects:
|
||||
topVariable = "%s_TOP" % project.getName().upper()
|
||||
topUserVariable = "%s_USER_TOP" % project.getName().upper()
|
||||
self._setEnvironment ( topVariable, topUserVariable )
|
||||
|
||||
if tools:
|
||||
# Checks if the requested tools are in the various projects.
|
||||
self._standalones = tools
|
||||
for project in self._projects:
|
||||
self._standalones = project.activate ( self._standalones )
|
||||
for tool in self._standalones:
|
||||
print "[WARNING] Tool \"%s\" is not part of any project." % tool
|
||||
|
||||
if projects:
|
||||
for projectName in projects:
|
||||
project = self.getProject ( projectName )
|
||||
if not project:
|
||||
ErrorMessage( 1, "No project of name \"%s\"."%projectName ).terminate()
|
||||
project.activateAll()
|
||||
|
||||
if not tools and not projects:
|
||||
for project in self._projects:
|
||||
project.activateAll ()
|
||||
|
||||
for project in self._projects:
|
||||
for tool in project.getActives():
|
||||
print "\nProcessing tool: \"%s\"." % tool
|
||||
getattr(self,command) ( tool )
|
||||
|
||||
for tool in self._standalones:
|
||||
print "\nProcessing tool: \"%s\"." % tool
|
||||
getattr(self,command) ( tool )
|
||||
return
|
||||
|
||||
|
||||
def enable ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_enableTool" )
|
||||
return
|
||||
|
||||
|
||||
def enabledTools ( self ):
|
||||
tools = []
|
||||
for project in self._projects:
|
||||
tools += project.getActives()
|
||||
return tools
|
||||
|
||||
|
||||
def build ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_build" )
|
||||
return
|
||||
|
||||
|
||||
def svnStatus ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnStatus" )
|
||||
return
|
||||
|
||||
|
||||
def svnUpdate ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnUpdate" )
|
||||
return
|
||||
|
||||
|
||||
def svnCheckout ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnCheckout" )
|
||||
return
|
||||
|
||||
|
||||
def svnDiff ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnDiff" )
|
||||
return
|
||||
|
||||
|
||||
def svnExport ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnExport" )
|
||||
return
|
||||
|
||||
|
||||
def svnTarball ( self, tools, projects ):
|
||||
if self._svnTag == "x":
|
||||
self._guessSvnTag ( self.getProject(projects[0]) )
|
||||
|
||||
self._doSpec ()
|
||||
self._doDebChangelog ()
|
||||
|
||||
if os.path.isdir(self._tarballDir):
|
||||
print "Removing previous tarball directory: \"%s\"." % self._tarballDir
|
||||
command = [ "/bin/rm", "-rf", self._tarballDir ]
|
||||
self._execute ( command, "Removing top export (tarball) directory" )
|
||||
|
||||
print "Creating tarball directory: \"%s\"." % self._tarballDir
|
||||
os.makedirs ( self._tarballDir )
|
||||
self.svnExport ( tools, projects )
|
||||
|
||||
# Remove unpublisheds (yet) tools/files.
|
||||
for item in self._packageExcludes:
|
||||
command = [ "/bin/rm", "-rf", os.path.join(self._archiveDir,item) ]
|
||||
self._execute ( command, "rm of %s failed" % item)
|
||||
|
||||
# Adds files neededs only for packaging purpose.
|
||||
command = [ "/bin/cp", "-r", os.path.join(self._sourceDir ,"bootstrap","Makefile.package")
|
||||
, os.path.join(self._archiveDir,"Makefile") ]
|
||||
self._execute ( command, "copy of %s failed" % "boostrap/Makefile.package")
|
||||
|
||||
command = [ "/bin/cp", self._specFile, self._archiveDir ]
|
||||
self._execute ( command, "Copying RPM spec file" )
|
||||
|
||||
command = [ "/bin/cp", "-r", self._debianDir, self._archiveDir ]
|
||||
self._execute ( command, "Copying Debian/Ubuntu package control files" )
|
||||
|
||||
os.chdir ( self._archiveDir )
|
||||
#command = [ "/usr/bin/patch", "--remove-empty-files"
|
||||
# , "--no-backup-if-mismatch"
|
||||
# , "-p0", "-i", self._distribPatch ]
|
||||
#self._execute ( command, "patch for distribution command failed" )
|
||||
|
||||
os.chdir ( self._tarballDir )
|
||||
command = [ "/bin/tar"
|
||||
, "--exclude-backups"
|
||||
, "--exclude-vcs"
|
||||
, "-jcvf", self._sourceTarBz2, os.path.basename(self._archiveDir) ]
|
||||
self._execute ( command, "tar command failed" )
|
||||
|
||||
print "Cleanup SVN export tarball archive directory: \"%s\"." % self._archiveDir
|
||||
command = [ "/bin/rm", "-rf", self._archiveDir ]
|
||||
self._execute ( command, "Removing archive export (tarball) directory" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def userTarball ( self, tools, projects ):
|
||||
self.enable( tools, projects )
|
||||
|
||||
userSourceTarBz2 = os.path.join ( self._tarballDir
|
||||
, datetime.date.today().strftime('%s-%s-%%Y%%m%%d.tar.bz2'%
|
||||
(self._packageName
|
||||
,self._packageVersion)) )
|
||||
|
||||
excludes = []
|
||||
for exclude in self._packageExcludes:
|
||||
excludes += [ '--exclude='+exclude ]
|
||||
|
||||
os.chdir ( self._sourceDir )
|
||||
command = [ "/bin/tar"
|
||||
, "--exclude-backups"
|
||||
, "--exclude-vcs"
|
||||
, "--transform=s,^,%s/src/,"%self._projectDir ] \
|
||||
+ excludes \
|
||||
+ [ "-jcvf", userSourceTarBz2 ] \
|
||||
+ self.enabledTools()
|
||||
self._execute ( command, "tar command failed" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def doRpm ( self ):
|
||||
self.svnTarball ( [], self._packageProjects )
|
||||
|
||||
for rpmDir in [ "SOURCES", "SPECS", "BUILD", "tmp"
|
||||
, "SRPMS", "RPMS/i386", "RPMS/i686", "RPMS/x86_64" ]:
|
||||
rpmFullDir = os.path.join ( self._rpmbuildDir, rpmDir )
|
||||
if not os.path.isdir(rpmFullDir):
|
||||
os.makedirs ( rpmFullDir )
|
||||
|
||||
#rpmSpecFile = os.path.join ( self._rpmbuildDir, "SPECS" , "coriolis2.spec" )
|
||||
rpmSourceFile = os.path.join ( self._rpmbuildDir, "SOURCES", self._sourceTarBz2 )
|
||||
sourceFile = os.path.join ( self._tarballDir, self._sourceTarBz2 )
|
||||
|
||||
#if os.path.isfile ( rpmSpecFile ):
|
||||
# os.unlink ( rpmSpecFile )
|
||||
#os.symlink ( self._specFile, rpmSpecFile )
|
||||
|
||||
if not os.path.islink ( rpmSourceFile ):
|
||||
os.symlink ( sourceFile, rpmSourceFile )
|
||||
|
||||
os.chdir ( self._rpmbuildDir )
|
||||
|
||||
command = [ "/usr/bin/rpmbuild"
|
||||
, "--define", "_topdir %s" % self._rpmbuildDir
|
||||
, "--define", "_tmppath %s" % self._tmppathDir
|
||||
, "--define", "_enable_debug_packages 0"
|
||||
, "-ta", "--with", "binarytar", rpmSourceFile ]
|
||||
|
||||
self._execute ( command, "Rebuild rpm packages" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def doDeb ( self ):
|
||||
self.svnTarball ( [], self._packageProjects )
|
||||
|
||||
if not os.path.isdir(self._debbuildDir):
|
||||
os.makedirs ( self._debbuildDir )
|
||||
|
||||
os.chdir ( self._debbuildDir )
|
||||
sourceFile = os.path.join ( self._tarballDir , self._sourceTarBz2 )
|
||||
debOrigFile = os.path.join ( self._debbuildDir, "coriolis2_1.0.%s.orig.tar.bz2" % self._svnTag )
|
||||
if not os.path.islink(debOrigFile):
|
||||
os.link ( sourceFile, debOrigFile )
|
||||
|
||||
command = [ "/bin/tar", "jxf", debOrigFile ]
|
||||
self._execute ( command, "Unpacking pristine sources" )
|
||||
|
||||
#command = [ "/bin/cp", "-r", self._debianDir, "." ]
|
||||
#self._execute ( command, "Copying Debian/Ubuntu package control files" )
|
||||
|
||||
packageDir = os.path.join ( self._debbuildDir, "coriolis2-1.0.%s" % self._svnTag )
|
||||
os.chdir ( packageDir )
|
||||
|
||||
self._environment["CFLAGS" ] = "-O2"
|
||||
self._environment["CXXFLAGS"] = "-O2"
|
||||
command = [ "/usr/bin/debuild", "-us", "-uc" ]
|
||||
self._execute ( command, "Rebuild Debian packages" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def loadConfiguration ( self, confFile ):
|
||||
moduleGlobals = globals()
|
||||
|
||||
if not confFile:
|
||||
print 'Making an educated guess to locate the configuration file:'
|
||||
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
, os.environ['HOME']+'/coriolis-2.x/src/bootstrap'
|
||||
, os.environ['HOME']+'/coriolis/src/bootstrap'
|
||||
, os.environ['HOME']+'/chams-2.x/src/bootstrap'
|
||||
, os.environ['HOME']+'/chams/src/bootstrap'
|
||||
, '/users/outil/coriolis/coriolis-2.x/src/bootstrap'
|
||||
, self._rootDir+'/src/bootstrap'
|
||||
]
|
||||
|
||||
for location in locations:
|
||||
confFile = location + '/build.conf'
|
||||
print ' <%s>' % confFile
|
||||
|
||||
if os.path.isfile(confFile): break
|
||||
if not confFile:
|
||||
ErrorMessage( 1, 'Cannot locate any configuration file.' ).terminate()
|
||||
else:
|
||||
if not os.path.isfile(confFile):
|
||||
ErrorMessage( 1, 'Missing configuration file:', '<%s>'%confFile ).terminate()
|
||||
|
||||
print 'Reading configuration from:'
|
||||
print ' <%s>' % options.conf
|
||||
|
||||
try:
|
||||
execfile( confFile, moduleGlobals )
|
||||
except Exception, e:
|
||||
ErrorMessage( 1, 'An exception occured while loading the configuration file:'
|
||||
, '<%s>\n' % (confFile)
|
||||
, 'You should check for simple python errors in this file.'
|
||||
, 'Error was:'
|
||||
, '%s\n' % e ).terminate()
|
||||
|
||||
if moduleGlobals.has_key('projects'):
|
||||
entryNb = 0
|
||||
for entry in moduleGlobals['projects']:
|
||||
entryNb += 1
|
||||
if not entry.has_key('name'):
|
||||
raise ErrorMessage( 1, 'Missing project name in project entry #%d.' % entryNb )
|
||||
if not entry.has_key('tools'):
|
||||
raise ErrorMessage( 1, 'Missing tools list in project entry #%d (<%s>).' \
|
||||
% (entryNb,entry['name']) )
|
||||
if not isinstance(entry['tools'],list):
|
||||
raise ErrorMessage( 1, 'Tools item of project entry #%d (<%s>) is not a list.' \
|
||||
% (entryNb,entry['name']) )
|
||||
if not entry.has_key('repository'):
|
||||
raise ErrorMessage( 1, 'Missing project repository in project entry #%d.' \
|
||||
% entryNb )
|
||||
|
||||
self.register( Project(entry['name'],entry['tools'],entry['repository']) )
|
||||
else:
|
||||
ErrorMessage( 1, 'Configuration file is missing the \'project\' symbol.'
|
||||
, '<%s>'%confFile ).terminate()
|
||||
|
||||
if moduleGlobals.has_key('projectdir'):
|
||||
self.projectDir = moduleGlobals['projectdir']
|
||||
|
||||
if moduleGlobals.has_key('svnconfig'):
|
||||
svnconfig = moduleGlobals['svnconfig']
|
||||
if svnconfig.has_key('method'): self._svnMethod = svnconfig['method']
|
||||
|
||||
if moduleGlobals.has_key('package'):
|
||||
package = moduleGlobals['package']
|
||||
if package.has_key('name' ): self.packageName = package['name']
|
||||
if package.has_key('version' ): self.packageVersion = package['version']
|
||||
if package.has_key('excludes'):
|
||||
if not isinstance(package['excludes'],list):
|
||||
raise ErrorMessage( 1, 'Excludes of package configuration is not a list.')
|
||||
self._packageExcludes = package['excludes']
|
||||
if package.has_key('projects'):
|
||||
if not isinstance(package['projects'],list):
|
||||
raise ErrorMessage( 1, 'Projects to package is not a list.')
|
||||
self._packageProjects = package['projects']
|
||||
return
|
||||
|
||||
|
||||
def showConfiguration ( self ):
|
||||
print 'BuildCoriolis Configuration:'
|
||||
if self._svnMethod:
|
||||
print ' SVN Method: <%s>' % self._svnMethod
|
||||
else:
|
||||
print ' SVN Method not defined, will not be able to checkout/commit.'
|
||||
|
||||
for project in self._projects:
|
||||
print ' project:%-15s repository:<%s>' % ( ('<%s>'%project.getName()), project.getRepository() )
|
||||
toolOrder = 1
|
||||
for tool in project.getTools():
|
||||
print '%s%02d:<%s>' % (' '*26,toolOrder,tool)
|
||||
toolOrder += 1
|
||||
print
|
||||
return
|
||||
from builder import ErrorMessage
|
||||
from builder.Builder import Builder
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -869,7 +48,7 @@ if __name__ == "__main__":
|
|||
parser.add_option ( "-u", "--check-deter", action="store_true" , dest="checkDeterminism", help="Enable Katabatic/Kite determinism checking (*very* slow)." )
|
||||
( options, args ) = parser.parse_args ()
|
||||
|
||||
builder = ProjectBuilder ()
|
||||
builder = Builder ()
|
||||
builder.loadConfiguration ( options.conf )
|
||||
|
||||
if options.showConf:
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/AboutWidget.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtGui import QPalette
|
||||
from PyQt4.QtGui import QColor
|
||||
from PyQt4.QtGui import QFont
|
||||
from PyQt4.QtGui import QWidget
|
||||
from PyQt4.QtGui import QFrame
|
||||
from PyQt4.QtGui import QLabel
|
||||
from PyQt4.QtGui import QVBoxLayout
|
||||
from PyQt4.QtGui import QAction
|
||||
from PyQt4.QtGui import QKeySequence
|
||||
from PyQt4.QtGui import QApplication
|
||||
|
||||
|
||||
class AboutWidget ( QWidget ):
|
||||
|
||||
def __init__ ( self, parent=None ):
|
||||
QWidget.__init__ ( self, parent )
|
||||
self.setFixedSize( 500, 400 )
|
||||
self.setStyleSheet( 'background-color: #ffffdd;' )
|
||||
|
||||
topLine = QFrame()
|
||||
topLine.setFrameShape( QFrame.HLine )
|
||||
topLine.setLineWidth ( 2 )
|
||||
botLine = QFrame()
|
||||
botLine.setFrameShape( QFrame.HLine )
|
||||
botLine.setLineWidth ( 2 )
|
||||
|
||||
title = QLabel( 'CCB' )
|
||||
title.setAlignment( Qt.AlignCenter )
|
||||
font = title.font()
|
||||
font.setPointSize( 72 )
|
||||
font.setWeight ( QFont.Bold )
|
||||
title.setFont( font )
|
||||
|
||||
subTitle = QLabel( 'Coriolis & Chams Builder for the Dummies' )
|
||||
subTitle.setAlignment( Qt.AlignCenter )
|
||||
subTitle.setFont( QFont('Courier',10,QFont.Bold) )
|
||||
|
||||
authors = QLabel( 'Coriolis CAD System 1.0 . . . . . . . . ccb 1.0\n'
|
||||
'Copyright (c) 2008-2013 . . . . . . . . . . UPMC\n'
|
||||
'Authors . . . . . . . . . . . . . Damien Dupuis\n'
|
||||
' . . . . . . . . . . . . Jean-Paul Chaput\n'
|
||||
'E-Mail . . . . . . . . Jean-Paul.Chaput@lip6.fr'
|
||||
)
|
||||
authors.setAlignment( Qt.AlignCenter )
|
||||
authors.setFont( QFont('Courier',10,QFont.Bold) )
|
||||
|
||||
vLayout = QVBoxLayout()
|
||||
vLayout.addStretch(10)
|
||||
vLayout.addWidget( topLine )
|
||||
vLayout.addWidget( title )
|
||||
vLayout.addStretch(1)
|
||||
vLayout.addWidget( subTitle )
|
||||
vLayout.addWidget( authors )
|
||||
vLayout.addStretch(1)
|
||||
vLayout.addWidget( botLine )
|
||||
vLayout.addStretch(10)
|
||||
|
||||
frame = QFrame()
|
||||
frame.setFrameShape ( QFrame.Box )
|
||||
frame.setFrameShadow( QFrame.Sunken )
|
||||
frame.setLayout ( vLayout )
|
||||
frame.setLineWidth ( 1 )
|
||||
|
||||
vLayout = QVBoxLayout()
|
||||
vLayout.addWidget( frame )
|
||||
|
||||
self.setLayout( vLayout )
|
||||
|
||||
self._exitAction = QAction( '&Exit', self )
|
||||
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
|
||||
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
|
||||
self._exitAction.triggered.connect( QApplication.closeAllWindows )
|
||||
self.addAction( self._exitAction )
|
||||
|
||||
self._closeAction = QAction( '&Close', self )
|
||||
self._closeAction.setStatusTip( 'Close the About Window' )
|
||||
self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
|
||||
self._closeAction.triggered.connect( self.close )
|
||||
self.addAction( self._closeAction )
|
||||
|
||||
return
|
|
@ -0,0 +1,543 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/Builder.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import os.path
|
||||
import datetime
|
||||
import subprocess
|
||||
from . import ErrorMessage
|
||||
from Project import Project
|
||||
from Configuration import Configuration
|
||||
|
||||
|
||||
class Builder:
|
||||
|
||||
def __init__ ( self ):
|
||||
self._conf = Configuration()
|
||||
self._quiet = False
|
||||
self._rmBuild = False
|
||||
self._doBuild = True
|
||||
self._noCache = False
|
||||
self._enableShared = "ON"
|
||||
self._enableDoc = "OFF"
|
||||
self._checkDatabase = "OFF"
|
||||
self._checkDeterminism = "OFF"
|
||||
self._verboseMakefile = "OFF"
|
||||
self._makeArguments = []
|
||||
self._environment = os.environ
|
||||
return
|
||||
|
||||
|
||||
def __setattr__ ( self, attribute, value ):
|
||||
if attribute[0] == "_":
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute in self._conf.getAllIds(): setattr( self._conf, attribute, value )
|
||||
|
||||
if attribute == "quiet": self._quiet = value
|
||||
elif attribute == "rmBuild": self._rmBuild = value
|
||||
elif attribute == "doBuild": self._doBuild = value
|
||||
elif attribute == "noCache": self._noCache = value
|
||||
elif attribute == "enableDoc": self._enableDoc = value
|
||||
elif attribute == "enableShared": self._enableShared = value
|
||||
elif attribute == "checkDatabase": self._checkDatabase = value
|
||||
elif attribute == "checkDeterminism": self._checkDeterminism = value
|
||||
elif attribute == "verboseMakefile": self._verboseMakefile = value
|
||||
elif attribute == "makeArguments": self._makeArguments = value.split ()
|
||||
return
|
||||
|
||||
|
||||
def __getattr__ ( self, attribute ):
|
||||
if attribute[0] != "_":
|
||||
if attribute == 'conf': return self._conf
|
||||
if attribute in self._conf.getAllIds():
|
||||
return getattr( self._conf, attribute )
|
||||
|
||||
if not self.__dict__.has_key(attribute):
|
||||
raise ErrorMessage( 1, 'Builder has no attribute <%s>.'%attribute )
|
||||
return self.__dict__[attribute]
|
||||
|
||||
|
||||
def _guessSvnTag ( self, project ):
|
||||
revisionPattern = re.compile ( r"^Revision:\s*(?P<revision>\d+)" )
|
||||
projectSvnDir = os.path.join ( self.svnMethod+project.getRepository() )
|
||||
|
||||
command = [ "svn", "info", projectSvnDir ]
|
||||
svnInfo = subprocess.Popen ( command, stdout=subprocess.PIPE )
|
||||
|
||||
for line in svnInfo.stdout.readlines():
|
||||
m = revisionPattern.match ( line )
|
||||
if m:
|
||||
self.svnTag = m.group("revision")
|
||||
print "Latest revision of project %s is %s." % (project.getName(),self.svnTag)
|
||||
return
|
||||
|
||||
print "[WARNING] Cannot guess revision for project \"%s\"." % project.getName()
|
||||
print " (using: \"x\")"
|
||||
return
|
||||
|
||||
|
||||
def _configure ( self, fileIn, file ):
|
||||
fdFileIn = open ( fileIn, "r" )
|
||||
fdFile = open ( file , "w" )
|
||||
|
||||
for line in fdFileIn.readlines():
|
||||
stable = False
|
||||
substituted0 = line
|
||||
|
||||
while not stable:
|
||||
substituted1 = re.sub ( r"@svntag@" , self.svnTag, substituted0 )
|
||||
substituted1 = re.sub ( r"@coriolisTop@", "/opt/coriolis2" , substituted1 )
|
||||
if substituted0 == substituted1: stable = True
|
||||
else: substituted0 = substituted1
|
||||
|
||||
fdFile.write ( substituted0 )
|
||||
|
||||
fdFileIn.close ()
|
||||
fdFile.close ()
|
||||
return
|
||||
|
||||
|
||||
def _doSpec ( self ):
|
||||
self._configure ( self.specFileIn, self.specFile )
|
||||
return
|
||||
|
||||
|
||||
def _doDebChangelog ( self ):
|
||||
self._configure ( self.debChangelogIn, self.debChangelog )
|
||||
return
|
||||
|
||||
|
||||
def _execute ( self, command, error ):
|
||||
sys.stdout.flush ()
|
||||
sys.stderr.flush ()
|
||||
child = subprocess.Popen ( command, env=self._environment, stdout=None )
|
||||
(pid,status) = os.waitpid ( child.pid, 0 )
|
||||
status >>= 8
|
||||
if status != 0:
|
||||
ErrorMessage( status, "%s (status:%d)."%(error,status) ).terminate()
|
||||
return
|
||||
|
||||
|
||||
def _enableTool ( self, tool ):
|
||||
return
|
||||
|
||||
|
||||
def _build ( self, tool ):
|
||||
toolSourceDir = os.path.join ( self.sourceDir, tool )
|
||||
toolBuildDir = os.path.join ( self.buildDir , tool )
|
||||
# Supplied directly in the CMakeLists.txt.
|
||||
#cmakeModules = os.path.join ( self.installDir, "share", "cmake", "Modules" )
|
||||
|
||||
if not os.path.isdir(toolSourceDir):
|
||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
||||
return
|
||||
|
||||
if self._rmBuild:
|
||||
print "Removing tool build directory: \"%s\"." % toolBuildDir
|
||||
command = [ "/bin/rm", "-rf", toolBuildDir ]
|
||||
self._execute ( command, "Removing tool build directory" )
|
||||
|
||||
if not os.path.isdir(toolBuildDir):
|
||||
print "Creating tool build directory: \"%s\"." % toolBuildDir
|
||||
os.makedirs ( toolBuildDir )
|
||||
os.chdir ( toolBuildDir )
|
||||
|
||||
command = ["cmake", "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
|
||||
, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
|
||||
#, "-D", "CMAKE_MODULE_PATH:STRING=%s" % cmakeModules
|
||||
, toolSourceDir ]
|
||||
self._execute ( command, "First CMake failed" )
|
||||
|
||||
os.chdir ( toolBuildDir )
|
||||
if self._noCache:
|
||||
cmakeCache = os.path.join(toolBuildDir,"CMakeCache.txt")
|
||||
if os.path.isfile ( cmakeCache ): os.unlink ( cmakeCache )
|
||||
|
||||
command = ["cmake", "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
|
||||
, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
|
||||
, "-D", "BUILD_DOC:STRING=%s" % self._enableDoc
|
||||
, "-D", "CHECK_DATABASE:STRING=%s" % self._checkDatabase
|
||||
, "-D", "CHECK_DETERMINISM:STRING=%s" % self._checkDeterminism
|
||||
, "-D", "CMAKE_VERBOSE_MAKEFILE:STRING=%s" % self._verboseMakefile
|
||||
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir
|
||||
]
|
||||
if self.libSuffix:
|
||||
command += [ "-D", "LIB_SUFFIX:STRING=%s" % self.libSuffix ]
|
||||
command += [ toolSourceDir ]
|
||||
self._execute ( command, "Second CMake failed" )
|
||||
|
||||
if self._doBuild:
|
||||
command = [ "make" ]
|
||||
#command += [ "DESTDIR=%s" % self.installDir ]
|
||||
if self._enableDoc == "ON":
|
||||
#if tool == "crlcore" or tool == "stratus1":
|
||||
if tool == "stratus1":
|
||||
command += [ "dvi", "safepdf", "html" ]
|
||||
command += self._makeArguments
|
||||
print "Make command:", command
|
||||
sys.stdout.flush ()
|
||||
self._execute ( command, "Build failed" )
|
||||
return
|
||||
|
||||
|
||||
def _svnStatus ( self, tool ):
|
||||
toolSourceDir = os.path.join ( self.sourceDir , tool )
|
||||
if not os.path.isdir(toolSourceDir):
|
||||
if not self._quiet:
|
||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
||||
return
|
||||
os.chdir ( toolSourceDir )
|
||||
|
||||
print "Checking SVN status of tool: ", tool
|
||||
command = [ "svn", "status", "-u", "-q" ]
|
||||
self._execute ( command, "svn status -u -q" )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def _svnDiff ( self, tool ):
|
||||
toolSourceDir = os.path.join ( self.sourceDir , tool )
|
||||
if not os.path.isdir(toolSourceDir):
|
||||
if not self._quiet:
|
||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
||||
return
|
||||
os.chdir ( toolSourceDir )
|
||||
|
||||
print "Doing a SVN diff of tool: ", tool
|
||||
command = [ "svn", "diff" ]
|
||||
if self.svnTag != "x":
|
||||
command += [ "--revision", self.svnTag ]
|
||||
self._execute ( command, "svn diff %s" % tool )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def _svnUpdate ( self, tool ):
|
||||
toolSourceDir = os.path.join ( self.sourceDir , tool )
|
||||
if not os.path.isdir(toolSourceDir):
|
||||
if not self._quiet:
|
||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir)
|
||||
return
|
||||
os.chdir ( toolSourceDir )
|
||||
|
||||
print "Doing a SVN update of tool: ", tool
|
||||
command = [ "svn", "update" ]
|
||||
self._execute ( command, "svn update" )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def _svnCheckout ( self, tool ):
|
||||
project = self.getToolProject ( tool )
|
||||
if not project:
|
||||
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
|
||||
,"Cannot guess the SVN repository." )
|
||||
return
|
||||
if not project.getRepository ():
|
||||
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
|
||||
return
|
||||
|
||||
if not os.path.isdir(self.sourceDir):
|
||||
print ErrorMessage( 0, "Source directory <%s> doesn't exists. Creating."%self.sourceDir )
|
||||
os.makedirs( self.sourceDir )
|
||||
|
||||
toolSvnTrunkDir = os.path.join ( self.svnMethod+project.getRepository(), tool, "trunk" )
|
||||
os.chdir ( self.sourceDir )
|
||||
|
||||
print "Doing a SVN checkout of tool: ", tool
|
||||
command = [ "svn", "co", toolSvnTrunkDir, tool ]
|
||||
if self.svnTag != "x":
|
||||
command += [ "--revision", self.svnTag ]
|
||||
self._execute ( command, "svn checkout %s" % tool )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def _svnExport ( self, tool ):
|
||||
project = self.getToolProject ( tool )
|
||||
if not project:
|
||||
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
|
||||
, "Cannot guess the SVN repository.")
|
||||
return
|
||||
if not project.getRepository ():
|
||||
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
|
||||
return
|
||||
|
||||
toolSvnTrunkDir = os.path.join ( self.svnMethod+project.getRepository(), tool, "trunk" )
|
||||
|
||||
if not os.path.isdir ( self.archiveDir ):
|
||||
os.mkdir ( self.archiveDir )
|
||||
os.chdir ( self.archiveDir )
|
||||
|
||||
toolExportDir = os.path.join ( self.archiveDir, tool )
|
||||
if os.path.isdir ( toolExportDir ):
|
||||
print "Removing tool export (tarball) directory: \"%s\"." % toolExportDir
|
||||
command = [ "/bin/rm", "-r", toolExportDir ]
|
||||
self._execute ( command, "Removing tool export (tarball) directory" )
|
||||
|
||||
print "Doing a SVN export of tool: ", tool
|
||||
command = [ "svn", "export", toolSvnTrunkDir, toolExportDir ]
|
||||
if self.svnTag != "x":
|
||||
command += [ "--revision", self.svnTag ]
|
||||
self._execute ( command, "svn export %s" % toolExportDir )
|
||||
print
|
||||
return
|
||||
|
||||
|
||||
def _setEnvironment ( self, systemVariable, userVariable ):
|
||||
if not self._environment.has_key(systemVariable) or self._environment[systemVariable] == "":
|
||||
if not self._environment.has_key(userVariable) or self._environment[userVariable] == "" :
|
||||
self._environment[ systemVariable ] = self.installDir
|
||||
print "[WARNING] Neither <%s> nor <%s> environment variables are sets." \
|
||||
% (systemVariable,userVariable)
|
||||
print " Setting <%s> to <%s>." % (systemVariable,self.installDir)
|
||||
else:
|
||||
self._environment[ systemVariable ] = self._environment[ userVariable ]
|
||||
|
||||
if not self._quiet:
|
||||
print "Setting <%s> to <%s>." % (systemVariable,self._environment[systemVariable])
|
||||
if self._environment.has_key(userVariable):
|
||||
print "Transmitting <%s> as <%s>." % (userVariable,self._environment[userVariable])
|
||||
return
|
||||
|
||||
|
||||
def _commandTemplate ( self, tools, projects, command ):
|
||||
# Set or guess the various projects TOP environment variables.
|
||||
for project in self.projects:
|
||||
topVariable = "%s_TOP" % project.getName().upper()
|
||||
topUserVariable = "%s_USER_TOP" % project.getName().upper()
|
||||
self._setEnvironment ( topVariable, topUserVariable )
|
||||
|
||||
if tools:
|
||||
# Checks if the requested tools are in the various projects.
|
||||
self.standalones = tools
|
||||
for project in self.projects:
|
||||
self.standalones = project.activate ( self.standalones )
|
||||
for tool in self.standalones:
|
||||
print "[WARNING] Tool \"%s\" is not part of any project." % tool
|
||||
|
||||
if projects:
|
||||
for projectName in projects:
|
||||
project = self.getProject ( projectName )
|
||||
if not project:
|
||||
ErrorMessage( 1, "No project of name \"%s\"."%projectName ).terminate()
|
||||
project.activateAll()
|
||||
|
||||
if not tools and not projects:
|
||||
for project in self.projects:
|
||||
project.activateAll ()
|
||||
|
||||
for project in self.projects:
|
||||
for tool in project.getActives():
|
||||
print "\nProcessing tool: \"%s\"." % tool
|
||||
getattr(self,command) ( tool )
|
||||
|
||||
for tool in self.standalones:
|
||||
print "\nProcessing tool: \"%s\"." % tool
|
||||
getattr(self,command) ( tool )
|
||||
return
|
||||
|
||||
|
||||
def enable ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_enableTool" )
|
||||
return
|
||||
|
||||
|
||||
def enabledTools ( self ):
|
||||
tools = []
|
||||
for project in self.projects:
|
||||
tools += project.getActives()
|
||||
return tools
|
||||
|
||||
|
||||
def build ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_build" )
|
||||
return
|
||||
|
||||
|
||||
def svnStatus ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnStatus" )
|
||||
return
|
||||
|
||||
|
||||
def svnUpdate ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnUpdate" )
|
||||
return
|
||||
|
||||
|
||||
def svnCheckout ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnCheckout" )
|
||||
return
|
||||
|
||||
|
||||
def svnDiff ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnDiff" )
|
||||
return
|
||||
|
||||
|
||||
def svnExport ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_svnExport" )
|
||||
return
|
||||
|
||||
|
||||
def svnTarball ( self, tools, projects ):
|
||||
if self.svnTag == "x":
|
||||
self._guessSvnTag ( self.getProject(projects[0]) )
|
||||
|
||||
self._doSpec ()
|
||||
self._doDebChangelog ()
|
||||
|
||||
if os.path.isdir(self.tarballDir):
|
||||
print "Removing previous tarball directory: \"%s\"." % self.tarballDir
|
||||
command = [ "/bin/rm", "-rf", self.tarballDir ]
|
||||
self._execute ( command, "Removing top export (tarball) directory" )
|
||||
|
||||
print "Creating tarball directory: \"%s\"." % self.tarballDir
|
||||
os.makedirs ( self.tarballDir )
|
||||
self.svnExport ( tools, projects )
|
||||
|
||||
# Remove unpublisheds (yet) tools/files.
|
||||
for item in self.packageExcludes:
|
||||
command = [ "/bin/rm", "-rf", os.path.join(self.archiveDir,item) ]
|
||||
self._execute ( command, "rm of %s failed" % item)
|
||||
|
||||
# Adds files neededs only for packaging purpose.
|
||||
command = [ "/bin/cp", "-r", os.path.join(self.sourceDir ,"bootstrap","Makefile.package")
|
||||
, os.path.join(self.archiveDir,"Makefile") ]
|
||||
self._execute ( command, "copy of %s failed" % "boostrap/Makefile.package")
|
||||
|
||||
command = [ "/bin/cp", self.specFile, self.archiveDir ]
|
||||
self._execute ( command, "Copying RPM spec file" )
|
||||
|
||||
command = [ "/bin/cp", "-r", self.debianDir, self.archiveDir ]
|
||||
self._execute ( command, "Copying Debian/Ubuntu package control files" )
|
||||
|
||||
os.chdir ( self.archiveDir )
|
||||
#command = [ "/usr/bin/patch", "--remove-empty-files"
|
||||
# , "--no-backup-if-mismatch"
|
||||
# , "-p0", "-i", self.distribPatch ]
|
||||
#self._execute ( command, "patch for distribution command failed" )
|
||||
|
||||
os.chdir ( self.tarballDir )
|
||||
command = [ "/bin/tar"
|
||||
, "--exclude-backups"
|
||||
, "--exclude-vcs"
|
||||
, "-jcvf", self.sourceTarBz2, os.path.basename(self.archiveDir) ]
|
||||
self._execute ( command, "tar command failed" )
|
||||
|
||||
print "Cleanup SVN export tarball archive directory: \"%s\"." % self.archiveDir
|
||||
command = [ "/bin/rm", "-rf", self.archiveDir ]
|
||||
self._execute ( command, "Removing archive export (tarball) directory" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def userTarball ( self, tools, projects ):
|
||||
self.enable( tools, projects )
|
||||
|
||||
userSourceTarBz2 = os.path.join ( self.tarballDir
|
||||
, datetime.date.today().strftime('%s-%s-%%Y%%m%%d.tar.bz2'%
|
||||
(self.packageName
|
||||
,self.packageVersion)) )
|
||||
|
||||
excludes = []
|
||||
for exclude in self.packageExcludes:
|
||||
excludes += [ '--exclude='+exclude ]
|
||||
|
||||
os.chdir ( self.sourceDir )
|
||||
command = [ "/bin/tar"
|
||||
, "--exclude-backups"
|
||||
, "--exclude-vcs"
|
||||
, "--transform=s,^,%s/src/,"%self.projectDir ] \
|
||||
+ excludes \
|
||||
+ [ "-jcvf", userSourceTarBz2 ] \
|
||||
+ self.enabledTools()
|
||||
self._execute ( command, "tar command failed" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def doRpm ( self ):
|
||||
self.svnTarball ( [], self.packageProjects )
|
||||
|
||||
for rpmDir in [ "SOURCES", "SPECS", "BUILD", "tmp"
|
||||
, "SRPMS", "RPMS/i386", "RPMS/i686", "RPMS/x86_64" ]:
|
||||
rpmFullDir = os.path.join ( self.rpmbuildDir, rpmDir )
|
||||
if not os.path.isdir(rpmFullDir):
|
||||
os.makedirs ( rpmFullDir )
|
||||
|
||||
#rpmSpecFile = os.path.join ( self.rpmbuildDir, "SPECS" , "coriolis2.spec" )
|
||||
rpmSourceFile = os.path.join ( self.rpmbuildDir, "SOURCES", self.sourceTarBz2 )
|
||||
sourceFile = os.path.join ( self.tarballDir, self.sourceTarBz2 )
|
||||
|
||||
#if os.path.isfile ( rpmSpecFile ):
|
||||
# os.unlink ( rpmSpecFile )
|
||||
#os.symlink ( self.specFile, rpmSpecFile )
|
||||
|
||||
if not os.path.islink ( rpmSourceFile ):
|
||||
os.symlink ( sourceFile, rpmSourceFile )
|
||||
|
||||
os.chdir ( self.rpmbuildDir )
|
||||
|
||||
command = [ "/usr/bin/rpmbuild"
|
||||
, "--define", "_topdir %s" % self.rpmbuildDir
|
||||
, "--define", "_tmppath %s" % self.tmppathDir
|
||||
, "--define", "_enable_debug_packages 0"
|
||||
, "-ta", "--with", "binarytar", rpmSourceFile ]
|
||||
|
||||
self._execute ( command, "Rebuild rpm packages" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def doDeb ( self ):
|
||||
self.svnTarball ( [], self.packageProjects )
|
||||
|
||||
if not os.path.isdir(self.debbuildDir):
|
||||
os.makedirs ( self.debbuildDir )
|
||||
|
||||
os.chdir ( self.debbuildDir )
|
||||
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
|
||||
debOrigFile = os.path.join ( self.debbuildDir, "coriolis2_1.0.%s.orig.tar.bz2" % self.svnTag )
|
||||
if not os.path.islink(debOrigFile):
|
||||
os.link ( sourceFile, debOrigFile )
|
||||
|
||||
command = [ "/bin/tar", "jxf", debOrigFile ]
|
||||
self._execute ( command, "Unpacking pristine sources" )
|
||||
|
||||
#command = [ "/bin/cp", "-r", self.debianDir, "." ]
|
||||
#self._execute ( command, "Copying Debian/Ubuntu package control files" )
|
||||
|
||||
packageDir = os.path.join ( self.debbuildDir, "coriolis2-1.0.%s" % self.svnTag )
|
||||
os.chdir ( packageDir )
|
||||
|
||||
self._environment["CFLAGS" ] = "-O2"
|
||||
self._environment["CXXFLAGS"] = "-O2"
|
||||
command = [ "/usr/bin/debuild", "-us", "-uc" ]
|
||||
self._execute ( command, "Rebuild Debian packages" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def loadConfiguration ( self, confFile ): self._conf.load( confFile )
|
||||
def showConfiguration ( self ): self._conf.show()
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/BuilderGui.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from PyQt4.QtGui import QTabWidget
|
||||
from PyQt4.QtGui import QApplication
|
||||
from PyQt4.QtGui import QMainWindow
|
||||
from PyQt4.QtGui import QAction
|
||||
from PyQt4.QtGui import QKeySequence
|
||||
from OptionsWidget import OptionsWidget
|
||||
from CompileWidget import CompileWidget
|
||||
from ConfigureWidget import ConfigureWidget
|
||||
from AboutWidget import AboutWidget
|
||||
|
||||
|
||||
class BuilderGui ( QMainWindow ):
|
||||
|
||||
def __init__ ( self, confFile, parent=None ):
|
||||
QMainWindow.__init__( self, parent )
|
||||
self.setWindowTitle( 'Coriolis/Chams Builder' )
|
||||
self._tabWidget = QTabWidget()
|
||||
self._configureWidget = ConfigureWidget(confFile)
|
||||
self._optionsWidget = OptionsWidget(self._configureWidget.conf)
|
||||
self._compileWidget = CompileWidget()
|
||||
self._aboutWidget = AboutWidget()
|
||||
|
||||
self._tabWidget.addTab( self._optionsWidget , 'Options' )
|
||||
self._tabWidget.addTab( self._compileWidget , 'Compile' )
|
||||
self._tabWidget.addTab( self._configureWidget, 'Configure' )
|
||||
self.setCentralWidget( self._tabWidget )
|
||||
|
||||
self._compileWidget.conf = self._configureWidget
|
||||
self._compileWidget.options = self._optionsWidget
|
||||
|
||||
self._exitAction = QAction( '&Exit', self )
|
||||
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
|
||||
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
|
||||
self._exitAction.triggered.connect( QApplication.closeAllWindows )
|
||||
|
||||
self._saveAction = QAction( '&Save Settings', self )
|
||||
self._saveAction.setStatusTip( 'Save Settings' )
|
||||
self._saveAction.setShortcut ( QKeySequence('CTRL+S') )
|
||||
self._saveAction.triggered.connect( self._configureWidget.saveSettings )
|
||||
self._saveAction.triggered.connect( self._optionsWidget.saveSettings )
|
||||
self._saveAction.triggered.connect( self._compileWidget.saveSettings )
|
||||
|
||||
self._aboutAction = QAction( '&About', self )
|
||||
self._aboutAction.setStatusTip( 'A Word About Who\'s Responsible for This Thing' )
|
||||
self._aboutAction.setShortcut ( QKeySequence('CTRL+A') )
|
||||
self._aboutAction.triggered.connect( self._aboutWidget.show )
|
||||
|
||||
fileMenu = self.menuBar().addMenu( 'File' )
|
||||
fileMenu.addAction( self._exitAction )
|
||||
fileMenu.addAction( self._saveAction )
|
||||
fileMenu.addAction( self._aboutAction )
|
||||
return
|
||||
|
||||
def closeEvent ( self, event ):
|
||||
self._configureWidget.saveSettings()
|
||||
self._optionsWidget .saveSettings()
|
||||
self._compileWidget .saveSettings()
|
||||
event.accept()
|
||||
return
|
|
@ -0,0 +1,209 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/CompileWidget.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtCore import pyqtSignal
|
||||
from PyQt4.QtCore import QSettings
|
||||
from PyQt4.QtGui import QFont
|
||||
from PyQt4.QtGui import QColor
|
||||
from PyQt4.QtGui import QPalette
|
||||
from PyQt4.QtGui import QTextCharFormat
|
||||
from PyQt4.QtGui import QWidget
|
||||
from PyQt4.QtGui import QLabel
|
||||
from PyQt4.QtGui import QPushButton
|
||||
from PyQt4.QtGui import QCheckBox
|
||||
from PyQt4.QtGui import QGroupBox
|
||||
from PyQt4.QtGui import QButtonGroup
|
||||
from PyQt4.QtGui import QVBoxLayout
|
||||
from PyQt4.QtGui import QHBoxLayout
|
||||
from PyQt4.QtGui import QGridLayout
|
||||
from PyQt4.QtGui import QScrollArea
|
||||
from PyQt4.QtGui import QComboBox
|
||||
from PyQt4.QtGui import QLineEdit
|
||||
from PyQt4.QtGui import QTextEdit
|
||||
from PyQt4.QtGui import QFileDialog
|
||||
from PyQt4.QtGui import QProgressBar
|
||||
from PyQt4.QtGui import QApplication
|
||||
from builder.Highlighter import Highlighter
|
||||
|
||||
|
||||
class CompileWidget ( QWidget ):
|
||||
|
||||
progress = pyqtSignal(int)
|
||||
|
||||
def __init__ ( self, parent=None ):
|
||||
QWidget.__init__ ( self, parent )
|
||||
self._options = None
|
||||
self._conf = None
|
||||
|
||||
self._go = QPushButton( 'Go' )
|
||||
self._go.setMaximumWidth( 100 )
|
||||
font = self._go.font()
|
||||
font.setPointSizeF( font.pointSizeF()*2.0 )
|
||||
font.setWeight ( QFont.Bold )
|
||||
self._go.setFont( font )
|
||||
self._go.clicked.connect( self.go )
|
||||
|
||||
self._saveLog = QPushButton( 'Save' )
|
||||
saveLogLabel = QLabel( 'Log File:' )
|
||||
saveLogBrowse = QPushButton( '&Browse' )
|
||||
saveLogBrowse.clicked.connect( self.browseSaveLog )
|
||||
self._saveLogEdit = QLineEdit( '' )
|
||||
|
||||
gLayout = QGridLayout()
|
||||
gLayout.addWidget( saveLogLabel , 0, 0, 1, 1, Qt.AlignRight )
|
||||
gLayout.addWidget( self._saveLogEdit, 0, 1, 1, 6 )
|
||||
gLayout.addWidget( saveLogBrowse , 0, 7, 1, 1 )
|
||||
|
||||
self._console = QTextEdit()
|
||||
self._console.setLineWrapMode( QTextEdit.NoWrap )
|
||||
self._console.setMinimumSize ( 800, 400 )
|
||||
palette = self._console.palette()
|
||||
palette.setColor( QPalette.Base, QColor.fromRgb(255,255,221) ) # ffffdd.
|
||||
self._console.setPalette( palette )
|
||||
font = QFont( 'Bitstream Vera Sans Mono', self._console.font().pointSize() )
|
||||
self._console.setFont( font )
|
||||
self._highlighter = Highlighter( self._console.document() )
|
||||
|
||||
self._progressBar = QProgressBar()
|
||||
self._progressBar.setRange ( 0, 100 )
|
||||
self._progressBar.setTextVisible( True )
|
||||
|
||||
hLayout = QHBoxLayout()
|
||||
hLayout.addStretch()
|
||||
hLayout.addWidget( self._go )
|
||||
hLayout.addStretch()
|
||||
hLayout.addWidget( self._saveLog )
|
||||
hLayout.addStretch()
|
||||
|
||||
vLayout = QVBoxLayout()
|
||||
vLayout.addLayout( hLayout )
|
||||
vLayout.addLayout( gLayout )
|
||||
vLayout.addWidget( self._progressBar )
|
||||
vLayout.addWidget( self._console )
|
||||
self.setLayout( vLayout )
|
||||
|
||||
self.progress.connect( self._progressBar.setValue )
|
||||
self._saveLog.clicked.connect( self.saveLog )
|
||||
|
||||
self.readSettings()
|
||||
return
|
||||
|
||||
|
||||
def _setOptions ( self, options ): self._options = options
|
||||
def _setConf ( self, conf ): self._conf = conf
|
||||
def _getOptions ( self ): return self._options
|
||||
def _getConf ( self ): return self._conf
|
||||
|
||||
options = property( _getOptions, _setOptions )
|
||||
conf = property( _getConf , _setConf )
|
||||
|
||||
|
||||
def browseSaveLog ( self ):
|
||||
self._saveLogEdit.setText( QFileDialog.getSaveFileName(self
|
||||
,'Select Log File Report'
|
||||
,self._saveLogEdit.text()
|
||||
,'Report Files (*.log *.txt)') )
|
||||
return
|
||||
|
||||
def saveLog ( self ):
|
||||
if self._saveLogEdit.text():
|
||||
fd = open( self._saveLogEdit.text(), 'w+' )
|
||||
fd.write( self._console.toPlainText() )
|
||||
fd.close()
|
||||
return
|
||||
|
||||
|
||||
def shellCommand ( self ):
|
||||
command = [ 'buildCoriolis.py' ]
|
||||
for project in self.options.projects:
|
||||
for tool in project.actives:
|
||||
command += [ '--tool='+tool ]
|
||||
toolsCount = len(command) - 1
|
||||
|
||||
if self.conf.rootDir: command += [ '--root=%s'%self.conf.rootDir ]
|
||||
|
||||
if self.options.svnUpdate: command += [ '--svn-update' ]
|
||||
if self.options.svnStatus: command += [ '--svn-update' ]
|
||||
if self.options.enableDoc: command += [ '--doc' ]
|
||||
if self.options.noCache: command += [ '--no-cache' ]
|
||||
if self.options.rmBuild: command += [ '--rm-build' ]
|
||||
if self.options.verbose: command += [ '--verbose' ]
|
||||
if self.options.make:
|
||||
makeArguments='install '+self.options.threads
|
||||
command += [ '--make=%s'%makeArguments ]
|
||||
|
||||
if self.options.buildMode == 'Debug':
|
||||
command += [ '--debug' ]
|
||||
return toolsCount, command
|
||||
|
||||
|
||||
def go ( self ):
|
||||
rePercentage = re.compile(r'^\[\s*(?P<percent>\d+)%\].*')
|
||||
reProcessTool = re.compile(r'^Processing tool:\s*"(?P<tool>.+)"')
|
||||
|
||||
if not self.options or not self.conf: return
|
||||
|
||||
toolsCount, command = self.shellCommand()
|
||||
if not toolsCount: return
|
||||
|
||||
self._progressBar.reset()
|
||||
self._progressBar.setRange( 0, toolsCount*100 )
|
||||
|
||||
strCommand = command[0]
|
||||
for arg in command[1:]:
|
||||
strCommand += ' ' + arg
|
||||
strCommand += '\n\n'
|
||||
self._console.setFontItalic( True )
|
||||
self._console.insertPlainText( strCommand )
|
||||
self._console.setFontItalic( False )
|
||||
|
||||
toolsDone = -1
|
||||
builderProcess = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
|
||||
while True:
|
||||
line = builderProcess.stdout.readline()
|
||||
if line == '': break
|
||||
|
||||
m = rePercentage.match( line )
|
||||
if m:
|
||||
self.progress.emit( toolsDone*100+int(m.group('percent')) )
|
||||
else:
|
||||
m = reProcessTool.match( line )
|
||||
if m:
|
||||
toolsDone += 1
|
||||
|
||||
self._console.insertPlainText( line )
|
||||
|
||||
scrollBar = self._console.verticalScrollBar()
|
||||
scrollBar.setValue( scrollBar.maximum() )
|
||||
QApplication.processEvents()
|
||||
builderProcess.wait()
|
||||
if builderProcess.returncode == None:
|
||||
pass
|
||||
return
|
||||
|
||||
def readSettings ( self ):
|
||||
settings = QSettings()
|
||||
self._saveLogEdit.setText( settings.value('compile/saveLog').toString() )
|
||||
return
|
||||
|
||||
def saveSettings ( self ):
|
||||
settings = QSettings()
|
||||
settings.setValue( 'compile/saveLog', self._saveLogEdit.text() )
|
||||
return
|
|
@ -0,0 +1,293 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/Configuration.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import os.path
|
||||
import datetime
|
||||
import subprocess
|
||||
from . import ErrorMessage
|
||||
from Project import Project
|
||||
|
||||
|
||||
class Configuration ( object ):
|
||||
|
||||
PrimaryNames = \
|
||||
[ 'confFile', 'projects', 'standalones'
|
||||
, 'svnTag', 'svnMethod'
|
||||
, 'projectDir', 'rootDir'
|
||||
, 'packageName', 'packageVersion', 'packageExcludes', 'packageProject'
|
||||
, 'osType', 'libSuffix', 'buildMode', 'libMode', 'enableShared'
|
||||
]
|
||||
SecondaryNames = \
|
||||
[ 'rpmbuildDir' , 'debbuildDir' , 'tmppathDir' , 'tarballDir'
|
||||
, 'archiveDir' , 'sourceDir' , 'osDir' , 'buildDir'
|
||||
, 'installDir' , 'specFileIn' , 'specFile'
|
||||
, 'debianDir' , 'debChangelogIn', 'debChangelog', 'sourceTarBz2'
|
||||
, 'binaryTarBz2', 'distribPatch'
|
||||
]
|
||||
|
||||
def __init__ ( self ):
|
||||
self._confFile = None
|
||||
self._projects = []
|
||||
self._standalones = []
|
||||
self._svnTag = "x"
|
||||
self._svnMethod = None
|
||||
self._projectDir = 'coriolis-2.x'
|
||||
self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
|
||||
self._packageName = None
|
||||
self._packageVersion = None
|
||||
self._packageExcludes = []
|
||||
self._packageProject = []
|
||||
self._enableShared = 'ON'
|
||||
self._buildMode = 'Release'
|
||||
|
||||
# Secondary (derived) variables.
|
||||
# Setup by _updateSecondary().
|
||||
self._guessOs()
|
||||
self._updateSecondary()
|
||||
return
|
||||
|
||||
|
||||
def __setattr__ ( self, attribute, value ):
|
||||
if attribute in Configuration.SecondaryNames:
|
||||
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
|
||||
return
|
||||
|
||||
if attribute[0] == '_':
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute == 'rootDir': value = os.path.expanduser(value)
|
||||
elif attribute == 'enableShared' and value != 'ON': value = 'OFF'
|
||||
|
||||
self.__dict__['_'+attribute] = value
|
||||
self._updateSecondary()
|
||||
return
|
||||
|
||||
|
||||
def __getattr__ ( self, attribute ):
|
||||
if attribute[0] != '_': attribute = '_'+attribute
|
||||
if not self.__dict__.has_key(attribute):
|
||||
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
|
||||
return self.__dict__[attribute]
|
||||
|
||||
|
||||
def _updateSecondary ( self ):
|
||||
if self._enableShared == "ON": self._libMode = "Shared"
|
||||
else: self._libMode = "Static"
|
||||
|
||||
#self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
|
||||
self._rpmbuildDir = os.path.join ( self._rootDir , "rpmbuild" )
|
||||
self._debbuildDir = os.path.join ( self._rootDir , "debbuild" )
|
||||
self._tmppathDir = os.path.join ( self._rpmbuildDir, "tmp" )
|
||||
self._tarballDir = os.path.join ( self._rootDir , "tarball" )
|
||||
self._archiveDir = os.path.join ( self._tarballDir , "%s-%s.%s" % (self._packageName
|
||||
,self._packageVersion
|
||||
,self._svnTag) )
|
||||
self._sourceDir = os.path.join ( self._rootDir , "src" )
|
||||
self._osDir = os.path.join ( self._rootDir
|
||||
, self._osType
|
||||
, "%s.%s" % (self._buildMode,self._libMode) )
|
||||
self._buildDir = os.path.join ( self._osDir, "build" )
|
||||
self._installDir = os.path.join ( self._osDir, "install" )
|
||||
|
||||
self._specFileIn = os.path.join ( self._sourceDir, "bootstrap", "%s.spec.in"%self._packageName )
|
||||
self._specFile = os.path.join ( self._sourceDir, "bootstrap", "%s.spec" %self._packageName )
|
||||
self._debianDir = os.path.join ( self._sourceDir, "bootstrap", "debian" )
|
||||
self._debChangelogIn = os.path.join ( self._debianDir, "changelog.in" )
|
||||
self._debChangelog = os.path.join ( self._debianDir, "changelog" )
|
||||
self._sourceTarBz2 = "%s-%s.%s.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
|
||||
self._binaryTarBz2 = "%s-binary-%s.%s-1.slsoc6.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
|
||||
self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName )
|
||||
return
|
||||
|
||||
|
||||
def _guessOs ( self ):
|
||||
self._libSuffix = None
|
||||
self._osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*")
|
||||
self._osSlsoc6x = re.compile (".*Linux.*el6.*")
|
||||
self._osSLSoC5x_64 = re.compile (".*Linux.*el5.*x86_64.*")
|
||||
self._osSLSoC5x = re.compile (".*Linux.*(el5|2.6.23.13.*SoC).*")
|
||||
self._osLinux_64 = re.compile (".*Linux.*x86_64.*")
|
||||
self._osLinux = re.compile (".*Linux.*")
|
||||
self._osFreeBSD8x_amd64 = re.compile (".*FreeBSD 8.*amd64.*")
|
||||
self._osFreeBSD8x_64 = re.compile (".*FreeBSD 8.*x86_64.*")
|
||||
self._osFreeBSD8x = re.compile (".*FreeBSD 8.*")
|
||||
self._osDarwin = re.compile (".*Darwin.*")
|
||||
|
||||
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
|
||||
lines = uname.stdout.readlines()
|
||||
|
||||
if self._osSlsoc6x_64.match(lines[0]):
|
||||
self._osType = "Linux.slsoc6x_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSlsoc6x .match(lines[0]): self._osType = "Linux.slsoc6x"
|
||||
elif self._osSLSoC5x_64.match(lines[0]):
|
||||
self._osType = "Linux.SLSoC5x_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSLSoC5x .match(lines[0]): self._osType = "Linux.SLSoC5x"
|
||||
elif self._osLinux_64 .match(lines[0]):
|
||||
self._osType = "Linux.x86_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osLinux .match(lines[0]): self._osType = "Linux.i386"
|
||||
elif self._osDarwin .match(lines[0]): self._osType = "Darwin"
|
||||
elif self._osFreeBSD8x_amd64.match(lines[0]):
|
||||
self._osType = "FreeBSD.8x.amd64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osFreeBSD8x_64.match(lines[0]):
|
||||
self._osType = "FreeBSD.8x.x86_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osFreeBSD8x .match(lines[0]): self._osType = "FreeBSD.8x.i386"
|
||||
else:
|
||||
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
|
||||
self._osType = uname.stdout.readlines()[0][:-1]
|
||||
|
||||
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
|
||||
print " (using: \"%s\")" % self._osType
|
||||
|
||||
return
|
||||
|
||||
|
||||
def getPrimaryIds ( self ): return Configuration.PrimaryNames
|
||||
def getSecondaryIds ( self ): return Configuration.SecondaryNames
|
||||
def getAllIds ( self ): return Configuration.PrimaryNames + Configuration.SecondaryNames
|
||||
|
||||
|
||||
def register ( self, project ):
|
||||
for registered in self._projects:
|
||||
if registered.getName() == project.getName():
|
||||
print ErrorMessage( 0, "Project \"%s\" is already registered (ignored)." )
|
||||
return
|
||||
self._projects += [ project ]
|
||||
return
|
||||
|
||||
|
||||
def getProject ( self, name ):
|
||||
for project in self._projects:
|
||||
if project.getName() == name:
|
||||
return project
|
||||
return None
|
||||
|
||||
|
||||
def getToolProject ( self, name ):
|
||||
for project in self._projects:
|
||||
if project.hasTool(name):
|
||||
return project
|
||||
return None
|
||||
|
||||
|
||||
def load ( self, confFile ):
|
||||
moduleGlobals = globals()
|
||||
|
||||
if not confFile:
|
||||
print 'Making an educated guess to locate the configuration file:'
|
||||
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
, os.environ['HOME']+'/coriolis-2.x/src/bootstrap'
|
||||
, os.environ['HOME']+'/coriolis/src/bootstrap'
|
||||
, os.environ['HOME']+'/chams-2.x/src/bootstrap'
|
||||
, os.environ['HOME']+'/chams/src/bootstrap'
|
||||
, '/users/outil/coriolis/coriolis-2.x/src/bootstrap'
|
||||
, self._rootDir+'/src/bootstrap'
|
||||
]
|
||||
|
||||
for location in locations:
|
||||
self._confFile = location + '/build.conf'
|
||||
print ' <%s>' % self._confFile
|
||||
|
||||
if os.path.isfile(self._confFile): break
|
||||
if not self._confFile:
|
||||
ErrorMessage( 1, 'Cannot locate any configuration file.' ).terminate()
|
||||
else:
|
||||
print 'Using user-supplied configuration file:'
|
||||
print ' <%s>' % confFile
|
||||
|
||||
self._confFile = confFile
|
||||
if not os.path.isfile(self._confFile):
|
||||
ErrorMessage( 1, 'Missing configuration file:', '<%s>'%self._confFile ).terminate()
|
||||
|
||||
print 'Reading configuration from:'
|
||||
print ' <%s>' % self._confFile
|
||||
|
||||
try:
|
||||
execfile( self._confFile, moduleGlobals )
|
||||
except Exception, e:
|
||||
ErrorMessage( 1, 'An exception occured while loading the configuration file:'
|
||||
, '<%s>\n' % (self._confFile)
|
||||
, 'You should check for simple python errors in this file.'
|
||||
, 'Error was:'
|
||||
, '%s\n' % e ).terminate()
|
||||
|
||||
if moduleGlobals.has_key('projects'):
|
||||
entryNb = 0
|
||||
for entry in moduleGlobals['projects']:
|
||||
entryNb += 1
|
||||
if not entry.has_key('name'):
|
||||
raise ErrorMessage( 1, 'Missing project name in project entry #%d.' % entryNb )
|
||||
if not entry.has_key('tools'):
|
||||
raise ErrorMessage( 1, 'Missing tools list in project entry #%d (<%s>).' \
|
||||
% (entryNb,entry['name']) )
|
||||
if not isinstance(entry['tools'],list):
|
||||
raise ErrorMessage( 1, 'Tools item of project entry #%d (<%s>) is not a list.' \
|
||||
% (entryNb,entry['name']) )
|
||||
if not entry.has_key('repository'):
|
||||
raise ErrorMessage( 1, 'Missing project repository in project entry #%d.' \
|
||||
% entryNb )
|
||||
|
||||
self.register( Project(entry['name'],entry['tools'],entry['repository']) )
|
||||
else:
|
||||
ErrorMessage( 1, 'Configuration file is missing the \'project\' symbol.'
|
||||
, '<%s>'%self._confFile ).terminate()
|
||||
|
||||
if moduleGlobals.has_key('projectdir'):
|
||||
self.projectDir = moduleGlobals['projectdir']
|
||||
|
||||
if moduleGlobals.has_key('svnconfig'):
|
||||
svnconfig = moduleGlobals['svnconfig']
|
||||
if svnconfig.has_key('method'): self._svnMethod = svnconfig['method']
|
||||
|
||||
if moduleGlobals.has_key('package'):
|
||||
package = moduleGlobals['package']
|
||||
if package.has_key('name' ): self.packageName = package['name']
|
||||
if package.has_key('version' ): self.packageVersion = package['version']
|
||||
if package.has_key('excludes'):
|
||||
if not isinstance(package['excludes'],list):
|
||||
raise ErrorMessage( 1, 'Excludes of package configuration is not a list.')
|
||||
self._packageExcludes = package['excludes']
|
||||
if package.has_key('projects'):
|
||||
if not isinstance(package['projects'],list):
|
||||
raise ErrorMessage( 1, 'Projects to package is not a list.')
|
||||
self._packageProjects = package['projects']
|
||||
return
|
||||
|
||||
|
||||
def show ( self ):
|
||||
print 'CCB Configuration:'
|
||||
if self._svnMethod:
|
||||
print ' SVN Method: <%s>' % self._svnMethod
|
||||
else:
|
||||
print ' SVN Method not defined, will not be able to checkout/commit.'
|
||||
|
||||
for project in self._projects:
|
||||
print ' project:%-15s repository:<%s>' % ( ('<%s>'%project.getName()), project.getRepository() )
|
||||
toolOrder = 1
|
||||
for tool in project.getTools():
|
||||
print '%s%02d:<%s>' % (' '*26,toolOrder,tool)
|
||||
toolOrder += 1
|
||||
print
|
||||
return
|
|
@ -0,0 +1,195 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/ConfigureWidget.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtCore import QVariant
|
||||
from PyQt4.QtCore import pyqtSignal
|
||||
from PyQt4.QtCore import QSettings
|
||||
from PyQt4.QtGui import QFont
|
||||
from PyQt4.QtGui import QWidget
|
||||
from PyQt4.QtGui import QGridLayout
|
||||
from PyQt4.QtGui import QHBoxLayout
|
||||
from PyQt4.QtGui import QVBoxLayout
|
||||
from PyQt4.QtGui import QLabel
|
||||
from PyQt4.QtGui import QPushButton
|
||||
from PyQt4.QtGui import QLineEdit
|
||||
from PyQt4.QtCore import QModelIndex
|
||||
from PyQt4.QtCore import QAbstractTableModel
|
||||
from PyQt4.QtGui import QAbstractItemView
|
||||
from PyQt4.QtGui import QHeaderView
|
||||
from PyQt4.QtGui import QTableView
|
||||
from PyQt4.QtGui import QGroupBox
|
||||
from PyQt4.QtGui import QFileDialog
|
||||
from PyQt4.QtGui import QApplication
|
||||
from Configuration import Configuration
|
||||
|
||||
|
||||
class ConfSettingsModel ( QAbstractTableModel ):
|
||||
|
||||
HeaderFont = QApplication.font()
|
||||
PrimaryFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Normal)
|
||||
SecondaryFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Normal)
|
||||
ValueFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Bold)
|
||||
|
||||
def __init__ ( self, conf, parent=None ):
|
||||
ConfSettingsModel.HeaderFont.setBold( True )
|
||||
ConfSettingsModel.SecondaryFont.setItalic( True )
|
||||
|
||||
QAbstractTableModel.__init__( self, parent )
|
||||
self._conf = conf
|
||||
self._ids = self._conf.getAllIds()
|
||||
return
|
||||
|
||||
def data ( self, index, role ):
|
||||
if role == Qt.SizeHintRole:
|
||||
if index.column() == 0: return 300
|
||||
else: return -1
|
||||
elif role == Qt.FontRole:
|
||||
if index.column() == 0:
|
||||
if index.row() >= len(self._conf.getPrimaryIds()):
|
||||
return ConfSettingsModel.SecondaryFont
|
||||
return ConfSettingsModel.PrimaryFont
|
||||
else:
|
||||
return ConfSettingsModel.ValueFont
|
||||
elif role == Qt.DisplayRole:
|
||||
row = index.row()
|
||||
if row < self.rowCount():
|
||||
if index.column() == 0: return self._ids[row]
|
||||
elif index.column() == 1: return getattr( self._conf, self._ids[row] )
|
||||
|
||||
return QVariant()
|
||||
|
||||
|
||||
def headerData ( self, section, orientation, role ):
|
||||
if orientation == Qt.Vertical: return QVariant()
|
||||
if role == Qt.FontRole: return ConfSettingsModel.HeaderFont
|
||||
if role != Qt.DisplayRole: return QVariant()
|
||||
|
||||
if section == 0: return 'Setting'
|
||||
elif section == 1: return 'Value'
|
||||
|
||||
return QVariant('?')
|
||||
|
||||
|
||||
def rowCount ( self, index=QModelIndex() ): return len(self._ids)
|
||||
def columnCount ( self, index=QModelIndex() ): return 2
|
||||
|
||||
|
||||
class ConfSettingsWidget ( QWidget ):
|
||||
|
||||
def __init__ ( self, conf, parent=None ):
|
||||
QWidget.__init__( self, parent )
|
||||
self._rowHeight = 20
|
||||
|
||||
self._view = QTableView()
|
||||
self._view.setShowGrid ( False )
|
||||
self._view.setAlternatingRowColors( True )
|
||||
self._view.setSelectionBehavior ( QAbstractItemView.SelectRows )
|
||||
#self._view.setSortingEnabled ( True )
|
||||
#self._view.installEventFilter ( self )
|
||||
|
||||
horizontalHeader = self._view.horizontalHeader ()
|
||||
horizontalHeader.setStretchLastSection ( True )
|
||||
horizontalHeader.setMinimumSectionSize ( 150 )
|
||||
horizontalHeader.setResizeMode ( QHeaderView.ResizeToContents )
|
||||
horizontalHeader.setDefaultSectionSize ( 150 )
|
||||
|
||||
verticalHeader = self._view.verticalHeader ();
|
||||
verticalHeader.setVisible ( False );
|
||||
verticalHeader.setDefaultSectionSize ( self._rowHeight );
|
||||
|
||||
self._baseModel = ConfSettingsModel( conf )
|
||||
self._view.setModel( self._baseModel );
|
||||
self._view.horizontalHeader().setStretchLastSection( True );
|
||||
self._view.resizeColumnToContents( 0 );
|
||||
|
||||
peanoDataLayout = QGridLayout();
|
||||
peanoDataLayout.addWidget( self._view, 0, 0, 1, 1 );
|
||||
|
||||
self.setLayout ( peanoDataLayout );
|
||||
return
|
||||
|
||||
|
||||
class ConfigureWidget ( QWidget ):
|
||||
|
||||
def __init__ ( self, confFile, parent=None ):
|
||||
QWidget.__init__ ( self, parent )
|
||||
self._confFile = confFile
|
||||
self._conf = Configuration()
|
||||
self._rootDir = ''
|
||||
|
||||
rootDirLabel = QLabel( 'Root Directory' )
|
||||
rootDirBrowse = QPushButton( '&Browse' )
|
||||
rootDirBrowse.clicked.connect( self.browseRootDir )
|
||||
self._rootDirEdit = QLineEdit( '' )
|
||||
#self._rootDirEdit.setFixedWidth( 600 )
|
||||
|
||||
gLayout = QGridLayout()
|
||||
gLayout.addWidget( rootDirLabel , 0, 0, 1, 1 )
|
||||
gLayout.addWidget( self._rootDirEdit, 0, 1, 1, 6 )
|
||||
gLayout.addWidget( rootDirBrowse , 0, 7, 1, 1 )
|
||||
groupDirs = QGroupBox( 'Directories' )
|
||||
groupDirs.setLayout( gLayout )
|
||||
|
||||
gLayout = QGridLayout()
|
||||
groupConf = QGroupBox( 'Configuration' )
|
||||
groupConf.setLayout( gLayout )
|
||||
|
||||
vLayout = QVBoxLayout()
|
||||
vLayout.addWidget ( groupDirs )
|
||||
vLayout.addWidget ( groupConf )
|
||||
#vLayout.addStretch()
|
||||
|
||||
self.setLayout( vLayout )
|
||||
|
||||
self._rootDirEdit.textChanged.connect( self.rootDirChanged )
|
||||
|
||||
self.readSettings()
|
||||
|
||||
noteLabel = QLabel( 'Those settings can be changed only by editing build.conf' )
|
||||
gLayout.addWidget( noteLabel , 0, 0, 1, 1 )
|
||||
gLayout.addWidget( ConfSettingsWidget(self._conf), 1, 0, 1, 1 )
|
||||
|
||||
|
||||
def _getRootDir ( self ): return self._rootDir
|
||||
def _getConf ( self ): return self._conf
|
||||
|
||||
rootDir = property( _getRootDir )
|
||||
conf = property( _getConf )
|
||||
|
||||
|
||||
def rootDirChanged ( self, rootDir ):
|
||||
self._rootDir = rootDir
|
||||
return
|
||||
|
||||
def browseRootDir ( self ):
|
||||
self._rootDirEdit.setText( QFileDialog.getExistingDirectory(self,'Select the Building Root Directory') )
|
||||
return
|
||||
|
||||
def readSettings ( self ):
|
||||
settings = QSettings()
|
||||
self._rootDirEdit.setText( settings.value('conf/rootDir').toString() )
|
||||
if not self._confFile and settings.value('conf/confFile'):
|
||||
self._confFile = str( settings.value('conf/confFile').toString() )
|
||||
self._conf.load( self._confFile )
|
||||
return
|
||||
|
||||
def saveSettings ( self ):
|
||||
settings = QSettings()
|
||||
settings.setValue( 'conf/rootDir' , self._rootDirEdit.text() )
|
||||
settings.setValue( 'conf/confFile', self._confFile )
|
||||
return
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/Highlighter.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import re
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtGui import QFont
|
||||
from PyQt4.QtGui import QColor
|
||||
from PyQt4.QtGui import QTextCharFormat
|
||||
from PyQt4.QtGui import QSyntaxHighlighter
|
||||
|
||||
|
||||
class Highlighter ( QSyntaxHighlighter ):
|
||||
|
||||
Normal = 0x0001
|
||||
Bold = 0x0002
|
||||
Italic = 0x0004
|
||||
|
||||
ttyBackground = QColor.fromRgb( 255, 255, 221 ) # #ffffdd
|
||||
ttyBlack = QColor.fromRgb( 46, 52, 54 ) # #2e3436
|
||||
ttyRed = QColor.fromRgb( 204, 0, 0 ) # #cc0000
|
||||
ttyGreen = QColor.fromRgb( 78, 154, 6 ) # #4e9a06
|
||||
ttyYellow = QColor.fromRgb( 196, 160, 0 ) # #c4a000
|
||||
ttyBlue = QColor.fromRgb( 52, 101, 164 ) # #3465a4
|
||||
ttyViolet = QColor.fromRgb( 117, 80, 123 ) # #75507b
|
||||
ttyCyan = QColor.fromRgb( 6, 152, 154 ) # #06989a
|
||||
ttyGrey = QColor.fromRgb( 211, 215, 207 ) # #d3d7cf
|
||||
ttyLightBlack = QColor.fromRgb( 85, 87, 83 ) # #555753
|
||||
ttyLightRed = QColor.fromRgb( 239, 41, 41 ) # #ef2929
|
||||
ttyLightGreen = QColor.fromRgb( 138, 226, 52 ) # #8ae234
|
||||
ttyLightYellow = QColor.fromRgb( 252, 233, 79 ) # #fce94f
|
||||
ttyLightBlue = QColor.fromRgb( 114, 159, 207 ) # #729fcf
|
||||
ttyLightViolet = QColor.fromRgb( 173, 127, 168 ) # #ad7fa8
|
||||
ttyLightCyan = QColor.fromRgb( 52, 226, 226 ) # #34e2e2
|
||||
ttyLightGrey = QColor.fromRgb( 238, 238, 236 ) # #eeeeec
|
||||
|
||||
Rules = [ [ttyLightViolet, Bold , re.compile(r'^Scanning.*'), None]
|
||||
, [ttyLightRed , Bold , re.compile(r'^Linking.*'), None]
|
||||
, [ttyLightGreen , Normal , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Building.*)'), None]
|
||||
, [ttyLightGreen , Bold , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Built target.*)'), None]
|
||||
, [ttyLightBlue , Normal , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Generating.*moc_.*)'), None]
|
||||
, [ttyLightBlue , Bold , re.compile(r'^Generating.*'), None]
|
||||
, [ttyLightCyan , Normal , re.compile(r'^Install the project.*'), None]
|
||||
, [ttyCyan , Bold , re.compile(r'^-- Install.*'), None]
|
||||
, [ttyCyan , Bold|Italic, re.compile(r'^-- Up-to-date.*'), None]
|
||||
]
|
||||
|
||||
def __init__ ( self, parent=None ):
|
||||
QSyntaxHighlighter.__init__ ( self, parent )
|
||||
for rule in Highlighter.Rules:
|
||||
if not rule[3]:
|
||||
rule[3] = QTextCharFormat()
|
||||
rule[3].setForeground( rule[0] )
|
||||
if rule[1] & Highlighter.Normal: rule[3].setFontWeight( QFont.Normal )
|
||||
if rule[1] & Highlighter.Bold: rule[3].setFontWeight( QFont.Bold )
|
||||
if rule[1] & Highlighter.Italic: rule[3].setFontItalic( True )
|
||||
return
|
||||
|
||||
def highlightBlock ( self, line ):
|
||||
for rule in Highlighter.Rules:
|
||||
m = rule[2].match(line)
|
||||
if m:
|
||||
if m.groupdict().has_key('percent'):
|
||||
self.setFormat( 7, len(line), rule[3] )
|
||||
else:
|
||||
self.setFormat( 0, len(line), rule[3] )
|
||||
return
|
|
@ -0,0 +1,179 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/OptionsWidget.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtCore import pyqtSignal
|
||||
from PyQt4.QtCore import QSettings
|
||||
from PyQt4.QtGui import QColor
|
||||
from PyQt4.QtGui import QWidget
|
||||
from PyQt4.QtGui import QPushButton
|
||||
from PyQt4.QtGui import QCheckBox
|
||||
from PyQt4.QtGui import QGroupBox
|
||||
from PyQt4.QtGui import QButtonGroup
|
||||
from PyQt4.QtGui import QVBoxLayout
|
||||
from PyQt4.QtGui import QHBoxLayout
|
||||
from PyQt4.QtGui import QGridLayout
|
||||
from PyQt4.QtGui import QScrollArea
|
||||
from PyQt4.QtGui import QComboBox
|
||||
from builder.Project import Project
|
||||
from builder.ConfigureWidget import ConfigureWidget
|
||||
from builder.ProjectWidgets import ProjectWidgets
|
||||
|
||||
|
||||
class OptionsWidget ( QWidget ):
|
||||
|
||||
progress = pyqtSignal(int)
|
||||
|
||||
def __init__ ( self, conf, parent=None ):
|
||||
QWidget.__init__ ( self, parent )
|
||||
self._conf = conf
|
||||
self._projects = []
|
||||
for project in self._conf.projects:
|
||||
self._projects += [ ProjectWidgets(project) ]
|
||||
|
||||
gLayout = QGridLayout()
|
||||
for column in range(len(self._projects)):
|
||||
self._projects[column].addToLayout( column, gLayout )
|
||||
toolsGroup = QGroupBox( 'Projects && Tools' )
|
||||
toolsGroup.setLayout( gLayout )
|
||||
|
||||
scrollToolsGroup = QScrollArea()
|
||||
scrollToolsGroup.setMinimumHeight( 400 )
|
||||
#scrollToolsGroup.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOn )
|
||||
scrollToolsGroup.setWidget( toolsGroup )
|
||||
|
||||
self._buildMode = QComboBox()
|
||||
self._buildMode.addItems( ('Release', 'Debug') )
|
||||
self._svnUpdate = QCheckBox( 'SVN Update' )
|
||||
self._svnStatus = QCheckBox( 'SVN Status' )
|
||||
self._make = QCheckBox( 'Build' )
|
||||
self._enableDoc = QCheckBox( 'Build Documentation' )
|
||||
self._noCache = QCheckBox( 'Remove previous CMake cache' )
|
||||
self._rmBuild = QCheckBox( 'Cleanup Build Directory' )
|
||||
self._verbose = QCheckBox( 'Display Compiler Commands' )
|
||||
self._threads = QComboBox()
|
||||
for j in range(16):
|
||||
self._threads.addItem( '-j%d'%(j+1), j+1 )
|
||||
|
||||
self._commandGroup = QButtonGroup()
|
||||
self._commandGroup.setExclusive( True )
|
||||
self._commandGroup.addButton( self._svnUpdate )
|
||||
self._commandGroup.addButton( self._svnStatus )
|
||||
self._commandGroup.addButton( self._make )
|
||||
|
||||
vLayout = QVBoxLayout()
|
||||
vLayout.addWidget( self._svnUpdate )
|
||||
vLayout.addWidget( self._svnStatus )
|
||||
vLayout.addWidget( self._make )
|
||||
vLayout.addStretch()
|
||||
commandGroup = QGroupBox( 'Command' )
|
||||
commandGroup.setLayout( vLayout )
|
||||
|
||||
vLayout = QVBoxLayout()
|
||||
vLayout.addWidget( self._buildMode )
|
||||
vLayout.addWidget( self._enableDoc )
|
||||
vLayout.addWidget( self._noCache )
|
||||
vLayout.addWidget( self._rmBuild )
|
||||
vLayout.addStretch()
|
||||
optionsGroup = QGroupBox( 'Command Options' )
|
||||
optionsGroup.setLayout( vLayout )
|
||||
|
||||
vLayout = QVBoxLayout()
|
||||
vLayout.addWidget( self._threads )
|
||||
vLayout.addWidget( self._verbose )
|
||||
vLayout.addStretch()
|
||||
miscGroup = QGroupBox( 'Misc. Options' )
|
||||
miscGroup.setLayout( vLayout )
|
||||
|
||||
hLayout = QHBoxLayout()
|
||||
hLayout.addWidget( commandGroup )
|
||||
hLayout.addWidget( optionsGroup )
|
||||
hLayout.addWidget( miscGroup )
|
||||
commands = QWidget()
|
||||
commands.setLayout( hLayout )
|
||||
|
||||
vLayout = QVBoxLayout()
|
||||
vLayout.addWidget( commands )
|
||||
vLayout.addWidget( scrollToolsGroup )
|
||||
vLayout.addStretch()
|
||||
self.setLayout( vLayout )
|
||||
|
||||
self.readSettings()
|
||||
return
|
||||
|
||||
|
||||
def _getProjects ( self ): return self._projects
|
||||
def _getBuildMode ( self ): return self._buildMode.currentText()
|
||||
def _getThreads ( self ): return self._threads.currentText()
|
||||
def _getSvnUpdate ( self ): return self._svnUpdate.isChecked()
|
||||
def _getSvnStatus ( self ): return self._svnStatus.isChecked()
|
||||
def _getMake ( self ): return self._make.isChecked()
|
||||
def _getEnableDoc ( self ): return self._enableDoc.isChecked()
|
||||
def _getNoCache ( self ): return self._noCache.isChecked()
|
||||
def _getRmBuild ( self ): return self._rmBuild.isChecked()
|
||||
def _getVerbose ( self ): return self._verbose.isChecked()
|
||||
|
||||
projects = property( _getProjects )
|
||||
buildMode = property( _getBuildMode )
|
||||
threads = property( _getThreads )
|
||||
svnUpdate = property( _getSvnUpdate )
|
||||
svnStatus = property( _getSvnStatus )
|
||||
make = property( _getMake )
|
||||
enableDoc = property( _getEnableDoc )
|
||||
noCache = property( _getNoCache )
|
||||
rmBuild = property( _getRmBuild )
|
||||
verbose = property( _getVerbose )
|
||||
|
||||
|
||||
def readSettings ( self ):
|
||||
settings = QSettings()
|
||||
self._svnUpdate.setChecked( settings.value('builder/svnUpdate').toBool() )
|
||||
self._svnStatus.setChecked( settings.value('builder/svnStatus').toBool() )
|
||||
self._make .setChecked( settings.value('builder/make' ).toBool() )
|
||||
self._enableDoc.setChecked( settings.value('builder/enableDoc').toBool() )
|
||||
self._noCache .setChecked( settings.value('builder/noCache' ).toBool() )
|
||||
self._rmBuild .setChecked( settings.value('builder/rmBuild' ).toBool() )
|
||||
self._verbose .setChecked( settings.value('builder/verbose' ).toBool() )
|
||||
|
||||
buildModeName = settings.value('builder/buildMode').toString()
|
||||
index = self._buildMode.findText( buildModeName )
|
||||
if index >= 0: self._buildMode.setCurrentIndex( index )
|
||||
|
||||
threads = settings.value('builder/threads').toString()
|
||||
index = self._threads.findText( threads )
|
||||
if index >= 0: self._threads.setCurrentIndex( index )
|
||||
|
||||
for project in self._projects: project.readFromSettings()
|
||||
return
|
||||
|
||||
|
||||
def saveSettings ( self ):
|
||||
settings = QSettings()
|
||||
settings.setValue('builder/svnUpdate', self._svnUpdate.isChecked() )
|
||||
settings.setValue('builder/svnStatus', self._svnStatus.isChecked() )
|
||||
settings.setValue('builder/make' , self._make .isChecked() )
|
||||
settings.setValue('builder/enableDoc', self._enableDoc.isChecked() )
|
||||
settings.setValue('builder/buildMode', self._buildMode.currentText() )
|
||||
settings.setValue('builder/noCache' , self._noCache .isChecked() )
|
||||
settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() )
|
||||
settings.setValue('builder/verbose' , self._verbose .isChecked() )
|
||||
settings.setValue('builder/threads' , self._threads .currentText() )
|
||||
|
||||
for project in self._projects: project.saveToSettings()
|
||||
return
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/Project.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
class Project ( object ):
|
||||
|
||||
def __init__ ( self, name, tools, repository ):
|
||||
self._name = name
|
||||
self._tools = tools
|
||||
self._repository = repository
|
||||
self._actives = []
|
||||
return
|
||||
|
||||
def getName ( self ): return self._name
|
||||
def getTools ( self ): return self._tools
|
||||
def getRepository ( self ): return self._repository
|
||||
def getActives ( self ): return self._actives
|
||||
def hasTool ( self, tool ): return tool in self._tools
|
||||
|
||||
def desactivate ( self ):
|
||||
self._active = []
|
||||
return
|
||||
|
||||
def activateAll ( self ):
|
||||
self._actives = self._tools
|
||||
return
|
||||
|
||||
def activate ( self, tools ):
|
||||
# Build the ordered list.
|
||||
for tool in self._tools:
|
||||
if (tool in tools) and not (tool in self._actives):
|
||||
self._actives += [ tool ]
|
||||
# Find the tools not part of the project.
|
||||
rejecteds = []
|
||||
for tool in tools:
|
||||
if not (tool in self._tools) and (not tool in rejecteds):
|
||||
rejecteds += [ tool ]
|
||||
return rejecteds
|
|
@ -0,0 +1,76 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/ProjectWidget.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtCore import QObject
|
||||
from PyQt4.QtCore import QSettings
|
||||
from PyQt4.QtGui import QPushButton
|
||||
from PyQt4.QtGui import QCheckBox
|
||||
|
||||
|
||||
class ProjectWidgets ( QObject ):
|
||||
|
||||
def __init__ ( self, project ):
|
||||
self._project = project
|
||||
self._projectButton = QPushButton( self._project.getName() )
|
||||
self._projectButton.setStyleSheet( 'font-weight: bold;' )
|
||||
|
||||
self._toolsCheckBoxes = []
|
||||
for tool in self._project.getTools():
|
||||
self._toolsCheckBoxes += [ QCheckBox( tool ) ]
|
||||
|
||||
#self._projectButton.clicked.connect( self.toggleToolsVisibility )
|
||||
return
|
||||
|
||||
def _getProjectButton ( self ): return self._projectButton
|
||||
def _getToolsCheckBoxes ( self ): return self._toolsCheckBoxes
|
||||
|
||||
def _getActives ( self ):
|
||||
actives = []
|
||||
for toolCb in self._toolsCheckBoxes:
|
||||
if toolCb.isChecked(): actives += [ str(toolCb.text()) ]
|
||||
return actives
|
||||
|
||||
projectButton = property( _getProjectButton )
|
||||
toolsCheckBoxes = property( _getToolsCheckBoxes )
|
||||
actives = property( _getActives )
|
||||
|
||||
def addToLayout( self, column, layout ):
|
||||
layout.addWidget( self._projectButton, 0, column, Qt.AlignLeft )
|
||||
for row in range(len(self._toolsCheckBoxes)):
|
||||
layout.addWidget( self._toolsCheckBoxes[row], row+1, column, Qt.AlignTop )
|
||||
return
|
||||
|
||||
#def toggleToolsVisibility ( self ):
|
||||
# self._visibleTools = not self._visibleTools
|
||||
# for toolCb in self._toolsCheckBoxes:
|
||||
# toolCb.setVisible( self._visibleTools )
|
||||
# return
|
||||
|
||||
def readFromSettings ( self ):
|
||||
settings = QSettings()
|
||||
for toolCb in self._toolsCheckBoxes:
|
||||
toolId = 'tools/'+self._project.getName()+'/'+toolCb.text()
|
||||
toolCb.setChecked( settings.value(toolId).toBool() )
|
||||
return
|
||||
|
||||
def saveToSettings ( self ):
|
||||
settings = QSettings()
|
||||
for toolCb in self._toolsCheckBoxes:
|
||||
toolId = 'tools/'+self._project.getName()+'/'+toolCb.text()
|
||||
settings.setValue( toolId, toolCb.isChecked() )
|
||||
return
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
# -*- mode:Python -*-
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
class ErrorMessage ( Exception ):
|
||||
|
||||
def __init__ ( self, code, *arguments ):
|
||||
self._code = code
|
||||
self._errors = [ 'Malformed call to ErrorMessage()'
|
||||
, '%s' % str(arguments) ]
|
||||
|
||||
text = None
|
||||
if len(arguments) == 1:
|
||||
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
|
||||
else:
|
||||
self._errors = arguments[0]
|
||||
elif len(arguments) > 1:
|
||||
text = list(arguments)
|
||||
|
||||
if text:
|
||||
self._errors = []
|
||||
while len(text[0]) == 0: del text[0]
|
||||
|
||||
lstrip = 0
|
||||
if text[0].startswith('[ERROR]'): lstrip = 8
|
||||
|
||||
for line in text:
|
||||
if line[0:lstrip ] == ' '*lstrip or \
|
||||
line[0:lstrip-1] == '[ERROR]':
|
||||
self._errors += [ line[lstrip:] ]
|
||||
else:
|
||||
self._errors += [ line.lstrip() ]
|
||||
return
|
||||
|
||||
def __str__ ( self ):
|
||||
if not isinstance(self._errors,list):
|
||||
return "[ERROR] %s" % self._errors
|
||||
|
||||
formatted = "\n"
|
||||
for i in range(len(self._errors)):
|
||||
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
|
||||
else: formatted += " %s" % self._errors[i]
|
||||
if i+1 < len(self._errors): formatted += "\n"
|
||||
return formatted
|
||||
|
||||
def addMessage ( self, message ):
|
||||
if not isinstance(self._errors,list):
|
||||
self._errors = [ self._errors ]
|
||||
if isinstance(message,list):
|
||||
for line in message:
|
||||
self._errors += [ line ]
|
||||
else:
|
||||
self._errors += [ message ]
|
||||
return
|
||||
|
||||
def terminate ( self ):
|
||||
print self
|
||||
sys.exit(self._code)
|
||||
|
||||
def _getCode ( self ): return self._code
|
||||
|
||||
code = property(_getCode)
|
|
@ -0,0 +1,256 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Authors : Jean-Paul Chaput |
|
||||
# | Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./ccb.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
showTrace = True
|
||||
|
||||
try:
|
||||
import sys
|
||||
import os.path
|
||||
import optparse
|
||||
import traceback
|
||||
import distutils.sysconfig
|
||||
import subprocess
|
||||
import re
|
||||
except ImportError, e:
|
||||
module = str(e).split()[-1]
|
||||
|
||||
print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module
|
||||
print ' Please check your standard Python installation, it may have problems.'
|
||||
quit()
|
||||
|
||||
|
||||
def safeImport ( moduleName, symbol=None ):
|
||||
try:
|
||||
module = __import__( moduleName, globals(), locals(), symbol )
|
||||
except ImportError, e:
|
||||
print '[ERROR] The <%s> python module or symbol cannot be loaded.' % moduleName
|
||||
print ' Please check the integrity of the <coriolis/boostrap> package.'
|
||||
if showTrace: traceback.print_tb(sys.exc_info()[2])
|
||||
sys.exit(1)
|
||||
except Exception, e:
|
||||
print '[ERROR] An exception occured while importing module <%s>. Is is a bug,' % moduleName
|
||||
print ' you may want to report it...'
|
||||
print ' %s' % e
|
||||
if showTrace: traceback.print_tb(sys.exc_info()[2])
|
||||
sys.exit(2)
|
||||
if symbol: return module.__dict__[symbol]
|
||||
return module
|
||||
|
||||
|
||||
def guessOs ():
|
||||
libDir = 'lib'
|
||||
osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*")
|
||||
osSlsoc6x = re.compile (".*Linux.*el6.*")
|
||||
osSLSoC5x_64 = re.compile (".*Linux.*el5.*x86_64.*")
|
||||
osSLSoC5x = re.compile (".*Linux.*(el5|2.6.23.13.*SoC).*")
|
||||
osLinux_64 = re.compile (".*Linux.*x86_64.*")
|
||||
osLinux = re.compile (".*Linux.*")
|
||||
osFreeBSD8x_amd64 = re.compile (".*FreeBSD 8.*amd64.*")
|
||||
osFreeBSD8x_64 = re.compile (".*FreeBSD 8.*x86_64.*")
|
||||
osFreeBSD8x = re.compile (".*FreeBSD 8.*")
|
||||
osDarwin = re.compile (".*Darwin.*")
|
||||
|
||||
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
|
||||
lines = uname.stdout.readlines()
|
||||
|
||||
if osSlsoc6x_64.match(lines[0]):
|
||||
osType = "Linux.slsoc6x_64"
|
||||
libDir = "lib64"
|
||||
elif osSlsoc6x .match(lines[0]): osType = "Linux.slsoc6x"
|
||||
elif osSLSoC5x_64.match(lines[0]):
|
||||
osType = "Linux.SLSoC5x_64"
|
||||
libDir = "lib64"
|
||||
elif osSLSoC5x .match(lines[0]): osType = "Linux.SLSoC5x"
|
||||
elif osLinux_64.match(lines[0]):
|
||||
osType = "Linux.x86_64"
|
||||
libDir = "lib64"
|
||||
elif osLinux .match(lines[0]): osType = "Linux.i386"
|
||||
elif osDarwin.match(lines[0]): osType = "Darwin"
|
||||
elif osFreeBSD8x_amd64.match(lines[0]):
|
||||
osType = "FreeBSD.8x.amd64"
|
||||
libDir = "lib64"
|
||||
elif osFreeBSD8x_64.match(lines[0]):
|
||||
osType = "FreeBSD.8x.x86_64"
|
||||
libDir = "lib64"
|
||||
elif osFreeBSD8x.match(lines[0]):
|
||||
osType = "FreeBSD.8x.i386"
|
||||
else:
|
||||
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
|
||||
osType = uname.stdout.readlines()[0][:-1]
|
||||
|
||||
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
|
||||
print " (using: \"%s\")" % osType
|
||||
|
||||
return osType, libDir
|
||||
|
||||
|
||||
def guessPythonSitePackage ():
|
||||
pathes = distutils.sysconfig.get_python_lib().split('/')[-2:]
|
||||
return os.path.join( pathes[0], pathes[1] )
|
||||
|
||||
|
||||
def autoLocate ():
|
||||
print 'Making an educated guess to locate myself:'
|
||||
sitePackage = guessPythonSitePackage()
|
||||
osType, libDir = guessOs()
|
||||
|
||||
builderDir = None
|
||||
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
, os.environ['HOME']+'/coriolis-2.x/src/bootstrap'
|
||||
, os.environ['HOME']+'/coriolis/src/bootstrap'
|
||||
, os.environ['HOME']+'/chams-1.x/src/bootstrap'
|
||||
, os.environ['HOME']+'/chams/src/bootstrap'
|
||||
, '/users/outil/coriolis/coriolis-2.x/src/bootstrap'
|
||||
, os.environ['HOME']+'/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
||||
, os.environ['HOME']+'/chams-1.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
||||
, os.environ['HOME']+'/chams/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
||||
, '/users/outil/coriolis/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
||||
]
|
||||
|
||||
for location in locations:
|
||||
print ' <%s>' % location,
|
||||
if os.path.isfile(location + '/builder/__init__.py'):
|
||||
if not builderDir:
|
||||
builderDir = location
|
||||
print '(Found*)'
|
||||
else:
|
||||
print '(Found)'
|
||||
else:
|
||||
print '(No)'
|
||||
|
||||
if not builderDir:
|
||||
print '[ERROR] Failed to locate the builder modules in any of the normal pathes.'
|
||||
print ' Please check your Coriolis/Bootsrap installation.'
|
||||
if showTrace: traceback.print_tb(sys.exc_info()[2])
|
||||
sys.exit(1)
|
||||
|
||||
sys.path.insert( 0, builderDir )
|
||||
return
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# CCB Main Part.
|
||||
|
||||
autoLocate()
|
||||
|
||||
parser = optparse.OptionParser ()
|
||||
parser.add_option ( "-g", "--gui" , action="store_true" , dest="gui" , help="Lauch the graphical interface." )
|
||||
# Build relateds.
|
||||
parser.add_option ( "-c", "--conf", type="string", dest="conf" , help="Fichier de configuration." )
|
||||
parser.add_option ( "--show-conf" , action="store_true" , dest="showConf" , help="Display the Project/Tools configuration, then exit." )
|
||||
parser.add_option ( "-q", "--quiet" , action="store_true" , dest="quiet" , help="Do not print all the informative messages." )
|
||||
parser.add_option ( "-r", "--release" , action="store_true" , dest="release" , help="Build a <Release> aka optimized version." )
|
||||
parser.add_option ( "-d", "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
|
||||
parser.add_option ( "-s", "--static" , action="store_true" , dest="static" , help="Try to link statically, as much as possible." )
|
||||
parser.add_option ( "--doc" , action="store_true" , dest="doc" , help="Enable the documentation building (uses with -j1)." )
|
||||
parser.add_option ( "-v", "--verbose" , action="store_true" , dest="verboseMakefile" , help="Tells CMake to print all compilation commands." )
|
||||
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
|
||||
parser.add_option ( "--no-build" , action="store_true" , dest="noBuild" , help="Do *not* build anything (by default: build)." )
|
||||
parser.add_option ( "--no-cache" , action="store_true" , dest="noCache" , help="Remove previous CMake cache before building." )
|
||||
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove previous build directoty before building." )
|
||||
parser.add_option ( "--make" , action="store" , type="string", dest="makeArguments", help="Arguments to pass to make (ex: \"-j4 install\")." )
|
||||
parser.add_option ( "--project" , action="append" , type="string", dest="projects" , help="The name of a project to build (may appears any number of time)." )
|
||||
parser.add_option ( "-t", "--tool" , action="append" , type="string", dest="tools" , help="The name of a tool to build (may appears any number of time)." )
|
||||
# SVN repository relateds.
|
||||
parser.add_option ( "--svn-tag" , action="store" , type="string", dest="svnTag" , help="Explicitly select a SVN tag (for SVN related commands)." )
|
||||
parser.add_option ( "--svn-method" , action="store" , type="string", dest="svnMethod" , help="Allows to sets the svn checkout method (svn+ssh://coriolis.soc.lip6.fr)." )
|
||||
parser.add_option ( "--svn-status" , action="store_true" , dest="svnStatus" , help="Check status against the SVN repository." )
|
||||
parser.add_option ( "--svn-diff" , action="store_true" , dest="svnDiff" , help="Perform a diff against the SVN repository." )
|
||||
parser.add_option ( "--svn-update" , action="store_true" , dest="svnUpdate" , help="Update to the latest SVN version *or* the one given by svn-tag." )
|
||||
parser.add_option ( "--svn-checkout" , action="store_true" , dest="svnCheckout", help="Checkout the latest SVN version *or* the one given by svn-tag." )
|
||||
# Miscellaneous.
|
||||
parser.add_option ( "--user-tarball" , action="store_true" , dest="userTarball", help="Regenerate a tarball from checked out sources (in <root>/tarball/." )
|
||||
parser.add_option ( "--tarball" , action="store_true" , dest="tarball" , help="Regenerate a tarball (in <root>/tarball/." )
|
||||
parser.add_option ( "--rpm" , action="store_true" , dest="doRpm" , help="Regenerate RPM packages." )
|
||||
parser.add_option ( "--deb" , action="store_true" , dest="doDeb" , help="Regenerate Debian/Ubuntu packages." )
|
||||
# Katabatic/Kite specific options.
|
||||
parser.add_option ( "-D", "--check-db" , action="store_true" , dest="checkDb" , help="Enable Katabatic/Kite data-base checking (*very* slow)." )
|
||||
parser.add_option ( "-u", "--check-deter", action="store_true" , dest="checkDeterminism", help="Enable Katabatic/Kite determinism checking (*very* slow)." )
|
||||
(options, args) = parser.parse_args ()
|
||||
|
||||
if options.gui:
|
||||
ErrorMessage = safeImport( 'builder' , 'ErrorMessage' )
|
||||
QApplication = safeImport( 'PyQt4.QtGui' , 'QApplication' )
|
||||
BuilderGui = safeImport( 'builder.BuilderGui', 'BuilderGui' )
|
||||
|
||||
try:
|
||||
app = QApplication( sys.argv )
|
||||
app.setOrganizationName ( 'UPMC' )
|
||||
app.setOrganizationDomain( 'lip6.fr' )
|
||||
app.setApplicationName ( 'CoriolisBuilder' )
|
||||
gui = BuilderGui( options.conf )
|
||||
gui.show()
|
||||
rcode = app.exec_()
|
||||
sys.exit( rcode )
|
||||
except ErrorMessage, e:
|
||||
print e
|
||||
if showTrace: traceback.print_tb(sys.exc_info()[2])
|
||||
sys.exit(2)
|
||||
except Exception, e:
|
||||
print '[ERROR] An exception occured while running the Qt application.'
|
||||
print ' %s' % e
|
||||
if showTrace: traceback.print_tb(sys.exc_info()[2])
|
||||
sys.exit(2)
|
||||
|
||||
else:
|
||||
|
||||
ErrorMessage = safeImport( 'builder' , 'ErrorMessage' )
|
||||
Builder = safeImport( 'builder.Builder', 'Builder' )
|
||||
|
||||
try:
|
||||
builder = Builder()
|
||||
builder.loadConfiguration( options.conf )
|
||||
|
||||
if options.showConf:
|
||||
builder.showConfiguration ()
|
||||
sys.exit(0)
|
||||
|
||||
if options.quiet: builder.quiet = True
|
||||
if options.release: builder.buildMode = "Release"
|
||||
if options.debug: builder.buildMode = "Debug"
|
||||
if options.static: builder.enableShared = "OFF"
|
||||
if options.doc: builder.enableDoc = "ON"
|
||||
if options.checkDb: builder.checkDatabase = "ON"
|
||||
if options.checkDeterminism: builder.enableDeterminism = "ON"
|
||||
if options.verboseMakefile: builder.verboseMakefile = "ON"
|
||||
if options.rootDir: builder.rootDir = options.rootDir
|
||||
if options.noBuild: builder.doBuild = False
|
||||
if options.noCache: builder.noCache = True
|
||||
if options.rmBuild: builder.rmBuild = True
|
||||
if options.makeArguments: builder.makeArguments = options.makeArguments
|
||||
if options.svnMethod: builder.svnMethod = options.svnMethod
|
||||
if options.svnTag: builder.svnTag = options.svnTag
|
||||
|
||||
if options.svnStatus: builder.svnStatus ( tools=options.tools, projects=options.projects )
|
||||
elif options.svnUpdate: builder.svnUpdate ( tools=options.tools, projects=options.projects )
|
||||
elif options.svnDiff: builder.svnDiff ( tools=options.tools, projects=options.projects )
|
||||
elif options.svnCheckout: builder.svnCheckout ( tools=options.tools, projects=options.projects )
|
||||
elif options.userTarball: builder.userTarball ( tools=options.tools, projects=options.projects )
|
||||
elif options.tarball: builder.svnTarball ( tools=options.tools, projects=options.projects )
|
||||
elif options.doRpm: builder.doRpm ()
|
||||
elif options.doDeb: builder.doDeb ()
|
||||
else: builder.build ( tools=options.tools, projects=options.projects )
|
||||
except ErrorMessage, e:
|
||||
print e
|
||||
if showTrace: traceback.print_tb(sys.exc_info()[2])
|
||||
sys.exit(e.code)
|
||||
except KeyboardInterrupt, e:
|
||||
print '\n[ERROR] Interrupted by user\'s request (CTRL+C)'
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(0)
|
Loading…
Reference in New Issue