-
Notifications
You must be signed in to change notification settings - Fork 30
How to write a renamer plugin (renamer v2)
A renamer plugin is a module which exports a function accepting a base class as input, returning a class extending that base. Below is the most simple possible plugin module. The class must define a replace
method which receives each filePath
(e.g. /user/Lloyd/Pictures/something.jpg
) as input and returns a modified path. This trivial example appends a jpg
extension to each file.
module.exports = PluginBase => class Example extends PluginBase {
replace (filePath) {
return filePath + '.jpg'
}
}
The full signature of the replace
method looks like this.
/**
* @param {string} filePath - The current file path being processed
* @param {object} options - The current options (in camel-case), e.g. `options.find`, `options.replace` plus any custom options.
* @param {number} index - The index of the current filePath within the full list of input files.
* @param {string[]} files - The full list of input files to process (after glob expressions have been expanded).
* @returns {string} - The modified or unmodified file path.
*/
replace (filePath, options, index, files) {
// do work
}
You can pass variables into the replace method by defining command-line options. To do this, you add an optionDefinitions
method which returns one or more option definition objects. In this example, we define an --ext-name
option which expects a string argument. The options
object passed to the replace
method will contain (in camel-case) all option values set on the command-line.
module.exports = PluginBase => class Example extends PluginBase {
optionDefinitions () {
return [
{
name: 'ext-name',
type: String,
description: 'The extension to append to each file.'
}
]
}
replace (filePath, options) {
return filePath + options.extName
}
}
The finishing touch is to give your plugin a description which will be printed in the "replace chain" section of renamer --help
.
module.exports = PluginBase => class Example extends PluginBase {
description () {
return 'Appends a file extension.'
}
optionDefinitions () {
return [
{
name: 'ext-name',
description: 'The extension to append to each file.'
}
]
}
replace (filePath, options) {
return filePath + options.extName
}
}
Chalk template literal syntax can be used anywhere within the string returned by description()
and/or each description
or typeLabel
property of the objects returned by optionDefinitions()
. For example
description () {
return 'This description has {red.underline underlined red text} in it.'
}
Similar example in the option definitions.
optionDefinitions () {
return [{
name: 'ext-name',
description: 'The {blue.italic extension} to append to each file.'
}]
}
If your plugin module is saved locally, you can load it via its path. This command will show your plugin description and custom options in the usage guide.
$ renamer --plugin ./example-plugin.js --help
To share your plugin with the world, publish it to npm. Be sure to add renamer-plugin
to the keywords
array in package.json
to help us find your plugin in this list. Other users can install and use your plugin like so.
$ npm install -g renamer-example-plugin
$ renamer --plugin renamer-example-plugin --help
A plugin template containing some trivial example content. Don't forget to give the class a better name than Plugin
.
module.exports = PluginBase => class Plugin extends PluginBase {
/**
* An optional description which will be printed in the "replace chain" section of `renamer --help`.
* @returns {string}
*/
description () {
return 'Plugin description.'
}
/**
* Zero or more custom option definitions.
* @see https://github.com/75lb/command-line-args/blob/master/doc/option-definition.md
* @returns {OptionDefinition[]}
*/
optionDefinitions () {
return []
}
/**
* This method is mandatory and should modify the incoming file path as required, returning the new path.
* @param {string} filePath - The current file path being processed
* @param {object} options - The current options (in camel-case), e.g. `options.find`, `options.replace` plus any custom options.
* @param {number} index - The index of the current filePath within the full list of input files.
* @param {string[]} files - The full list of input files to process (after glob expressions have been expanded).
* @returns {string} - The modified or unmodified file path.
*/
replace (filePath, options, index, files) {
const path = require('path')
const file = path.parse(filePath)
const newName = file.name + '_example'
return path.join(file.dir, newName + file.ext)
}
}