Skip to content

Commit

Permalink
feat: add hasFolder()
Browse files Browse the repository at this point in the history
  • Loading branch information
coderbyheart committed Apr 11, 2024
1 parent e40abec commit 875c3d1
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test-and-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
run: npx eslint .
- name: Check if source code is properly formatted
run: npx prettier -c ./
- run: npm test
- name: Semantic release
continue-on-error: true
run: npx semantic-release
3 changes: 2 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
npx lint-staged
npx lint-staged
npm test
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"type": "module",
"scripts": {
"prepare": "husky",
"prepublishOnly": "npx tsc --noEmit false --outDir ./dist -d"
"prepublishOnly": "npx tsc --noEmit false --outDir ./dist -d",
"test": "npx tsx --test src/*.spec.ts"
},
"repository": {
"type": "git",
Expand Down
15 changes: 15 additions & 0 deletions src/hashFolder.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { describe, it } from 'node:test'
import assert from 'node:assert/strict'
import path from 'node:path'
import { hashFolder } from './hashFolder.js'
import { fileURLToPath } from 'node:url'
const __dirname = fileURLToPath(new URL('.', import.meta.url))

void describe('hashFolder', () => {
void it('should calculate correct MD5 hash value for folder with files', async () => {
const folderPath = path.join(__dirname, 'test-folder')
const expectedMd5 = '2446ef9dbaecdce8dbf59fdfb68b0f81'
const actualMd5 = await hashFolder(folderPath)
assert.equal(actualMd5, expectedMd5)
})
})
57 changes: 57 additions & 0 deletions src/hashFolder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { createHash } from 'node:crypto'
import { createReadStream, readdirSync, statSync } from 'node:fs'
import { join } from 'node:path'

const hashFile = async (file: string): Promise<string> => {
const hash = createHash('md5')
const content = createReadStream(file)

return new Promise((resolve, reject) => {
content.pipe(hash)
content
.on('close', () => {
return resolve(hash.digest('hex'))
})
.on('error', (error) => {
return reject(error)
})
})
}

const generateMd5ForFolder = async (
path: string,
): Promise<Record<string, string>> => {
const files = readdirSync(path)
const md5Hashes: Record<string, string> = {}

for (const file of files) {
const filePath = join(path, file)
const fileStats = statSync(filePath)

if (fileStats.isFile()) {
md5Hashes[filePath] = await hashFile(filePath)
} else if (fileStats.isDirectory()) {
const filesInNestedFolder = await generateMd5ForFolder(filePath)
for (const file in filesInNestedFolder) {
md5Hashes[file] = filesInNestedFolder[file] ?? ''
}
}
}

return md5Hashes
}

export const hashFolder = async (path: string): Promise<string> => {
const filesHash = await generateMd5ForFolder(path)

const hashMD5 = createHash('md5')
Object.entries(filesHash)
.sort((a, b) =>
a[0].toLocaleLowerCase().localeCompare(b[0].toLocaleLowerCase()),
)
.forEach(([file, hash]) => {
hashMD5.update(`${hash} ${file.replace(path, '')}`)
})

return hashMD5.digest('hex')
}
1 change: 1 addition & 0 deletions src/test-folder/nest-folder/another.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Eget aliquet nibh praesent tristique. Nullam eget felis eget nunc lobortis mattis aliquam faucibus purus. Ut tellus elementum sagittis vitae. Adipiscing enim eu turpis egestas pretium aenean pharetra magna ac. Commodo sed egestas egestas fringilla phasellus faucibus scelerisque eleifend donec. Aliquam sem fringilla ut morbi. Urna id volutpat lacus laoreet. Integer eget aliquet nibh praesent tristique magna sit amet. Mi tempus imperdiet nulla malesuada pellentesque elit eget gravida. Lacinia quis vel eros donec ac odio. Eget gravida cum sociis natoque penatibus et magnis dis parturient. Mauris rhoncus aenean vel elit. Sollicitudin tempor id eu nisl. Risus pretium quam vulputate dignissim suspendisse. Vitae semper quis lectus nulla at. Purus ut faucibus pulvinar elementum integer. Placerat orci nulla pellentesque dignissim enim sit amet. Lectus quam id leo in vitae turpis.
1 change: 1 addition & 0 deletions src/test-folder/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla scelerisque interdum elit ac ultricies. Proin vitae enim dictum, convallis odio quis, pellentesque turpis. Curabitur blandit magna vel dui consectetur bibendum. Fusce viverra tristique quam at mattis. Suspendisse vehicula libero vitae tincidunt convallis. Nam malesuada lacinia semper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed sit amet volutpat nunc. Donec malesuada dolor ut turpis viverra volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed elementum malesuada odio, vel vehicula nisi faucibus a. Sed bibendum justo ut lectus malesuada efficitur. Vivamus vitae pharetra justo.

0 comments on commit 875c3d1

Please sign in to comment.