DoRead.py :  » Build » A-A-P » aap-1.091 » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Build » A A P 
A A P » aap 1.091 » DoRead.py
# Part of the A-A-P recipe executive: Read the toplevel recipe and process it

# Copyright (C) 2002-2003 Stichting NLnet Labs
# Permission to copy and use this file is specified in the file COPYING.
# If this file is missing you can find it here: http://www.a-a-p.org/COPYING

import os
import os.path
import string
import sys

from Work import Work,set_defaults,getwork
from Util import *
from Error import *
from DoArgs import add_cmdline_settings
import Global
from ParsePos import ParsePos
from Process import Process
from RecPos import RecPos
from Message import *
from Dictlist import list2str
import Scope


recipe_active = {}      # recipes that are currently being read


def recipe_dir(recdict, name):
    """
    When the directory of the recipe "name" is not the current directory,
    print the name of the directory and make it the current one.
    "name" must be an absolute path name.
    Return the recipe name relative to the new directory.
    """
    dirpath, tail = os.path.split(name)
    goto_dir(recdict, dirpath)
    return tail


def read_recipe_dir(recdict, dirname):
    """Check directory "dirname" for recipes and read them all."""
    from glob import glob
    for f in glob(os.path.join(dirname, "*.aap")):
        read_recipe([], recdict, f, 1)


def did_read_recipe(work, sname):
    """
    Return True if recipe "sname" was already read.
    """
    return work.recipe_already_read.get(full_fname(sname))


def read_recipe(rpstack, recdict, sname, toplevel, optional = 0, reread = 0):
    """
    Read a recipe, turn it into Python and execute the result.
    This will fill the "recdict" dictionary with the stuff found in the recipe.
    Included and child recipes will be loaded recursively.
    This doesn't execute the build commands in the recipe(s) yet.
    "toplevel" is non-zero when reading a recipe for the toplevel, zero for an
    ":include" command inside build commands.
    """
    name = full_fname(sname)
    if not reread and recipe_active.has_key(name):
        msg_warning(recdict,
                         _('Skipping recipe already being read: "%s"') % sname)
    else:
        # Remember that this recipe has been read, if there is a Work object.
        getwork(recdict).recipe_already_read[name] = 1

        try:
            fd = open(name, "r")
        except:
            if optional:
                msg_note(recdict, _('Recipe cannot be read: "%s"') % sname)
                return
            raise UserError, _('Cannot open "%s" for reading.') % sname

        if reread:
            msg_extra(recdict, _('Restart reading recipe "') + sname + '"')
        else:
            msg_extra(recdict, _('Reading recipe "') + sname + '"')

        recipe_active[name] = 1
        rpstack.append(RecPos(name))

        # create an object to contain the file position
        fp = ParsePos(rpstack, file = fd)

        #
        # Parse and execute the recipe.
        # Process() also closes the file.
        #
        try:
            Process(fp, recdict, toplevel)
            del recipe_active[name]
            msg_extra(recdict, _('Finished reading recipe "') + sname + '"')
        except OriginUpdate:
            # Encountered a ":fetch" command that updated the recipe file and
            # executed the new one, aap_recipe() then thows OriginUpdate to
            # cancel executing the old one.
            pass
        except FinishRecipe:
            # Encountered a ":finish" command.
            pass

        del rpstack[-1]


def doread(find_recipe, recipe = None):
    """
    Read the main recipe and process it (but don't execute the build rules).
    This will fill a Work object with the stuff found in the recipe.
    When "find_recipe" is zero, don't search for a "main.aap" recipe to use.
    When 'recipe' is not None read the recipe with this name.
    """

    # Reset recipe_active, an error may have left something behind.
    # Do save the old value, doread() may be invoked recursively.
    global recipe_active
    save_recipe_active = recipe_active
    recipe_active = {}

    # Create the empty "work" and toplevel recdict.
    work = Work()
    recdict = work.recdict

    # Read the default and startup recipes.
    set_defaults(recdict)

    # Add values set in the command line arguments
    add_cmdline_settings(recdict)

    # Set $TARGETARG.
    recdict["TARGETARG"] = list2str(Global.cmd_args.targets)

    # Mark all dependencies defined here as startup ones.
    for dep in work.dependencies:
        dep.startup = 1

    #
    # Decide which recipe to execute.
    #
    if recipe:
        recipe = os.path.abspath(recipe)
    elif Global.cmd_args.has_option("recipe"):
        # Use the recipe specified with "-f recipe"
        if Global.cmd_args.has_option("search-up"):
            msg_warning(recdict,
                             _("Recipe argument overrules --search-up option"))
        recipe = Global.cmd_args.options.get("recipe")
        from Remote import is_url
        if is_url(recipe):
            # If the recipe is a URL, fetch it into the local directory.
            from CopyMove import remote_copy_move
            dest = os.path.basename(recipe)
            failed = remote_copy_move([], recdict, 1, [ {"name" : recipe} ],
                           {"name" : dest}, {"interactive" : 1}, 0, errmsg = 1)
            if failed:
                raise UserError, _("Fetching recipe failed.")
            recipe = dest

        if recipe == "NONE":
            # Don't use a recipe, for: aap -f NONE -c ":print $AAP"
            recipe = None
        else:
            recipe = os.path.abspath(recipe)
    elif find_recipe:
        if Global.cmd_args.has_option("search-up"):
            # Search the directory tree upwards for a "main.aap" recipe.
            dirpath = os.getcwd()
            while dirpath:
                recipe = os.path.join(dirpath, "main.aap")
                if os.path.isfile(recipe):
                    break
                dirpath, tail = os.path.split(dirpath)
                if not tail:
                    dirpath = ''
            if not dirpath:
                raise UserError, _("Cannot find a main.aap file.")
        else:
            # Use the default recipe "main.aap".
            recipe = os.path.abspath("main.aap")
    else:
        recipe = None

    if recipe:
        if not os.path.isfile(recipe):
            raise UserError, _('Recipe file "%s" not found') % recipe

        # Go to the directory of the recipe.  We never return to the current
        # dir.
        recipe = recipe_dir(recdict, recipe)
        work.top_recipe = recipe

        post_cd_init(recdict, work)

        # Read and parse the recipe, results are added to "recdict".
        read_recipe([], recdict, recipe, 1)
    else:
        # Use the current directory.
        post_cd_init(recdict, work)

    # Restore the old "recipe_active".
    recipe_active = save_recipe_active

    return work


def post_cd_init(recdict, work):
    """Inits that can only be done when the top directory has been set."""
    # Need an absolute path to avoid ":cd" changes the meaning.
    recdict["PKGDIR"] = os.path.abspath("pack")

    # Open the message log here.
    msg_startlog(recdict)

    # Remember the top directory.
    work.top_dir = os.getcwd()
    recdict["TOPDIR"] = ''
    recdict["BASEDIR"] = '.'

    # Find Python modules in the directory of the recipe.
    sys.path.append(work.top_dir)


# vim: set sw=4 et sts=4 tw=79 fo+=l:
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.