예제 #1
0
def _initialize_repository(session,
                           src_path: str,
                           initialize_commands: str = None,
                           test_commands: str = None,
                           src_directory: str = None,
                           commit_only=False,
                           ignored_files=''):
    '''
    Given a src_path to a repository, create the repository in the database
    '''
    logger.info('Initializing repository at "{}"'.format(src_path))
    url = get_repository_url_from_path(src_path)
    repository = get(session, Repository, url=url)

    name = get_repository_name_from_url(url)
    logger.info('Repository name is "{}" with url "{}"'.format(name, url))
    if not initialize_commands:
        msg = ('Input the commands to intialize the repo (ex. '
               '"source env/bin/activate"): ')
        initialize_commands = input(msg)
    if not test_commands:
        msg = ('Input the command to run the tests for the repo: ')
        test_commands = input(msg)
    if not src_directory:
        msg = ('Input the source directory for your project: ')
        src_directory = input(msg)

    # first check to see if the repository already exists
    repository = get(session, Repository, url=url)
    if not repository:
        repository = create(session,
                            Repository,
                            name=name,
                            url=url,
                            initialize_commands=initialize_commands,
                            test_commands=test_commands,
                            src_directory=src_directory,
                            src_path=src_path,
                            ignored_files=ignored_files)

    _check_repo_is_clean(repository, path=repository.original_path)

    # create the mirror repository that BugBuddy primarily works on
    sync_mirror_repo(repository)

    # make sure the mirrored repo is on bug_buddy branch
    set_bug_buddy_branch(repository)

    # Initialize the repository by recording functions and creating synthetic
    # diffs
    if not commit_only:
        snapshot(repository, allow_empty=True)

    session.commit()
    logger.info(
        'Your repository "{}" has been successfully initialized!'.format(
            repository))

    return repository
예제 #2
0
def delete_command(src_path: str):
    '''
    Entry-point for the "bugbuddy generate" command

    @param src_path: path to the repository
    '''
    url = get_repository_url_from_path(src_path)
    with session_manager() as session:
        repository = get(session, Repository, url=url)

        # make sure you cannot delete the bug_buddy branch
        if repository.name not in ['bug_buddy', 'BugBuddy']:
            msg = ('Would you like to delete the bug_buddy branch for {}?\n'
                   '(y/n)\n'.format(repository))
            should_delete = input(msg)

            if is_affirmative(should_delete):
                logger.info('Deleting bug_buddy branch')
                delete_bug_buddy_branch(repository or Mock(src_path=src_path))

        if repository:
            logger.info('Deleting data from the database')
            delete(session, repository)

        else:
            logger.info('No matching repo found in the database')
예제 #3
0
def get_matching_commit_for_diffs(repository, base_synthetic_diffs):
    '''
    Given a set of diffs, return if there is a commit that has those diffs
    '''
    session = Session.object_session(repository)
    base_synthetic_ids = [diff.id for diff in base_synthetic_diffs]
    diff_hash = get_hash_given_base_synthetic_ids(base_synthetic_ids)
    return get(session, Commit, synthetic_diff_hash=diff_hash)
예제 #4
0
def _get_repository_from_src_path(session, src_path: str):
    '''
    Returns the repository given a src_path
    '''
    url = get_repository_url_from_path(src_path)
    repository = get(session, Repository, url=url)
    if not repository:
        msg = ('This repository is not in the BudBuddy database, would you '
               'like to initialize the repository?  (y/n)\n'.format(src_path))
        should_initialize = input(msg)
        if is_affirmative(should_initialize):
            repository = _initialize_repository(session, src_path)
        else:
            logger.info('No worries!')

    if src_path != repository.original_path:
        _migrate_repository_to_new_path(session, repository, src_path)
    return repository
예제 #5
0
    def on_any_event(self, event):
        '''
        Catches all events
        '''
        if '/.' in event.src_path:
            return

        updated_file = os.path.relpath(event.src_path,
                                       self.repository.original_path)
        if (not updated_file or updated_file in self.repository.ignored_files
                or not updated_file.endswith('.py')):
            return

        # we have to recreate the repository in this thread for Sqlite
        with session_manager() as session:
            repository = get(session, Repository, id=self.repository.id)
            # logger.info('Syncing updates')
            # Copy the change over to the mirror repository
            sync_mirror_repo(repository)

            if not is_repo_clean(self.repository):
                logger.info('Valid change event: {}'.format(event))

                # make sure the repository is on the bug_buddy branch
                start = time.time()
                commit = snapshot(repository, commit_only=self.commit_only)
                total_time = time.time() - start
                logger.info(
                    'Completed snapshot of {commit} in {m}m {s}s'.format(
                        commit=commit, m=total_time / 60, s=total_time % 60))
                session.commit()

                if not self.commit_only:
                    run_all_tests(commit)

                    for test_failure in commit.failed_test_results:
                        predict_blame(test_failure)

                    # display the results in the cli output
                    # self.score_card.render(commit)
                    commit.summary()

            else:
                logger.info('Nothing was changed')
예제 #6
0
def commit_generator(repository_id: int, batch_size: int):
    '''
    Returns augmented commit data for training
    '''
    with session_manager() as session:
        repository = get(session, Repository, id=repository_id)
        while True:
            features = []
            labels = []
            commits = get_commits(repository,
                                  num_commits=batch_size,
                                  synthetic=True)

            for commit in commits:
                feature = commit_to_state(commit)
                set_functions_altered_noise(feature)
                set_tests_not_run_noise(feature)

                label = commit_to_test_failure_label(commit)

                features.append(feature)
                labels.append(label)

            yield numpy.stack(features), numpy.stack(labels)
예제 #7
0
def get_function_from_patch(repository: Repository, patch: str, file_path: str,
                            first_line: int, last_line: int):
    '''
    Given a patch, find the corresponding function if possible
    '''
    session = Session.object_session(repository)
    pattern = re.compile('def \w*\(')
    matching_functions = pattern.findall(patch)
    if len(matching_functions) != 1:
        # import pdb; pdb.set_trace()
        print('multiple matching_functions: ', matching_functions)

    else:
        function_name = matching_functions[0]

        # it comes out from the regex as def xxxxxx( so we need to splice out
        # just the function name
        function_name = function_name[4:-1]
        return get(
            session,
            Function,
            name=function_name,
            file_path=file_path,
        )