Last active
March 31, 2019 10:39
-
-
Save varjmes/fcf88d69cffcaa5b8d4ed0cb877cb18f to your computer and use it in GitHub Desktop.
Creating the tree!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Blob { | |
constructor(data) { | |
this.data = data | |
} | |
type() { | |
return 'blob' | |
} | |
toString() { | |
return this.data | |
} | |
} | |
module.exports = Blob |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const crypto = require('crypto') | |
const fs = require('fs') | |
const path = require('path') | |
const zlib = require('zlib') | |
class Database { | |
constructor(pathname) { | |
this.pathname = pathname | |
this.tempChars = [ | |
...Array.from({ length: 26 }, (_, i) => | |
String.fromCharCode('A'.charCodeAt(0) + i) | |
), | |
...Array.from({ length: 26 }, (_, i) => | |
String.fromCharCode('a'.charCodeAt(0) + i) | |
), | |
...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
] | |
} | |
hashIt(string) { | |
return crypto | |
.createHash('sha1') | |
.update(string, 'utf-8') | |
.digest('hex') | |
} | |
writeObject(oid, content) { | |
const dirPath = path.join(this.pathname, oid.slice(0, 2)) | |
const objectPath = path.join(dirPath, oid.slice(2, oid.length)) | |
const tempPath = path.join(this.pathname, this.generateTempName()) | |
const compressed = zlib.deflateSync(content) | |
fs.writeFileSync(tempPath, compressed, { flag: 'wx+' }) | |
if (!fs.existsSync(dirPath)) { | |
fs.mkdirSync(dirPath) | |
} | |
fs.renameSync(tempPath, objectPath) | |
} | |
generateTempName() { | |
const randomString = Array.from( | |
{ length: 6 }, | |
(_, i) => | |
this.tempChars[Math.floor(Math.random() * this.tempChars.length)] | |
).join('') | |
return `tmp_obj_${randomString}` | |
} | |
store(object) { | |
const string = object.toString() | |
const type = Buffer.from(object.type()) | |
const typeByte = Buffer.from(`${type} ${string.byteLength.toString()}\x00`) | |
const content = Buffer.concat([typeByte, string]) | |
object.oid = this.hashIt(content) | |
this.writeObject(object.oid, content) | |
} | |
} | |
module.exports = Database |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Entry { | |
constructor(name, oid) { | |
this.name = name | |
this.oid = oid | |
} | |
} | |
module.exports = Entry |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Tree { | |
constructor(entries) { | |
this.entryFormat = 'A7Z*H40' | |
this.mode = '100644' | |
this.entries = entries | |
} | |
type() { | |
return 'tree' | |
} | |
toString() { | |
const entries = this.entries.sort((a, b) => { | |
return -(a.name < b.name) || +(a.name > b.name) | |
}) | |
const packed = entries.map(entry => { | |
let mode = Buffer.from(this.mode.replace(/^0/, '')) | |
let space = Buffer.from(' ') | |
let name = Buffer.from(entry.name, 'utf8') | |
let nullChar = Buffer.from([0]) | |
let oid = Buffer.from(entry.oid.match(/../g).map(n => parseInt(n, 16))) | |
return Buffer.concat([mode, space, name, nullChar, oid]) | |
}) | |
return Buffer.concat(packed) | |
} | |
} | |
module.exports = Tree |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs') | |
const path = require('path') | |
const Blob = require('./blob') | |
const Database = require('./database') | |
const Entry = require('./entry') | |
const Tree = require('./tree') | |
const Workspace = require('./workspace') | |
const directories = ['objects', 'refs'] | |
const command = process.argv[2] | |
switch (command) { | |
case 'init': { | |
const repoPath = process.argv[3] || '' | |
const gitPath = path.resolve(repoPath, '.git') | |
directories.map(dir => { | |
const dirPath = path.join(gitPath, dir) | |
fs.mkdirSync(dirPath, { recursive: true }) | |
}) | |
console.info(`Initialised empty vrs repository in ${gitPath}`) | |
process.exit(0) | |
} | |
case 'commit': { | |
const gitPath = path.resolve('.git') | |
const dbPath = path.join(gitPath, 'objects') | |
const workspace = new Workspace(process.cwd()) | |
const database = new Database(dbPath) | |
const entries = [] | |
workspace.listFiles().forEach(filePath => { | |
const data = workspace.readFile(filePath) | |
const blob = new Blob(data) | |
database.store(blob) | |
entries.push(new Entry(filePath, blob.oid)) | |
}) | |
const tree = new Tree(entries) | |
database.store(tree) | |
console.info(`tree: ${tree.oid}`) | |
process.exit(0) | |
} | |
default: | |
console.error(`vrs: '${command}' is not a valid vrs command`) | |
process.exit(1) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs') | |
const path = require('path') | |
class Workspace { | |
constructor(pathname) { | |
this.ignore = ['.', '..', '.git'] | |
this.pathname = pathname | |
} | |
listFiles() { | |
return fs | |
.readdirSync(this.pathname) | |
.filter(item => !this.ignore.includes(item)) | |
} | |
readFile(filePath) { | |
return fs.readFileSync(path.join(this.pathname, filePath)) | |
} | |
} | |
module.exports = Workspace |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Good to know, I'm now using that, thanks!
I think my problem is encoding on the tree file.
blob file
tree file