diff --git a/bin/Source/GitSource.py b/bin/Source/GitSource.py index 23a380f08..956dbc85b 100644 --- a/bin/Source/GitSource.py +++ b/bin/Source/GitSource.py @@ -1,284 +1,273 @@ -# -# copyright (c) 2009 Ralf Habacker -# copyright (c) 2009 Patrick Spendrin -# -# git support - -from Source.VersionSystemSourceBase import * -import tempfile - -## \todo requires installed git package -> add suport for installing packages - -class GitSource ( VersionSystemSourceBase ): - """git support""" - def __init__(self, subinfo=None): - utils.trace( 'GitSource __init__', 2 ) - if subinfo: - self.subinfo = subinfo - VersionSystemSourceBase.__init__( self ) - - # detect git installation - gitInstallDir = os.path.join( self.rootdir, 'dev-utils', 'git' ) - if os.path.exists( gitInstallDir ): - self.gitPath = os.path.join(gitInstallDir, 'bin', 'git') - utils.debug( 'using git from %s' % gitInstallDir, 1 ) - else: - self.gitPath = 'git' - - def __getCurrentBranch( self ): - branch = None - if os.path.exists( self.checkoutDir() ): - tmpFile = tempfile.TemporaryFile() - self.__git("branch -a", stdout=tmpFile ) - # TODO: check return value for success - tmpFile.seek( 0 ) - for line in tmpFile: - line = str(line,"UTF-8") - if line.startswith("*"): - branch = line[2:].rstrip() - break - return branch - - def __isLocalBranch( self, branch ): - if os.path.exists( self.checkoutDir() ): - tmpFile = tempfile.TemporaryFile() - self.__git("branch", stdout=tmpFile ) - # TODO: check return value for success - tmpFile.seek( 0 ) - for line in tmpFile: - if str(line[2:].rstrip(), "UTF-8") == branch: - return True - return False - - def __isTag( self, _tag ): - if os.path.exists( self.checkoutDir() ): - tmpFile = tempfile.TemporaryFile() - self.__git("tag", stdout=tmpFile ) - # TODO: check return value for success - tmpFile.seek( 0 ) - for line in tmpFile: - if str(line.rstrip(), "UTF-8") == _tag: - return True - return False - - def __getCurrentRevision( self ): - """return the revision returned by git show""" - - # run the command - branch = self.__getCurrentBranch() - if not self.__isTag( branch ): - # open a temporary file - do not use generic tmpfile because this doesn't give a good file object with python - with tempfile.TemporaryFile() as tmpFile: - self.__git("show", "--abbrev-commit", stdout=tmpFile ) - tmpFile.seek( os.SEEK_SET ) - # read the temporary file and grab the first line - # print the revision - everything else should be quiet now - line = tmpFile.readline() - return str(line, "UTF-8").replace("commit ", "").strip() - else: - # in case this is a tag, print out the tag version - return branch - - def __fetchSingleBranch( self, repopath = None ): - utils.trace( 'GitSource __fetchSingleBranch', 2 ) - # get the path where the repositories should be stored to - if repopath == None: - repopath = self.repositoryUrl() - - # in case you need to move from a read only Url to a writeable one, here it gets replaced - repopath = repopath.replace( "[git]", "" ) - repoString = utils.replaceVCSUrl( repopath ) - [ repoUrl, repoBranch, repoTag ] = utils.splitVCSUrl( repoString ) - if not repoBranch and not repoTag: - repoBranch = "master" - - ret = True - # only run if wanted (e.g. no --offline is given on the commandline) - if ( not self.noFetch ): - self.setProxy() - safePath = os.environ[ "PATH" ] - # add the git path to the PATH variable so that git can be called without path - os.environ[ "PATH" ] = os.path.join( self.rootdir, "git", "bin" ) + ";" + safePath - checkoutDir = self.checkoutDir() - # if we only have the checkoutdir but no .git within, - # clean this up first - if os.path.exists(checkoutDir) \ - and not os.path.exists(checkoutDir + "\.git"): - os.rmdir(checkoutDir) - if os.path.exists(checkoutDir): - if not repoTag: - ret = self.__git("pull", "origin", repoBranch or "master" ) - if self.subinfo.options.fetch.checkoutSubmodules: - self.__git("submodule update --init --recursive") - else: - # it doesn't exist so clone the repo - os.makedirs( checkoutDir ) - # first try to replace with a repo url from etc/portage/emergehosts.conf - recursive = '--recursive' if self.subinfo.options.fetch.checkoutSubmodules else '' - ret = self.__git('clone', recursive, repoUrl, '.') - - # if a branch is given, we should check first if the branch is already downloaded - # locally, otherwise we can track the remote branch - if ret and repoBranch and not repoTag: - track = "" - if not self.__isLocalBranch( repoBranch ): - track = "--track origin/" - ret = self.__git('checkout', "%s%s" % (track, repoBranch )) - - # we can have tags or revisions in repoTag - if ret and repoTag: - if self.__isTag( repoTag ): - if not self.__isLocalBranch( "_" + repoTag ): - ret = self.__git('checkout', '-b', '_%s' % repoTag, repoTag) - else: - ret = self.__git('checkout', '_%s' % repoTag) - else: - ret = self.__git('checkout', repoTag) - - else: - utils.debug( "skipping git fetch (--offline)" ) - return ret - - def __git(self, command, *args, **kwargs): - """executes a git command in a shell. - Default for cwd is self.checkoutDir()""" - if command in ('clone', 'checkout', 'fetch', 'pull', 'submodule') and os.getenv("EMERGE_LOG_DIR"): - # if stdout/stderr is redirected, git clone qt hangs forever. - # It does not with option -q (suppressing progress info) - command += ' -q' - parts = [self.gitPath, command] - parts.extend(args) - if not kwargs.get('cwd'): - kwargs['cwd'] = self.checkoutDir() - return utils.system(' '.join(parts), **kwargs) - - def __fetchMultipleBranch(self, repopath=None): - utils.trace( 'GitSource __fetchMultipleBranch', 2 ) - # get the path where the repositories should be stored to - if repopath == None: - repopath = self.repositoryUrl() - - # in case you need to move from a read only Url to a writeable one, here it gets replaced - repopath = repopath.replace("[git]", "") - repoString = utils.replaceVCSUrl( repopath ) - [repoUrl, repoBranch, repoTag ] = utils.splitVCSUrl( repoString ) - - ret = True - # only run if wanted (e.g. no --offline is given on the commandline) - if ( not self.noFetch ): - self.setProxy() - safePath = os.environ["PATH"] - # add the git path to the PATH variable so that git can be called without path - os.environ["PATH"] = os.path.join( self.rootdir, "git", "bin" ) + ";" + safePath - rootCheckoutDir = os.path.join(self.checkoutDir(), '.git') - if not os.path.exists( rootCheckoutDir ): - # it doesn't exist so clone the repo - os.makedirs( rootCheckoutDir ) - ret = self.__git('clone', '--mirror', repoUrl, '.', cwd=rootCheckoutDir) - else: - ret = self.__git('fetch', cwd=rootCheckoutDir) - if not ret: - utils.die( "could not fetch remote data" ) - - if repoBranch == "": - repoBranch = "master" - if ret: - branchDir = os.path.join(self.checkoutDir(), repoBranch) - if not os.path.exists(branchDir): - os.makedirs(branchDir) - ret = self.__git('clone', '--local --shared -b', repoBranch, rootCheckoutDir, branchDir, cwd=branchDir) - else: - ret = self.__git('pull') - if not ret: - utils.die( "could not pull into branch %s" % repoBranch ) - - if ret: - #ret = self.__git('checkout', '-f') - ret = self.__git("checkout", "-f", repoTag or repoBranch, cwd=branchDir) - else: - utils.debug( "skipping git fetch (--offline)" ) - return ret - - - def fetch(self, repopath=None): - utils.trace( 'GitSource fetch', 2 ) - if utils.envAsBool("EMERGE_GIT_MULTIBRANCH"): - return self.__fetchMultipleBranch(repopath) - else: - return self.__fetchSingleBranch(repopath) - - def applyPatch(self, fileName, patchdepth, unusedSrcDir=None): - """apply single patch o git repository""" - utils.trace( 'GitSource ', 2 ) - if fileName: - patchfile = os.path.join ( self.packageDir(), fileName ) - if utils.envAsBool("EMERGE_GIT_MULTIBRANCH"): - repopath = self.repositoryUrl() - # in case you need to move from a read only Url to a writeable one, here it gets replaced - repopath = repopath.replace("[git]", "") - repoString = utils.replaceVCSUrl( repopath ) - repoBranch = utils.splitVCSUrl( repoString )[1] or "master" - sourceDir = os.path.join(self.checkoutDir(), repoBranch) - else: - sourceDir = self.sourceDir() - #FIXME this reverts previously applied patches ! - #self.__git('checkout', '-f',cwd=sourceDir) - sourceDir = self.checkoutDir() - return self.__git('apply', '--whitespace=fix', - '-p %d' % patchdepth, patchfile, cwd=sourceDir) - return True - - def createPatch( self ): - """create patch file from git source into the related package dir. - The patch file is named autocreated.patch""" - utils.trace( 'GitSource createPatch', 2 ) - patchFileName = os.path.join( self.packageDir(), "%s-%s.patch" % \ - ( self.package, str( datetime.date.today() ).replace('-', '') ) ) - with open(patchFileName,'w') as patchFile: - return self.__git('diff', stdout=patchFile) - - def sourceVersion( self ): - """print the revision returned by git show""" - utils.trace( 'GitSource sourceVersion', 2 ) - - print(self.__getCurrentRevision()) - return True - - def checkoutDir(self, index=0 ): - utils.trace( 'GitSource checkoutDir', 2 ) - return VersionSystemSourceBase.checkoutDir( self, index ) - - def sourceDir(self, index=0 ): - utils.trace( 'GitSource sourceDir', 2 ) - repopath = self.repositoryUrl() - # in case you need to move from a read only Url to a writeable one, here it gets replaced - repopath = repopath.replace("[git]", "") - repoString = utils.replaceVCSUrl( repopath ) - _, repoBranch, _ = utils.splitVCSUrl( repoString ) - if repoBranch == "": - repoBranch = "master" - if utils.envAsBool("EMERGE_GIT_MULTIBRANCH"): - sourcedir = os.path.join(self.checkoutDir(index), repoBranch) - else: - sourcedir = self.checkoutDir(index) - - if self.subinfo.hasTargetSourcePath(): - sourcedir = os.path.join(sourcedir, self.subinfo.targetSourcePath()) - - utils.debug("using sourcedir: %s" % sourcedir, 2) - return sourcedir - - def getUrls( self ): - """print the url where to clone from and the branch/tag/hash""" - # in case you need to move from a read only Url to a writeable one, here it gets replaced - repopath = self.repositoryUrl().replace( "[git]", "" ) - repoString = utils.replaceVCSUrl( repopath ) - [ repoUrl, repoBranch, repoTag ] = utils.splitVCSUrl( repoString ) - if not repoBranch and not repoTag: - repoBranch = "master" - print('|'.join([repoUrl, repoBranch, repoTag])) - return True - - def currentRevision(self): - """return the name or number of the current revision""" - return self.__getCurrentRevision() +# +# copyright (c) 2009 Ralf Habacker +# copyright (c) 2009 Patrick Spendrin +# +# git support + +from Source.VersionSystemSourceBase import * +import tempfile + +## \todo requires installed git package -> add suport for installing packages + +class GitSource ( VersionSystemSourceBase ): + """git support""" + def __init__(self, subinfo=None): + utils.trace( 'GitSource __init__', 2 ) + if subinfo: + self.subinfo = subinfo + VersionSystemSourceBase.__init__( self ) + + # detect git installation + gitInstallDir = os.path.join( self.rootdir, 'dev-utils', 'git' ) + if os.path.exists( gitInstallDir ): + self.gitPath = os.path.join(gitInstallDir, 'bin', 'git') + utils.debug( 'using git from %s' % gitInstallDir, 1 ) + else: + self.gitPath = 'git' + + def __getCurrentBranch( self ): + branch = None + if os.path.exists( self.checkoutDir() ): + tmpFile = tempfile.TemporaryFile() + self.__git("branch -a", stdout=tmpFile ) + # TODO: check return value for success + tmpFile.seek( 0 ) + for line in tmpFile: + line = str(line,"UTF-8") + if line.startswith("*"): + branch = line[2:].rstrip() + break + return branch + + def __isLocalBranch( self, branch ): + if os.path.exists( self.checkoutDir() ): + tmpFile = tempfile.TemporaryFile() + self.__git("branch", stdout=tmpFile ) + # TODO: check return value for success + tmpFile.seek( 0 ) + for line in tmpFile: + if str(line[2:].rstrip(), "UTF-8") == branch: + return True + return False + + def __isTag( self, _tag ): + if os.path.exists( self.checkoutDir() ): + tmpFile = tempfile.TemporaryFile() + self.__git("tag", stdout=tmpFile ) + # TODO: check return value for success + tmpFile.seek( 0 ) + for line in tmpFile: + if str(line.rstrip(), "UTF-8") == _tag: + return True + return False + + def __getCurrentRevision( self ): + """return the revision returned by git show""" + + # run the command + branch = self.__getCurrentBranch() + if not self.__isTag( branch ): + # open a temporary file - do not use generic tmpfile because this doesn't give a good file object with python + with tempfile.TemporaryFile() as tmpFile: + self.__git("show", "--abbrev-commit", stdout=tmpFile ) + tmpFile.seek( os.SEEK_SET ) + # read the temporary file and grab the first line + # print the revision - everything else should be quiet now + line = tmpFile.readline() + return str(line, "UTF-8").replace("commit ", "").strip() + else: + # in case this is a tag, print out the tag version + return branch + + def __fetchSingleBranch( self, repopath = None ): + utils.trace( 'GitSource __fetchSingleBranch', 2 ) + # get the path where the repositories should be stored to + if repopath == None: + repopath = self.repositoryUrl() + + # in case you need to move from a read only Url to a writeable one, here it gets replaced + repopath = repopath.replace( "[git]", "" ) + repoString = utils.replaceVCSUrl( repopath ) + [ repoUrl, repoBranch, repoTag ] = utils.splitVCSUrl( repoString ) + if not repoBranch and not repoTag: + repoBranch = "master" + + ret = True + # only run if wanted (e.g. no --offline is given on the commandline) + if ( not self.noFetch ): + self.setProxy() + safePath = os.environ[ "PATH" ] + # add the git path to the PATH variable so that git can be called without path + os.environ[ "PATH" ] = os.path.join( self.rootdir, "git", "bin" ) + ";" + safePath + checkoutDir = self.checkoutDir() + # if we only have the checkoutdir but no .git within, + # clean this up first + if os.path.exists(checkoutDir) \ + and not os.path.exists(checkoutDir + "\.git"): + os.rmdir(checkoutDir) + if os.path.exists(checkoutDir): + if not repoTag: + ret = self.__git("pull", "origin", repoBranch or "master" ) + if self.subinfo.options.fetch.checkoutSubmodules: + self.__git("submodule update --init --recursive") + else: + # it doesn't exist so clone the repo + os.makedirs( checkoutDir ) + # first try to replace with a repo url from etc/portage/emergehosts.conf + recursive = '--recursive' if self.subinfo.options.fetch.checkoutSubmodules else '' + ret = self.__git('clone', recursive, repoUrl, '.') + + # if a branch is given, we should check first if the branch is already downloaded + # locally, otherwise we can track the remote branch + if ret and repoBranch and not repoTag: + track = "" + if not self.__isLocalBranch( repoBranch ): + track = "--track origin/" + ret = self.__git('checkout', "%s%s" % (track, repoBranch )) + + # we can have tags or revisions in repoTag + if ret and repoTag: + if self.__isTag( repoTag ): + if not self.__isLocalBranch( "_" + repoTag ): + ret = self.__git('checkout', '-b', '_%s' % repoTag, repoTag) + else: + ret = self.__git('checkout', '_%s' % repoTag) + else: + ret = self.__git('checkout', repoTag) + + else: + utils.debug( "skipping git fetch (--offline)" ) + return ret + + def __git(self, command, *args, **kwargs): + """executes a git command in a shell. + Default for cwd is self.checkoutDir()""" + if command in ('clone', 'checkout', 'fetch', 'pull', 'submodule') and os.getenv("EMERGE_LOG_DIR"): + # if stdout/stderr is redirected, git clone qt hangs forever. + # It does not with option -q (suppressing progress info) + command += ' -q' + parts = [self.gitPath, command] + parts.extend(args) + if not kwargs.get('cwd'): + kwargs['cwd'] = self.checkoutDir() + return utils.system(' '.join(parts), **kwargs) + + def __fetchMultipleBranch(self, repopath=None): + utils.trace( 'GitSource __fetchMultipleBranch', 2 ) + # get the path where the repositories should be stored to + if repopath == None: + repopath = self.repositoryUrl() + + # in case you need to move from a read only Url to a writeable one, here it gets replaced + repopath = repopath.replace("[git]", "") + repoString = utils.replaceVCSUrl( repopath ) + [repoUrl, repoBranch, repoTag ] = utils.splitVCSUrl( repoString ) + + ret = True + # only run if wanted (e.g. no --offline is given on the commandline) + if ( not self.noFetch ): + self.setProxy() + safePath = os.environ["PATH"] + # add the git path to the PATH variable so that git can be called without path + os.environ["PATH"] = os.path.join( self.rootdir, "git", "bin" ) + ";" + safePath + rootCheckoutDir = os.path.join(self.checkoutDir(), '.git') + if not os.path.exists( rootCheckoutDir ): + # it doesn't exist so clone the repo + os.makedirs( rootCheckoutDir ) + ret = self.__git('clone', '--mirror', repoUrl, '.', cwd=rootCheckoutDir) + else: + ret = self.__git('fetch', cwd=rootCheckoutDir) + if not ret: + utils.die( "could not fetch remote data" ) + + if repoBranch == "": + repoBranch = "master" + if ret: + branchDir = os.path.join(self.checkoutDir(), repoBranch) + if not os.path.exists(branchDir): + os.makedirs(branchDir) + ret = self.__git('clone', '--local --shared -b', repoBranch, rootCheckoutDir, branchDir, cwd=branchDir) + else: + ret = self.__git('pull') + if not ret: + utils.die( "could not pull into branch %s" % repoBranch ) + + if ret: + #ret = self.__git('checkout', '-f') + ret = self.__git("checkout", "-f", repoTag or repoBranch, cwd=branchDir) + else: + utils.debug( "skipping git fetch (--offline)" ) + return ret + + + def fetch(self, repopath=None): + utils.trace( 'GitSource fetch', 2 ) + if utils.envAsBool("EMERGE_GIT_MULTIBRANCH"): + return self.__fetchMultipleBranch(repopath) + else: + return self.__fetchSingleBranch(repopath) + + def applyPatch(self, fileName, patchdepth, unusedSrcDir=None): + """apply single patch o git repository""" + utils.trace( 'GitSource ', 2 ) + if fileName: + patchfile = os.path.join ( self.packageDir(), fileName ) + if utils.envAsBool("EMERGE_GIT_MULTIBRANCH"): + repopath = self.repositoryUrl() + # in case you need to move from a read only Url to a writeable one, here it gets replaced + repopath = repopath.replace("[git]", "") + repoString = utils.replaceVCSUrl( repopath ) + repoBranch = utils.splitVCSUrl( repoString )[1] or "master" + sourceDir = os.path.join(self.checkoutDir(), repoBranch) + else: + sourceDir = self.sourceDir() + #FIXME this reverts previously applied patches ! + #self.__git('checkout', '-f',cwd=sourceDir) + sourceDir = self.checkoutDir() + return self.__git('apply', '--whitespace=fix', + '-p %d' % patchdepth, patchfile, cwd=sourceDir) + return True + + def createPatch( self ): + """create patch file from git source into the related package dir. + The patch file is named autocreated.patch""" + utils.trace( 'GitSource createPatch', 2 ) + patchFileName = os.path.join( self.packageDir(), "%s-%s.patch" % \ + ( self.package, str( datetime.date.today() ).replace('-', '') ) ) + with open(patchFileName,'w') as patchFile: + return self.__git('diff', stdout=patchFile) + + def sourceVersion( self ): + """print the revision returned by git show""" + utils.trace( 'GitSource sourceVersion', 2 ) + + print(self.__getCurrentRevision()) + return True + + def checkoutDir(self, index=0 ): + utils.trace( 'GitSource checkoutDir', 2 ) + return VersionSystemSourceBase.checkoutDir( self, index ) + + def sourceDir(self, index=0 ): + utils.trace( 'GitSource sourceDir', 2 ) + repopath = self.repositoryUrl() + # in case you need to move from a read only Url to a writeable one, here it gets replaced + repopath = repopath.replace("[git]", "") + repoString = utils.replaceVCSUrl( repopath ) + _, repoBranch, _ = utils.splitVCSUrl( repoString ) + if repoBranch == "": + repoBranch = "master" + if utils.envAsBool("EMERGE_GIT_MULTIBRANCH"): + sourcedir = os.path.join(self.checkoutDir(index), repoBranch) + else: + sourcedir = self.checkoutDir(index) + + if self.subinfo.hasTargetSourcePath(): + sourcedir = os.path.join(sourcedir, self.subinfo.targetSourcePath()) + + utils.debug("using sourcedir: %s" % sourcedir, 2) + return sourcedir + + def currentRevision(self): + """return the name or number of the current revision""" + return self.__getCurrentRevision() diff --git a/bin/Source/SvnSource.py b/bin/Source/SvnSource.py index 2684caec1..52da9e1c8 100644 --- a/bin/Source/SvnSource.py +++ b/bin/Source/SvnSource.py @@ -1,241 +1,238 @@ -# -# copyright (c) 2009 Ralf Habacker -# -# subversion support -## \todo needs dev-utils/subversion package, add some kind of tool requirement tracking for SourceBase derived classes - -from Source.VersionSystemSourceBase import * - -class SvnSource (VersionSystemSourceBase): - """subversion support""" - def __init__(self, subinfo=None): - utils.trace( "SvnSource.__init__", 2 ) - if subinfo: - self.subinfo = subinfo - VersionSystemSourceBase.__init__( self ) - self.options = None - ## \todo add internal dependency for subversion package - self.svnInstallDir = os.path.join(self.rootdir, 'dev-utils', 'svn', 'bin') - - def checkoutDir( self, index=0 ): - utils.trace( "SvnSource.checkoutDir", 2 ) - if self.subinfo.hasSvnTarget(): - u = self.getUrl(index) - (url, dummy) = self.splitUrl(u) - - if url.find("://") == -1: - if os.getenv("KDESVNDIR") == None: - sourcedir = os.path.join( self.downloadDir(), "svn-src", "kde", url ) - else: - sourcedir = os.path.join( os.getenv("KDESVNDIR"), url ) - else: - sourcedir = os.path.join( self.downloadDir(), "svn-src" ) - sourcedir = os.path.join( sourcedir, self.package ) - _, path = self.__splitPath(url) - if path and utils.envAsBool("EMERGE_SVN_STDLAYOUT"): - sourcedir = os.path.join( sourcedir, path ) - else: - utils.die("svnTarget property not set for this target") - - if self.subinfo.targetSourceSuffix() != None: - sourcedir = "%s-%s" % (sourcedir, self.subinfo.targetSourceSuffix()) - - return sourcedir - - def applyPatch(self, fileName, patchdepth, unusedSrcDir=None): - """apply a patch to a svn repository checkout""" - utils.trace( "SvnSource.applyPatch", 2 ) - if fileName: - patchfile = os.path.join (self.packageDir(), fileName) - # @todo check if this could be merged into SourceBase.applyPatch - if self.noCopy: - srcdir = self.sourceDir() - else: - srcdir = self.buildDir() - return utils.applyPatch(srcdir, patchfile, patchdepth) - return True - - def setProxy(self): - """set proxy for fetching sources from subversion repository""" - (host, port, username, password) = self.proxySettings() - if host == None: - return - - proxyOptions = " --config-option servers:global:http-proxy-host=%s" % host - proxyOptions += " --config-option servers:global:http-proxy-port=%s" % port - if username != None: - proxyOptions += " --config-option servers:global:http-proxy-username=%s" % username - proxyOptions += " --config-option servers:global:http-proxy-password=%s" % password - - self.options = proxyOptions - - def fetch( self, repopath = None ): - """ checkout or update an existing repository path """ - utils.trace( "SvnSource.fetch", 2 ) - if self.noFetch: - utils.debug( "skipping svn fetch (--offline)" ) - return True - - if not os.path.exists(self.svnInstallDir): - utils.die("required subversion package not installed in %s" % self.svnInstallDir) - - for i in range(self.repositoryUrlCount()): - if repopath: - url = repopath - else: - url = self.repositoryUrl(i) - self.__tryCheckoutFromRoot(url, self.checkoutDir(i), self.repositoryUrlOptions(i) != 'norecursive') - return True - - def __getCurrentRevision( self ): - """ return the revision returned by svn info """ - - revision = None - # first, change the output to always be english - if "LANG" in os.environ: - oldLanguage = os.environ["LANG"] - else: - oldLanguage = "" - os.environ["LANG"] = "C" - - # handle multiple urls in targets - # we need to find the main url which is marked with #main - # if not marked use the second last one, which is used currently - sourcedir = None - n = self.repositoryUrlCount() - if n > 1: - for i in range(0, n): - if self.repositoryUrlOptions(i) == 'main': - sourcedir = self.checkoutDir(i) - break - # if not found use the second last one - if sourcedir == None: - sourcedir = self.checkoutDir(n-2) - else: - sourcedir = self.checkoutDir() - - # set up the command - cmd = "%s/svn info %s" % ( self.svnInstallDir, sourcedir ) - - # open a temporary file - do not use generic tmpfile because this doesn't give a good file object with python - tempFileName = os.path.join( self.checkoutDir().replace('/', '\\'), ".emergesvninfo.tmp" ) - with open( tempFileName, "wb+" ) as tempfile: - - # run the command - with utils.LockFile(utils.LockFileName("SVN")): - utils.system( cmd, stdout=tempfile ) - - tempfile.seek(os.SEEK_SET) - # read the temporary file and find the line with the revision - for line in tempfile: - if line.startswith("Revision: "): - revision = line.replace("Revision: ", "").strip() - break - - os.environ["LANG"] = oldLanguage - os.remove( tempFileName ) - return revision - - def __splitPath(self, path): - """ split a path into a base part and a relative repository url. - The delimiters are currently 'trunk', 'branches' and 'tags'. - """ - pos = path.find('trunk') - if pos == -1: - pos = path.find('branches') - if pos == -1: - pos = path.find('tags') - if pos == -1: - ret = [path, None] - else: - ret = [path[:pos-1], path[pos:]] - return ret - - def __tryCheckoutFromRoot ( self, url, sourcedir, recursive=True ): - """This method checkout source with svn informations from - the svn root repository directory. It detects the svn root - by searching the predefined root subdirectories 'trunk', 'branches' - and 'tags' which will probably fit for most servers - """ - (urlBase, urlPath) = self.__splitPath(url) - if urlPath == None: - return self.__checkout(url, sourcedir, recursive) - - (srcBase, srcPath) = self.__splitPath(sourcedir) - if srcPath == None: - return self.__checkout(url, sourcedir, recursive) - - urlRepo = urlBase - srcDir = srcBase - urlParts = urlPath.split('/') - pathSep = '/' - srcParts = srcPath.split(pathSep) - - # url and source parts not match - if len(urlParts) != len(srcParts): - return self.__checkout(url, sourcedir, recursive) - - for i in range(0, len(urlParts)-1): - urlPart = urlParts[i] - srcPart = srcParts[i] - if ( urlPart == "" ): - continue - - urlRepo += '/' + urlPart - srcDir += pathSep + srcPart - - if os.path.exists(srcDir): - continue - self.__checkout( urlRepo, srcDir, False ) - - self.__checkout( url, sourcedir, recursive ) - - def __checkout( self, url, sourcedir, recursive=True ): - """internal method for subversion checkout and update""" - option = "" - if not recursive: - option = "--depth=files" - - if utils.verbose() < 2 and not utils.envAsBool("KDESVNVERBOSE"): - option += " --quiet" - - self.setProxy() - - if self.options != None: - option += self.options - - if self.subinfo.options.fetch.ignoreExternals: - option += " --ignore-externals " - - url = utils.replaceVCSUrl( url ) - - if os.path.exists( sourcedir ): - cmd = "%s/svn update %s %s" % ( self.svnInstallDir, option, sourcedir ) - else: - cmd = "%s/svn checkout %s %s %s" % (self.svnInstallDir, option, url, sourcedir ) - - with utils.LockFile(utils.LockFileName("SVN")): - return utils.system( cmd ) - - def createPatch( self ): - """create patch file from svn source into the related package dir. The patch file is named autocreated.patch""" - cmd = "%s/svn diff %s > %s" % ( self.svnInstallDir, self.checkoutDir(), os.path.join( self.packageDir(), "%s-%s.patch" % \ - ( self.package, str( datetime.date.today() ).replace('-', '') ) ) ) - with utils.LockFile(utils.LockFileName("SVN")): - return utils.system( cmd ) - - def sourceVersion( self ): - """ print the revision returned by svn info """ - return True - - def getUrls( self ): - """print the url where to check out from""" - for i in range(self.repositoryUrlCount()): - url = self.repositoryUrl(i) - if self.repositoryUrlOptions(i) == 'norecursive': url = '--depth=files ' + url - print(url) - return True - - def currentRevision(self): - """return the name or number of the current revision""" - return self.__getCurrentRevision() +# +# copyright (c) 2009 Ralf Habacker +# +# subversion support +## \todo needs dev-utils/subversion package, add some kind of tool requirement tracking for SourceBase derived classes + +from Source.VersionSystemSourceBase import * + +class SvnSource (VersionSystemSourceBase): + """subversion support""" + def __init__(self, subinfo=None): + utils.trace( "SvnSource.__init__", 2 ) + if subinfo: + self.subinfo = subinfo + VersionSystemSourceBase.__init__( self ) + self.options = None + ## \todo add internal dependency for subversion package + self.svnInstallDir = os.path.join(self.rootdir, 'dev-utils', 'svn', 'bin') + + def checkoutDir( self, index=0 ): + utils.trace( "SvnSource.checkoutDir", 2 ) + if self.subinfo.hasSvnTarget(): + u = self.getUrl(index) + (url, dummy) = self.splitUrl(u) + + if url.find("://") == -1: + if os.getenv("KDESVNDIR") == None: + sourcedir = os.path.join( self.downloadDir(), "svn-src", "kde", url ) + else: + sourcedir = os.path.join( os.getenv("KDESVNDIR"), url ) + else: + sourcedir = os.path.join( self.downloadDir(), "svn-src" ) + sourcedir = os.path.join( sourcedir, self.package ) + _, path = self.__splitPath(url) + if path and utils.envAsBool("EMERGE_SVN_STDLAYOUT"): + sourcedir = os.path.join( sourcedir, path ) + else: + utils.die("svnTarget property not set for this target") + + if self.subinfo.targetSourceSuffix() != None: + sourcedir = "%s-%s" % (sourcedir, self.subinfo.targetSourceSuffix()) + + return sourcedir + + def applyPatch(self, fileName, patchdepth, unusedSrcDir=None): + """apply a patch to a svn repository checkout""" + utils.trace( "SvnSource.applyPatch", 2 ) + if fileName: + patchfile = os.path.join (self.packageDir(), fileName) + # @todo check if this could be merged into SourceBase.applyPatch + if self.noCopy: + srcdir = self.sourceDir() + else: + srcdir = self.buildDir() + return utils.applyPatch(srcdir, patchfile, patchdepth) + return True + + def setProxy(self): + """set proxy for fetching sources from subversion repository""" + (host, port, username, password) = self.proxySettings() + if host == None: + return + + proxyOptions = " --config-option servers:global:http-proxy-host=%s" % host + proxyOptions += " --config-option servers:global:http-proxy-port=%s" % port + if username != None: + proxyOptions += " --config-option servers:global:http-proxy-username=%s" % username + proxyOptions += " --config-option servers:global:http-proxy-password=%s" % password + + self.options = proxyOptions + + def fetch( self, repopath = None ): + """ checkout or update an existing repository path """ + utils.trace( "SvnSource.fetch", 2 ) + if self.noFetch: + utils.debug( "skipping svn fetch (--offline)" ) + return True + + if not os.path.exists(self.svnInstallDir): + utils.die("required subversion package not installed in %s" % self.svnInstallDir) + + for i in range(0, self.repositoryUrlCount()): + if repopath: + url = repopath + else: + url = self.repositoryUrl(i) + sourcedir = self.checkoutDir(i) + if self.repositoryUrlOptions(i) == 'norecursive': + self.__tryCheckoutFromRoot(url, sourcedir, False) + else: + self.__tryCheckoutFromRoot(url, sourcedir, True) + i += 1 + return True + + def __getCurrentRevision( self ): + """ return the revision returned by svn info """ + + revision = None + # first, change the output to always be english + if "LANG" in os.environ: + oldLanguage = os.environ["LANG"] + else: + oldLanguage = "" + os.environ["LANG"] = "C" + + # handle multiple urls in targets + # we need to find the main url which is marked with #main + # if not marked use the second last one, which is used currently + sourcedir = None + n = self.repositoryUrlCount() + if n > 1: + for i in range(0, n): + if self.repositoryUrlOptions(i) == 'main': + sourcedir = self.checkoutDir(i) + break + # if not found use the second last one + if sourcedir == None: + sourcedir = self.checkoutDir(n-2) + else: + sourcedir = self.checkoutDir() + + # set up the command + cmd = "%s/svn info %s" % ( self.svnInstallDir, sourcedir ) + + # open a temporary file - do not use generic tmpfile because this doesn't give a good file object with python + tempFileName = os.path.join( self.checkoutDir().replace('/', '\\'), ".emergesvninfo.tmp" ) + with open( tempFileName, "wb+" ) as tempfile: + + # run the command + with utils.LockFile(utils.LockFileName("SVN")): + utils.system( cmd, stdout=tempfile ) + + tempfile.seek(os.SEEK_SET) + # read the temporary file and find the line with the revision + for line in tempfile: + if line.startswith("Revision: "): + revision = line.replace("Revision: ", "").strip() + break + + os.environ["LANG"] = oldLanguage + os.remove( tempFileName ) + return revision + + def __splitPath(self, path): + """ split a path into a base part and a relative repository url. + The delimiters are currently 'trunk', 'branches' and 'tags'. + """ + pos = path.find('trunk') + if pos == -1: + pos = path.find('branches') + if pos == -1: + pos = path.find('tags') + if pos == -1: + ret = [path, None] + else: + ret = [path[:pos-1], path[pos:]] + return ret + + def __tryCheckoutFromRoot ( self, url, sourcedir, recursive=True ): + """This method checkout source with svn informations from + the svn root repository directory. It detects the svn root + by searching the predefined root subdirectories 'trunk', 'branches' + and 'tags' which will probably fit for most servers + """ + (urlBase, urlPath) = self.__splitPath(url) + if urlPath == None: + return self.__checkout(url, sourcedir, recursive) + + (srcBase, srcPath) = self.__splitPath(sourcedir) + if srcPath == None: + return self.__checkout(url, sourcedir, recursive) + + urlRepo = urlBase + srcDir = srcBase + urlParts = urlPath.split('/') + pathSep = '/' + srcParts = srcPath.split(pathSep) + + # url and source parts not match + if len(urlParts) != len(srcParts): + return self.__checkout(url, sourcedir, recursive) + + for i in range(0, len(urlParts)-1): + urlPart = urlParts[i] + srcPart = srcParts[i] + if ( urlPart == "" ): + continue + + urlRepo += '/' + urlPart + srcDir += pathSep + srcPart + + if os.path.exists(srcDir): + continue + self.__checkout( urlRepo, srcDir, False ) + + self.__checkout( url, sourcedir, recursive ) + + def __checkout( self, url, sourcedir, recursive=True ): + """internal method for subversion checkout and update""" + option = "" + if not recursive: + option = "--depth=files" + + if utils.verbose() < 2 and not utils.envAsBool("KDESVNVERBOSE"): + option += " --quiet" + + self.setProxy() + + if self.options != None: + option += self.options + + if self.subinfo.options.fetch.ignoreExternals: + option += " --ignore-externals " + + url = utils.replaceVCSUrl( url ) + + if os.path.exists( sourcedir ): + cmd = "%s/svn update %s %s" % ( self.svnInstallDir, option, sourcedir ) + else: + cmd = "%s/svn checkout %s %s %s" % (self.svnInstallDir, option, url, sourcedir ) + + with utils.LockFile(utils.LockFileName("SVN")): + return utils.system( cmd ) + + def createPatch( self ): + """create patch file from svn source into the related package dir. The patch file is named autocreated.patch""" + cmd = "%s/svn diff %s > %s" % ( self.svnInstallDir, self.checkoutDir(), os.path.join( self.packageDir(), "%s-%s.patch" % \ + ( self.package, str( datetime.date.today() ).replace('-', '') ) ) ) + with utils.LockFile(utils.LockFileName("SVN")): + return utils.system( cmd ) + + def sourceVersion( self ): + """ print the revision returned by svn info """ + return True + + def currentRevision(self): + """return the name or number of the current revision""" + return self.__getCurrentRevision() diff --git a/bin/emerge.py b/bin/emerge.py index 3375f9c0a..c2a9c265d 100644 --- a/bin/emerge.py +++ b/bin/emerge.py @@ -1,647 +1,645 @@ -# -*- coding: utf-8 -*- -# this will emerge some programs... - -# copyright: -# Holger Schroeder -# Patrick Spendrin - -import sys - -# The minimum python version for emerge please edit here -# if you add code that changes this requirement -MIN_PY_VERSION = (3, 0, 0) - -if sys.version_info[0:3] < MIN_PY_VERSION: - print ("Error: Python too old!") - print ("Emerge needs at least Python Version %s.%s.%s" % MIN_PY_VERSION ) - print ("Please install it and adapt your kdesettings.bat") - exit(1) - -import os -import utils -import portage -import emergePlatform -import portageSearch -import shutil -from InstallDB import * -import time -import datetime -import threading - - -def usage(): - print(""" -Usage: - emerge [[ command and flags ] [ singletarget ] - [ command and flags ] [ singletarget ] - ... ] - - where singletarget can be of the form: - category - package - category/package - -Emerge is a tool for building KDE-related software under Windows. emerge -automates it, looks for the dependencies and fetches them automatically. -Some options should be used with extreme caution since they will -make your kde installation unusable in 999 out of 1000 cases. - -Commands (no packagename needed - will be ignored when given): - ---print-installed This will show a list of all packages that - are installed currently. It queries both - databases (etc\portage\installed) and the - manifest directory - it prints out only those - packages that are contained within - --print-installable ---print-installable This will give you a list of packages that can - be installed. Currently you don't need to - enter the category and package: only the - package will be enough. ---update-all this option tries to update all installed - packages that contain one or multiple svn - targets. This is equivalent to running all - those packages with the flag --update. - -Commands (must have a packagename): - ---print-targets This will print all the different targets one package - can contain: different releases might have different - tags that are build as targets of a package. As an - example: You could build the latest amarok sources with - the target 'svnHEAD' the previous '1.80' release would - be contained as target '1.80'. ---print-revision This will print the revision that the source repository - of this package currently has or nothing if there is no - repository. ---fetch retrieve package sources (also checkout sources from - svn or git). ---unpack unpack package sources and make up the build directory. ---compile compile the sources: this includes - configure'ing/cmake'ing and running [mingw32-|n|]make. ---configure configure the sources (support is package specific) ---make run [mingw32-|n|]make (support is package specific) ---install This will run [mingw32-|n|]make install into the image - directory of each package. ---manifest This step creates the files contained in the manifest - dir. ---qmerge This will merge the image directory into the KDEROOT ---test This will run the unittests if they are present ---package This step will create a package out of the image - directory instead of merge'ing the image directory into - the KDEROOT (Requires the packager to be installed - already.) ---full-package This will create packages instead of installing stuff - to KDEROOT ---install-deps This will fetch and install all required dependencies - for the specified package ---unmerge this uninstalls a package from KDEROOT - it requires a - working manifest directory. unmerge only delete - unmodified files by default. You may use the -f or - --force option to let unmerge delete all files - unconditional. ---cleanallbuilds Clean complete build directory. ---cleanbuild Clean build directory for the specified package. This - cleans also all the image directories of all targets of - the specified package. ---checkdigest Check digest for the specified package. If no digest is - available calculate and print digests. ---geturls Prints the required urls for the source(s) of this - package. ---cleanimage Clean image directory for the specified package and - target. ---createpatch Create source patch file for the specific package based - on the original archive file or checkout revision of - the used software revision control system. ---disable-buildhost This disables the building for the host. ---disable-buildtarget This disables the building for the target. - -Flags: - ---buildtype=[BUILDTYPE] This will override the build type set by the - environment option EMERGE_BUILDTYPE . - Please set it to one out of Release, Debug, - RelWithDebInfo, MinSizeRel ---target=[TARGET] This will override the build of the default - target. The default Target is marked with a - star in the printout of --print-targets ---options= Set emerge property from string . - An example for is "cmake.openIDE=1"; - see options.py for more informations. ---patchlevel=[PATCHLEVEL] This will add a patch level when used together - with --package ---log-dir=[LOG_DIR] This will log the build output to a logfile in - LOG_DIR for each package. Logging information - is appended to existing logs. - --i ignore install: using this option will install a package over an - existing install. This can be useful if you want to check some - new code and your last build isn't that old. --p ---probe probing: emerge will only look which files it has to build - according to the list of installed files and according to the - dependencies of the package. --q quiet: there should be no output - The verbose level should be 0 --t test: if used on an KDE target it will override the environment - variable and build the target with -DKDE_BUILD_TESTS=ON --v verbose: increases the verbose level of emerge. Default is 1. - verbose level 1 contains some notes from emerge, all output of - cmake, make and other programs that are used. verbose level 2 - adds an option VERBOSE=1 to make and emerge is more verbose - highest level is verbose level 3. --z if packages from version control system sources are installed, - it marks them as out of date and rebuilds them (tags are not - marked as out of date). --sz similar to -z, only that it acts only on the last package, and - works as normal on the rest. ---noclean this option will try to use an existing build directory. Please - handle this option with care - it will possibly break if the - directory isn't existing. ---nocopy this option is deprecated. In older releases emerge would have - copied everything from the SVN source tree to a source directory - under %KDEROOT%\\tmp - currently nocopy is applied by default if - EMERGE_NOCOPY is not set to "False". Be aware that setting - EMERGE_NOCOPY to "False" might slow down the build process, - irritate you and increase the disk space roughly by the size of - SVN source tree. ---offline do not try to connect to the internet: KDE packages will try to - use an existing source tree and other packages would try to use - existing packages in the download directory. If that doesn't - work, the build will fail. ---update this option is the same as '-i --noclean'. It will update a single - package that is already installed. ---cleanup Clean your portage directory, to prevent emerge errors, removes - empty directories and *.pyc files - -Internal options or options that aren't fully implemented yet: -PLEASE DO NOT USE! ---version-dir ---version-package - -More information see the README or http://windows.kde.org/. -Send feedback to . - -""") - -@utils.log -def doExec( category, package, version, action, opts ): - utils.startTimer("%s for %s" % ( action,package),1) - utils.debug( "emerge doExec called. action: %s opts: %s" % (action, opts), 2 ) - fileName = portage.getFilename( category, package, version ) - opts_string = ( "%s " * len( opts ) ) % tuple( opts ) - commandstring = "python %s %s %s" % ( fileName, action, opts_string ) - - utils.debug( "file: " + fileName, 1 ) - try: - #Switched to import the packages only, because otherwise degugging is very hard, if it troubles switch back - #makes touble for xcompile -> changed back - if not utils.system( commandstring ): - utils.die( "running %s" % commandstring ) - #mod = portage.__import__( fileName ) - #mod.Package().execute(action) - except OSError: - utils.stopTimer("%s for %s" % ( action,package)) - return False - utils.stopTimer("%s for %s" % ( action,package)) - return True - -def updateTitle(startTime,title): - while(len(utils._TIMERS)>0): - delta = datetime.datetime.now() - startTime - utils.setTitle("emerge %s %s" %(title , delta)) - time.sleep(1) - -def handlePackage( category, package, version, buildAction, opts ): - utils.debug( "emerge handlePackage called: %s %s %s %s" % (category, package, version, buildAction), 2 ) - success = True - - if continueFlag: - actionList = ['fetch', 'unpack', 'configure', 'make', 'cleanimage', 'install', 'manifest', 'qmerge'] - - found = None - for action in actionList: - if not found and action != buildAction: - continue - found = True - success = success and doExec( category, package, version, action, opts ) - elif ( buildAction == "all" or buildAction == "full-package" ): - os.putenv( "EMERGE_BUILD_STEP", "" ) - success = doExec( category, package, version, "fetch", opts ) - success = success and doExec( category, package, version, "unpack", opts ) - if emergePlatform.isCrossCompilingEnabled(): - if not disableHostBuild: - os.putenv( "EMERGE_BUILD_STEP", "host" ) - success = success and doExec( category, package, version, "compile", opts ) - success = success and doExec( category, package, version, "cleanimage", opts ) - success = success and doExec( category, package, version, "install", opts ) - if ( buildAction == "all" ): - success = success and doExec( category, package, version, "manifest", opts ) - if ( buildAction == "all" ): - success = success and doExec( category, package, version, "qmerge", opts ) - if( buildAction == "full-package" ): - success = success and doExec( category, package, version, "package", opts ) - if disableTargetBuild: - return success - os.putenv( "EMERGE_BUILD_STEP", "target" ) - - success = success and doExec( category, package, version, "compile", opts ) - success = success and doExec( category, package, version, "cleanimage", opts ) - success = success and doExec( category, package, version, "install", opts ) - if ( buildAction == "all" ): - success = success and doExec( category, package, version, "manifest", opts ) - if ( buildAction == "all" ): - success = success and doExec( category, package, version, "qmerge", opts ) - if( buildAction == "full-package" ): - success = success and doExec( category, package, version, "package", opts ) - - elif ( buildAction in [ "fetch", "unpack", "preconfigure", "configure", "compile", "make", "qmerge", "checkdigest", "dumpdeps", - "package", "manifest", "unmerge", "test", "cleanimage", "cleanbuild", "createpatch", "geturls", - "printrev"] and category and package and version ): - os.putenv( "EMERGE_BUILD_STEP", "" ) - success = True - if emergePlatform.isCrossCompilingEnabled(): - if not disableHostBuild: - os.putenv( "EMERGE_BUILD_STEP", "host" ) - success = doExec( category, package, version, buildAction, opts ) - if disableTargetBuild: - return success - os.putenv( "EMERGE_BUILD_STEP", "target" ) - success = success and doExec( category, package, version, buildAction, opts ) - elif ( buildAction == "install" ): - os.putenv( "EMERGE_BUILD_STEP", "" ) - success = True - if emergePlatform.isCrossCompilingEnabled(): - if not disableHostBuild: - os.putenv( "EMERGE_BUILD_STEP", "host" ) - success = doExec( category, package, version, "cleanimage", opts ) - success = success and doExec( category, package, version, "install", opts ) - if disableTargetBuild: - return success - os.putenv( "EMERGE_BUILD_STEP", "target" ) - success = success and doExec( category, package, version, "cleanimage", opts ) - success = success and doExec( category, package, version, "install", opts ) - elif ( buildAction == "version-dir" ): - print("%s-%s" % ( package, version )) - success = True - elif ( buildAction == "version-package" ): - print("%s-%s-%s" % ( package, os.getenv( "KDECOMPILER" ), version )) - success = True - elif ( buildAction == "print-installable" ): - portage.printInstallables() - success = True - elif ( buildAction == "print-installed" ): - if isDBEnabled(): - printInstalled() - else: - portage.printInstalled() - success = True - elif ( buildAction == "print-targets" ): - portage.printTargets( category, package, version ) - success = True - elif ( buildAction == "install-deps" ): - success = True - else: - success = utils.error( "could not understand this buildAction: %s" % buildAction ) - - return success - -# -# "main" action starts here -# - -# TODO: all the rest should go into main(). But here I am not -# sure - maybe some of those variables are actually MEANT to -# be used in other modules. Put this back for now - -# but as a temporary solution rename variables to mainXXX -# where it is safe so there are less redefinitions in inner scopes - -utils.startTimer("Emerge") -tittleThread = threading.Thread(target=updateTitle,args = (datetime.datetime.now()," ".join(sys.argv[1:]),)) -tittleThread.setDaemon(True) -tittleThread.start() - - -mainBuildAction = "all" -packageName = None -doPretend = False -outDateVCS = False -outDatePackage = False -stayQuiet = False -disableHostBuild = False -disableTargetBuild = False -ignoreInstalled = False -updateAll = False -continueFlag = False - -if len( sys.argv ) < 2: - usage() - utils.die("") - -environ = dict() # TODO: why do we need this at all? -environ["EMERGE_TRACE"] = os.getenv( "EMERGE_TRACE" ) -environ["EMERGE_BUILDTESTS"] = os.getenv( "EMERGE_BUILDTESTS" ) -environ["EMERGE_OFFLINE"] = os.getenv( "EMERGE_OFFLINE" ) -environ["EMERGE_FORCED"] = os.getenv( "EMERGE_FORCED" ) -environ["EMERGE_VERSION"] = os.getenv( "EMERGE_VERSION" ) -environ["EMERGE_BUILDTYPE"] = os.getenv( "EMERGE_BUILDTYPE" ) -environ["EMERGE_TARGET"] = os.getenv( "EMERGE_TARGET" ) -environ["EMERGE_PKGPATCHLVL"] = os.getenv( "EMERGE_PKGPATCHLVL" ) -environ["EMERGE_LOG_DIR"] = os.getenv( "EMERGE_LOG_DIR" ) - -if environ['EMERGE_TRACE'] == None or not environ['EMERGE_TRACE'].isdigit(): - trace = 0 - os.environ["EMERGE_TRACE"] = str( trace ) -else: - trace = int( environ[ "EMERGE_TRACE" ] ) - -mainOpts = list() - -executableName = sys.argv.pop( 0 ) -nextArguments = sys.argv[:] - -for i in sys.argv: - nextArguments.pop(0) - if ( i == "-p" or i == "--probe" ): - doPretend = True - elif ( i.startswith("--options=") ): - # @todo how to add -o option - options = i.replace( "--options=", "" ) - if "EMERGE_OPTIONS" in os.environ: - os.environ["EMERGE_OPTIONS"] += " %s" % options - else: - os.environ["EMERGE_OPTIONS"] = options - elif ( i == "-z" ): - outDateVCS = True - elif ( i == "-sz" ): - outDatePackage = True - elif ( i == "-q" ): - stayQuiet = True - elif ( i == "-t" ): - os.environ["EMERGE_BUILDTESTS"] = "True" - elif i == "-c" or i == "--continue": - continueFlag = True - elif ( i == "--offline" ): - mainOpts.append( "--offline" ) - os.environ["EMERGE_OFFLINE"] = "True" - elif ( i == "-f" or i == "--force" ): - os.environ["EMERGE_FORCED"] = "True" - elif ( i.startswith( "--buildtype=" ) ): - os.environ["EMERGE_BUILDTYPE"] = i.replace( "--buildtype=", "" ) - elif ( i.startswith( "--target=" ) ): - os.environ["EMERGE_TARGET"] = i.replace( "--target=", "" ) - elif ( i.startswith( "--patchlevel=" ) ): - os.environ["EMERGE_PKGPATCHLVL"] = i.replace( "--patchlevel=", "" ) - elif ( i.startswith( "--log-dir=" ) ): - os.environ["EMERGE_LOG_DIR"] = i.replace( "--log-dir=", "" ) - elif ( i == "-v" ): - utils.Verbose.increase() - elif ( i == "--trace" ): - trace = trace + 1 - os.environ["EMERGE_TRACE"] = str( trace ) - elif ( i == "--nocopy" ): - os.environ["EMERGE_NOCOPY"] = str( True ) - elif ( i == "--noclean" ): - os.environ["EMERGE_NOCLEAN"] = str( True ) - elif ( i == "--clean" ): - os.environ["EMERGE_NOCLEAN"] = str( False ) - elif ( i in [ "--version-dir", "--version-package", "--print-installable", - "--print-installed", "--print-targets" ] ): - mainBuildAction = i[2:] - stayQuiet = True - if i in [ "--print-installable", "--print-installed" ]: - break - elif ( i == "-i" ): - ignoreInstalled = True - elif ( i == "--update" ): - ignoreInstalled = True - os.environ["EMERGE_NOCLEAN"] = str( True ) - elif ( i == "--update-all" ): - ignoreInstalled = True - os.environ["EMERGE_NOCLEAN"] = str( True ) - updateAll = True - elif ( i == "--install-deps" ): - ignoreInstalled = True - mainBuildAction = "install-deps" - elif ( i in [ "--fetch", "--unpack", "--preconfigure", "--configure", "--compile", "--make", - "--install", "--qmerge", "--manifest", "--package", "--unmerge", "--test", "--checkdigest", "--dumpdeps", - "--full-package", "--cleanimage", "--cleanbuild", "--createpatch", "--geturls"] ): - mainBuildAction = i[2:] - elif ( i == "--print-revision" ): - mainBuildAction = "printrev" - elif ( i == "--disable-buildhost" ): - disableHostBuild = True - elif ( i == "--disable-buildtarget" ): - disableTargetBuild = True - elif( i == "--cleanup" ): - utils.debug("Starting to clean emerge" ) - utils.system("cd %s && git clean -f -x -e *.py -e *.diff -e *.ba\\t -e *.cmd -e *.reg" % os.path.join(os.getenv("KDEROOT"),"emerge") ) - exit(0) - elif( i == "--cleanup-dry" ): - utils.debug("Starting to clean emerge" ) - utils.system("cd %s && git clean --dry-run -x -e *.py -e *.diff -e *.ba\\t -e *.cmd -e *.reg" % os.path.join(os.getenv("KDEROOT"),"emerge") ) - exit(0) - elif i == "--cleanallbuilds": - # clean complete build directory - utils.cleanDirectory(os.path.join( os.getenv("KDEROOT"), "build")) - exit(0) - elif ( i == "--search" ): - package = nextArguments.pop(0) - category = "" - if not package.find("/") == -1: - (category,package) = package.split("/") - portageSearch.printSearch(category, package) - exit(0) - elif ( i.startswith( "-" ) ): - usage() - exit ( 1 ) - else: - packageName = i - break - -if stayQuiet == True: - utils.setVerbose(0) - -# get KDEROOT from env -KDEROOT = os.getenv( "KDEROOT" ) -utils.debug( "buildAction: %s" % mainBuildAction ) -utils.debug( "doPretend: %s" % doPretend, 1 ) -utils.debug( "packageName: %s" % packageName ) -utils.debug( "buildType: %s" % os.getenv( "EMERGE_BUILDTYPE" ) ) -utils.debug( "buildTests: %s" % utils.envAsBool( "EMERGE_BUILDTESTS" ) ) -utils.debug( "verbose: %d" % utils.verbose(), 1 ) -utils.debug( "trace: %s" % os.getenv( "EMERGE_TRACE" ), 1 ) -utils.debug( "KDEROOT: %s\n" % KDEROOT, 1 ) -utils.debug_line() - -def unset_var( varname ): - if not os.getenv( varname ) == None: - print() - utils.warning( "%s found as environment variable. you cannot override emerge"\ - " with this - unsetting %s locally" % ( varname, varname ) ) - os.environ[ varname ] = "" - -unset_var( "CMAKE_INCLUDE_PATH" ) -unset_var( "CMAKE_LIBRARY_PATH" ) -unset_var( "CMAKE_FIND_PREFIX" ) -unset_var( "CMAKE_INSTALL_PREFIX" ) - -# adding emerge/bin to find base.py and gnuwin32.py etc. -os.environ["PYTHONPATH"] = os.getenv( "PYTHONPATH", "" ) + os.pathsep + \ - os.path.join( os.getcwd(), os.path.dirname( executableName ) ) -sys.path.append( os.path.join( os.getcwd(), os.path.dirname( executableName ) ) ) - -_deplist = [] -deplist = [] -packageList = [] -categoryList = [] - - -buildType = os.getenv("EMERGE_BUILDTYPE") -if "EMERGE_DEFAULTCATEGORY" in os.environ: - defaultCategory = os.environ["EMERGE_DEFAULTCATEGORY"] -else: - defaultCategory = "kde" - -if updateAll: - installedPackages = portage.PortageInstance.getInstallables() - if portage.PortageInstance.isCategory( packageName ): - utils.debug( "Updating installed packages from category " + packageName, 1 ) - else: - utils.debug( "Updating all installed packages", 1 ) - packageList = [] - for mainCategory, mainPackage, mainVersion in installedPackages: - if portage.PortageInstance.isCategory( packageName ) and ( mainCategory != packageName ): - continue - if portage.isInstalled( mainCategory, mainPackage, mainVersion, buildType ) \ - and portage.isPackageUpdateable( mainCategory, mainPackage, mainVersion ): - categoryList.append( mainCategory ) - packageList.append( mainPackage ) - utils.debug( "Will update packages: " + str (packageList), 1 ) -elif packageName: - packageList, categoryList = portage.getPackagesCategories(packageName) - -for entry in packageList: - utils.debug( "%s" % entry, 1 ) -utils.debug_line( 1 ) - -for mainCategory, entry in zip (categoryList, packageList): - _deplist = portage.solveDependencies( mainCategory, entry, "", _deplist ) - -deplist = [p.ident() for p in _deplist] - -for item in range( len( deplist ) ): - if deplist[ item ][ 0 ] in categoryList and deplist[ item ][ 1 ] in packageList: - deplist[ item ].append( ignoreInstalled ) - else: - deplist[ item ].append( False ) - - utils.debug( "dependency: %s" % deplist[ item ], 1 ) - -#for item in deplist: -# cat = item[ 0 ] -# pac = item[ 1 ] -# ver = item[ 2 ] - -# if portage.isInstalled( cat, pac, ver, buildType) and updateAll and not portage.isPackageUpdateable( cat, pac, ver ): -# print "remove:", cat, pac, ver -# deplist.remove( item ) - -if mainBuildAction == "install-deps": - # the first dependency is the package itself - ignore it - # TODO: why are we our own dependency? - del deplist[ 0 ] - -deplist.reverse() - -# package[0] -> category -# package[1] -> package -# package[2] -> version - -if ( mainBuildAction != "all" and mainBuildAction != "install-deps" ): - # if a buildAction is given, then do not try to build dependencies - # and do the action although the package might already be installed. - # This is still a bit problematic since packageName might not be a valid - # package - - if packageName and len( deplist ) >= 1: - mainCategory, mainPackage, mainVersion, tag, ignoreInstalled = deplist[ -1 ] - else: - mainCategory, mainPackage, mainVersion = None, None, None - - if not handlePackage( mainCategory, mainPackage, mainVersion, mainBuildAction, mainOpts ): - utils.notify("Emerge %s failed" % mainBuildAction, "%s of %s/%s-%s failed" % ( mainBuildAction,mainCategory, mainPackage, mainVersion),mainBuildAction) - exit(1) - utils.notify("Emerge %s finished"% mainBuildAction, "%s of %s/%s-%s finished" % ( mainBuildAction,mainCategory, mainPackage, mainVersion),mainBuildAction) - -else: - for mainCategory, mainPackage, mainVersion, defaultTarget, ignoreInstalled in deplist: - target = "" - targetList = [] - isLastPackage = [mainCategory, mainPackage, mainVersion, defaultTarget, ignoreInstalled] == deplist[-1] - if outDateVCS or (outDatePackage and isLastPackage): - target = os.getenv( "EMERGE_TARGET" ) - if not target or target not in list(portage.PortageInstance.getAllTargets( mainCategory, mainPackage, mainVersion ).keys()): - # if no target or a wrong one is defined, simply set the default target here - target = defaultTarget - targetList = portage.PortageInstance.getUpdatableVCSTargets( mainCategory, mainPackage, mainVersion ) - if isDBEnabled(): - if emergePlatform.isCrossCompilingEnabled(): - hostEnabled = portage.isHostBuildEnabled( mainCategory, mainPackage, mainVersion ) - targetEnabled = portage.isTargetBuildEnabled( mainCategory, mainPackage, mainVersion ) - hostInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, "" ) - targetInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, os.getenv( "EMERGE_TARGET_PLATFORM" ) ) - isInstalled = ( not hostEnabled or hostInstalled ) and ( not targetEnabled or targetInstalled ) - else: - isInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, "" ) - else: - isInstalled = portage.isInstalled( mainCategory, mainPackage, mainVersion, buildType ) - if ( isInstalled and not ignoreInstalled ) and not ( - isInstalled and (outDateVCS or (outDatePackage and isLastPackage) ) and target in targetList ): - if utils.verbose() > 1 and mainPackage == packageName: - utils.warning( "already installed %s/%s-%s" % ( mainCategory, mainPackage, mainVersion ) ) - elif utils.verbose() > 2 and not mainPackage == packageName: - utils.warning( "already installed %s/%s-%s" % ( mainCategory, mainPackage, mainVersion ) ) - else: - # in case we only want to see which packages are still to be build, simply return the package name - if ( doPretend ): - if utils.verbose() > 0: - msg = " " - if emergePlatform.isCrossCompilingEnabled(): - if isDBEnabled(): - hostEnabled = portage.isHostBuildEnabled( mainCategory, mainPackage, mainVersion ) - targetEnabled = portage.isTargetBuildEnabled( mainCategory, mainPackage, mainVersion ) - hostInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, "" ) - targetInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, os.getenv( "EMERGE_TARGET_PLATFORM" ) ) - msg += portage.getHostAndTarget( hostEnabled and not hostInstalled, targetEnabled and not targetInstalled ) - else: - msg = "" - utils.warning( "pretending %s/%s-%s%s" % ( mainCategory, mainPackage, mainVersion, msg ) ) - else: - mainAction = mainBuildAction - if mainBuildAction == "install-deps": - mainAction = "all" - - if not handlePackage( mainCategory, mainPackage, mainVersion, mainAction, mainOpts ): - utils.error( "fatal error: package %s/%s-%s %s failed" % \ - ( mainCategory, mainPackage, mainVersion, mainBuildAction ) ) - utils.notify("Emerge build failed", "Build of %s/%s-%s failed" % ( mainCategory, mainPackage, mainVersion),mainAction) - exit( 1 ) - utils.notify("Emerge build finished", "Build of %s/%s-%s finished" % ( mainCategory, mainPackage, mainVersion),mainAction) - -utils.new_line() -if len( nextArguments ) > 0: - command = "\"" + sys.executable + "\" -u " + executableName + " " + " ".join( nextArguments ) - - #for element in environ.keys(): - # if environ[ element ]: - # os.environ[ element ] = environ[ element ] - # elif element == "EMERGE_VERBOSE": - # os.environ[ element ] = "1" - # else: - # os.environ[ element ] = "" - if not utils.system(command): - utils.die( "cannot execute next commands cmd: %s" % command ) - -utils.stopTimer("Emerge") - +# -*- coding: utf-8 -*- +# this will emerge some programs... + +# copyright: +# Holger Schroeder +# Patrick Spendrin + +import sys + +# The minimum python version for emerge please edit here +# if you add code that changes this requirement +MIN_PY_VERSION = (3, 0, 0) + +if sys.version_info[0:3] < MIN_PY_VERSION: + print ("Error: Python too old!") + print ("Emerge needs at least Python Version %s.%s.%s" % MIN_PY_VERSION ) + print ("Please install it and adapt your kdesettings.bat") + exit(1) + +import os +import utils +import portage +import emergePlatform +import portageSearch +import shutil +from InstallDB import * +import time +import datetime +import threading + + +def usage(): + print(""" +Usage: + emerge [[ command and flags ] [ singletarget ] + [ command and flags ] [ singletarget ] + ... ] + + where singletarget can be of the form: + category + package + category/package + +Emerge is a tool for building KDE-related software under Windows. emerge +automates it, looks for the dependencies and fetches them automatically. +Some options should be used with extreme caution since they will +make your kde installation unusable in 999 out of 1000 cases. + +Commands (no packagename needed - will be ignored when given): + +--print-installed This will show a list of all packages that + are installed currently. It queries both + databases (etc\portage\installed) and the + manifest directory - it prints out only those + packages that are contained within + --print-installable +--print-installable This will give you a list of packages that can + be installed. Currently you don't need to + enter the category and package: only the + package will be enough. +--update-all this option tries to update all installed + packages that contain one or multiple svn + targets. This is equivalent to running all + those packages with the flag --update. + +Commands (must have a packagename): + +--print-targets This will print all the different targets one package + can contain: different releases might have different + tags that are build as targets of a package. As an + example: You could build the latest amarok sources with + the target 'svnHEAD' the previous '1.80' release would + be contained as target '1.80'. +--print-revision This will print the revision that the source repository + of this package currently has or nothing if there is no + repository. +--fetch retrieve package sources (also checkout sources from + svn or git). +--unpack unpack package sources and make up the build directory. +--compile compile the sources: this includes + configure'ing/cmake'ing and running [mingw32-|n|]make. +--configure configure the sources (support is package specific) +--make run [mingw32-|n|]make (support is package specific) +--install This will run [mingw32-|n|]make install into the image + directory of each package. +--manifest This step creates the files contained in the manifest + dir. +--qmerge This will merge the image directory into the KDEROOT +--test This will run the unittests if they are present +--package This step will create a package out of the image + directory instead of merge'ing the image directory into + the KDEROOT (Requires the packager to be installed + already.) +--full-package This will create packages instead of installing stuff + to KDEROOT +--install-deps This will fetch and install all required dependencies + for the specified package +--unmerge this uninstalls a package from KDEROOT - it requires a + working manifest directory. unmerge only delete + unmodified files by default. You may use the -f or + --force option to let unmerge delete all files + unconditional. +--cleanallbuilds Clean complete build directory. +--cleanbuild Clean build directory for the specified package. This + cleans also all the image directories of all targets of + the specified package. +--checkdigest Check digest for the specified package. If no digest is + available calculate and print digests. +--cleanimage Clean image directory for the specified package and + target. +--createpatch Create source patch file for the specific package based + on the original archive file or checkout revision of + the used software revision control system. +--disable-buildhost This disables the building for the host. +--disable-buildtarget This disables the building for the target. + +Flags: + +--buildtype=[BUILDTYPE] This will override the build type set by the + environment option EMERGE_BUILDTYPE . + Please set it to one out of Release, Debug, + RelWithDebInfo, MinSizeRel +--target=[TARGET] This will override the build of the default + target. The default Target is marked with a + star in the printout of --print-targets +--options= Set emerge property from string . + An example for is "cmake.openIDE=1"; + see options.py for more informations. +--patchlevel=[PATCHLEVEL] This will add a patch level when used together + with --package +--log-dir=[LOG_DIR] This will log the build output to a logfile in + LOG_DIR for each package. Logging information + is appended to existing logs. + +-i ignore install: using this option will install a package over an + existing install. This can be useful if you want to check some + new code and your last build isn't that old. +-p +--probe probing: emerge will only look which files it has to build + according to the list of installed files and according to the + dependencies of the package. +-q quiet: there should be no output - The verbose level should be 0 +-t test: if used on an KDE target it will override the environment + variable and build the target with -DKDE_BUILD_TESTS=ON +-v verbose: increases the verbose level of emerge. Default is 1. + verbose level 1 contains some notes from emerge, all output of + cmake, make and other programs that are used. verbose level 2 + adds an option VERBOSE=1 to make and emerge is more verbose + highest level is verbose level 3. +-z if packages from version control system sources are installed, + it marks them as out of date and rebuilds them (tags are not + marked as out of date). +-sz similar to -z, only that it acts only on the last package, and + works as normal on the rest. +--noclean this option will try to use an existing build directory. Please + handle this option with care - it will possibly break if the + directory isn't existing. +--nocopy this option is deprecated. In older releases emerge would have + copied everything from the SVN source tree to a source directory + under %KDEROOT%\\tmp - currently nocopy is applied by default if + EMERGE_NOCOPY is not set to "False". Be aware that setting + EMERGE_NOCOPY to "False" might slow down the build process, + irritate you and increase the disk space roughly by the size of + SVN source tree. +--offline do not try to connect to the internet: KDE packages will try to + use an existing source tree and other packages would try to use + existing packages in the download directory. If that doesn't + work, the build will fail. +--update this option is the same as '-i --noclean'. It will update a single + package that is already installed. +--cleanup Clean your portage directory, to prevent emerge errors, removes + empty directories and *.pyc files + +Internal options or options that aren't fully implemented yet: +PLEASE DO NOT USE! +--version-dir +--version-package + +More information see the README or http://windows.kde.org/. +Send feedback to . + +""") + +@utils.log +def doExec( category, package, version, action, opts ): + utils.startTimer("%s for %s" % ( action,package),1) + utils.debug( "emerge doExec called. action: %s opts: %s" % (action, opts), 2 ) + fileName = portage.getFilename( category, package, version ) + opts_string = ( "%s " * len( opts ) ) % tuple( opts ) + commandstring = "python %s %s %s" % ( fileName, action, opts_string ) + + utils.debug( "file: " + fileName, 1 ) + try: + #Switched to import the packages only, because otherwise degugging is very hard, if it troubles switch back + #makes touble for xcompile -> changed back + if not utils.system( commandstring ): + utils.die( "running %s" % commandstring ) + #mod = portage.__import__( fileName ) + #mod.Package().execute(action) + except OSError: + utils.stopTimer("%s for %s" % ( action,package)) + return False + utils.stopTimer("%s for %s" % ( action,package)) + return True + +def updateTitle(startTime,title): + while(len(utils._TIMERS)>0): + delta = datetime.datetime.now() - startTime + utils.setTitle("emerge %s %s" %(title , delta)) + time.sleep(1) + +def handlePackage( category, package, version, buildAction, opts ): + utils.debug( "emerge handlePackage called: %s %s %s %s" % (category, package, version, buildAction), 2 ) + success = True + + if continueFlag: + actionList = ['fetch', 'unpack', 'configure', 'make', 'cleanimage', 'install', 'manifest', 'qmerge'] + + found = None + for action in actionList: + if not found and action != buildAction: + continue + found = True + success = success and doExec( category, package, version, action, opts ) + elif ( buildAction == "all" or buildAction == "full-package" ): + os.putenv( "EMERGE_BUILD_STEP", "" ) + success = doExec( category, package, version, "fetch", opts ) + success = success and doExec( category, package, version, "unpack", opts ) + if emergePlatform.isCrossCompilingEnabled(): + if not disableHostBuild: + os.putenv( "EMERGE_BUILD_STEP", "host" ) + success = success and doExec( category, package, version, "compile", opts ) + success = success and doExec( category, package, version, "cleanimage", opts ) + success = success and doExec( category, package, version, "install", opts ) + if ( buildAction == "all" ): + success = success and doExec( category, package, version, "manifest", opts ) + if ( buildAction == "all" ): + success = success and doExec( category, package, version, "qmerge", opts ) + if( buildAction == "full-package" ): + success = success and doExec( category, package, version, "package", opts ) + if disableTargetBuild: + return success + os.putenv( "EMERGE_BUILD_STEP", "target" ) + + success = success and doExec( category, package, version, "compile", opts ) + success = success and doExec( category, package, version, "cleanimage", opts ) + success = success and doExec( category, package, version, "install", opts ) + if ( buildAction == "all" ): + success = success and doExec( category, package, version, "manifest", opts ) + if ( buildAction == "all" ): + success = success and doExec( category, package, version, "qmerge", opts ) + if( buildAction == "full-package" ): + success = success and doExec( category, package, version, "package", opts ) + + elif ( buildAction in [ "fetch", "unpack", "preconfigure", "configure", "compile", "make", "qmerge", "checkdigest", "dumpdeps", + "package", "manifest", "unmerge", "test", "cleanimage", "cleanbuild", "createpatch", "geturls", + "printrev"] and category and package and version ): + os.putenv( "EMERGE_BUILD_STEP", "" ) + success = True + if emergePlatform.isCrossCompilingEnabled(): + if not disableHostBuild: + os.putenv( "EMERGE_BUILD_STEP", "host" ) + success = doExec( category, package, version, buildAction, opts ) + if disableTargetBuild: + return success + os.putenv( "EMERGE_BUILD_STEP", "target" ) + success = success and doExec( category, package, version, buildAction, opts ) + elif ( buildAction == "install" ): + os.putenv( "EMERGE_BUILD_STEP", "" ) + success = True + if emergePlatform.isCrossCompilingEnabled(): + if not disableHostBuild: + os.putenv( "EMERGE_BUILD_STEP", "host" ) + success = doExec( category, package, version, "cleanimage", opts ) + success = success and doExec( category, package, version, "install", opts ) + if disableTargetBuild: + return success + os.putenv( "EMERGE_BUILD_STEP", "target" ) + success = success and doExec( category, package, version, "cleanimage", opts ) + success = success and doExec( category, package, version, "install", opts ) + elif ( buildAction == "version-dir" ): + print("%s-%s" % ( package, version )) + success = True + elif ( buildAction == "version-package" ): + print("%s-%s-%s" % ( package, os.getenv( "KDECOMPILER" ), version )) + success = True + elif ( buildAction == "print-installable" ): + portage.printInstallables() + success = True + elif ( buildAction == "print-installed" ): + if isDBEnabled(): + printInstalled() + else: + portage.printInstalled() + success = True + elif ( buildAction == "print-targets" ): + portage.printTargets( category, package, version ) + success = True + elif ( buildAction == "install-deps" ): + success = True + else: + success = utils.error( "could not understand this buildAction: %s" % buildAction ) + + return success + +# +# "main" action starts here +# + +# TODO: all the rest should go into main(). But here I am not +# sure - maybe some of those variables are actually MEANT to +# be used in other modules. Put this back for now + +# but as a temporary solution rename variables to mainXXX +# where it is safe so there are less redefinitions in inner scopes + +utils.startTimer("Emerge") +tittleThread = threading.Thread(target=updateTitle,args = (datetime.datetime.now()," ".join(sys.argv[1:]),)) +tittleThread.setDaemon(True) +tittleThread.start() + + +mainBuildAction = "all" +packageName = None +doPretend = False +outDateVCS = False +outDatePackage = False +stayQuiet = False +disableHostBuild = False +disableTargetBuild = False +ignoreInstalled = False +updateAll = False +continueFlag = False + +if len( sys.argv ) < 2: + usage() + utils.die("") + +environ = dict() # TODO: why do we need this at all? +environ["EMERGE_TRACE"] = os.getenv( "EMERGE_TRACE" ) +environ["EMERGE_BUILDTESTS"] = os.getenv( "EMERGE_BUILDTESTS" ) +environ["EMERGE_OFFLINE"] = os.getenv( "EMERGE_OFFLINE" ) +environ["EMERGE_FORCED"] = os.getenv( "EMERGE_FORCED" ) +environ["EMERGE_VERSION"] = os.getenv( "EMERGE_VERSION" ) +environ["EMERGE_BUILDTYPE"] = os.getenv( "EMERGE_BUILDTYPE" ) +environ["EMERGE_TARGET"] = os.getenv( "EMERGE_TARGET" ) +environ["EMERGE_PKGPATCHLVL"] = os.getenv( "EMERGE_PKGPATCHLVL" ) +environ["EMERGE_LOG_DIR"] = os.getenv( "EMERGE_LOG_DIR" ) + +if environ['EMERGE_TRACE'] == None or not environ['EMERGE_TRACE'].isdigit(): + trace = 0 + os.environ["EMERGE_TRACE"] = str( trace ) +else: + trace = int( environ[ "EMERGE_TRACE" ] ) + +mainOpts = list() + +executableName = sys.argv.pop( 0 ) +nextArguments = sys.argv[:] + +for i in sys.argv: + nextArguments.pop(0) + if ( i == "-p" or i == "--probe" ): + doPretend = True + elif ( i.startswith("--options=") ): + # @todo how to add -o option + options = i.replace( "--options=", "" ) + if "EMERGE_OPTIONS" in os.environ: + os.environ["EMERGE_OPTIONS"] += " %s" % options + else: + os.environ["EMERGE_OPTIONS"] = options + elif ( i == "-z" ): + outDateVCS = True + elif ( i == "-sz" ): + outDatePackage = True + elif ( i == "-q" ): + stayQuiet = True + elif ( i == "-t" ): + os.environ["EMERGE_BUILDTESTS"] = "True" + elif i == "-c" or i == "--continue": + continueFlag = True + elif ( i == "--offline" ): + mainOpts.append( "--offline" ) + os.environ["EMERGE_OFFLINE"] = "True" + elif ( i == "-f" or i == "--force" ): + os.environ["EMERGE_FORCED"] = "True" + elif ( i.startswith( "--buildtype=" ) ): + os.environ["EMERGE_BUILDTYPE"] = i.replace( "--buildtype=", "" ) + elif ( i.startswith( "--target=" ) ): + os.environ["EMERGE_TARGET"] = i.replace( "--target=", "" ) + elif ( i.startswith( "--patchlevel=" ) ): + os.environ["EMERGE_PKGPATCHLVL"] = i.replace( "--patchlevel=", "" ) + elif ( i.startswith( "--log-dir=" ) ): + os.environ["EMERGE_LOG_DIR"] = i.replace( "--log-dir=", "" ) + elif ( i == "-v" ): + utils.Verbose.increase() + elif ( i == "--trace" ): + trace = trace + 1 + os.environ["EMERGE_TRACE"] = str( trace ) + elif ( i == "--nocopy" ): + os.environ["EMERGE_NOCOPY"] = str( True ) + elif ( i == "--noclean" ): + os.environ["EMERGE_NOCLEAN"] = str( True ) + elif ( i == "--clean" ): + os.environ["EMERGE_NOCLEAN"] = str( False ) + elif ( i in [ "--version-dir", "--version-package", "--print-installable", + "--print-installed", "--print-targets" ] ): + mainBuildAction = i[2:] + stayQuiet = True + if i in [ "--print-installable", "--print-installed" ]: + break + elif ( i == "-i" ): + ignoreInstalled = True + elif ( i == "--update" ): + ignoreInstalled = True + os.environ["EMERGE_NOCLEAN"] = str( True ) + elif ( i == "--update-all" ): + ignoreInstalled = True + os.environ["EMERGE_NOCLEAN"] = str( True ) + updateAll = True + elif ( i == "--install-deps" ): + ignoreInstalled = True + mainBuildAction = "install-deps" + elif ( i in [ "--fetch", "--unpack", "--preconfigure", "--configure", "--compile", "--make", + "--install", "--qmerge", "--manifest", "--package", "--unmerge", "--test", "--checkdigest", "--dumpdeps", + "--full-package", "--cleanimage", "--cleanbuild", "--createpatch", "--geturls"] ): + mainBuildAction = i[2:] + elif ( i == "--print-revision" ): + mainBuildAction = "printrev" + elif ( i == "--disable-buildhost" ): + disableHostBuild = True + elif ( i == "--disable-buildtarget" ): + disableTargetBuild = True + elif( i == "--cleanup" ): + utils.debug("Starting to clean emerge" ) + utils.system("cd %s && git clean -f -x -e *.py -e *.diff -e *.ba\\t -e *.cmd -e *.reg" % os.path.join(os.getenv("KDEROOT"),"emerge") ) + exit(0) + elif( i == "--cleanup-dry" ): + utils.debug("Starting to clean emerge" ) + utils.system("cd %s && git clean --dry-run -x -e *.py -e *.diff -e *.ba\\t -e *.cmd -e *.reg" % os.path.join(os.getenv("KDEROOT"),"emerge") ) + exit(0) + elif i == "--cleanallbuilds": + # clean complete build directory + utils.cleanDirectory(os.path.join( os.getenv("KDEROOT"), "build")) + exit(0) + elif ( i == "--search" ): + package = nextArguments.pop(0) + category = "" + if not package.find("/") == -1: + (category,package) = package.split("/") + portageSearch.printSearch(category, package) + exit(0) + elif ( i.startswith( "-" ) ): + usage() + exit ( 1 ) + else: + packageName = i + break + +if stayQuiet == True: + utils.setVerbose(0) + +# get KDEROOT from env +KDEROOT = os.getenv( "KDEROOT" ) +utils.debug( "buildAction: %s" % mainBuildAction ) +utils.debug( "doPretend: %s" % doPretend, 1 ) +utils.debug( "packageName: %s" % packageName ) +utils.debug( "buildType: %s" % os.getenv( "EMERGE_BUILDTYPE" ) ) +utils.debug( "buildTests: %s" % utils.envAsBool( "EMERGE_BUILDTESTS" ) ) +utils.debug( "verbose: %d" % utils.verbose(), 1 ) +utils.debug( "trace: %s" % os.getenv( "EMERGE_TRACE" ), 1 ) +utils.debug( "KDEROOT: %s\n" % KDEROOT, 1 ) +utils.debug_line() + +def unset_var( varname ): + if not os.getenv( varname ) == None: + print() + utils.warning( "%s found as environment variable. you cannot override emerge"\ + " with this - unsetting %s locally" % ( varname, varname ) ) + os.environ[ varname ] = "" + +unset_var( "CMAKE_INCLUDE_PATH" ) +unset_var( "CMAKE_LIBRARY_PATH" ) +unset_var( "CMAKE_FIND_PREFIX" ) +unset_var( "CMAKE_INSTALL_PREFIX" ) + +# adding emerge/bin to find base.py and gnuwin32.py etc. +os.environ["PYTHONPATH"] = os.getenv( "PYTHONPATH", "" ) + os.pathsep + \ + os.path.join( os.getcwd(), os.path.dirname( executableName ) ) +sys.path.append( os.path.join( os.getcwd(), os.path.dirname( executableName ) ) ) + +_deplist = [] +deplist = [] +packageList = [] +categoryList = [] + + +buildType = os.getenv("EMERGE_BUILDTYPE") +if "EMERGE_DEFAULTCATEGORY" in os.environ: + defaultCategory = os.environ["EMERGE_DEFAULTCATEGORY"] +else: + defaultCategory = "kde" + +if updateAll: + installedPackages = portage.PortageInstance.getInstallables() + if portage.PortageInstance.isCategory( packageName ): + utils.debug( "Updating installed packages from category " + packageName, 1 ) + else: + utils.debug( "Updating all installed packages", 1 ) + packageList = [] + for mainCategory, mainPackage, mainVersion in installedPackages: + if portage.PortageInstance.isCategory( packageName ) and ( mainCategory != packageName ): + continue + if portage.isInstalled( mainCategory, mainPackage, mainVersion, buildType ) \ + and portage.isPackageUpdateable( mainCategory, mainPackage, mainVersion ): + categoryList.append( mainCategory ) + packageList.append( mainPackage ) + utils.debug( "Will update packages: " + str (packageList), 1 ) +elif packageName: + packageList, categoryList = portage.getPackagesCategories(packageName) + +for entry in packageList: + utils.debug( "%s" % entry, 1 ) +utils.debug_line( 1 ) + +for mainCategory, entry in zip (categoryList, packageList): + _deplist = portage.solveDependencies( mainCategory, entry, "", _deplist ) + +deplist = [p.ident() for p in _deplist] + +for item in range( len( deplist ) ): + if deplist[ item ][ 0 ] in categoryList and deplist[ item ][ 1 ] in packageList: + deplist[ item ].append( ignoreInstalled ) + else: + deplist[ item ].append( False ) + + utils.debug( "dependency: %s" % deplist[ item ], 1 ) + +#for item in deplist: +# cat = item[ 0 ] +# pac = item[ 1 ] +# ver = item[ 2 ] + +# if portage.isInstalled( cat, pac, ver, buildType) and updateAll and not portage.isPackageUpdateable( cat, pac, ver ): +# print "remove:", cat, pac, ver +# deplist.remove( item ) + +if mainBuildAction == "install-deps": + # the first dependency is the package itself - ignore it + # TODO: why are we our own dependency? + del deplist[ 0 ] + +deplist.reverse() + +# package[0] -> category +# package[1] -> package +# package[2] -> version + +if ( mainBuildAction != "all" and mainBuildAction != "install-deps" ): + # if a buildAction is given, then do not try to build dependencies + # and do the action although the package might already be installed. + # This is still a bit problematic since packageName might not be a valid + # package + + if packageName and len( deplist ) >= 1: + mainCategory, mainPackage, mainVersion, tag, ignoreInstalled = deplist[ -1 ] + else: + mainCategory, mainPackage, mainVersion = None, None, None + + if not handlePackage( mainCategory, mainPackage, mainVersion, mainBuildAction, mainOpts ): + utils.notify("Emerge %s failed" % mainBuildAction, "%s of %s/%s-%s failed" % ( mainBuildAction,mainCategory, mainPackage, mainVersion),mainBuildAction) + exit(1) + utils.notify("Emerge %s finished"% mainBuildAction, "%s of %s/%s-%s finished" % ( mainBuildAction,mainCategory, mainPackage, mainVersion),mainBuildAction) + +else: + for mainCategory, mainPackage, mainVersion, defaultTarget, ignoreInstalled in deplist: + target = "" + targetList = [] + isLastPackage = [mainCategory, mainPackage, mainVersion, defaultTarget, ignoreInstalled] == deplist[-1] + if outDateVCS or (outDatePackage and isLastPackage): + target = os.getenv( "EMERGE_TARGET" ) + if not target or target not in list(portage.PortageInstance.getAllTargets( mainCategory, mainPackage, mainVersion ).keys()): + # if no target or a wrong one is defined, simply set the default target here + target = defaultTarget + targetList = portage.PortageInstance.getUpdatableVCSTargets( mainCategory, mainPackage, mainVersion ) + if isDBEnabled(): + if emergePlatform.isCrossCompilingEnabled(): + hostEnabled = portage.isHostBuildEnabled( mainCategory, mainPackage, mainVersion ) + targetEnabled = portage.isTargetBuildEnabled( mainCategory, mainPackage, mainVersion ) + hostInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, "" ) + targetInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, os.getenv( "EMERGE_TARGET_PLATFORM" ) ) + isInstalled = ( not hostEnabled or hostInstalled ) and ( not targetEnabled or targetInstalled ) + else: + isInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, "" ) + else: + isInstalled = portage.isInstalled( mainCategory, mainPackage, mainVersion, buildType ) + if ( isInstalled and not ignoreInstalled ) and not ( + isInstalled and (outDateVCS or (outDatePackage and isLastPackage) ) and target in targetList ): + if utils.verbose() > 1 and mainPackage == packageName: + utils.warning( "already installed %s/%s-%s" % ( mainCategory, mainPackage, mainVersion ) ) + elif utils.verbose() > 2 and not mainPackage == packageName: + utils.warning( "already installed %s/%s-%s" % ( mainCategory, mainPackage, mainVersion ) ) + else: + # in case we only want to see which packages are still to be build, simply return the package name + if ( doPretend ): + if utils.verbose() > 0: + msg = " " + if emergePlatform.isCrossCompilingEnabled(): + if isDBEnabled(): + hostEnabled = portage.isHostBuildEnabled( mainCategory, mainPackage, mainVersion ) + targetEnabled = portage.isTargetBuildEnabled( mainCategory, mainPackage, mainVersion ) + hostInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, "" ) + targetInstalled = installdb.isInstalled( mainCategory, mainPackage, mainVersion, os.getenv( "EMERGE_TARGET_PLATFORM" ) ) + msg += portage.getHostAndTarget( hostEnabled and not hostInstalled, targetEnabled and not targetInstalled ) + else: + msg = "" + utils.warning( "pretending %s/%s-%s%s" % ( mainCategory, mainPackage, mainVersion, msg ) ) + else: + mainAction = mainBuildAction + if mainBuildAction == "install-deps": + mainAction = "all" + + if not handlePackage( mainCategory, mainPackage, mainVersion, mainAction, mainOpts ): + utils.error( "fatal error: package %s/%s-%s %s failed" % \ + ( mainCategory, mainPackage, mainVersion, mainBuildAction ) ) + utils.notify("Emerge build failed", "Build of %s/%s-%s failed" % ( mainCategory, mainPackage, mainVersion),mainAction) + exit( 1 ) + utils.notify("Emerge build finished", "Build of %s/%s-%s finished" % ( mainCategory, mainPackage, mainVersion),mainAction) + +utils.new_line() +if len( nextArguments ) > 0: + command = "\"" + sys.executable + "\" -u " + executableName + " " + " ".join( nextArguments ) + + #for element in environ.keys(): + # if environ[ element ]: + # os.environ[ element ] = environ[ element ] + # elif element == "EMERGE_VERBOSE": + # os.environ[ element ] = "1" + # else: + # os.environ[ element ] = "" + if not utils.system(command): + utils.die( "cannot execute next commands cmd: %s" % command ) + +utils.stopTimer("Emerge") +