123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976 |
- import subprocess, sys, os, copy
- import urllib, shutil, subprocess
- import platform, json, operator
- import threading, types, traceback
- if sys.version_info >= (2, 6) :
- import multiprocessing
- def find_executable(executable, path=None):
- """Try to find 'executable' in the directories listed in 'path' (a
- string listing directories separated by 'os.pathsep'; defaults to
- os.environ['PATH']). Returns the complete filename or None if not
- found
- """
- if path is None:
- path = os.environ['PATH']
- paths = path.split(os.pathsep)
- extlist = ['']
- if os.name == 'os2':
- (base, ext) = os.path.splitext(executable)
-
-
- if not ext:
- executable = executable + ".exe"
- elif sys.platform == 'win32':
- pathext = os.environ['PATHEXT'].lower().split(os.pathsep)
- (base, ext) = os.path.splitext(executable)
- if ext.lower() not in pathext:
- extlist = pathext
- for ext in extlist:
- execname = executable + ext
- if os.path.isfile(execname):
- return execname
- else:
- for p in paths:
- f = os.path.join(p, execname)
- if os.path.isfile(f):
- return f
- else:
- return None
- def processorCount () :
- if sys.version_info >= (2, 6) :
- coreCount = multiprocessing.cpu_count ()
- else:
- coreCount = 1
- return coreCount
- def argumentIsString (argument) :
- if sys.version_info < (3,0):
- return isinstance (argument, types.StringTypes)
- else:
- return type (argument) is str
- def BLACK () :
- return '\033[90m'
- def RED () :
- return '\033[91m'
- def GREEN () :
- return '\033[92m'
- def YELLOW () :
- return '\033[93m'
- def BLUE () :
- return '\033[94m'
- def MAGENTA () :
- return '\033[95m'
- def CYAN () :
- return '\033[96m'
- def WHITE () :
- return '\033[97m'
- def ENDC () :
- return '\033[0m'
- def BOLD () :
- return '\033[1m'
- def UNDERLINE () :
- return '\033[4m'
- def BLINK () :
- return '\033[5m'
- def BOLD_BLUE () :
- return BOLD () + BLUE ()
- def BOLD_GREEN () :
- return BOLD () + GREEN ()
- def BOLD_RED () :
- return BOLD () + RED ()
- def runHiddenCommand (cmd, logUtilityTool=False) :
- executable = find_executable (cmd [0])
- if executable == None:
- print (BOLD_RED () + "*** Cannot find '" + cmd[0] + "' executable ***" + ENDC ())
- sys.exit (1)
- if logUtilityTool:
- print ("Utility tool is '" + executable + "'")
- result = ""
- childProcess = subprocess.Popen (cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
- while True:
- line = childProcess.stdout.readline ()
- if line != "":
- result += line
- else:
- childProcess.wait ()
- if childProcess.returncode != 0 :
- sys.exit (childProcess.returncode)
- return result
- def runCommand (cmd, title, showCommand, logUtilityTool) :
- if title != "":
- print (BOLD_BLUE () + title + ENDC ())
- if (title == "") or showCommand :
- cmdAsString = ""
- for s in cmd:
- if (s == "") or (s.find (" ") >= 0):
- cmdAsString += '"' + s + '" '
- else:
- cmdAsString += s + ' '
- print (cmdAsString)
- executable = find_executable (cmd [0])
- if executable == None:
- print (BOLD_RED () + "*** Cannot find '" + cmd[0] + "' executable ***" + ENDC ())
- sys.exit (1)
- if logUtilityTool:
- print ("Utility tool is '" + executable + "'")
- returncode = subprocess.call (cmd)
- if returncode != 0 :
- sys.exit (returncode)
- def runInThread (job, displayLock, terminationSemaphore):
- executable = find_executable (job.mCommand [0])
- if executable == None:
- print (BOLD_RED () + "*** Cannot find '" + job.mCommand[0] + "' executable ***" + ENDC ())
- job.mReturnCode = 1
- terminationSemaphore.release ()
- else:
- if job.mLogUtilityTool :
- print ("Utility tool is '" + executable + "'")
- childProcess = subprocess.Popen (job.mCommand, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
- while True:
- line = childProcess.stdout.readline ()
- if line != "":
- job.mOutputLines.append (line)
- displayLock.acquire ()
- sys.stdout.write (line)
- displayLock.release ()
- else:
- childProcess.wait ()
- job.mReturnCode = childProcess.returncode
- terminationSemaphore.release ()
- break
- def modificationDateForFile (dateCacheDictionary, file):
- absFilePath = os.path.abspath (file)
- if absFilePath in dateCacheDictionary :
- return dateCacheDictionary [absFilePath]
- elif not os.path.exists (absFilePath):
- date = sys.float_info.max
- dateCacheDictionary [absFilePath] = date
- return date
- else:
- date = os.path.getmtime (absFilePath)
- dateCacheDictionary [absFilePath] = date
- return date
- class PostCommand:
- mCommand = []
- mTitle = ""
-
- def __init__ (self, title = ""):
- self.mCommand = []
- self.mTitle = title
- class Job:
- mTargets = []
- mCommand = []
- mTitle = ""
- mRequiredFiles = []
- mPostCommands = []
- mReturnCode = None
- mPriority = 0
- mState = 0
- mOutputLines = []
- mOpenSourceOnError = False
- mLogUtilityTool = False
-
- def __init__ (self, targets, requiredFiles, command, postCommands, priority, title, openSourceOnError, logUtilityTool):
- self.mTargets = copy.deepcopy (targets)
- self.mCommand = copy.deepcopy (command)
- self.mRequiredFiles = copy.deepcopy (requiredFiles)
- self.mTitle = copy.deepcopy (title)
- self.mPostCommands = copy.deepcopy (postCommands)
- self.mPriority = priority
- self.mOutputLines = []
- self.mOpenSourceOnError = openSourceOnError
- self.mLogUtilityTool = logUtilityTool
-
- def run (self, displayLock, terminationSemaphore, showCommand, progressString):
- displayLock.acquire ()
- if self.mTitle != "":
- print (progressString + BOLD_BLUE () + self.mTitle + ENDC ())
- if (self.mTitle == "") or showCommand :
- cmdAsString = ""
- for s in self.mCommand:
- if (s == "") or (s.find (" ") >= 0):
- cmdAsString += '"' + s + '" '
- else:
- cmdAsString += s + ' '
- print (progressString + cmdAsString)
- displayLock.release ()
- thread = threading.Thread (target=runInThread, args=(self, displayLock, terminationSemaphore))
- thread.start()
-
- def runPostCommand (self, displayLock, terminationSemaphore, showCommand):
- postCommand = self.mPostCommands [0]
- self.mCommand = postCommand.mCommand
- displayLock.acquire ()
- print (BOLD_BLUE () + postCommand.mTitle + ENDC ())
- if showCommand:
- cmdAsString = ""
- for s in self.mCommand:
- if (s == "") or (s.find (" ") >= 0):
- cmdAsString += '"' + s + '" '
- else:
- cmdAsString += s + ' '
- print (cmdAsString)
- displayLock.release ()
- thread = threading.Thread (target=runInThread, args=(self, displayLock, terminationSemaphore))
- thread.start()
- class Rule:
- mTargets = []
- mDependences = []
- mCommand = []
- mSecondaryMostRecentModificationDate = 0.0
- mTitle = ""
- mPostCommands = []
- mPriority = 0
- mDeleteTargetOnError = False
- mCleanOperation = 0
- mOpenSourceOnError = False
-
- def __init__ (self, targets, title = ""):
-
- if not type (targets) is list:
- print (BOLD_RED () + "*** Rule type instanciation: first argument 'targets' is not a list ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- else:
- for aTarget in targets:
-
- if not argumentIsString (aTarget):
- print (BOLD_RED () + "*** Rule type instanciation: an element of first argument 'targets' is not a string ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- if not argumentIsString (title):
- print (BOLD_RED () + "*** Rule type instanciation: second argument 'title' is not a string ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- self.mTargets = copy.deepcopy (targets)
- self.mDependences = []
- self.mCommand = []
- self.mSecondaryMostRecentModificationDate = 0.0
- self.mPostCommands = []
- self.mPriority = 0
- self.mDeleteTargetOnError = False
- self.mOpenSourceOnError = False
- self.mCleanOperation = 0
- if title == "":
- self.mTitle = "Building"
- for s in targets:
- self.mTitle += " " + s
- else:
- self.mTitle = copy.deepcopy (title)
-
- def deleteTargetFileOnClean (self):
- self.mCleanOperation = 1
-
- def deleteTargetDirectoryOnClean (self):
- self.mCleanOperation = 2
-
- def enterSecondaryDependanceFile (self, secondaryDependanceFile, make):
- if not argumentIsString (secondaryDependanceFile):
- print (BOLD_RED () + "*** Rule.enterSecondaryDependanceFile: 'secondaryDependanceFile' argument is not a string ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- if make.mSelectedGoal != "clean":
- filePath = os.path.abspath (secondaryDependanceFile)
- if not os.path.exists (filePath):
- self.mSecondaryMostRecentModificationDate = sys.float_info.max
- else:
- f = open (filePath, "r")
- s = f.read ()
- f.close ()
- s = s.replace ("\\ ", "\x01")
- s = s.replace ("\\\n", "")
- liste = s.split ("\n\n")
-
- for s in liste:
-
- components = s.split (':')
-
-
-
-
- if len (components) > 1 :
- for src in components [1].split ():
- secondarySource = src.replace ("\x01", " ")
-
- modifDate = modificationDateForFile (make.mModificationDateDictionary, secondarySource)
- if self.mSecondaryMostRecentModificationDate < modifDate :
- self.mSecondaryMostRecentModificationDate = modifDate
-
- class Make:
- mRuleList = []
- mJobList = []
- mErrorCount = 0
- mModificationDateDictionary = {}
- mGoals = {}
- mSelectedGoal = ""
- mLinuxTextEditor = ""
- mMacTextEditor = ""
- mSimulateClean = False
- mLogUtilityTool = True
- mShowProgressString = True
-
- def __init__ (self, goal, logUtilityTool=False):
- if not argumentIsString (goal):
- print (BOLD_RED () + "*** Make instanciation: 'goal' argument is not a string ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- self.mRuleList = []
- self.mJobList = []
- self.mErrorCount = 0
- self.mModificationDateDictionary = {}
- self.mGoals = {}
- self.mSelectedGoal = goal
- self.mLinuxTextEditor = "gEdit"
- self.mMacTextEditor = "TextEdit"
- self.mLogUtilityTool = logUtilityTool
-
- def doNotShowProgressString (self) :
- self.mShowProgressString = False
-
- def addRule (self, rule):
- if not isinstance (rule, Rule):
- print (BOLD_RED () + "*** Make.addRule: 'rule' argument is not an instance of Rule type ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- self.mRuleList.append (copy.deepcopy (rule))
-
- def printRules (self):
- print (BOLD_BLUE () + "--- Print " + str (len (self.mRuleList)) + " rule" + ("s" if len (self.mRuleList) > 1 else "") + " ---" + ENDC ())
- for rule in self.mRuleList:
- message = ""
- for s in rule.mTargets:
- message += " \"" + s + "\""
- print (BOLD_GREEN () + "Target:" + message + ENDC ())
- for dep in rule.mDependences:
- print (" Dependence: \"" + dep + "\"")
- s = " Command: "
- for cmd in rule.mCommand:
- s += " \"" + cmd + "\""
- print (s)
- print (" Title: \"" + rule.mTitle + "\"")
- print (" Delete target on error: " + ("yes" if rule.mDeleteTargetOnError else "no"))
- cleanOp = "none"
- if rule.mCleanOperation == 1:
- cleanOp = "delete target file(s)"
- elif rule.mCleanOperation == 2:
- dirSet = set ()
- for s in rule.mTargets:
- path = os.path.dirname (s)
- if path != "":
- dirSet.add (path)
- cleanOp = "delete target directory:"
- for s in dirSet:
- cleanOp += " \"" + s + "\""
- print (" Clean operation: " + cleanOp)
- index = 0
- for postCommand in rule.mPostCommands:
- index = index + 1
- s = " Post command " + str (index) + ": "
- for cmd in postCommand.mCommand:
- s += " \"" + cmd + "\""
- print (s)
- print (" Title: \"" + postCommand.mTitle + "\"")
- print (BOLD_BLUE () + "--- End of print rule ---" + ENDC ())
-
- def writeRuleDependancesInDotFile (self, dotFileName):
- s = "digraph G {\n"
- s += " node [fontname=courier]\n"
- arrowSet = set ()
- for rule in self.mRuleList:
- for target in rule.mTargets:
- s += ' "' + target + '" [shape=rectangle]\n'
- for dep in rule.mDependences:
- arrowSet.add (' "' + target + '" -> "' + dep + '"\n')
- for arrow in arrowSet:
- s += arrow
- s += "}\n"
- f = open (dotFileName, "w")
- f.write (s)
- f.close ()
-
- def checkRules (self):
- if self.mErrorCount == 0:
- ruleList = copy.deepcopy (self.mRuleList)
- index = 0
- looping = True
-
- while looping:
- looping = False
- while index < len (ruleList):
- aRule = ruleList [index]
- index = index + 1
-
- depIdx = 0
- while depIdx < len (aRule.mDependences):
- dep = aRule.mDependences [depIdx]
- depIdx = depIdx + 1
- hasBuildRule = False
- for r in ruleList:
- for target in r.mTargets:
- if dep == target:
- hasBuildRule = True
- break
- if not hasBuildRule:
- looping = True
- if not os.path.exists (os.path.abspath (dep)):
- self.mErrorCount = self.mErrorCount + 1
- print (BOLD_RED () + "Check rules error: '" + dep + "' does not exist, and there is no rule for building it." + ENDC ())
- depIdx = depIdx - 1
- aRule.mDependences.pop (depIdx)
-
- if len (aRule.mDependences) == 0 :
- looping = True
- index = index - 1
- ruleList.pop (index)
- idx = 0
- while idx < len (ruleList):
- r = ruleList [idx]
- idx = idx + 1
- for target in aRule.mTargets:
- while r.mDependences.count (target) > 0 :
- r.mDependences.remove (target)
-
- if len (ruleList) > 0:
- self.mErrorCount = self.mErrorCount + 1
- print (BOLD_RED () + "Check rules error; circulary dependances between:" + ENDC ())
- for aRule in ruleList:
- targetList = ""
- for target in aRule.mTargets:
- targetList += " '" + aRule.mTarget + "'"
- print (BOLD_RED () + " - " + targetList + ", depends from:" + ENDC ())
- for dep in aRule.mDependences:
- print (BOLD_RED () + " '" + dep + "'" + ENDC ())
-
- def existsJobForTarget (self, target):
- for job in self.mJobList:
- for aTarget in job.mTargets:
- if aTarget == target:
- return True
- return False
-
- def makeJob (self, target):
-
- if self.mErrorCount != 0:
- return False
-
- if self.existsJobForTarget (target):
- return True
-
- absTarget = os.path.abspath (target)
- rule = None
- matchCount = 0
- for r in self.mRuleList:
- for aTarget in r.mTargets:
- if target == aTarget:
- matchCount = matchCount + 1
- rule = r
- if matchCount == 0:
- absTarget = os.path.abspath (target)
- if not os.path.exists (absTarget):
- print (BOLD_RED () + "No rule for making '" + target + "'" + ENDC ())
- self.mErrorCount = self.mErrorCount + 1
- return False
- elif matchCount > 1:
- print (BOLD_RED () + str (matchCount) + " rules for making '" + target + "'" + ENDC ())
- self.mErrorCount = self.mErrorCount + 1
- return False
-
- appendToJobList = not os.path.exists (absTarget)
-
- jobDependenceFiles = []
- for dependence in rule.mDependences:
- willBeBuilt = self.makeJob (dependence)
- if willBeBuilt:
- jobDependenceFiles.append (dependence)
- appendToJobList = True
-
- if not appendToJobList:
- targetDateModification = os.path.getmtime (absTarget)
- for source in rule.mDependences:
- sourceDateModification = os.path.getmtime (source)
- if targetDateModification < sourceDateModification:
- appendToJobList = True
- break
-
- if not appendToJobList:
- targetDateModification = os.path.getmtime (absTarget)
- if targetDateModification < rule.mSecondaryMostRecentModificationDate:
- appendToJobList = True
-
- if appendToJobList:
- self.mJobList.append (Job (
- rule.mTargets,
- jobDependenceFiles,
- rule.mCommand,
- rule.mPostCommands,
- rule.mPriority,
- rule.mTitle,
- rule.mOpenSourceOnError,
- self.mLogUtilityTool
- ))
-
- return appendToJobList
-
-
-
-
-
-
-
- def runJobs (self, maxConcurrentJobs, showCommand):
- if self.mErrorCount == 0:
- if len (self.mJobList) == 0:
- print (BOLD_BLUE () + "Nothing to make." + ENDC ())
- else:
-
- self.mJobList = sorted (self.mJobList, key=operator.attrgetter("mPriority"), reverse=True)
-
- if maxConcurrentJobs <= 0:
- maxConcurrentJobs = processorCount () - maxConcurrentJobs
- jobCount = 0 ;
- terminationSemaphore = threading.Semaphore (0)
- displayLock = threading.Lock ()
- loop = True
- returnCode = 0
- totalJobCount = float (len (self.mJobList))
- launchedJobCount = 0.0
- while loop:
-
- for job in self.mJobList:
- if (returnCode == 0) and (jobCount < maxConcurrentJobs):
- if (job.mState == 0) and (len (job.mRequiredFiles) == 0):
-
- for aTarget in job.mTargets:
- absTargetDirectory = os.path.dirname (os.path.abspath (aTarget))
- if not os.path.exists (absTargetDirectory):
- displayLock.acquire ()
- runCommand (
- ["mkdir", "-p", os.path.dirname (aTarget)], "Making \"" + os.path.dirname (aTarget) + "\" directory",
- showCommand,
- job.mLogUtilityTool
- )
- displayLock.release ()
-
- launchedJobCount += 1.0
- if self.mShowProgressString:
- progressString = "[{0:3d}%] ".format (int (100.0 * launchedJobCount / totalJobCount))
- else:
- progressString = ""
-
- job.run (displayLock, terminationSemaphore, showCommand, progressString)
- jobCount = jobCount + 1
- job.mState = 1
- elif job.mState == 2:
- job.mReturnCode = None
- job.runPostCommand (displayLock, terminationSemaphore, showCommand)
- jobCount = jobCount + 1
- job.mState = 3
-
-
- terminationSemaphore.acquire ()
-
- index = 0
- while index < len (self.mJobList):
- job = self.mJobList [index]
- index = index + 1
- if (job.mState == 1) and (job.mReturnCode != None) and (job.mReturnCode == 0) :
- jobCount = jobCount - 1
- for aTarget in job.mTargets:
- if not os.path.exists (os.path.abspath (aTarget)):
- displayLock.acquire ()
- print (MAGENTA () + BOLD () + "Warning: target \"" + aTarget + "\" was not created by rule execution." + ENDC ())
- displayLock.release ()
- if len (job.mPostCommands) > 0:
- job.mState = 2
- else:
- job.mState = 4
- index = index - 1
- elif (job.mState == 1) and (job.mReturnCode != None) and (job.mReturnCode > 0) :
- jobCount = jobCount - 1
- job.mState = 4
- index = index - 1
- if job.mOpenSourceOnError:
- for line in job.mOutputLines:
- components = line.split (':')
- if (len (components) > 1) and os.path.exists (os.path.abspath (components [0])) :
- if sys.platform == "darwin":
- os.system ("open -a \"" + self.mMacTextEditor + "\" \"" + components [0] + "\"")
- elif sys.platform == "linux2":
- os.system ("\"" + self.mLinuxTextEditor + "\" \"" + components [0] + "\"")
- elif (job.mState == 3) and (job.mReturnCode == 0):
- jobCount = jobCount - 1
- job.mPostCommands.pop (0)
- if len (job.mPostCommands) > 0:
- job.mState = 2
- else:
- job.mState = 4
- index = index - 1
- elif (job.mState == 3) and (job.mReturnCode > 0):
- jobCount = jobCount - 1
- job.mState = 4
- index = index - 1
- elif job.mState == 4:
- index = index - 1
- self.mJobList.pop (index)
-
-
-
- idx = 0
- while idx < len (self.mJobList):
- aJob = self.mJobList [idx]
- idx = idx + 1
- for aTarget in job.mTargets:
- while aJob.mRequiredFiles.count (aTarget) > 0 :
- aJob.mRequiredFiles.remove (aTarget)
-
-
-
- if (job.mReturnCode > 0) and (returnCode == 0):
- self.mErrorCount = self.mErrorCount + 1
- print (BOLD_RED () + "Return code: " + str (job.mReturnCode) + ENDC ())
- if (returnCode == 0) and (jobCount > 0) :
- print ("Wait for job termination...")
- returnCode = job.mReturnCode
- loop = (len (self.mJobList) > 0) if (returnCode == 0) else (jobCount > 0)
-
- def searchFileInRelativeDirectories (self, file, directoryList):
- matchCount = 0
- result = ""
- for sourceDir in directoryList:
- sourcePath = sourceDir + "/" + file
- if os.path.exists (os.path.abspath (sourcePath)):
- matchCount = matchCount + 1
- prefix = os.path.commonprefix ([os.getcwd (), sourcePath])
- result = sourcePath [len (prefix):]
- if result [0] == '/' :
- result = result [1:]
- if matchCount == 0:
- print (BOLD_RED () + "Cannot find '" + file + "'" + ENDC ())
- self.mErrorCount = self.mErrorCount + 1
- elif matchCount > 1:
- print (BOLD_RED () + str (matchCount) + " source files for making '" + file + "'" + ENDC ())
- self.mErrorCount = self.mErrorCount + 1
- result = ""
- return result
-
- def searchFileInDirectories (self, file, directoryList):
- matchCount = 0
- result = ""
- for sourceDir in directoryList:
- sourcePath = sourceDir + "/" + file
- if os.path.exists (os.path.abspath (sourcePath)):
- matchCount = matchCount + 1
- result = sourcePath
- if matchCount == 0:
- print (BOLD_RED () + "Cannot find '" + file + "'" + ENDC ())
- self.mErrorCount = self.mErrorCount + 1
- elif matchCount > 1:
- print (BOLD_RED () + str (matchCount) + " source files for making '" + file + "'" + ENDC ())
- self.mErrorCount = self.mErrorCount + 1
- result = ""
- return result
-
- def addGoal (self, goal, targetList, message):
- if not argumentIsString (goal):
- print (BOLD_RED () + "*** Make.addGoal: 'goal' first argument is not a string ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- if not type (targetList) is list:
- print (BOLD_RED () + "*** Make.addGoal: 'targetList' second argument is not a list ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- else:
- for aTarget in targetList:
- if not argumentIsString (aTarget):
- print (BOLD_RED () + "*** Make.addGoal: an element of 'targetList' second argument 'targets' is not a string ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- if not argumentIsString (message):
- print (BOLD_RED () + "*** Make.addGoal: 'message' third argument is not a string ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- if (goal in self.mGoals) or (goal == "clean") :
- self.enterError ("The '" + goal + "' goal is already defined")
- else:
- self.mGoals [goal] = (targetList, message)
-
-
- def printGoals (self):
- print (BOLD_BLUE () + "--- Print " + str (len (self.mGoals)) + " goal" + ("s" if len (self.mGoals) > 1 else "") + " ---" + ENDC ())
- for goalKey in self.mGoals.keys ():
- print (BOLD_GREEN () + "Goal: \"" + goalKey + "\"" + ENDC ())
- (targetList, message) = self.mGoals [goalKey]
- for target in targetList:
- print (" Target: \"" + target + "\"")
- print (" Message: \"" + message + "\"")
- print (BOLD_BLUE () + "--- End of print goals ---" + ENDC ())
-
- def runGoal (self, maxConcurrentJobs, showCommand):
- if not isinstance (maxConcurrentJobs, int):
- print (BOLD_RED () + "*** Make.runGoal: 'maxConcurrentJobs' first argument is not an integer ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- if not isinstance (showCommand, bool):
- print (BOLD_RED () + "*** Make.runGoal: 'showCommand' second argument is not a boolean ***" + ENDC ())
- traceback.print_stack ()
- sys.exit (1)
- if self.mSelectedGoal in self.mGoals :
- (targetList, message) = self.mGoals [self.mSelectedGoal]
- for target in targetList:
- self.makeJob (target)
- self.runJobs (maxConcurrentJobs, showCommand)
- if self.mErrorCount > 0:
- for rule in self.mRuleList:
- for aTarget in rule.mTargets:
- if rule.mDeleteTargetOnError and os.path.exists (os.path.abspath (aTarget)):
- runCommand (["rm", aTarget], "Delete \"" + aTarget + "\" on error", showCommand, self.mLogUtilityTool)
- elif self.mSelectedGoal == "clean" :
- filesToRemoveList = []
- directoriesToRemoveSet = set ()
- for rule in self.mRuleList:
- if rule.mCleanOperation == 1:
- for aTarget in rule.mTargets:
- filesToRemoveList.append (aTarget)
- elif rule.mCleanOperation == 2:
- for aTarget in rule.mTargets:
- dirPath = os.path.dirname (aTarget)
- if dirPath == "":
- filesToRemoveList.append (aTarget)
- else:
- directoriesToRemoveSet.add (dirPath)
- for dir in directoriesToRemoveSet:
- if os.path.exists (os.path.abspath (dir)):
- if self.mSimulateClean:
- print (MAGENTA () + BOLD () + "Simulated clean command: " + ENDC () + "rm -fr '" + dir + "'")
- else:
- runCommand (["rm", "-fr", dir], "Removing \"" + dir + "\"", showCommand, self.mLogUtilityTool)
- for file in filesToRemoveList:
- if os.path.exists (os.path.abspath (file)):
- if self.mSimulateClean:
- print (MAGENTA () + BOLD () + "Simulated clean command: " + ENDC () + "rm -f '" + file + "'")
- else:
- runCommand (["rm", "-f", file], "Deleting \"" + file + "\"", showCommand, self.mLogUtilityTool)
- else:
- errorMessage = "The '" + self.mSelectedGoal + "' goal is not defined; defined goals:"
- for key in self.mGoals:
- (targetList, message) = self.mGoals [key]
- errorMessage += "\n '" + key + "': " + message
- print (BOLD_RED () + errorMessage + ENDC ())
- self.mErrorCount = self.mErrorCount + 1
-
- def simulateClean (self):
- self.mSimulateClean = True
-
- def enterError (self, message):
- print (BOLD_RED () + message + ENDC ())
- self.mErrorCount = self.mErrorCount + 1
-
- def printErrorCountAndExitOnError (self):
- if self.mErrorCount == 1:
- print (BOLD_RED () + "1 error." + ENDC ())
- sys.exit (1)
- elif self.mErrorCount > 1:
- print (BOLD_RED () + str (self.mErrorCount) + " errors." + ENDC ())
- sys.exit (1)
-
- def printErrorCount (self):
- if self.mErrorCount == 1:
- print (BOLD_RED () + "1 error." + ENDC ())
- elif self.mErrorCount > 1:
- print (BOLD_RED () + str (self.mErrorCount) + " errors." + ENDC ())
-
- def errorCount (self):
- return self.mErrorCount
|