コード例 #1
0
ファイル: Session.py プロジェクト: Andais/jasy
    def init(self, autoInitialize=True, updateRepositories=True, scriptEnvironment=None):
        """
        Initialize the actual session with projects

        :param autoInitialize: Whether the projects should be automatically added when the current folder contains a valid Jasy project.
        :param updateRepositories: Whether to update repositories of all project dependencies.
        :param scriptEnvironment: API object as being used for loadLibrary to add Python features offered by projects.
        """

        self.__scriptEnvironment = scriptEnvironment
        self.__updateRepositories = updateRepositories

        if autoInitialize and jasy.core.Config.findConfig("jasyproject"):

            try:
                self.addProject(jasy.core.Project.getProjectFromPath("."))

            except UserError as err:
                Console.outdent(True)
                Console.error(err)
                raise UserError("Critical: Could not initialize session!")

            Console.info("Active projects (%s):", len(self.__projects))
            Console.indent()

            for project in self.__projects:
                if project.version:
                    Console.info("%s @ %s", Console.colorize(project.getName(), "bold"), Console.colorize(project.version, "magenta"))
                else:
                    Console.info(Console.colorize(project.getName(), "bold"))

            Console.outdent()        
コード例 #2
0
ファイル: Class.py プロジェクト: Andais/jasy
    def __getOptimizedTree(self, permutation=None, context=None):
        """Returns an optimized tree with permutations applied"""

        field = "opt-tree[%s]-%s" % (self.id, permutation)
        tree = self.project.getCache().read(field, self.mtime)
        if not tree:
            tree = copy.deepcopy(self.__getTree("%s:plain" % context))

            # Logging
            msg = "Processing class %s" % Console.colorize(self.id, "bold")
            if permutation:
                msg += Console.colorize(" (%s)" % permutation, "grey")
            if context:
                msg += Console.colorize(" [%s]" % context, "cyan")
                
            Console.info("%s..." % msg)
            Console.indent()

            # Apply permutation
            if permutation:
                Console.debug("Patching tree with permutation: %s", permutation)
                Console.indent()
                jasy.js.clean.Permutate.patch(tree, permutation)
                Console.outdent()

            # Cleanups
            jasy.js.clean.DeadCode.cleanup(tree)
            ScopeScanner.scan(tree)
            jasy.js.clean.Unused.cleanup(tree)
        
            self.project.getCache().store(field, tree, self.mtime, True)
            Console.outdent()

        return tree
コード例 #3
0
ファイル: Class.py プロジェクト: zynga/jasy
    def __getOptimizedTree(self, permutation=None, context=None):
        """Returns an optimized tree with permutations applied"""

        field = "opt-tree[%s]-%s" % (self.id, permutation)
        tree = self.project.getCache().read(field, self.mtime)
        if not tree:
            tree = copy.deepcopy(self.__getTree("%s:plain" % context))

            # Logging
            msg = "Processing class %s" % Console.colorize(self.id, "bold")
            if permutation:
                msg += Console.colorize(" (%s)" % permutation, "grey")
            if context:
                msg += Console.colorize(" [%s]" % context, "cyan")

            Console.info("%s..." % msg)
            Console.indent()

            # Apply permutation
            if permutation:
                Console.debug("Patching tree with permutation: %s",
                              permutation)
                Console.indent()
                jasy.js.clean.Permutate.patch(tree, permutation)
                Console.outdent()

            # Cleanups
            jasy.js.clean.DeadCode.cleanup(tree)
            ScopeScanner.scan(tree)
            jasy.js.clean.Unused.cleanup(tree)

            self.project.getCache().store(field, tree, self.mtime, True)
            Console.outdent()

        return tree
コード例 #4
0
ファイル: Task.py プロジェクト: isabella232/jasy
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")))
コード例 #5
0
ファイル: Config.py プロジェクト: isabella232/jasy
    def ask(self,
            question,
            name,
            accept=None,
            required=True,
            default=None,
            force=False,
            parse=True):
        """
        Asks the user for value for the given configuration field:

        :param question: Question to ask the user
        :type question: string
        :param name: Name of field to store value in
        :type name: string
        :param accept: Any of the supported types to validate for (see matchesType)
        :type accept: string
        :param required: Whether the field is required
        :type required: boolean
        :param default: Default value whenever user has given no value
        """

        while True:
            msg = "- %s?" % question
            if accept is not None:
                msg += Console.colorize(" [%s]" % accept, "grey")

            if default is None:
                msg += Console.colorize(" (%s)" % name, "magenta")
            else:
                msg += Console.colorize(" (%s=%s)" % (name, default),
                                        "magenta")

            msg += ": "

            sys.stdout.write(msg)

            # Do not ask user for solved items
            if not force and self.has(name):
                print(
                    "%s %s" %
                    (self.get(name), Console.colorize("(pre-filled)", "cyan")))
                return

            # Read user input, but ignore any leading/trailing white space
            value = input().strip()

            # Fallback to default if no value is given and field is not required
            if not required and value == "":
                value = default

            # Don't accept empty values
            if value == "":
                continue

            # Try setting the current value
            if self.set(name, value, accept=accept, parse=parse):
                break
コード例 #6
0
ファイル: Inspect.py プロジェクト: isabella232/jasy
def generateApi(api):
    """Returns a stringified output for the given API set."""

    import jasy.env.Task as Task

    result = []

    for key in sorted(api):

        if key.startswith("__"):
            continue

        value = api[key]

        if isinstance(value, Task.Task):
            continue

        msg = Console.colorize(key, "bold")

        if inspect.isfunction(value):
            msg += Console.colorize(highlightArgs(value), "bold")
        elif inspect.isclass(value):
            msg += Console.colorize(highlightArgs(value.__init__, True),
                                    "bold")

        humanType = extractType(value)
        if humanType:
            msg += Console.colorize(" [%s]" % extractType(value), "magenta")

        msg += extractDoc(value) or ""

        result.append(msg)

        if inspect.isclass(value) or inspect.ismodule(value) or isinstance(
                value, object):

            if inspect.isclass(value):
                sprefix = ""
            elif inspect.ismodule(value) or isinstance(value, object):
                sprefix = "%s." % key

            smembers = dict(inspect.getmembers(value))

            for skey in sorted(smembers):
                if not "__" in skey:
                    svalue = smembers[skey]
                    if inspect.ismethod(svalue) or inspect.isfunction(svalue):
                        msg = "  - %s%s" % (sprefix,
                                            Console.colorize(skey, "bold"))
                        msg += highlightArgs(svalue, humanType
                                             in ("Class", "Object"))
                        msg += extractDoc(svalue, indent=6) or ""
                        result.append(msg)

        result.append("")

    return "\n".join(result)
