Esempio n. 1
0
def update_references(commit_id: str,
                      wit_dir: Optional[str] = None,
                      checkout: bool = False) -> None:
    """Update the reference file in `wit_dir`."""
    if wit_dir is None:
        try:
            wit_dir = utilities.get_wit_dir()
        except FileNotFoundError as err:
            print(err)
            return
    reference_path = os.path.join(wit_dir, 'references.txt')
    active_branch = utilities.get_active_branch(wit_dir)
    if active_branch:
        active_branch_id = utilities.get_parent_id(wit_dir)[active_branch]
        if not checkout and active_branch_id == utilities.get_parent_id(
                wit_dir)['HEAD']:
            active_branch_id = commit_id
    with open(reference_path, 'r') as file_handler:
        reference = file_handler.readlines()
    text = ''
    for line in reference:
        branch_name, branch_id = line.rstrip().split('=')
        if branch_name == 'HEAD':
            branch_id = commit_id
        elif branch_name == active_branch:
            branch_id = active_branch_id
        text += f'{branch_name}={branch_id}\n'
    with open(reference_path, 'w') as file_handler:
        file_handler.write(text.rstrip())
Esempio n. 2
0
def get_adjacency(wit_dir: Optional[str] = None,
                  branch_id: Optional[str] = None,
                  all_commits: bool = False) -> Dict[str, List[str]]:
    """Return an 'adjacency list' dictionary of commit inheritance to draw a graph from."""
    if wit_dir is None:
        wit_dir = utilities.get_wit_dir()

    try:
        if branch_id:
            head_id = branch_id
        else:
            head_id = utilities.get_parent_id(wit_dir)['HEAD']
    except KeyError:
        head_id = 'None'

    adjacency: Dict[str, List[str]] = {}
    if head_id != 'None':
        adjacency[head_id] = utilities.get_parent_id(
            wit_dir, commit_id=head_id)['parent'].split(', ')
    update_adjacency(adjacency, wit_dir)

    if all_commits:
        for commit_id in os.listdir(os.path.join(wit_dir, 'images')):
            if '.txt' not in commit_id and commit_id not in adjacency:
                adjacency[commit_id] = utilities.get_parent_id(
                    wit_dir, commit_id=commit_id)['parent'].split(', ')

    return adjacency
Esempio n. 3
0
def add_annotation(G: Any, wit_dir: str) -> Any:
    """Add labels with branch names to nodes in `G`"""
    pos = nx.circular_layout(G)
    pos_len = len(pos)
    if pos_len == 1:
        label_dif = LABEL_DIF_2
        double_x = DOUBLE_X_2
        double_y = DOUBLE_Y_2
    else:
        label_dif = LABEL_DIF + pos_len / DIVISOR
        double_x = DOUBLE_X + pos_len / DIVISOR
        double_y = DOUBLE_Y
    branches = utilities.get_parent_id(wit_dir)
    all_ids: List[str] = []
    for branch_name in branches:
        branch_id = branches[branch_name]
        if branch_id in pos:
            branch_pos = pos[branch_id]
            branch_label = [
                branch_pos[0] - label_dif,
                branch_pos[1] - label_dif / BRANCH_DIVISOR
            ]
            if branch_id in all_ids:
                count = all_ids.count(branch_id)
                branch_label = [
                    branch_label[0] - double_x,
                    branch_label[1] + double_y * count
                ]
            plt.annotate(branch_name,
                         xy=branch_pos,
                         xytext=branch_label,
                         arrowprops=ARROW_PROPS)
            all_ids.append(branch_id)
    return pos
Esempio n. 4
0
def create_metadata_file(commit_id: str,
                         *message: str,
                         merged_branch_id: Optional[str] = None,
                         wit_dir: Optional[str] = None) -> None:
    """Create a metadata file for the current image."""
    if wit_dir is None:
        try:
            wit_dir = utilities.get_wit_dir()
        except FileNotFoundError as err:
            print(err)
            return
    images_dir = os.path.join(wit_dir, 'images')
    metadata_path = os.path.join(images_dir, f'{commit_id}.txt')
    try:
        parent = utilities.get_parent_id(wit_dir)['HEAD']
        if merged_branch_id:
            parent += f', {merged_branch_id}'
    except KeyError:
        parent = 'None'
    cur_time = time.strftime('%a %b %d %H:%M:%S %Y %z', time.gmtime())
    printable = f'parent={parent}\ndate={cur_time}'
    if message:
        to_print = ' '.join(message)
        printable += f'\nmessage={to_print}'
    with open(metadata_path, 'x') as metadata:
        metadata.write(printable)
