Пример #1
0
    def generateResourceInfoCode(self, script, settings, libraries, format=False):

        def addResourceInfoToPackages(script):
            for package in script.packages:
                package_resources = []
                # TODO: the next is a hack, since package.classes are still id's
                package_classes   = [x for x in script.classesObj if x.id in package.classes]
                for clazz in package_classes:
                    package_resources.extend(clazz.resources)
                package.data.resources = Script.createResourceStruct(package_resources, formatAsTree=resources_tree,
                                                             updateOnlyExistingSprites=True)
            return


        # -- main --------------------------------------------------------------

        compConf       = self._job.get ("compile-options")
        compConf       = ExtMap (compConf)
        resources_tree = compConf.get ("code/resources-tree", False)

        classes = Class.mapResourcesToClasses (libraries, script.classesObj,
                                            self._job.get("asset-let", {}))
        filteredResources = []
        for clazz in classes:
            filteredResources.extend(clazz.resources)
        resdata = Script.createResourceStruct (filteredResources, formatAsTree=resources_tree,
                                           updateOnlyExistingSprites=True)
        # add resource info to packages
        addResourceInfoToPackages(script)

        return resdata # end: generateResourceInfoCode()
Пример #2
0
def runResources(confObj, script):
    jobconf = script.jobconfig
    if not jobconf.get("copy-resources", False):
        return
    console = Context.console

    console.info("Copying resources...")
    classList = script.classesObj
    resTargetRoot = jobconf.get("copy-resources/target", "build")
    resTargetRoot = confObj.absPath(resTargetRoot)
    #generator.approot  = resTargetRoot  # doesn't seem necessary anymore

    # map resources to class.resources
    classList = Class.mapResourcesToClasses(script.libraries, classList,
                                            jobconf.get("asset-let", {}))

    console.indent()
    # make resources to copy unique
    resources_to_copy = set(_res for cls in classList
                            for _res in cls.resources)
    # Copy resources
    #for lib in libs:
    for res in resources_to_copy:
        # construct target path
        resTarget = os.path.join(resTargetRoot, 'resource', res.id)
        # Copy
        _copyResources(res.path, os.path.dirname(resTarget))

    console.outdent()
Пример #3
0
def runResources(confObj, script):
    jobconf = script.jobconfig
    if not jobconf.get("copy-resources", False):
        return
    console = Context.console

    console.info("Copying resources...")
    classList = script.classesObj
    resTargetRoot = jobconf.get("copy-resources/target", "build")
    resTargetRoot = confObj.absPath(resTargetRoot)
    # generator.approot  = resTargetRoot  # doesn't seem necessary anymore

    # map resources to class.resources
    classList = Class.mapResourcesToClasses(script.libraries, classList, jobconf.get("asset-let", {}))

    console.indent()
    # make resources to copy unique
    resources_to_copy = set(_res for cls in classList for _res in cls.resources)
    # Copy resources
    # for lib in libs:
    for res in resources_to_copy:
        # construct target path
        resTarget = os.path.join(resTargetRoot, "resource", res.id)
        # Copy
        _copyResources(res.path, os.path.dirname(resTarget))

    console.outdent()
Пример #4
0
    def makeClassObj(self, filePathId, filePath, props):
        ##
        # provide a default context dict
        def get_contextdict():
            contextdict = {}
            contextdict["console"] = context.console
            contextdict["cache"] = context.cache
            contextdict["jobconf"] = context.jobconf
            contextdict["envchecksmap"] = {}
            return contextdict

        # -----------------------------------------------------------------------
        contextdict = get_contextdict(
        )  # TODO: Clazz() still relies on a context dict!
        if filePathId == "qx.core.Environment":
            clazz = qcEnvClass(filePathId, filePath, self, contextdict)
        else:
            clazz = Class(filePathId, filePath, self, contextdict)

        # extract code ID (e.g. class name, mixin name, ...)
        #fileCodeId = self.checkClassId(clazz, filePathId)  # involves parsing

        clazz.encoding = props.fileEncoding
        clazz.size = props.fileSize  # dependency logging uses this
        clazz.package = props.filePackage  # Apiloader uses this
        clazz.relpath = props.fileRel  # Locale uses this
        clazz.m_time_ = props.fileStat.st_mtime

        return clazz, filePathId
Пример #5
0
    def packagesResourceInfo(self, script):
        classes = Class.mapResourcesToClasses (script.libraries, script.classesObj,
                                            self._job.get("asset-let", {}))

        for package in script.packages:
            package_resources = []
            package_classes   = package.classes
            for clazz in package_classes:
                package_resources.extend(clazz.resources)
            package.data.resources = Script.createResourceStruct(package_resources, formatAsTree=False,
                                                         updateOnlyExistingSprites=True)
        return script
Пример #6
0
    def makeClassObj(self, filePathId, filePath, props):
        ##
        # provide a default context dict
        def get_contextdict():
            contextdict = {}
            contextdict["console"] = context.console
            contextdict["cache"] = context.cache
            contextdict["jobconf"] = context.jobconf
            contextdict["envchecksmap"] = {}
            return contextdict

        # -----------------------------------------------------------------------
        contextdict = get_contextdict() # TODO: Clazz() still relies on a context dict!
        if filePathId == "qx.core.Environment":
            clazz = qcEnvClass(filePathId, filePath, self, contextdict)
        else:
            clazz = Class(filePathId, filePath, self, contextdict)

        # extract code ID (e.g. class name, mixin name, ...)
        #fileCodeId = self.checkClassId(clazz, filePathId)  # involves parsing

        clazz.encoding = props.fileEncoding
        clazz.size     = props.fileSize     # dependency logging uses this
        clazz.package  = props.filePackage  # Apiloader uses this
        clazz.relpath  = props.fileRel       # Locale uses this
        clazz.m_time_  = props.fileStat.st_mtime

        return clazz, filePathId
