Beispiel #1
0
    def processAnimations(self):
        """Processes jasyanimation files to merge animation data into asset registry."""

        assets = self.__assets
        configs = [fileId for fileId in assets if assets[fileId].isImageAnimationConfig()]

        if configs:
            Console.info("Processing %s...", Console.colorize("%s animations", "magenta") % len(configs))

        Console.indent()
        for fileId in configs:
            Console.debug("Processing %s...", fileId)

            asset = assets[fileId]
            base = os.path.dirname(fileId)

            try:
                config = asset.getParsedObject()
            except ValueError as err:
                raise UserError("Could not parse jasyanimation at %s: %s" % (fileId, err))

            for relPath in config:
                imageId = "%s/%s" % (base, relPath)
                data = config[relPath]

                if imageId not in assets:
                    raise UserError("Unknown asset %s in %s" % (imageId, fileId))

                animationAsset = assets[imageId]

                if "rows" in data or "columns" in data:
                    rows = Util.getKey(data, "rows", 1)
                    columns = Util.getKey(data, "columns", 1)
                    frames = Util.getKey(data, "frames")

                    animationAsset.addImageAnimationData(columns, rows, frames)

                    if frames is None:
                        frames = rows * columns

                elif "layout" in data:
                    layout = data["layout"]
                    animationAsset.addImageAnimationData(None, None, layout=layout)
                    frames = len(layout)

                else:
                    raise UserError("Invalid image frame data for: %s" % imageId)

                Console.debug("  - Animation %s has %s frames", imageId, frames)

            Console.debug("  - Deleting animation config from assets: %s", fileId)
            del assets[fileId]

        Console.outdent()
Beispiel #2
0
    def expandFileName(self, fileName):
        """
        Replaces placeholders inside the given filename and returns the result. The placeholders are based on the
        current state of the session.

        These are the currently supported placeholders:

        - {{locale}}: Name of current locale e.g. de_DE
        - {{permutation}}: SHA1 checksum of current permutation
        - {{id}}: SHA1 checksum based on permutation and repository branch/revision

        """

        if "{{destination}}" in fileName:
            fileName = fileName.replace("{{destination}}", self.getDestinationPath())

        if self.__permutation:
            if "{{permutation}}" in fileName:
                fileName = fileName.replace("{{permutation}}", self.__permutation.getChecksum())

            if "{{id}}" in fileName:
                buildId = "%s@%s" % (self.__permutation.getKey(), self.__session.getMain().getRevision())
                buildHash = Util.generateChecksum(buildId)
                fileName = fileName.replace("{{id}}", buildHash)

            if "{{locale}}" in fileName:
                locale = self.__permutation.get("locale")
                fileName = fileName.replace("{{locale}}", locale)

        elif "{{id}}" in fileName:
            fileName = fileName.replace("{{id}}", "none@%s" % (self.__session.getMain().getRevision()))

        return fileName
Beispiel #3
0
def printTasks(indent=16):
    """Prints out a list of all avaible tasks and their descriptions."""

    for name in sorted(__taskRegistry):
        obj = __taskRegistry[name]

        formattedName = name
        if obj.__doc__:
            space = (indent - len(name)) * " "
            print("    %s: %s%s" % (formattedName, space, Console.colorize(obj.__doc__, "magenta")))
        else:
            print("    %s" % formattedName)

        if obj.availableArgs or obj.hasFlexArgs:
            text = ""
            if obj.availableArgs:
                text += Util.hyphenate("--%s <var>" % " <var> --".join(obj.availableArgs))

            if obj.hasFlexArgs:
                if text:
                    text += " ..."
                else:
                    text += "--<name> <var>"

            print("      %s" % (Console.colorize(text, "grey")))
Beispiel #4
0
    def setId(self, id):

        super().setId(id)

        self.extension = os.path.splitext(self.id.lower())[1]
        self.type = Util.getKey(AssetExtensions, self.extension, "other")
        self.shortType = self.type[0]
Beispiel #5
0
    def setId(self, id):

        super().setId(id)

        self.extension = os.path.splitext(self.id.lower())[1]
        self.type = Util.getKey(AssetExtensions, self.extension, "other")
        self.shortType = self.type[0]