Esempio n. 5
0
def update_adjacency(adjacency: Dict[str, List[str]], wit_dir: str) -> None:
    """Update adjacency list in `adjacency` based on its values."""
    length = len(adjacency)
    temp = list(adjacency.values())
    for commits in temp:
        for commit_id in commits:
            if commit_id not in adjacency and commit_id != 'None':
                adjacency[commit_id] = utilities.get_parent_id(
                    wit_dir, commit_id=commit_id)['parent'].split(', ')
    if len(adjacency) != length:
        update_adjacency(adjacency, wit_dir)
Esempio n. 6
0
def checkout(commit_id: str) -> None:
    """Rollback to a previous image."""
    try:
        wit_dir_parent = utilities.get_wit_dir_parent()
    except FileNotFoundError as err:
        print(err)
        return

    wit_dir = os.path.join(wit_dir_parent, '.wit')
    branches = utilities.get_parent_id(wit_dir)
    if commit_id not in branches and commit_id not in os.listdir(
            os.path.join(wit_dir, 'images')):
        print('Invalid commit id. Unable to perform checkout.')
        return

    changes, unstaged, _, _ = status(no_print=True)
    if changes or unstaged:
        print(
            'Unable to perform checkout. There are changes not yet committed.')
        return

    if commit_id in branches:
        branch_name = commit_id
        commit_id = branches[commit_id]
    elif commit_id in branches.values():
        for key, value in branches.items():
            if value == commit_id:
                branch_name = key
    else:
        branch_name = ''
    utilities.update_activated(branch_name, wit_dir)
    for file in status_funcs.get_all_files(
            os.path.join(wit_dir, 'images', commit_id)):
        og_path = utilities.get_original_name(file)
        staging_area = utilities.get_new_path(og_path,
                                              wit_dir_parent,
                                              additions=['staging_area'])

        for path in (og_path, staging_area):
            if os.path.exists(path):
                try:
                    os.remove(path)
                except PermissionError:
                    shutil.rmtree(path)
            try:
                shutil.copy2(file, path)
            except PermissionError:
                shutil.copytree(file, path)

    commit_funcs.update_references(commit_id, wit_dir, checkout=True)
    print(f'Reverted to {commit_id}')
Esempio n. 7
0
def branch(branch_name: str) -> None:
    """Label the current commit id as `branch_name`, and define it as the acctivated branch."""
    try:
        wit_dir = utilities.get_wit_dir()
    except FileNotFoundError as err:
        print(err)
        return

    branches = utilities.get_parent_id(wit_dir)
    head_id = branches['HEAD']
    reference = os.path.join(wit_dir, 'references.txt')
    if branch_name not in branches:
        with open(reference, 'a') as file_handler:
            file_handler.write(f'\n{branch_name}={head_id}')
        print(f'Branch \'{branch_name}\' created.')
    else:
        print(f'A branch named \'{branch_name}\' already exists.')
Esempio n. 8
0
def status(
    no_print: bool = False
) -> Tuple[List[str], List[str], List[str], List[str]]:
    """Print commitment status of files."""
    parent_dir = utilities.get_wit_dir_parent()
    wit_dir = os.path.join(parent_dir, '.wit')
    staging_area = os.path.join(wit_dir, 'staging_area')
    try:
        head_id = utilities.get_parent_id(wit_dir)['HEAD']
    except KeyError:
        head_id = ''
        changes = [
            os.path.join(parent_dir, path) for path in os.listdir(staging_area)
        ]
        removed = []
    else:
        last_image = os.path.join(wit_dir, 'images', head_id)
        changes = list(
            status_funcs.get_nonexistent_files(staging_area, last_image))
        changes.extend(
            list(status_funcs.get_changed_files(staging_area, last_image)))
        removed = list(
            status_funcs.get_nonexistent_files(last_image, parent_dir))
    unstaged = list(status_funcs.get_changed_files(parent_dir, staging_area))
    untracked = list(
        status_funcs.get_nonexistent_files(parent_dir, staging_area))

    if not no_print:
        printable = ''
        if head_id:
            printable += f'Current commit id: {head_id}'
            active_branch = utilities.get_active_branch(wit_dir)
            if active_branch:
                printable += f'\nActive branch: {active_branch}'
        else:
            printable += 'No images currently exist.'
        printable += (f'\n\nChanges to be committed:\n{changes}'
                      f'\n\nUnstaged changes:\n{unstaged}'
                      f'\n\nUntracked files:\n{untracked}'
                      f'\n\nRemoved files:\n{removed}')
        print(printable)

    return changes, unstaged, untracked, removed