コード例 #7
0
def info():
    """
    Prints information about Jasy to the console.
    """

    import jasy.core.Console as Console

    print("Jasy %s is a powerful web tooling framework" % __version__)
    print("Copyright (c) 2010-2012 Zynga Inc. %s" % Console.colorize("http://zynga.com/", "underline"))
    print("Visit %s for details." % Console.colorize("https://github.com/zynga/jasy", "underline"))
    print()
コード例 #8
0
ファイル: Inspect.py プロジェクト: sebastian-software/jasy
def generateApi(api):
    """Returns a stringified output for the given API set."""

    import jasy.env.Task as Task

    result = []

    for key in sorted(api):

        if key.startswith("__"):
            continue

        value = api[key]

        if isinstance(value, Task.Task):
            continue

        msg = Console.colorize(key, "bold")

        if inspect.isfunction(value):
            msg += Console.colorize(highlightArgs(value), "bold")
        elif inspect.isclass(value):
            msg += Console.colorize(highlightArgs(value.__init__, True), "bold")

        humanType = extractType(value)
        if humanType:
            msg += Console.colorize(" [%s]" % extractType(value), "magenta")

        msg += extractDoc(value) or ""

        result.append(msg)

        if inspect.isclass(value) or inspect.ismodule(value) or isinstance(value, object):

            if inspect.isclass(value):
                sprefix = ""
            elif inspect.ismodule(value) or isinstance(value, object):
                sprefix = "%s." % key

            smembers = dict(inspect.getmembers(value))

            for skey in sorted(smembers):
                if not "__" in skey:
                    svalue = smembers[skey]
                    if inspect.ismethod(svalue) or inspect.isfunction(svalue):
                        msg = "  - %s%s" % (sprefix, Console.colorize(skey, "bold"))
                        msg += highlightArgs(svalue, humanType in ("Class", "Object"))
                        msg += extractDoc(svalue, indent=6) or ""
                        result.append(msg)

        result.append("")

    return "\n".join(result)
コード例 #9
0
ファイル: Config.py プロジェクト: Andais/jasy
    def ask(self, question, name, accept=None, required=True, default=None, force=False, parse=True):
        """
        Asks the user for value for the given configuration field:

        :param question: Question to ask the user
        :type question: string
        :param name: Name of field to store value in
        :type name: string
        :param accept: Any of the supported types to validate for (see matchesType)
        :type accept: string
        :param required: Whether the field is required
        :type required: boolean
        :param default: Default value whenever user has given no value
        """

        while True:
            msg = "- %s?" % question
            if accept is not None:
                msg += Console.colorize(" [%s]" % accept, "grey")

            if default is None:
                msg += Console.colorize(" (%s)" % name, "magenta")
            else:
                msg += Console.colorize(" (%s=%s)" % (name, default), "magenta")

            msg += ": "

            sys.stdout.write(msg)

            # Do not ask user for solved items
            if not force and self.has(name):
                print("%s %s" % (self.get(name), Console.colorize("(pre-filled)", "cyan")))
                return

            # Read user input, but ignore any leading/trailing white space
            value = input().strip()

            # Fallback to default if no value is given and field is not required
            if not required and value == "":
                value = default

            # Don't accept empty values
            if value == "":
                continue

            # Try setting the current value
            if self.set(name, value, accept=accept, parse=parse):
                break
コード例 #10
0
ファイル: Project.py プロジェクト: E01T/jasy
    def __resolve(project):

        name = project.getName()

        # List of required projects
        Console.info("Getting requirements of %s...", Console.colorize(name, "bold"))
        Console.indent()
        requires = project.getRequires(checkoutDirectory, updateRepositories)
        Console.outdent()

        if not requires:
            return

        Console.debug("Processing %s requirements...", len(requires))
        Console.indent()

        # Adding all project in reverse order.
        # Adding all local ones first before going down to their requirements
        for requiredProject in reversed(requires):
            requiredName = requiredProject.getName()
            if not requiredName in names:
                Console.debug("Adding: %s %s (via %s)", requiredName, requiredProject.version, project.getName())
                names[requiredName] = True
                result.append(requiredProject)
            else:
                Console.debug("Blocking: %s %s (via %s)", requiredName, requiredProject.version, project.getName())

        # Process all requirements of added projects
        for requiredProject in requires:
            if requiredProject.hasRequires():
                __resolve(requiredProject)

        Console.outdent()
コード例 #11
0
ファイル: Style.py プロジェクト: isabella232/jasy
    def getCompressed(self, profile):
        """Returns the compressed CSS code of this item."""

        field = "style:compressed[%s]-%s" % (self.id, profile.getId())
        mtime = self.getModificationTime(profile)

        compressed = self.project.getCache().read(field, mtime)

        if compressed is None:

            Console.info("Compressing tree %s...", Console.colorize(self.id, "bold"))

            # Start with the merged tree (includes resolved)
            tree = self.getMergedTree(profile)

            # Reduce tree
            Engine.reduceTree(tree, profile)

            # Compress tree
            compressed = Engine.compressTree(tree, profile.getCompressionLevel(), profile.getFormattingLevel())

            # Store in cache
            self.project.getCache().store(field, compressed, mtime)

        return compressed
コード例 #12
0
ファイル: Session.py プロジェクト: isabella232/jasy
    def loadCommands(self, objectName, fileName, encoding="utf-8"):
        """Loads new commands into the session wide command registry."""

        counter = 0
        commands = self.__commands

        # Method for being used as a decorator to share methods to the outside
        def share(func):
            name = "%s.%s" % (objectName, func.__name__)
            if name in commands:
                raise Exception("Command %s already exists!" % name)

            commands[name] = func

            nonlocal counter
            counter += 1

            return func

        # Execute given file. Using clean new global environment
        # but add additional decorator for allowing to define shared methods
        # and the session object (self).
        code = open(fileName, "r", encoding=encoding).read()
        exec(compile(code, os.path.abspath(fileName), "exec"), {"share" : share, "session" : self})

        # Export destination name as global
        Console.info("Imported %s.", Console.colorize("%s commands" % counter, "magenta"))

        return counter
