From 2e935a524961d2883244513cb8a6cdbd13ff5faf Mon Sep 17 00:00:00 2001 From: HaidarJbeily7 Date: Sat, 23 Nov 2024 23:51:14 +0300 Subject: [PATCH 1/5] feat: implement dir walkjs --- .../src/objects/org/eolang/fs/dir$walk.js | 16 ++++---- .../objects/org/eolang/fs/dir$walk.test.js | 39 +++++++++++++++++++ 2 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 eo2js-runtime/test/objects/org/eolang/fs/dir$walk.test.js 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 e9a262b..bad7b3a 100644 --- a/eo2js-runtime/src/objects/org/eolang/fs/dir$walk.js +++ b/eo2js-runtime/src/objects/org/eolang/fs/dir$walk.js @@ -1,22 +1,22 @@ const object = require('../../../../runtime/object') const {LAMBDA} = require('../../../../runtime/attribute/specials'); const at_void = require('../../../../runtime/attribute/at-void'); -const ErFailure = require('../../../../runtime/error/ErFailure'); +const at_string = require('../../../../runtime/attribute/at-string'); +const fs = require('fs'); +const path = require('path'); +const glob = require('glob'); /** - * Dir.walk. + * Dir.walk recursively walks a directory and returns files matching a glob pattern. * @return {Object} - Dir.walk object - * @todo #3:30min Implement dir$walk atom. We need to implement the atom and make sure it - * works. For the details of implementation check the Java analogue on - * https://github.com/objectionary/eo/tree/master/eo-runtime/src/main/java/EOorg/EOeolang */ const dir$walk = function() { const obj = object('dir$walk') obj.attrs['glob'] = at_void('glob') obj.assets[LAMBDA] = function(_) { - throw new ErFailure( - `Atom dir$walk is not implemented yet` - ) + const pattern = obj.attrs['glob'].data; + const files = glob.sync(pattern); + return at_string(files.join('\n')); } 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 new file mode 100644 index 0000000..cc139e6 --- /dev/null +++ b/eo2js-runtime/test/objects/org/eolang/fs/dir$walk.test.js @@ -0,0 +1,39 @@ +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 at_string = require('../../../../../temp/runtime/attribute/at-string'); +const fs = require('fs'); +const path = require('path'); + +describe('dir$walk', function() { + const testDir = path.resolve(__dirname, '../../../../../temp/test-dir'); + + beforeEach(function() { + if (fs.existsSync(testDir)) { + fs.rmSync(testDir, {recursive: true}); + } + fs.mkdirSync(testDir, {recursive: true}); + fs.writeFileSync(path.join(testDir, 'file1.txt'), ''); + fs.writeFileSync(path.join(testDir, 'file2.js'), ''); + fs.mkdirSync(path.join(testDir, 'subdir')); + fs.writeFileSync(path.join(testDir, 'subdir/file3.txt'), ''); + }); + + afterEach(function() { + fs.rmSync(testDir, {recursive: true}); + }); + + it('should find files matching glob pattern', function() { + const walk = dir$walk(); + walk.attrs['glob'] = at_string(path.join(testDir, '**/*.txt')); + const result = dataized(walk, STRING).split('\n').sort(); + assert.deepEqual( + result, + [ + path.join(testDir, 'file1.txt'), + path.join(testDir, 'subdir/file3.txt') + ].sort() + ); + }); +}); From 0eda4ef5f7257d7257c0c53caa53e2565b23ca12 Mon Sep 17 00:00:00 2001 From: HaidarJbeily7 Date: Sun, 24 Nov 2024 00:22:58 +0300 Subject: [PATCH 2/5] feat: implement dir walkjs --- .../objects/org/eolang/fs/dir$walk.test.js | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) 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 cc139e6..76585e8 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 @@ -2,37 +2,37 @@ 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 at_string = require('../../../../../temp/runtime/attribute/at-string'); +const at_string = require('../../../../runtime/attribute/at-string'); const fs = require('fs'); const path = require('path'); describe('dir$walk', function() { - const testDir = path.resolve(__dirname, '../../../../../temp/test-dir'); + const directory = path.resolve(__dirname, '../../../../../temp/test-dir'); beforeEach(function() { - if (fs.existsSync(testDir)) { - fs.rmSync(testDir, {recursive: true}); + if (fs.existsSync(directory)) { + fs.rmSync(directory, {recursive: true}); } - fs.mkdirSync(testDir, {recursive: true}); - fs.writeFileSync(path.join(testDir, 'file1.txt'), ''); - fs.writeFileSync(path.join(testDir, 'file2.js'), ''); - fs.mkdirSync(path.join(testDir, 'subdir')); - fs.writeFileSync(path.join(testDir, 'subdir/file3.txt'), ''); + fs.mkdirSync(directory, {recursive: true}); + fs.writeFileSync(path.join(directory, 'file1.txt'), ''); + fs.writeFileSync(path.join(directory, 'file2.js'), ''); + fs.mkdirSync(path.join(directory, 'subdir')); + fs.writeFileSync(path.join(directory, 'subdir/file3.txt'), ''); }); afterEach(function() { - fs.rmSync(testDir, {recursive: true}); + fs.rmSync(directory, {recursive: true}); }); it('should find files matching glob pattern', function() { const walk = dir$walk(); - walk.attrs['glob'] = at_string(path.join(testDir, '**/*.txt')); + walk.attrs['glob'] = at_string(path.join(directory, '**/*.txt')); const result = dataized(walk, STRING).split('\n').sort(); assert.deepEqual( result, [ - path.join(testDir, 'file1.txt'), - path.join(testDir, 'subdir/file3.txt') + path.join(directory, 'file1.txt'), + path.join(directory, 'subdir/file3.txt') ].sort() ); }); From 7dcdbcb5f259d05b9bd88f477efc2438cfd9ae54 Mon Sep 17 00:00:00 2001 From: HaidarJbeily7 Date: Sun, 24 Nov 2024 00:35:03 +0300 Subject: [PATCH 3/5] feat: implement dir walkjs --- eo2js-runtime/src/objects/org/eolang/fs/dir$walk.js | 6 ++---- eo2js-runtime/test/objects/org/eolang/fs/dir$walk.test.js | 4 ++-- 2 files changed, 4 insertions(+), 6 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 bad7b3a..2ab1ae1 100644 --- a/eo2js-runtime/src/objects/org/eolang/fs/dir$walk.js +++ b/eo2js-runtime/src/objects/org/eolang/fs/dir$walk.js @@ -1,9 +1,7 @@ const object = require('../../../../runtime/object') const {LAMBDA} = require('../../../../runtime/attribute/specials'); const at_void = require('../../../../runtime/attribute/at-void'); -const at_string = require('../../../../runtime/attribute/at-string'); -const fs = require('fs'); -const path = require('path'); +const data = require('../../../../runtime/data'); const glob = require('glob'); /** @@ -16,7 +14,7 @@ const dir$walk = function() { obj.assets[LAMBDA] = function(_) { const pattern = obj.attrs['glob'].data; const files = glob.sync(pattern); - return at_string(files.join('\n')); + return data.toObject(files.join('\n')); } 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 76585e8..bc75d0b 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 @@ -2,7 +2,7 @@ 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 at_string = require('../../../../runtime/attribute/at-string'); +const data = require('../../../../../temp/runtime/data'); const fs = require('fs'); const path = require('path'); @@ -26,7 +26,7 @@ describe('dir$walk', function() { it('should find files matching glob pattern', function() { const walk = dir$walk(); - walk.attrs['glob'] = at_string(path.join(directory, '**/*.txt')); + walk.attrs['glob'] = data.toObject(path.join(directory, '**/*.txt')); const result = dataized(walk, STRING).split('\n').sort(); assert.deepEqual( result, From fe442b397f6c6ce96606b88b767d6ef2991624f6 Mon Sep 17 00:00:00 2001 From: HaidarJbeily7 Date: Sun, 24 Nov 2024 00:48:31 +0300 Subject: [PATCH 4/5] feat: implement dir walkjs --- eo2js-runtime/test/objects/org/eolang/fs/dir$walk.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 bc75d0b..7caa75c 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 @@ -26,13 +26,13 @@ describe('dir$walk', function() { it('should find files matching glob pattern', function() { const walk = dir$walk(); - walk.attrs['glob'] = data.toObject(path.join(directory, '**/*.txt')); + walk.attrs['glob'] = data.toObject('**/*.txt'); const result = dataized(walk, STRING).split('\n').sort(); assert.deepEqual( result, [ - path.join(directory, 'file1.txt'), - path.join(directory, 'subdir/file3.txt') + 'file1.txt', + 'subdir/file3.txt' ].sort() ); }); From eef3c25922b530331787e5fc918ced1b12b152f8 Mon Sep 17 00:00:00 2001 From: HaidarJbeily7 Date: Sun, 24 Nov 2024 11:12:10 +0300 Subject: [PATCH 5/5] 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'