From eef3c25922b530331787e5fc918ced1b12b152f8 Mon Sep 17 00:00:00 2001 From: HaidarJbeily7 Date: Sun, 24 Nov 2024 11:12:10 +0300 Subject: [PATCH] feat: implement dir walkjs --- .../src/objects/org/eolang/fs/dir$walk.js | 42 ++++++++++++++++--- .../objects/org/eolang/fs/dir$walk.test.js | 23 ++++++---- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/eo2js-runtime/src/objects/org/eolang/fs/dir$walk.js b/eo2js-runtime/src/objects/org/eolang/fs/dir$walk.js index 2ab1ae1..15f4a23 100644 --- a/eo2js-runtime/src/objects/org/eolang/fs/dir$walk.js +++ b/eo2js-runtime/src/objects/org/eolang/fs/dir$walk.js @@ -1,8 +1,10 @@ const object = require('../../../../runtime/object') -const {LAMBDA} = require('../../../../runtime/attribute/specials'); +const {LAMBDA, RHO} = require('../../../../runtime/attribute/specials'); const at_void = require('../../../../runtime/attribute/at-void'); const data = require('../../../../runtime/data'); -const glob = require('glob'); +const dataized = require('../../../../runtime/dataized'); +const fs = require('fs'); +const path = require('path'); /** * Dir.walk recursively walks a directory and returns files matching a glob pattern. @@ -11,10 +13,38 @@ const glob = require('glob'); const dir$walk = function() { const obj = object('dir$walk') obj.attrs['glob'] = at_void('glob') - obj.assets[LAMBDA] = function(_) { - const pattern = obj.attrs['glob'].data; - const files = glob.sync(pattern); - return data.toObject(files.join('\n')); + obj.assets[LAMBDA] = function(self) { + const dirPath = dataized(self.take(RHO).take('file').take('path')).toString(); + const pattern = dataized(self.take('glob')).toString(); + const absPath = path.resolve(dirPath); + const phi = require('../../../../runtime/phi'); + const eolang = phi.take('org.eolang'); + const fs_file = eolang.take('fs.file'); + + const walkSync = function(dir, pattern) { + let results = []; + const list = fs.readdirSync(dir); + list.forEach(function(file) { + const filePath = path.join(dir, file); + const stat = fs.statSync(filePath); + if (stat && stat.isDirectory()) { + results = results.concat(walkSync(filePath, pattern)); + } else { + const relativePath = path.relative(absPath, filePath); + if (require('minimatch')(relativePath, pattern)) { + results.push(fs_file.copy().with({0: data.toObject(relativePath)})); + } + } + }); + return results; + } + + try { + const files = walkSync(absPath, pattern); + return data.toTuple(files); + } catch (err) { + throw new Error(`Can't walk at ${absPath}: ${err.message}`); + } } return obj } diff --git a/eo2js-runtime/test/objects/org/eolang/fs/dir$walk.test.js b/eo2js-runtime/test/objects/org/eolang/fs/dir$walk.test.js index 7caa75c..80181f8 100644 --- a/eo2js-runtime/test/objects/org/eolang/fs/dir$walk.test.js +++ b/eo2js-runtime/test/objects/org/eolang/fs/dir$walk.test.js @@ -1,13 +1,15 @@ const assert = require('assert'); -const dir$walk = require('../../../../../temp/objects/org/eolang/fs/dir$walk'); -const {STRING} = require('../../../../../temp/runtime/types'); -const dataized = require('../../../../../temp/runtime/dataized'); -const data = require('../../../../../temp/runtime/data'); +const dir$walk = require('../../../../../src/objects/org/eolang/fs/dir$walk'); +const {STRING} = require('../../../../../src/runtime/types'); +const dataized = require('../../../../../src/runtime/dataized'); +const data = require('../../../../../src/runtime/data'); const fs = require('fs'); const path = require('path'); +const object = require('../../../../../src/runtime/object'); +const {RHO} = require('../../../../../src/runtime/attribute/specials'); describe('dir$walk', function() { - const directory = path.resolve(__dirname, '../../../../../temp/test-dir'); + const directory = path.resolve(__dirname, '../test-dir'); beforeEach(function() { if (fs.existsSync(directory)) { @@ -25,11 +27,16 @@ describe('dir$walk', function() { }); it('should find files matching glob pattern', function() { + const dir = object('dir'); + dir.attrs['file'] = object('file'); + dir.attrs['file'].attrs['path'] = data.toObject(directory); const walk = dir$walk(); - walk.attrs['glob'] = data.toObject('**/*.txt'); - const result = dataized(walk, STRING).split('\n').sort(); + walk.attrs[RHO] = dir; + walk.attrs['glob'] = data.toObject('**/*.txt'); + const files = dataized(walk); + const paths = files.map(file => dataized(file.take('path'), STRING)); assert.deepEqual( - result, + paths.sort(), [ 'file1.txt', 'subdir/file3.txt'