
"""
Convenience factory code for building operation object lists for pf.
Contains factory code to build basic operation chains as well as
janrain project operation chains.
"""

import pf
import os

def janrainProjectMaker(local_dir, name, modules):
    """
    A factory function which creates the appropriate list of Operation
    and Repository instances, given a JanRain, Inc. project name,
    local repository tree path, and a list of project module names.
    """
    remote = 'vault@repos:/home/vault/projects'
    data = {'name': name,
            'remote': remote}

    upstream_stable = pf.Repository('upstream stable',
        remote + '/%(name)s/stable' % data, True)

    upstream_testing = pf.Repository('upstream testing',
        remote + '/%(name)s/testing' % data, True)

    local_stable = pf.Repository('local stable',
        local_dir + '/%(name)s/stable' % data)

    local_testing = pf.Repository('local testing',
        local_dir + '/%(name)s/testing' % data)

    local_unstable = pf.Repository('working copy',
        local_dir + '/%(name)s/unstable' % data)

    skel = [(pf.Operation.pushpull, local_unstable, local_testing),
            (pf.Operation.pushpull, local_testing, upstream_testing),
            (pf.Operation.push, local_testing, local_stable),
            (pf.Operation.pushpull, local_stable, upstream_stable),
            ]

    # Use the skell tuples above to create Operation instances.  Each
    # tuple is (callback, repo_1, repo_2).  This loop creates the
    # right Operation instances for each "module" of a project.  For
    # example, the "phpstack" project has modules [openid, yadis].
    # This loop is necessary to create the operations for all modules
    # at a given "stability level"; for example, this creates all the
    # local_unstable -> local_testing paths for each module before
    # creating any other paths for the other operations.
    result = []
    for m in modules:
        for cb, r1, r2 in skel:
            result.append(cb(pf.Repository(r1.name, r1.path + '/' + m, r1.remote),
                             pf.Repository(r2.name, r2.path + '/' + m, r2.remote)))

    return result

def basic(dirs):
    """
    Given a list of dirs, create a list of push-pull operations
    between each consecutive pair.  N dirs results in (N-1)
    operations.  All resulting repos are assumed to be local.
    """
    repos = []
    for d in dirs:
        repos.append(pf.Repository(os.path.basename(d), d))

    return [pf.Operation.pushpull(repos[i], repos[i+1])
            for i in range(len(repos) - 1)]
