<commit_before>#!/usr/bin/env python3

import sys
import os
import shutil

import mvtools_exception
import mvtools_envvars
import path_utils

import detect_repo_type
import svn_lib

import delayed_file_backup
import maketimestamp
import get_platform

def make_patch_filename(path, operation, index):
    if operation is None:
        return "%s_reset_svn_repo_%s.patch" % (str(index), path_utils.basename_filtered(path))
    else:
        return "%s_reset_svn_repo_%s_%s.patch" % (str(index), operation, path_utils.basename_filtered(path))

def _report_patch(patch_filename):
    return "generated backup patch: [%s]" % patch_filename

def _test_repo_path(path):

    v, r = detect_repo_type.detect_repo_type(path)
    if not v:
        return False, r
    if r is None:
        return False, "Path [%s] does not point to a supported repository." % path
    return True, r

def reset_svn_repo_previous(target_repo, backup_obj, previous):

    report = []
    has_any_failed = False

    if previous is None:
        return False, ["Previous is unspecified"]

    v, r = svn_lib.get_previous_list(target_repo, previous)
    if not v:
        return False, ["Unable to retrieve list of previous for repo [%s]: [%s]" % (target_repo, r)]
    prev_list = r

    if previous > len(prev_list):
        return False, ["A higher quantity of previous has been requested than there are available previous revisions (repo [%s])" % target_repo]

    c = 0
    for pl in prev_list:
        c += 1

        if c > previous:
            break

        # generate the backup patch
        backup_filename = make_patch_filename(pl, "previous", c)
        backup_contents = ""
        v, r = svn_lib.diff(target_repo, None, pl)
        if not v:
            return False, ["Unable to retrieve diff of previous for repo [%s]: [%s]" % (target_repo, r)]
        backup_contents = r

        # make the backup patch
        v, r = backup_obj.make_backup("previous", backup_filename, backup_contents)
        gen_patch = r
        if not v:
            return False, ["Failed because [%s] already exists." % gen_patch]
        report.append(_report_patch(gen_patch))

    if previous > c:
        report.append("WARNING: more indices were requested to be reset than there were previous commits (repo: [%s], requested previous reset counts: [%d], total previous entries reset: [%d])" % (target_repo, previous, (c)))

    v, r = svn_lib.kill_previous(target_repo, previous)
    if not v:
        return False, ["Unable to rewind to previous for repo [%s]: [%s]" % (target_repo, r)]

    return (not has_any_failed), report

def reset_svn_repo_unversioned(target_repo, backup_obj):

    report = []
    has_any_failed = False

    v, r = svn_lib.get_list_unversioned(target_repo)
    if not v:
        return False, ["Unable to retrieve list of unversioned for repo [%s]: [%s]" % (target_repo, r)]
    unversioned_list = r

    # make backups first
    for ui in unversioned_list:

        subfolder = "unversioned"
        dn = path_utils.dirname_filtered(ui)
        if dn is None:
            return False, ["Failed because [%s]'s dirname can't be resolved." % ui]
        v, r = path_utils.based_path_find_outstanding_path(target_repo, dn)
        if v:
            subfolder = path_utils.concat_path(subfolder, r)

        # make the backup patch
        v, r = backup_obj.make_backup_frompath(subfolder, path_utils.basename_filtered(ui), ui)
        gen_patch = r
        if not v:
            return False, ["Failed because [%s] already exists." % gen_patch]
        report.append(_report_patch(gen_patch))

    # then delete all unversioned, files and folders (that contain unversioned files *only*)
    for ui in unversioned_list:
        if not path_utils.remove_path(ui):
            has_any_failed = True
            return False, ["Failed removing path [%s]" % ui]

    return (not has_any_failed), report

def reset_svn_repo_head(target_repo, backup_obj):

    report = []
    has_any_failed = False

    # get new+added files
    v, r = svn_lib.get_head_added_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of added files: [%s]" % r]
    added_files = r

    # get versioned+delete-scheduled files
    v, r = svn_lib.get_head_deleted_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of to-be-deleted files: [%s]" % r]
    to_be_deleted_files = r

    # get versioned+replace-scheduled files
    v, r = svn_lib.get_head_replaced_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of replaced files: [%s]" % r]
    replaced_files = r

    # get missing files
    v, r = svn_lib.get_head_missing_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of missing files: [%s]" % r]
    missing_files = r

    # get modified files
    v, r = svn_lib.get_head_modified_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of modified files: [%s]" % r]
    modified_files = r

    # get conflicted files
    v, r = svn_lib.get_head_conflicted_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of conflicted files: [%s]" % r]
    conflicted_files = r

    # un-add new+added files (will be left as unversioned in the repo)
    if len(added_files) > 0:
        v, r = svn_lib.revert(target_repo, added_files)
        if not v:
            return False, ["Failed attempting to un-add files: [%s]" % r]
        for af in added_files:
            report.append("file [%s] was un-added" % af)

    # un-delete files
    if len(to_be_deleted_files) > 0:
        v, r = svn_lib.revert(target_repo, to_be_deleted_files)
        if not v:
            return False, ["Failed attempting to un-delete files: [%s]" % r]
        for af in to_be_deleted_files:
            report.append("file [%s] was un-deleted" % af)

    # un-replace files
    if len(replaced_files) > 0:
        v, r = svn_lib.revert(target_repo, replaced_files)
        if not v:
            return False, ["Failed attempting to un-replace files: [%s]" % r]
        for rf in replaced_files:
            report.append("file [%s] was un-replaced" % rf)

    # restore missing
    for mf in missing_files:
        v, r = svn_lib.restore_subpath(target_repo, mf)
        if not v:
            return False, ["Failed attempting to restore missing file [%s]: [%s]" % (mf, r)]
        report.append("file [%s] has been restored" % mf)

    all_relevant_files_for_bk = []
    all_relevant_files_for_bk += modified_files.copy()
    all_relevant_files_for_bk += conflicted_files.copy()

    # revert files, backing them up first
    c = 0
    for mf in all_relevant_files_for_bk:
        c += 1

        # generate the backup patch
        backup_filename = make_patch_filename(mf, "head", c)
        backup_contents = ""
        v, r = svn_lib.diff(target_repo, [mf])
        if not v:
            return False, ["Failed retrieving diff for [%s]: [%s]" % (mf, r)]
        backup_contents = r

        subfolder = "head"
        dn = path_utils.dirname_filtered(mf)
        if dn is None:
            return False, ["Unable to resolve [%s]'s dirname." % mf]
        v, r = path_utils.based_path_find_outstanding_path(target_repo, dn)
        if v:
            subfolder = path_utils.concat_path(subfolder, r)

        # make the backup patch
        v, r = backup_obj.make_backup(subfolder, backup_filename, backup_contents)
        gen_patch = r
        if not v:
            return False, ["Failed because [%s] already exists." % gen_patch]

        # revert file changes
        v, r = svn_lib.revert(target_repo, [mf])
        if not v:
            return False, ["[%s] patch was generated but reverting failed: [%s]" % (gen_patch, r)]
        report.append(_report_patch(gen_patch))

    return (not has_any_failed), report

def reset_svn_repo(target_repo, head, unversioned, previous):

    target_repo = path_utils.filter_remove_trailing_sep(target_repo)
    target_repo = os.path.abspath(target_repo)

    if not os.path.exists(target_repo):
        return False, ["Target repository %s does not exist" % target_repo]

    v, r = _test_repo_path(target_repo)
    if not v:
        return False, [r]
    detected_repo_type = r
    if detected_repo_type != detect_repo_type.REPO_TYPE_SVN:
        return False, ["Unsupported repository type: [%s] and [%s]." % (target_repo, detected_repo_type)]

    v, r = mvtools_envvars.mvtools_envvar_read_temp_path()
    if not v:
        return False, [r]
    temp_path = r
    if not os.path.exists(temp_path):
        return False, ["Can't reset svn repo. MVTOOLS_TEMP_PATH envvar is not defined or the path does not exist."]

    timestamp_now = maketimestamp.get_timestamp_now_compact()
    backup_patches_folder = "%s_reset_svn_repo_backup_%s" % (path_utils.basename_filtered(target_repo), timestamp_now)
    backup_patches_folder_fullpath = path_utils.concat_path(temp_path, backup_patches_folder)

    try:
        backup_obj = delayed_file_backup.delayed_file_backup(backup_patches_folder_fullpath)
    except mvtools_exception.mvtools_exception as mvtex:
        return False, [mvtex.message]

    has_any_failed = False
    report = []

    # head
    if head:
        v, r = reset_svn_repo_head(target_repo, backup_obj)
        if not v:
            has_any_failed = True
            report.append("reset_svn_repo_head: [%s]." % r)
        else:
            report += r

    # unversioned
    if unversioned:
        v, r = reset_svn_repo_unversioned(target_repo, backup_obj)
        if not v:
            has_any_failed = True
            report.append("reset_svn_repo_unversioned: [%s]." % r)
        else:
            report += r

    # previous
    if previous > 0:
        v, r = reset_svn_repo_previous(target_repo, backup_obj, previous)
        if not v:
            has_any_failed = True
            report.append("reset_svn_repo_previous: [%s]." % r)
        else:
            report += r

    return (not has_any_failed), report