Пример #7
0
    def _checkCache(self, fileId, variants, optimize, format=False):
        filePath = self._classes[fileId].path

        classVariants     = self._classes[fileId].classVariants()
        relevantVariants  = Class.projectClassVariantsToCurrent(classVariants, variants)
        variantsId = util.toString(relevantVariants)

        optimizeId = self.generateOptimizeId(optimize)

        cacheId = "compiled-%s-%s-%s-%s" % (filePath, variantsId, optimizeId, format)
        compiled, _ = self._cache.read(cacheId, filePath)

        return cacheId, compiled
Пример #8
0
    def checkCache(self, fileId, variants, optimize, format=False):
        filePath = self._classes[fileId]["path"]

        classVariants     = self._classesObj[fileId].classVariants()
        relevantVariants  = Class.projectClassVariantsToCurrent(classVariants, variants)
        variantsId = util.toString(relevantVariants)

        optimizeId = self.generateOptimizeId(optimize)

        cacheId = "compiled-%s-%s-%s-%s" % (filePath, variantsId, optimizeId, format)
        compiled, _ = self._cache.read(cacheId, filePath)

        return cacheId, compiled
Пример #9
0
 def dependencies(self, classId, classPath, variantSet, force=False):
     print "\nrunning on Pyro server", str(self.num)
     c = Class(classId, classPath, None, generator_context, self.classList)
     d, cached = c.dependencies(variantSet, force)
     return d, cached
Пример #10
0
    def _scanClassPath(self, timeOfLastScan=0):

        codeIdFromTree = True  # switch between regex- and tree-based codeId search

        # Check class path
        classPath = os.path.join(self.path, self.classPath)
        if not os.path.isdir(classPath):
            raise ConfigurationError("Class path from Manifest doesn't exist: %s" % self.classPath)

        # Check multiple namespaces
        if not len([d for d in os.listdir(classPath) if not d.startswith(".")]) == 1:
            self._console.warn(
                "The class path must contain exactly one namespace; ignoring everything else: '%s'" % (classPath,)
            )

        # Check Manifest namespace matches file system
        nsPrefix = self.namespace.replace(".", os.sep)
        classNSRoot = os.path.join(classPath, nsPrefix)
        if not os.path.isdir(classNSRoot):
            raise ValueError("Manifest namespace does not exist on file system:  '%s'" % (classNSRoot))

        self._console.debug("Scanning class folder...")

        classList = []
        existClassIds = dict([(x.id, x) for x in self._classes])  # if we scanned before
        docs = {}

        # TODO: Clazz still relies on a context dict!
        contextdict = {}
        contextdict["console"] = context.console
        contextdict["cache"] = context.cache
        contextdict["jobconf"] = context.jobconf
        contextdict["envchecksmap"] = {}

        # Iterate...
        for root, dirs, files in filetool.walk(classNSRoot):
            # Filter ignored directories
            for ignoredDir in dirs:
                if self._ignoredDirEntries.match(ignoredDir):
                    dirs.remove(ignoredDir)

            # Add good directories
            currNameSpace = root[len(classNSRoot + os.sep) :]
            currNameSpace = currNameSpace.replace(os.sep, ".")

            # Searching for files
            for fileName in files:
                # Ignore dot files
                if fileName.startswith(".") or self._ignoredDirEntries.match(fileName):
                    continue
                self._console.dot()

                # Process path data
                filePath = os.path.join(root, fileName)
                fileRel = filePath.replace(classNSRoot + os.sep, "")
                fileExt = os.path.splitext(fileName)[-1]
                fileStat = os.stat(filePath)
                fileSize = fileStat.st_size
                fileMTime = fileStat.st_mtime

                # Compute full URI from relative path
                fileUri = self.classUri + "/" + fileRel.replace(os.sep, "/")

                # Compute identifier from relative path
                filePathId = fileRel.replace(fileExt, "").replace(os.sep, ".")
                filePathId = self.namespace + "." + filePathId
                filePathId = unidata.normalize("NFC", filePathId)  # combine combining chars: o" -> ö

                # check if known and fresh
                if filePathId in existClassIds and fileMTime < timeOfLastScan:
                    classList.append(existClassIds[filePathId])
                    # print "re-using existing", filePathId
                    continue  # re-use known class

                # Extract package ID
                filePackage = filePathId[: filePathId.rfind(".")]

                # Handle doc files
                if fileName == self._docFilename:
                    fileFor = filePathId[: filePathId.rfind(".")]
                    docs[filePackage] = {
                        "relpath": fileRel,
                        "path": filePath,
                        "encoding": self.encoding,
                        "namespace": self.namespace,
                        "id": filePathId,
                        "package": filePackage,
                        "size": fileSize,
                    }

                    # Stop further processing
                    continue

                # Ignore non-script
                if os.path.splitext(fileName)[-1] != ".js":
                    continue

                if filePathId == "qx.core.Environment":
                    clazz = qcEnvClass(filePathId, filePath, self, contextdict, self._classesObj)
                else:
                    clazz = Class(filePathId, filePath, self, contextdict, self._classesObj)

                # Extract code ID (e.g. class name, mixin name, ...)
                try:
                    if codeIdFromTree:
                        fileCodeId = self._getCodeId(clazz)
                    else:
                        # Read content
                        fileContent = filetool.read(filePath, self.encoding)
                        fileCodeId = self._getCodeId1(fileContent)
                except ValueError, e:
                    argsList = []
                    for arg in e.args:
                        argsList.append(arg)
                    argsList[0] = argsList[0] + u" (%s)" % fileName
                    e.args = tuple(argsList)
                    raise e

                # Ignore all data files (e.g. translation, doc files, ...)
                if fileCodeId == None:
                    continue

                # Compare path and content
                if fileCodeId != filePathId:
                    self._console.error("Detected conflict between filename and classname!")
                    self._console.indent()
                    self._console.error("Classname: %s" % fileCodeId)
                    self._console.error("Path: %s" % fileRel)
                    self._console.outdent()
                    raise RuntimeError()

                # Store file data
                self._console.debug("Adding class %s" % filePathId)
                clazz.encoding = self.encoding
                clazz.size = fileSize  # dependency logging uses this
                clazz.package = filePackage  # Apiloader uses this
                clazz.relpath = fileRel  # Locale uses this
                clazz.m_time_ = fileStat.st_mtime
                classList.append(clazz)