コード例 #13
0
ファイル: Manager.py プロジェクト: sebastian-software/jasy
    def processSprites(self):
        """Processes jasysprite files to merge sprite data into asset registry."""

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

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

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

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

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

            Console.indent()
            for spriteImage in spriteConfig:
                spriteImageId = "%s/%s" % (spriteBase, spriteImage)

                singleRelPaths = spriteConfig[spriteImage]
                Console.debug("Image %s combines %s images", spriteImageId, len(singleRelPaths))

                for singleRelPath in singleRelPaths:
                    singleId = "%s/%s" % (spriteBase, singleRelPath)
                    singleData = singleRelPaths[singleRelPath]
                    singleItem = assets[singleId]

                    # Verify that sprite sheet is up-to-date
                    fileChecksum = singleItem.getChecksum()
                    storedChecksum = singleData["checksum"]

                    Console.debug("Checksum Compare: %s <=> %s", fileChecksum, storedChecksum)
                    if storedChecksum != fileChecksum:
                        raise UserError("Sprite Sheet is not up-to-date. Checksum of %s differs." % singleId)

                    if spriteImageId not in sprites:
                        spriteImageIndex = len(sprites)
                        sprites.append(spriteImageId)
                    else:
                        spriteImageIndex = sprites.index(spriteImageId)

                    # Add relevant data to find image on sprite sheet
                    singleItem.addImageSpriteData(spriteImageIndex, singleData["left"], singleData["top"])

            Console.outdent()

            # The config file does not make any sense on the client side
            Console.debug("Deleting sprite config from assets: %s", fileId)
            del assets[fileId]

        Console.outdent()
        self.__sprites = sprites
コード例 #14
0
ファイル: Class.py プロジェクト: zynga/jasy
    def __getTree(self, context=None):

        field = "tree[%s]" % self.id
        tree = self.project.getCache().read(field, self.mtime)
        if not tree:
            Console.info("Processing class %s %s...",
                         Console.colorize(self.id, "bold"),
                         Console.colorize("[%s]" % context, "cyan"))

            Console.indent()
            tree = Parser.parse(self.getText(), self.id)
            ScopeScanner.scan(tree)
            Console.outdent()

            self.project.getCache().store(field, tree, self.mtime, True)

        return tree
コード例 #15
0
ファイル: __init__.py プロジェクト: swernerx/konstrukteur
def info():
    """Prints information about Jasy to the console."""

    import jasy.core.Console as Console

    print("Konstrukteur %s is a static site generator" % __version__)
    print("Visit %s for details." % Console.colorize("https://github.com/fastner/konstrukteur", "underline"))
    print()
コード例 #16
0
ファイル: __init__.py プロジェクト: isabella232/jasy
def info():
    """Prints information about Jasy to the console."""

    import jasy.core.Console as Console

    print("Jasy %s is a powerful web tooling framework" % __version__)
    print("Visit %s for details." % Console.colorize("https://github.com/sebastian-software/jasy", "underline"))
    print()
コード例 #17
0
ファイル: Task.py プロジェクト: zynga/jasy
def runTask(project, task, **kwargs):
    """
    Executes the given task of the given projects. 
    
    This happens inside a new sandboxed session during which the 
    current session is paused/resumed automatically.
    """

    remote = session.getProjectByName(project)
    if remote is not None:
        remotePath = remote.getPath()
        remoteName = remote.getName()
    elif os.path.isdir(project):
        remotePath = project
        remoteName = os.path.basename(project)
    else:
        raise UserError("Unknown project or invalid path: %s" % project)

    Console.info("Running %s of project %s...", Console.colorize(task, "bold"),
                 Console.colorize(remoteName, "bold"))

    # Pauses this session to allow sub process fully accessing the same projects
    session.pause()

    # Build parameter list from optional arguments
    params = ["--%s=%s" % (key, kwargs[key]) for key in kwargs]
    if not "prefix" in kwargs:
        params.append("--prefix=%s" % session.getCurrentPrefix())

    # Full list of args to pass to subprocess
    args = [__command, task] + params

    # Change into sub folder and execute jasy task
    oldPath = os.getcwd()
    os.chdir(remotePath)
    returnValue = subprocess.call(args, shell=sys.platform == "win32")
    os.chdir(oldPath)

    # Resumes this session after sub process was finished
    session.resume()

    # Error handling
    if returnValue != 0:
        raise UserError("Executing of sub task %s from project %s failed" %
                        (task, project))
コード例 #18
0
ファイル: Class.py プロジェクト: Zenwolf/jasy
    def __getTree(self, context=None):

        field = "tree[%s]" % self.id
        tree = self.project.getCache().read(field, self.mtime)
        if not tree:
            Console.info(
                "Processing class %s %s...",
                Console.colorize(self.id, "bold"),
                Console.colorize("[%s]" % context, "cyan"),
            )

            Console.indent()
            tree = Parser.parse(self.getText(), self.id)
            ScopeScanner.scan(tree)
            Console.outdent()

            self.project.getCache().store(field, tree, self.mtime, True)

        return tree
コード例 #19
0
ファイル: Doctor.py プロジェクト: Andais/jasy
def doCompleteDoctor():
    """Checks for uninstalled or too old versions of requirements and gives a complete output"""

    Console.header("Doctor")

    dists = [dist for dist in pip.get_installed_distributions()]
    keys = [dist.key for dist in pip.get_installed_distributions()]

    versions = {}
    for dist in dists:
        versions[dist.key] = dist.version

    def checkSingleInstallation(keys, versions, packageName, minVersion, installPath, updatePath):
        Console.info('%s:' % packageName)
        Console.indent()
        if packageName.lower() in keys:
            Console.info(Console.colorize('Found installation', "green"))
            if LooseVersion(minVersion) > LooseVersion("0.0"):
                if LooseVersion(versions[packageName.lower()]) >= LooseVersion(minVersion):
                    Console.info(Console.colorize('Version is OK (needed: %s installed: %s)' % (minVersion, versions[packageName.lower()]), "green"))
                else:
                    Console.info(Console.colorize(Console.colorize('- Version is NOT OK (needed: %s installed: %s)' % (minVersion, versions[packageName.lower()]) , "red"), "bold"))
                    Console.info('Update to the newest version of %s using %s' % (packageName, updatePath))
        else:
            Console.info(Console.colorize(Console.colorize('Did NOT find installation', "red"), "bold"))
            Console.info('Install the newest version of %s using %s' % (packageName, installPath))
        Console.outdent()


    # Required packages
    Console.info(Console.colorize("Required Packages:", "bold"))
    Console.indent()
    for entry in needs:
        checkSingleInstallation(keys, versions, entry["packageName"], entry["minVersion"], entry["installPath"], entry["updatePath"])
    Console.outdent()

    # Optional packages
    Console.info("")
    Console.info(Console.colorize("Optional Packages:", "bold"))
    Console.indent()
    for entry in optionals:
        checkSingleInstallation(keys, versions, entry["packageName"], entry["minVersion"], entry["installPath"], entry["updatePath"])
    Console.outdent()
