Add the new version of the nightbuilder client

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11954 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
samuncle 2012-11-16 00:34:10 +00:00
parent 9ad6ea9653
commit 0efdf0744a
8 changed files with 576 additions and 0 deletions

View File

@ -0,0 +1,3 @@
configuration in config.py
To launch, python night.py

View File

@ -0,0 +1,52 @@
#!/bin/python
# From Supertuxkart SVN revision $Revision$
# Copyright (C) 2012 Jean-manuel clemencon (samuncle)
# Class used to build the project
################################################################################
from subprocess import check_output
from utils import *
class Build:
"""
Interface for the builder
"""
# if an error occured
__noError = True
#-------------------------------------------------------------------------------
def __init__ (self, buildDir):
"""
Constructor of the builder class
"""
self.__buildDir = buildDir
#-------------------------------------------------------------------------------
def make(self, job):
"""
the make command
"""
changeDir = Cdir(self.__buildDir)
# we try to build supertuxkart
try:
check_output(["make -j" + str(job)], shell=True)
except:
self.__noError = False
del changeDir
#-------------------------------------------------------------------------------
def clean(self):
"""
the clean command
"""
changeDir = Cdir(self.__buildDir)
check_output(["make clean"], shell=True)
del changeDir
#-------------------------------------------------------------------------------
def noError(self):
"""
return true if no error
"""
return self.__noError

View File

@ -0,0 +1,43 @@
#!/bin/python
# From Supertuxkart SVN revision $Revision$
# Copyright (C) 2012 Jean-manuel clemencon (samuncle)
# configuration for nightly builder
CONFIG = {
# Directory options
"WORKINGDIR" : "/home/tux/stkalpha/supertuxkart",
"BUILDDIR" : "/home/tux/stkalpha/supertuxkart/cmake_build",
"COMPRESSDIR" : "/home/tux/stkbeta",
"LOGDIR" : "/home/tux/stkalpha",
"SCRIPTDIR" : "/home/tux/stkalpha/nightbuilder",
# directory in the server
"REMOTEDIR" : "/web/public/stknigtly",
# Build options
"JOBMAX" : 3,
# FTP options
"FTPHOST" : "ftp.tux.net",
"FTPUSER" : "tux",
"FTPPASS" : "hell0",
# other
"PLATFORM" : "64",
"OS" : "lin",
"VERSION" : "svn"
}
# arguments by default
# PLEASE Don't edit this section if you don't know what you are doing. Thanks
ARG = {
"BIN" : True,
"DATA" : True,
"CLEAN" : False,
"SEND" : True,
"FORCE" : True,
"UPDATE" : True,
"JOB" : 2,
"HELP" : False
}

140
tools/nightbuilder/night.py Normal file
View File