Пример #11
0
    def _scanClassPath(self, timeOfLastScan=0):

        ##
        # provide a default context dict
        def get_contextdict():
            contextdict = {}
            contextdict["console"] = context.console
            contextdict["cache"] = context.cache
            contextdict["jobconf"] = context.jobconf
            contextdict["envchecksmap"] = {}
            return contextdict

        ##
        # check class path is on file system
        def check_class_path(classRoot):
            if not os.path.isdir(classRoot):
                raise ConfigurationError("Class path from Manifest doesn't exist: %s" % self.classPath)

        ##
        # check single subdirectory from class path
        def check_multiple_namespaces(classRoot):
            if not len([d for d in os.listdir(classRoot) if not d.startswith(".")]) == 1:
                self._console.warn("The class path should contain exactly one namespace: '%s'" % (classRoot,))

        ##
        # check manifest namespace is on file system
        def check_manifest_namespace(classRoot):
            nsPrefix = self.namespace.replace(".", os.sep)
            classNSRoot = os.path.join(classRoot, nsPrefix)
            if not os.path.isdir(classNSRoot):
                raise ValueError("Manifest namespace does not exist on file system:  '%s'" % (classNSRoot))

        # ----------------------------------------------------------------------

        codeIdFromTree = True  # switch between regex- and tree-based codeId search
        classList = []
        existClassIds = dict([(x.id, x) for x in self._classes])  # if we scanned before
        docs = {}
        contextdict = get_contextdict()  # TODO: Clazz() still relies on a context dict!
        classRoot = os.path.join(self.path, self.classPath)

        check_class_path(classRoot)
        check_multiple_namespaces(classRoot)
        check_manifest_namespace(classRoot)

        self._console.debug("Scanning class folder...")

        # Iterate...
        for root, dirs, files in filetool.walk(classRoot):
            # Filter ignored directories
            for ignoredDir in dirs:
                if self._ignoredDirEntries.match(ignoredDir):
                    dirs.remove(ignoredDir)

            # Searching for files
            for fileName in files:
                # ignore dot files
                if fileName.startswith(".") or self._ignoredDirEntries.match(fileName):
                    continue
                self._console.dot()

                # basic attributes
                filePath = os.path.join(root, fileName)  # /foo/bar/baz/source/class/my/space/AppClass.js
                fileRel = filePath.replace(classRoot + os.sep, "")  # my/space/AppClass.js
                fileExt = os.path.splitext(fileName)[-1]  # "js"
                filePathId = fileRel.replace(fileExt, "").replace(os.sep, ".")  # my.space.AppClass
                filePathId = unidata.normalize("NFC", filePathId)  # o" -> ö
                filePackage = filePathId[: filePathId.rfind(".")] if "." in filePathId else ""  # my.space
                fileStat = os.stat(filePath)
                fileSize = fileStat.st_size
                fileMTime = fileStat.st_mtime

                # ignore non-script
                if fileExt != ".js":
                    continue

                # check if known and fresh
                if filePathId in existClassIds and fileMTime < timeOfLastScan:
                    classList.append(existClassIds[filePathId])
                    continue  # re-use known class

                # handle doc files
                if fileName == self._docFilename:
                    docs[filePackage] = {
                        "relpath": fileRel,
                        "path": filePath,
                        "encoding": self.encoding,
                        "namespace": self.namespace,
                        "id": filePathId,
                        "package": filePackage,
                        "size": fileSize,
                    }
                    # stop further processing
                    continue

                if filePathId == "qx.core.Environment":
                    clazz = qcEnvClass(filePathId, filePath, self, contextdict)
                else:
                    clazz = Class(filePathId, filePath, self, contextdict)

                # extract code ID (e.g. class name, mixin name, ...)
                try:
                    if codeIdFromTree:
                        fileCodeId = self._getCodeId(clazz)
                    else:
                        # use regexp
                        fileContent = filetool.read(filePath, self.encoding)
                        fileCodeId = self._getCodeId1(fileContent)
                except ValueError, e:
                    argsList = []
                    for arg in e.args:
                        argsList.append(arg)
                    argsList[0] = argsList[0] + u" (%s)" % fileName
                    e.args = tuple(argsList)
                    raise e

                # ignore all data files (e.g. translation, doc files, ...)
                if fileCodeId == None:
                    continue

                # compare path and content
                if fileCodeId != filePathId:
                    errmsg = [
                        u"Detected conflict between filename and classname!\n",
                        u"    Classname: %s\n" % fileCodeId,
                        u"    Path: %s\n" % filePath,
                    ]
                    raise RuntimeError(u"".join(errmsg))

                # store file data
                self._console.debug("Adding class %s" % filePathId)
                clazz.encoding = self.encoding
                clazz.size = fileSize  # dependency logging uses this
                clazz.package = filePackage  # Apiloader uses this
                clazz.relpath = fileRel  # Locale uses this
                clazz.m_time_ = fileStat.st_mtime
                classList.append(clazz)
