Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

renamer

Package Overview
Dependencies
Maintainers
1
Versions
63
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

renamer - npm Package Compare versions

Comparing version 0.3.0 to 0.3.1

lib/Result.js

28

cli.js
#!/usr/bin/env node
"use strict";
var Thing = require("nature").Thing,
var Model = require("nature").Model,
dope = require("console-dope"),
renamer = require("./lib/renamer"),
Renamer = renamer.Renamer,
RenameOptions = renamer.RenameOptions,
w = require("wodge");

@@ -41,3 +43,3 @@

var argv;
argv = new Thing()
argv = new Model()
.on("error", function(err){

@@ -47,3 +49,4 @@ logError("Error: " + err.message);

})
.mixIn(new renamer.RenameOptions(), "rename")
.mixIn(new RenameOptions(), "rename")
.define({ name: "verbose", type: "boolean", alias: "v" })
.define({ name: "help", type: "boolean", alias: "h" })

@@ -60,3 +63,17 @@ .set(process.argv);

if (argv.files.length){
renamer.process(argv.where({ group: "rename" }) );
if (argv["dry-run"]) dope.bold.underline.log("Dry run");
var renamer = new Renamer(argv.where({ group: "rename" }));
var results = renamer.process();
results.forEach(function(file){
if (file.error){
log(false, file.before + " %red{->} " + file.after, file.error)
} else {
if(file.renamed){
log(true, file.before + " %green{->} " + file.after);
} else if (!file.renamed && argv.verbose){
log(false, file.before);
}
}
});
} else {

@@ -74,4 +91,1 @@ dope.log(usage);

*/
/*
BUG: renamer -r blah{{index}} * // index should not reset when processing folders, also appears incorrectly as tick in dry-run
*/
"use strict";
var Thing = require("nature").Thing,
var Model = require("nature").Model,
path = require("path"),
dope = require("console-dope"),
util = require("util"),
fs = require("fs"),
Result = require("./Result"),
mfs = require("more-fs"),
Glob = require("glob").Glob,

@@ -11,17 +12,4 @@ w = require("wodge");

exports.RenameOptions = RenameOptions;
exports.process = process;
exports.Renamer = Renamer;
function log(success, msg, error){
dope.log(
"%%%s{%s} %s %s",
success ? "green" : "red",
success ? w.symbol.tick : w.symbol.cross,
msg,
error ? "(%red{" + error + "})" : ""
);
}
function logError(msg){
dope.red.log(msg);
}
function RenameOptions(){

@@ -38,8 +26,41 @@ this.define({

.define({ name: "dry-run", type: "boolean", alias: "d" })
.define({ name: "verbose", type: "boolean", alias: "v" })
.define({ name: "insensitive", type: "boolean", alias: "i" });
}
util.inherits(RenameOptions, Thing);
util.inherits(RenameOptions, Model);
/**
@constructor
*/
function Renamer(options){
this._options = new RenameOptions().set(options);
if (!this._options.valid) throw new Error("Invalid options: " + this._options.validationMessages);
}
/**
@method process
@return {Array} results An array of result objects
@example
[
{ before: "file1.txt", after: "clive.txt", renamed: false, error: "file exists" }
{ before: "file2.txt", after: "clive2.txt", renamed: true }
]
*/
Renamer.prototype.process = function(){
var options = this._options,
fileStats = new mfs.FileStats(options.files);
options.files = fileStats.files
.concat(fileStats.dirs.reverse())
.map(function(file){ return { before: file }; });
var results = options.files
.map(this._renameFile.bind(this))
.map(replaceIndexToken)
.map(this._dryRun.bind(this))
.map(this._renameOnDisk.bind(this));
return results;
};
/**
Search globally by default. If `options.regex` is not set then ensure any special regex characters in `options.find` are escaped.

@@ -55,8 +76,11 @@ */

Perform the replace, on the basename only. If no `options.find` is supplied, the entire basename is replaced by `options.replace`.
@returns {Object} beforeAfter An object containing the input path before and after the rename.
@method
@param result {ResultObject} input
@returns {ResultObject} resultObject An object containing the input path before and after the rename.
*/
function renameFile(options, file){
Renamer.prototype._renameFile = function(result, index, resultsSoFar){
var after,
dirname = path.dirname(file),
basename = path.basename(file),
options = this._options,
dirname = path.dirname(result.before),
basename = path.basename(result.before),
re = regExBuilder(options);

@@ -71,106 +95,51 @@

return { before: path.normalize(file), after: after };
}
result.before = path.normalize(result.before);
result.after = after;
result.renamed = true;
function replaceIndexToken(beforeAfter, index){
if (beforeAfter.after){
beforeAfter.after = beforeAfter.after.replace("{{index}}", index + 1);
}
return beforeAfter;
}
return result;
};
function doRename(options, from, to){
var newFilenames = [],
logMsg = from + " %green{->} " + to;
Renamer.prototype._dryRun = function(result, index, resultsSoFar){
var existing = resultsSoFar.filter(function(prevResult, prevIndex){
return prevIndex < index && (prevResult.before !== result.before) && (prevResult.after === result.after);
});
if (from === to || !to ){
if (options.verbose) log(false, from);
} else {
if (fs.existsSync(to) || newFilenames.indexOf(to) > -1){
log(false, logMsg, "file exists");
} else {
if (!options["dry-run"]) {
try {
fs.renameSync(from, to);
newFilenames.push(to);
log(true, logMsg);
} catch(e){
log(false, logMsg, e.message);
}
} else {
newFilenames.push(to);
log(true, logMsg);
}
}
if (result.before === result.after ){
result.renamed = false;
} else if (existing.length || fs.existsSync(result.after)){
result.renamed = false;
result.error = "file exists";
}
}
function renameFiles(options){
var results;
return result;
};
try {
results = options.files
.map(renameFile.bind(null, options))
.map(replaceIndexToken);
} catch (e){
logError(e.message);
process.exit(1);
}
results.forEach(function(result){
doRename(options, result.before, result.after);
});
}
/*
@returns {Object} fileStats Each key is an existing file, it's value either 1 or 2, meaning "file" or "directory", e.g.:
{
"file1": 1,
"file2": 1,
"folder1": 2,
"folder1/file1": 1,
"folder1/file2": 1
}
/**
Perform the replace, on disk. Sets the `renamed` and/or `error` properties on the resultObject.
@method
@param result {ResultObject} input
@returns {ResultObject} resultObject
*/
function getFileStats(files){
var fileStats = {},
existingFiles = files.filter(fs.existsSync),
notExistingFiles = w.without(files, existingFiles);
Renamer.prototype._renameOnDisk = function(result){
var options = this._options;
existingFiles.forEach(function(file){
fileStats[file] = fs.statSync(file).isDirectory() ? 2 : 1;
});
notExistingFiles.forEach(function(file){
var glob = new Glob(file, { sync: true, stat: true });
if (glob.found.length){
glob.found.forEach(function(file){
fileStats[file] = glob.cache[file] instanceof Array ? 2 : 1;
});
} else {
logError("File does not exist: " + file);
if (!options["dry-run"] && result.renamed === true) {
try {
fs.renameSync(result.before, result.after);
} catch(e){
result.renamed = false;
result.error = e.message;
}
});
return fileStats;
}
}
function process(options){
var options = new RenameOptions().set(options);
return result;
};
if (!options.valid) throw new Error("Invalid options: " + options.validationMessages);
if (options["dry-run"]){
dope.negative.log("Dry run");
function replaceIndexToken(result, index){
if (result.after){
result.after = result.after.replace("{{index}}", index + 1);
}
var fileStats = getFileStats(options.files),
files = w.pluck(fileStats, function(val){ return val === 1; }),
dirs = w.pluck(fileStats, function(val){ return val === 2; });
options.files = files;
renameFiles(options);
options.files = dirs.reverse();
renameFiles(options);
return result;
}
{
"name": "renamer",
"description": "Batch rename files and folders",
"version": "0.3.0",
"version": "0.3.1",
"bin": "cli.js",

@@ -13,8 +13,9 @@ "main": "./lib/renamer",

"dependencies": {
"nature": "~0.3.0",
"nature": "~0.4.0",
"glob": "~3.2.6",
"wodge": "~0.4.0",
"console-dope": "~0.3"
"console-dope": "~0.3",
"more-fs": "~0.1.2"
},
"devDependencies": {}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc