Repository: yargs/yargs
Pull request #1384 (2019-07-29 05:25:27)

Support multiple epilogs being added
# Context
We wrap our commands in a function that adds `docs`, `maintainer`, and `slack` properties to the command module object. We use these properties as part of an automatically generated epilog that we add to each command.

# Problem
Currently subsequent calls to `epilog` will overwrite any previous epilog.

# Fix
Store epilogs in an array which is added to on each `epilog` call. Join them with new lines when building usage.


Patch:
diff --git a/lib/usage.js b/lib/usage.js
index ded4fc4..fed6d9f 100644
--- a/lib/usage.js
+++ b/lib/usage.js
@@ -122,9 +122,9 @@ module.exports = function usage (yargs, y18n) {
   }
   self.getDescriptions = () => descriptions
 
-  let epilog
+  let epilogs = []
   self.epilog = (msg) => {
-    epilog = msg
+    epilogs.push(msg)
   }
 
   let wrapSet = false
@@ -151,7 +151,7 @@ module.exports = function usage (yargs, y18n) {
     normalizeAliases()
 
     // handle old demanded API
-    const base$0 = path.basename(yargs.$0)
+    const base$0 = yargs.customScriptName ? yargs.$0 : path.basename(yargs.$0)
     const demandedOptions = yargs.getDemandedOptions()
     const demandedCommands = yargs.getDemandedCommands()
     const groups = yargs.getGroups()
@@ -345,8 +345,8 @@ module.exports = function usage (yargs, y18n) {
     }
 
     // the usage string.
-    if (epilog) {
-      const e = epilog.replace(/\$0/g, base$0)
+    if (epilogs.length > 0) {
+      const e = epilogs.map(epilog => epilog.replace(/\$0/g, base$0)).join('\n')
       ui.div(`${e}\n`)
     }
 
@@ -505,7 +505,7 @@ module.exports = function usage (yargs, y18n) {
     failureOutput = false
     usages = []
     usageDisabled = false
-    epilog = undefined
+    epilogs = []
     examples = []
     commands = []
     descriptions = objFilter(descriptions, (k, v) => !localLookup[k])
@@ -520,7 +520,7 @@ module.exports = function usage (yargs, y18n) {
     frozen.failureOutput = failureOutput
     frozen.usages = usages
     frozen.usageDisabled = usageDisabled
-    frozen.epilog = epilog
+    frozen.epilogs = epilogs
     frozen.examples = examples
     frozen.commands = commands
     frozen.descriptions = descriptions
@@ -531,7 +531,7 @@ module.exports = function usage (yargs, y18n) {
     failureOutput = frozen.failureOutput
     usages = frozen.usages
     usageDisabled = frozen.usageDisabled
-    epilog = frozen.epilog
+    epilogs = frozen.epilogs
     examples = frozen.examples
     commands = frozen.commands
     descriptions = frozen.descriptions
diff --git a/yargs.js b/yargs.js
index e9eae4b..67f9d11 100644
--- a/yargs.js
+++ b/yargs.js
@@ -37,7 +37,8 @@ function Yargs (processArgs, cwd, parentRequire) {
 
   if (!cwd) cwd = process.cwd()
 
-  self.scriptName = function scriptName (scriptName) {
+  self.scriptName = function (scriptName) {
+    self.customScriptName = true
     self.$0 = scriptName
     return self
   }


Test patch:
diff --git a/test/usage.js b/test/usage.js
index 4d21153..f3c9725 100644
--- a/test/usage.js
+++ b/test/usage.js
@@ -1250,6 +1250,24 @@ describe('usage tests', () => {
       r.errors.should.have.length(0)
       r.exit.should.equal(true)
     })
+
+    it('should not alter the user supplied scriptName', () => {
+      const r = checkUsage(() => yargs(['--help'])
+        .scriptName('./custom')
+        .command('command')
+        .parse()
+      )
+      r.logs.join('\n').split(/\n+/).should.deep.equal([
+        './custom [command]',
+        'Commands:',
+        '  ./custom command',
+        'Options:',
+        '  --help     Show help                                                 [boolean]',
+        '  --version  Show version number                                       [boolean]'
+      ])
+      r.errors.should.have.length(0)
+      r.exit.should.equal(true)
+    })
   })
 
   it('should succeed when rebase', () => {
@@ -1925,6 +1943,28 @@ describe('usage tests', () => {
       ])
     })
 
+    it('supports multiple epilogs', () => {
+      const r = checkUsage(() => yargs('')
+        .epilog('for more info view the manual at http://example.com')
+        .epilog('you can also find us on slack at http://devtoolscommunity.herokuapp.com')
+        .epilog('keep up to date by reading our blog at http://yargs.js.org/blog.html')
+        .demand('y')
+        .wrap(null)
+        .parse()
+      )
+
+      r.errors.join('\n').split(/\n+/).should.deep.equal([
+        'Options:',
+        '  --help     Show help  [boolean]',
+        '  --version  Show version number  [boolean]',
+        '  -y  [required]',
+        'for more info view the manual at http://example.com',
+        'you can also find us on slack at http://devtoolscommunity.herokuapp.com',
+        'keep up to date by reading our blog at http://yargs.js.org/blog.html',
+        'Missing required argument: y'
+      ])
+    })
+
     it('replaces $0 in epilog string', () => {
       const r = checkUsage(() => yargs('')
         .epilog("Try '$0 --long-help' for more information")