refactor and improve both functions

uses promise.all now
This commit is contained in:
David Kebler 2024-12-14 18:45:07 -08:00
parent a05927ef7e
commit d522ac6883
7 changed files with 99 additions and 46 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/node_modules/
/coverage/
test/combined2.list

37
api.md Normal file
View file

@ -0,0 +1,37 @@
## Functions
<dl>
<dt><a href="#readLines">readLines(files, dir)</a><code>Promise.&lt;array&gt;</code></dt>
<dd><p>read lines from one or more files and return an array of those all those lines</p>
</dd>
<dt><a href="#writeLines">writeLines(filePath, list)</a><code>Promise.&lt;null&gt;</code></dt>
<dd><p>Writes files with a line for each element in a array or item in comma delimited list</p>
</dd>
</dl>
<a name="readLines"></a>
## readLines(files, dir) ⇒ <code>Promise.&lt;array&gt;</code>
read lines from one or more files and return an array of those all those lines
**Kind**: global function
**Returns**: <code>Promise.&lt;array&gt;</code> - - resolves to an single array of all lines from all files (no guarenteed order)
| Param | Type | Description |
| --- | --- | --- |
| files | <code>array</code> \| <code>string</code> | array or comma delimited string of file paths. Can be absolute or relative (see dir) |
| dir | <code>string</code> | the directory to join to any relative paths |
<a name="writeLines"></a>
## writeLines(filePath, list) ⇒ <code>Promise.&lt;null&gt;</code>
Writes files with a line for each element in a array or item in comma delimited list
**Kind**: global function
**Returns**: <code>Promise.&lt;null&gt;</code> - can catch errors but otherwise nothing resolves
| Param | Type | Description |
| --- | --- | --- |
| filePath | <code>string</code> | filepath to which file is written |
| list | <code>array</code> \| <code>string</code> | each element becomes line in file | each comma delimited item becomes a line |

View file

@ -28,9 +28,7 @@
"url": "https://github.com/uCOMmandIt/uci-utils/issues"
},
"homepage": "https://github.com/uCOMmandIt/uci-utils#readme",
"dependencies": {
"p-settle": "^5.1.1"
},
"dependencies": {},
"devDependencies": {
"chai": "^5.1.2",
"chai-arrays": "^2.2.0",

View file

@ -1,2 +1,7 @@
### Read Lines to Array
#### a uCOMmandIt Utiltiy Function
exports two functions, readlines, writelines
[API](./api.md)

View file

@ -1,50 +1,49 @@
import { promisify } from 'util'
import path from 'path'
import { readFile, writeFile } from 'fs'
const read = promisify(readFile)
const write = promisify(writeFile)
import settle from 'p-settle'
// import logger from '@uci-utils/logger'
// let log = logger({ package:'@uci-utils/read-lines', file:'src/read-lines.js'})
import path from 'node:path'
import { readFile as read, writeFile as write, stat } from 'node:fs/promises'
// read lines from one or more files
/**
* read lines from one or more files and return an array of those all those lines
* @param {array|string} files - array or comma delimited string of file paths. Can be absolute or relative (see dir)
* @param {string} dir - the directory to join to any relative paths
* @returns {Promise<array>} - resolves to an single array of all lines from all files (no guarenteed order)
*/
function readLines (files=[],dir) {
// log.debug({files:files,dir:dir,msg:'additional files'})
let list = []
if (!Array.isArray(files)) files=[files]
// each set in an the array is new line delimited set of ignore patterns
// settle returns array of error,value pairs
return settle(files.map(file => {
// console.log('directory',path.dirname(file))
if (path.dirname(file)==='.') file = dir+'/'+file
// log.debug({function:'readLines',file:file,msg:'reading a file of lines into array'})
return read(file)
// if not an array of file names it must be a string
if (!Array.isArray(files)) files=files.split(',')
return Promise.all(files.map(async file => {
if (! path.isAbsolute(file) ) {
if ( typeof dir === 'string' ) {
file = path.join(dir,file)
}}
return await read(file)
.then(lines => {
list.push(...lines.toString().match(/.+/g))
return Promise.resolve(lines)
})
.catch(e => {
return Promise.reject(e)
});
}))
.then((sets) => {
sets.forEach( set => {
if (set.isFulfilled) list.push(...set.value.toString().match(/.+/g))
else
console.log("unable to read file")
// log.warn({function:'readLines', error:set.reason, msg:' was unable to read file'})
})
return Promise.resolve(list)
})
.catch((err) => {
// only returned when something horrible is wrong
return Promise.reject(err)
})
}
// an ignore list should not be huge so can serailize at once
function writeLines (filePath,list) {
/**
* Writes files with a line for each element in a array or item in comma delimited list
* @param {string} filePath - filepath to which file is written
* @param {array|string} list - each element becomes line in file | each comma delimited item becomes a line
* @returns {Promise<null>} can catch errors but otherwise nothing resolves
*/
function writeLines (filePath,list) {
if (typeof list === "string") list = list.split(',')
return write(filePath,list.join('\n'))
.then(() => {
// log.info({function:'writeLines', file:filePath, msg:'wrote array to file of lines'})
})
.catch( err => {
// log.fatal({function:'writeLines', error:err, msg:'unable to write array to file of lines'})
})
}
export default readLines

View file

@ -1,7 +0,0 @@
/node_modules/
/coverage/
tests/
test/
*.test.js
testing/
example/

View file

@ -1,5 +1,3 @@
// let ignoreFiles = ['.npmignore','.gitignore']
import { readLines, writeLines } from '../src/read-lines.js'
import { it } from 'mocha'
import { dirname } from 'dirname-filename-esm';
@ -41,6 +39,20 @@ function readList() {
let result = await readLines(['./test/.gitignore',__dirname+'/.npmignore'])
expect(result, 'list build failed').to.be.containingAllOf(shouldbe)
})
it('==> can read files passed as a comma delimited string', async function () {
const shouldbe = [ 'tests/',
'test/',
'*.test.js',
'testing/',
'example/',
'/node_modules/',
'/coverage/' ]
let result = await readLines('test/.gitignore,test/.npmignore')
expect(result, 'list build failed').to.be.containingAllOf(shouldbe)
})
}
@ -52,4 +64,12 @@ function writeList() {
const result = await readLines(['combined.list'],__dirname)
expect(result, 'list build failed').to.be.containingAllOf(shouldbe)
})
it('==> can write an comma delimited string of items as lines in a file', async function () {
const shouldbe = await readLines(['.gitignore','.npmignore'],__dirname)
await writeLines(__dirname+'/combined2.list',shouldbe.join(','))
const result = await readLines(['combined2.list'],__dirname)
expect(result, 'list build failed').to.be.containingAllOf(shouldbe)
})
}