Пример #12
0
 def optimizeEnvironmentClass(envClass, compConf):
     assert envClass.id == "qx.core.Environment"
     tree = Class.optimizeEnvironmentClass(envClass, compConf)
     code = Packer().serializeNode(tree, None, [u''], compConf.format)
     code = u''.join(code)
     return code
Пример #13
0
    def depsToProviderFormat(classDepsIter, depsLogConf):
        ##
        # duplicates CodeProvider.passesOutputFilter
        def passesOutputFilter(resId):
            # must match some include expressions
            if not filter(None, [x.search(resId) for x in inclregexps]):  # [None, None, _sre.match, None, _sre.match, ...]
                return False
            # must not match any exclude expressions
            if filter(None, [x.search(resId) for x in exclregexps]):
                return False
            return True

        # ---------------------------------------

        inclregexps = jobconf.get("provider/include", ["*"])
        exclregexps = jobconf.get("provider/exclude", [])
        inclregexps = map(textutil.toRegExp, inclregexps)
        exclregexps = map(textutil.toRegExp, exclregexps)
        replace_dots = depsLogConf.get("json/replace-dots-in", [])
        slashes_keys = 'keys' in replace_dots
        slashes_vals = 'values' in replace_dots

        classToDeps = {}
        # Class deps
        for (packageId, classId, depId, loadOrRun) in classDepsIter:
            if passesOutputFilter(classId):
                if classId not in classToDeps:
                    classToDeps[classId] = {}
                    classToDeps[classId]["load"] = []
                    classToDeps[classId]["run"] = []
                if depId != None:
                    classToDeps[classId][loadOrRun].append(depId)

        if slashes_vals:
            # transform dep items
            for key, val in classToDeps.items():
                newval = []
                for ldep in val["load"]:
                    newdep = ldep.replace(".", "/")
                    newval.append(newdep)
                val["load"] = newval
                newval = []
                for ldep in val["run"]:
                    newdep = ldep.replace(".", "/")
                    newval.append(newdep)
                val["run"] = newval

        # Resource deps
        # class list
        classObjs = [x for x in script.classesObj if x.id in classToDeps.keys()]
        # map resources to class.resources
        classObjs = Class.mapResourcesToClasses(script.libraries, classObjs, jobconf.get("asset-let", {}))

        for clazz in classObjs:
            reskeys = ["/resource/resources#"+x.id for x in clazz.resources]
            classToDeps[clazz.id]["run"].extend(reskeys)

        # Message key deps
        for classId in classToDeps:
            #classKeys, _ = Locale.getTranslation(classId, {})
            classKeys, _ = script.classesAll[classId].messageStrings({})
            transIds  = set(x['id'] for x in classKeys) # get the msgid's, uniquely
            transIds.update(x['plural'] for x in classKeys if 'plural' in x) # add plural keys
            transKeys = ["/translation/i18n-${lang}#" + x for x in transIds]
            classToDeps[classId]["run"].extend(transKeys)

        # CLDR dependency
        for classId in classToDeps:
            if script.classesAll[classId].getHints("cldr"):
                classToDeps[classId]["run"].append("/locale/locale-${lang}#cldr")

        if slashes_keys:
            # transform dep keys ("qx.Class" -> "qx/Class.js")
            for key, val in classToDeps.items():
                if key.find(".")>-1:
                    newkey = key.replace(".", "/")
                    classToDeps[newkey] = classToDeps[key]
                    del classToDeps[key]

        # sort information for each class (for stable output)
        for classvals in classToDeps.values():
            for key in classvals:
                classvals[key] = sorted(classvals[key], reverse=True)

        # write to file
        file_ = depsLogConf.get('json/file', "deps.json")
        console.info("Writing dependency data to file: %s" % file_)
        pretty = depsLogConf.get('json/pretty', None)
        if pretty:
            indent     = 2
            separators = (', ', ': ')
        else:
            indent     = None
            separators = (',', ':')
        filetool.save(file_, json.dumps(classToDeps, sort_keys=True, indent=indent, separators=separators))

        return
