line-replace
Advanced tools
+25
-13
@@ -34,10 +34,15 @@ #!/usr/bin/env node | ||
| function onReplace (data) { | ||
| if (data.text === data.replacedText) displayResult('noChanges', data) | ||
| if (!data.text) displayResult('lineCleared', data) | ||
| if (!data.replacedText) displayResult('blankLineReplaced', data) | ||
| function onReplace(data) { | ||
| const { text, replacedText, error } = data | ||
| if (error) { | ||
| displayResult('error', data) | ||
| return | ||
| } | ||
| if (text === replacedText) displayResult('noChanges', data) | ||
| if (!text) displayResult('lineCleared', data) | ||
| if (!replacedText) displayResult('blankLineReplaced', data) | ||
| displayResult('changed', data) | ||
| } | ||
| function displayResult (type, data) { | ||
| function displayResult(type, data) { | ||
| const message = getResultMessage(type, data) | ||
@@ -48,4 +53,5 @@ console.log(message) | ||
| function getResultMessage (type, data) { | ||
| const fileLine = `${data.file}:${data.line}` | ||
| function getResultMessage(type, data) { | ||
| const { file, line, text, replacedText, error } = data | ||
| const fileLine = `${file}:${line}` | ||
@@ -55,3 +61,3 @@ const blankLineReplaced = ` | ||
| was replaced with: | ||
| ${data.text} | ||
| ${text} | ||
| ` | ||
@@ -66,12 +72,17 @@ const noChanges = ` | ||
| Previous content: | ||
| ${data.replacedText} | ||
| ${replacedText} | ||
| ` | ||
| const changed = ` | ||
| The content on '${fileLine}': | ||
| ${data.replacedText} | ||
| ${replacedText} | ||
| was replaced with: | ||
| ${data.text} | ||
| ${text} | ||
| ` | ||
| const error = ` | ||
| Replacement on '${fileLine}' FAILED: | ||
| ${error.message} | ||
| ` | ||
| const messages = { | ||
@@ -81,3 +92,4 @@ blankLineReplaced, | ||
| lineCleared, | ||
| changed | ||
| changed, | ||
| error | ||
| } | ||
@@ -88,3 +100,3 @@ | ||
| function showUsage () { | ||
| function showUsage() { | ||
| console.log(` | ||
@@ -91,0 +103,0 @@ USAGE: |
+8
-14
| { | ||
| "name": "line-replace", | ||
| "version": "1.0.3", | ||
| "version": "2.0.1", | ||
| "description": "Replace a line in a file with passed string.", | ||
| "main": "src/line-replace.js", | ||
| "scripts": { | ||
| "test-focus": "standard-focus", | ||
| "test": "standard && mocha", | ||
| "test": "mocha", | ||
| "test-watch": "mocha --watch --recursive", | ||
@@ -23,3 +22,6 @@ "start": "node ./bin/index.js" | ||
| ], | ||
| "author": "Alberto Miranda", | ||
| "author": { | ||
| "name": "Alberto Miranda", | ||
| "url": "http://albertomiranda.com.ar" | ||
| }, | ||
| "license": "MIT", | ||
@@ -32,13 +34,5 @@ "bugs": { | ||
| "devDependencies": { | ||
| "chai": "^3.5.0", | ||
| "mocha": "^3.2.0", | ||
| "standard-focus": "^1.1.1" | ||
| }, | ||
| "standard": { | ||
| "globals": [ | ||
| "describe", | ||
| "it", | ||
| "beforeEach" | ||
| ] | ||
| "chai": "^4.2.0", | ||
| "mocha": "^7.1.2" | ||
| } | ||
| } |
+24
-5
| # line-replace | ||
| Replace a line in a file with passed string. | ||
@@ -9,6 +10,6 @@ | ||
| Global, for command line usage: | ||
| `npm install -g line-replace` | ||
| `npm i -g line-replace` | ||
| Local, for programatic usage in your project: | ||
| `npm install --save line-replace` | ||
| `npm i line-replace` | ||
@@ -29,2 +30,12 @@ ## Command line usage | ||
| You can also use it directly with `npx`: | ||
| `npx line-replace [file]:[line] [[string]]` | ||
| For example: | ||
| `npx line-replace test.txt:1 'HEY!'` | ||
| Note that **line numbers start at 1**. | ||
| ## Programatic usage | ||
@@ -39,3 +50,3 @@ | ||
| addNewLine: true, | ||
| callback: ({file, line, text, replacedText}) => {} | ||
| callback: ({ file, line, text, replacedText, error }) => {} | ||
| }) | ||
@@ -51,2 +62,3 @@ ``` | ||
| For example, with the following content: | ||
| ``` | ||
@@ -59,2 +71,3 @@ First line. | ||
| Running: | ||
| ``` | ||
@@ -66,3 +79,3 @@ lineReplace({ | ||
| addNewLine: false, | ||
| callback: ({file, line, text, replacedText}) => {} | ||
| callback: ({file, line, text, replacedText, error}) => {} | ||
| }) | ||
@@ -72,2 +85,3 @@ ``` | ||
| Will result in: | ||
| ``` | ||
@@ -82,2 +96,7 @@ First line. | ||
| Enjoy! | ||
| ## Changelog | ||
| ### v2.0 | ||
| - FS sync methods replaced with async + [utils.promisify](https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original) (added in Node v8). | ||
| - Passing errors to callback. |
+26
-7
| const fs = require('fs') | ||
| const util = require('util') | ||
| const readline = require('readline') | ||
| const stream = require('stream') | ||
| const rename = util.promisify(fs.rename) | ||
| const unlink = util.promisify(fs.unlink) | ||
| function lineReplace ({file, line, text, addNewLine = true, callback}) { | ||
| function lineReplace({ file, line, text, addNewLine = true, callback }) { | ||
| const readStream = fs.createReadStream(file) | ||
@@ -12,2 +15,17 @@ const tempFile = `${file}.tmp` | ||
| readStream.on('error', async ({ message }) => { | ||
| await unlink(tempFile) | ||
| callback({ error: message, file, line, replacedText, text }) | ||
| }) | ||
| writeStream.on('error', async ({ message }) => { | ||
| await unlink(tempFile) | ||
| callback({ error: message, file, line, replacedText, text }) | ||
| }) | ||
| rl.on('error', async ({ message }) => { | ||
| await unlink(tempFile) | ||
| callback({ error: message, file, line, replacedText, text }) | ||
| }) | ||
| let currentLine = 0 | ||
@@ -31,11 +49,12 @@ rl.on('line', (originalLine) => { | ||
| // Replace original file with fixed file (the temp file). | ||
| writeStream.end(() => { | ||
| writeStream.end(async () => { | ||
| try { | ||
| fs.unlinkSync(file) // Delete original file. | ||
| fs.renameSync(tempFile, file) // Rename temp file with original file name. | ||
| } catch (e) { | ||
| throw e | ||
| await unlink(file) // Delete original file. | ||
| await rename(tempFile, file) // Rename temp file with original file name. | ||
| } catch (error) { | ||
| callback({ error, file, line, replacedText, text }) | ||
| return | ||
| } | ||
| callback({file, line, replacedText, text}) | ||
| callback({ file, line, replacedText, text }) | ||
| }) | ||
@@ -42,0 +61,0 @@ }) |
@@ -1,2 +0,2 @@ | ||
| const {expect} = require('chai') | ||
| const { expect } = require('chai') | ||
| const fs = require('fs') | ||
@@ -19,5 +19,7 @@ const path = require('path') | ||
| function onReplace (replaceData) { | ||
| const fileData = fs.readFileSync(testFile, {encoding: 'utf8'}) | ||
| expect(fileData).to.equal(testFileContent.replace('First line.', 'Hi there!')) | ||
| function onReplace(replaceData) { | ||
| const fileData = fs.readFileSync(testFile, { encoding: 'utf8' }) | ||
| expect(fileData).to.equal( | ||
| testFileContent.replace('First line.', 'Hi there!') | ||
| ) | ||
| done() | ||
@@ -35,5 +37,10 @@ } | ||
| function onReplace (replaceData) { | ||
| const fileData = fs.readFileSync(testFile, {encoding: 'utf8'}) | ||
| expect(fileData).to.equal(testFileContent.replace('This kinda works!\n', `This kinda works!\nLet's rock!`)) | ||
| function onReplace(replaceData) { | ||
| const fileData = fs.readFileSync(testFile, { encoding: 'utf8' }) | ||
| expect(fileData).to.equal( | ||
| testFileContent.replace( | ||
| 'This kinda works!\n', | ||
| `This kinda works!\nLet's rock!` | ||
| ) | ||
| ) | ||
| done() | ||
@@ -51,5 +58,7 @@ } | ||
| function onReplace (replaceData) { | ||
| const fileData = fs.readFileSync(testFile, {encoding: 'utf8'}) | ||
| expect(fileData).to.equal(testFileContent.replace('This kinda works!', '')) | ||
| function onReplace(replaceData) { | ||
| const fileData = fs.readFileSync(testFile, { encoding: 'utf8' }) | ||
| expect(fileData).to.equal( | ||
| testFileContent.replace('This kinda works!', '') | ||
| ) | ||
| done() | ||
@@ -68,4 +77,4 @@ } | ||
| function onReplace (replaceData) { | ||
| const fileData = fs.readFileSync(testFile, {encoding: 'utf8'}) | ||
| function onReplace(replaceData) { | ||
| const fileData = fs.readFileSync(testFile, { encoding: 'utf8' }) | ||
| const newContent = testFileContent | ||
@@ -87,3 +96,3 @@ .replace('This kinda works!\n', '') | ||
| function onReplace (replaceData) { | ||
| function onReplace(replaceData) { | ||
| expect(replaceData.text).to.equal('Hello, everything ok there?') | ||
@@ -96,5 +105,27 @@ expect(replaceData.replacedText).to.equal('First line.') | ||
| }) | ||
| it('should pass errors to callback', (done) => { | ||
| const text = 'Hello, did you get the error?' | ||
| const unexistentFile = 'does-not-exist.txt' | ||
| lineReplace({ | ||
| file: unexistentFile, | ||
| line: 1, | ||
| text, | ||
| callback: onReplace | ||
| }) | ||
| function onReplace({ text, replacedText, line, file, error }) { | ||
| expect(text).to.equal(text) | ||
| expect(replacedText).to.equal(undefined) | ||
| expect(line).to.equal(1) | ||
| expect(file).to.equal(unexistentFile) | ||
| expect(error).to.equal( | ||
| `ENOENT: no such file or directory, open '${file}'` | ||
| ) | ||
| done() | ||
| } | ||
| }) | ||
| }) | ||
| function resetTestFile () { | ||
| function resetTestFile() { | ||
| testFileContent = `First line. | ||
@@ -101,0 +132,0 @@ This kinda works! |
+1
-1
@@ -1,2 +0,2 @@ | ||
| Hello, everything ok there? | ||
| First line. | ||
| This kinda works! | ||
@@ -3,0 +3,0 @@ |
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
12378
16.65%2
-33.33%301
22.86%95
25%