'finds an approximation of the optimal distribution of the containers over the shards, provided a set of hard-coded weights '
        'in parsefiles_config.yml.')
    parser.add_argument('num_shards', type = int, help = "the number of shards amongst which to distribute Docker builds")

    return parser.parse_args()

if __name__ == '__main__':

    args = arg_parse()

    # configure logging
    logging.basicConfig()

    # get input from standard in
    images = read_input()

    # get images that are used and described in configuration file
    used_images = docker_images.get_used_images(images)

    # find optimal packing of the images amongst shards
    shards = pack_shards(used_images, args.num_shards)

    # print space separated list of containers for each shard
    for shard in shards:
        middle = " "

        conts = [x[0] for x in shard["images"]]

        line = middle.join(conts)
        print line
        type=int,
        help="the number of shards amongst which to distribute Docker builds")

    return parser.parse_args()


if __name__ == '__main__':

    args = arg_parse()

    # configure logging
    logging.basicConfig()

    # get input from standard in
    images = read_input()

    # get images that are used and described in configuration file
    used_images = docker_images.get_used_images(images)

    # find optimal packing of the images amongst shards
    shards = pack_shards(used_images, args.num_shards)

    # print space separated list of containers for each shard
    for shard in shards:
        middle = " "

        conts = [x[0] for x in shard["images"]]

        line = middle.join(conts)
        print line
    # gets any playbooks in the commit range
    plays = get_plays(change_set, BUILD_DIR, config["aws_plays_paths"])

    # transforms list of roles and plays into list of original roles and the roles contained in the plays
    roles = change_set_to_roles(change_set, BUILD_DIR, config["roles_paths"],
                                config["aws_plays_paths"], graph)

    # expands roles set to include roles that are dependent on existing roles
    dependent_roles = get_dependencies(roles, graph)

    # determine which docker plays cover at least one role
    docker_plays = get_docker_plays(dependent_roles, graph)

    docker_plays = docker_plays | plays

    # filter out docker plays without a Dockerfile
    docker_plays = filter_docker_plays(docker_plays, BUILD_DIR)

    # Add playbooks to the list whose docker file has been modified
    modified_docker_files = _get_modified_dockerfiles(change_set, BUILD_DIR)

    # Add plays to the list which got changed in docker/plays directory
    docker_plays_dir = get_modified_dockerfiles_plays(change_set, BUILD_DIR)

    all_plays = set(
        set(docker_plays) | set(modified_docker_files) | set(docker_plays_dir))
    used_images = docker_images.get_used_images(all_plays)
    if used_images:
        print " ".join(zip(*used_images)[0])