Beispiel #6
0
    def __getFilteredPages(self, currentItem):
        """Return sorted list of only pages of same language and not hidden."""

        pages = self.__pages
        currentLang = currentItem["lang"]
        pageList = [pageItem for pageItem in pages if pageItem["lang"] == currentLang and not pageItem["status"] == "hidden"]

        return sorted(pageList, key=lambda pageItem: JasyUtil.getKey(pageItem, "pos", 1000000))
Beispiel #7
0
    def __init__(self):

        atexit.register(self.close)

        # Behaves like Date.now() in JavaScript: UTC date in milliseconds
        self.__timeStamp = int(round(time.time() * 1000))
        self.__timeHash = Util.generateChecksum(str(self.__timeStamp))

        self.__projects = []
        self.__fields = {}
        self.__translationBundles = {}
Beispiel #8
0
def executeTask(taskname, **kwargs):
    """Executes the given task by name with any optional named arguments."""

    if taskname in __taskRegistry:
        try:
            camelCaseArgs = {Util.camelize(key) : kwargs[key] for key in kwargs}
            return __taskRegistry[taskname](**camelCaseArgs)
        except UserError as err:
            raise
        except:
            Console.error("Unexpected error! Could not finish task %s successfully!" % taskname)
            raise
    else:
        raise UserError("No such task: %s" % taskname)
Beispiel #9
0
    def expandFileName(self, fileName):
        """
        Replaces placeholders inside the given filename and returns the result. The placeholders are based on the
        current state of the session.

        These are the currently supported placeholders:

        - {{locale}}: Name of current locale e.g. de_DE
        - {{permutation}}: SHA1 checksum of current permutation
        - {{id}}: SHA1 checksum based on permutation and repository branch/revision

        """

        if "{{destination}}" in fileName:
            fileName = fileName.replace("{{destination}}",
                                        self.getDestinationPath())

        if self.__permutation:
            if "{{permutation}}" in fileName:
                fileName = fileName.replace("{{permutation}}",
                                            self.__permutation.getChecksum())

            if "{{id}}" in fileName:
                buildId = "%s@%s" % (self.__permutation.getKey(),
                                     self.__session.getMain().getRevision())
                buildHash = Util.generateChecksum(buildId)
                fileName = fileName.replace("{{id}}", buildHash)

            if "{{locale}}" in fileName:
                locale = self.__permutation.get("locale")
                fileName = fileName.replace("{{locale}}", locale)

        elif "{{id}}" in fileName:
            fileName = fileName.replace(
                "{{id}}", "none@%s" % (self.__session.getMain().getRevision()))

        return fileName
Beispiel #10
0
def getTargetFolder(url, version=None):
    """
    Returns the target folder name based on the URL and version using SHA1 checksums.

    :param url: URL to the repository
    :type url: string
    :param version: Version to use
    :type url: string

    """

    if Git.isUrl(url):

        version = Git.expandVersion(version)

        folder = url[url.rindex("/") + 1:]
        if folder.endswith(".git"):
            folder = folder[:-4]

        identifier = "%s@%s" % (url, version)
        version = version[version.rindex("/") + 1:]

    hash = Util.generateChecksum(identifier)
    return "%s-%s-%s" % (folder, version, hash)
Beispiel #11
0
def getTargetFolder(url, version=None):
    """
    Returns the target folder name based on the URL and version using SHA1 checksums.

    :param url: URL to the repository
    :type url: string
    :param version: Version to use
    :type url: string

    """

    if Git.isUrl(url):

        version = Git.expandVersion(version)

        folder = url[url.rindex("/") + 1:]
        if folder.endswith(".git"):
            folder = folder[:-4]

        identifier = "%s@%s" % (url, version)
        version = version[version.rindex("/") + 1:]

    hash = Util.generateChecksum(identifier)
    return "%s-%s-%s" % (folder, version, hash)
Beispiel #12
0
 def __init__(self, combination):
     
     self.__combination = combination
     self.__key = self.__buildKey(combination)
     self.__checksum = Util.generateChecksum(self.__key)
Beispiel #13
0
    def __init__(self, combination):

        self.__combination = combination
        self.__key = self.__buildKey(combination)
        self.__checksum = Util.generateChecksum(self.__key)