def puaq():
    print("Usage: %s target_repo [--head] [--unversioned] [--previous X]" % path_utils.basename_filtered(__file__))
    sys.exit(1)

if __name__ == "__main__":

    if len(sys.argv) < 2:
        puaq()

    target_repo = sys.argv[1]
    params = sys.argv[2:]

    head = False
    unversioned = False
    previous = 0
    previous_parse_next = False

    for p in params:

        if previous_parse_next:
            previous = int(p)
            previous_parse_next = False
            continue

        if p == "--head":
            head = True
        elif p == "--unversioned":
            unversioned = True
        elif p == "--previous":
            previous_parse_next = True

    v, r = reset_svn_repo(target_repo, head, unversioned, previous)
    for i in r:
        print(i)
    if not v:
        print("Not everything succeeded.")
        sys.exit(1)
    print("All succeeded.")
<commit_msg>reset_svn_repo: removed a tiny piece of redundant/dead code<commit_after>#!/usr/bin/env python3

import sys
import os
import shutil

import mvtools_exception
import mvtools_envvars
import path_utils

import detect_repo_type
import svn_lib

import delayed_file_backup
import maketimestamp
import get_platform

def make_patch_filename(path, operation, index):
    if operation is None:
        return "%s_reset_svn_repo_%s.patch" % (str(index), path_utils.basename_filtered(path))
    else:
        return "%s_reset_svn_repo_%s_%s.patch" % (str(index), operation, path_utils.basename_filtered(path))

def _report_patch(patch_filename):
    return "generated backup patch: [%s]" % patch_filename

def _test_repo_path(path):

    v, r = detect_repo_type.detect_repo_type(path)
    if not v:
        return False, r
    if r is None:
        return False, "Path [%s] does not point to a supported repository." % path
    return True, r

def reset_svn_repo_previous(target_repo, backup_obj, previous):

    report = []
    has_any_failed = False

    if previous is None:
        return False, ["Previous is unspecified"]

    v, r = svn_lib.get_previous_list(target_repo, previous)
    if not v:
        return False, ["Unable to retrieve list of previous for repo [%s]: [%s]" % (target_repo, r)]
    prev_list = r

    if previous > len(prev_list):
        return False, ["A higher quantity of previous has been requested than there are available previous revisions (repo [%s])" % target_repo]

    c = 0
    for pl in prev_list:
        c += 1

        if c > previous:
            break

        # generate the backup patch
        backup_filename = make_patch_filename(pl, "previous", c)
        backup_contents = ""
        v, r = svn_lib.diff(target_repo, None, pl)
        if not v:
            return False, ["Unable to retrieve diff of previous for repo [%s]: [%s]" % (target_repo, r)]
        backup_contents = r

        # make the backup patch
        v, r = backup_obj.make_backup("previous", backup_filename, backup_contents)
        gen_patch = r
        if not v:
            return False, ["Failed because [%s] already exists." % gen_patch]
        report.append(_report_patch(gen_patch))

    if previous > c:
        report.append("WARNING: more indices were requested to be reset than there were previous commits (repo: [%s], requested previous reset counts: [%d], total previous entries reset: [%d])" % (target_repo, previous, (c)))

    v, r = svn_lib.kill_previous(target_repo, previous)
    if not v:
        return False, ["Unable to rewind to previous for repo [%s]: [%s]" % (target_repo, r)]

    return (not has_any_failed), report

def reset_svn_repo_unversioned(target_repo, backup_obj):

    report = []
    has_any_failed = False

    v, r = svn_lib.get_list_unversioned(target_repo)
    if not v:
        return False, ["Unable to retrieve list of unversioned for repo [%s]: [%s]" % (target_repo, r)]
    unversioned_list = r

    # make backups first
    for ui in unversioned_list:

        subfolder = "unversioned"
        dn = path_utils.dirname_filtered(ui)
        if dn is None:
            return False, ["Failed because [%s]'s dirname can't be resolved." % ui]
        v, r = path_utils.based_path_find_outstanding_path(target_repo, dn)
        if v:
            subfolder = path_utils.concat_path(subfolder, r)

        # make the backup patch
        v, r = backup_obj.make_backup_frompath(subfolder, path_utils.basename_filtered(ui), ui)
        gen_patch = r
        if not v:
            return False, ["Failed because [%s] already exists." % gen_patch]
        report.append(_report_patch(gen_patch))

    # then delete all unversioned, files and folders (that contain unversioned files *only*)
    for ui in unversioned_list:
        if not path_utils.remove_path(ui):
            return False, ["Failed removing path [%s]" % ui]

    return (not has_any_failed), report

def reset_svn_repo_head(target_repo, backup_obj):

    report = []
    has_any_failed = False

    # get new+added files
    v, r = svn_lib.get_head_added_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of added files: [%s]" % r]
    added_files = r

    # get versioned+delete-scheduled files
    v, r = svn_lib.get_head_deleted_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of to-be-deleted files: [%s]" % r]
    to_be_deleted_files = r

    # get versioned+replace-scheduled files
    v, r = svn_lib.get_head_replaced_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of replaced files: [%s]" % r]
    replaced_files = r

    # get missing files
    v, r = svn_lib.get_head_missing_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of missing files: [%s]" % r]
    missing_files = r

    # get modified files
    v, r = svn_lib.get_head_modified_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of modified files: [%s]" % r]
    modified_files = r

    # get conflicted files
    v, r = svn_lib.get_head_conflicted_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of conflicted files: [%s]" % r]
    conflicted_files = r

    # un-add new+added files (will be left as unversioned in the repo)
    if len(added_files) > 0:
        v, r = svn_lib.revert(target_repo, added_files)
        if not v:
            return False, ["Failed attempting to un-add files: [%s]" % r]
        for af in added_files:
            report.append("file [%s] was un-added" % af)

    # un-delete files
    if len(to_be_deleted_files) > 0:
        v, r = svn_lib.revert(target_repo, to_be_deleted_files)
        if not v:
            return False, ["Failed attempting to un-delete files: [%s]" % r]
        for af in to_be_deleted_files:
            report.append("file [%s] was un-deleted" % af)

    # un-replace files
    if len(replaced_files) > 0:
        v, r = svn_lib.revert(target_repo, replaced_files)
        if not v:
            return False, ["Failed attempting to un-replace files: [%s]" % r]
        for rf in replaced_files:
            report.append("file [%s] was un-replaced" % rf)

    # restore missing
    for mf in missing_files:
        v, r = svn_lib.restore_subpath(target_repo, mf)
        if not v:
            return False, ["Failed attempting to restore missing file [%s]: [%s]" % (mf, r)]
        report.append("file [%s] has been restored" % mf)

    all_relevant_files_for_bk = []
    all_relevant_files_for_bk += modified_files.copy()
    all_relevant_files_for_bk += conflicted_files.copy()

    # revert files, backing them up first
    c = 0
    for mf in all_relevant_files_for_bk:
        c += 1

        # generate the backup patch
        backup_filename = make_patch_filename(mf, "head", c)
        backup_contents = ""
        v, r = svn_lib.diff(target_repo, [mf])
        if not v:
            return False, ["Failed retrieving diff for [%s]: [%s]" % (mf, r)]
        backup_contents = r

        subfolder = "head"
        dn = path_utils.dirname_filtered(mf)
        if dn is None:
            return False, ["Unable to resolve [%s]'s dirname." % mf]
        v, r = path_utils.based_path_find_outstanding_path(target_repo, dn)
        if v:
            subfolder = path_utils.concat_path(subfolder, r)

        # make the backup patch
        v, r = backup_obj.make_backup(subfolder, backup_filename, backup_contents)
        gen_patch = r
        if not v:
            return False, ["Failed because [%s] already exists." % gen_patch]

        # revert file changes
        v, r = svn_lib.revert(target_repo, [mf])
        if not v:
            return False, ["[%s] patch was generated but reverting failed: [%s]" % (gen_patch, r)]
        report.append(_report_patch(gen_patch))

    return (not has_any_failed), report