Пример #14
0
    def depsToProviderFormat(classDepsIter, depsLogConf):
        ##
        # duplicates CodeProvider.passesOutputFilter
        def passesOutputFilter(resId):
            # must match some include expressions
            if not filter(None, [
                    x.search(resId) for x in inclregexps
            ]):  # [None, None, _sre.match, None, _sre.match, ...]
                return False
            # must not match any exclude expressions
            if filter(None, [x.search(resId) for x in exclregexps]):
                return False
            return True

        # ---------------------------------------

        inclregexps = jobconf.get("provider/include", ["*"])
        exclregexps = jobconf.get("provider/exclude", [])
        inclregexps = map(textutil.toRegExp, inclregexps)
        exclregexps = map(textutil.toRegExp, exclregexps)
        replace_dots = depsLogConf.get("json/replace-dots-in", [])
        slashes_keys = 'keys' in replace_dots
        slashes_vals = 'values' in replace_dots

        classToDeps = {}
        # Class deps
        for (packageId, classId, depId, loadOrRun) in classDepsIter:
            if passesOutputFilter(classId):
                if classId not in classToDeps:
                    classToDeps[classId] = {}
                    classToDeps[classId]["load"] = []
                    classToDeps[classId]["run"] = []
                if depId != None:
                    classToDeps[classId][loadOrRun].append(depId)

        if slashes_vals:
            # transform dep items
            for key, val in classToDeps.items():
                newval = []
                for ldep in val["load"]:
                    newdep = ldep.replace(".", "/")
                    newval.append(newdep)
                val["load"] = newval
                newval = []
                for ldep in val["run"]:
                    newdep = ldep.replace(".", "/")
                    newval.append(newdep)
                val["run"] = newval

        # Resource deps
        # class list
        classObjs = [
            x for x in script.classesObj if x.id in classToDeps.keys()
        ]
        # map resources to class.resources
        classObjs = Class.mapResourcesToClasses(script.libraries, classObjs,
                                                jobconf.get("asset-let", {}))

        for clazz in classObjs:
            reskeys = ["/resource/resources#" + x.id for x in clazz.resources]
            classToDeps[clazz.id]["run"].extend(reskeys)

        # Message key deps
        for classId in classToDeps:
            #classKeys, _ = Locale.getTranslation(classId, {})
            classKeys, _ = script.classesAll[classId].messageStrings({})
            transIds = set(x['id']
                           for x in classKeys)  # get the msgid's, uniquely
            transIds.update(x['plural'] for x in classKeys
                            if 'plural' in x)  # add plural keys
            transKeys = ["/translation/i18n-${lang}#" + x for x in transIds]
            classToDeps[classId]["run"].extend(transKeys)

        # CLDR dependency
        for classId in classToDeps:
            if script.classesAll[classId].getHints("cldr"):
                classToDeps[classId]["run"].append(
                    "/locale/locale-${lang}#cldr")

        if slashes_keys:
            # transform dep keys ("qx.Class" -> "qx/Class.js")
            for key, val in classToDeps.items():
                if key.find(".") > -1:
                    newkey = key.replace(".", "/")
                    classToDeps[newkey] = classToDeps[key]
                    del classToDeps[key]

        # sort information for each class (for stable output)
        for classvals in classToDeps.values():
            for key in classvals:
                classvals[key] = sorted(classvals[key], reverse=True)

        # write to file
        file_ = depsLogConf.get('json/file', "deps.json")
        console.info("Writing dependency data to file: %s" % file_)
        pretty = depsLogConf.get('json/pretty', None)
        if pretty:
            indent = 2
            separators = (', ', ': ')
        else:
            indent = None
            separators = (',', ':')
        filetool.save(
            file_,
            json.dumps(classToDeps,
                       sort_keys=True,
                       indent=indent,
                       separators=separators))

        return
Пример #15
0
    def _scanClassPath(self, timeOfLastScan=0):

        codeIdFromTree = True  # switch between regex- and tree-based codeId search

        # Check class path
        classPath = os.path.join(self.path, self.classPath)
        if not os.path.isdir(classPath):
            raise ConfigurationError(
                "Class path from Manifest doesn't exist: %s" % self.classPath)

        # Check multiple namespaces
        if not len([d for d in os.listdir(classPath) if not d.startswith(".")
                    ]) == 1:
            self._console.warn(
                "The class path must contain exactly one namespace; ignoring everything else: '%s'"
                % (classPath, ))

        # Check Manifest namespace matches file system
        nsPrefix = self.namespace.replace(".", os.sep)
        classNSRoot = os.path.join(classPath, nsPrefix)
        if not os.path.isdir(classNSRoot):
            raise ValueError(
                "Manifest namespace does not exist on file system:  '%s'" %
                (classNSRoot))

        self._console.debug("Scanning class folder...")

        classList = []
        existClassIds = dict([(x.id, x)
                              for x in self._classes])  # if we scanned before
        docs = {}

        # TODO: Clazz still relies on a context dict!
        contextdict = {}
        contextdict["console"] = context.console
        contextdict["cache"] = context.cache
        contextdict["jobconf"] = context.jobconf
        contextdict["envchecksmap"] = {}

        # Iterate...
        for root, dirs, files in filetool.walk(classNSRoot):
            # Filter ignored directories
            for ignoredDir in dirs:
                if self._ignoredDirEntries.match(ignoredDir):
                    dirs.remove(ignoredDir)

            # Add good directories
            currNameSpace = root[len(classNSRoot + os.sep):]
            currNameSpace = currNameSpace.replace(os.sep,
                                                  ".")  # TODO: var name

            # Searching for files
            for fileName in files:
                # Ignore dot files
                if fileName.startswith(".") or self._ignoredDirEntries.match(
                        fileName):
                    continue
                self._console.dot()

                # Process path data
                filePath = os.path.join(root, fileName)
                fileRel = filePath.replace(
                    classNSRoot + os.sep,
                    "")  # now only path fragment *afte* NS
                fileExt = os.path.splitext(fileName)[-1]
                fileStat = os.stat(filePath)
                fileSize = fileStat.st_size
                fileMTime = fileStat.st_mtime

                # Compute full URI from relative path
                fileUri = self.classUri + "/" + fileRel.replace(os.sep, "/")

                # Compute identifier from relative path
                filePathId = fileRel.replace(fileExt, "").replace(os.sep, ".")
                filePathId = self.namespace + "." + filePathId  # e.g. "qx.core.Environment"
                filePathId = unidata.normalize(
                    "NFC", filePathId)  # combine combining chars: o" -> ö
                fileId = nsPrefix + "/" + fileRel  # e.g. "qx/core/Environment.js"

                # check if known and fresh
                if (filePathId in existClassIds
                        and fileMTime < timeOfLastScan):
                    classList.append(existClassIds[filePathId])
                    #print "re-using existing", filePathId
                    continue  # re-use known class

                # Extract package ID
                filePackage = filePathId[:filePathId.rfind(".")]

                # Handle doc files
                if fileName == self._docFilename:
                    fileFor = filePathId[:filePathId.rfind(".")]
                    docs[filePackage] = {
                        "relpath": fileId,
                        "path": filePath,
                        "encoding": self.encoding,
                        "namespace": self.namespace,
                        "id": filePathId,
                        "package": filePackage,
                        "size": fileSize
                    }

                    # Stop further processing
                    continue

                # Ignore non-script
                if os.path.splitext(fileName)[-1] != ".js":
                    continue

                if filePathId == "qx.core.Environment":
                    clazz = qcEnvClass(filePathId, filePath, self, contextdict)
                else:
                    clazz = Class(filePathId, filePath, self, contextdict)

                # Extract code ID (e.g. class name, mixin name, ...)
                try:
                    if codeIdFromTree:
                        fileCodeId = self._getCodeId(clazz)
                    else:
                        # Read content
                        fileContent = filetool.read(filePath, self.encoding)
                        fileCodeId = self._getCodeId1(fileContent)
                except ValueError, e:
                    argsList = []
                    for arg in e.args:
                        argsList.append(arg)
                    argsList[0] = argsList[0] + u' (%s)' % fileName
                    e.args = tuple(argsList)
                    raise e

                # Ignore all data files (e.g. translation, doc files, ...)
                if fileCodeId == None:
                    continue

                # Compare path and content
                if fileCodeId != filePathId:
                    self._console.error(
                        "Detected conflict between filename and classname!")
                    self._console.indent()
                    self._console.error("Classname: %s" % fileCodeId)
                    self._console.error("Path: %s" % filePath)
                    self._console.outdent()
                    raise RuntimeError()

                # Store file data
                self._console.debug("Adding class %s" % filePathId)
                clazz.encoding = self.encoding
                clazz.size = fileSize  # dependency logging uses this
                clazz.package = filePackage  # Apiloader uses this
                clazz.relpath = fileId  # Locale uses this
                clazz.m_time_ = fileStat.st_mtime
                classList.append(clazz)