コード例 #20
0
ファイル: Task.py プロジェクト: sebastian-software/jasy
def runTask(project, task, **kwargs):
    """
    Executes the given task of the given projects.

    This happens inside a new sandboxed session during which the current session is paused/resumed automatically.

    """

    remote = session.getProjectByName(project)
    if remote is not None:
        remotePath = remote.getPath()
        remoteName = remote.getName()
    elif os.path.isdir(project):
        remotePath = project
        remoteName = os.path.basename(project)
    else:
        raise UserError("Unknown project or invalid path: %s" % project)

    Console.info("Running %s of project %s...", Console.colorize(task, "bold"), Console.colorize(remoteName, "bold"))

    # Pauses this session to allow sub process fully accessing the same projects
    session.pause()

    # Build parameter list from optional arguments
    params = ["--%s=%s" % (key, kwargs[key]) for key in kwargs]
    if not "prefix" in kwargs:
        params.append("--prefix=%s" % session.getCurrentPrefix())

    # Full list of args to pass to subprocess
    args = [__command, task] + params

    # Change into sub folder and execute jasy task
    oldPath = os.getcwd()
    os.chdir(remotePath)
    returnValue = subprocess.call(args, shell=sys.platform == "win32")
    os.chdir(oldPath)

    # Resumes this session after sub process was finished
    session.resume()

    # Error handling
    if returnValue != 0:
        raise UserError("Executing of sub task %s from project %s failed" % (task, project))
コード例 #21
0
ファイル: Manager.py プロジェクト: sebastian-software/jasy
    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()
コード例 #22
0
ファイル: Style.py プロジェクト: isabella232/jasy
    def getFields(self):
        """Returns the fields which are used by this stylesheet."""

        field = "style:fields[%s]" % self.id
        fields = self.project.getCache().read(field, self.mtime)
        if fields is None:
            Console.debug("Collecting fields %s...", Console.colorize(self.id, "bold"))
            fields = collectFields(self.__getTree())
            self.project.getCache().store(field, fields, self.mtime)

        return fields
コード例 #23
0
ファイル: Options.py プロジェクト: isabella232/jasy
    def printOptions(self, indent=16):

        for name in sorted(self.__defaults):
            col = len(name)
            msg = "  --%s" % name

            for shortcut in self.__shortcuts:
                if self.__shortcuts[shortcut] == name:
                    col += len(" [-%s]" % shortcut)
                    msg += Console.colorize(" [-%s]" % shortcut, "grey")

            if name in self.__help:
                msg += ": "
                diff = indent - col
                if diff > 0:
                    msg += " " * diff

                msg += Console.colorize(self.__help[name], "magenta")

            print(msg)
コード例 #24
0
ファイル: Style.py プロジェクト: Zenwolf/jasy
    def __getTree(self, context=None):
        """
        Returns the parsed tree
        """

        field = "tree[%s]" % self.id
        tree = self.project.getCache().read(field, self.mtime)
        if not tree:
            Console.info(
                "Processing stylesheet %s %s...",
                Console.colorize(self.id, "bold"),
                Console.colorize("[%s]" % context, "cyan"),
            )

            Console.indent()
            tree = Parser.parse(self.getText(), self.id)
            Console.outdent()

            self.project.getCache().store(field, tree, self.mtime, True)

        return tree
コード例 #25
0
ファイル: Session.py プロジェクト: isabella232/jasy
    def init(self, autoInitialize=True, updateRepositories=True, scriptEnvironment=None):
        """
        Initialize the actual session with projects.

        :param autoInitialize: Whether the projects should be automatically added when the current folder contains a valid Jasy project.
        :param updateRepositories: Whether to update repositories of all project dependencies.
        :param scriptEnvironment: API object as being used for loadLibrary to add Python features offered by projects.
        :param commandEnvironment: API object as being used for loadCommands to add Python features for any item nodes.

        """

        self.__scriptEnvironment = scriptEnvironment
        self.__updateRepositories = updateRepositories

        if autoInitialize and Config.findConfig("jasyproject"):

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

            try:
                self.addProject(Project.getProjectFromPath(".", self))

            except UserError as err:
                Console.outdent(True)
                Console.error(err)
                raise UserError("Critical: Could not initialize session!")

            self.getVirtualProject()

            Console.debug("Active projects (%s):", len(self.__projects))
            Console.indent()

            for project in self.__projects:
                if project.version:
                    Console.debug("%s @ %s", Console.colorize(project.getName(), "bold"), Console.colorize(project.version, "magenta"))
                else:
                    Console.debug(Console.colorize(project.getName(), "bold"))

            Console.outdent()
            Console.outdent()
コード例 #26
0
ファイル: Doctor.py プロジェクト: zynga/jasy
 def checkSingleInstallation(keys, versions, packageName, minVersion,
                             installPath, updatePath):
     Console.info('%s:' % packageName)
     Console.indent()
     if packageName.lower() in keys:
         Console.info(Console.colorize('Found installation', "green"))
         if LooseVersion(minVersion) > LooseVersion("0.0"):
             if LooseVersion(versions[packageName.lower()]) >= LooseVersion(
                     minVersion):
                 Console.info(
                     Console.colorize(
                         'Version is OK (needed: %s installed: %s)' %
                         (minVersion, versions[packageName.lower()]),
                         "green"))
             else:
                 Console.info(
                     Console.colorize(
                         Console.colorize(
                             '- Version is NOT OK (needed: %s installed: %s)'
                             % (minVersion, versions[packageName.lower()]),
                             "red"), "bold"))
                 Console.info(
                     'Update to the newest version of %s using %s' %
                     (packageName, updatePath))
     else:
         Console.info(
             Console.colorize(
                 Console.colorize('Did NOT find installation', "red"),
                 "bold"))
         Console.info('Install the newest version of %s using %s' %
                      (packageName, installPath))
     Console.outdent()
