def install_app(apppath, appname, apptype, projectdir):
    """Copies the app into the project directory"""
    copy_functions = {
            'file': fromfilesys,
            'git': fromgit,
            'hg': fromhg,
            }
    try:
        cf = copy_functions[apptype]
    except __HOLE__:
        raise CopyError("App type not supported")

    # Copy the app into the app dir
    dst = os.path.join(projectdir, APPDIR, appname)
    cf(apppath, dst)

    # Detect whether this application is in "bare" form with application data
    # in the top most level of the repository, or in "package" form with the
    # application being one level removed and the top level containing a
    # setup.py, readme, license, etc.
    bare = -1 # unknown
    
    # The existance of a metadatafile in the application is a very good
    # indicator
    if os.path.exists(os.path.join(dst, "metadata.json")):
        bare = True
    if os.path.exists(os.path.join(dst, appname, "metadata.json")):
        bare = False

    if bare == -1:
        # Check for a models file
        if os.path.exists(os.path.join(dst, "models.py")):
            bare = True
        if os.path.exists(os.path.join(dst, appname, "models.py")):
            bare = False
    if bare == -1:
        # Check for a views.py file
        if os.path.exists(os.path.join(dst, "views.py")):
            bare = True
        if os.path.exists(os.path.join(dst, appname, "views.py")):
            bare = False

    if bare == -1:
        raise CopyError("Could not detect repository format. Please make sure your application has one of these files: metadata.json, models.py, or views.py")

    # Now symlink the application into the project itself
    if bare:
        os.symlink(dst, os.path.join(projectdir, appname))
    else:
        os.symlink(os.path.join(dst, appname),
                os.path.join(projectdir, appname))


###################
# Upgrade functions
###################
dataset/ETHPy150Open bmbouter/Opus/opus/lib/builder/sources.py/install_app