def reset_svn_repo(target_repo, head, unversioned, previous):

    target_repo = path_utils.filter_remove_trailing_sep(target_repo)
    target_repo = os.path.abspath(target_repo)

    if not os.path.exists(target_repo):
        return False, ["Target repository %s does not exist" % target_repo]

    v, r = _test_repo_path(target_repo)
    if not v:
        return False, [r]
    detected_repo_type = r
    if detected_repo_type != detect_repo_type.REPO_TYPE_SVN:
        return False, ["Unsupported repository type: [%s] and [%s]." % (target_repo, detected_repo_type)]

    v, r = mvtools_envvars.mvtools_envvar_read_temp_path()
    if not v:
        return False, [r]
    temp_path = r
    if not os.path.exists(temp_path):
        return False, ["Can't reset svn repo. MVTOOLS_TEMP_PATH envvar is not defined or the path does not exist."]

    timestamp_now = maketimestamp.get_timestamp_now_compact()
    backup_patches_folder = "%s_reset_svn_repo_backup_%s" % (path_utils.basename_filtered(target_repo), timestamp_now)
    backup_patches_folder_fullpath = path_utils.concat_path(temp_path, backup_patches_folder)

    try:
        backup_obj = delayed_file_backup.delayed_file_backup(backup_patches_folder_fullpath)
    except mvtools_exception.mvtools_exception as mvtex:
        return False, [mvtex.message]

    has_any_failed = False
    report = []

    # head
    if head:
        v, r = reset_svn_repo_head(target_repo, backup_obj)
        if not v:
            has_any_failed = True
            report.append("reset_svn_repo_head: [%s]." % r)
        else:
            report += r

    # unversioned
    if unversioned:
        v, r = reset_svn_repo_unversioned(target_repo, backup_obj)
        if not v:
            has_any_failed = True
            report.append("reset_svn_repo_unversioned: [%s]." % r)
        else:
            report += r

    # previous
    if previous > 0:
        v, r = reset_svn_repo_previous(target_repo, backup_obj, previous)
        if not v:
            has_any_failed = True
            report.append("reset_svn_repo_previous: [%s]." % r)
        else:
            report += r

    return (not has_any_failed), report

def puaq():
    print("Usage: %s target_repo [--head] [--unversioned] [--previous X]" % path_utils.basename_filtered(__file__))
    sys.exit(1)

if __name__ == "__main__":

    if len(sys.argv) < 2:
        puaq()

    target_repo = sys.argv[1]
    params = sys.argv[2:]

    head = False
    unversioned = False
    previous = 0
    previous_parse_next = False

    for p in params:

        if previous_parse_next:
            previous = int(p)
            previous_parse_next = False
            continue

        if p == "--head":
            head = True
        elif p == "--unversioned":
            unversioned = True
        elif p == "--previous":
            previous_parse_next = True

    v, r = reset_svn_repo(target_repo, head, unversioned, previous)
    for i in r:
        print(i)
    if not v:
        print("Not everything succeeded.")
        sys.exit(1)
    print("All succeeded.")
<|endoftext|>


<commit_before>#!/usr/bin/env python3

import sys
import os
import shutil

import mvtools_exception
import mvtools_envvars
import path_utils

import detect_repo_type
import svn_lib

import delayed_file_backup
import maketimestamp
import get_platform

def make_patch_filename(path, operation, index):
    if operation is None:
        return "%s_reset_svn_repo_%s.patch" % (str(index), path_utils.basename_filtered(path))
    else:
        return "%s_reset_svn_repo_%s_%s.patch" % (str(index), operation, path_utils.basename_filtered(path))

def _report_patch(patch_filename):
    return "generated backup patch: [%s]" % patch_filename

def _test_repo_path(path):

    v, r = detect_repo_type.detect_repo_type(path)
    if not v:
        return False, r
    if r is None:
        return False, "Path [%s] does not point to a supported repository." % path
    return True, r

def reset_svn_repo_head(target_repo, backup_obj):

    report = []
    has_any_failed = False

    # get new+added files
    v, r = svn_lib.get_head_added_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of added files: [%s]" % r]
    added_files = r

    # get versioned+delete-scheduled files
    v, r = svn_lib.get_head_deleted_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of to-be-deleted files: [%s]" % r]
    to_be_deleted_files = r

    # get versioned+replace-scheduled files
    v, r = svn_lib.get_head_replaced_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of replaced files: [%s]" % r]
    replaced_files = r

    # get missing files
    v, r = svn_lib.get_head_missing_files(target_repo)
    if not v:
        return False, ["reset_svn_repo_file: Unable to retrieve list of missing files: [%s]" % r]
    missing_files = r

    # get modified files
    v, r = svn_lib.get_head_modified_files(target_repo)
    if not v:
        return False, ["reset_svn_repo_file: Unable to retrieve list of modified files: [%s]" % r]
    modified_files = r

    # get conflicted files
    v, r = svn_lib.get_head_conflicted_files(target_repo)
    if not v:
        return False, ["reset_svn_repo_file: Unable to retrieve list of conflicted files: [%s]" % r]
    conflicted_files = r

    # un-add new+added files (will be left as unversioned in the repo)
    if len(added_files) > 0:
        v, r = svn_lib.revert(target_repo, added_files)
        if not v:
            return False, ["Failed attempting to un-add files: [%s]" % r]
        for af in added_files:
            report.append("File [%s] was un-added" % af)

    # un-delete files
    if len(to_be_deleted_files) > 0:
        v, r = svn_lib.revert(target_repo, to_be_deleted_files)
        if not v:
            return False, ["Failed attempting to un-delete files: [%s]" % r]
        for af in to_be_deleted_files:
            report.append("File [%s] was un-deleted" % af)

    # un-replace files
    if len(replaced_files) > 0:
        v, r = svn_lib.revert(target_repo, replaced_files)
        if not v:
            return False, ["Failed attempting to un-replace files: [%s]" % r]
        for rf in replaced_files:
            report.append("File [%s] was un-replaced" % rf)

    # restore missing
    for mf in missing_files:
        v, r = svn_lib.restore_subpath(target_repo, mf)
        if not v:
            return False, ["Failed attempting to restore file [%s]: [%s]" % (mf, r)]
        report.append("file [%s] has been restored" % mf)

    all_relevant_files_for_bk = []
    all_relevant_files_for_bk += modified_files.copy()
    all_relevant_files_for_bk += conflicted_files.copy()

    # revert files, backing them up first
    c = 0
    for mf in all_relevant_files_for_bk:
        c += 1

        # generate the backup patch
        backup_filename = make_patch_filename(mf, "head", c)
        backup_contents = ""
        v, r = svn_lib.diff(target_repo, [mf])
        if not v:
            return False, ["Failed retrieving diff for [%s]: [%s]" % (mf, r)]
        backup_contents = r

        subfolder = "head"
        dn = path_utils.dirname_filtered(mf)
        if dn is None:
            return False, ["Unable to resolve [%s]'s dirname." % mf]
        v, r = path_utils.based_path_find_outstanding_path(target_repo, dn)
        if v:
            subfolder = path_utils.concat_path(subfolder, r)

        # make the backup patch
        v, r = backup_obj.make_backup(subfolder, backup_filename, backup_contents)
        gen_patch = r
        if not v:
            return False, ["Failed because [%s] already exists." % gen_patch]

        # revert file changes
        v, r = svn_lib.revert(target_repo, [mf])
        if not v:
            return False, ["[%s] patch was generated but reverting failed: [%s]" % (gen_patch, r)]
        report.append(_report_patch(gen_patch))

    return (not has_any_failed), report

def reset_svn_repo(target_repo, head, unversioned, previous):

    target_repo = path_utils.filter_remove_trailing_sep(target_repo)
    target_repo = os.path.abspath(target_repo)

    if not os.path.exists(target_repo):
        return False, ["Target repository %s does not exist" % target_repo]

    v, r = _test_repo_path(target_repo)
    if not v:
        return False, [r]
    detected_repo_type = r
    if detected_repo_type != detect_repo_type.REPO_TYPE_SVN:
        return False, ["Unsupported repository type: [%s] and [%s]." % (target_repo, detected_repo_type)]

    v, r = mvtools_envvars.mvtools_envvar_read_temp_path()
    if not v:
        return False, [r]
    temp_path = r
    if not os.path.exists(temp_path):
        return False, ["Can't reset svn repo. MVTOOLS_TEMP_PATH envvar is not defined or the path does not exist."]

    timestamp_now = maketimestamp.get_timestamp_now_compact()
    backup_patches_folder = "%s_reset_svn_repo_backup_%s" % (path_utils.basename_filtered(target_repo), timestamp_now)
    backup_patches_folder_fullpath = path_utils.concat_path(temp_path, backup_patches_folder)

    try:
        backup_obj = delayed_file_backup.delayed_file_backup(backup_patches_folder_fullpath)
    except mvtools_exception.mvtools_exception as mvtex:
        return False, [mvtex.message]

    has_any_failed = False
    report = []

    # head
    if head:
        v, r = reset_svn_repo_head(target_repo, backup_obj)
        if not v:
            has_any_failed = True
            report.append("reset_svn_repo_head: [%s]." % r)
        else:
            report += r

    # mvtodo: unversioned

    # mvtodo: previous

    return (not has_any_failed), report

def puaq():
    print("Usage: %s target_repo [--head] [--unversioned] [--previous X]" % path_utils.basename_filtered(__file__))
    sys.exit(1)