コード例 #27
0
ファイル: Style.py プロジェクト: isabella232/jasy
    def getMetaData(self, permutation):
        """Returns the meta data of this stylesheet."""

        permutation = self.filterPermutation(permutation)

        field = "style:meta[%s]-%s" % (self.id, permutation)
        meta = self.project.getCache().read(field, self.mtime)
        if meta is None:
            Console.debug("Collecting meta data %s...", Console.colorize(self.id, "bold"))
            meta = MetaData.MetaData(self.__getPermutatedTree(permutation))
            self.project.getCache().store(field, meta, self.mtime)

        return meta
コード例 #28
0
ファイル: Style.py プロジェクト: isabella232/jasy
    def getIncludes(self, permutation):
        """Returns the includes which are referenced by this stylesheet."""

        field = "style:includes[%s]" % self.id
        includes = self.project.getCache().read(field, self.mtime)
        if includes is None:
            Console.debug("Collecting includes %s...", Console.colorize(self.id, "bold"))
            includes = []
            for includeName, includeNode in includeGenerator(self.__getPermutatedTree(permutation)):
                includes.append(includeName)

            self.project.getCache().store(field, includes, self.mtime)

        return includes
コード例 #29
0
ファイル: Session.py プロジェクト: isabella232/jasy
    def addProject(self, project):
        """
        Adds the given project to the list of known projects. Projects should be added in order of their priority. This
        adds the field configuration of each project to the session fields. Fields must not conflict between different
        projects (same name).

        :param project: Instance of Project to append to the list
        :type project: object

        """

        result = Project.getProjectDependencies(project, "external", self.__updateRepositories)
        for project in result:

            Console.info("Adding %s...", Console.colorize(project.getName(), "bold"))
            Console.indent()

            # Append to session list
            self.__projects.append(project)

            # Import library methods
            libraryPath = os.path.join(project.getPath(), "jasylibrary.py")
            if os.path.exists(libraryPath):
                self.loadLibrary(project.getName(), libraryPath, doc="Library of project %s" % project.getName())

            # Import command methods
            commandPath = os.path.join(project.getPath(), "jasycommand.py")
            if os.path.exists(commandPath):
                self.loadCommands(project.getName(), commandPath)

            # Import project defined fields which might be configured using "activateField()"
            fields = project.getFields()
            for name in fields:
                entry = fields[name]

                if name in self.__fields:
                    raise UserError("Field '%s' was already defined!" % (name))

                if "check" in entry:
                    check = entry["check"]
                    if check in ["Boolean", "String", "Number"] or isinstance(check, list):
                        pass
                    else:
                        raise UserError("Unsupported check: '%s' for field '%s'" % (check, name))

                self.__fields[name] = entry


            Console.outdent()
コード例 #30
0
ファイル: Session.py プロジェクト: isabella232/jasy
    def loadLibrary(self, objectName, fileName, encoding="utf-8", doc=None):
        """
        Creates a new object inside the user API (jasyscript.py) with the given name
        containing all @share'd functions and fields loaded from the given file.
        """

        if objectName in self.__scriptEnvironment:
            raise UserError("Could not import library %s as the object name %s is already used." % (fileName, objectName))

        # Create internal class object for storing shared methods
        class Shared(object):
            pass
        exportedModule = Shared()
        exportedModule.__doc__ = doc or "Imported from %s" % os.path.relpath(fileName, os.getcwd())
        counter = 0

        # Method for being used as a decorator to share methods to the outside
        def share(func):
            nonlocal counter
            setattr(exportedModule, func.__name__, func)
            counter += 1

            return func

        def itemtype(type, name):
            def wrap(cls):
                id = "%s.%s" % (objectName, type[0].upper() + type[1:])
                self.addItemType(id, name, cls)
                return cls
            return wrap

        def postscan():
            def wrap(f):
                self.__postscans.append(f)
                return f
            return wrap

        # Execute given file. Using clean new global environment
        # but add additional decorator for allowing to define shared methods
        # and the session object (self).
        code = open(fileName, "r", encoding=encoding).read()
        exec(compile(code, os.path.abspath(fileName), "exec"), {"share" : share, "itemtype": itemtype, "postscan": postscan, "session" : self})

        # Export destination name as global
        self.__scriptEnvironment[objectName] = exportedModule

        Console.info("Imported %s.", Console.colorize("%s methods" % counter, "magenta"))

        return counter
コード例 #31
0
ファイル: Style.py プロジェクト: isabella232/jasy
    def __getTree(self):
        """Returns the abstract syntax tree of the stylesheet."""

        field = "style:tree[%s]" % self.id
        tree = self.project.getCache().read(field, self.mtime)

        if not tree:
            Console.info("Parsing stylesheet %s...", Console.colorize(self.id, "bold"))

            Console.indent()
            tree = Engine.getTree(self.getText(), self.id)
            Console.outdent()

            self.project.getCache().store(field, tree, self.mtime, True)

        return tree
コード例 #32
0
ファイル: Script.py プロジェクト: sebastian-software/jasy
    def __getTree(self):
        """Returns the abstract syntax tree."""

        field = "script:tree[%s]" % self.id
        tree = self.project.getCache().read(field, self.mtime)
        if not tree:
            Console.info("Processing class %s...", Console.colorize(self.id, "bold"))

            Console.indent()
            tree = Parser.parse(self.getText(), self.id)
            ScopeScanner.scan(tree)
            Console.outdent()

            self.project.getCache().store(field, tree, self.mtime, True)

        return tree
コード例 #33
0
ファイル: Script.py プロジェクト: isabella232/jasy
    def __getTree(self):
        """Returns the abstract syntax tree."""

        field = "script:tree[%s]" % self.id
        tree = self.project.getCache().read(field, self.mtime)
        if not tree:
            Console.info("Processing class %s...",
                         Console.colorize(self.id, "bold"))

            Console.indent()
            tree = Parser.parse(self.getText(), self.id)
            ScopeScanner.scan(tree)
            Console.outdent()

            self.project.getCache().store(field, tree, self.mtime, True)

        return tree