@ -0,0 +1,140 @@
#!/bin/python
# From Supertuxkart SVN revision $Revision$
# Copyright (C) 2012 Jean-manuel clemencon (samuncle)
################################################################################
# Script used to build nighlies
import os
import sys
import getopt
# import the configuration file
from config import *
# import functions/class
from utils import *
from svn import *
from build import *
from package import *
from send import *
def main():
# error
noBuildErr = False
nosvnErr = False
isBuilt = False
# parse input FIXME The parser doesn't work
#parser(sys.argv[1:])
# welcome message
print
print "nightly builder for supertuxkart"
print "Copyright (C) 2012 Jean-manuel clemencon (samuncle)"
print separator(COLOR.OKBLUE)
# display help
if (ARG["HELP"]):
usage()
print separator(COLOR.OKBLUE)
print
exit()
# svn part -----------------------------------------------------------------
# init the svn
mysvn = Svn(CONFIG["WORKINGDIR"])
print "current svn revision: " + str(mysvn.getLocalRevision())
# Update the svn
if (ARG["UPDATE"]):
space = bufferedOutput("start svn update @ " + getTime())
try:
mysvn.update()
nosvnErr = True
sys.stdout.write(COLOR.OKGREEN + space + "[DONE]" + COLOR.ENDC + "\n")
except:
sys.stdout.write(COLOR.WARNING + 74 * " " + "[FAIL]" + COLOR.ENDC + "\n")
# If no error occured
if (nosvnErr):
print "svn updated rev: " + str(mysvn.getLastRevision())
# buid part ----------------------------------------------------------------
# init the build
mybuild = Build(CONFIG["WORKINGDIR"] + "/cmake_build")
# Clean the project
if (ARG["CLEAN"]):
space = bufferedOutput("start clean @ " + getTime())
try:
mybuild.clean()
sys.stdout.write(COLOR.OKGREEN + space + "[DONE]" + COLOR.ENDC + "\n")
except:
sys.stdout.write(COLOR.WARNING + 74 * " " + "[FAIL]" + COLOR.ENDC + "\n")
# build the project (only if no error and the revision has changed
if (nosvnErr):
if (mysvn.getIsChanged()):
print "revision changed"
space = bufferedOutput("start compilation @ " + getTime())
mybuild.make(ARG["JOB"])
isBuilt = True
if (mybuild.noError()):
noBuildErr = True
sys.stdout.write(COLOR.OKGREEN + space + "[DONE]" + COLOR.ENDC + "\n")
else:
sys.stdout.write(COLOR.WARNING + 74 * " " + "[FAIL]" + COLOR.ENDC + "\n")
else:
print "revsion not changed"
# Build the project (force)
if (ARG["FORCE"] and (not isBuilt) ):
space = bufferedOutput("start forced compilation @ " + getTime())
mybuild.make(ARG["JOB"])
if (mybuild.noError()):
noBuildErr = True
sys.stdout.write(COLOR.OKGREEN + space + "[DONE]" + COLOR.ENDC + "\n")
else:
sys.stdout.write(COLOR.WARNING + 74 * " " + "[FAIL]" + COLOR.ENDC + "\n")
# package part -------------------------------------------------------------
mypack = Package(mysvn.getLastRevision(), CONFIG["COMPRESSDIR"],CONFIG["OS"],CONFIG["PLATFORM"])
# pack the binary
if (noBuildErr and ARG["BIN"]):
space = bufferedOutput("start bin file compress @ " + getTime())
try:
mypack.addFile("supertuxkart", "stkbin", CONFIG["BUILDDIR"] + "/bin")
sys.stdout.write(COLOR.OKGREEN + space + "[DONE]" + COLOR.ENDC + "\n")
except:
sys.stdout.write(COLOR.WARNING + 74 * " " + "[FAIL]" + COLOR.ENDC + "\n")
# pack the data
if(ARG["DATA"]):
space = bufferedOutput("start data file compress @ " + getTime())
try:
mypack.addDir("data", "stkdat", CONFIG["WORKINGDIR"], "*.svn*")
sys.stdout.write(COLOR.OKGREEN + space + "[DONE]" + COLOR.ENDC + "\n")
except:
sys.stdout.write(COLOR.WARNING + 74 * " " + "[FAIL]" + COLOR.ENDC + "\n")
# network part -------------------------------------------------------------
if(ARG["SEND"]):
# send file by FTP
space = bufferedOutput("start file(s) transfer by FTP @ " + getTime())
myFiles = mypack.getFiles()
mysend = Send(CONFIG["FTPHOST"],CONFIG["FTPUSER"],CONFIG["FTPPASS"],CONFIG["SCRIPTDIR"])
for i in myFiles:
mysend.add(i, CONFIG["COMPRESSDIR"], CONFIG["REMOTEDIR"])
#FIXME The ftp didn't throw an exception.
try:
mysend.send()
sys.stdout.write(COLOR.OKGREEN + space + "[DONE]" + COLOR.ENDC + "\n")
except:
sys.stdout.write(COLOR.WARNING + 74 * " " + "[FAIL]" + COLOR.ENDC + "\n")
print separator(COLOR.OKBLUE)
print
if __name__ == "__main__":
main()
#sys.argv[1:]