if __name__ == "__main__":

    if len(sys.argv) < 2:
        puaq()

    target_repo = sys.argv[1]
    params = sys.argv[2:]

    head = False
    unversioned = False
    previous = 0
    previous_parse_next = False

    for p in params:

        if previous_parse_next:
            previous = int(p)
            previous_parse_next = False
            continue

        if p == "--head":
            head = True
        elif p == "--unversioned":
            unversioned = True
        elif p == "--previous":
            previous_parse_next = True

    v, r = reset_svn_repo(target_repo, head, unversioned, previous)
    for i in r:
        print(i)
    if not v:
        print("Not everything succeeded.")
        sys.exit(1)
    print("All succeeded.")
<commit_msg>reset_svn_repo: implemented the --unversioned switch<commit_after>#!/usr/bin/env python3

import sys
import os
import shutil

import mvtools_exception
import mvtools_envvars
import path_utils

import detect_repo_type
import svn_lib

import delayed_file_backup
import maketimestamp
import get_platform

def make_patch_filename(path, operation, index):
    if operation is None:
        return "%s_reset_svn_repo_%s.patch" % (str(index), path_utils.basename_filtered(path))
    else:
        return "%s_reset_svn_repo_%s_%s.patch" % (str(index), operation, path_utils.basename_filtered(path))

def _report_patch(patch_filename):
    return "generated backup patch: [%s]" % patch_filename

def _test_repo_path(path):

    v, r = detect_repo_type.detect_repo_type(path)
    if not v:
        return False, r
    if r is None:
        return False, "Path [%s] does not point to a supported repository." % path
    return True, r

def reset_svn_repo_unversioned(target_repo, backup_obj):

    report = []
    has_any_failed = False

    v, r = svn_lib.get_list_unversioned(target_repo)
    if not v:
        return False, ["reset_svn_repo_unversioned: [%s]" % r]
    unversioned_list = r

    # make backups first
    for ui in unversioned_list:

        subfolder = "unversioned"
        dn = path_utils.dirname_filtered(ui)
        if dn is None:
            return False, ["reset_svn_repo_previous: failed because [%s]'s dirname can't be resolved." % ui]
        v, r = path_utils.based_path_find_outstanding_path(target_repo, dn)
        if v:
            subfolder = path_utils.concat_path(subfolder, r)

        # make the backup patch
        v, r = backup_obj.make_backup_frompath(subfolder, path_utils.basename_filtered(ui), ui)
        gen_patch = r
        if not v:
            return False, ["reset_svn_repo_previous: failed because [%s] already exists." % gen_patch]
        report.append(_report_patch(gen_patch))

    # then delete all unversioned, files and folders (that contain unversioned files *only*)
    for ui in unversioned_list:
        if not path_utils.remove_path(ui):
            has_any_failed = True
            report.append("Failed removing path [%s]" % ui)

    return (not has_any_failed), report

def reset_svn_repo_head(target_repo, backup_obj):

    report = []
    has_any_failed = False

    # get new+added files
    v, r = svn_lib.get_head_added_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of added files: [%s]" % r]
    added_files = r

    # get versioned+delete-scheduled files
    v, r = svn_lib.get_head_deleted_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of to-be-deleted files: [%s]" % r]
    to_be_deleted_files = r

    # get versioned+replace-scheduled files
    v, r = svn_lib.get_head_replaced_files(target_repo)
    if not v:
        return False, ["Unable to retrieve list of replaced files: [%s]" % r]
    replaced_files = r

    # get missing files
    v, r = svn_lib.get_head_missing_files(target_repo)
    if not v:
        return False, ["reset_svn_repo_file: Unable to retrieve list of missing files: [%s]" % r]
    missing_files = r

    # get modified files
    v, r = svn_lib.get_head_modified_files(target_repo)
    if not v:
        return False, ["reset_svn_repo_file: Unable to retrieve list of modified files: [%s]" % r]
    modified_files = r

    # get conflicted files
    v, r = svn_lib.get_head_conflicted_files(target_repo)
    if not v:
        return False, ["reset_svn_repo_file: Unable to retrieve list of conflicted files: [%s]" % r]
    conflicted_files = r

    # un-add new+added files (will be left as unversioned in the repo)
    if len(added_files) > 0:
        v, r = svn_lib.revert(target_repo, added_files)
        if not v:
            return False, ["Failed attempting to un-add files: [%s]" % r]
        for af in added_files:
            report.append("File [%s] was un-added" % af)

    # un-delete files
    if len(to_be_deleted_files) > 0:
        v, r = svn_lib.revert(target_repo, to_be_deleted_files)
        if not v:
            return False, ["Failed attempting to un-delete files: [%s]" % r]
        for af in to_be_deleted_files:
            report.append("File [%s] was un-deleted" % af)

    # un-replace files
    if len(replaced_files) > 0:
        v, r = svn_lib.revert(target_repo, replaced_files)
        if not v:
            return False, ["Failed attempting to un-replace files: [%s]" % r]
        for rf in replaced_files:
            report.append("File [%s] was un-replaced" % rf)

    # restore missing
    for mf in missing_files:
        v, r = svn_lib.restore_subpath(target_repo, mf)
        if not v:
            return False, ["Failed attempting to restore file [%s]: [%s]" % (mf, r)]
        report.append("file [%s] has been restored" % mf)

    all_relevant_files_for_bk = []
    all_relevant_files_for_bk += modified_files.copy()
    all_relevant_files_for_bk += conflicted_files.copy()

    # revert files, backing them up first
    c = 0
    for mf in all_relevant_files_for_bk:
        c += 1

        # generate the backup patch
        backup_filename = make_patch_filename(mf, "head", c)
        backup_contents = ""
        v, r = svn_lib.diff(target_repo, [mf])
        if not v:
            return False, ["Failed retrieving diff for [%s]: [%s]" % (mf, r)]
        backup_contents = r

        subfolder = "head"
        dn = path_utils.dirname_filtered(mf)
        if dn is None:
            return False, ["Unable to resolve [%s]'s dirname." % mf]
        v, r = path_utils.based_path_find_outstanding_path(target_repo, dn)
        if v:
            subfolder = path_utils.concat_path(subfolder, r)

        # make the backup patch
        v, r = backup_obj.make_backup(subfolder, backup_filename, backup_contents)
        gen_patch = r
        if not v:
            return False, ["Failed because [%s] already exists." % gen_patch]

        # revert file changes
        v, r = svn_lib.revert(target_repo, [mf])
        if not v:
            return False, ["[%s] patch was generated but reverting failed: [%s]" % (gen_patch, r)]
        report.append(_report_patch(gen_patch))

    return (not has_any_failed), report

def reset_svn_repo(target_repo, head, unversioned, previous):

    target_repo = path_utils.filter_remove_trailing_sep(target_repo)
    target_repo = os.path.abspath(target_repo)

    if not os.path.exists(target_repo):
        return False, ["Target repository %s does not exist" % target_repo]

    v, r = _test_repo_path(target_repo)
    if not v:
        return False, [r]
    detected_repo_type = r
    if detected_repo_type != detect_repo_type.REPO_TYPE_SVN:
        return False, ["Unsupported repository type: [%s] and [%s]." % (target_repo, detected_repo_type)]

    v, r = mvtools_envvars.mvtools_envvar_read_temp_path()
    if not v:
        return False, [r]
    temp_path = r
    if not os.path.exists(temp_path):
        return False, ["Can't reset svn repo. MVTOOLS_TEMP_PATH envvar is not defined or the path does not exist."]

    timestamp_now = maketimestamp.get_timestamp_now_compact()
    backup_patches_folder = "%s_reset_svn_repo_backup_%s" % (path_utils.basename_filtered(target_repo), timestamp_now)
    backup_patches_folder_fullpath = path_utils.concat_path(temp_path, backup_patches_folder)

    try:
        backup_obj = delayed_file_backup.delayed_file_backup(backup_patches_folder_fullpath)
    except mvtools_exception.mvtools_exception as mvtex:
        return False, [mvtex.message]

    has_any_failed = False
    report = []

    # head
    if head:
        v, r = reset_svn_repo_head(target_repo, backup_obj)
        if not v:
            has_any_failed = True
            report.append("reset_svn_repo_head: [%s]." % r)
        else:
            report += r

    # unversioned
    if unversioned:
        v, r = reset_svn_repo_unversioned(target_repo, backup_obj)
        if not v:
            has_any_failed = True
            report.append("reset_svn_repo_unversioned: [%s]." % r)
        else:
            report += r

    # mvtodo: previous

    return (not has_any_failed), report

def puaq():
    print("Usage: %s target_repo [--head] [--unversioned] [--previous X]" % path_utils.basename_filtered(__file__))
    sys.exit(1)

if __name__ == "__main__":

    if len(sys.argv) < 2:
        puaq()

    target_repo = sys.argv[1]
    params = sys.argv[2:]

    head = False
    unversioned = False
    previous = 0
    previous_parse_next = False

    for p in params:

        if previous_parse_next:
            previous = int(p)
            previous_parse_next = False
            continue

        if p == "--head":
            head = True
        elif p == "--unversioned":
            unversioned = True
        elif p == "--previous":
            previous_parse_next = True

    v, r = reset_svn_repo(target_repo, head, unversioned, previous)
    for i in r:
        print(i)
    if not v:
        print("Not everything succeeded.")
        sys.exit(1)
    print("All succeeded.")