コード例 #34
0
ファイル: Doctor.py プロジェクト: Zenwolf/jasy
    def checkSingleInstallation(keys, versions, packageName, minVersion, installPath, updatePath):
        if packageName.lower() in keys:
            if LooseVersion(minVersion) > LooseVersion("0.0"):
                if LooseVersion(versions[packageName.lower()]) < LooseVersion(minVersion):
                    Console.info(Console.colorize(Console.colorize('Jasy requirement error: "%s"' % packageName, "red"), "bold"))
                    Console.indent()
                    Console.info(Console.colorize(Console.colorize('Version is NOT OK (needed: %s installed: %s)' % (minVersion, versions[packageName.lower()]) , "red"), "bold"))
                    Console.info('Update to the newest version of %s using %s' % (packageName, updatePath))
                    Console.outdent()
                    return False
        else:
            Console.info(Console.colorize(Console.colorize('Jasy requirement error: "%s"' % packageName, "red"), "bold"))
            Console.indent()
            Console.info(Console.colorize(Console.colorize('Did NOT find installation', "red"), "bold"))
            Console.info('Install the newest version of %s using %s' % (packageName, installPath))
            Console.outdent()
            return False

        return True
コード例 #35
0
ファイル: Inspect.py プロジェクト: sebastian-software/jasy
def highlightArgs(value, inClassOrObject=False):

    argsspec = inspect.getfullargspec(value)

    if inClassOrObject and argsspec.args and argsspec.args[0] == "self":
        del argsspec.args[0]

    argmsg = "(%s" % ", ".join(argsspec.args)

    if argsspec.varkw is not None:
        if argsspec.args:
            argmsg += ", "

        argmsg += "..."

    argmsg += ")"

    return Console.colorize(argmsg, "cyan")
コード例 #36
0
ファイル: Inspect.py プロジェクト: isabella232/jasy
def highlightArgs(value, inClassOrObject=False):

    argsspec = inspect.getfullargspec(value)

    if inClassOrObject and argsspec.args and argsspec.args[0] == "self":
        del argsspec.args[0]

    argmsg = "(%s" % ", ".join(argsspec.args)

    if argsspec.varkw is not None:
        if argsspec.args:
            argmsg += ", "

        argmsg += "..."

    argmsg += ")"

    return Console.colorize(argmsg, "cyan")
コード例 #37
0
    def set(self, name, value, accept=None, parse=False):
        """
        Saves the given value under the given field
        """

        # Don't accept None value
        if value is None:
            return False

        # Parse value for easy type checks
        if parse:
            try:
                parsedValue = eval(value)
            except:
                pass
            else:
                value = parsedValue

                # Convert tuples/sets into JSON compatible array
                if type(value) in (tuple, set):
                    value = list(value)

        # Check for given type
        if accept is not None and not matchesType(value, accept):
            print(Console.colorize("  - Invalid value: %s" % str(value),
                                   "red"))
            return False

        if "." in name:
            splits = name.split(".")
            current = self.__data
            for split in splits[:-1]:
                if not split in current:
                    current[split] = {}

                current = current[split]

            current[splits[-1]] = value

        else:
            self.__data[name] = value

        return True
コード例 #38
0
ファイル: Doctor.py プロジェクト: zynga/jasy
    def checkSingleInstallation(keys, versions, packageName, minVersion,
                                installPath, updatePath):
        if packageName.lower() in keys:
            if LooseVersion(minVersion) > LooseVersion("0.0"):
                if LooseVersion(versions[packageName.lower()]) < LooseVersion(
                        minVersion):
                    Console.info(
                        Console.colorize(
                            Console.colorize(
                                'Jasy requirement error: "%s"' % packageName,
                                "red"), "bold"))
                    Console.indent()
                    Console.info(
                        Console.colorize(
                            Console.colorize(
                                'Version is NOT OK (needed: %s installed: %s)'
                                % (minVersion, versions[packageName.lower()]),
                                "red"), "bold"))
                    Console.info(
                        'Update to the newest version of %s using %s' %
                        (packageName, updatePath))
                    Console.outdent()
                    return False
        else:
            Console.info(
                Console.colorize(
                    Console.colorize(
                        'Jasy requirement error: "%s"' % packageName, "red"),
                    "bold"))
            Console.indent()
            Console.info(
                Console.colorize(
                    Console.colorize('Did NOT find installation', "red"),
                    "bold"))
            Console.info('Install the newest version of %s using %s' %
                         (packageName, installPath))
            Console.outdent()
            return False

        return True
コード例 #39
0
ファイル: Config.py プロジェクト: Andais/jasy
    def set(self, name, value, accept=None, parse=False):
        """
        Saves the given value under the given field
        """

        # Don't accept None value
        if value is None:
            return False

        # Parse value for easy type checks
        if parse:
            try:
                parsedValue = eval(value)
            except:
                pass
            else:
                value = parsedValue

                # Convert tuples/sets into JSON compatible array
                if type(value) in (tuple, set):
                    value = list(value)

        # Check for given type
        if accept is not None and not matchesType(value, accept):
            print(Console.colorize("  - Invalid value: %s" % str(value), "red"))
            return False

        if "." in name:
            splits = name.split(".")
            current = self.__data
            for split in splits[:-1]:
                if not split in current:
                    current[split] = {}

                current = current[split]

            current[splits[-1]] = value

        else:
            self.__data[name] = value

        return True
コード例 #40
0
ファイル: Doctor.py プロジェクト: Zenwolf/jasy
 def checkSingleInstallation(keys, versions, packageName, minVersion, installPath, updatePath):
     Console.info('%s:' % packageName)
     Console.indent()
     if packageName.lower() in keys:
         Console.info(Console.colorize('Found installation', "green"))
         if LooseVersion(minVersion) > LooseVersion("0.0"):
             if LooseVersion(versions[packageName.lower()]) >= LooseVersion(minVersion):
                 Console.info(Console.colorize('Version is OK (needed: %s installed: %s)' % (minVersion, versions[packageName.lower()]), "green"))
             else:
                 Console.info(Console.colorize(Console.colorize('- Version is NOT OK (needed: %s installed: %s)' % (minVersion, versions[packageName.lower()]) , "red"), "bold"))
                 Console.info('Update to the newest version of %s using %s' % (packageName, updatePath))
     else:
         Console.info(Console.colorize(Console.colorize('Did NOT find installation', "red"), "bold"))
         Console.info('Install the newest version of %s using %s' % (packageName, installPath))
     Console.outdent()