View File

@ -0,0 +1,80 @@
#!/bin/python
# From Supertuxkart SVN revision $Revision$
# Copyright (C) 2012 Jean-manuel clemencon (samuncle)
# Class used to package the project
################################################################################
from subprocess import check_output
from utils import *
class Package:
"""
Interface for the builder
"""
__revision = 0
__listFile = []
#-------------------------------------------------------------------------------
def __init__ (self, revision, compressDir, os,platform):
"""
Constructor of the builder class
"""
self.__os = os
self.__revision = str(revision)
self.__platform = platform
self.__compressDir = compressDir
#-------------------------------------------------------------------------------
def addFile(self, inFile, outFile, workingDir):
"""
Packing a file
"""
# filename
name = outFile \
+ "_" + self.__os \
+ self.__platform \
+ "_" + self.__revision \
+ ".zip"
self.__listFile.append(name)
# prepare the command
command = "zip " \
+ self.__compressDir \
+ "/" + name \
+ " " + inFile
# execute the command to pack the binary
changeDir = Cdir(workingDir)
check_output([command], shell=True)
del changeDir
#-------------------------------------------------------------------------------
def addDir(self, inFile, outFile, workingDir, exclude):
"""
Packing a directory
"""
# filename
name = outFile \
+ "_" + self.__os \
+ "_" + self.__revision \
+ ".zip"
self.__listFile.append(name)
# prepare the command
command = "zip -r --exclude=" \
+ exclude \
+ " " +self.__compressDir \
+ "/" + name \
+ " " + inFile
# execute the command to pack the binary
changeDir = Cdir(workingDir)
check_output([command], shell=True)
del changeDir
#-------------------------------------------------------------------------------
def getFiles(self):
"""
Return the list of file/directory added
"""
return self.__listFile

View File

@ -0,0 +1,65 @@
#!/bin/python
# From Supertuxkart SVN revision $Revision$
# Copyright (C) 2012 Jean-manuel clemencon (samuncle)
# Class used to package the project
################################################################################
from subprocess import check_output
import os
from utils import *
class Send:
"""
Interface for the network
"""
def __init__ (self, ftpHost, ftpUser, ftpPass, ftpFileDir):
"""
Constructor of the builder class
"""
# Get the configuration for the FTP connection
lines = [
'FTP_HOST="' + ftpHost + '"\n',
'FTP_USER="' + ftpUser + '"\n',
'FTP_PASS="' + ftpPass + '"\n',
'\n',
'ftp -n -p $FTP_HOST << EOF\n',
'user $FTP_USER $FTP_PASS\n'
]
# open the ftp script
self.__ftpCmd = open("ftp.sh", "w")
self.__ftpCmd.writelines(lines)
self.__ftpFileDir = ftpFileDir
def add(self, filename, localDir, remoteDir):
"""
Add a file to the sender
"""
command = "put " \
+ localDir \
+ "/" + filename \
+ " " + remoteDir \
+ "/" + filename \
+ "\n"
self.__ftpCmd.write(command)
def send(self):
"""
Send files previously added
"""
self.__ftpCmd.write("bye\nEOF\n")
self.__ftpCmd.close()
check_output([self.__ftpFileDir+"/ftp.sh"], shell=True)
#os.system("./ftp.sh")
def alert(self):
"""
Send an e-mail alert to the mailing list
"""
#TODO

93
tools/nightbuilder/svn.py Normal file
View File

