diff --git a/.gitignore b/.gitignore index a9a8a531..58908482 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,8 @@ node_modules/ package-lock.json # testing -/coverage +**/coverage +coverage/ # production build/ diff --git a/lerna.json b/lerna.json index dc4a6991..fe5353db 100644 --- a/lerna.json +++ b/lerna.json @@ -2,5 +2,5 @@ "packages": [ "packages/*" ], - "version": "0.3.0-alpha.5" + "version": "0.3.0" } diff --git a/package.json b/package.json index 8a398331..cdc4cc4c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,5 @@ "uninstall:global": "npm uninstall -g @pando/git-pando @pando/git-remote-pando", "install:global": "npm run unlink:all && npm install -g @pando/git-pando @pando/git-remote-pando" }, - "devDependencies": { - "lerna": "^3.4.3" - } + "devDependencies": {} } diff --git a/packages/git-pando/package.json b/packages/git-pando/package.json index d871e491..af4ebd38 100755 --- a/packages/git-pando/package.json +++ b/packages/git-pando/package.json @@ -1,6 +1,6 @@ { "name": "@pando/git-pando", - "version": "0.3.0-alpha.5", + "version": "0.3.0", "description": "Git extension for pando", "author": "Pando Network ", "contributors": [ @@ -30,9 +30,9 @@ "@aragon/apm": "^3.1.0-beta.1", "@aragon/os": "^4.0.1", "@aragon/wrapper": "^3.0.0-beta.4", - "@pando/colony": "^0.3.0-alpha.5", - "@pando/kit": "^0.3.0-alpha.5", - "@pando/repository": "^0.3.0-alpha.5", + "@pando/colony": "^0.3.0", + "@pando/kit": "^0.3.0", + "@pando/repository": "^0.3.0", "eth-ens-namehash": "^2.0.8", "eth-provider": "0.2.1", "find-up": "^3.0.0", @@ -52,5 +52,5 @@ "tslint-config-prettier": "^1.18.0", "typescript": "^3.3.1" }, - "gitHead": "cb2b7c6fe7805fdbbcd29733c3ebb24eeb5d3d42" + "gitHead": "a449d46d5eb6a86efae8f0fdcf1e1749e432d928" } diff --git a/packages/git-remote-pando/package.json b/packages/git-remote-pando/package.json index 893f4911..c3b1f9e1 100755 --- a/packages/git-remote-pando/package.json +++ b/packages/git-remote-pando/package.json @@ -1,6 +1,6 @@ { "name": "@pando/git-remote-pando", - "version": "0.3.0-alpha.5", + "version": "0.3.0", "description": "git-remote-helper for pando", "author": "Pando Network ", "contributors": [ @@ -27,7 +27,7 @@ "build": "tsc" }, "dependencies": { - "@pando/repository": "^0.3.0-alpha.5", + "@pando/repository": "^0.3.0", "cids": "^0.5.7", "debug": "^4.1.1", "eth-provider": "0.2.1", @@ -52,5 +52,5 @@ "tslint-config-prettier": "^1.18.0", "typescript": "^3.3.1" }, - "gitHead": "cb2b7c6fe7805fdbbcd29733c3ebb24eeb5d3d42" + "gitHead": "a449d46d5eb6a86efae8f0fdcf1e1749e432d928" } diff --git a/packages/pando-colony/package.json b/packages/pando-colony/package.json index 461c6d68..23b933b3 100755 --- a/packages/pando-colony/package.json +++ b/packages/pando-colony/package.json @@ -1,6 +1,6 @@ { "name": "@pando/colony", - "version": "0.3.0-alpha.5", + "version": "0.3.0", "author": "Pando Network ", "contributors": [ "Olivier Sarrouy ", @@ -24,8 +24,8 @@ "publish:major:rinkeby": "aragon apm publish major --use-frame --files ./app/build --environment rinkeby" }, "dependencies": { - "@aragon/os": "^4.0.1", - "@pando/repository": "^0.3.0-alpha.5" + "@aragon/os": "4.2.0", + "@pando/repository": "^0.3.0" }, "devDependencies": { "@aragon/cli": "^5.5.0", @@ -42,5 +42,5 @@ "prettier": "^1.8.2", "truffle": "^5.0.0" }, - "gitHead": "cb2b7c6fe7805fdbbcd29733c3ebb24eeb5d3d42" + "gitHead": "a449d46d5eb6a86efae8f0fdcf1e1749e432d928" } diff --git a/packages/pando-kit/package.json b/packages/pando-kit/package.json index e66adcbd..573132cf 100755 --- a/packages/pando-kit/package.json +++ b/packages/pando-kit/package.json @@ -1,6 +1,6 @@ { "name": "@pando/kit", - "version": "0.3.0-alpha.5", + "version": "0.3.0", "author": "Pando Network ", "contributors": [ "Olivier Sarrouy " @@ -24,14 +24,14 @@ "@aragon/apps-finance": "^2.1.0", "@aragon/apps-shared-minime": "^1.0.0", "@aragon/apps-token-manager": "^2.0.0", - "@aragon/apps-vault": "^4.0.0", + "@aragon/apps-vault": "4.1.0", "@aragon/apps-voting": "^2.0.0", - "@aragon/os": "4.0.1", - "@pando/colony": "^0.3.0-alpha.5" + "@aragon/os": "4.2.0", + "@pando/colony": "^0.3.0" }, "devDependencies": { "@aragon/cli": "^5.5.0", - "@pando/repository": "^0.3.0-alpha.5", + "@pando/repository": "^0.3.0", "eslint": "5.5.0", "eslint-config-prettier": "^3.0.1", "eslint-config-standard": "^12.0.0", @@ -44,7 +44,8 @@ "eth-provider": "^0.2.1", "ethlint": "^1.2.1", "prettier": "^1.8.2", - "truffle": "^5.0.0" + "truffle": "^5.0.0", + "truffle-contract": "^4.0.14" }, - "gitHead": "cb2b7c6fe7805fdbbcd29733c3ebb24eeb5d3d42" + "gitHead": "a449d46d5eb6a86efae8f0fdcf1e1749e432d928" } diff --git a/packages/pando-lib/package.json b/packages/pando-lib/package.json new file mode 100644 index 00000000..7dfc9c77 --- /dev/null +++ b/packages/pando-lib/package.json @@ -0,0 +1,62 @@ +{ + "name": "pando-lib", + "version": "0.3.0", + "description": "utility scripts for handling state-management for git-pando", + "main": "prettier.config.js", + "scripts": { + "watch": "tsc -w", + "lint": "tslint -c tslint.json 'src/**/*.ts'", + "build": "tsc", + "test": "mocha --timeout 500000 -r ts-node/register src/**/*.spec.ts" + }, + "dependencies": { + "@types/node": "^10.12.21", + "cids": "^0.5.7", + "ipfs-http-client": "^29.1.1", + "ipld": "^0.23.0", + "ipld-git": "~0.4.0", + "lodash.orderby": "^4.6.0", + "lodash.uniqwith": "^4.5.0", + "rimraf": "^2.6.3", + "multicodec": "~0.5.0", + "multihashes": "~0.4.14", + "multihashing-async": "~0.7.0", + "smart-buffer": "^4.0.2", + "strftime": "~0.10.0" + }, + "devDependencies": { + "@types/chai": "^4.1.7", + "@types/mocha": "^5.2.6", + "chai": "^4.2.0", + "chai-as-promised": "^7.1.1", + "dirty-chai": "^2.0.1", + "mocha": "^6.1.4", + "ts-node": "^8.1.0", + "tslint": "^5.14.0", + "tslint-config-prettier": "^1.18.0", + "typescript": "^3.3.1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/pandonetwork/pando.git" + }, + "keywords": [ + "aragon", + "dao", + "pando", + "ipfs", + "ethereum", + "git" + ], + "author": "Pando Network ", + "contributors": [ + "Olivier Sarrouy ", + "Cory Dickson " + ], + "license": "(GPL-3.0-or-later OR MIT)", + "bugs": { + "url": "https://github.com/pandonetwork/pando/issues" + }, + "homepage": "https://github.com/pandonetwork/pando#readme", + "gitHead": "a449d46d5eb6a86efae8f0fdcf1e1749e432d928" +} diff --git a/packages/pando-lib/prettier.config.js b/packages/pando-lib/prettier.config.js new file mode 100644 index 00000000..d13ae925 --- /dev/null +++ b/packages/pando-lib/prettier.config.js @@ -0,0 +1,7 @@ +module.exports = { + bracketSpacing: true, + semi: false, + singleQuote: true, + printWidth: 160, + trailingComma: 'es5', +} diff --git a/packages/pando-lib/src/scripts.ts b/packages/pando-lib/src/scripts.ts new file mode 100644 index 00000000..7232829e --- /dev/null +++ b/packages/pando-lib/src/scripts.ts @@ -0,0 +1,201 @@ +import CID from 'cids' +import IPFS from 'ipfs-http-client' +import IPLD from 'ipld' +import IPLDGit from 'ipld-git' +import { cidToSha } from 'ipld-git/src/util/util.js' +import orderBy from 'lodash.orderby' +import uniqWith from 'lodash.uniqwith' + +const ipfs = IPFS({ host: 'ipfs.infura.io', port: '5001', protocol: 'https' }) +const ipld = new IPLD({ blockService: ipfs.block, formats: [IPLDGit] }) + +export interface IAuthorOrCommitter { + name: string + email: string + date: string +} + +export interface ITree { [path: string]: string } + +export interface ILinkedDataCommit { + author: IAuthorOrCommitter + committer: IAuthorOrCommitter + message: string + parents: ILinkedDataCommit[] | null + tree: ITree +} + +export interface IModifiedTree { + [path: string]: { + lastEdit: { + date: string + message: string + } + mode: string | number + blob: string + } +} + +export const fetchFilesFromTree = (hash: string, path?: string) => { + return new Promise(async (resolve, reject) => { + let files = {} + const cid = new CID(hash) + + ipld.get(cid, async (err, result) => { + if (err) { + reject(err) + } else { + let tree = result.value as ITree + for (const entry in tree) { + if (entry) { + const _path = path ? path + '/' + entry : entry + if (tree[entry]['mode'] === '40000') { + const _files = await fetchFilesFromTree(tree[entry]['hash']['/'], _path) + files = { ...files, ..._files } + } else { + files[_path] = { + mode: tree[entry]['mode'], + blob: new CID(tree[entry]['hash']['/']).toBaseEncodedString()} + } + } + } + resolve(files as IModifiedTree) + } + }) + }) +} + +export const fetchHistory = async (cid: CID, history: Commit[]): Promise => { + return new Promise(async (resolve, reject) => { + try { + const commit = await fetchCommit(cid) + history.push(commit) + + for (const parent of commit.parents) { + history = await fetchHistory(parent['/'], history) + } + + resolve(history) + } catch (err) { + reject(err) + } + }) +} + +export const fetchCommit = async (cid: CID): Promise => { + return new Promise((resolve, reject) => { + try { + ipld.get(cid, async (err, result) => { + if (err) { + reject(err) + } else { + const IPLDCommit = result.value as ILinkedDataCommit + const commit = new Commit(IPLDCommit) + commit.cid = cid + await commit.fetchModifiedTree() + resolve(commit) + } + }) + } catch (err) { + reject(err) + } + }) +} + +export const fetchOrderedHistory = async (cid: CID, formerHistory: Commit[]) => { + let history = await fetchHistory(cid, formerHistory) + history = uniqWith(history, (one, two) => { + return one.cid === two.cid + }) + + history = orderBy( + history, + [ + commit => { + // https://github.com/git/git/blob/v2.3.0/Documentation/date-formats.txt + /* eslint-disable-next-line no-unused-vars */ + const [timestamp, offset] = commit.author.date.split(' ') + return timestamp + }, + ], + ['desc'] + ) + + return history +} + +export default class Commit { + public cid: string + public sha: string + public author: IAuthorOrCommitter + public committer: IAuthorOrCommitter + public message: string + public parents: ILinkedDataCommit[] + public tree: ITree | IModifiedTree | {} + + constructor(commit: ILinkedDataCommit) { + + if (commit) { + if (commit.tree.hasOwnProperty('/')) { + const _cid = new CID(commit.tree['/']) + const _parents : ILinkedDataCommit[] = commit.parents ? + commit.parents.map(parent => (new CID(Object.values(parent)[0]).toBaseEncodedString())) : [] + this.cid = _cid + this.sha = cidToSha(commit.tree['/']).toString('hex') + this.author = commit.author + this.committer = commit.committer + this.message = commit.message + this.tree = commit.tree + this.parents = _parents + } + } + } + + public async fetchModifiedTree(): Promise { + return new Promise(async (resolve, reject) => { + try { + let files = await fetchFilesFromTree(this.tree['/']) + for (const path in files) { + files[path] = { + lastEdit: { date: this.committer.date, message: this.message}, + ...files[path] + } + } + this.tree = files + resolve() + } catch (err) { + reject("Error") + } + }) + + } + + public async getOrderedHistory(): Promise { + return new Promise(async (resolve, reject) => { + try { + const orderedHistory = await fetchOrderedHistory(this.cid, []) + resolve(orderedHistory) + } catch (err) { + reject(err) + } + }) + } +} + +export function retrieveIPLDCommitObject(commit: Commit): Promise{ + const commitCid = commit.cid + return new Promise((resolve, reject) => { + try { + ipld.get(commitCid, async (err, result) => { + if (err) { + reject(err) + } else { + const IPLDCommit = result.value as ILinkedDataCommit + resolve(IPLDCommit) + } + }) + } catch (err) { + reject(err) + } + }) +} \ No newline at end of file diff --git a/packages/pando-lib/src/test/fixtures/0a1690e0640a212aafed1824eb208ffddab1789b b/packages/pando-lib/src/test/fixtures/0a1690e0640a212aafed1824eb208ffddab1789b new file mode 100644 index 00000000..31f6b188 Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/0a1690e0640a212aafed1824eb208ffddab1789b differ diff --git a/packages/pando-lib/src/test/fixtures/0faccf822badf55f15fb0c3f4122fa13798f769e b/packages/pando-lib/src/test/fixtures/0faccf822badf55f15fb0c3f4122fa13798f769e new file mode 100644 index 00000000..b397a3ee Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/0faccf822badf55f15fb0c3f4122fa13798f769e differ diff --git a/packages/pando-lib/src/test/fixtures/19f0805d8de36b6442e8c573074112ba72ad6780 b/packages/pando-lib/src/test/fixtures/19f0805d8de36b6442e8c573074112ba72ad6780 new file mode 100644 index 00000000..8a375168 Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/19f0805d8de36b6442e8c573074112ba72ad6780 differ diff --git a/packages/pando-lib/src/test/fixtures/42fd8d7404f5127314e248b2cbbe1423f12faeb9 b/packages/pando-lib/src/test/fixtures/42fd8d7404f5127314e248b2cbbe1423f12faeb9 new file mode 100644 index 00000000..af1098f2 --- /dev/null +++ b/packages/pando-lib/src/test/fixtures/42fd8d7404f5127314e248b2cbbe1423f12faeb9 @@ -0,0 +1,3 @@ +xK +0@]$NndJ+#%7Wpxx \CE`NHG*y,8!;DcЛie +U_rbpy$hki5% \ No newline at end of file diff --git a/packages/pando-lib/src/test/fixtures/4b271beec86978454072b632f382c6ccb3938a45 b/packages/pando-lib/src/test/fixtures/4b271beec86978454072b632f382c6ccb3938a45 new file mode 100644 index 00000000..b612a5c3 Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/4b271beec86978454072b632f382c6ccb3938a45 differ diff --git a/packages/pando-lib/src/test/fixtures/4d5e7ac145aaf440600dd06a97e8cc65f8acd4dc b/packages/pando-lib/src/test/fixtures/4d5e7ac145aaf440600dd06a97e8cc65f8acd4dc new file mode 100644 index 00000000..0b11bf96 --- /dev/null +++ b/packages/pando-lib/src/test/fixtures/4d5e7ac145aaf440600dd06a97e8cc65f8acd4dc @@ -0,0 +1,2 @@ +xJ@ާ{Q6=Dli,ldK)Myg\l}!BD.A+ɜL1KXHP +=92YDe42g!Il^pݯQk5VeZ8H91C㮅EDx8G|wӜxb`"c(8RF)= >`Wc25D{@N!]N Ls뫬alc02ZpƮǖZ`]aV׷MyXŴAs<^fsӣqܤC!-S_6U?CE \ No newline at end of file diff --git a/packages/pando-lib/src/test/fixtures/5af4dc18899e8ac95904eaf2b4abf1a2ca5e1507 b/packages/pando-lib/src/test/fixtures/5af4dc18899e8ac95904eaf2b4abf1a2ca5e1507 new file mode 100644 index 00000000..34be5977 Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/5af4dc18899e8ac95904eaf2b4abf1a2ca5e1507 differ diff --git a/packages/pando-lib/src/test/fixtures/70a3540bd51658ab564806785d5516a4e89b6450 b/packages/pando-lib/src/test/fixtures/70a3540bd51658ab564806785d5516a4e89b6450 new file mode 100644 index 00000000..efe1fd9c Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/70a3540bd51658ab564806785d5516a4e89b6450 differ diff --git a/packages/pando-lib/src/test/fixtures/7ffd1401f599c70364eda431d29363e037b2c92c b/packages/pando-lib/src/test/fixtures/7ffd1401f599c70364eda431d29363e037b2c92c new file mode 100644 index 00000000..2168694b Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/7ffd1401f599c70364eda431d29363e037b2c92c differ diff --git a/packages/pando-lib/src/test/fixtures/802992c4220de19a90767f3000a79a31b98d0df7 b/packages/pando-lib/src/test/fixtures/802992c4220de19a90767f3000a79a31b98d0df7 new file mode 100644 index 00000000..6a172c1c Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/802992c4220de19a90767f3000a79a31b98d0df7 differ diff --git a/packages/pando-lib/src/test/fixtures/832b4a8497de78248f70c06e0f06e785a74fea4c b/packages/pando-lib/src/test/fixtures/832b4a8497de78248f70c06e0f06e785a74fea4c new file mode 100644 index 00000000..ec235752 Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/832b4a8497de78248f70c06e0f06e785a74fea4c differ diff --git a/packages/pando-lib/src/test/fixtures/88a72947d8b4f0ab7185389efcdd5dace4643e04 b/packages/pando-lib/src/test/fixtures/88a72947d8b4f0ab7185389efcdd5dace4643e04 new file mode 100644 index 00000000..371d2ce1 --- /dev/null +++ b/packages/pando-lib/src/test/fixtures/88a72947d8b4f0ab7185389efcdd5dace4643e04 @@ -0,0 +1,2 @@ +x +!E[ЧѢU@'S8L}~ .7Z]]ߘe)\РJT#șARȁ|t'ƍ.msh՘b24BiDO9Xdj[ϡpzv&L BPp%\E?:tpM_^OugF:|'v68~K\)U[lZ`+g=f&X i \ No newline at end of file diff --git a/packages/pando-lib/src/test/fixtures/cf461f783732a8aa5f7d8679e112bd4c876aa19b b/packages/pando-lib/src/test/fixtures/cf461f783732a8aa5f7d8679e112bd4c876aa19b new file mode 100644 index 00000000..472520a7 Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/cf461f783732a8aa5f7d8679e112bd4c876aa19b differ diff --git a/packages/pando-lib/src/test/fixtures/d52e70c9e34ac03cdf77f46aec388c2f9574bd93 b/packages/pando-lib/src/test/fixtures/d52e70c9e34ac03cdf77f46aec388c2f9574bd93 new file mode 100644 index 00000000..6a19749b Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/d52e70c9e34ac03cdf77f46aec388c2f9574bd93 differ diff --git a/packages/pando-lib/src/test/fixtures/ed19ea7ea03ecd036c653b9c4cba16df71424a60 b/packages/pando-lib/src/test/fixtures/ed19ea7ea03ecd036c653b9c4cba16df71424a60 new file mode 100644 index 00000000..5c2d2668 --- /dev/null +++ b/packages/pando-lib/src/test/fixtures/ed19ea7ea03ecd036c653b9c4cba16df71424a60 @@ -0,0 +1 @@ +xmj@Ex2Nf$cP_ghvۻ:\8] J/T_a*ѱ>KWǑ5kxנ5J-qChh:h'8']F5'n="LLhXI% !0;NsGx}.C~$>.u3ntd˄"]9'HK{ eM \ No newline at end of file diff --git a/packages/pando-lib/src/test/fixtures/ee048050d16bc428c4faef1074b740866ad553bb b/packages/pando-lib/src/test/fixtures/ee048050d16bc428c4faef1074b740866ad553bb new file mode 100644 index 00000000..041fe5fa --- /dev/null +++ b/packages/pando-lib/src/test/fixtures/ee048050d16bc428c4faef1074b740866ad553bb @@ -0,0 +1 @@ +xj0EW}i1QtdD f:E-jD#vwup8Re #/D)Ie1S H6^kI\eHN;., /<#LR_ܮ} ?)>P7˩4!sWʙ>q[X@C\\5įjD5Qp}e8 \ No newline at end of file diff --git a/packages/pando-lib/src/test/fixtures/f5227cbd32973ec90f48f2547e6fe16c80b92bd5 b/packages/pando-lib/src/test/fixtures/f5227cbd32973ec90f48f2547e6fe16c80b92bd5 new file mode 100644 index 00000000..e33b610f Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/f5227cbd32973ec90f48f2547e6fe16c80b92bd5 differ diff --git a/packages/pando-lib/src/test/fixtures/fa59b93c6ce9db82ce57de9046eb738e9f3c0952 b/packages/pando-lib/src/test/fixtures/fa59b93c6ce9db82ce57de9046eb738e9f3c0952 new file mode 100644 index 00000000..1cbecd68 Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/fa59b93c6ce9db82ce57de9046eb738e9f3c0952 differ diff --git a/packages/pando-lib/src/test/fixtures/fc80daf21bb484cfd42ad4ed4d17da48638199ea b/packages/pando-lib/src/test/fixtures/fc80daf21bb484cfd42ad4ed4d17da48638199ea new file mode 100644 index 00000000..d94fbe09 Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/fc80daf21bb484cfd42ad4ed4d17da48638199ea differ diff --git a/packages/pando-lib/src/test/fixtures/ffef5350b6f8762cc6272b0255e968f50b6577ed b/packages/pando-lib/src/test/fixtures/ffef5350b6f8762cc6272b0255e968f50b6577ed new file mode 100644 index 00000000..de1e6d24 Binary files /dev/null and b/packages/pando-lib/src/test/fixtures/ffef5350b6f8762cc6272b0255e968f50b6577ed differ diff --git a/packages/pando-lib/src/test/fixtures/objects.json b/packages/pando-lib/src/test/fixtures/objects.json new file mode 100644 index 00000000..d5cdb60c --- /dev/null +++ b/packages/pando-lib/src/test/fixtures/objects.json @@ -0,0 +1,26 @@ +[ + "b1c46e7c32ff56e56a3da52be375348a664650ba", + "ee048050d16bc428c4faef1074b740866ad553bb", + "d52e70c9e34ac03cdf77f46aec388c2f9574bd93", + "70a3540bd51658ab564806785d5516a4e89b6450", + "0faccf822badf55f15fb0c3f4122fa13798f769e", + "933b7583b7767b07ea4cf242c1be29162eb8bb85", + "4d5e7ac145aaf440600dd06a97e8cc65f8acd4dc", + "ed19ea7ea03ecd036c653b9c4cba16df71424a60", + "cf461f783732a8aa5f7d8679e112bd4c876aa19b", + "88a72947d8b4f0ab7185389efcdd5dace4643e04", + "ffef5350b6f8762cc6272b0255e968f50b6577ed", + "7ffd1401f599c70364eda431d29363e037b2c92c", + "a0f06ca3cdb1e6e7f603794ef1cd9f9867f85551", + "4b271beec86978454072b632f382c6ccb3938a45", + "f5227cbd32973ec90f48f2547e6fe16c80b92bd5", + "5af4dc18899e8ac95904eaf2b4abf1a2ca5e1507", + "832b4a8497de78248f70c06e0f06e785a74fea4c", + "0a1690e0640a212aafed1824eb208ffddab1789b", + "fc80daf21bb484cfd42ad4ed4d17da48638199ea", + "9f358a4addefcab294b83e4282bfef1f9625a249", + "19f0805d8de36b6442e8c573074112ba72ad6780", + "42fd8d7404f5127314e248b2cbbe1423f12faeb9", + "fa59b93c6ce9db82ce57de9046eb738e9f3c0952", + "802992c4220de19a90767f3000a79a31b98d0df7" +] diff --git a/packages/pando-lib/src/test/fixtures/update.sh b/packages/pando-lib/src/test/fixtures/update.sh new file mode 100755 index 00000000..a706f26b --- /dev/null +++ b/packages/pando-lib/src/test/fixtures/update.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +ls . | awk -F '' 'NF == 40' | xargs rm +rm testdata.tar.gz -f +wget https://github.com/ipfs/go-ipld-git/raw/master/testdata.tar.gz +tar xzf testdata.tar.gz +rm testdata.tar.gz +mv .git git + +find git/objects -type f | cut -d'/' -f3- | sed 's/\///g' | jq --raw-input . | jq --slurp . > objects.json +paste <(find git/objects -type f) <(find git/objects -type f | cut -d'/' -f3- | sed 's/\///g') | xargs -L 1 mv -v +rm -rf git diff --git a/packages/pando-lib/src/test/scripts.spec.ts b/packages/pando-lib/src/test/scripts.spec.ts new file mode 100644 index 00000000..1d59dc21 --- /dev/null +++ b/packages/pando-lib/src/test/scripts.spec.ts @@ -0,0 +1,130 @@ +import Commit, * as lib from '../scripts' +import IPLD from 'ipld' +import IPFS from 'ipfs-http-client' +import IPLDGit from 'ipld-git' +import { cidToSha } from 'ipld-git/src/util/util.js' +import CID from 'cids' +import chai from 'chai' +import dirtyChai from 'dirty-chai' +import multicodec from 'multicodec' + +const expect = chai.expect +chai.use(dirtyChai) +const ipfs = IPFS({ host: 'ipfs.infura.io', port: '5001', protocol: 'https' }) +const ipld = new IPLD({ blockService: ipfs.block, formats: [IPLDGit] }) + +describe('pando library', () => { + let commit, commit2 + let commitBlob + let commit2Blob + let treeBlob + + let commitCid + let commit2Cid + let treeCid + let blobCid + + let commitNode + let commit2Node + let treeNode + let blobNode + + before( async () => { + blobNode = Buffer.from('626c6f62203800736f6d6564617461', 'hex') // blob 8\0somedata + blobCid = await IPLDGit.util.cid(blobNode) + + treeNode = { + somefile: { + hash: blobCid, + mode: '100644' + } + } + + treeBlob = IPLDGit.util.serialize(treeNode) + treeCid = await IPLDGit.util.cid(treeBlob) + + commitNode = { + gitType: 'commit', + tree: treeCid, + parents: [], + author: { + name: 'John Doe', + email: 'johndoe@example.com', + date: '2017-06-12T23:22:12+02:00' + }, + committer: { + name: 'John Doe', + email: 'johndoe@example.com', + date: '2017-06-12T23:22:12+02:00' + }, + message: 'Encoded\n' + } + + commitBlob = IPLDGit.util.serialize(commitNode) + commitCid = await IPLDGit.util.cid(commitBlob) + + commit2Node = { + gitType: 'commit', + tree: treeCid, + parents: [ + commitCid + ], + author: { + name: 'John Doe', + email: 'johndoe@example.com', + date: '1497302533 +0200' + }, + committer: { + name: 'John Doe', + email: 'johndoe@example.com', + date: '1497302533 +0200' + }, + message: 'Change nothing\n' + } + + commit2Blob = IPLDGit.util.serialize(commit2Node) + commit2Cid = await IPLDGit.util.cid(commit2Blob) + + const nodes = [blobNode, treeNode, commitNode, commit2Node] + const result = await ipld.putMany(nodes, multicodec.GIT_RAW) + ;[blobCid, treeCid, commitCid, commit2Cid] = await result.all() + commit = await lib.fetchCommit(commitCid) + commit2 = await lib.fetchCommit(commit2Cid) + }) + + describe('instantiate Commit class', async () => { + it('it has the correct cid and attributes', () => { + expect(commit.cid).to.eql(commitCid) + expect(commit.sha).to.eql(cidToSha(commitCid)) + expect(commit.author).to.eql(commitNode.author) + expect(commit.committer).to.eql(commitNode.committer) + expect(commit.message).to.eql(commitNode.message) + expect(commit.parents).to.eql(commitNode.parents) + expect(commit.tree).to.eql(commitNode.tree) + }) + + it('reorders parent commits to a descending date historical array', async (done) => { + const history = await commit2.getOrderedHistory() + expect(history[0].cid).to.be.eql(commit2Cid) + expect(history[1].cid).to.be.eql(commitCid) + done() + }) + + it('contains the tree with historical data about commiter and date modified', async (done) => { + await commit.fetchModifiedTree() + expect(commit.tree as lib.IModifiedTree).to.not.be.undefined + expect(commit.tree as lib.IModifiedTree).to.not.be.empty + + for (const path in commit.tree) { + expect(commit.tree[path].hasOwnProperty('lastEdit')).to.be.true + expect(commit.tree[path].lastEdit.date).to.be.eql(commit.committer.date) + expect(commit.tree[path].lastEdit.message).to.be.eql(commit.message) + } + done() + }) + it('Can retrieve IPLD object from Commit', async () => { + const ipldCommitObj = await lib.retrieveIPLDCommitObject(commit.cid) + expect(ipldCommitObj).to.be.deep.equal(commitNode) + }) + }) +}) diff --git a/packages/pando-lib/tsconfig.json b/packages/pando-lib/tsconfig.json new file mode 100644 index 00000000..3d469aea --- /dev/null +++ b/packages/pando-lib/tsconfig.json @@ -0,0 +1,10 @@ +{ + "exclude": ["node_modules", "**/*.spec.ts"], + "compilerOptions": { + "esModuleInterop": true, + "module": "CommonJS", + "outDir": "./build", + "target": "ES2017", + "typeRoots": ["node_modules/@types"] + } +} diff --git a/packages/pando-lib/tslint.json b/packages/pando-lib/tslint.json new file mode 100644 index 00000000..a5abedd7 --- /dev/null +++ b/packages/pando-lib/tslint.json @@ -0,0 +1,4 @@ +{ + "extends": ["tslint:latest", "tslint-config-prettier"], + "rules": { "curly": [true, "ignore-same-line"], "interface-name": false, "variable-name": false } +} diff --git a/packages/pando-repository/app/src/script.js b/packages/pando-repository/app/src/script.js index 4a75b9cf..d604e563 100644 --- a/packages/pando-repository/app/src/script.js +++ b/packages/pando-repository/app/src/script.js @@ -37,22 +37,7 @@ app.store(async (state, event) => { switch (event.event) { case 'UpdateRef': try { - let history = await fetchHistory(event.returnValues.hash, []) - history = uniqWith(history, (one, two) => { - return one.cid === two.cid - }) - history = orderBy( - history, - [ - commit => { - // https://github.com/git/git/blob/v2.3.0/Documentation/date-formats.txt - /* eslint-disable-next-line no-unused-vars */ - const [timestamp, offset] = commit.author.date.split(' ') - return timestamp - }, - ], - ['desc'] - ) + let history = await fetchOrderedHistory(event.returnValues.hash, []) state.branches[branchFromRef(event.returnValues.ref)] = history } catch (err) { console.error('Failed to load commit history due to:', err) @@ -123,6 +108,7 @@ const fetchCommit = async hash => { commit.cid = cid.toBaseEncodedString() commit.sha = cidToSha(hash).toString('hex') commit.files = await fetchFilesFromTree(commit.tree['/']) + console.log(commit) resolve(commit) } }) @@ -156,3 +142,25 @@ const fetchFilesFromTree = (hash, path) => { }) }) } + +const fetchOrderedHistory = async (hash, formerHistory) => { + let history = await fetchHistory(hash, formerHistory) + history = uniqWith(history, (one, two) => { + return one.cid === two.cid + }) + + history = orderBy( + history, + [ + commit => { + // https://github.com/git/git/blob/v2.3.0/Documentation/date-formats.txt + /* eslint-disable-next-line no-unused-vars */ + const [timestamp, offset] = commit.author.date.split(' ') + return timestamp + }, + ], + ['desc'] + ) + + return history +} diff --git a/packages/pando-repository/package.json b/packages/pando-repository/package.json index 98bee398..90f19fce 100644 --- a/packages/pando-repository/package.json +++ b/packages/pando-repository/package.json @@ -1,6 +1,6 @@ { "name": "@pando/repository", - "version": "0.3.0-alpha.5", + "version": "0.3.0", "author": "Pando Network ", "contributors": [ "Olivier Sarrouy ", @@ -14,7 +14,7 @@ "lint:contracts": "solium --dir ./contracts", "lint:tests": "eslint ./test", "lint:app": "cd app && npm run lint", - "lint": "npm run lint:contracts && npm run lint:tests && npm run lint:app", + "lint": "npm run lint:contracts && npm run lint:tests && npm run lint:app && tslint -c tslint.json 'app/src/**/*.ts'", "compile": "aragon contracts compile", "test": "aragon contracts test --network devchain", "start": "cd app && npm run start", @@ -26,11 +26,13 @@ "publish:major:rinkeby": "aragon apm publish major --use-frame --files ./app/build --environment rinkeby" }, "dependencies": { - "@aragon/os": "^4.0.1" + "@aragon/os": "^4.0.1", + "ipld-git": "^0.3.0" }, "devDependencies": { "@aragon/cli": "^5.5.0", "@aragon/test-helpers": "^1.1.0", + "@types/node": "^10.12.21", "eslint": "5.5.0", "eslint-config-prettier": "^3.0.1", "eslint-config-standard": "^12.0.0", @@ -41,7 +43,10 @@ "eslint-plugin-standard": "^4.0.0", "ethlint": "^1.2.3", "prettier": "^1.8.2", - "truffle": "^5.0.0" + "truffle": "^5.0.0", + "tslint": "^5.14.0", + "tslint-config-prettier": "^1.18.0", + "typescript": "^3.4.3" }, - "gitHead": "cb2b7c6fe7805fdbbcd29733c3ebb24eeb5d3d42" + "gitHead": "a449d46d5eb6a86efae8f0fdcf1e1749e432d928" } diff --git a/packages/pando-repository/tsconfig.json b/packages/pando-repository/tsconfig.json new file mode 100644 index 00000000..e0372c0d --- /dev/null +++ b/packages/pando-repository/tsconfig.json @@ -0,0 +1,10 @@ +{ + "exclude": ["node_modules", "**/*.spec.ts"], + "compilerOptions": { + "esModuleInterop": true, + "module": "CommonJS", + "outDir": "./build", + "target": "ES2017", + "allowJs": true + } +} diff --git a/packages/pando-repository/tslint.json b/packages/pando-repository/tslint.json new file mode 100644 index 00000000..a5abedd7 --- /dev/null +++ b/packages/pando-repository/tslint.json @@ -0,0 +1,4 @@ +{ + "extends": ["tslint:latest", "tslint-config-prettier"], + "rules": { "curly": [true, "ignore-same-line"], "interface-name": false, "variable-name": false } +}