# Part of the A-A-P recipe executive: Install a package

# 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.path

from Util import *
from RecPython import *
from RecPos import RecPos
from Message import *
from CopyMove import remote_copy_move
from DoRead import doread
from DoAddDef import doadddef
from DoBuild import dobuild

def doinstall(pkgname):
    """
    Install package "pkgname".
    Returns zero for success, non-zero for an error.
    """
    return install_pkg([RecPos("install package")], {}, pkgname)


def assert_pkg(rpstack, recdict, pkgname, optional = 0):
    """
    Assert that package "pkgname" is installed.
    Install it when it isn't present.
    """
    # Check if a command with the package name exists.
    while 1:
        if program_path(pkgname):
            return;

        # Can't find it, ask the user what to do.
        if optional:
            opt = "c. Continue anyway\n"
        else:
            opt = ""
        r = raw_input(('Cannot find package "%s"!\n' % pkgname) +
               ("1. Let Aap attempt installing the package\n"
                "2. Retry (install it yourself first)\n"
                "%s"
                "q. Quit\n"
                "Choice: " % opt))
        if not r:
            continue
        if optional and (r[0] == "c" or r[0] == 'C'):
            return;
        if r[0] == "q" or r[0] == 'Q':
            recipe_error(rpstack, _('Package "%s" was not found') % pkgname)
        if r[0] == "1":
            break

    # Install the package.
    install_pkg(rpstack, recdict, pkgname)


def install_pkg(rpstack, recdict, pkgname):
    """
    Install package "pkgname".
    """

    # Decide what directory the package recipes are located in.
    # E.g., for Unix: ~/.aap/packages/pkgname/
    home = home_dir()
    if not home:
        recipe_error(rpstack, _('No $HOME found'))
        return None
    pkgdir = os.path.join(home, "packages", pkgname)

    # Create the directory when needed.
    try:
        assert_dir(rpstack, recdict, pkgdir)
    except StandardError, e:
        recipe_error(rpstack, (_('Cannot create directory "%s": ') % pkgdir)
                                                                      + str(e))
    try:
        # Change directory to where package recipes are located.
        # Remember the current directory, so that we can go back.
        old_cwd = os.getcwd()
        try:
            goto_dir(recdict, pkgdir)
        except StandardError, e:
            recipe_error(rpstack, (_('Cannot change to directory "%s": ')
                                                            % pkgdir) + str(e))

        # Obtain the bootstrap recipe from the A-A-P web server.
        recipe = "boot.aap"
        url = ("http://www.a-a-p.org/package.php?package=%s&osname=%s"
                                                         % (pkgname, osname()))
        failed = remote_copy_move(rpstack, recdict, 1, 
                                    [ {"name" : url } ], {"name" : recipe},
                                    {"force": 1}, 0, errmsg = 1)
        if failed:
            recipe_error(rpstack, _('Cannot obtain package recipe for "%s"')
                                                                     % pkgname)

        # Create a Work object and fill it with the recipe contents.
        work = doread(0, recipe = recipe)
        recdict = work.recdict

        # Note: we don't add the default dependencies (install, clean) here.

        # Execute the recipe.
        if has_target(recdict, "all"):
            # This normally downloads and builds the package.
            dobuild(work, "all")
        if has_target(recdict, "install"):
            # Found an install target, execute it.
            dobuild(work, "install")
        else:
            # No install target, something must have gone wrong.
            msg_error(recdict,
                        _("Package recipe does not contain an install target"))
    finally:
        # Go back to the directory where we started.
        goto_dir(recdict, old_cwd)

    return work


# vim: set sw=4 et sts=4 tw=79 fo+=l:
