[Scummvm-cvs-logs] SF.net SVN: scummvm:[41021] buildbot/config

dhewg at users.sourceforge.net dhewg at users.sourceforge.net
Sat May 30 11:21:03 CEST 2009


Revision: 41021
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41021&view=rev
Author:   dhewg
Date:     2009-05-30 09:21:03 +0000 (Sat, 30 May 2009)

Log Message:
-----------
Added the buildbot config files.

Added Paths:
-----------
    buildbot/config/master.cfg
    buildbot/config/scumm.py

Added: buildbot/config/master.cfg
===================================================================
--- buildbot/config/master.cfg	                        (rev 0)
+++ buildbot/config/master.cfg	2009-05-30 09:21:03 UTC (rev 41021)
@@ -0,0 +1,606 @@
+# -*- python -*-
+# ex: set syntax=python:
+
+#######
+####### ScummVM settings for buildbot
+#######
+
+import os, sys, copy
+sys.path.append("/var/lib/buildbot/master")
+import scumm
+import scummsecret
+
+# Toggles a few things, only meant for debugging and local testing.
+scumm_testenv = False
+
+scumm_svnroot = "https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/"
+
+scumm_branch = "branches/branch-0-13-0"
+scumm_branch_desc = "0.13.0"
+
+if scumm_testenv:
+	scumm_package_dst_trunk = "/tmp"
+	scumm_package_dst_branch = "/tmp"
+else:
+	scumm_package_dst_trunk = "/var/www/snapshots/trunk"
+	scumm_package_dst_branch = "/var/www/snapshots/0.13.0"
+
+# Files to package for trunk snapshots (common to all ports).
+scumm_package_trunk = [
+	"AUTHORS",
+	"COPYING",
+	"COPYING.LGPL",
+	"COPYRIGHT",
+	"NEWS",
+	"README",
+	"gui/themes/scummmodern.zip",
+	"dists/pred.dic",
+	"dists/engine-data/drascula.dat",
+	"dists/engine-data/kyra.dat",
+	"dists/engine-data/m4.dat",
+	"dists/engine-data/igor.tbl",
+	"dists/engine-data/lure.dat",
+	"dists/engine-data/queen.tbl",
+	"dists/engine-data/sky.cpt"
+]
+
+# Files to package for branch snapshots (common to all ports).
+scumm_package_branch = scumm_package_trunk
+
+scumm_env = {
+	"LC_ALL": "C",
+	"CXX": "",
+	"CXXFLAGS": "",
+	"CPPFLAGS": "",
+	"LDFLAGS": ""
+}
+
+# Our platform definitions.
+
+scumm_platforms_trunk = {}
+scumm_platforms_branch = {}
+
+# debian lenny 32bit.
+scumm_env_lenny = copy.deepcopy(scumm_env)
+scumm_env_lenny["CXX"] = "ccache g++"
+
+p = {
+	"configureargs": [ ],
+	"env": scumm_env_lenny,
+	"strip": "strip scummvm",
+	"package": [ "scummvm" ]
+}
+
+scumm_platforms_trunk["lenny"] = p
+scumm_platforms_branch["lenny"] = p
+
+# debian lenny 64bit.
+scumm_root_lenny_x86_64 = "/opt/toolchains/debian-lenny-x86_64"
+scumm_env_lenny_x86_64 = copy.deepcopy(scumm_env)
+scumm_env_lenny_x86_64["CXX"] = "ccache g++"
+scumm_env_lenny_x86_64["CXXFLAGS"] = "-m64"
+scumm_env_lenny_x86_64["LDFLAGS"] = "-m64 -Wl,-rpath,%s/lib -Wl,-rpath,%s/usr/lib" % \
+									(scumm_root_lenny_x86_64, scumm_root_lenny_x86_64)
+
+p = {
+	"configureargs": [
+		"--host=x86_64-unknown-linux-gnu",
+		"--with-sdl-prefix=%s/usr" % scumm_root_lenny_x86_64,
+		"--with-mad-prefix=%s/usr" % scumm_root_lenny_x86_64,
+		"--with-ogg-prefix=%s/usr" % scumm_root_lenny_x86_64,
+		"--with-fluidsynth-prefix=%s/usr" % scumm_root_lenny_x86_64
+	],
+	"env": scumm_env_lenny_x86_64,
+	"strip": "strip scummvm",
+	"package": [ "scummvm" ]
+}
+
+scumm_platforms_trunk["lenny-x86_64"] = p
+scumm_platforms_branch["lenny-x86_64"] = p
+
+# mingw 32bit, using the mingw compiler from the debian repositories.
+scumm_root_mingw_w32 = "/opt/toolchains/i586-mingw32msvc"
+scumm_env_mingw_w32 = copy.deepcopy(scumm_env)
+scumm_env_mingw_w32["CXX"] = "ccache i586-mingw32msvc-g++"
+
+p = {
+	"configureargs": [
+		"--host=i586-mingw32msvc",
+		"--with-sdl-prefix=%s" % scumm_root_mingw_w32,
+		"--with-mad-prefix=%s" % scumm_root_mingw_w32,
+		"--with-ogg-prefix=%s" % scumm_root_mingw_w32,
+		"--with-flac-prefix=%s" % scumm_root_mingw_w32,
+		"--with-zlib-prefix=%s" % scumm_root_mingw_w32
+	],
+	"env": scumm_env_mingw_w32,
+	"strip": "i586-mingw32msvc-strip scummvm.exe",
+	"package": [
+		"scummvm.exe",
+		"%s/bin/SDL.dll" % scumm_root_mingw_w32
+	]
+}
+
+scumm_platforms_trunk["mingw-w32"] = p
+scumm_platforms_branch["mingw-w32"] = p
+
+# mingw 64bit, using an experimental snapshot of mingw-w64.
+scumm_root_mingw_w64 = "/opt/toolchains/mingw-w64-bin_i686-linux"
+scumm_env_mingw_w64 = copy.deepcopy(scumm_env)
+scumm_env_mingw_w64["PATH"] = "%s/bin:%s" % (scumm_root_mingw_w64, os.environ["PATH"])
+scumm_env_mingw_w64["CXX"] = "ccache x86_64-pc-mingw32-g++"
+
+p = {
+	"configureargs": [
+		"--host=x86_64-pc-mingw32",
+		"--with-sdl-prefix=%s" % scumm_root_mingw_w64,
+		"--with-mad-prefix=%s" % scumm_root_mingw_w64,
+		"--with-ogg-prefix=%s" % scumm_root_mingw_w64,
+		"--with-flac-prefix=%s" % scumm_root_mingw_w64,
+		"--with-zlib-prefix=%s" % scumm_root_mingw_w64
+	],
+	"env": scumm_env_mingw_w64,
+	"strip": "%s/bin/x86_64-pc-mingw32-strip scummvm.exe" % scumm_root_mingw_w64,
+	"package": [
+		"scummvm.exe",
+		"%s/bin/SDL.dll" % scumm_root_mingw_w64,
+		"%s/bin/libgcc_s_sjlj-1.dll" % scumm_root_mingw_w64
+	]
+}
+
+scumm_platforms_trunk["mingw-w64"] = p
+
+# wii
+scumm_root_wii = "/opt/toolchains/devkitPPC-r16"
+scumm_env_wii = copy.deepcopy(scumm_env)
+scumm_env_wii["PATH"] = "%s/devkitPPC/bin:%s" % (scumm_root_wii, os.environ["PATH"])
+scumm_env_wii["CXX"] = "ccache powerpc-gekko-g++"
+scumm_env_wii["DEVKITPRO"] = "%s" % scumm_root_wii
+scumm_env_wii["DEVKITPPC"] = "%s/devkitPPC" % scumm_root_wii
+
+p = {
+	"configureargs": [
+		"--host=wii",
+		"--with-tremor-prefix=%s/3rd/wii" % scumm_root_wii,
+		"--with-flac-prefix=%s/3rd/wii" % scumm_root_wii
+	],
+	"env": scumm_env_wii,
+	"package": [ "scummvm.dol" ]
+}
+
+scumm_platforms_trunk["wii"] = p
+
+# Mac OS X Intel
+scumm_root_osx_intel = "/opt/toolchains/i686-apple-darwin9-10.4"
+scumm_env_osx_intel = copy.deepcopy(scumm_env)
+scumm_env_osx_intel["PATH"] = "%s/bin:%s" % (scumm_root_osx_intel, os.environ["PATH"])
+scumm_env_osx_intel["CXX"] = "ccache i686-apple-darwin9-g++"
+
+p = {
+	"configureargs": [
+		"--host=i686-apple-darwin9",
+		"--disable-nasm",
+		"--with-sdl-prefix=%s" % scumm_root_osx_intel,
+		"--with-mad-prefix=%s" % scumm_root_osx_intel,
+		"--with-ogg-prefix=%s" % scumm_root_osx_intel,
+		"--with-flac-prefix=%s" % scumm_root_osx_intel,
+		"--with-zlib-prefix=%s" % scumm_root_osx_intel,
+	],
+	"env": scumm_env_osx_intel,
+	"strip": "%s/bin/i686-apple-darwin9-strip scummvm" % scumm_root_osx_intel,
+	"package": [ "scummvm" ]
+}
+
+scumm_platforms_trunk["os_x_intel"] = p
+
+# Mac OS X PPC
+scumm_root_osx_ppc = "/opt/toolchains/powerpc-apple-darwin8-10.2"
+scumm_env_osx_ppc = copy.deepcopy(scumm_env)
+scumm_env_osx_ppc["PATH"] = "%s/bin:%s" % (scumm_root_osx_ppc, os.environ["PATH"])
+scumm_env_osx_ppc["CXX"] = "ccache ppc-apple-darwin8-g++"
+scumm_env_osx_ppc["CXXFLAGS"] = "-fabi-version=1 -fno-use-cxa-atexit"
+scumm_env_osx_ppc["LDFLAGS"] = "-static-libgcc -ldl"
+scumm_env_osx_ppc["MACOSX_DEPLOYMENT_TARGET"] = "10.2"
+
+p = {
+	"configureargs": [
+		"--host=ppc-apple-darwin8",
+		"--with-sdl-prefix=%s" % scumm_root_osx_ppc,
+		"--with-mad-prefix=%s" % scumm_root_osx_ppc,
+		"--with-ogg-prefix=%s" % scumm_root_osx_ppc,
+		"--with-vorbis-prefix=%s" % scumm_root_osx_ppc,
+		"--with-flac-prefix=%s" % scumm_root_osx_ppc,
+		"--with-zlib-prefix=%s" % scumm_root_osx_ppc,
+		"--with-staticlib-prefix=%s" % scumm_root_osx_ppc,
+	],
+	"env": scumm_env_osx_ppc,
+	"strip": "%s/bin/ppc-apple-darwin8-strip scummvm" % scumm_root_osx_ppc,
+	"package": [ "scummvm" ]
+}
+
+scumm_platforms_trunk["os_x_ppc"] = p
+
+# iPhone
+scumm_root_iphone = "/opt/toolchains/arm-apple-darwin9-llvm-gcc-4.2"
+scumm_libdir_iphone = "%s/SDK/usr/local" % scumm_root_iphone
+scumm_env_iphone = copy.deepcopy(scumm_env)
+scumm_env_iphone["PATH"] = "%s/bin:%s" % (scumm_root_iphone, os.environ["PATH"])
+scumm_env_iphone["CXX"] = "ccache arm-apple-darwin9-g++"
+scumm_env_iphone["AS"] = "%s/bin/arm-apple-darwin9-as" % scumm_root_iphone
+scumm_env_iphone["LDFLAGS"] = "-F%s/SDK/System/Library/PrivateFrameworks -bind_at_load" % scumm_root_iphone
+scumm_env_iphone["LIBDIR"] = scumm_libdir_iphone
+
+p = {
+	"configureargs": [
+		"--host=iphone",
+		"--with-mad-prefix=%s" % scumm_libdir_iphone,
+		"--with-ogg-prefix=%s" % scumm_libdir_iphone,
+		"--with-flac-prefix=%s" % scumm_libdir_iphone,
+		"--with-zlib-prefix=%s" % scumm_libdir_iphone
+	],
+	"env": scumm_env_iphone,
+	"strip": "%s/bin/arm-apple-darwin9-strip scummvm" % scumm_root_iphone,
+	"package": [ "scummvm" ]
+}
+
+scumm_platforms_trunk["iphone"] = p
+
+# PSP
+scumm_root_psp = "/opt/toolchains/psp"
+scumm_env_psp = copy.deepcopy(scumm_env)
+scumm_env_psp["PATH"] = "%s/bin:%s" % (scumm_root_psp, os.environ["PATH"])
+scumm_env_psp["CXX"] = "ccache psp-g++"
+scumm_env_psp["PSPDEV"] = scumm_root_psp
+
+p = {
+	"configureargs": [
+		"--host=psp",
+	],
+	"env": scumm_env_psp,
+	"strip": "%s/bin/psp-strip scummvm.elf" % scumm_root_psp,
+	"package": [ "scummvm.elf" ]
+}
+
+scumm_platforms_trunk["psp"] = p
+
+# GP2X
+scumm_root_gp2x = "/opt/toolchains/open2x-gcc-4.1.1"
+scumm_env_gp2x = copy.deepcopy(scumm_env)
+scumm_env_gp2x["PATH"] = "%s/bin:%s" % (scumm_root_gp2x, os.environ["PATH"])
+scumm_env_gp2x["CXX"] = "ccache arm-open2x-linux-g++"
+scumm_env_gp2x["AS"] = "arm-open2x-linux-as"
+scumm_env_gp2x["ASFLAGS"] = "-mfloat-abi=soft"
+
+p = {
+	"configureargs": [
+		"--host=gp2x",
+		"--with-mad-prefix=%s" % scumm_root_gp2x,
+		"--with-tremor-prefix=%s" % scumm_root_gp2x,
+		"--with-zlib-prefix=%s" % scumm_root_gp2x,
+	],
+	"env": scumm_env_gp2x,
+	"strip": "%s/bin/arm-open2x-linux-strip scummvm.gp2x" % scumm_root_gp2x,
+	"package": [ "scummvm.gp2x" ]
+}
+
+scumm_platforms_trunk["gp2x"] = p
+
+# DC
+scumm_root_dc= "/opt/toolchains/dc"
+scumm_env_dc = copy.deepcopy(scumm_env)
+scumm_env_dc["PATH"] = "%s/bin:%s" % (scumm_root_dc, os.environ["PATH"])
+scumm_env_dc["CXX"] = "ccache sh-elf-g++"
+
+p = {
+	"configureargs": [
+		"--host=dreamcast",
+		"--enable-plugins",
+		"--default-dynamic"
+	],
+	"env": scumm_env_dc,
+	"package": [
+		"SCUMMVM.BIN",
+		"AGI.PLG",
+		"AGOS.PLG",
+		"CINE.PLG",
+		"CRUISE.PLG",
+		"DRASCULA.PLG",
+		"GOB.PLG",
+		"GROOVIE.PLG",
+		"IGOR.PLG",
+		"KYRA.PLG",
+		"LURE.PLG",
+		"M4.PLG",
+		"MADE.PLG",
+		"PARALLACTION.PLG",
+		"QUEEN.PLG",
+		"SAGA.PLG",
+		"SCI.PLG",
+		"SCUMM.PLG",
+		"SKY.PLG",
+		"SWORD1.PLG",
+		"SWORD2.PLG",
+		"TINSEL.PLG",
+		"TOUCHE.PLG",
+		"TUCKER.PLG "
+	]
+}
+
+scumm_platforms_trunk["dc"] = p
+
+#######
+####### buildbot setup
+#######
+
+c = BuildmasterConfig = {}
+
+####### BUILDSLAVES
+
+# The slave buildbots.
+
+from buildbot.buildslave import BuildSlave
+
+# the fetching schedulers count as build too, and since its waiting for
+# the compiling builders, we need at least 2 concurrent jobs
+c["slaves"] = [ BuildSlave("localslave", scummsecret.pwd_localslave) ]
+c["slavePortnum"] = "tcp:9989:interface=127.0.0.1"
+
+####### CHANGESOURCES
+
+# Poll for new revisions in SVN.
+# Trunk and one branch are taken into account.
+
+from buildbot.changes.svnpoller import SVNPoller, split_file_branches
+from buildbot.changes.pb import PBChangeSource
+
+if scumm_testenv:
+	c["change_source"] = PBChangeSource()
+else:
+	c["change_source"] = SVNPoller(scumm_svnroot,
+									split_file = split_file_branches,
+									pollinterval = 3 * 60)
+
+####### SCHEDULERS
+
+# Only fetch changes from SVN, these checkouts are used by all compile runs.
+
+from buildbot.scheduler import Scheduler, Triggerable
+
+s_trunk = Scheduler(name = "fetch-trunk",
+					branch = None,
+					treeStableTimer = 5,
+					builderNames = [ "fetch-trunk" ])
+
+s_branch = Scheduler(name = "fetch-branch",
+					branch = scumm_branch,
+					treeStableTimer = 5,
+					builderNames = [ "fetch-branch" ])
+
+# The building schedulers, starting the associated builders
+
+builders_trunk = []
+for i in scumm_platforms_trunk.keys():
+	builders_trunk.append("trunk-%s" % i)
+
+s_build_trunk = Triggerable(name = "trunk", builderNames = builders_trunk)
+
+builders_branch = []
+for i in scumm_platforms_branch.keys():
+	builders_branch.append("branch-%s" % i)
+
+s_build_branch = Triggerable(name = "branch", builderNames = builders_branch)
+
+# The nightly schedulers.
+s_nightly_trunk = scumm.Nightly(name = "nightly_trunk",
+								branch = None,
+								builderNames = [ "nightly-trunk" ],
+								hour = 4,
+								minute = 0,
+								onlyIfChanged = True)
+
+s_nightly_branch = scumm.Nightly(name = "nightly_branch",
+								branch = scumm_branch,
+								builderNames = [ "nightly-branch" ],
+								hour = 5,
+								minute = 0,
+								onlyIfChanged = True)
+
+c["schedulers"] = [
+	s_trunk,
+	s_branch,
+	s_build_trunk,
+	s_build_branch,
+	s_nightly_trunk,
+	s_nightly_branch,
+]
+
+####### BUILDERS
+
+from buildbot.process import factory
+from buildbot.process.properties import WithProperties
+from buildbot.steps.source import SVN
+from buildbot.steps.trigger import Trigger
+from buildbot.steps.shell import Compile
+
+# One lock to rule them all.
+# Used to prevent SVN updates when the nightly schedulers are busy.
+from buildbot.locks import MasterLock, SlaveLock
+lock_src = MasterLock("source")
+lock_bot = SlaveLock("slave", maxCount = 1)
+
+# The SVN fetching builders
+
+c["builders"] = []
+
+f = factory.BuildFactory()
+f.useProgress = False
+f.addStep(SVN(mode = "update",
+				workdir = "src",
+				baseURL = scumm_svnroot,
+				defaultBranch = "trunk"))
+f.addStep(Trigger(schedulerNames = [ "trunk" ],
+					updateSourceStamp = True,
+					waitForFinish = True))
+
+c["builders"].append( {
+	"name": "fetch-trunk",
+	"slavename": "localslave",
+	"builddir": "src-trunk",
+	"factory": f,
+	"category": "fetch",
+	"locks": [ lock_src.access("exclusive") ]
+})
+
+f = factory.BuildFactory()
+f.useProgress = False
+f.addStep(SVN(mode = "update",
+				workdir = "src",
+				baseURL = scumm_svnroot,
+				defaultBranch = scumm_branch))
+f.addStep(Trigger(schedulerNames = [ "branch" ],
+					updateSourceStamp = True,
+					waitForFinish = True))
+
+c["builders"].append( {
+	"name": "fetch-branch",
+	"slavename": "localslave",
+	"builddir": "src-branch",
+	"factory": f,
+	"category": "fetch",
+	"locks": [ lock_src.access("exclusive") ]
+})
+
+# Nightly builders
+
+f = factory.BuildFactory()
+f.addStep(scumm.Clean(prefix = "trunk"))
+f.addStep(Trigger(schedulerNames = [ "trunk" ],
+					updateSourceStamp = True,
+					waitForFinish = True,
+					set_properties = { "package": True }))
+
+c["builders"].append( {
+	"name": "nightly-trunk",
+	"slavename": "localslave",
+	"builddir": "nightly-trunk",
+	"factory": f,
+	"category": "nightly",
+	"locks": [ lock_src.access("exclusive") ]
+})
+
+f = factory.BuildFactory()
+f.addStep(scumm.Clean(prefix = "branch"))
+f.addStep(Trigger(schedulerNames = [ "branch" ],
+					updateSourceStamp = True,
+					waitForFinish = True,
+					set_properties = { "package": True }))
+
+c["builders"].append( {
+	"name": "nightly-branch",
+	"slavename": "localslave",
+	"builddir": "nightly-branch",
+	"factory": f,
+	"category": "nightly",
+	"locks": [ lock_src.access("exclusive") ]
+})
+
+# Dynamic generated builders based on the platforms defined at the top of this file
+
+for name, config in scumm_platforms_trunk.items():
+	f = factory.BuildFactory()
+	f.useProgress = False
+
+	f.addStep(scumm.Configure(command =  [
+								"../../src-trunk/src/configure",
+								"--enable-all-engines"
+							] + config["configureargs"],
+							env = config["env"]))
+
+	f.addStep(Compile(command = [
+							"make",
+							"-j3",
+							WithProperties("SCUMMVM_SVN_REVISION=%(got_revision)s")
+						],
+						env = config["env"]))
+
+	if config.has_key("strip"):
+		f.addStep(scumm.Strip(command = config["strip"]))
+
+	f.addStep(scumm.Package(srcpath = "../../src-trunk/src/",
+							dstpath = scumm_package_dst_trunk,
+							package = scumm_package_trunk,
+							buildname = name + "-trunk",
+							platform_package = config["package"]))
+
+	c["builders"].append( {
+		"name": "trunk-%s" % name,
+		"slavename": "localslave",
+		"builddir": "trunk-%s" % name,
+		"factory": f,
+		"locks": [ lock_bot.access('counting') ],
+		"category": "trunk"
+	})
+
+for name, config in scumm_platforms_branch.items():
+	f = factory.BuildFactory()
+	f.useProgress = False
+	f.addStep(scumm.Configure(command =  [
+								"../../src-branch/src/configure"
+						] + config["configureargs"],
+							env = config["env"]))
+
+	f.addStep(Compile(command = [
+							"make",
+							"-j3",
+							WithProperties("SCUMMVM_SVN_REVISION=%(got_revision)s")
+						],
+						env = config["env"]))
+
+	if config.has_key("strip"):
+		f.addStep(scumm.Strip(command = config["strip"]))
+
+	f.addStep(scumm.Package(srcpath = "../../src-branch/src/",
+							dstpath = scumm_package_dst_branch,
+							package = scumm_package_branch,
+							buildname = name + "-%s" % scumm_branch_desc,
+							platform_package = config["package"]))
+
+	c["builders"].append( {
+		"name": "branch-%s" % name,
+		"slavename": "localslave",
+		"builddir": "branch-%s" % name,
+		"factory": f,
+		"locks": [ lock_bot.access('counting') ],
+		"category": "branch"
+	})
+
+####### STATUS TARGETS
+
+c["status"] = []
+
+from buildbot.status import html, client
+
+c["status"].append(html.WebStatus("tcp:8010:interface=127.0.0.1"))
+
+if scumm_testenv:
+	irc = scumm.IRC("irc.freenode.org", "svmbb",
+					channel = "#bbtest",
+					categories = [ "trunk", "branch" ],
+					stableTimer = 5 * 60)
+else:
+	irc = scumm.IRC("irc.freenode.org", "ScummBot",
+					channel = "#scummvm",
+					password= scummsecret.pwd_nickserv,
+					categories = [ "trunk", "branch" ],
+					stableTimer = 5 * 60)
+
+c["status"].append(irc)
+
+####### PROJECT IDENTITY
+
+c["projectName"] = "ScummVM"
+c["projectURL"] = "http://scummvm.org/"
+if scumm_testenv:
+	c["buildbotURL"] = "http://localhost:8010/"
+else:
+	c["buildbotURL"] = "http://buildbot.scummvm.org/buildbot/"
+