Пример #16
0
                    # calculate dependencies and add required classes
                    classlistFromClassRecursive(depsItem, excludeWithDeps, variants, result, warn_deps, [], allowBlockLoaddeps)
                    #classlistFromClassIterative(depsItem, excludeWithDeps, variants, result, warn_deps, [], allowBlockLoaddeps)

                self._console.dotclear()
                #print len(result),"  ",

                # process qx.core.Environment
                if ("qx.core.Environment" in resultNames 
                    and "variants" in script.optimize
                    and not processedEnvironment):
                    envObj = self._classesObj["qx.core.Environment"]
                    envTreeId = "tree-%s-%s" % (envObj.path, util.toString({})) # TODO: {} is a temp. hack
                    compOpts = CompileOptions(optimize=[], variants=variants)
                    compOpts.allClassVariants = script.classVariants([self._classesObj[x] for x in resultNames])
                    tree = Class.optimizeEnvironmentClass(envObj, compOpts)
                    self._cache.write(envTreeId, tree, memory=True, writeToFile=False)
                    # this is for the side-effect of leaving a modified tree for qx.core.Environmet
                    # in the cache!
                    _ = envObj.dependencies(variants, force=True)
                    # this is for the side-effect of re-calculating the transitive dependencies
                    # of qx.core.Environment!
                    processedEnvironment = True
                else:
                    # We currently know that one additional iteration is enough,
                    # after optimizeEnvironmentClass() has run. This has to do
                    # with the fact that it only removes dependencies to
                    # qx.bom.client.* classes, which in turn do not use
                    # qx.core.Env calls. So after calculating the new class
                    # list, allClassVariants will not have changed. If it would,
                    # we would need to re-calculate until the class list is
Пример #17
0
 def tree(self, classId, classPath, variantSet):
     c = Class(classId, classPath, None, generator_context, {})
     t = c.tree(variantSet)
     return t