<|endoftext|>


<commit_before>#   Copyright (c) 2006-2007 Open Source Applications Foundation
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

"""This module provides the communication and management between the various
server interfaces and the browser's js interface"""

import copy, os
try:
    import json as simplejson
except:
    import simplejson
import logging
from uuid import uuid1
import windmill
from time import sleep

test_results_logger = logging.getLogger('test_results')

class ControllerQueue(object):

    def __init__(self, command_resolution_suite, test_resolution_suite):
        self.resolution_suites = {'test': test_resolution_suite,
                                  'command': command_resolution_suite}
        self.queue = []
        self.current_suite = None

    def add_command(self, command, suite_name=None):
        """Add Command to the controller queue"""
        if suite_name is None and not command.get('suite_name'):
            suite_name = self.current_suite
        command['suite_name'] = suite_name

        if command['params'].get('priority', None):
            priority = command['params'].pop('priority')
        else:
            priority = 0

        command['type'] = 'command'

        if type(priority) is int:
            self.queue.insert(priority, command)
        else:
            self.queue.append(command)

    def add_test(self, test, suite_name=None):
        if suite_name is None and not test.get('suite_name'):
            suite_name = self.current_suite
        test['suite_name'] = suite_name

        test['type'] = 'test'

        self.queue.append(test)

    def start_suite(self, suite_name):
        self.current_suite = suite_name

    def stop_suite(self):
        self.current_suite = None

    # def command(self, command):
    #     self.command_queue.insert(0, command)

    def next_action(self):

        if len(self.queue) is not 0:
            controller_action = self.queue.pop(0)
            self.resolution_suites[controller_action.pop('type')].add(controller_action)
            return controller_action
        else:
            return None

callback = {'version':'0.1'}

class TestResolutionSuite(object):
    """Collection of tests run and results"""
    result_processor = None

    def __init__(self):
        self.unresolved = {}
        self.resolved = {}
        self.current_suite = None

    def resolve(self, result, uuid, starttime, endtime, debug=None):
        """Resolve test by uuid"""
        test = self.unresolved.pop(uuid)
        if debug:
            test['debug'] = debug
        test['result'] = result
        test['starttime'] = starttime
        test['endtime'] = endtime
        self.resolved[uuid] = test

        if result is False:
            test_results_logger.error('Test Failure in test %s' % repr(test))
        elif result is True:
            test_results_logger.debug('Test Success in test %s' % repr(test))

        if self.result_processor is not None:
            if result is False:
                self.result_processor.failure(test, debug=debug)
            elif result is True:
                self.result_processor.success(test, debug=debug)

    def report_without_resolve(self, result, uuid, starttime, endtime, suite_name, debug=None):
        test = {'result':result, 'uuid':uuid, 'starttime':starttime, 'endtime':endtime,
                'suite_name':suite_name, 'debug':debug}
        if result is False:
            test_results_logger.error('Test Failure in test %s' % repr(test))
        elif result is True:
            test_results_logger.debug('Test Success in test %s' % repr(test))

        if self.result_processor is not None:
            if result is False:
                self.result_processor.failure(test, debug=debug)
            elif result is True:
                self.result_processor.success(test, debug=debug)

    def start_suite(self, suite_name):
        self.current_suite = suite_name

    def stop_suite(self):
        self.current_suite = None

    def add(self, test, suite_name=None):
        self.unresolved[test['params']['uuid']] = test

class CommandResolutionSuite(object):

    def __init__(self):
        self.unresolved = {}
        self.resolved ={}

    def resolve(self, status, uuid, result):
        """Resolve command by uuid"""
        command = self.unresolved.pop(uuid, None)
        command['status'] = status
        command['result'] = result
        self.resolved[uuid] = command

        if status is False:
            test_results_logger.error('Command Failure in command %s' % command)
        elif status is True:
            test_results_logger.debug('Command Succes in command %s' % command)

    def add(self, command, suite_name=None):
        self.unresolved[command['params']['uuid']] = command

class RecursiveRPC(object):

    def __init__(self, execution_method):
        self.execution_method = execution_method

    def __getattr__(self, key):
        """Call a method on the controller as if it was a local method"""
        class ExecuteJSONRecursiveAttribute(object):
            def __init__(self, name, execution_method):
                self.name = name
                self.execution_method = execution_method
            def __call__(self, **kwargs):
                rpc = {'method':self.name, 'params':kwargs}
                return self.execution_method(rpc)
            def __getattr__(self, key):
                return ExecuteRecursiveAttribute(self.name+'.'+key, self.execution_method)

        return ExecuteRecursiveAttribute(key, self.execution_method)

class RPCMethods(object):

    def __init__(self, queue, test_resolution_suite, command_resolution_suite):
        self._queue = queue
        self._logger = logging.getLogger('jsonrpc_methods_instance')
        self._test_resolution_suite = test_resolution_suite
        self._command_resolution_suite = command_resolution_suite

    def start_suite(self, suite_name):
        self._test_resolution_suite.start_suite(suite_name)
        self._queue.start_suite(suite_name)
        return 200

    def stop_suite(self):
        self._test_resolution_suite.stop_suite()
        return 200

    def add_object(self, queue_method, action_object, suite_name=None):
        """Procedue neutral addition method"""
        callback_object = copy.copy(callback)
        callback_object.update(action_object)
        if not callback_object['params'].get('uuid'):
            callback_object['params']['uuid'] = str(uuid1())
        self._logger.debug('Adding object %s' % str(callback_object))
        queue_method(callback_object, suite_name=suite_name)
        return callback_object['params']['uuid']

    def add_json_test(self, json, suite_name=None):
        """Add test from json object with 'method' and 'params' defined"""
        action_object = simplejson.loads(json)
        self.add_object(self._queue.add_test,  action_object, suite_name)
        return 200

    def add_test(self, test_object, suite_name=None):
        self.add_object(self._queue.add_test,  test_object, suite_name)
        return 200

    def add_json_command(self, json):
        """Add command from json object with 'method' and 'params' defined"""
        action_object = simplejson.loads(json)
        self.add_object(self._queue.add_command, action_object)
        return 200

    def add_command(self, command_object):
        """Add command from object"""
        self.add_object(self._queue.add_command, command_object)
        return 200

    def execute_object(self, queue_method, resolution_suite, action_object):
        """Procedure neutral blocking exeution of a given object."""
        uuid = self.add_object(queue_method, action_object)

        while not resolution_suite.resolved.get(uuid):
            sleep(.25)

        result = resolution_suite.resolved[uuid]
        result.pop('totaltime', None)
        return result

    def execute_json_command(self, json):
        """Add command from json object with 'method' and 'params' defined, block until it returns, return the result"""
        action_object = simplejson.loads(json)
        return self.execute_object(self._queue.add_command, self._command_resolution_suite, action_object)

    def execute_json_test(self, json):
        """Add test from json object with 'method' and 'params' defined, block until it returns, return the result"""
        action_object = simplejson.loads(json)
        return self.execute_object(self._queue.add_test, self._test_resolution_suite, action_object)

    def execute_command(self, action_object):
        """Add command from dict object with 'method' and 'params' defined, block until it returns, return the result"""
        return self.execute_object(self._queue.add_command, self._command_resolution_suite, action_object)

    def execute_test(self, action_object):
        """Add test from dict object with 'method' and 'params' defined, block until it returns, return the result"""
        return self.execute_object(self._queue.add_test, self._test_resolution_suite, action_object)

    def run_json_tests(self, tests):
        """Run list of json tests"""
        return self.run_tests([simplejson.loads(test) for test in tests])

    def run_tests(self, tests):
        """Run list of tests"""
        for test in tests:
            if test['method'].find('command') is -1:
                self.add_test(test)
            else:
                self.add_command(test)
        return 200

    def clear_queue(self):
        """Clear the server queue"""
        self._queue.queue = []
        return 200

