diff --git a/.gitignore b/.gitignore index 21481c8..e2e4ca4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ node_modules .statik -dummy \ No newline at end of file +dummy-par \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 52bd0ef..615eb85 100755 --- a/dist/index.js +++ b/dist/index.js @@ -5,16 +5,18 @@ import { Init } from "./vc/init.js"; import { Add } from "./vc/stage.js"; import { Commit } from "./vc/commit.js"; import { Log } from "./vc/history.js"; -console.log(figlet.textSync("Statik")); +import { Jump, List } from "./vc/branching.js"; const program = new Command(); program .name("statik") .version("1.0.5-alpha") - .description("An IPFS based version control system with static file hosting features"); + .description(figlet.textSync("Statik") + "\nAn IPFS based version control system with static file hosting features"); program.command("init ").description("Initialize a new Statik repository"); program.command("add [file_path]").description("Add a file to the Statik repository"); program.command("commit ").description("Commit changes to the Statik repository"); -program.command("log").description("View the commit history of the Statik repository"); +program.command("log").description("View the commit history of the current branch"); +program.command("branch").description("List all branches in the Statik repository"); +program.command("jump ").description("Switch between branches"); program.parse(process.argv); if (program.args.length < 1) { program.outputHelp(); @@ -35,6 +37,12 @@ switch (program.args[0]) { case "log": Log(cwd); break; + case "branch": + List(cwd); + break; + case "jump": + Jump(cwd, program.args[1]); + break; default: program.outputHelp(); process.exit(0); diff --git a/dist/index.js.map b/dist/index.js.map index 950b36f..e7c6e4f 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEvC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAC9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,wEAAwE,CAAC,CAAA;AACxF,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAA;AACzF,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,WAAW,CAAC,qCAAqC,CAAC,CAAA;AACrF,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,WAAW,CAAC,yCAAyC,CAAC,CAAA;AAC1F,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,kDAAkD,CAAC,CAAA;AACtF,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,IAAG,OAAO,CAAC,IAAI,CAAC,MAAM,GAAC,CAAC,EAAE;IACxB,OAAO,CAAC,UAAU,EAAE,CAAA;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;CAChB;AAGD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAC1B,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;IACvB,KAAK,MAAM;QACT,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACrC,IAAI,CAAC,GAAG,EAAC,aAAa,CAAC,CAAC;QACxB,MAAM;IACR,KAAK,KAAK;QACR,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM;IACR,KAAK,QAAQ;QACX,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM;IACR,KAAK,KAAK;QACR,GAAG,CAAC,GAAG,CAAC,CAAC;QACT,MAAM;IACR;QACE,OAAO,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;CAClB"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAC9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAC,0EAA0E,CAAC,CAAA;AACpH,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAA;AACzF,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,WAAW,CAAC,qCAAqC,CAAC,CAAA;AACrF,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,WAAW,CAAC,yCAAyC,CAAC,CAAA;AAC1F,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,+CAA+C,CAAC,CAAA;AACnF,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,4CAA4C,CAAC,CAAA;AACnF,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAA;AACvE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;IAC3B,OAAO,CAAC,UAAU,EAAE,CAAA;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;CAChB;AAGD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAC1B,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;IACvB,KAAK,MAAM;QACT,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACrC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACzB,MAAM;IACR,KAAK,KAAK;QACR,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM;IACR,KAAK,QAAQ;QACX,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM;IACR,KAAK,KAAK;QACR,GAAG,CAAC,GAAG,CAAC,CAAC;QACT,MAAM;IACR,KAAK,QAAQ;QACX,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,MAAM;IACR,KAAK,MAAM;QACT,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM;IACR;QACE,OAAO,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;CAClB"} \ No newline at end of file diff --git a/dist/utils/changes.js b/dist/utils/changes.js new file mode 100644 index 0000000..92e4cba --- /dev/null +++ b/dist/utils/changes.js @@ -0,0 +1,37 @@ +import fs from 'fs'; +import { multihashToCID } from "./cid.js"; +const checkChange = async (currentFiles, prevContent, file, client, cwd) => { + if (!currentFiles.includes(file)) + return false; + const prevFile = prevContent.find((f) => f.path === file); + // console.log(prevFile) + const cid = multihashToCID(prevFile.cid); + // console.log(cid,path) + const asyncitr = client.cat(cid); + for await (const itr of asyncitr) { + const data = Buffer.from(itr).toString(); + if (data !== fs.readFileSync(cwd + "/" + file).toString()) + return true; + } + return false; +}; +export async function isOverriding(cwd, client, prevContent, currentFiles) { + let overrides = false; + // console.log(currentFiles) + const prevFiles = prevContent.map((file) => file.path); + // console.log(prevFiles) + const added = currentFiles.filter((file) => !prevFiles.includes(file)); + const deleted = prevFiles.filter((file) => !currentFiles.includes(file)); + if (deleted.length) + overrides = true; + let changed = []; + for (const file of prevFiles) { + if (await checkChange(currentFiles, prevContent, file, client, cwd)) + changed.push(file); + } + if (changed.length) + overrides = true; + // console.log(overrides,added,deleted,changed) + return { overrides, newFiles: added, deletedFiles: deleted, updated: changed }; +} +//# sourceMappingURL=changes.js.map \ No newline at end of file diff --git a/dist/utils/changes.js.map b/dist/utils/changes.js.map new file mode 100644 index 0000000..a366c98 --- /dev/null +++ b/dist/utils/changes.js.map @@ -0,0 +1 @@ +{"version":3,"file":"changes.js","sourceRoot":"","sources":["../../src/utils/changes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,MAAM,WAAW,GAAG,KAAK,EAAC,YAAqB,EAAC,WAAiB,EAAC,IAAW,EAAC,MAAsB,EAAC,GAAU,EAAE,EAAE;IAC/G,IAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAC7C,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IAC9D,wBAAwB;IACxB,MAAM,GAAG,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IACxC,wBAAwB;IACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAChC,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,QAAQ,EAAE;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;QACxC,IAAI,IAAI,KAAK,EAAE,CAAC,YAAY,CAAC,GAAG,GAAE,GAAG,GAAE,IAAI,CAAC,CAAC,QAAQ,EAAE;YAAE,OAAO,IAAI,CAAC;KACxE;IACD,OAAO,KAAK,CAAA;AAChB,CAAC,CAAA;AACD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,MAAsB,EAAE,WAAiB,EAAC,YAAqB;IAC3G,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,4BAA4B;IAC5B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3D,yBAAyB;IACzB,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3E,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;IAC7E,IAAI,OAAO,CAAC,MAAM;QAAE,SAAS,GAAG,IAAI,CAAC;IACrC,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE;QAC1B,IAAI,MAAM,WAAW,CAAC,YAAY,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,EAAC,GAAG,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;KACtF;IACD,IAAI,OAAO,CAAC,MAAM;QAAE,SAAS,GAAG,IAAI,CAAC;IACrC,+CAA+C;IAC/C,OAAO,EAAC,SAAS,EAAC,QAAQ,EAAC,KAAK,EAAC,YAAY,EAAC,OAAO,EAAC,OAAO,EAAC,OAAO,EAAC,CAAC;AAC3E,CAAC"} \ No newline at end of file diff --git a/dist/utils/cid.js b/dist/utils/cid.js new file mode 100644 index 0000000..fe07958 --- /dev/null +++ b/dist/utils/cid.js @@ -0,0 +1,7 @@ +import { CID } from "ipfs-http-client"; +export function multihashToCID(cid) { + const { code, version, hash } = cid; + const bytes = new Uint8Array(Object.values(hash)); + return new CID(version, code, cid, bytes); +} +//# sourceMappingURL=cid.js.map \ No newline at end of file diff --git a/dist/utils/cid.js.map b/dist/utils/cid.js.map new file mode 100644 index 0000000..412a73a --- /dev/null +++ b/dist/utils/cid.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cid.js","sourceRoot":"","sources":["../../src/utils/cid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,MAAM,UAAU,cAAc,CAAC,GAAO;IAClC,MAAM,EAAC,IAAI,EAAC,OAAO,EAAC,IAAI,EAAC,GAAG,GAAG,CAAA;IAC/B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IACjD,OAAO,IAAI,GAAG,CAAC,OAAO,EAAC,IAAI,EAAC,GAAG,EAAC,KAAK,CAAC,CAAA;AAC1C,CAAC"} \ No newline at end of file diff --git a/dist/utils/dirwalk.js b/dist/utils/dirwalk.js new file mode 100644 index 0000000..f69655a --- /dev/null +++ b/dist/utils/dirwalk.js @@ -0,0 +1,33 @@ +import fs from 'fs'; +import path from 'path'; +export function* readAllFiles(dir) { + const files = fs.readdirSync(dir, { withFileTypes: true }); + const cwd = process.cwd(); + for (const file of files) { + if (file.isDirectory()) { + yield* readAllFiles(path.join(dir, file.name)); + } + else { + yield path.relative(cwd, path.join(dir, file.name)); + } + } +} +export function deleteAllFiles(dir, exempt) { + const files = fs.readdirSync(dir, { withFileTypes: true }); + const cwd = process.cwd(); + for (const file of files) { + if (file.isDirectory()) { + deleteAllFiles(path.join(dir, file.name), exempt); + } + if (!exempt.includes(path.relative(cwd, path.join(dir, file.name)))) { + if (file.isFile()) { + fs.unlinkSync(path.join(dir, file.name)); + } + else if (file.isDirectory() && !fs.readdirSync(path.join(dir, file.name)).length) { + fs.rmdirSync(path.join(dir, file.name)); + } + } + } + return; +} +//# sourceMappingURL=dirwalk.js.map \ No newline at end of file diff --git a/dist/utils/dirwalk.js.map b/dist/utils/dirwalk.js.map new file mode 100644 index 0000000..a4dcd69 --- /dev/null +++ b/dist/utils/dirwalk.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dirwalk.js","sourceRoot":"","sources":["../../src/utils/dirwalk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,SAAS,CAAC,CAAC,YAAY,CAAC,GAAW;IACrC,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACtB,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;YACpB,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;SAClD;aAAM;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;SACvD;KACJ;AACL,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAU,EAAE,MAAe;IACtD,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACtB,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;YACpB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,EAAC,MAAM,CAAC,CAAC;SACpD;QACD,IAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC;YAC/D,IAAG,IAAI,CAAC,MAAM,EAAE,EAAC;gBACb,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;aAC3C;iBAAK,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE;gBAC/E,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;aAC1C;SACJ;KACJ;IACD,OAAM;AACV,CAAC"} \ No newline at end of file diff --git a/dist/utils/fetchContent.js b/dist/utils/fetchContent.js new file mode 100644 index 0000000..cd3e1a2 --- /dev/null +++ b/dist/utils/fetchContent.js @@ -0,0 +1,16 @@ +export async function commitContent(commitId, client) { + let asyncitr = client.cat(commitId); + let prevSnapshot = ""; + for await (const itr of asyncitr) { + const data = Buffer.from(itr).toString(); + prevSnapshot = JSON.parse(data).snapshot; + } + let prevContent = []; + asyncitr = client.cat(prevSnapshot); + for await (const itr of asyncitr) { + const data = Buffer.from(itr).toString(); + prevContent = JSON.parse(data); + } + return prevContent; +} +//# sourceMappingURL=fetchContent.js.map \ No newline at end of file diff --git a/dist/utils/fetchContent.js.map b/dist/utils/fetchContent.js.map new file mode 100644 index 0000000..4cda03c --- /dev/null +++ b/dist/utils/fetchContent.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fetchContent.js","sourceRoot":"","sources":["../../src/utils/fetchContent.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,MAAsB;IACxE,IAAI,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACnC,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,QAAQ,EAAE;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;QACxC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAA;KAC3C;IACD,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IACnC,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,QAAQ,EAAE;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;QACxC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;KACjC;IACD,OAAO,WAAW,CAAA;AACtB,CAAC"} \ No newline at end of file diff --git a/dist/vc/branching.js b/dist/vc/branching.js new file mode 100644 index 0000000..bb03d4e --- /dev/null +++ b/dist/vc/branching.js @@ -0,0 +1,125 @@ +import { create } from "ipfs-http-client"; +import { IsStatik } from "../utils/checkStatik.js"; +import fs from 'fs'; +import { FetchConfig } from "../utils/fetchConfig.js"; +import Path from 'path'; +import { multihashToCID } from "../utils/cid.js"; +import { isOverriding } from "../utils/changes.js"; +import { commitContent } from "../utils/fetchContent.js"; +import { deleteAllFiles, readAllFiles } from "../utils/dirwalk.js"; +export async function List(cwd) { + try { + IsStatik(cwd); + // List all files + const currentBranch = fs.readFileSync(cwd + "/.statik/HEAD").toString(); + const files = fs.readdirSync(cwd + "/.statik/heads"); + for (const file of files) { + if (file === currentBranch) { + console.log("-> " + file + " <-"); + } + else { + console.log(file); + } + } + } + catch (err) { + console.error(err); + } +} +export async function Jump(cwd, branch) { + try { + IsStatik(cwd); + const currentBranch = fs.readFileSync(cwd + "/.statik/HEAD").toString(); + if (branch === currentBranch) { + console.log("Already on branch " + branch); + return; + } + const currentHead = fs.readFileSync(cwd + "/.statik/heads/" + currentBranch).toString(); + // Check for staged changes + if (fs.readFileSync(cwd + "/.statik/SNAPSHOT").toString().length) { + console.log("There are staged changes. You cannot switch branch without commiting it"); + return; + } + if (!fs.existsSync(cwd + "/.statik/heads/" + branch)) { + console.log("Branching out to " + branch + "..."); + fs.writeFileSync(cwd + "/.statik/heads/" + branch, currentHead); + fs.writeFileSync(cwd + "/.statik/HEAD", branch); + } + else { + const commitId = fs.readFileSync(cwd + "/.statik/heads/" + branch).toString(); + const client = create({ url: FetchConfig(cwd).ipfs_node_url }); + console.log("Switching to branch " + branch + "\n" + "Head commit <" + commitId + ">"); + const currentFiles = [...readAllFiles(cwd)]; + // Check for unstaged changes + const oldBranchContent = await commitContent(currentHead, client); + const { overrides: hasUnstagedChanges, newFiles: addedFiles, updated: unstagedChanges, deletedFiles } = await isOverriding(cwd, client, oldBranchContent, currentFiles); + if (hasUnstagedChanges) { + if (unstagedChanges.length > 0) { + console.log("\nUnstaged changes:"); + for (const file of unstagedChanges) { + console.log(file); + } + } + if (deletedFiles.length > 0) { + console.log("\nDeleted files:"); + for (const file of deletedFiles) { + console.log(file); + } + } + console.log("\nThere are unstaged changes. You cannot switch branch without commiting it"); + console.log("Abort"); + process.exit(1); + } + // Handle the case where not unstaged but overriding + // Solution: Prevent only if added files and deleted files are overriding + // Check for overriding changes + const newBranchContent = await commitContent(commitId, client); + const { newFiles, updated } = await isOverriding(cwd, client, newBranchContent, addedFiles); + if (updated.length > 0) { + console.log("Overriding changes:"); + for (const file of updated) { + console.log(file); + } + console.log("There are overriding changes. You cannot switch branch without commiting it"); + console.log("Abort"); + process.exit(1); + } + // Find the basepath and recursively delete all files + let basepathCount = Infinity; + let index = 0; + if (newBranchContent.length > 0) { + basepathCount = newBranchContent[0].path.split("/").length; + } + for (let i = 1; i < newBranchContent.length; i++) { + if (newBranchContent[i].path.split("/").length < basepathCount) { + basepathCount = newBranchContent[i].path.split("/").length; + index = i; + } + } + // Conditionally delete files. Exempt new files under basepath + const basepath = Path.dirname(newBranchContent[index].path); + deleteAllFiles(cwd + "/" + basepath, newFiles); + for (const obj of newBranchContent) { + const path = obj.path; + // Derive CID from multihash + const cid = multihashToCID(obj.cid); + // console.log(cid,path) + const asyncitr = client.cat(cid); + for await (const itr of asyncitr) { + const data = Buffer.from(itr).toString(); + const dirname = Path.dirname(cwd + "/" + path); + if (!fs.existsSync(dirname)) { + fs.mkdirSync(dirname, { recursive: true }); + } + fs.writeFileSync(path, data); + } + } + fs.writeFileSync(cwd + "/.statik/HEAD", branch); + return; + } + } + catch (err) { + console.error(err); + } +} +//# sourceMappingURL=branching.js.map \ No newline at end of file diff --git a/dist/vc/branching.js.map b/dist/vc/branching.js.map new file mode 100644 index 0000000..a2ed17e --- /dev/null +++ b/dist/vc/branching.js.map @@ -0,0 +1 @@ +{"version":3,"file":"branching.js","sourceRoot":"","sources":["../../src/vc/branching.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/vc/commit.js b/dist/vc/commit.js index 2d15c08..94e110e 100644 --- a/dist/vc/commit.js +++ b/dist/vc/commit.js @@ -11,7 +11,8 @@ export async function Commit(cwd, message) { process.exit(1); } const client = create({ url: FetchConfig(cwd).ipfs_node_url }); - const prevCommit = fs.readFileSync(cwd + "/.statik/HEAD").toString(); + const branch = fs.readFileSync(cwd + "/.statik/HEAD").toString(); + const prevCommit = fs.readFileSync(cwd + "/.statik/heads/" + branch).toString(); const commit = { prevCommit: prevCommit, snapshot: snapshot, @@ -19,7 +20,7 @@ export async function Commit(cwd, message) { timestamp: Date.now() }; const result = await client.add(JSON.stringify(commit)); - fs.writeFileSync(cwd + "/.statik/HEAD", result.path); + fs.writeFileSync(cwd + "/.statik/heads/" + branch, result.path); fs.writeFileSync(cwd + "/.statik/SNAPSHOT", ""); console.log("Committed to IPFS with hash: " + result.path); process.exit(0); diff --git a/dist/vc/commit.js.map b/dist/vc/commit.js.map index df8a93c..8950480 100644 --- a/dist/vc/commit.js.map +++ b/dist/vc/commit.js.map @@ -1 +1 @@ -{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/vc/commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAW,EAAC,OAAe;IACpD,IAAG;QACC,QAAQ,CAAC,GAAG,CAAC,CAAA;QACb,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,GAAC,mBAAmB,CAAC,CAAC,QAAQ,EAAE,CAAA;QACpE,IAAG,CAAC,QAAQ,CAAC,MAAM,EAAC;YAChB,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAA;YACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SAClB;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,EAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,aAAa,EAAC,CAAC,CAAA;QAC5D,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,GAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAA;QAClE,MAAM,MAAM,GAAG;YACX,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACxB,CAAA;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;QACvD,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,eAAe,EAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACjD,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,mBAAmB,EAAC,EAAE,CAAC,CAAA;QAC5C,OAAO,CAAC,GAAG,CACP,+BAA+B,GAAC,MAAM,CAAC,IAAI,CAC9C,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;IAAA,OAAM,CAAC,EAAC;QACL,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;AAEL,CAAC"} \ No newline at end of file +{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/vc/commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAW,EAAC,OAAe;IACpD,IAAG;QACC,QAAQ,CAAC,GAAG,CAAC,CAAA;QACb,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,GAAC,mBAAmB,CAAC,CAAC,QAAQ,EAAE,CAAA;QACpE,IAAG,CAAC,QAAQ,CAAC,MAAM,EAAC;YAChB,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAA;YACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SAClB;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,EAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,aAAa,EAAC,CAAC,CAAA;QAC5D,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,GAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC9D,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,GAAC,iBAAiB,GAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC3E,MAAM,MAAM,GAAG;YACX,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACxB,CAAA;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;QACvD,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,iBAAiB,GAAC,MAAM,EAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC1D,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,mBAAmB,EAAC,EAAE,CAAC,CAAA;QAC5C,OAAO,CAAC,GAAG,CACP,+BAA+B,GAAC,MAAM,CAAC,IAAI,CAC9C,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;IAAA,OAAM,CAAC,EAAC;QACL,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;AAEL,CAAC"} \ No newline at end of file diff --git a/dist/vc/history.js b/dist/vc/history.js index c6e6d07..7ac7f43 100644 --- a/dist/vc/history.js +++ b/dist/vc/history.js @@ -6,7 +6,8 @@ export async function Log(cwd) { try { IsStatik(cwd); const client = create({ url: FetchConfig(cwd).ipfs_node_url }); - let head = fs.readFileSync(cwd + "/.statik/HEAD").toString(); + const branch = fs.readFileSync(cwd + "/.statik/HEAD").toString(); + let head = fs.readFileSync(cwd + "/.statik/heads/" + branch).toString(); let asyncitr = client.cat(head); console.log("Commit history: "); while (head.length) { diff --git a/dist/vc/history.js.map b/dist/vc/history.js.map index d6d1cdc..728b584 100644 --- a/dist/vc/history.js.map +++ b/dist/vc/history.js.map @@ -1 +1 @@ -{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/vc/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,GAAW;IACjC,IAAG;QACC,QAAQ,CAAC,GAAG,CAAC,CAAA;QACb,MAAM,MAAM,GAAG,MAAM,CAAC,EAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,aAAa,EAAC,CAAC,CAAA;QAC5D,IAAI,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,GAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC1D,IAAI,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC/B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;QAC/B,OAAM,IAAI,CAAC,MAAM,EAAC;YACd,IAAI,KAAK,EAAC,MAAM,GAAG,IAAI,QAAQ,EAAC;gBAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;gBACxC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAC,IAAI,GAAC,GAAG,GAAC,GAAG,GAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAA;gBACtD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAA;gBAClC,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;aAC9B;SACJ;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;IAAA,OAAM,CAAC,EAAC;QACL,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;AACL,CAAC"} \ No newline at end of file +{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/vc/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,GAAW;IACjC,IAAG;QACC,QAAQ,CAAC,GAAG,CAAC,CAAA;QACb,MAAM,MAAM,GAAG,MAAM,CAAC,EAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,aAAa,EAAC,CAAC,CAAA;QAC5D,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,GAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC9D,IAAI,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,GAAC,iBAAiB,GAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;QACnE,IAAI,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC/B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;QAC/B,OAAM,IAAI,CAAC,MAAM,EAAC;YACd,IAAI,KAAK,EAAC,MAAM,GAAG,IAAI,QAAQ,EAAC;gBAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;gBACxC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAC,IAAI,GAAC,GAAG,GAAC,GAAG,GAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAA;gBACtD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAA;gBAClC,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;aAC9B;SACJ;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;IAAA,OAAM,CAAC,EAAC;QACL,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;AACL,CAAC"} \ No newline at end of file diff --git a/dist/vc/init.js b/dist/vc/init.js index bd525b9..f0d572e 100644 --- a/dist/vc/init.js +++ b/dist/vc/init.js @@ -6,9 +6,9 @@ export async function Init(cwd, ipfs_node_url) { reinitialize = true; fs.rmdirSync(cwd + "/.statik", { recursive: true }); } - fs.mkdirSync(cwd + "/.statik"); - fs.mkdirSync(cwd + "/.statik/refs/heads", { recursive: true }); - fs.writeFileSync(cwd + "/.statik/HEAD", ""); + fs.mkdirSync(cwd + "/.statik/heads", { recursive: true }); + fs.writeFileSync(cwd + "/.statik/heads/main", ""); + fs.writeFileSync(cwd + "/.statik/HEAD", "main"); fs.writeFileSync(cwd + "/.statik/SNAPSHOT", ""); fs.writeFileSync(cwd + "/.statik/CONFIG", JSON.stringify({ ipfs_node_url: ipfs_node_url diff --git a/dist/vc/init.js.map b/dist/vc/init.js.map index e927634..b4fb1fb 100644 --- a/dist/vc/init.js.map +++ b/dist/vc/init.js.map @@ -1 +1 @@ -{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/vc/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAW,EAAC,aAAoB;IACvD,IAAG;QACC,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAG,EAAE,CAAC,UAAU,CAAC,GAAG,GAAC,UAAU,CAAC,EAAC;YAC7B,YAAY,GAAG,IAAI,CAAC;YACpB,EAAE,CAAC,SAAS,CAAC,GAAG,GAAC,UAAU,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;SAClD;QACD,EAAE,CAAC,SAAS,CAAC,GAAG,GAAC,UAAU,CAAC,CAAA;QAC5B,EAAE,CAAC,SAAS,CAAC,GAAG,GAAC,qBAAqB,EAAC,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;QAEzD,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,eAAe,EAAE,EAAE,CAAC,CAAA;QACzC,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,mBAAmB,EAAE,EAAE,CAAC,CAAA;QAC7C,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;YACnD,aAAa,EAAE,aAAa;SAC/B,CAAC,CAAC,CAAA;QAEH,IAAG,YAAY,EAAC;YACZ,OAAO,CAAC,KAAK,CAAC,qCAAqC,GAAC,GAAG,GAAC,UAAU,CAAC,CAAA;SACtE;aAAI;YACD,OAAO,CAAC,GAAG,CAAC,mCAAmC,GAAC,GAAG,GAAC,UAAU,CAAC,CAAA;SAClE;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;IAAA,OAAM,CAAC,EAAC;QACL,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;AACL,CAAC"} \ No newline at end of file +{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/vc/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAW,EAAC,aAAoB;IACvD,IAAG;QACC,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAG,EAAE,CAAC,UAAU,CAAC,GAAG,GAAC,UAAU,CAAC,EAAC;YAC7B,YAAY,GAAG,IAAI,CAAC;YACpB,EAAE,CAAC,SAAS,CAAC,GAAG,GAAC,UAAU,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;SAClD;QACD,EAAE,CAAC,SAAS,CAAC,GAAG,GAAC,gBAAgB,EAAC,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;QAEpD,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,qBAAqB,EAAE,EAAE,CAAC,CAAA;QAC/C,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,eAAe,EAAE,MAAM,CAAC,CAAA;QAC7C,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,mBAAmB,EAAE,EAAE,CAAC,CAAA;QAC7C,EAAE,CAAC,aAAa,CAAC,GAAG,GAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;YACnD,aAAa,EAAE,aAAa;SAC/B,CAAC,CAAC,CAAA;QAEH,IAAG,YAAY,EAAC;YACZ,OAAO,CAAC,KAAK,CAAC,qCAAqC,GAAC,GAAG,GAAC,UAAU,CAAC,CAAA;SACtE;aAAI;YACD,OAAO,CAAC,GAAG,CAAC,mCAAmC,GAAC,GAAG,GAAC,UAAU,CAAC,CAAA;SAClE;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;IAAA,OAAM,CAAC,EAAC;QACL,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;KAClB;AACL,CAAC"} \ No newline at end of file diff --git a/dist/vc/stage.js b/dist/vc/stage.js index c22ac12..84cfcf8 100644 --- a/dist/vc/stage.js +++ b/dist/vc/stage.js @@ -11,11 +11,14 @@ export async function Add(cwd, paths) { return; } const client = create({ url: FetchConfig(cwd).ipfs_node_url }); - const prevCommit = fs.readFileSync(cwd + "/.statik/HEAD").toString(); + const branch = fs.readFileSync(cwd + "/.statik/HEAD").toString(); + const prevCommit = fs.readFileSync(cwd + "/.statik/heads/" + branch).toString(); if (!prevCommit.length) { let snapshot = []; for (const path of paths) { for await (const result of client.addAll(globSource(path, { recursive: true }))) { + if (fs.statSync(cwd + "/" + path).isDirectory()) + continue; snapshot.push(result); } } @@ -40,6 +43,10 @@ export async function Add(cwd, paths) { // Not optimized for (const path of paths) { for await (const result of client.addAll(globSource(path, { recursive: true }))) { + // Check if the path is a directory + const path = result.path; + if (fs.statSync(cwd + "/" + path).isDirectory()) + continue; let flag = true; for (const prev of prevContent) { if (prev.path == result.path) { @@ -53,6 +60,11 @@ export async function Add(cwd, paths) { } } const result = await client.add(JSON.stringify(prevContent)); + // console.log(result.path,prevSnapshot) + if (result.path == prevSnapshot) { + console.log("There are no changes to add"); + return; + } fs.writeFileSync(cwd + "/.statik/SNAPSHOT", result.path); console.log("Files staged to IPFS with cid: " + result.path); } diff --git a/dist/vc/stage.js.map b/dist/vc/stage.js.map index d567124..8da85a0 100644 --- a/dist/vc/stage.js.map +++ b/dist/vc/stage.js.map @@ -1 +1 @@ -{"version":3,"file":"stage.js","sourceRoot":"","sources":["../../src/vc/stage.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"stage.js","sourceRoot":"","sources":["../../src/vc/stage.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index 9b99fdd..20521e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "statikvc", - "version": "1.0.5-alpha", + "version": "1.1.0-alpha", "description": "An IPFS based version control system with static file hosting features. Basic functions like repo initiation, staging, committing, and logging have been implemented. (Under active development)", "exports": "./dist/index.js", "scripts": { diff --git a/src/index.ts b/src/index.ts index 4cc9c6c..b2959a0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,24 +3,24 @@ import { Command } from "commander"; import figlet from "figlet"; import { Init } from "./vc/init.js"; import { Add } from "./vc/stage.js"; -import { create } from "ipfs-http-client"; import { Commit } from "./vc/commit.js"; import { Log } from "./vc/history.js"; - -console.log(figlet.textSync("Statik")); +import { Jump, List } from "./vc/branching.js"; const program = new Command(); program .name("statik") .version("1.0.5-alpha") - .description("An IPFS based version control system with static file hosting features") + .description(figlet.textSync("Statik")+"\nAn IPFS based version control system with static file hosting features") program.command("init ").description("Initialize a new Statik repository") program.command("add [file_path]").description("Add a file to the Statik repository") program.command("commit ").description("Commit changes to the Statik repository") -program.command("log").description("View the commit history of the Statik repository") +program.command("log").description("View the commit history of the current branch") +program.command("branch").description("List all branches in the Statik repository") +program.command("jump ").description("Switch between branches") program.parse(process.argv); -if(program.args.length<1) { +if (program.args.length < 1) { program.outputHelp() process.exit(0) } @@ -30,7 +30,7 @@ const cwd = process.cwd(); switch (program.args[0]) { case "init": const ipfs_node_url = program.args[1] - Init(cwd,ipfs_node_url); + Init(cwd, ipfs_node_url); break; case "add": Add(cwd, program.args.slice(1)); @@ -41,6 +41,12 @@ switch (program.args[0]) { case "log": Log(cwd); break; + case "branch": + List(cwd); + break; + case "jump": + Jump(cwd, program.args[1]); + break; default: program.outputHelp(); process.exit(0) diff --git a/src/utils/changes.ts b/src/utils/changes.ts new file mode 100644 index 0000000..7d3336e --- /dev/null +++ b/src/utils/changes.ts @@ -0,0 +1,32 @@ +import { IPFSHTTPClient } from "ipfs-http-client/dist/src/types"; +import fs from 'fs' +import { multihashToCID } from "./cid.js"; +const checkChange = async(currentFiles:string[],prevContent:any[],file:string,client: IPFSHTTPClient,cwd:string) => { + if(!currentFiles.includes(file)) return false + const prevFile = prevContent.find((f: any) => f.path === file) + // console.log(prevFile) + const cid = multihashToCID(prevFile.cid) + // console.log(cid,path) + const asyncitr = client.cat(cid) + for await (const itr of asyncitr) { + const data = Buffer.from(itr).toString() + if (data !== fs.readFileSync(cwd +"/"+ file).toString()) return true; + } + return false +} +export async function isOverriding(cwd: string, client: IPFSHTTPClient, prevContent:any[],currentFiles:string[]) { + let overrides = false; + // console.log(currentFiles) + const prevFiles = prevContent.map((file: any) => file.path) + // console.log(prevFiles) + const added = currentFiles.filter((file: any) => !prevFiles.includes(file)) + const deleted = prevFiles.filter((file: any) => !currentFiles.includes(file)) + if (deleted.length) overrides = true; + let changed = [] + for (const file of prevFiles) { + if (await checkChange(currentFiles,prevContent,file,client,cwd)) changed.push(file) + } + if (changed.length) overrides = true; + // console.log(overrides,added,deleted,changed) + return {overrides,newFiles:added,deletedFiles:deleted,updated:changed}; +} \ No newline at end of file diff --git a/src/utils/cid.ts b/src/utils/cid.ts new file mode 100644 index 0000000..d7aaa1c --- /dev/null +++ b/src/utils/cid.ts @@ -0,0 +1,6 @@ +import { CID } from "ipfs-http-client"; +export function multihashToCID(cid:any){ + const {code,version,hash} = cid + const bytes = new Uint8Array(Object.values(hash)) + return new CID(version,code,cid,bytes) +} \ No newline at end of file diff --git a/src/utils/dirwalk.ts b/src/utils/dirwalk.ts new file mode 100644 index 0000000..e2fed80 --- /dev/null +++ b/src/utils/dirwalk.ts @@ -0,0 +1,32 @@ +import fs from 'fs'; +import path from 'path'; + +export function* readAllFiles(dir: string): Generator { + const files = fs.readdirSync(dir, { withFileTypes: true }); + const cwd = process.cwd() + for (const file of files) { + if (file.isDirectory()) { + yield* readAllFiles(path.join(dir, file.name)); + } else { + yield path.relative(cwd, path.join(dir, file.name)); + } + } +} + +export function deleteAllFiles(dir:string, exempt:string[]) { + const files = fs.readdirSync(dir, { withFileTypes: true }); + const cwd = process.cwd() + for (const file of files) { + if (file.isDirectory()) { + deleteAllFiles(path.join(dir, file.name),exempt); + } + if(!exempt.includes(path.relative(cwd, path.join(dir, file.name)))){ + if(file.isFile()){ + fs.unlinkSync(path.join(dir, file.name)) + }else if (file.isDirectory() && !fs.readdirSync(path.join(dir, file.name)).length) { + fs.rmdirSync(path.join(dir, file.name)) + } + } + } + return +} \ No newline at end of file diff --git a/src/utils/fetchContent.ts b/src/utils/fetchContent.ts new file mode 100644 index 0000000..256dde7 --- /dev/null +++ b/src/utils/fetchContent.ts @@ -0,0 +1,17 @@ +import { IPFSHTTPClient } from "ipfs-http-client/dist/src/types"; + +export async function commitContent(commitId: string, client: IPFSHTTPClient) { + let asyncitr = client.cat(commitId) + let prevSnapshot = ""; + for await (const itr of asyncitr) { + const data = Buffer.from(itr).toString() + prevSnapshot = JSON.parse(data).snapshot + } + let prevContent = []; + asyncitr = client.cat(prevSnapshot) + for await (const itr of asyncitr) { + const data = Buffer.from(itr).toString() + prevContent = JSON.parse(data) + } + return prevContent +} \ No newline at end of file diff --git a/src/vc/branching.ts b/src/vc/branching.ts new file mode 100644 index 0000000..7b772b5 --- /dev/null +++ b/src/vc/branching.ts @@ -0,0 +1,125 @@ +import { create } from "ipfs-http-client"; +import { IsStatik } from "../utils/checkStatik.js"; +import fs from 'fs' +import { FetchConfig } from "../utils/fetchConfig.js"; +import Path from 'path' +import { multihashToCID } from "../utils/cid.js"; +import { isOverriding } from "../utils/changes.js"; +import { commitContent } from "../utils/fetchContent.js"; +import { deleteAllFiles, readAllFiles } from "../utils/dirwalk.js"; +export async function List(cwd: string){ + try{ + IsStatik(cwd) + // List all files + const currentBranch = fs.readFileSync(cwd+"/.statik/HEAD").toString() + const files = fs.readdirSync(cwd+"/.statik/heads") + for(const file of files){ + if(file===currentBranch){ + console.log("-> "+file+" <-") + }else{ + console.log(file) + } + } + }catch(err){ + console.error(err) + } +} + +export async function Jump(cwd: string,branch: string){ + try{ + IsStatik(cwd) + const currentBranch = fs.readFileSync(cwd+"/.statik/HEAD").toString() + if(branch===currentBranch){ + console.log("Already on branch "+branch) + return + } + const currentHead = fs.readFileSync(cwd+"/.statik/heads/"+currentBranch).toString() + // Check for staged changes + if(fs.readFileSync(cwd+"/.statik/SNAPSHOT").toString().length){ + console.log("There are staged changes. You cannot switch branch without commiting it") + return + } + + if(!fs.existsSync(cwd+"/.statik/heads/"+branch)){ + console.log("Branching out to "+branch+"...") + fs.writeFileSync(cwd+"/.statik/heads/"+branch,currentHead) + fs.writeFileSync(cwd+"/.statik/HEAD",branch); + }else{ + const commitId = fs.readFileSync(cwd+"/.statik/heads/"+branch).toString() + const client = create({url: FetchConfig(cwd).ipfs_node_url}) + console.log("Switching to branch "+branch+"\n"+"Head commit <"+commitId+">") + const currentFiles = [...readAllFiles(cwd)] + + // Check for unstaged changes + const oldBranchContent = await commitContent(currentHead,client) + const {overrides:hasUnstagedChanges,newFiles:addedFiles,updated:unstagedChanges,deletedFiles} = await isOverriding(cwd,client,oldBranchContent,currentFiles) + if(hasUnstagedChanges){ + if(unstagedChanges.length>0){ + console.log("\nUnstaged changes:") + for(const file of unstagedChanges){ + console.log(file) + } + } + if(deletedFiles.length>0){ + console.log("\nDeleted files:") + for(const file of deletedFiles){ + console.log(file) + } + } + console.log("\nThere are unstaged changes. You cannot switch branch without commiting it") + console.log("Abort") + process.exit(1) + } + // Handle the case where not unstaged but overriding + // Solution: Prevent only if added files and deleted files are overriding + // Check for overriding changes + const newBranchContent = await commitContent(commitId,client) + const {newFiles,updated} = await isOverriding(cwd,client,newBranchContent,addedFiles) + if(updated.length>0){ + console.log("Overriding changes:") + for(const file of updated){ + console.log(file) + } + console.log("There are overriding changes. You cannot switch branch without commiting it") + console.log("Abort") + process.exit(1) + } + + // Find the basepath and recursively delete all files + let basepathCount=Infinity; + let index = 0 + if(newBranchContent.length>0){ + basepathCount = newBranchContent[0].path.split("/").length + } + for(let i=1;i