Пример #18
0
    def _scanClassPath(self, path, uri, encoding):
        if not os.path.exists(path):
            raise ValueError("The given class path does not exist: %s" % path)

        self._console.debug("Scanning class folder...")

        classList = {}
        docs = {}

        # Iterate...
        for root, dirs, files in filetool.walk(path):
            # Filter ignored directories
            for ignoredDir in dirs:
                if self._ignoredDirectories.match(ignoredDir):
                    dirs.remove(ignoredDir)

            # Add good directories
            currNameSpace = root[len(path+os.sep):]
            currNameSpace = currNameSpace.replace(os.sep, ".")

            # Searching for files
            for fileName in files:
                # Ignore dot files
                if fileName.startswith("."):
                    continue

                # Process path data
                filePath = os.path.join(root, fileName)
                fileRel  = filePath.replace(path + os.sep, "")
                fileExt  = os.path.splitext(fileName)[-1]
                fileSize = os.stat(filePath).st_size

                # Compute full URI from relative path
                fileUri = uri + "/" + fileRel.replace(os.sep, "/")

                # Compute identifier from relative path
                filePathId = fileRel.replace(fileExt, "").replace(os.sep, ".")

                # Extract package ID
                filePackage = filePathId[:filePathId.rfind(".")]

                # Handle doc files
                if fileName == self._docFilename:
                    fileFor = filePathId[:filePathId.rfind(".")]
                    docs[filePackage] = {
                        "relpath" : fileRel,
                        "path" : filePath,
                        "encoding" : encoding,
                        "namespace" : self.namespace,
                        "id" : filePathId,
                        "package" : filePackage,
                        "size" : fileSize
                    }

                    # Stop further processing
                    continue

                # Ignore non-script
                if os.path.splitext(fileName)[-1] != ".js":
                    continue

                # Read content
                fileContent = filetool.read(filePath, encoding)

                # Extract code ID (e.g. class name, mixin name, ...)
                try:
                    fileCodeId = self._getCodeId(fileContent)
                except ValueError, e:
                    argsList = []
                    for arg in e.args:
                        argsList.append(arg)
                    argsList[0] = argsList[0] + u' (%s)' % fileName
                    e.args = tuple(argsList)
                    raise e

                # Ignore all data files (e.g. translation, doc files, ...)
                if fileCodeId == None:
                    continue

                # Compare path and content
                if fileCodeId != filePathId:
                    self._console.error("Detected conflict between filename and classname!")
                    self._console.indent()
                    self._console.error("Classname: %s" % fileCodeId)
                    self._console.error("Path: %s" % fileRel)
                    self._console.outdent()
                    raise RuntimeError()

                # Store file data
                self._console.debug("Adding class %s" % filePathId)
                classList[filePathId] = {
                    "relpath" : fileRel,
                    "path" : filePath,
                    "encoding" : encoding,
                    "namespace" : self.namespace,
                    "id" : filePathId,
                    "package" : filePackage,
                    "size" : fileSize
                }
                # TODO: Clazz still relies on a context dict!
                contextdict = {}
                contextdict["console"] = context.console
                contextdict["cache"] = context.cache
                contextdict["jobconf"] = context.jobconf
                # TODO: currently creation of throw-away objects (unless they're .append'ed)
                clazz = Class(classList[filePathId], filePath, self, contextdict, self._classesObj)
                clazz.encoding = encoding
                clazz.size     = fileSize     # dependency logging uses this
                clazz.package  = filePackage  # Apiloader uses this
Пример #19
0
 def tree(self, classId, classPath, variantSet):
     c = Class(classId, classPath, None, generator_context, {})
     t = c.tree()
     return t
Пример #20
0
 def dependencies(self, classId, classPath, variantSet, force=False):
     print "\nrunning on Pyro server", str(self.num)
     c = Class(classId, classPath, None, generator_context, self.classList)
     d, cached = c.dependencies(variantSet, force)
     return d, cached
Пример #21
0
    def _scanClassPath(self, path, uri, encoding):
        if not os.path.exists(path):
            raise ValueError("The given class path does not exist: %s" % path)

        self._console.debug("Scanning class folder...")

        classList = {}
        docs = {}

        # Iterate...
        for root, dirs, files in filetool.walk(path):
            # Filter ignored directories
            for ignoredDir in dirs:
                if self._ignoredDirectories.match(ignoredDir):
                    dirs.remove(ignoredDir)

            # Add good directories
            currNameSpace = root[len(path + os.sep):]
            currNameSpace = currNameSpace.replace(os.sep, ".")

            # Searching for files
            for fileName in files:
                # Ignore dot files
                if fileName.startswith("."):
                    continue

                # Process path data
                filePath = os.path.join(root, fileName)
                fileRel = filePath.replace(path + os.sep, "")
                fileExt = os.path.splitext(fileName)[-1]
                fileSize = os.stat(filePath).st_size

                # Compute full URI from relative path
                fileUri = uri + "/" + fileRel.replace(os.sep, "/")

                # Compute identifier from relative path
                filePathId = fileRel.replace(fileExt, "").replace(os.sep, ".")

                # Extract package ID
                filePackage = filePathId[:filePathId.rfind(".")]

                # Handle doc files
                if fileName == self._docFilename:
                    fileFor = filePathId[:filePathId.rfind(".")]
                    docs[filePackage] = {
                        "relpath": fileRel,
                        "path": filePath,
                        "encoding": encoding,
                        "namespace": self.namespace,
                        "id": filePathId,
                        "package": filePackage,
                        "size": fileSize
                    }

                    # Stop further processing
                    continue

                # Ignore non-script
                if os.path.splitext(fileName)[-1] != ".js":
                    continue

                # Read content
                fileContent = filetool.read(filePath, encoding)

                # Extract code ID (e.g. class name, mixin name, ...)
                try:
                    fileCodeId = self._getCodeId(fileContent)
                except ValueError, e:
                    e.args[0] = e.args[0] + u' (%s)' % fileName
                    raise e

                # Ignore all data files (e.g. translation, doc files, ...)
                if fileCodeId == None:
                    continue

                # Compare path and content
                if fileCodeId != filePathId:
                    self._console.error(
                        "Detected conflict between filename and classname!")
                    self._console.indent()
                    self._console.error("Classname: %s" % fileCodeId)
                    self._console.error("filePathId: %s" % filePathId)
                    self._console.error("Path: %s" % fileRel)
                    self._console.outdent()
                    raise RuntimeError()

                # Store file data
                self._console.debug("Adding class %s" % filePathId)
                classList[filePathId] = {
                    "relpath": fileRel,
                    "path": filePath,
                    "encoding": encoding,
                    "namespace": self.namespace,
                    "id": filePathId,
                    "package": filePackage,
                    "size": fileSize
                }
                # TODO: Clazz still relies on a context dict!
                contextdict = {}
                contextdict["console"] = context.console
                contextdict["cache"] = context.cache
                contextdict["jobconf"] = context.jobconf
                # TODO: currently creation of throw-away objects (unless they're .append'ed)
                clazz = Class(classList[filePathId], filePath, self,
                              contextdict, self._classesObj)
                clazz.encoding = encoding
                clazz.size = fileSize  # dependency logging uses this
                clazz.package = filePackage  # Apiloader uses this