class JSONRPCMethods(RPCMethods):

    def next_action(self):
        """The next action for the browser to execute"""
        windmill.ide_is_awake = True
        from windmill.bin import admin_lib
        if len(admin_lib.on_ide_awake) is not 0:
            for func in copy.copy(admin_lib.on_ide_awake):
                func()
                admin_lib.on_ide_awake.remove(func)

        action = self._queue.next_action()
        if action is not None:
            self._logger.debug('queue has next_action %s' % str(action))
            return action
        else:
            self._logger.debug('queue has no next_action, returning "pause" method')
            action = copy.copy(callback)
            action.update({'method':'defer'})
            return action

    def report(self, uuid, result, starttime, endtime, debug=None):
        """Report fass/fail for a test"""
        self._test_resolution_suite.resolve(result, uuid, starttime, endtime, debug)
        return 200

    def report_without_resolve(self, uuid, result, starttime, endtime, suite_name, debug=None):
        self._test_resolution_suite.report_without_resolve(result, uuid, starttime, endtime, suite_name, debug)
        return 200

    def command_result(self, status, uuid, result):
        self._command_resolution_suite.resolve(status, uuid, result)

    def status_change(self, status):
        pass

    def set_test_url(self, url):
        windmill.settings['FORWARDING_TEST_URL'] = url
        windmill.server.proxy.initial_forwarding_registry = {}
        windmill.server.proxy.forwarding_registry = {}
        return 200

    def restart_test_run(self, tests):
        self.clear_queue()
        self._test_resolution_suite.unresolved = {}
        self._command_resolution_suite.unresolved ={}
        for test in tests:
            self.add_test(test, suite_name=test.get('suite_name'))

    def create_save_file(self, transformer, suite_name, tests):
        if not windmill.settings['SAVES_PATH']:
            windmill.authoring.transforms.create_saves_path()
        for test in tests:
            if test.get('suite_name'):
                test.pop('suite_name')
            if test['params'].get('uuid'):
                test['params'].pop('uuid')
        return windmill.authoring.transforms.registry[transformer](suite_name, tests)

    def teardown(self):
        """teardown_module function for functest based python tests"""
        import windmill
        if windmill.settings['EXIT_ON_DONE']:
            from windmill.bin import admin_lib
            admin_lib.teardown(admin_lib.shell_objects_dict)
            windmill.runserver_running = False
            sleep(.25)

class XMLRPCMethods(RPCMethods):
    def stop_runserver(self):
        import windmill
        windmill.runserver_running = False

            <commit_msg>Adding tests option to teardown for jstests.<commit_after>#   Copyright (c) 2006-2007 Open Source Applications Foundation
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

"""This module provides the communication and management between the various
server interfaces and the browser's js interface"""

import copy, os
try:
    import json as simplejson
except:
    import simplejson
import logging
from uuid import uuid1
import windmill
from time import sleep

test_results_logger = logging.getLogger('test_results')

class ControllerQueue(object):

    def __init__(self, command_resolution_suite, test_resolution_suite):
        self.resolution_suites = {'test': test_resolution_suite,
                                  'command': command_resolution_suite}
        self.queue = []
        self.current_suite = None

    def add_command(self, command, suite_name=None):
        """Add Command to the controller queue"""
        if suite_name is None and not command.get('suite_name'):
            suite_name = self.current_suite
        command['suite_name'] = suite_name

        if command['params'].get('priority', None):
            priority = command['params'].pop('priority')
        else:
            priority = 0

        command['type'] = 'command'

        if type(priority) is int:
            self.queue.insert(priority, command)
        else:
            self.queue.append(command)

    def add_test(self, test, suite_name=None):
        if suite_name is None and not test.get('suite_name'):
            suite_name = self.current_suite
        test['suite_name'] = suite_name

        test['type'] = 'test'

        self.queue.append(test)

    def start_suite(self, suite_name):
        self.current_suite = suite_name

    def stop_suite(self):
        self.current_suite = None

    # def command(self, command):
    #     self.command_queue.insert(0, command)

    def next_action(self):

        if len(self.queue) is not 0:
            controller_action = self.queue.pop(0)
            self.resolution_suites[controller_action.pop('type')].add(controller_action)
            return controller_action
        else:
            return None

callback = {'version':'0.1'}

class TestResolutionSuite(object):
    """Collection of tests run and results"""
    result_processor = None

    def __init__(self):
        self.unresolved = {}
        self.resolved = {}
        self.current_suite = None

    def resolve(self, result, uuid, starttime, endtime, debug=None):
        """Resolve test by uuid"""
        test = self.unresolved.pop(uuid)
        if debug:
            test['debug'] = debug
        test['result'] = result
        test['starttime'] = starttime
        test['endtime'] = endtime
        self.resolved[uuid] = test

        if result is False:
            test_results_logger.error('Test Failure in test %s' % repr(test))
        elif result is True:
            test_results_logger.debug('Test Success in test %s' % repr(test))

        if self.result_processor is not None:
            if result is False:
                self.result_processor.failure(test, debug=debug)
            elif result is True:
                self.result_processor.success(test, debug=debug)

    def report_without_resolve(self, result, uuid, starttime, endtime, suite_name, debug=None):
        test = {'result':result, 'uuid':uuid, 'starttime':starttime, 'endtime':endtime,
                'suite_name':suite_name, 'debug':debug}
        if result is False:
            test_results_logger.error('Test Failure in test %s' % repr(test))
        elif result is True:
            test_results_logger.debug('Test Success in test %s' % repr(test))

        if self.result_processor is not None:
            if result is False:
                self.result_processor.failure(test, debug=debug)
            elif result is True:
                self.result_processor.success(test, debug=debug)

    def start_suite(self, suite_name):
        self.current_suite = suite_name

    def stop_suite(self):
        self.current_suite = None

    def add(self, test, suite_name=None):
        self.unresolved[test['params']['uuid']] = test

class CommandResolutionSuite(object):

    def __init__(self):
        self.unresolved = {}
        self.resolved ={}

    def resolve(self, status, uuid, result):
        """Resolve command by uuid"""
        command = self.unresolved.pop(uuid, None)
        command['status'] = status
        command['result'] = result
        self.resolved[uuid] = command

        if status is False:
            test_results_logger.error('Command Failure in command %s' % command)
        elif status is True:
            test_results_logger.debug('Command Succes in command %s' % command)

    def add(self, command, suite_name=None):
        self.unresolved[command['params']['uuid']] = command

class RecursiveRPC(object):

    def __init__(self, execution_method):
        self.execution_method = execution_method

    def __getattr__(self, key):
        """Call a method on the controller as if it was a local method"""
        class ExecuteJSONRecursiveAttribute(object):
            def __init__(self, name, execution_method):
                self.name = name
                self.execution_method = execution_method
            def __call__(self, **kwargs):
                rpc = {'method':self.name, 'params':kwargs}
                return self.execution_method(rpc)
            def __getattr__(self, key):
                return ExecuteRecursiveAttribute(self.name+'.'+key, self.execution_method)

        return ExecuteRecursiveAttribute(key, self.execution_method)

class RPCMethods(object):

    def __init__(self, queue, test_resolution_suite, command_resolution_suite):
        self._queue = queue
        self._logger = logging.getLogger('jsonrpc_methods_instance')
        self._test_resolution_suite = test_resolution_suite
        self._command_resolution_suite = command_resolution_suite

    def start_suite(self, suite_name):
        self._test_resolution_suite.start_suite(suite_name)
        self._queue.start_suite(suite_name)
        return 200

    def stop_suite(self):
        self._test_resolution_suite.stop_suite()
        return 200

    def add_object(self, queue_method, action_object, suite_name=None):
        """Procedue neutral addition method"""
        callback_object = copy.copy(callback)
        callback_object.update(action_object)
        if not callback_object['params'].get('uuid'):
            callback_object['params']['uuid'] = str(uuid1())
        self._logger.debug('Adding object %s' % str(callback_object))
        queue_method(callback_object, suite_name=suite_name)
        return callback_object['params']['uuid']

    def add_json_test(self, json, suite_name=None):
        """Add test from json object with 'method' and 'params' defined"""
        action_object = simplejson.loads(json)
        self.add_object(self._queue.add_test,  action_object, suite_name)
        return 200

    def add_test(self, test_object, suite_name=None):
        self.add_object(self._queue.add_test,  test_object, suite_name)
        return 200

    def add_json_command(self, json):
        """Add command from json object with 'method' and 'params' defined"""
        action_object = simplejson.loads(json)
        self.add_object(self._queue.add_command, action_object)
        return 200

    def add_command(self, command_object):
        """Add command from object"""
        self.add_object(self._queue.add_command, command_object)
        return 200

    def execute_object(self, queue_method, resolution_suite, action_object):
        """Procedure neutral blocking exeution of a given object."""
        uuid = self.add_object(queue_method, action_object)

        while not resolution_suite.resolved.get(uuid):
            sleep(.25)

        result = resolution_suite.resolved[uuid]
        result.pop('totaltime', None)
        return result

    def execute_json_command(self, json):
        """Add command from json object with 'method' and 'params' defined, block until it returns, return the result"""
        action_object = simplejson.loads(json)
        return self.execute_object(self._queue.add_command, self._command_resolution_suite, action_object)

    def execute_json_test(self, json):
        """Add test from json object with 'method' and 'params' defined, block until it returns, return the result"""
        action_object = simplejson.loads(json)
        return self.execute_object(self._queue.add_test, self._test_resolution_suite, action_object)

    def execute_command(self, action_object):
        """Add command from dict object with 'method' and 'params' defined, block until it returns, return the result"""
        return self.execute_object(self._queue.add_command, self._command_resolution_suite, action_object)

    def execute_test(self, action_object):
        """Add test from dict object with 'method' and 'params' defined, block until it returns, return the result"""
        return self.execute_object(self._queue.add_test, self._test_resolution_suite, action_object)

    def run_json_tests(self, tests):
        """Run list of json tests"""
        return self.run_tests([simplejson.loads(test) for test in tests])

    def run_tests(self, tests):
        """Run list of tests"""
        for test in tests:
            if test['method'].find('command') is -1:
                self.add_test(test)
            else:
                self.add_command(test)
        return 200

    def clear_queue(self):
        """Clear the server queue"""
        self._queue.queue = []
        return 200

