Skip to content

Commit

Permalink
[feature] #38 Count number of matches
Browse files Browse the repository at this point in the history
  • Loading branch information
adamreisnz committed Apr 20, 2019
1 parent 4fbe617 commit 98b4e3c
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 135 deletions.
4 changes: 2 additions & 2 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ console.log(`Replacing '${from}' with '${to}'`);

//Replace
try {
const changes = replace.sync(options);
successHandler(changes, verbose);
const results = replace.sync(options);
successHandler(results, verbose);
}
catch (error) {
errorHandler(error);
Expand Down
7 changes: 4 additions & 3 deletions lib/helpers/get-paths-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ const globAsync = require('./glob-async');
/**
* Get paths asynchrously
*/
module.exports = function getPathsAsync(
patterns, ignore, disableGlobs, allowEmptyPaths, cfg
) {
module.exports = function getPathsAsync(patterns, config) {

//Extract relevant config
const {ignore, disableGlobs, allowEmptyPaths, glob: cfg} = config;

//Not using globs?
if (disableGlobs) {
Expand Down
7 changes: 5 additions & 2 deletions lib/helpers/get-paths-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ const glob = require('glob');
/**
* Get paths (sync)
*/
module.exports = function getPathsSync(patterns, ignore, disableGlobs, cfg) {
module.exports = function getPathsSync(patterns, config) {

//Extract relevant config
const {ignore, disableGlobs, glob: globConfig} = config;

//Not using globs?
if (disableGlobs) {
return patterns;
}

//Prepare glob config
cfg = Object.assign({ignore}, cfg, {nodir: true});
const cfg = Object.assign({ignore}, globConfig, {nodir: true});

//Get paths
const paths = patterns
Expand Down
28 changes: 23 additions & 5 deletions lib/helpers/make-replacements.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,27 @@ function getReplacement(replace, isArray, i) {
/**
* Helper to make replacements
*/
module.exports = function makeReplacements(contents, from, to, file) {
module.exports = function makeReplacements(contents, from, to, file, count) {

//Turn into array
if (!Array.isArray(from)) {
from = [from];
}

//Check if replace value is an array
//Check if replace value is an array and prepare result
const isArray = Array.isArray(to);
const oldContents = contents;
const result = {file};

//Counting?
if (count) {
result.numMatches = 0;
}

//Make replacements
from.forEach((item, i) => {

//Call function if given, passing the filename
//Call function if given, passing in the filename
if (typeof item === 'function') {
item = item(file);
}
Expand All @@ -46,10 +53,21 @@ module.exports = function makeReplacements(contents, from, to, file) {
replacement = (...args) => original(...args, file);
}

//Count matches
if (count) {
const match = contents.match(item);
if (match) {
result.numMatches += match.length;
}
}

//Make replacement
contents = contents.replace(item, replacement);
});

//Return modified contents
return contents;
//Check if changed
result.hasChanged = (oldContents !== contents);

//Return result and new contents
return [result, contents];
};
6 changes: 2 additions & 4 deletions lib/helpers/parse-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const defaults = {
encoding: 'utf-8',
disableGlobs: false,
allowEmptyPaths: false,
countMatches: false,
isRegex: false,
verbose: false,
dry: false,
Expand All @@ -28,7 +29,7 @@ module.exports = function parseConfig(config) {
config.glob = config.glob || {};

//Extract data
const {files, from, to, ignore, encoding, glob} = config;
const {files, from, to, ignore, encoding} = config;

//Validate values
if (typeof files === 'undefined') {
Expand All @@ -40,9 +41,6 @@ module.exports = function parseConfig(config) {
if (typeof to === 'undefined') {
throw new Error('Must specify a replacement (can be blank string)');
}
if (typeof glob !== 'object') {
throw new Error('Invalid glob config');
}

//Ensure arrays
if (!Array.isArray(files)) {
Expand Down
28 changes: 16 additions & 12 deletions lib/helpers/replace-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,36 @@ const makeReplacements = require('./make-replacements');
/**
* Helper to replace in a single file (async)
*/
module.exports = function replaceAsync(file, from, to, enc, dry) {
module.exports = function replaceAsync(file, from, to, config) {

//Extract relevant config
const {encoding, dry, countMatches} = config;

//Wrap in promise
return new Promise((resolve, reject) => {
fs.readFile(file, enc, (error, contents) => {
fs.readFile(file, encoding, (error, contents) => {
//istanbul ignore if
if (error) {
return reject(error);
}

//Replace contents and check if anything changed
let newContents = makeReplacements(contents, from, to, file);
if (newContents === contents) {
return resolve({file, hasChanged: false});
}
//Make replacements
const [result, newContents] = makeReplacements(
contents, from, to, file, countMatches
);

//Dry run, resolve
if (dry) {
return resolve({file, hasChanged: true});
//Not changed or dry run?
if (!result.hasChanged || dry) {
return resolve(result);
}

//Write to file
fs.writeFile(file, newContents, enc, error => {
fs.writeFile(file, newContents, encoding, error => {
//istanbul ignore if
if (error) {
return reject(error);
}
resolve({file, hasChanged: true});
resolve(result);
});
});
});
Expand Down
25 changes: 12 additions & 13 deletions lib/helpers/replace-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,22 @@ const makeReplacements = require('./make-replacements');
/**
* Helper to replace in a single file (sync)
*/
module.exports = function replaceSync(file, from, to, enc, dry) {
module.exports = function replaceSync(file, from, to, config) {

//Read contents
const contents = fs.readFileSync(file, enc);
//Extract relevant config and read file contents
const {encoding, dry, countMatches} = config;
const contents = fs.readFileSync(file, encoding);

//Replace contents and check if anything changed
const newContents = makeReplacements(contents, from, to, file);
if (newContents === contents) {
return false;
}
const [result, newContents] = makeReplacements(
contents, from, to, file, countMatches
);

//Dry run?
if (dry) {
return true;
//Contents changed and not a dry run? Write to file
if (result.hasChanged && !dry) {
fs.writeFileSync(file, newContents, encoding);
}

//Write to file
fs.writeFileSync(file, newContents, enc);
return true;
//Return result
return result;
};
44 changes: 12 additions & 32 deletions lib/replace-in-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ function replaceInFile(config, cb) {
}

//Get config
const {
files, from, to, encoding, ignore, allowEmptyPaths, disableGlobs,
dry, verbose, glob,
} = config;
const {files, from, to, dry, verbose} = config;

//Dry run?
//istanbul ignore if: No need to test console logs
Expand All @@ -39,26 +36,19 @@ function replaceInFile(config, cb) {
}

//Find paths
return getPathsAsync(files, ignore, disableGlobs, allowEmptyPaths, glob)
return getPathsAsync(files, config)

//Make replacements
.then(paths => Promise.all(paths.map(file => {
return replaceAsync(file, from, to, encoding, dry);
})))

//Convert results to array of changed files
.then(results => {
return results
.filter(result => result.hasChanged)
.map(result => result.file);
})
.then(paths => Promise.all(
paths.map(file => replaceAsync(file, from, to, config))
))

//Success handler
.then(changedFiles => {
.then(results => {
if (cb) {
cb(null, changedFiles);
cb(null, results);
}
return changedFiles;
return results;
})

//Error handler
Expand All @@ -81,27 +71,17 @@ replaceInFile.sync = function(config) {
config = parseConfig(config);

//Get config, paths, and initialize changed files
const {
files, from, to, encoding, ignore, disableGlobs, dry, verbose, glob,
} = config;
const paths = getPathsSync(files, ignore, disableGlobs, glob);
const changedFiles = [];
const {files, from, to, dry, verbose} = config;
const paths = getPathsSync(files, config);

//Dry run?
//istanbul ignore if: No need to test console logs
if (dry && verbose) {
console.log(chalk.yellow('Dry run, not making any changes'));
}

//Process synchronously
paths.forEach(path => {
if (replaceSync(path, from, to, encoding, dry)) {
changedFiles.push(path);
}
});

//Return changed files
return changedFiles;
//Process synchronously and return results
return paths.map(path => replaceSync(path, from, to, config));
};

//Export
Expand Down
Loading

0 comments on commit 98b4e3c

Please sign in to comment.