Пример #22
0
    def _scanClassPath(self, timeOfLastScan=0):

        ##
        # provide a default context dict
        def get_contextdict():
            contextdict = {}
            contextdict["console"] = context.console
            contextdict["cache"] = context.cache
            contextdict["jobconf"] = context.jobconf
            contextdict["envchecksmap"] = {}
            return contextdict

        ##
        # check class path is on file system
        def check_class_path(classRoot):
            if not os.path.isdir(classRoot):
                raise ConfigurationError(
                    "Class path from Manifest doesn't exist: %s" %
                    self.classPath)

        ##
        # check single subdirectory from class path
        def check_multiple_namespaces(classRoot):
            try:
                self._checkNamespace(classRoot)
            except ValueError:
                self._console.warn(
                    "The class path should contain exactly one namespace: '%s'"
                    % (classRoot, ))

        ##
        # check manifest namespace is on file system
        def check_manifest_namespace(classRoot):
            nsPrefix = self.namespace.replace(".", os.sep)
            classNSRoot = os.path.join(classRoot, nsPrefix)
            if not os.path.isdir(classNSRoot):
                raise ValueError(
                    "Manifest namespace does not exist on file system:  '%s'" %
                    (classNSRoot))

        # ----------------------------------------------------------------------

        codeIdFromTree = True  # switch between regex- and tree-based codeId search
        classList = []
        existClassIds = dict([(x.id, x)
                              for x in self._classes])  # if we scanned before
        docs = {}
        contextdict = get_contextdict(
        )  # TODO: Clazz() still relies on a context dict!
        classRoot = os.path.join(self.path, self.classPath)

        check_class_path(classRoot)
        check_multiple_namespaces(classRoot)
        check_manifest_namespace(classRoot)

        self._console.debug("Scanning class folder...")

        # Iterate...
        for root, dirs, files in filetool.walk(classRoot):
            # Filter ignored directories
            for ignoredDir in dirs:
                if self._ignoredDirEntries.match(ignoredDir):
                    dirs.remove(ignoredDir)

            # Searching for files
            for fileName in files:
                # ignore dot files
                if fileName.startswith(".") or self._ignoredDirEntries.match(
                        fileName):
                    continue
                self._console.dot()

                # basic attributes
                filePath = os.path.join(
                    root,
                    fileName)  # /foo/bar/baz/source/class/my/space/AppClass.js
                fileRel = filePath.replace(classRoot + os.sep,
                                           '')  # my/space/AppClass.js
                fileExt = os.path.splitext(fileName)[-1]  # "js"
                filePathId = fileRel.replace(fileExt, "").replace(
                    os.sep, ".")  # my.space.AppClass
                filePathId = unidata.normalize("NFC", filePathId)  # o" -> ö
                filePackage = filePathId[:filePathId.rfind(
                    ".")] if "." in filePathId else ""  # my.space
                fileStat = os.stat(filePath)
                fileSize = fileStat.st_size
                fileMTime = fileStat.st_mtime

                # ignore non-script
                if fileExt != ".js":
                    continue

                # check if known and fresh
                if (filePathId in existClassIds
                        and fileMTime < timeOfLastScan):
                    classList.append(existClassIds[filePathId])
                    continue  # re-use known class

                # handle doc files
                if fileName == self._docFilename:
                    docs[filePackage] = {
                        "relpath": fileRel,
                        "path": filePath,
                        "encoding": self.encoding,
                        "namespace": self.namespace,
                        "id": filePathId,
                        "package": filePackage,
                        "size": fileSize
                    }
                    # stop further processing
                    continue

                if filePathId == "qx.core.Environment":
                    clazz = qcEnvClass(filePathId, filePath, self, contextdict)
                else:
                    clazz = Class(filePathId, filePath, self, contextdict)

                # extract code ID (e.g. class name, mixin name, ...)
                try:
                    if codeIdFromTree:
                        fileCodeId = self._getCodeId(clazz)
                    else:
                        # use regexp
                        fileContent = filetool.read(filePath, self.encoding)
                        fileCodeId = self._getCodeId1(fileContent)
                except ValueError, e:
                    argsList = []
                    for arg in e.args:
                        argsList.append(arg)
                    argsList[0] = argsList[0] + u' (%s)' % fileName
                    e.args = tuple(argsList)
                    raise e

                # ignore all data files (e.g. translation, doc files, ...)
                if fileCodeId == None:
                    continue

                # compare path and content
                if fileCodeId != filePathId:
                    errmsg = [
                        u"Detected conflict between filename and classname!\n",
                        u"    Classname: %s\n" % fileCodeId,
                        u"    Path: %s\n" % filePath,
                    ]
                    raise RuntimeError(u''.join(errmsg))

                # store file data
                self._console.debug("Adding class %s" % filePathId)
                clazz.encoding = self.encoding
                clazz.size = fileSize  # dependency logging uses this
                clazz.package = filePackage  # Apiloader uses this
                clazz.relpath = fileRel  # Locale uses this
                clazz.m_time_ = fileStat.st_mtime
                classList.append(clazz)