class JSONRPCMethods(RPCMethods):

    def next_action(self):
        """The next action for the browser to execute"""
        windmill.ide_is_awake = True
        from windmill.bin import admin_lib
        if len(admin_lib.on_ide_awake) is not 0:
            for func in copy.copy(admin_lib.on_ide_awake):
                func()
                admin_lib.on_ide_awake.remove(func)

        action = self._queue.next_action()
        if action is not None:
            self._logger.debug('queue has next_action %s' % str(action))
            return action
        else:
            self._logger.debug('queue has no next_action, returning "pause" method')
            action = copy.copy(callback)
            action.update({'method':'defer'})
            return action

    def report(self, uuid, result, starttime, endtime, debug=None):
        """Report fass/fail for a test"""
        self._test_resolution_suite.resolve(result, uuid, starttime, endtime, debug)
        return 200

    def report_without_resolve(self, uuid, result, starttime, endtime, suite_name, debug=None):
        self._test_resolution_suite.report_without_resolve(result, uuid, starttime, endtime, suite_name, debug)
        return 200

    def command_result(self, status, uuid, result):
        self._command_resolution_suite.resolve(status, uuid, result)

    def status_change(self, status):
        pass

    def set_test_url(self, url):
        windmill.settings['FORWARDING_TEST_URL'] = url
        windmill.server.proxy.initial_forwarding_registry = {}
        windmill.server.proxy.forwarding_registry = {}
        return 200

    def restart_test_run(self, tests):
        self.clear_queue()
        self._test_resolution_suite.unresolved = {}
        self._command_resolution_suite.unresolved ={}
        for test in tests:
            self.add_test(test, suite_name=test.get('suite_name'))

    def create_save_file(self, transformer, suite_name, tests):
        if not windmill.settings['SAVES_PATH']:
            windmill.authoring.transforms.create_saves_path()
        for test in tests:
            if test.get('suite_name'):
                test.pop('suite_name')
            if test['params'].get('uuid'):
                test['params'].pop('uuid')
        return windmill.authoring.transforms.registry[transformer](suite_name, tests)

    def teardown(self, tests):
        """teardown_module function for functest based python tests"""
        import windmill
        if windmill.settings['EXIT_ON_DONE']:
            from windmill.bin import admin_lib
            admin_lib.teardown(admin_lib.shell_objects_dict)
            windmill.runserver_running = False
            sleep(.25)

class XMLRPCMethods(RPCMethods):
    def stop_runserver(self):
        import windmill
        windmill.runserver_running = False

            <|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
# pytest documentation build configuration file, created by
# sphinx-quickstart on Fri Oct  8 17:54:28 2010.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The full version, including alpha/beta/rc tags.
# The short X.Y version.
version = "2.6"
release = "2.6.2"

import sys, os

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))

autodoc_member_order = "bysource"
todo_include_todos = 1

# -- General configuration -----------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.autosummary',
    'sphinx.ext.intersphinx', 'sphinx.ext.viewcode']

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix of source filenames.
source_suffix = '.txt'

# The encoding of source files.
#source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = 'contents'

# General information about the project.
project = u'pytest'
copyright = u'2014, holger krekel'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['links.inc', '_build', 'naming20.txt', 'test/*',
    "old_*",
    '*attic*',
    '*/attic*',
    'funcargs.txt',
    'setup.txt',
    'example/remoteinterp.txt',
    ]

# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
add_module_names = False

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []

# -- Options for HTML output ---------------------------------------------------

sys.path.append(os.path.abspath('_themes'))
html_theme_path = ['_themes']

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'flask'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
html_theme_options = {
  'index_logo': None
}

# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []

# The name for this set of Sphinx documents.  If None, it defaults to
# "<project> v<release> documentation".
html_title = None

# A shorter title for the navigation bar.  Default is the same as html_title.
html_short_title = "pytest-%s" % release

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = "img/pytest1.png"

# The name of an image file (within the static path) to use as favicon of the
# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = "img/pytest1favi.ico"

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
#html_sidebars = {'index': 'indexsidebar.html'}

html_sidebars = {
    'index': [
        'sidebarintro.html',
        'globaltoc.html',
        'links.html',
        'sourcelink.html',
        'searchbox.html'
    ],
    '**': [
        'globaltoc.html',
        'relations.html',
        'links.html',
        'sourcelink.html',
        'searchbox.html'
    ]
}

# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
#html_additional_pages = {'index': 'index.html'}

# If false, no module index is generated.
html_domain_indices = True

# If false, no index is generated.
html_use_index = False

# If true, the index is split into individual pages for each letter.
#html_split_index = False

# If true, links to the reST sources are added to the pages.
html_show_sourcelink = False

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None

# Output file base name for HTML help builder.
htmlhelp_basename = 'pytestdoc'

# -- Options for LaTeX output --------------------------------------------------

# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'

# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
  ('contents', 'pytest.tex', u'pytest Documentation',
   u'holger krekel, trainer and consultant, http://merlinux.eu', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
# the title page.
latex_logo = 'img/pytest1.png'

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False

# If true, show page references after internal links.
#latex_show_pagerefs = False

# If true, show URL addresses after external links.
#latex_show_urls = False

# Additional stuff for the LaTeX preamble.
#latex_preamble = ''

# Documents to append as an appendix to all manuals.
#latex_appendices = []

# If false, no module index is generated.
latex_domain_indices = False

# -- Options for manual page output --------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    ('usage', 'pytest', u'pytest usage',
     [u'holger krekel at merlinux eu'], 1)
]

# -- Options for Epub output ---------------------------------------------------

# Bibliographic Dublin Core info.
epub_title = u'pytest'
epub_author = u'holger krekel at merlinux eu'
epub_publisher = u'holger krekel at merlinux eu'
epub_copyright = u'2013, holger krekel et alii'

# The language of the text. It defaults to the language option
# or en if the language is not set.
#epub_language = ''

# The scheme of the identifier. Typical schemes are ISBN or URL.
#epub_scheme = ''

# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#epub_identifier = ''

# A unique identification for the text.
#epub_uid = ''

# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_pre_files = []

# HTML files shat should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_post_files = []

# A list of files that should not be packed into the epub file.
#epub_exclude_files = []

# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3

# Allow duplicate toc entries.
#epub_tocdup = True

# -- Options for texinfo output ------------------------------------------------

texinfo_documents = [
  (master_doc, 'pytest', 'pytest Documentation',
   ('Holger Krekel@*Benjamin Peterson@*Ronny Pfannschmidt@*'
    'Floris Bruynooghe@*others'),
   'pytest',
   'simple powerful testing with Pytho',
   'Programming',
   1),
]

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('http://docs.python.org/', None),
#                       'lib': ("http://docs.python.org/2.7library/", None),
                    }

def setup(app):
    #from sphinx.ext.autodoc import cut_lines
    #app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))
    app.add_description_unit('confval', 'confval',
                             objname='configuration value',
                             indextemplate='pair: %s; configuration value')
<commit_msg>fix doc release version<commit_after># -*- coding: utf-8 -*-
#
# pytest documentation build configuration file, created by
# sphinx-quickstart on Fri Oct  8 17:54:28 2010.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The full version, including alpha/beta/rc tags.
# The short X.Y version.
version = "2.6"
release = "2.6.3"

import sys, os

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))

autodoc_member_order = "bysource"
todo_include_todos = 1

# -- General configuration -----------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.autosummary',
    'sphinx.ext.intersphinx', 'sphinx.ext.viewcode']

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix of source filenames.
source_suffix = '.txt'

# The encoding of source files.
#source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = 'contents'

# General information about the project.
project = u'pytest'
copyright = u'2014, holger krekel'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['links.inc', '_build', 'naming20.txt', 'test/*',
    "old_*",
    '*attic*',
    '*/attic*',
    'funcargs.txt',
    'setup.txt',
    'example/remoteinterp.txt',
    ]

# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
add_module_names = False

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []

# -- Options for HTML output ---------------------------------------------------

sys.path.append(os.path.abspath('_themes'))
html_theme_path = ['_themes']

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'flask'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
html_theme_options = {
  'index_logo': None
}

# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []

# The name for this set of Sphinx documents.  If None, it defaults to
# "<project> v<release> documentation".
html_title = None

# A shorter title for the navigation bar.  Default is the same as html_title.
html_short_title = "pytest-%s" % release

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = "img/pytest1.png"

# The name of an image file (within the static path) to use as favicon of the
# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = "img/pytest1favi.ico"

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
#html_sidebars = {'index': 'indexsidebar.html'}