Beispiel #14
0
    def processAnimations(self):
        """Processes jasyanimation files to merge animation data into asset registry."""

        assets = self.__assets
        configs = [
            fileId for fileId in assets
            if assets[fileId].isImageAnimationConfig()
        ]

        if configs:
            Console.info(
                "Processing %s...",
                Console.colorize("%s animations", "magenta") % len(configs))

        Console.indent()
        for fileId in configs:
            Console.debug("Processing %s...", fileId)

            asset = assets[fileId]
            base = os.path.dirname(fileId)

            try:
                config = asset.getParsedObject()
            except ValueError as err:
                raise UserError("Could not parse jasyanimation at %s: %s" %
                                (fileId, err))

            for relPath in config:
                imageId = "%s/%s" % (base, relPath)
                data = config[relPath]

                if imageId not in assets:
                    raise UserError("Unknown asset %s in %s" %
                                    (imageId, fileId))

                animationAsset = assets[imageId]

                if "rows" in data or "columns" in data:
                    rows = Util.getKey(data, "rows", 1)
                    columns = Util.getKey(data, "columns", 1)
                    frames = Util.getKey(data, "frames")

                    animationAsset.addImageAnimationData(columns, rows, frames)

                    if frames is None:
                        frames = rows * columns

                elif "layout" in data:
                    layout = data["layout"]
                    animationAsset.addImageAnimationData(None,
                                                         None,
                                                         layout=layout)
                    frames = len(layout)

                else:
                    raise UserError("Invalid image frame data for: %s" %
                                    imageId)

                Console.debug("  - Animation %s has %s frames", imageId,
                              frames)

            Console.debug("  - Deleting animation config from assets: %s",
                          fileId)
            del assets[fileId]

        Console.outdent()
Beispiel #15
0
    def __init__(self, session):

        Console.info("Initializing profile...")
        Console.indent()

        # Reference to global session object
        self.__session = session

        # Initialize data instance
        self.__data = {}

        # Set default values (which require serialization)
        self.setJsOutputFolder("js")
        self.setCssOutputFolder("css")
        self.setAssetOutputFolder("asset")
        self.setTemplateOutputFolder("tmpl")

        self.setCompressionLevel(0)
        self.setFormattingLevel(100)

        # Initialize file manager
        fileManager = self.__fileManager = FileManager.FileManager(self)

        # Enforce scan of projects
        session.scan()

        # Part registry holds information about all parts of the application to build
        self.__parts = {}

        # Copy fields and commands from session
        # This happens to have local access to all of them + being able to add and tweak data locally
        self.__fields = copy.copy(session.getFields())
        self.__commands = copy.copy(session.getCommands())

        # Behaves like Date.now() in JavaScript: UTC date in milliseconds
        self.__timeStamp = int(round(time.time() * 1000))
        self.__timeHash = Util.generateChecksum(str(self.__timeStamp))

        # No further steps when session has no projects e.g. during "distclean"
        if not session.getProjects():
            return

        # Initialize asset manager
        Console.info("Initializing asset manager...")
        Console.indent()
        assetManager = self.__assetManager = AssetManager.AssetManager(self)

        # Registering assets
        for project in self.getProjects():
            assetManager.addProject(project)

        # Enable sprite sheets and image animations
        assetManager.processSprites()
        assetManager.processAnimations()

        Console.outdent()

        # Registering commands
        Console.info("Registering commands...")

        self.addCommand("asset.url",
                        lambda fileId: assetManager.getAssetUrl(fileId), "url")
        self.addCommand("asset.width",
                        lambda fileId: assetManager.getAssetWidth(fileId),
                        "px")
        self.addCommand("asset.height",
                        lambda fileId: assetManager.getAssetHeight(fileId),
                        "px")

        self.addCommand("sprite.url",
                        lambda fileId: assetManager.getSpriteUrl(fileId),
                        "url")
        self.addCommand("sprite.left",
                        lambda fileId: assetManager.getSpriteLeft(fileId),
                        "px")
        self.addCommand("sprite.top",
                        lambda fileId: assetManager.getSpriteTop(fileId), "px")
        self.addCommand("sprite.width",
                        lambda fileId: assetManager.getSpriteWidth(fileId),
                        "px")
        self.addCommand("sprite.height",
                        lambda fileId: assetManager.getSpriteHeight(fileId),
                        "px")

        self.addCommand(
            "animation.columns",
            lambda fileId: assetManager.getAnimationColumns(fileId), "number")
        self.addCommand("animation.rows",
                        lambda fileId: assetManager.getAnimationRows(fileId),
                        "number")
        self.addCommand("animation.frames",
                        lambda fileId: assetManager.getAnimationFrames(fileId),
                        "number")

        Console.outdent()
