import { emptyBlobName , git , revParse } from "./git" ; import { fromJSON , toJSON } from "./json-util" ; export class GitNotes { public static readonly defaultNotesRef = "refs/notes/gitgitgadget" ; public readonly workDir ? : string ; public readonly notesRef : string ; public constructor ( workDir ? , notesRef ? ) { this . workDir = workDir ; this . notesRef = notesRef || GitNotes . defaultNotesRef ; } public async get < T > ( key ) { const json = await this . getString ( key ) ; if ( json === undefined ) { return undefined ; } return fromJSON ( json ) ; } public async getString ( key ) { const obj = await this . key2obj ( key ) ; try { return await this . notes ( "show" , obj ) ; } catch ( reason ) { return undefined ; } } public async set < T > ( key , value , force ? ) { return await this . setString ( key , toJSON ( value ) , force ) ; } public async setString ( key , value , force ? ) { const obj = await this . key2obj ( key ) ; if ( obj !== emptyBlobName && ! await revParse ( `${ obj }^{blob}` , this . workDir ) ) { try { await this . notes ( "add" , "-m" , key , this . notesRef ) ; await this . notes ( "remove" , `${ this . notesRef }^` ) ; } catch ( reason ) { await this . notes ( "add" , "-m" , key , emptyBlobName ) ; await this . notes ( "remove" , emptyBlobName ) ; } } if ( force ) { await this . notes ( "add" , "-f" , "-m" , value , obj ) ; } else { await this . notes ( "add" , "-m" , value , obj ) ; } } public async appendCommitNote ( commit , note ) { return await this . notes ( "append" , "-m" , note , commit ) ; } public async getCommitNotes ( commit ) { return await this . notes ( "show" , commit ) ; } public async getLastCommitNote ( commit ) { const notes = await this . getCommitNotes ( commit ) ; return notes . replace ( /^[^]*\n\n/ , "" ) ; } public async update ( ) { if ( this . notesRef === "refs/notes/gitgitgadget" || this . notesRef === "refs/notes/commit-to-mail" || this . notesRef === "refs/notes/mail-to-commit" ) { await git ( [ "fetch" , "https://github.com/gitgitgadget/git" , `+${ this . notesRef }:${ this . notesRef }` ] , { workDir : this . workDir } ) ; } else { throw new Error ( `Don't know how to update ${ this . notesRef }` ) ; } } protected async key2obj ( key ) { if ( ! key ) { return emptyBlobName ; } return await git ( [ "hash-object" , "--stdin" ] , { stdin : `${ key }\n` , workDir : this . workDir , } ) ; } protected async notes ( ... args ) { return await git ( [ "notes" , `--ref=${ this . notesRef }` , ... args ] , { workDir : this . workDir , } ) ; } }