@ -0,0 +1,93 @@
#!/bin/python
# From Supertuxkart SVN revision $Revision$
# Copyright (C) 2012 Jean-manuel clemencon (samuncle)
# Class for the SVN
################################################################################
import os
from subprocess import check_output
from utils import *
class Svn:
"""
Interface for the SVN
"""
__svnInfoLocal = "" # info of the local repo
__svnInfoLast = "" # info when it's updated
__localRev = 0 # the local revision number
__lastRev = 0 # the updated revision number
__isUp = False # is the repo has been already updated
#-------------------------------------------------------------------------------
def __init__ (self, workingDir):
"""
Constructor of the svn class
"""
# local copy for the configuration
self.__workingDir = workingDir
# cd to the working dir and get info from current revision
changeDir = Cdir(self.__workingDir)
self.__svnInfoLocal = check_output(["svn info"], shell=True)
del changeDir
# exctract the local revision
self.__localRev = self.__parseInfo(self.__svnInfoLocal)
#-------------------------------------------------------------------------------
def __parseInfo(self, strIn):
"""
Parse info to extract the revision
"""
workingData = strIn.split("\n")
for i in workingData:
if "Revision: " in i:
return int(i.split("Revision: ")[1])
#-------------------------------------------------------------------------------
def update(self):
"""
update the repository (svn up)
"""
# cd to the directory and update the svn
changeDir = Cdir(self.__workingDir)
self.__svnInfoLocal = check_output(["svn up"], shell=True)
self.__svnInfoLast = check_output(["svn info"], shell=True)
del changeDir
# exctract the last revision
self.__lastRev = self.__parseInfo(self.__svnInfoLast)
# now we have updated the SVN
self.__isUp = True
#-------------------------------------------------------------------------------
def getLocalRevision(self):
"""
return the local revision
"""
return self.__localRev
#-------------------------------------------------------------------------------
def getLastRevision(self):
"""
return the last revision
"""
if not (self.__isUp):
raise Exception ("The revision has not been updated.")
return self.__lastRev
#-------------------------------------------------------------------------------
def getIsChanged(self):
"""
return true if revision has changed
"""
if not (self.__isUp):
raise Exception ("The revision has not been updated.")
if (self.__lastRev != self.__localRev):
return True
else:
return False

100
tools/nightbuilder/utils.py Normal file
View File

@ -0,0 +1,100 @@
#!/bin/python
# From Supertuxkart SVN revision $Revision$
# Copyright (C) 2012 Jean-manuel clemencon (samuncle)
################################################################################
import os
import sys
from time import gmtime, strftime
# import config
from config import *
class Cdir:
"""
A class used to change the directory and reset it when it's destructed
"""
#-------------------------------------------------------------------------------
def __init__ (self, path):
self.oriPath = os.getcwd()
os.chdir(path)
#-------------------------------------------------------------------------------
def __del__ (self):
os.chdir(self.oriPath)
class COLOR:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
def separator(color):
return color + 80 * "-" + COLOR.ENDC
#-------------------------------------------------------------------------------
# usage of the script. Displayed if -h is invoqued
def usage(error = ""):
if (error):
print "[error] " + error
h = [
" Options avaliables:",
" --bin # package the binary",
" --data # package the data",
" --clean # remove all packages and logs",
" --send # send the package via FTP",
" --force # force the build (even the revision hasn't changed)",
" --update # update the SVN",
" --web # html output"
" --job= # like -j for make",
" --help # display help",
]
for i in h:
print i
def getTime():
return strftime("%a, %d %b %Y %H:%M:%S GMT+01", gmtime())
#-------------------------------------------------------------------------------
# Used to format output
def bufferedOutput(string, nb = 74):
space = (nb - len(string)) * " "
sys.stdout.write(string)
sys.stdout.flush()
return space
#-------------------------------------------------------------------------------
def parser(argv):
a = os.system("ls")
print a
try:
opts, args = getopt.getopt(argv, "bdcsfuhj:", ["bin",
"data",
"clean",
"send",
"force",
"update",
"help",
"job="
])
for opt, args in opts:
if opt in ("-h", "--help"):
ARG["HELP"] = True
"""
if opt in ("-b", "bin"):
ARG["BIN"] = True
if opt in ("-d", "data"):
ARG["DATA"] = True
if opt in ("-s", "send"):
ARG["SEND"] = True
if opt in ("-f", "force"):
ARG["FORCE"] = True
if opt in ("-u", "update"):
ARG["UPDATE"] = True
"""
except:
usage("unrecognized option")