Beispiel #16
0
    def scan(self):

        if self.scanned:
            return

        updatemsg = "[updated]" if self.__modified else "[cached]"

        if self.version:
            Console.info("Scanning %s @ %s %s...", Console.colorize(self.getName(), "bold"), Console.colorize(self.version, "magenta"), Console.colorize(updatemsg, "grey"))
        else:
            Console.info("Scanning %s %s...", Console.colorize(self.getName(), "bold"), Console.colorize(updatemsg, "grey"))

        Console.indent()

        # Support for pre-initialize projects...
        setup = self.__setup
        if setup and self.__modified:
            Console.info("Running setup...")
            Console.indent()

            for cmd in setup:
                Console.info("Executing %s...", cmd)

                result = None
                try:
                    result = None
                    result = Util.executeCommand(cmd, "Failed to execute setup command %s" % cmd, path=self.__path)
                except Exception as ex:
                    if result:
                        Console.error(result)

                    raise UserError("Could not scan project %s: %s" % (self.__name, ex))

            Console.outdent()

        # Processing custom content section. Only supports classes and assets.
        if self.__config.has("content"):
            self.kind = "manual"
            self.__addContent(self.__config.get("content"))

        else:
            # Read scan path from config
            if not self.__config.has("scan"):
                if self.__hasDir("source"):
                    self.kind = "application"
                    scan = self.__resolveScanConfig(structures[self.kind])
                elif self.__hasDir("src"):
                    self.kind = "resource"
                    scan = self.__resolveScanConfig(structures[self.kind])
                else:
                    self.kind = "flat"
                    scan = self.__resolveScanConfig(structures[self.kind])

            else:
                scan = self.__resolveScanConfig(self.__config.get("scan"))

            for config in scan:
                if isinstance(config["paths"], str):
                    self.__addDir(config["paths"], config["regex"], config["type"], config["package"])
                else:
                    for path in config["paths"]:
                        self.__addDir(path, config["regex"], config["type"], config["package"])

        # Generate summary
        summary = []
        for section in self.items.keys():
            content = self.items[section]
            name, constructor = self.__resolveConstructor(section)
            if content:
                summary.append(Console.colorize("%s %s" % (len(content), name), "magenta"))

        # Print out
        if summary:
            Console.info("Content: %s" % (", ".join(summary)))

        self.scanned = True

        Console.outdent()
Beispiel #17
0
    def scan(self):

        if self.scanned:
            return

        updatemsg = "[updated]" if self.__modified else "[cached]"

        if self.version:
            Console.info("Scanning %s @ %s %s...",
                         Console.colorize(self.getName(), "bold"),
                         Console.colorize(self.version, "magenta"),
                         Console.colorize(updatemsg, "grey"))
        else:
            Console.info("Scanning %s %s...",
                         Console.colorize(self.getName(), "bold"),
                         Console.colorize(updatemsg, "grey"))

        Console.indent()

        # Support for pre-initialize projects...
        setup = self.__setup
        if setup and self.__modified:
            Console.info("Running setup...")
            Console.indent()

            for cmd in setup:
                Console.info("Executing %s...", cmd)

                result = None
                try:
                    result = None
                    result = Util.executeCommand(
                        cmd,
                        "Failed to execute setup command %s" % cmd,
                        path=self.__path)
                except Exception as ex:
                    if result:
                        Console.error(result)

                    raise UserError("Could not scan project %s: %s" %
                                    (self.__name, ex))

            Console.outdent()

        # Processing custom content section. Only supports classes and assets.
        if self.__config.has("content"):
            self.kind = "manual"
            self.__addContent(self.__config.get("content"))

        else:
            # Read scan path from config
            if not self.__config.has("scan"):
                if self.__hasDir("source"):
                    self.kind = "application"
                    scan = self.__resolveScanConfig(structures[self.kind])
                elif self.__hasDir("src"):
                    self.kind = "resource"
                    scan = self.__resolveScanConfig(structures[self.kind])
                else:
                    self.kind = "flat"
                    scan = self.__resolveScanConfig(structures[self.kind])

            else:
                scan = self.__resolveScanConfig(self.__config.get("scan"))

            for config in scan:
                if isinstance(config["paths"], str):
                    self.__addDir(config["paths"], config["regex"],
                                  config["type"], config["package"])
                else:
                    for path in config["paths"]:
                        self.__addDir(path, config["regex"], config["type"],
                                      config["package"])

        # Generate summary
        summary = []
        for section in self.items.keys():
            content = self.items[section]
            name, constructor = self.__resolveConstructor(section)
            if content:
                summary.append(
                    Console.colorize("%s %s" % (len(content), name),
                                     "magenta"))

        # Print out
        if summary:
            Console.info("Content: %s" % (", ".join(summary)))

        self.scanned = True

        Console.outdent()