コード例 #41
0
    def __resolve(project):

        name = project.getName()

        # List of required projects
        Console.info("Getting requirements of %s...",
                     Console.colorize(name, "bold"))
        Console.indent()
        requires = project.getRequires(checkoutDirectory, updateRepositories)
        Console.outdent()

        if not requires:
            return

        Console.debug("Processing %s requirements...", len(requires))
        Console.indent()

        # Adding all project in reverse order.
        # Adding all local ones first before going down to their requirements
        childProjects = []
        for requiredProject in reversed(requires):
            requiredName = requiredProject.getName()
            if requiredName not in names:
                Console.debug("Adding: %s %s (via %s)", requiredName,
                              requiredProject.version, project.getName())
                names[requiredName] = True
                result.append(requiredProject)
                childProjects.append(requiredProject)
            elif not requiredProject in result:
                Console.debug("Blocking: %s %s (via %s)", requiredName,
                              requiredProject.version, project.getName())
                requiredProject.pause()

        # Process all requirements of added projects
        for requiredProject in reversed(childProjects):
            if requiredProject.hasRequires():
                __resolve(requiredProject)

        Console.outdent()
コード例 #42
0
ファイル: Style.py プロジェクト: isabella232/jasy
    def __getPermutatedTree(self, permutation=None):
        """
        Returns a permutated tree: a copy of the original tree
        where conditions based on the given permutation are resolved.
        """

        if permutation is None:
            return self.__getTree()

        permutation = self.filterPermutation(permutation)
        field = "style:permutated[%s]-%s" % (self.id, permutation)
        tree = self.project.getCache().read(field, self.mtime)

        if not tree:
            tree = copy.deepcopy(self.__getTree())

            Console.info("Permutating stylesheet %s...", Console.colorize(self.id, "bold"))
            Console.indent()
            Engine.permutateTree(tree, permutation)
            Console.outdent()

            self.project.getCache().store(field, tree, self.mtime, True)

        return tree
コード例 #43
0
ファイル: Context.py プロジェクト: isabella232/jasy
def help():
    """Shows this help screen."""

    import jasy

    jasy.info()

    print(Console.colorize(Console.colorize("Usage", "underline"), "bold"))
    print("  $ jasy [<options...>] <task1> [<args...>] [<task2> [<args...>]]")

    print()
    print(Console.colorize(Console.colorize("Global Options", "underline"), "bold"))
    Task.getOptions().printOptions()

    print()
    print(Console.colorize(Console.colorize("Available Tasks", "underline"), "bold"))
    Task.printTasks()

    print()
コード例 #44
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()
コード例 #45
0
def massFilePatcher(path, data):

    # Convert method with access to local data
    def convertPlaceholder(mo):
        field = mo.group(1)
        value = data.get(field)

        # Verify that None means missing
        if value is None and not data.has(field):
            raise ValueError('No value for placeholder "%s"' % field)

        # Requires value being a string
        return str(value)

    # Patching files recursively
    Console.info("Patching files...")
    Console.indent()
    for dirPath, dirNames, fileNames in os.walk(path):
        relpath = os.path.relpath(dirPath, path)

        # Filter dotted directories like .git, .bzr, .hg, .svn, etc.
        for dirname in dirNames:
            if dirname.startswith("."):
                dirNames.remove(dirname)

        for fileName in fileNames:
            filePath = os.path.join(dirPath, fileName)
            fileRel = os.path.normpath(os.path.join(relpath, fileName))

            Console.debug("Processing: %s..." % fileRel)

            fileHandle = open(filePath,
                              "r",
                              encoding="utf-8",
                              errors="surrogateescape")
            fileContent = []

            # Parse file line by line to detect binary files early and omit
            # fully loading them into memory
            try:
                isBinary = False

                for line in fileHandle:
                    if '\0' in line:
                        isBinary = True
                        break
                    else:
                        fileContent.append(line)

                if isBinary:
                    Console.debug("Ignoring binary file: %s", fileRel)
                    continue

            except UnicodeDecodeError as ex:
                Console.warn("Can't process file: %s: %s", fileRel, ex)
                continue

            fileContent = "".join(fileContent)

            # Update content with available data
            try:
                resultContent = fieldPattern.sub(convertPlaceholder,
                                                 fileContent)
            except ValueError as ex:
                Console.warn("Unable to process file %s: %s!", fileRel, ex)
                continue

            # Only write file if there where any changes applied
            if resultContent != fileContent:
                Console.info("Updating: %s...",
                             Console.colorize(fileRel, "bold"))

                fileHandle = open(filePath,
                                  "w",
                                  encoding="utf-8",
                                  errors="surrogateescape")
                fileHandle.write(resultContent)
                fileHandle.close()

    Console.outdent()
