L3VOQYAF3HCAFWJ7QFULL54WUZ35B4K3MWU5YDRW7R4VTXSDWJUQC
YPHDYP3LZIQDWKGSFYGMQEGXKVSX3NKBJTSYVTCJ7ZIJTA36FAQAC
OXW4KMVURSBSSHOFK4DADOGVBRCURJ6EFFU6BBZE6IQC7BUBR5IQC
NCBEWRYEEJMJO37SHY7XCNFZYWLT5HUHCKN47UGSEY3FFWFX6QFQC
B4SKYP3Y5R7UPPGLLZV7OK3SIN4TRAJ3IL6FS3T7ZFZF5HTEQARQC
L44OILGKTGXSLQ3A4UQH44AMJXAVZSFISAB6ICHCDB6D42NKUWBQC
ZGMIJNFVDK7R6AF56FNCA23W5KV3HVBUBPTWMLQADCEPB3MOPELQC
H6KYVQ2QJCVDTFB35I4RDFC6OT6HTRTU45RQEQMONBFS2NITP4MAC
VP6KWIRTMOLWYL66Z5KE2UBZ725EHUNGEKR3XVNLUIJV3HQNKFRQC
import { TreeDataProvider, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { PijulChange, Repository } from '../pijul';
/**
* The Changelog provider class is a Treedata provider which provides
* TreeData for the `pijul.views.changelog` TreeView
*/
export class ChangelogViewProvider implements TreeDataProvider<PijulChange> {
/**
* Create a new Changelog provider instance
* @param repository
*/
constructor (
private readonly repository: Repository
) {}
/**
* Convert a PijulChange into a TreeItem
* @param element
*/
getTreeItem (element: PijulChange): TreeItem | Thenable<TreeItem> {
return {
id: element.hash,
label: element.message,
description: element.hash,
collapsibleState: TreeItemCollapsibleState.None
};
}
/**
* Get the children of the element or the root if no element is passed
* @param element An optional element to get the children of
*/
async getChildren (element?: PijulChange): Promise<PijulChange[] | null | undefined> {
if (element) {
// Changes don't have children
// TODO: Implement change dependency tracking
return null;
} else {
return await this.repository.getLog();
}
}
}
}
/**
* Use the `pijul log` command and parse the results
* to generate a log of pijul changes.
*/
async getLog (): Promise<PijulChange[]> {
const changes: PijulChange[] = [];
// TODO: Test how this scales to repositories with thousands or hundreds of thousands of changes
const result = await this._pijul.exec(this.repositoryRoot, ['log']);
const parsePattern = /Change\s([0-9A-Z]{53})\nAuthor:\s(.*)\nDate:\s(.*)\n\n.\s(.*)/gm;
do {
const match = parsePattern.exec(result.stdout);
if (match === null) break;
// Skip the first item, which is the entire match and select the individual capture groups
const [, hash, author, date, message] = match;
changes.push(new PijulChange(hash, message.trim(), author, date));
} while (true);
return changes;
}
/**
* Class representing a single change in the repository.
*/
export class PijulChange {
/**
* Create a new instance of a Pijul change object.
* @param hash The change hash
* @param message The message for the change
*/
constructor (
public readonly hash: string,
public readonly message: string,
public readonly author: string,
public readonly date: string
) {}