Beispiel #18
0
    def __init__(self, session):

        Console.info("Initializing profile...")
        Console.indent()

        # Reference to global session object
        self.__session = session

        # Initialize data instance
        self.__data = {}


        # Set default values (which require serialization)
        self.setJsOutputFolder("js")
        self.setCssOutputFolder("css")
        self.setAssetOutputFolder("asset")
        self.setTemplateOutputFolder("tmpl")

        self.setCompressionLevel(0)
        self.setFormattingLevel(100)


        # Initialize file manager
        fileManager = self.__fileManager = FileManager.FileManager(self)

        # Enforce scan of projects
        session.scan()

        # Part registry holds information about all parts of the application to build
        self.__parts = {}

        # Copy fields and commands from session
        # This happens to have local access to all of them + being able to add and tweak data locally
        self.__fields = copy.copy(session.getFields())
        self.__commands = copy.copy(session.getCommands())

        # Behaves like Date.now() in JavaScript: UTC date in milliseconds
        self.__timeStamp = int(round(time.time() * 1000))
        self.__timeHash = Util.generateChecksum(str(self.__timeStamp))

        # No further steps when session has no projects e.g. during "distclean"
        if not session.getProjects():
            return

        # Initialize asset manager
        Console.info("Initializing asset manager...")
        Console.indent()
        assetManager = self.__assetManager = AssetManager.AssetManager(self)

        # Registering assets
        for project in self.getProjects():
            assetManager.addProject(project)

        # Enable sprite sheets and image animations
        assetManager.processSprites()
        assetManager.processAnimations()

        Console.outdent()

        # Registering commands
        Console.info("Registering commands...")

        self.addCommand("asset.url", lambda fileId: assetManager.getAssetUrl(fileId), "url")
        self.addCommand("asset.width", lambda fileId: assetManager.getAssetWidth(fileId), "px")
        self.addCommand("asset.height", lambda fileId: assetManager.getAssetHeight(fileId), "px")

        self.addCommand("sprite.url", lambda fileId: assetManager.getSpriteUrl(fileId), "url")
        self.addCommand("sprite.left", lambda fileId: assetManager.getSpriteLeft(fileId), "px")
        self.addCommand("sprite.top", lambda fileId: assetManager.getSpriteTop(fileId), "px")
        self.addCommand("sprite.width", lambda fileId: assetManager.getSpriteWidth(fileId), "px")
        self.addCommand("sprite.height", lambda fileId: assetManager.getSpriteHeight(fileId), "px")

        self.addCommand("animation.columns", lambda fileId: assetManager.getAnimationColumns(fileId), "number")
        self.addCommand("animation.rows", lambda fileId: assetManager.getAnimationRows(fileId), "number")
        self.addCommand("animation.frames", lambda fileId: assetManager.getAnimationFrames(fileId), "number")

        Console.outdent()