コード例 #46
0
def create(name="myproject",
           origin=None,
           originVersion=None,
           skeleton=None,
           destination=None,
           session=None,
           **argv):
    """
    Creates a new project from a defined skeleton or an existing project's root directory (only if there is a jasycreate
    config file).

    :param name: The name of the new created project
    :type name: string
    :param origin: Path or git url to the base project
    :type origin: string
    :param originVersion: Version of the base project from wich will be created.
    :type originVersion: string
    :param skeleton: Name of a defined skeleton. None for creating from root
    :type skeleton: string
    :param destination: Destination path for the new created project
    :type destination: string
    :param session: An optional session to use as origin project
    :type session: object

    """

    if not validProjectName.match(name):
        raise UserError(
            "Invalid project name: %s (Use lowercase characters and numbers only for broadest compabibility)"
            % name)

    #
    # Initial Checks
    #

    # Figuring out destination folder
    if destination is None:
        destination = name

    destinationPath = os.path.abspath(os.path.expanduser(destination))
    if os.path.exists(destinationPath):
        raise UserError(
            "Cannot create project %s in %s. File or folder exists!" %
            (name, destinationPath))

    # Origin can be either:
    # 1) None, which means a skeleton from the current main project
    # 2) An repository URL
    # 3) A project name known inside the current session
    # 4) Relative or absolute folder path

    originPath = None
    originName = None

    if origin is None:
        originProject = session and session.getMain()

        if originProject is None:
            raise UserError(
                "Auto discovery failed! No Jasy projects registered!")

        originPath = originProject.getPath()
        originName = originProject.getName()
        originRevision = None

    elif Repository.isUrl(origin):
        Console.info("Using remote skeleton")

        tempDirectory = tempfile.TemporaryDirectory()
        originPath = os.path.join(tempDirectory.name, "clone")
        originUrl = origin

        Console.indent()
        originRevision = Repository.update(originUrl, originVersion,
                                           originPath)
        Console.outdent()

        if originRevision is None:
            raise UserError("Could not clone origin repository!")

        Console.debug("Cloned revision: %s" % originRevision)
        if findConfig(os.path.join(
                originPath, "jasycreate")) or os.path.isfile(
                    os.path.join(originPath, "jasycreate.py")):
            originProject = None
        else:
            originProject = getProjectFromPath(originPath, session)
            originName = originProject.getName()

    else:
        originProject = session and session.getProjectByName(origin)
        originVersion = None
        originRevision = None

        if originProject is not None:
            originPath = originProject.getPath()
            originName = origin

        elif os.path.isdir(origin):
            originPath = origin
            if findConfig(os.path.join(
                    originPath, "jasycreate")) or os.path.isfile(
                        os.path.join(originPath, "jasycreate.py")):
                originProject = None
            else:
                originProject = getProjectFromPath(originPath, session)
                originName = originProject.getName()

        else:
            raise UserError("Invalid value for origin: %s" % origin)

    # Figure out the skeleton root folder
    if originProject is not None:
        skeletonDir = os.path.join(
            originPath, originProject.getConfigValue("skeletonDir",
                                                     "skeleton"))
    else:
        skeletonDir = originPath
    if not os.path.isdir(skeletonDir):
        raise UserError('The project %s offers no skeletons!' % originName)

    # For convenience: Use first skeleton in skeleton folder if no other selection was applied
    if skeleton is None:
        if originProject is not None:
            skeleton = getFirstSubFolder(skeletonDir)
        else:
            skeleton = skeletonDir

    # Finally we have the skeleton path (the root folder to copy for our app)
    skeletonPath = os.path.join(skeletonDir, skeleton)
    if not os.path.isdir(skeletonPath):
        raise UserError('Skeleton %s does not exist in project "%s"' %
                        (skeleton, originName))

    #
    # Actual Work
    #

    # Prechecks done
    if originName:
        Console.info('Creating %s from %s %s...',
                     Console.colorize(name, "bold"),
                     Console.colorize(skeleton + " @", "bold"),
                     Console.colorize(originName, "magenta"))
    else:
        Console.info('Creating %s from %s...', Console.colorize(name, "bold"),
                     Console.colorize(skeleton, "bold"))
    Console.debug('Skeleton: %s', Console.colorize(skeletonPath, "grey"))
    Console.debug('Destination: %s', Console.colorize(destinationPath, "grey"))

    # Copying files to destination
    Console.info("Copying files...")
    shutil.copytree(skeletonPath, destinationPath)
    Console.debug("Files were copied successfully.")

    # Close origin project
    if originProject:
        originProject.close()

    # Change to directory before continuing
    os.chdir(destinationPath)

    # Create configuration file from question configs and custom scripts
    Console.info("Starting configuration...")
    config = Config()

    config.set("name", name)
    config.set("jasy.version", jasy.__version__)
    if originName:
        config.set("origin.name", originName)
    config.set("origin.version", originVersion)
    config.set("origin.revision", originRevision)
    config.set("origin.skeleton", os.path.basename(skeletonPath))

    config.injectValues(**argv)
    if originProject is not None:
        config.readQuestions("jasycreate", optional=True)
        config.executeScript("jasycreate.py", optional=True)

    # Do actual replacement of placeholders
    massFilePatcher(destinationPath, config)
    Console.debug("Files were patched successfully.")

    # Done
    Console.info('Your application %s was created successfully!',
                 Console.colorize(name, "bold"))
コード例 #47
0
ファイル: Doctor.py プロジェクト: zynga/jasy
def doCompleteDoctor():
    """Checks for uninstalled or too old versions of requirements and gives a complete output"""

    Console.header("Doctor")

    dists = [dist for dist in pip.get_installed_distributions()]
    keys = [dist.key for dist in pip.get_installed_distributions()]

    versions = {}
    for dist in dists:
        versions[dist.key] = dist.version

    def checkSingleInstallation(keys, versions, packageName, minVersion,
                                installPath, updatePath):
        Console.info('%s:' % packageName)
        Console.indent()
        if packageName.lower() in keys:
            Console.info(Console.colorize('Found installation', "green"))
            if LooseVersion(minVersion) > LooseVersion("0.0"):
                if LooseVersion(versions[packageName.lower()]) >= LooseVersion(
                        minVersion):
                    Console.info(
                        Console.colorize(
                            'Version is OK (needed: %s installed: %s)' %
                            (minVersion, versions[packageName.lower()]),
                            "green"))
                else:
                    Console.info(
                        Console.colorize(
                            Console.colorize(
                                '- Version is NOT OK (needed: %s installed: %s)'
                                % (minVersion, versions[packageName.lower()]),
                                "red"), "bold"))
                    Console.info(
                        'Update to the newest version of %s using %s' %
                        (packageName, updatePath))
        else:
            Console.info(
                Console.colorize(
                    Console.colorize('Did NOT find installation', "red"),
                    "bold"))
            Console.info('Install the newest version of %s using %s' %
                         (packageName, installPath))
        Console.outdent()

    # Required packages
    Console.info(Console.colorize("Required Packages:", "bold"))
    Console.indent()
    for entry in needs:
        checkSingleInstallation(keys, versions, entry["packageName"],
                                entry["minVersion"], entry["installPath"],
                                entry["updatePath"])
    Console.outdent()

    # Optional packages
    Console.info("")
    Console.info(Console.colorize("Optional Packages:", "bold"))
    Console.indent()
    for entry in optionals:
        checkSingleInstallation(keys, versions, entry["packageName"],
                                entry["minVersion"], entry["installPath"],
                                entry["updatePath"])
    Console.outdent()