Add changelog view to the source control panel

[?]
Jan 4, 2021, 10:15 PM
L3VOQYAF3HCAFWJ7QFULL54WUZ35B4K3MWU5YDRW7R4VTXSDWJUQC

Dependencies

  • [2] YPHDYP3L Fix infinite loop on state refresh
  • [3] OXW4KMVU Add QuickDiffProvider
  • [*] NCBEWRYE Initialize Repository
  • [*] B4SKYP3Y Add repository model and add steps to initialize it
  • [*] ZGMIJNFV Create pijul.ts for executing commands using the Pijul CLI
  • [*] L44OILGK Add reset command to resource state context menu
  • [*] H6KYVQ2Q Add a class to represent resources
  • [*] VP6KWIRT Add inline icons for commands on SCM view

Change contents

  • file addition: views (dxwrx-rx-r)
    [5.104980]
  • file addition: changelog.ts (-xw-x--x--)
    [0.8]
    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();
    }
    }
    }
  • edit in src/repository.ts at line 7
    [2.60]
    [6.229]
    import { ChangelogViewProvider } from './views/changelog';
  • edit in src/repository.ts at line 107
    [3.1]
    [3.1]
    this.disposables.push(window.registerTreeDataProvider('pijul.views.log', new ChangelogViewProvider(this.repository)));
  • edit in src/pijul.ts at line 312
    [8.763]
    [8.763]
    }
    /**
    * 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;
  • edit in src/pijul.ts at line 431
    [9.6228]
    [7.7479]
    }
    /**
    * 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
    ) {}
  • edit in package.json at line 247
    [10.1822]
    [8.1681]
    }
    ]
    },
    "views": {
    "scm": [
    {
    "id": "pijul.views.log",
    "name": "Changelog",
    "contextualTitle": "Pijul",
    "visibility": "visible"