Beispiel #19
0
    def getRequires(self,
                    checkoutDirectory="external",
                    updateRepositories=True):
        """
        Return the project requirements as project instances
        """

        global projects

        result = []

        for entry in self.__requires:

            if type(entry) is dict:
                source = entry["source"]
                config = Util.getKey(entry, "config")
                version = Util.getKey(entry, "version")
                kind = Util.getKey(entry, "kind")
            else:
                source = entry
                config = None
                version = None
                kind = None

            # Versions are expected being string type
            if version is not None:
                version = str(version)

            revision = None

            if Repository.isUrl(source):
                kind = kind or Repository.getType(source)
                path = os.path.abspath(
                    os.path.join(checkoutDirectory,
                                 Repository.getTargetFolder(source, version)))

                # Only clone and update when the folder is unique in this session
                # This reduces git/hg/svn calls which are typically quite expensive
                if not path in projects:
                    revision = Repository.update(source, version, path,
                                                 updateRepositories)
                    if revision is None:
                        raise UserError("Could not update repository %s" %
                                        source)

            else:
                kind = "local"
                if not source.startswith(("/", "~")):
                    path = os.path.join(self.__path, source)
                else:
                    path = os.path.abspath(os.path.expanduser(source))

            if path in projects:
                project = projects[path]

            else:
                fullversion = []

                # Produce user readable version when non is defined
                if version is None and revision is not None:
                    version = "master"

                if version is not None:
                    if "/" in version:
                        fullversion.append(version[version.rindex("/") + 1:])
                    else:
                        fullversion.append(version)

                if revision is not None:
                    # Shorten typical long revisions as used by e.g. Git
                    if type(revision) is str and len(revision) > 20:
                        fullversion.append(revision[:10])
                    else:
                        fullversion.append(revision)

                if fullversion:
                    fullversion = "-".join(fullversion)
                else:
                    fullversion = None

                project = Project(path, config, fullversion)
                projects[path] = project

            result.append(project)

        return result
Beispiel #20
0
    def scan(self):

        if self.scanned:
            return

        updatemsg = "[updated]" if self.__modified else "[cached]"
        Console.info("Scanning project %s %s...", self.__name,
                     Console.colorize(updatemsg, "grey"))
        Console.indent()

        # Support for pre-initialize projects...
        setup = self.__setup
        if setup and self.__modified:
            Console.info("Running setup...")
            Console.indent()

            for cmd in setup:
                Console.info("Executing %s...", cmd)

                result = None
                try:
                    result = None
                    result = Util.executeCommand(
                        cmd,
                        "Failed to execute setup command %s" % cmd,
                        path=self.__path)
                except Exception as ex:
                    if result:
                        Console.error(result)

                    raise UserError("Could not scan project %s: %s" %
                                    (self.__name, ex))

            Console.outdent()

        # Processing custom content section. Only supports classes and assets.
        if self.__config.has("content"):
            self.kind = "manual"
            self.__addContent(self.__config.get("content"))

        # Application projects
        elif self.__hasDir("source"):
            self.kind = "application"

            if self.__hasDir("source/class"):
                self.__addDir("source/class", "classes")
            if self.__hasDir("source/asset"):
                self.__addDir("source/asset", "assets")
            if self.__hasDir("source/translation"):
                self.__addDir("source/translation", "translations")

        # Compat - please change to class/style/asset instead
        elif self.__hasDir("src"):
            self.kind = "resource"
            self.__addDir("src", "classes")

        # Resource projects
        else:
            self.kind = "resource"

            if self.__hasDir("class"):
                self.__addDir("class", "classes")
            if self.__hasDir("asset"):
                self.__addDir("asset", "assets")
            if self.__hasDir("translation"):
                self.__addDir("translation", "translations")

        # Generate summary
        summary = []
        for section in ["classes", "assets", "translations"]:
            content = getattr(self, section, None)
            if content:
                summary.append("%s %s" % (len(content), section))

        # Print out
        if summary:
            Console.info("Done %s: %s" %
                         (Console.colorize("[%s]" % self.kind, "grey"),
                          Console.colorize(", ".join(summary), "green")))
        else:
            Console.error("Project is empty!")

        self.scanned = True

        Console.outdent()