html_sidebars = {
    'index': [
        'sidebarintro.html',
        'globaltoc.html',
        'links.html',
        'sourcelink.html',
        'searchbox.html'
    ],
    '**': [
        'globaltoc.html',
        'relations.html',
        'links.html',
        'sourcelink.html',
        'searchbox.html'
    ]
}

# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
#html_additional_pages = {'index': 'index.html'}

# If false, no module index is generated.
html_domain_indices = True

# If false, no index is generated.
html_use_index = False

# If true, the index is split into individual pages for each letter.
#html_split_index = False

# If true, links to the reST sources are added to the pages.
html_show_sourcelink = False

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None

# Output file base name for HTML help builder.
htmlhelp_basename = 'pytestdoc'

# -- Options for LaTeX output --------------------------------------------------

# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'

# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
  ('contents', 'pytest.tex', u'pytest Documentation',
   u'holger krekel, trainer and consultant, http://merlinux.eu', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
# the title page.
latex_logo = 'img/pytest1.png'

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False

# If true, show page references after internal links.
#latex_show_pagerefs = False

# If true, show URL addresses after external links.
#latex_show_urls = False

# Additional stuff for the LaTeX preamble.
#latex_preamble = ''

# Documents to append as an appendix to all manuals.
#latex_appendices = []

# If false, no module index is generated.
latex_domain_indices = False

# -- Options for manual page output --------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    ('usage', 'pytest', u'pytest usage',
     [u'holger krekel at merlinux eu'], 1)
]

# -- Options for Epub output ---------------------------------------------------

# Bibliographic Dublin Core info.
epub_title = u'pytest'
epub_author = u'holger krekel at merlinux eu'
epub_publisher = u'holger krekel at merlinux eu'
epub_copyright = u'2013, holger krekel et alii'

# The language of the text. It defaults to the language option
# or en if the language is not set.
#epub_language = ''

# The scheme of the identifier. Typical schemes are ISBN or URL.
#epub_scheme = ''

# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#epub_identifier = ''

# A unique identification for the text.
#epub_uid = ''

# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_pre_files = []

# HTML files shat should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_post_files = []

# A list of files that should not be packed into the epub file.
#epub_exclude_files = []

# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3

# Allow duplicate toc entries.
#epub_tocdup = True

# -- Options for texinfo output ------------------------------------------------

texinfo_documents = [
  (master_doc, 'pytest', 'pytest Documentation',
   ('Holger Krekel@*Benjamin Peterson@*Ronny Pfannschmidt@*'
    'Floris Bruynooghe@*others'),
   'pytest',
   'simple powerful testing with Pytho',
   'Programming',
   1),
]

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('http://docs.python.org/', None),
#                       'lib': ("http://docs.python.org/2.7library/", None),
                    }

def setup(app):
    #from sphinx.ext.autodoc import cut_lines
    #app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))
    app.add_description_unit('confval', 'confval',
                             objname='configuration value',
                             indextemplate='pair: %s; configuration value')
<|endoftext|>


<commit_before>"""This is the docstring for the example.py module.  Modules names should
have short, all-lowercase names.  The module name may have underscores if
this improves readability.

Every module should have a docstring at the very top of the file.  The
module's docstring may extend over multiple lines.  If your docstring does
extend over multiple lines, the closing three quotation marks must be on
a line by itself, preferably preceded by a blank line.

"""
from __future__ import division, absolute_import, print_function

import os # standard library imports first

# Do NOT import using *, e.g. from numpy import *
#
# Import the module using
#
#   import numpy
#
# instead or import individual functions as needed, e.g
#
#  from numpy import array, zeros
#
# If you prefer the use of abbreviated module names, we suggest the
# convention used by NumPy itself::

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# These abbreviated names are not to be used in docstrings; users must
# be able to paste and execute docstrings after importing only the
# numpy module itself, unabbreviated.

from my_module import my_func, other_func

def foo(var1, var2, long_var_name='hi') :
    r"""A one-line summary that does not use variable names or the
    function name.

    Several sentences providing an extended description. Refer to
    variables using back-ticks, e.g. `var`.

    Parameters
    ----------
    var1 : array_like
        Array_like means all those objects -- lists, nested lists, etc. --
        that can be converted to an array.  We can also refer to
        variables like `var1`.
    var2 : int
        The type above can either refer to an actual Python type
        (e.g. ``int``), or describe the type of the variable in more
        detail, e.g. ``(N,) ndarray`` or ``array_like``.
    long_var_name : {'hi', 'ho'}, optional
        Choices in brackets, default first when optional.

    Returns
    -------
    type
        Explanation of anonymous return value of type ``type``.
    describe : type
        Explanation of return value named `describe`.
    out : type
        Explanation of `out`.

    Other Parameters
    ----------------
    only_seldom_used_keywords : type
        Explanation
    common_parameters_listed_above : type
        Explanation

    Raises
    ------
    BadException
        Because you shouldn't have done that.

    See Also
    --------
    otherfunc : relationship (optional)
    newfunc : Relationship (optional), which could be fairly long, in which
              case the line wraps here.
    thirdfunc, fourthfunc, fifthfunc

    Notes
    -----
    Notes about the implementation algorithm (if needed).

    This can have multiple paragraphs.

    You may include some math:

    .. math:: X(e^{j\omega } ) = x(n)e^{ - j\omega n}

    And even use a greek symbol like :math:`omega` inline.

    References
    ----------
    Cite the relevant literature, e.g. [1]_.  You may also cite these
    references in the notes section above.

    .. [1] O. McNoleg, "The integration of GIS, remote sensing,
       expert systems and adaptive co-kriging for environmental habitat
       modelling of the Highland Haggis using object-oriented, fuzzy-logic
       and neural-network techniques," Computers & Geosciences, vol. 22,
       pp. 585-588, 1996.

    Examples
    --------
    These are written in doctest format, and should illustrate how to
    use the function.

    >>> a=[1,2,3]
    >>> print [x + 3 for x in a]
    [4, 5, 6]
    >>> print "a\n\nb"
    a
    b

    """

    pass
<commit_msg>PEP8 fixes<commit_after>"""This is the docstring for the example.py module.  Modules names should
have short, all-lowercase names.  The module name may have underscores if
this improves readability.

Every module should have a docstring at the very top of the file.  The
module's docstring may extend over multiple lines.  If your docstring does
extend over multiple lines, the closing three quotation marks must be on
a line by itself, preferably preceded by a blank line.

"""
from __future__ import division, absolute_import, print_function

import os # standard library imports first

# Do NOT import using *, e.g. from numpy import *
#
# Import the module using
#
#   import numpy
#
# instead or import individual functions as needed, e.g
#
#  from numpy import array, zeros
#
# If you prefer the use of abbreviated module names, we suggest the
# convention used by NumPy itself::

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# These abbreviated names are not to be used in docstrings; users must
# be able to paste and execute docstrings after importing only the
# numpy module itself, unabbreviated.

from my_module import my_func, other_func

def foo(var1, var2, long_var_name='hi'):
    r"""A one-line summary that does not use variable names or the
    function name.

    Several sentences providing an extended description. Refer to
    variables using back-ticks, e.g. `var`.

    Parameters
    ----------
    var1 : array_like
        Array_like means all those objects -- lists, nested lists, etc. --
        that can be converted to an array.  We can also refer to
        variables like `var1`.
    var2 : int
        The type above can either refer to an actual Python type
        (e.g. ``int``), or describe the type of the variable in more
        detail, e.g. ``(N,) ndarray`` or ``array_like``.
    long_var_name : {'hi', 'ho'}, optional
        Choices in brackets, default first when optional.

    Returns
    -------
    type
        Explanation of anonymous return value of type ``type``.
    describe : type
        Explanation of return value named `describe`.
    out : type
        Explanation of `out`.

    Other Parameters
    ----------------
    only_seldom_used_keywords : type
        Explanation
    common_parameters_listed_above : type
        Explanation

    Raises
    ------
    BadException
        Because you shouldn't have done that.

    See Also
    --------
    otherfunc : relationship (optional)
    newfunc : Relationship (optional), which could be fairly long, in which
              case the line wraps here.
    thirdfunc, fourthfunc, fifthfunc

    Notes
    -----
    Notes about the implementation algorithm (if needed).

    This can have multiple paragraphs.

    You may include some math:

    .. math:: X(e^{j\omega } ) = x(n)e^{ - j\omega n}

    And even use a greek symbol like :math:`omega` inline.

    References
    ----------
    Cite the relevant literature, e.g. [1]_.  You may also cite these
    references in the notes section above.

    .. [1] O. McNoleg, "The integration of GIS, remote sensing,
       expert systems and adaptive co-kriging for environmental habitat
       modelling of the Highland Haggis using object-oriented, fuzzy-logic
       and neural-network techniques," Computers & Geosciences, vol. 22,
       pp. 585-588, 1996.

    Examples
    --------
    These are written in doctest format, and should illustrate how to
    use the function.

    >>> a = [1, 2, 3]
    >>> print [x + 3 for x in a]
    [4, 5, 6]
    >>> print "a\n\nb"
    a
    b

    """

    pass
<|endoftext|>