Add a class to represent resources

[?]
Dec 28, 2020, 4:40 AM
H6KYVQ2QJCVDTFB35I4RDFC6OT6HTRTU45RQEQMONBFS2NITP4MAC

Dependencies

  • [2] QGP57DI2 Fix handling of empty json diff
  • [3] LUFSQKUV Enable support for experimental decorators
  • [4] NCBEWRYE Initialize Repository
  • [5] WW67NYZV Configure eslint for JS standard formatting
  • [6] YUVLBWV3 Populate resource groups for unrecorded and untracked changes
  • [7] 3N3RS66T Create pijul output channel and configure activation events
  • [*] B4SKYP3Y Add repository model and add steps to initialize it
  • [*] ZGMIJNFV Create pijul.ts for executing commands using the Pijul CLI
  • [*] IBRKAWNM Moved utility modules into their own folder

Change contents

  • file addition: resource.ts (-xw-x--x--)
    [4.104980]
    import { FileDecoration, SourceControlResourceDecorations, SourceControlResourceState, ThemeColor, Uri } from 'vscode';
    /**
    * Class which represents a resource within the repository, containing its URI and Pijul state
    */
    export class Resource implements SourceControlResourceState {
    constructor (
    private readonly _resourceUri: Uri,
    private readonly status: ResourceStatus
    ) { }
    /**
    * The URI of the resource
    */
    get resourceUri (): Uri {
    // TODO: Handle moves?
    return this._resourceUri;
    }
    /**
    * The tooltip briefly explaining the state of the resource
    */
    private get tooltip (): string {
    switch (this.status) {
    case ResourceStatus.Edit: return 'Edit';
    case ResourceStatus.Replacement: return 'Replacement';
    case ResourceStatus.FileAdd: return 'Added';
    case ResourceStatus.FileMove: return 'Moved';
    case ResourceStatus.FileDel: return 'Deleted';
    case ResourceStatus.FileUndel: return 'Undeleted';
    case ResourceStatus.SolveNameConflict: return 'Solve Name Conflict';
    case ResourceStatus.SolveOrderConflict: return 'Solve Order Conflict';
    case ResourceStatus.UnsolveNameConflict: return 'Unsolve Name Conflict';
    case ResourceStatus.UnsolveOrderConflict: return 'Unsolve Order Conflict';
    case ResourceStatus.ResurrectZombies: return 'Resurrect Zombies';
    case ResourceStatus.Untracked: return 'Untracked';
    // I don't know why typescript doesn't complain about this one
    default: return '';
    }
    }
    /**
    * Boolean indicating if the filename should be rendered with strikethrough
    */
    private get strikeThrough (): boolean {
    return this.status === ResourceStatus.FileDel;
    }
    /**
    * Boolean indicating if the filename should be faded
    */
    private get faded (): boolean {
    return this.status === ResourceStatus.Untracked;
    }
    /**
    * Accessor for the decoration applied to the resource in the source control menu
    */
    get decorations (): SourceControlResourceDecorations {
    const tooltip = this.tooltip;
    const strikeThrough = this.strikeThrough;
    const faded = this.faded;
    return { strikeThrough, faded, tooltip };
    }
    /**
    * The badge, a short string indicating the state of the resource
    */
    get badge (): string {
    switch (this.status) {
    case ResourceStatus.FileMove:
    return 'MV';
    case ResourceStatus.FileDel:
    return 'D';
    case ResourceStatus.FileUndel:
    return 'UD';
    case ResourceStatus.FileAdd:
    return 'A';
    case ResourceStatus.SolveNameConflict:
    case ResourceStatus.SolveOrderConflict:
    return 'SC';
    case ResourceStatus.UnsolveNameConflict:
    case ResourceStatus.UnsolveOrderConflict:
    return 'UC';
    case ResourceStatus.Edit:
    return 'M';
    case ResourceStatus.Replacement:
    return 'R';
    case ResourceStatus.ResurrectZombies:
    return 'RZ';
    case ResourceStatus.Untracked:
    return '';
    default:
    // This should never happen so typescript won't accept it without error, but
    // I'm leaving it in for safety.
    // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
    throw new Error(`Unknown pijul status: ${this.status}`);
    }
    }
    /**
    * The theme colour that should be used for the badge
    */
    get colour (): ThemeColor {
    switch (this.status) {
    case ResourceStatus.Replacement:
    return new ThemeColor('pijulDecoration.replacementForeground');
    case ResourceStatus.Edit:
    return new ThemeColor('pijulDecoration.editForeground');
    case ResourceStatus.FileDel:
    case ResourceStatus.FileUndel:
    return new ThemeColor('pijulDecoration.deletedResourceForeground');
    case ResourceStatus.FileAdd:
    return new ThemeColor('pijulDecoration.addedForeground');
    case ResourceStatus.FileMove:
    case ResourceStatus.Untracked:
    return new ThemeColor('pijulDecoration.untrackedForeground');
    case ResourceStatus.SolveNameConflict:
    case ResourceStatus.SolveOrderConflict:
    case ResourceStatus.UnsolveNameConflict:
    case ResourceStatus.UnsolveOrderConflict:
    case ResourceStatus.ResurrectZombies:
    return new ThemeColor('pijulDecoration.conflictForeground');
    default:
    // This should never happen so typescript won't accept it without error, but
    // I'm leaving it in for safety.
    // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
    throw new Error(`Unknown pijul status: ${this.status}`);
    }
    }
    /**
    * Accessor for the file decoration that should be applied to this resource
    */
    get resourceDecoration (): FileDecoration {
    const decorations = new FileDecoration(this.badge, this.tooltip, this.colour);
    decorations.propagate = this.status !== ResourceStatus.FileDel;
    return decorations;
    }
    // TODO: Methods for opening the resource
    // TODO: Icons
    // TODO: Priority
    // TODO: Commands
    }
    /**
    * Enum corresponding to the various Pijul file states
    */
    export enum ResourceStatus {
    FileMove = 'file move',
    FileDel = 'file del',
    FileUndel = 'file undel',
    SolveNameConflict = 'solve name conflict',
    UnsolveNameConflict = 'unsolve name conflict',
    FileAdd = 'file add',
    Edit = 'edit',
    Replacement = 'replacement',
    SolveOrderConflict = 'solve order conflict',
    UnsolveOrderConflict = 'unsolve order conflict',
    ResurrectZombies = 'resurrect zombies',
    Untracked = 'untracked'
    // TODO: Ignored status?
    }
  • replacement in src/repository.ts at line 100
    [4.349][4.349:466](),[4.466][3.242:355]()
    this.untrackedGroup.resourceStates = (await this.repository.getUntrackedFiles()).map(u => ({ resourceUri: u }));
    this.changedGroup.resourceStates = (await this.repository.getChangedFiles()).map(u => ({ resourceUri: u }));
    [4.349]
    [4.589]
    this.untrackedGroup.resourceStates = (await this.repository.getUntrackedFiles()).map(u => ({ resourceUri: u, decorations: { faded: true } }));
    this.changedGroup.resourceStates = await this.repository.getChangedFiles();
  • edit in src/pijul.ts at line 6
    [4.766]
    [11.0]
    import { Resource, ResourceStatus } from './resource';
  • replacement in src/pijul.ts at line 207
    [4.2727][4.2727:2772](),[4.2879][4.2879:2915]()
    async getChangedFiles (): Promise<Uri[]> {
    const changedFiles: Uri[] = [];
    [4.2727]
    [2.0]
    async getChangedFiles (): Promise<Resource[]> {
    const changedFiles: Resource[] = [];
  • replacement in src/pijul.ts at line 213
    [2.199][2.199:251]()
    changedFiles.push(createResourceUri(file));
    [2.199]
    [2.251]
    const fileChanges = pijulDiff[file] as IPijulFileDiff[];
    changedFiles.push(new Resource(createResourceUri(file), fileChanges[0].operation as ResourceStatus));
  • edit in src/pijul.ts at line 332
    [10.7479]
    [10.7479]
    }
    export interface IPijulFileDiff {
    operation: string
    line: number
  • replacement in package.json at line 69
    [4.1696][4.1696:1700]()
    }
    [4.1696]
    [4.108637]
    },
    "colors": [
    {
    "id": "pijulDecoration.addedForeground",
    "description": "Colour representing an added file",
    "defaults": {
    "light": "#587c0c",
    "dark": "#81b88b",
    "highContrast": "#1b5225"
    }
    },
    {
    "id": "pijulDecoration.editForeground",
    "description": " Colour representing an edited file",
    "defaults": {
    "light": "#895503",
    "dark": "#E2C08D",
    "highContrast": "#E2C08D"
    }
    },
    {
    "id": "pijulDecoration.deletedForeground",
    "description": "Colour representing a delete file",
    "defaults": {
    "light": "#ad0707",
    "dark": "#c74e39",
    "highContrast": "#c74e39"
    }
    },
    {
    "id": "pijulDecoration.untrackedForeground",
    "description": "Colour representing an untracked file",
    "defaults": {
    "light": "#007100",
    "dark": "#73C991",
    "highContrast": "#73C991"
    }
    },
    {
    "id": "pijulDecoration.replacementForeground",
    "description": "Colour representing a replacement",
    "defaults": {
    "light": "#895503",
    "dark": "#E2C08D",
    "highContrast": "#E2C08D"
    }
    },
    {
    "id": "pijulDecoration.conflictForeground",
    "description": "Colour representing a conflict",
    "defaults": {
    "light": "#6c6cc4",
    "dark": "#6c6cc4",
    "highContrast": "#6c6cc4"
    }
    }
    ]