Beispiel #21
0
    def scan(self):

        if self.scanned:
            return

        updatemsg = "[updated]" if self.__modified else "[cached]"
        Console.info("Scanning project %s %s...", self.__name, Console.colorize(updatemsg, "grey"))
        Console.indent()

        # Support for pre-initialize projects...
        setup = self.__setup
        if setup and self.__modified:
            Console.info("Running setup...")
            Console.indent()

            for cmd in setup:
                Console.info("Executing %s...", cmd)

                result = None
                try:
                    result = None
                    result = Util.executeCommand(cmd, "Failed to execute setup command %s" % cmd, path=self.__path)
                except Exception as ex:
                    if result:
                        Console.error(result)

                    raise UserError("Could not scan project %s: %s" % (self.__name, ex))

            Console.outdent()
        
        # Processing custom content section. Only supports classes and assets.
        if self.__config.has("content"):
            self.kind = "manual"
            self.__addContent(self.__config.get("content"))

        # Application projects
        elif self.__hasDir("source"):
            self.kind = "application"

            if self.__hasDir("source/class"):
                self.__addDir("source/class", "classes")
            if self.__hasDir("source/style"):
                self.__addDir("source/style", "styles")
            if self.__hasDir("source/asset"):
                self.__addDir("source/asset", "assets")
            if self.__hasDir("source/translation"):
                self.__addDir("source/translation", "translations")
                
        # Compat - please change to class/style/asset instead
        elif self.__hasDir("src"):
            self.kind = "resource"
            self.__addDir("src", "classes")

        # Resource projects
        else:
            self.kind = "resource"

            if self.__hasDir("class"):
                self.__addDir("class", "classes")
            if self.__hasDir("style"):
                self.__addDir("style", "styles")
            if self.__hasDir("asset"):
                self.__addDir("asset", "assets")
            if self.__hasDir("translation"):
                self.__addDir("translation", "translations")

        # Generate summary
        summary = []
        for section in ["classes", "styles", "translations", "assets"]:
            content = getattr(self, section, None)
            if content:
                summary.append("%s %s" % (len(content), section))

        # Print out
        if summary:
            Console.info("Content: %s" % (Console.colorize(", ".join(summary), "green")))
        else:
            Console.error("Project is empty!")

        self.scanned = True

        Console.outdent()
Beispiel #22
0
    def getRequires(self, checkoutDirectory="external", updateRepositories=True):
        """
        Return the project requirements as project instances
        """

        global projects
        
        result = []
        
        for entry in self.__requires:
            
            if type(entry) is dict:
                source = entry["source"]
                config = Util.getKey(entry, "config")
                version = Util.getKey(entry, "version")
                kind = Util.getKey(entry, "kind")
            else:
                source = entry
                config = None
                version = None
                kind = None

            # Versions are expected being string type
            if version is not None:
                version = str(version)

            revision = None
            
            if Repository.isUrl(source):
                kind = kind or Repository.getType(source)
                path = os.path.abspath(os.path.join(checkoutDirectory, Repository.getTargetFolder(source, version)))
                
                # Only clone and update when the folder is unique in this session
                # This reduces git/hg/svn calls which are typically quite expensive
                if not path in projects:
                    revision = Repository.update(source, version, path, updateRepositories)
                    if revision is None:
                        raise UserError("Could not update repository %s" % source)
            
            else:
                kind = "local"
                if not source.startswith(("/", "~")):
                    path = os.path.join(self.__path, source)
                else:
                    path = os.path.abspath(os.path.expanduser(source))

                path = os.path.normpath(path)
            
            if path in projects:
                project = projects[path]
                
            else:
                fullversion = []
                
                # Produce user readable version when non is defined
                if version is None and revision is not None:
                    version = "master"
                
                if version is not None:
                    if "/" in version:
                        fullversion.append(version[version.rindex("/")+1:])
                    else:
                        fullversion.append(version)
                    
                if revision is not None:
                    # Shorten typical long revisions as used by e.g. Git
                    if type(revision) is str and len(revision) > 20:
                        fullversion.append(revision[:10])
                    else:
                        fullversion.append(revision)
                        
                if fullversion:
                    fullversion = "-".join(fullversion)
                else:
                    fullversion = None

                project = Project(path, config, fullversion)
                projects[path] = project
            
            result.append(project)
        
        return result