Property changes on: buildbot/config/master.cfg
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Added: buildbot/config/scumm.py
===================================================================
--- buildbot/config/scumm.py	                        (rev 0)
+++ buildbot/config/scumm.py	2009-05-30 09:21:03 UTC (rev 41021)
@@ -0,0 +1,522 @@
+
+# code to deliver build status through twisted.words (instant messaging
+# protocols: irc, etc)
+
+import os, re, shlex, glob
+
+from zope.interface import Interface, implements
+from twisted.internet import protocol, reactor
+from twisted.words.protocols import irc
+from twisted.python import log, failure
+from twisted.application import internet
+
+from buildbot import interfaces, util
+from buildbot import version
+from buildbot.sourcestamp import SourceStamp
+from buildbot.process.base import BuildRequest
+from buildbot.status import base
+from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, EXCEPTION, SKIPPED
+from buildbot import scheduler
+from buildbot.steps.shell import ShellCommand
+
+from string import join, capitalize, lower
+
+# Nightly scheduler helper class. It stores the SVN revision of the latest change,
+# so it can be used for the builds it is issuing.
+class Nightly(scheduler.Nightly):
+	def addChange(self, change):
+		if change.branch == self.branch:
+			self.properties.setProperty("got_revision", change.revision, "Scheduler")
+		scheduler.Nightly.addChange(self, change)
+
+# Buildstep class for our build system. A ./configure run is forced on nightly builds,
+# which results in a full rebuild. For incremental builds, its only run when no
+# Makefile exists (which is generated by the script itself).
+class Configure(ShellCommand):
+	name = "configure"
+	haltOnFailure = 1
+	flunkOnFailure = 1
+	description = [ "configuring" ]
+	descriptionDone = [ "configure" ]
+	descriptionDoneSkipped = [ "configure", "(skipped)" ]
+	skipped = False
+
+	def start(self):
+		properties = self.build.getProperties()
+
+		# buildbot workaround, pass on the revision.
+		if properties.has_key("revision"):
+			if not properties.has_key("got_revision") or properties["got_revision"] == None:
+				self.setProperty("got_revision", properties["revision"])
+
+		self.command = "[ -f Makefile ] || " + " ".join(self.command)
+
+		ShellCommand.start(self)
+
+	def commandComplete(self, cmd):
+		if cmd.rc == 0 and len(cmd.logs["stdio"].getText()) < 1:
+			self.skipped = True
+
+		ShellCommand.commandComplete(self, cmd)
+
+	def describe(self, done = False):
+		if done and self.skipped:
+			self.descriptionDone = self.descriptionDoneSkipped
+
+		return ShellCommand.describe(self, done)
+
+# Small buildstep class to strip binaries, only done on nightly builds.
+class Strip(ShellCommand):
+	name = "strip"
+	haltOnFailure = 1
+	flunkOnFailure = 1
+	description = [ "stripping" ]
+	descriptionDone = [ "strip" ]
+
+	def start(self):
+		properties = self.build.getProperties()
+
+		if not properties.has_key("package"):
+			return SKIPPED
+
+		ShellCommand.start(self)
+
+# Buildstep class to package binaries, only done on nightly builds.
+class Package(ShellCommand):
+	name = "package"
+	haltOnFailure = 1
+	flunkOnFailure = 1
+	description = [ "packaging" ]
+	descriptionDone = [ "package" ]
+
+	def __init__(self, **kwargs):
+		self.srcpath = kwargs["srcpath"]
+		del kwargs["srcpath"]
+		self.dstpath = kwargs["dstpath"]
+		del kwargs["dstpath"]
+		self.package = kwargs["package"]
+		del kwargs["package"]
+		self.buildname = kwargs["buildname"]
+		del kwargs["buildname"]
+		self.platform_package = kwargs["platform_package"]
+		del kwargs["platform_package"]
+
+		kwargs["workdir"] = "package"
+
+		ShellCommand.__init__(self, **kwargs)
+
+		self.addFactoryArguments(srcpath = self.srcpath)
+		self.addFactoryArguments(dstpath = self.dstpath)
+		self.addFactoryArguments(package = self.package)
+		self.addFactoryArguments(buildname = self.buildname)
+		self.addFactoryArguments(platform_package = self.platform_package)
+
+	def start(self):
+		properties = self.build.getProperties()
+
+		if not properties.has_key("package"):
+			return SKIPPED
+
+		name = "%s-r%s" % (self.buildname, properties["got_revision"])
+		file = "%s.tar.bz2" % name
+		symlink = "%s-latest.tar.bz2" % self.buildname
+		files = [ os.path.join(self.srcpath, i) for i in self.package ]
+		files += [ os.path.join("../build", i) for i in self.platform_package ]
+
+		self.command = "mkdir %s && " \
+						"cp %s %s/ && " \
+						"tar cvjf %s %s/ && " \
+						"mv %s %s/ && " \
+						"ln -sf %s %s && " \
+						" rm -rf %s || " \
+						"( rm -rf %s; return 1 )" \
+						% (name,
+							" ".join(files), name,
+							file, name,
+							file, self.dstpath,
+							file, os.path.join(self.dstpath, symlink),
+							name,
+							name)
+					
+		ShellCommand.start(self)
+
+class Clean(ShellCommand):
+	name = "clean"
+	haltOnFailure = 1
+	flunkOnFailure = 1
+	description = [ "cleaning" ]
+	descriptionDone = [ "clean" ]
+
+	def __init__(self, **kwargs):
+		self.prefix = kwargs["prefix"]
+		del kwargs["prefix"]
+
+		ShellCommand.__init__(self, **kwargs)
+
+		self.addFactoryArguments(prefix = self.prefix)
+
+	def start(self):
+		self.command = "ccache -C && rm -rf ../../%s-*" % self.prefix
+		ShellCommand.start(self)
+
+# IRC stuff
+
+scumm_buildbot_root_url = "http://buildbot.scummvm.org/"
+
+class IrcStatusBot(irc.IRCClient):
+	implements(Interface)
+
+	timer = None
+
+	def __init__(self, nickname, password, channel, status, categories, stableTimer):
+		self.nickname = nickname
+		self.channel = channel
+		self.password = password
+		self.status = status
+		self.categories = categories
+		self.stableTimer = stableTimer
+		self.delayedSuccess = []
+		self.delayedFailure = []
+		self.status.subscribe(self)
+
+	silly = {
+				"hello": "yes?",
+				"hi": "hello"
+			}
+
+	def log(self, msg):
+		log.msg("%s: %s" % (self, msg))
+
+	def send(self, message):
+		self.msg(self.channel, message.encode("ascii", "replace"))
+
+	def act(self, action):
+		self.me(self.channel, action.encode("ascii", "replace"))
+
+	def getAllBuilders(self):
+		names = self.status.getBuilderNames(categories = self.categories)
+		names.sort()
+		builders = [self.status.getBuilder(n) for n in names]
+		return builders
+
+	def getFailureBuilders(self):
+		failure = []
+		for b in self.getAllBuilders():
+			last = b.getLastFinishedBuild()
+			if last != None and last.getResults() == FAILURE:
+				failure.append(b.getName())
+		return failure
+
+	def buildsetSubmitted(self, buildset):
+		self.log('Buildset %s added' % (buildset))
+
+	def builderAdded(self, builderName, builder):
+		self.log('Builder %s added' % (builder))
+		builder.subscribe(self)
+
+	def builderChangedState(self, builderName, state):
+		self.log('Builder %s changed state to %s' % (builderName, state))
+		idle = True
+		for b in self.getAllBuilders():
+			if b.getState()[0] != "idle":
+				idle = False
+				break
+
+		if not idle:
+			return
+
+		if self.timer:
+			self.log('All builders are idle, reporting now')
+			self.timer.reset(0)
+
+	def requestSubmitted(self, brstatus):
+		self.log('BuildRequest for %s submiitted to Builder %s' % 
+			(brstatus.getSourceStamp(), brstatus.builderName))
+
+	def builderRemoved(self, builderName):
+		self.msg('Builder %s removed' % (builderName))
+
+	def buildStarted(self, builderName, build):
+		builder = build.getBuilder()
+		self.log('Builder %r in category %s started' % (builder, builder.category))
+
+	def buildFinished(self, builderName, build, results):
+		builder = build.getBuilder()
+
+		# only notify about builders we are interested in
+		self.log('Builder %r in category %s finished' % (builder, builder.category))
+
+		if (self.categories != None and builder.category not in self.categories):
+			return
+
+		result = build.getResults()
+		if not result in [ SUCCESS, FAILURE ]:
+			return
+
+		prevResult = build.getPreviousBuild().getResults()
+		if not prevResult in [ SUCCESS, FAILURE ]:
+			return
+
+		if result == prevResult:
+			return
+
+		self.log('Delaying status report for builder %r' % builder)
+
+		if result == SUCCESS:
+			self.delayedSuccess.append(builder.getName())
+		else:
+			self.delayedFailure.append(builder.getName())
+
+		if self.timer:
+			self.log('Canceling previous status callback')
+			self.timer.cancel()
+			self.timer = None
+
+		self.timer = reactor.callLater(self.stableTimer,
+										self.reportBuildStatus,
+										build.getProperty("got_revision"))
+
+	def reportBuildStatus(self, revision):
+		self.timer = None
+
+		m = "Port build status changed with r\x02%s\x0f: " % revision
+
+		if len(self.delayedSuccess) > 0:
+			m += "\x0303Success\x0f: %s" % ", ".join(self.delayedSuccess)
+			self.delayedSuccess = []
+
+		if len(self.delayedFailure) > 0:
+			m += "\x0304Failure\x0f: %s" % ", ".join(self.delayedFailure)
+			self.delayedFailure = []
+
+		failure = self.getFailureBuilders()
+		if len(failure) == 0:
+			m += ". Nice work, all ports built fine now"
+
+		m += ". %s" % scumm_buildbot_root_url
+
+		self.send(m)
+
+	def handleAction(self, data, user):
+		if not data.endswith("s %s" % self.nickname):
+			return
+
+		words = data.split()
+		verb = words[-2]
+
+		timeout = 4
+		if verb == "kicks":
+			response = "%s back" % verb
+			timeout = 1
+		else:
+			response = "%s %s too" % (verb, user)
+
+		reactor.callLater(timeout, self.act, response)
+
+	def handleMessage(self, message, who):
+		message = message.lstrip()
+		if self.silly.has_key(message):
+			return self.doSilly(message)
+
+		parts = message.split(' ', 1)
+		if len(parts) == 1:
+			parts = parts + ['']
+		cmd, args = parts
+
+		meth = self.getCommandMethod(cmd)
+
+		if (meth == None):
+			return
+
+		self.log("IRC command '%s' from user '%s'" % (cmd, who))
+
+		error = None
+		try:
+			meth(args.strip(), who)
+		except:
+			f = failure.Failure()
+			log.err(f)
+			error = "Something bad happened (see logs): %s" % f.type
+
+		if error:
+			try:
+				self.send(error)
+			except:
+				log.err()
+
+	def doSilly(self, message):
+		response = self.silly[message]
+		if type(response) != type([]):
+			response = [response]
+		when = 0.5
+		for r in response:
+			reactor.callLater(when, self.send, r)
+			when += 2.5
+
+	def getCommandMethod(self, command):
+		meth = getattr(self, 'command_' + command.upper(), None)
+		return meth
+
+	def command_VERSION(self, args, who):
+		self.send("buildbot-%s at your service" % version)
+
+	def command_PING(self, args, who):
+		self.send("pong")
+
+	def command_STATUS(self, args, who):
+		failure = self.getFailureBuilders()
+
+		if len(failure) < 1:
+			self.send("Last time I checked, all ports built just fine")
+			return
+
+		if len(failure) == 1:
+			self.send("%s is currently not building" % failure[0])
+			return
+
+		self.send("%d ports are currently not building: %s, see %s" % \
+					(len(failure),
+					 ", ".join(failure),
+					 scumm_buildbot_root_url))
+
+	# the following irc.IRCClient methods are called when we have input
+
+	def privmsg(self, user, channel, message):
+		if not channel == self.channel:
+			return
+
+		user = user.split('!', 1)[0] # rest is ~user at hostname
+
+		if message.startswith("%s:" % self.nickname) or message.startswith("%s," % self.nickname):
+			message = message[len("%s:" % self.nickname):]
+			self.handleMessage(message.strip(), user)
+		# to track users comings and goings, add code here
+
+	def action(self, user, channel, data):
+		data = data.strip()
+		user = user.split('!', 1)[0] # rest is ~user at hostname
+
+		# somebody did an action (/me actions) in the broadcast channel
+		if self.nickname in data:
+			self.handleAction(data, user)
+
+	def signedOn(self):
+		if self.password:
+			self.msg("Nickserv", "IDENTIFY " + self.password)
+		self.join(self.channel)
+
+	def joined(self, channel):
+		self.log("I have joined %s" % channel)
+
+	def left(self, channel):
+		self.log("I have left %s" % channel)
+
+	def kickedFrom(self, channel, kicker, message):
+		self.log("I have been kicked from %s by %s: %s" % (channel,
+														  kicker,
+														  message))
+
+	# we can using the following irc.IRCClient methods to send output.
+	#
+	# self.say(channel, message) # broadcast
+	# self.msg(user, message) # unicast
+	# self.me(channel, action) # send action
+	# self.away(message='')
+	# self.quit(message='')
+
+class ThrottledClientFactory(protocol.ClientFactory):
+	lostDelay = 2
+	failedDelay = 60
+
+	def clientConnectionLost(self, connector, reason):
+		reactor.callLater(self.lostDelay, connector.connect)
+
+	def clientConnectionFailed(self, connector, reason):
+		reactor.callLater(self.failedDelay, connector.connect)
+
+class IrcStatusFactory(ThrottledClientFactory):
+	protocol = IrcStatusBot
+
+	status = None
+	control = None
+	shuttingDown = False
+	p = None
+
+	def __init__(self, nickname, password, channel, categories, stableTimer):
+		#ThrottledClientFactory.__init__(self) # doesn't exist
+		self.status = None
+		self.nickname = nickname
+		self.password = password
+		self.channel = channel
+		self.categories = categories
+		self.stableTimer = stableTimer
+
+	def __getstate__(self):
+		d = self.__dict__.copy()
+		del d['p']
+		return d
+
+	def shutdown(self):
+		self.shuttingDown = True
+		if self.p:
+			self.p.quit("buildmaster reconfigured: bot disconnecting")
+
+	def buildProtocol(self, address):
+		p = self.protocol(self.nickname, self.password,
+						  self.channel, self.status,
+						  self.categories, self.stableTimer)
+		p.factory = self
+		p.status = self.status
+		p.control = self.control
+		self.p = p
+		return p
+
+	# TODO: I think a shutdown that occurs while the connection is being
+	# established will make this explode
+
+	def clientConnectionLost(self, connector, reason):
+		if self.shuttingDown:
+			log.msg("not scheduling reconnection attempt")
+			return
+		ThrottledClientFactory.clientConnectionLost(self, connector, reason)
+
+	def clientConnectionFailed(self, connector, reason):
+		if self.shuttingDown:
+			log.msg("not scheduling reconnection attempt")
+			return
+		ThrottledClientFactory.clientConnectionFailed(self, connector, reason)
+
+
+class IRC(base.StatusReceiverMultiService):
+	compare_attrs = ["host", "port", "nick", "password",
+					 "channel", "categories"]
+
+	def __init__(self, host, nick, channel, port = 6667, categories = None,
+					password = None, stableTimer = 60):
+		base.StatusReceiverMultiService.__init__(self)
+
+		# need to stash these so we can detect changes later
+		self.host = host
+		self.port = port
+		self.nick = nick
+		self.channel = channel
+		self.password = password
+		self.categories = categories
+		self.stableTimer = stableTimer
+
+		# need to stash the factory so we can give it the status object
+		self.f = IrcStatusFactory(self.nick, self.password, self.channel,
+									self.categories, self.stableTimer)
+
+		c = internet.TCPClient(host, port, self.f)
+		c.setServiceParent(self)
+
+	def setServiceParent(self, parent):
+		base.StatusReceiverMultiService.setServiceParent(self, parent)
+		self.f.status = parent.getStatus()
+
+	def stopService(self):
+		# make sure the factory will stop reconnecting
+		self.f.shutdown()
+		return base.StatusReceiverMultiService.stopService(self)
+


Property changes on: buildbot/config/scumm.py
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list