Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

585 lines
24 KiB

  1. #====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
  2. #
  3. # Purpose: Syncs, builds and runs tests on the steam code in
  4. # the currently active p4 clientspec
  5. #
  6. #=============================================================================
  7. # INSTALLATION INSTRUCTIONS:
  8. #
  9. # 1. add the vc compiler solution compiler devenv.exe to the path (defaults to being in "C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Common7\\IDE\\devenv.exe")
  10. # 2. create a P4 clientspec that contains the steam code, eg. //steam/main/...
  11. # 3. make that the default clientspec
  12. # 4. sync to it
  13. # 5. run this build script from inside that directory
  14. import sys, os, string, re, time, smtplib, getopt, P4, SystemHelpers
  15. # config options
  16. g_bTest = 0 # 1: disables reporting to SRCDEV; only reports to admin
  17. g_bRunTests = 0 # 1: enables testing after build is complete
  18. g_bSync = 0 # 1: enables syncing to perforce
  19. g_bLockMutex = 0 # 1: require mutex to be free before proceeding to build
  20. g_bBuild = 0 # 1: build binaries
  21. g_bDebug = 0 # 1: enables debug output
  22. g_bDev = 0 # 1: script builds immediately upon start, regardless of presence of perforce state
  23. g_bShaders = 0
  24. g_bXBOX = 0
  25. g_szEmailAlias = "" # email alias of users interested in build failures
  26. g_szAdministrator = "" # address to auto-email if the script fails for some reason, test output
  27. g_szMailhost = "" # set to hostname of machine running an SMTP server
  28. g_szSenderEmail = "" # email address that the failure mails come from; TODO: Get buildmachine email
  29. g_szBuildExe = "" # executable for compilation; devenv: .Net, BuildConsole: IncrediBuild
  30. #g_szBuildExe = "devenv" # executable for compilation; devenv: .Net, BuildConsole: IncrediBuild
  31. g_szBuildType = "" # build type; /rebuild or /build
  32. g_szBuildFlags = "" # should be empty for devenv, /all for buildconsole
  33. g_szTestingFile = "" # name of testing file, located in .\Build Machine Tests\
  34. g_szLocalLogFile = "" # name of generated log file; currently not used
  35. g_szPublishedErrorsDir = "" # place to copy log file to reference in failure email
  36. g_szTestDirectory = "" # directory where the testing files are located
  37. g_szBaseDir = os.getcwd() # directory from which the script is launched
  38. g_szP4SrcFilesToWatch = "" # path to src files to watch
  39. g_szP4ForceFilesToWatch = "" # path to bin files to watch
  40. g_szP4SyncFilesToWatch = ""
  41. g_szP4Mutex = "" # name of perforce mutex to wait for
  42. g_szP4ChangeCounter = "" # perforce counter containg the changelist number we're verifying
  43. g_szP4VerifiedCounter = "" # perforce counter the last changelist number we have verified
  44. g_nP4MostRecentCheckin = 0 # used to keep track of current checkin
  45. g_nP4LastVerifiedCheckin = 0 # used to keep track of last verified checkin
  46. g_nSleepTimeBetweenChecks = 10 # number of seconds to wait before checking for a free mutex
  47. g_szBuildName = ""
  48. # mails off a success checkin
  49. def SendSuccessEmail( _szEmail, _szChangeNumber ):
  50. cMailport = smtplib.SMTP(g_szMailhost)
  51. szTestString = ""
  52. if g_bTest:
  53. szTestString = "TEST"
  54. print "sending success email to: " + _szEmail
  55. szMessage = 'From: ' + g_szBuildName + ' Builder ' + ' <' + g_szSenderEmail + '>\n' +\
  56. 'To: ' + szTestString + _szEmail + '\n' +\
  57. 'Subject: [ ' + g_szBuildName + ' build successful ]' +\
  58. '\n' +\
  59. '\n' +\
  60. 'Your checkin:\n\n' +\
  61. _szChangeNumber +\
  62. '\n\n' +\
  63. 'has been successfully built and verified against all tests.\n'
  64. if ( g_bTest | g_bDev ):
  65. cMailport.sendmail( g_szSenderEmail, g_szAdministrator, szMessage )
  66. else:
  67. cMailport.sendmail( g_szSenderEmail, _szEmail, szMessage )
  68. cMailport.quit()
  69. # print of debugging messages
  70. def dPrint( _szText ):
  71. if g_bDebug:
  72. print _szText
  73. # mails off the current error string
  74. def SendFailureEmail( _szErr ):
  75. cMailport = smtplib.SMTP( g_szMailhost )
  76. szTestString = ""
  77. if g_bTest:
  78. szTestString = "TEST"
  79. print "sending failure email to: " + g_szEmailAlias
  80. print "failure reason: " + _szErr
  81. szMessage = 'From: ' + g_szBuildName + ' Builder' + ' <' + g_szSenderEmail + '>\n' +\
  82. 'To: ' + szTestString + g_szEmailAlias + '\n' +\
  83. 'Subject: [ ' + g_szBuildName + ' branch broken ]' +\
  84. '\n' +\
  85. '\n' +\
  86. _szErr +\
  87. '\n' +\
  88. P4.GetUnverifiedCheckins( g_szP4SrcFilesToWatch, g_szP4VerifiedCounter, g_szP4ChangeCounter )
  89. if g_bTest | g_bDev:
  90. cMailport.sendmail( g_szSenderEmail, g_szAdministrator, szMessage )
  91. else:
  92. cMailport.sendmail( g_szSenderEmail, szTestString + g_szEmailAlias, szMessage )
  93. cMailport.quit()
  94. # use to email the admin about any unexpected errors that occur
  95. def ComplainToAdmin( _szErr ):
  96. cMailport = smtplib.SMTP(g_szMailhost)
  97. print "sending script failure email to: " + g_szAdministrator
  98. print "failure reason: |" + _szErr + "|"
  99. szMessage = 'From: ' + g_szBuildName + " Builder" + ' <' + g_szSenderEmail + '>\n' +\
  100. 'To: ' + g_szAdministrator + '\n' +\
  101. 'Subject: [ ' + g_szBuildName + ' builder build script error ]' +\
  102. '\n' +\
  103. '\n' +\
  104. 'error reason:\n' +\
  105. _szErr +\
  106. '\n'
  107. cMailport.sendmail(g_szSenderEmail, g_szAdministrator, szMessage)
  108. cMailport.quit()
  109. # parses out the reason for failure from a test
  110. def GetTestFailureReason( _nBuild ):
  111. # start our error message
  112. szMsg = "Test log file:\n"
  113. # make a directory to copy the error files into, based on the build config and the p4 changelist number
  114. nBuildNum = P4.GetCounter(g_szP4ChangeCounter)
  115. szErrDir = g_szPublishedErrorsDir + nBuildNum + "\\" + _nBuild
  116. os.popen("mkdir " + szErrDir, "r").read()
  117. # copy all the files to the errors dir
  118. os.popen("copy " + _nBuild + "\\*.*" + " " + szErrDir + " /Y", "r").read()
  119. # add the error log to the failure message
  120. szMsg += " " + szErrDir + "\\" + g_szLocalLogFile + "\n"
  121. # add the minidumps to the failure message
  122. rgMinidumps = string.split( os.popen("dir " + _nBuild + "\\*.mdmp /b", "r").read(), "\n" )
  123. if len(rgMinidumps) > 1:
  124. szMsg += "\nCrash dump:\n"
  125. for szMinidump in rgMinidumps:
  126. if len(szMinidump) > 16:
  127. szMsg += " " + szErrDir + "\\" + szMinidump + "\n"
  128. szMsg += "To view the minidump, click the link above then click \"open\" on the next dialog.\nHit \"F5\" in the now open debugger. When it asks for the source code, change the start of the suggested path from \"c:\\\" to \"\\\\steam3builder\\\".\n"
  129. # delete the minidumps, so they don't confuse us next time
  130. os.popen("del " + _nBuild + "\\*.mdmp", "r").read()
  131. # parse out the error from the logfile
  132. szLog = os.popen( "type " + _nBuild + "\\" + szLocalLogFile, "r").read()
  133. szLogLines = []
  134. szLogLines = string.split( szLog, "\n" )
  135. bFoundErr = 0
  136. for szLine in szLogLines:
  137. aszToken = string.split(szLine, ' ')
  138. if len( aszToken ) > 3:
  139. if aszToken[0] == "***" and aszToken[1] == "TEST" and aszToken[2] == "FAILED":
  140. # probably an error line, add to the list
  141. szMsg += szLine
  142. szMsg += "\n"
  143. bFoundErr = 1
  144. # if we haven't found any error lines, use the last line of the file
  145. if bFoundErr == 0 and len(szLogLines) > 0:
  146. szMsg += szLogLines[len(szLogLines) - 1]
  147. return szMsg
  148. # performs a single test run of the specified exe with the specified test parameters
  149. def RunTest( _szCommand ):
  150. aszParms = string.split( _szCommand, " ", 1)
  151. print "running " + _szCommand
  152. print os.popen( _szCommand, "r" ).read()
  153. # return success
  154. return aszParms[0]
  155. def RunCompare( _szCommand ):
  156. szResult = os.popen( _szCommand, "r" ).read()
  157. return szResult
  158. def SearchFileForErrors( _szFile, _szError ):
  159. print ("Searching " + _szFile + " for occurences of " + _szError + ".\n")
  160. bIncludeNext = 0
  161. szErrorResults = ""
  162. aszFileLines = string.split( os.popen( "type " + _szFile, "r").read(), "\n" )
  163. for szLine in aszFileLines:
  164. if ( bIncludeNext == 1 ):
  165. szErrorResults += szLine + "\n"
  166. bIncludeNext = 0
  167. aszParms = string.split(szLine, " ", 1)
  168. if (aszParms[0] == _szError):
  169. #there is a UnitTest error, warning, or assert
  170. szErrorResults += "\n" + szLine + "\n"
  171. bIncludeNext = 1;
  172. return szErrorResults
  173. # runs a set of tests as defined by the test script file
  174. def RunTestScript( ):
  175. print ("Enter Testing")
  176. # make sure we're in the right dir
  177. SystemHelpers.ChangeDir("..")
  178. # load the script
  179. szReturn = os.popen( "RunTestScripts.py" ).read()
  180. return szReturn
  181. # runs a single build, and runs the tests on the build if specified
  182. def RunBuild( _szBuild ):
  183. # launch devstudio to build the solution
  184. szCmd = _szBuild
  185. aszToken = string.split(szCmd, " ", 3)
  186. if aszToken[0] == "devenv":
  187. #we are building this. Find out what it is.
  188. if aszToken[2] == "/project":
  189. #building a project. Grab it.
  190. aszToken = string.split(szCmd, " ", 5)
  191. szCmd = g_szBuildExe + " " + aszToken[1] + " /project " + aszToken[3] + " " + g_szBuildType + " " + aszToken[5]
  192. else:
  193. #not build a specific project. Probably everything under lostcoast.
  194. szCmd = g_szBuildExe + " " + aszToken[1] + " " + g_szBuildType + " " + aszToken[3] + " " + g_szBuildFlags
  195. else:
  196. #didn't see the devenv line; not building this but it isn't an error either.
  197. return ""
  198. print "building: " + szCmd
  199. szOutput = os.popen(szCmd, "r").read()
  200. # parse the output for any errors
  201. aszOutputLines = string.split(szOutput, "\n")
  202. bSuccess = 1
  203. szBuildErr = "\n\n\nError building configuration " + _szBuild + ":\n"
  204. for szLine in aszOutputLines:
  205. if g_bDebug:
  206. print szLine;
  207. aszTokens = string.split(string.lstrip(szLine), ' ', 4)
  208. if len(aszTokens) > 1:
  209. if aszTokens[0] == "--------------------Configuration:":
  210. bPrintedProject = 0
  211. szProject = aszTokens[1]
  212. if aszTokens[1] == ":" and aszTokens[2] == "error" and aszTokens[3] != "PRJ0019":
  213. # probably an error line, add to the list
  214. count = string.count( szBuildErr, aszTokens[4])
  215. if ( count == 0 ):
  216. if ( bPrintedProject == 0 ):
  217. szBuildErr += "Project: " + szProject + "\n"
  218. bPrintedProject = 1
  219. szBuildErr += szLine + "\n"
  220. #err2 += szLine + "\n"
  221. bSuccess = 0
  222. if aszTokens[1] == ":" and aszTokens[2] == "error" and aszTokens[3] == "PRJ0019":
  223. # the delete error line, add to the list
  224. szBuildErr += "IGNORE: "
  225. szBuildErr += szLine + "\n"
  226. #err2 += szLine + "\n"
  227. aszTokens = string.split(string.lstrip(szLine), ' ')
  228. if len(aszTokens) > 4:
  229. # can't do this: the weird delete error will trigger this and we need to ignore that
  230. # check that the "Rebuild All: x succeeded, y failed, z skipped line says no failures
  231. #if szT[0] == "Rebuild" and szT[3] rrorMessages + "The " + szTestName + " test failed\nThe error is " + szCompareLine
  232. #if szErrorMessages== "succeeded," and szT[5] == "failed," and not szT[4] == "0":
  233. # failure
  234. # bSuccess = 0
  235. # check for linker errors
  236. if aszTokens[0] == "LINK" and aszTokens[1] == ":" and aszTokens[2] == "fatal" and aszTokens[3] == "error":
  237. if ( bPrintedProject == 0 ):
  238. szBuildErr += "Project: " + szProject + "\n"
  239. bPrintedProject = 1
  240. # linker error line, add to the list
  241. szBuildErr += szLine + "\n"
  242. #err2 += szLine + "\n"
  243. bSuccess = 0
  244. # can't do this either: Delete file problem
  245. # check the standard error dealie.
  246. # if szT[1] == '-' and szT[3] == "error(s)," and szT[2] != '0':
  247. #we have a build error here
  248. # err += szLine
  249. # err += "\n"
  250. #check for fatal error
  251. if aszTokens[2] == "fatal" and aszTokens[3] == "error":
  252. if ( bPrintedProject == 0 ):
  253. szBuildErr += "Project: " + szProject + "\n"
  254. bPrintedProject = 1
  255. #fatal error
  256. szBuildErr += szLine + "\n"
  257. #err2 += szLine + "\n"
  258. bSuccess = 0
  259. # return immediately if failed
  260. if not bSuccess:
  261. print szBuildErr
  262. szBuildErr + "\n\n"
  263. #ComplainToAdmin(err2)
  264. return szBuildErr
  265. return ""
  266. def RunBuildBatch():
  267. bSuccess = 1
  268. #aszBatchBuildLines = string.split( os.popen( "type " + szBatchFile, "r").read(), "\n" )
  269. #bIsDevLine = 0
  270. szBuildErrs = ""
  271. szBuildResult = RunBuild( "devenv everything.sln /build \"debug|win32\" " )
  272. szBuildResult += RunBuild( "devenv everything.sln /build \"release|win32\" " )
  273. szTestResult = RunTestScript()
  274. if szBuildResult != "":
  275. szBuildErrs += szBuildResult
  276. bSuccess = 0
  277. if szTestResult != "\n":
  278. szBuildErrs += szTestResult
  279. bSuccess = 0
  280. if not bSuccess:
  281. SendFailureEmail(szBuildErrs)
  282. return bSuccess
  283. # runs all the builds
  284. def RunAllBuilds():
  285. bSuccess = 1
  286. szBuildErrs = ""
  287. SystemHelpers.ChangeDir("\game")
  288. if g_bBuild:
  289. SystemHelpers.ChangeDir("\src")
  290. # build the shadercompiler and all shaders
  291. if g_bShaders:
  292. print( "Compiling shadercompile" )
  293. os.system( "devenv shadercompile.sln /rebuild release > silence" )
  294. # should check here to make sure the shadercompile worked
  295. SystemHelpers.ChangeDir("\\src\\materialsystem\\stdshaders")
  296. print( "Building shaders" )
  297. child_stdin, child_stdout, child_stderr = os.popen3( "buildallshaders.bat" )
  298. print( child_stdout.read() )
  299. szSomeShaderErr = child_stderr.read()
  300. szShaderErrors = ""
  301. aszShaderLines = string.split( szSomeShaderErr, "\n" )
  302. for szLine in aszShaderLines:
  303. dPrint( szLine )
  304. nCount = string.count( szLine, 'U1073:' )
  305. if nCount > 0:
  306. aszToken = string.split( szLine, " " )
  307. szShaderName = aszToken[9]
  308. szShaderErrors = szShaderErrors + "The shader file " + szShaderName + " is missing and failed during buildallshaders.bat.\n"
  309. if szShaderErrors:
  310. SendFailureEmail( szShaderErrors )
  311. SystemHelpers.ChangeDir("\\src")
  312. bSuccess = bSuccess & RunBuildBatch();
  313. #XBOX Section
  314. if g_bXBOX:
  315. szXBoxOutput = RunBuild( "devenv source_x360.sln /rebuild \"release|xbox 360\"" )
  316. if "\n\n\nError building configuration " + "devenv source_x360.sln /rebuild release" + ":\n" != szXBoxOutput:
  317. bSuccess = 0
  318. SendFailureEmail( szXBoxOutput )
  319. #delete tier0.dll
  320. if g_bRunTests:
  321. szTestErrors = RunTestScript()
  322. if szTestErrors != "\n":
  323. # success = 0
  324. ComplainToAdmin( szTestErrors )
  325. return bSuccess
  326. # builds from a local branch and runs a subset of tests
  327. def PerformSourceBuild():
  328. # build and test in each configuration
  329. if not RunAllBuilds():
  330. print "Source build failed"
  331. return 0
  332. print "Source build: SUCCESS"
  333. return 1
  334. # syncs, builds, runs tests
  335. def PerformDailyBuild():
  336. print " changes detected, starting daily build"
  337. # update the counter to be what we're verifying
  338. change = P4.SubmittedChangelist( g_szP4SrcFilesToWatch )
  339. g_nP4MostRecentCheckin = change
  340. g_nP4LastVerifiedCheckin = P4.GetCounter(g_szP4VerifiedCounter)
  341. if g_nP4MostRecentCheckin and g_nP4LastVerifiedCheckin:
  342. print "Most recent checkin is " + g_nP4MostRecentCheckin + "\n"
  343. print "Last verified checkin is " + g_nP4LastVerifiedCheckin + "\n"
  344. # the p4 command can occasionally fail to deliver a valid changelist number, unclear why
  345. # can't update the counter, it just means we'll run twice
  346. if change:
  347. P4.SetCounter(g_szP4ChangeCounter, change)
  348. # sync to the new files
  349. if ( g_bSync ):
  350. SystemHelpers.ChangeDir("\\src")
  351. print( "Cleaning\n" )
  352. os.system("cleanalltargets.bat > silence")
  353. SystemHelpers.ChangeDir("\\")
  354. print "Synching force files."
  355. P4.Sync( g_szP4ForceFilesToWatch, 1 )
  356. print "Synching other files."
  357. P4.Sync( g_szP4SyncFilesToWatch, 0 )
  358. print( "Setting up VPC" )
  359. os.system("setupVPC.bat")
  360. #P4.UnlockMutex(g_szP4Mutex)
  361. # build and test in each configuration
  362. if not RunAllBuilds():
  363. print "Daily build failed"
  364. return
  365. # send a success email, from past the last successful checkin to the current
  366. if change:
  367. szVerifiedOrig = P4.GetCounter(g_szP4VerifiedCounter)
  368. if szVerifiedOrig:
  369. szVerifiedPlusOne = str( int( szVerifiedOrig ) + 1 )
  370. changes = P4.GetChangelistRange(szVerifiedPlusOne, change, g_szP4SrcFilesToWatch );
  371. for ch in changes:
  372. if len(ch) > 1:
  373. szEmail = P4.GetEmailFromChangeLine(ch)
  374. SendSuccessEmail(szEmail, ch)
  375. #SendSuccessEmail("jason", ch)
  376. # remember this change that we've verified
  377. P4.SetCounter(g_szP4VerifiedCounter, change)
  378. print "Daily build: AN UNEQUIVOCAL SUCCESS"
  379. def PrintConfig():
  380. print("Configuration:")
  381. print("test = " + str(g_bTest))
  382. print("run_tests = " + str(g_bRunTests))
  383. print("lock_mutex = " + str(g_bLockMutex))
  384. print("build = " + str(g_bBuild))
  385. print("debug = " + str(g_bDebug))
  386. print("dev = " + str(g_bDev))
  387. print("shaders = " + str(g_bShaders))
  388. print("sync = " + str(g_bSync))
  389. print("email_alias = " + g_szEmailAlias)
  390. print("admin_email = " + g_szAdministrator)
  391. print("mail_host = " + g_szMailhost)
  392. print("sender_email = " + g_szSenderEmail)
  393. print("build_exe = " + g_szBuildExe)
  394. print("build_type = " + g_szBuildType)
  395. print("build_flags = " + g_szBuildFlags)
  396. print("test_file = " + g_szTestingFile)
  397. print("log_file = " + g_szLocalLogFile)
  398. print("error_dir = " + g_szPublishedErrorsDir)
  399. print("test_dir = " + g_szTestDirectory)
  400. print("src_files = " + g_szP4SrcFilesToWatch)
  401. print("force_files = " + g_szP4ForceFilesToWatch)
  402. print("sync_files = " + g_szP4SyncFilesToWatch)
  403. print("mutex = " + g_szP4Mutex)
  404. print("change_counter = " + g_szP4ChangeCounter)
  405. print("verify_counter = " + g_szP4VerifiedCounter)
  406. print("build_name = " + g_szBuildName)
  407. def ParseConfigFile(configFileName):
  408. aszBatchBuildLines = string.split( os.popen( "type " + configFileName, "r").read(), "\n" )
  409. global g_bTest
  410. global g_bRunTests
  411. global g_bLockMutex
  412. global g_bBuild
  413. global g_bDebug
  414. global g_bDev
  415. global g_bShaders
  416. global g_bSync
  417. global g_szEmailAlias
  418. global g_szAdministrator
  419. global g_szMailhost
  420. global g_szSenderEmail
  421. global g_szBuildExe
  422. global g_szBuildType
  423. global g_szBuildFlags
  424. global g_szTestingFile
  425. global g_szLocalLogFile
  426. global g_szPublishedErrorsDir
  427. global g_szTestDirectory
  428. global g_szP4SrcFilesToWatch
  429. global g_szP4ForceFilesToWatch
  430. global g_szP4SyncFilesToWatch
  431. global g_szP4Mutex
  432. global g_szP4ChangeCounter
  433. global g_szP4VerifiedCounter
  434. global g_szBuildName
  435. for szLine in aszBatchBuildLines:
  436. aszTokens = string.split(string.lstrip(szLine), ' ', 2)
  437. firstToken = aszTokens[0]
  438. if firstToken == '#' or firstToken == '':
  439. continue
  440. secondToken = aszTokens[1]
  441. if firstToken == "test":
  442. g_bTest = int(secondToken)
  443. elif firstToken == "run_tests":
  444. g_bRunTests = int(secondToken)
  445. elif firstToken == "lock_mutex":
  446. g_bLockMutex = int(secondToken)
  447. elif firstToken == "build":
  448. g_bBuild = int(secondToken)
  449. elif firstToken == "debug":
  450. g_bDebug = int(secondToken)
  451. elif firstToken == "dev":
  452. g_bDev = int(secondToken)
  453. elif firstToken == "shaders":
  454. g_bShaders = int(secondToken)
  455. elif firstToken == "sync":
  456. g_bSync = int(secondToken)
  457. elif firstToken == "email_alias":
  458. g_szEmailAlias = secondToken
  459. elif firstToken == "admin_email":
  460. g_szAdministrator = secondToken
  461. elif firstToken == "mail_host":
  462. g_szMailhost = secondToken
  463. elif firstToken == "sender_email":
  464. g_szSenderEmail = secondToken
  465. elif firstToken == "build_exe":
  466. g_szBuildExe = secondToken
  467. elif firstToken == "build_type":
  468. g_szBuildType = secondToken
  469. elif firstToken == "build_flags":
  470. g_szBuildFlags = secondToken
  471. elif firstToken == "test_file":
  472. g_szTestingFile = secondToken
  473. elif firstToken == "log_file":
  474. g_szLocalLogFile = secondToken
  475. elif firstToken == "error_dir":
  476. g_szPublishedErrorsDir = secondToken
  477. elif firstToken == "test_dir":
  478. g_szTestDirectory = secondToken
  479. elif firstToken == "src_files":
  480. g_szP4SrcFilesToWatch += secondToken
  481. elif firstToken == "force_files":
  482. g_szP4ForceFilesToWatch += secondToken + ";"
  483. elif firstToken == "sync_files":
  484. g_szP4SyncFilesToWatch += secondToken + ";"
  485. elif firstToken == "mutex":
  486. g_szP4Mutex = secondToken
  487. elif firstToken == "change_counter":
  488. g_szP4ChangeCounter = secondToken
  489. elif firstToken == "verify_counter":
  490. g_szP4VerifiedCounter = secondToken
  491. elif firstToken == "build_name":
  492. g_szBuildName = secondToken
  493. PrintConfig()
  494. #-----------------------------------------------------------------------------
  495. # Main
  496. #-----------------------------------------------------------------------------
  497. if __name__ == '__main__':
  498. try:
  499. print "----------------------------------------------------"
  500. print g_szBuildName + " BUILD SCRIPT STARTED"
  501. ParseConfigFile(sys.argv[1])
  502. while 1:
  503. if (g_bDev | P4.AnyNewCheckins( g_szP4ChangeCounter, g_szP4SrcFilesToWatch )):
  504. print "Changes Detected.\n"
  505. if ( (g_bTest & ~g_bLockMutex) | ~g_bLockMutex | P4.Query(g_szP4Mutex) ):
  506. PerformDailyBuild()
  507. g_bDev = 0
  508. print ""
  509. print "------------------------------------------"
  510. print "waiting for changes to be detected..."
  511. else:
  512. time.sleep( g_nSleepTimeBetweenChecks - ( g_bTest * g_nSleepTimeBetweenChecks ))
  513. else:
  514. time.sleep( g_nSleepTimeBetweenChecks )
  515. except RuntimeError, e:
  516. ComplainToAdmin(e)