wp-advads 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/package.json +1 -1
  2. package/src/app.js +16 -27
  3. package/src/commands/backup/index.js +11 -7
  4. package/src/commands/file/create-file.js +96 -0
  5. package/src/commands/file/index.js +29 -0
  6. package/src/commands/help/index.js +11 -4
  7. package/src/commands/index.js +5 -0
  8. package/src/commands/release/change-version.js +124 -0
  9. package/src/commands/release/changelog.js +259 -0
  10. package/src/commands/release/composer.js +37 -0
  11. package/src/commands/release/git.js +119 -0
  12. package/src/commands/release/github.js +62 -0
  13. package/src/commands/release/index.js +41 -45
  14. package/src/commands/release/prompts.js +59 -0
  15. package/src/commands/release/semver.js +198 -0
  16. package/src/commands/release/translations.js +66 -0
  17. package/src/commands/setup/create-plugin.js +213 -170
  18. package/src/commands/setup/index.js +2 -2
  19. package/src/commands/setup/prompts.js +15 -17
  20. package/src/utilities/cache.js +23 -0
  21. package/src/utilities/command.js +29 -0
  22. package/src/utilities/file.js +57 -0
  23. package/src/utilities/folder.js +64 -0
  24. package/src/utilities/formatting.js +97 -0
  25. package/src/utilities/index.js +6 -0
  26. package/src/utilities/shell.js +36 -0
  27. package/template/configs/.eslintignore +4 -1
  28. package/template/configs/.gitattributes +33 -0
  29. package/template/configs/{.phpcs.xml → .phpcs.xml.dist} +1 -0
  30. package/template/configs/.prettierignore +2 -0
  31. package/template/configs/.stylelintrc +19 -5
  32. package/template/configs/package.json +2 -2
  33. package/template/configs/webpack.mix.js +4 -3
  34. package/template/make/file-singleton.php +43 -0
  35. package/template/make/file.php +26 -0
  36. package/template/tools/laravel-mix/wp-pot.js +40 -28
  37. package/template/tools/wp-glotpress.js +125 -103
  38. package/src/helpers.js +0 -135
  39. package/template/.husky/pre-commit +0 -4
  40. package/template/configs/gitattributes +0 -25
  41. package/template/configs/gitignore +0 -38
  42. package/template/configs/webpack.mix.local.js +0 -3
  43. /package/template/{assets → plugin/assets/scss}/app.scss +0 -0
  44. /package/template/{assets → plugin/assets/src}/app.js +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "wp-advads",
4
- "version": "1.0.7",
4
+ "version": "1.0.9",
5
5
  "description": "Create a Advanced Ads wordPress plugin eco system.",
6
6
  "author": {
7
7
  "name": "Shakeeb Ahmed",
package/src/app.js CHANGED
@@ -4,26 +4,25 @@
4
4
  * External dependencies
5
5
  */
6
6
  import chalk from 'chalk'
7
- import { waterfall } from 'async'
8
- import logSymbols from 'log-symbols'
9
7
 
10
8
  /**
11
9
  * Internal Dependencies
12
10
  */
13
- import { getCommand } from './helpers.js'
14
- import { execute as backupCommand } from './commands/backup/index.js'
15
- import { execute as helpCommand } from './commands/help/index.js'
16
- import { execute as releaseCommand } from './commands/release/index.js'
17
- import { execute as setupCommand } from './commands/setup/index.js'
11
+ import { getCommand } from './utilities/index.js'
18
12
  import packageDetails from '../package.json' assert { type: "json" }
19
13
 
14
+ /**
15
+ * Commands
16
+ */
17
+ import * as commands from './commands/index.js'
18
+
20
19
  /**
21
20
  * App
22
21
  */
23
22
  async function app() {
24
23
  console.log(
25
24
  [
26
- chalk.hex('#FADC00').inverse.bold('Advanced Ads WordPress Plugin Scaffolding'),
25
+ chalk.hex('#FADC00').inverse.bold('Advanced Ads WordPress Plugin Toolkit'),
27
26
  chalk.white( 'v' + packageDetails.version ),
28
27
  chalk.dim( 'by Shakeeb Ahmed' )
29
28
  ].join(" ")
@@ -32,34 +31,24 @@ async function app() {
32
31
 
33
32
  const { command, args } = getCommand()
34
33
  if ( 'help' === command ) {
35
- helpCommand()
34
+ commands.help()
36
35
  }
37
36
 
38
37
  if ( 'backup' === command ) {
39
- backupCommand()
38
+ commands.backup()
40
39
  }
41
40
 
42
- if ( 'setup' === command ) {
43
- setupCommand()
41
+ if ( 'make:file' === command ) {
42
+ commands.makeFile(args)
44
43
  }
45
44
 
46
- if ( 'release' === command ) {
47
- releaseCommand(args)
45
+ if ( 'make:plugin' === command ) {
46
+ commands.setupPlugin(args)
48
47
  }
49
48
 
50
- // if ( 'make:file' === command ) {
51
- // waterfall(
52
- // [
53
- // function( next ) {
54
- // next(null, args)
55
- // },
56
- // createFile,
57
- // ],
58
- // ( err, results ) => {
59
- // console.log( `${logSymbols.success} ${chalk.bold.green(`All done!`)}` )
60
- // }
61
- // )
62
- // }
49
+ if ( 'make:release' === command ) {
50
+ commands.release(args)
51
+ }
63
52
  }
64
53
 
65
54
  app()
@@ -1,18 +1,16 @@
1
1
  /**
2
2
  * External Dependencies
3
3
  */
4
- import chalk from 'chalk'
5
4
  import { waterfall } from 'async'
6
- import logSymbols from 'log-symbols'
7
5
 
8
6
  /**
9
7
  * Internal Dependencies
10
8
  */
11
- import { heading, getCurrentFolder, backupFile, deleteFile } from "../../helpers.js"
9
+ import { heading, getCurrentFolder, backupFile, deleteFile, msgErrorTitle, msgSuccessTitle } from "../../utilities/index.js"
12
10
 
13
11
  function backupFiles(next) {
14
12
  backupFile('Pre commit hook', getCurrentFolder() + '/.git/hooks/pre-commit')
15
- next(null)
13
+ next()
16
14
  }
17
15
 
18
16
  function deleteFiles(next) {
@@ -26,11 +24,11 @@ function deleteFiles(next) {
26
24
  deleteFile('Package json', getCurrentFolder() + '/package.json')
27
25
  deleteFile('Package local', getCurrentFolder() + '/package.local.json')
28
26
 
29
- next(null)
27
+ next()
30
28
  }
31
29
 
32
30
 
33
- export function execute() {
31
+ export default function() {
34
32
  heading('Doing backup now...')
35
33
  console.log('');
36
34
 
@@ -40,7 +38,13 @@ export function execute() {
40
38
  deleteFiles
41
39
  ],
42
40
  ( err, results ) => {
43
- console.log( `${logSymbols.success} ${chalk.bold.green(`All done!`)}` )
41
+ console.log('');
42
+ if (err) {
43
+ msgErrorTitle('We failed!!!')
44
+ return
45
+ }
46
+
47
+ msgSuccessTitle('All done!')
44
48
  }
45
49
  )
46
50
  }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import fs from 'fs-extra'
5
+ import Handlebars from 'handlebars'
6
+ import { series, eachSeries } from 'async'
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { getSettings, getRootFolder, getTemplateFolder, runCommand } from "../../utilities/index.js"
12
+
13
+ class CreateFile {
14
+ run( args, callback ) {
15
+ const { file, singleton = false } = args
16
+ const namespace = file.split('\\')
17
+
18
+ this.template = getTemplateFolder()
19
+
20
+ // Settings
21
+ this.settings = getSettings()
22
+ this.settings.namespace = ''
23
+ this.settings.className = namespace.pop()
24
+ this.settings.heading = file
25
+ .replace(/\\/g, ' ')
26
+ .replace(/_/g, ' ')
27
+
28
+ // Filename
29
+ this.fileName = this.settings.className
30
+ .toLowerCase()
31
+ .replace(/_/g, '-')
32
+ this.fileName = `class-${this.fileName}.php`
33
+
34
+ // Folder
35
+ this.folder = getRootFolder() + '/includes/'
36
+
37
+ // Files
38
+ this.files =[ singleton ? '/file-singleton.php' : '/file.php' ]
39
+
40
+ if (namespace.length > 0) {
41
+ this.settings.namespace = '\\' + namespace.join('\\')
42
+ this.folder = this.folder + namespace.join('/').toLowerCase() + '/'
43
+ }
44
+
45
+ series(
46
+ [
47
+ this.directories,
48
+ this.prepareFiles,
49
+ (next) => {
50
+ runCommand( 'composer', [ 'dump' ], next )
51
+ },
52
+ ],
53
+ ( err, results ) => {
54
+ callback()
55
+ }
56
+ )
57
+ }
58
+
59
+ directories = ( next ) => {
60
+ console.log( 'Creating directories!!' )
61
+ this.dirs = [
62
+ // Root
63
+ this.folder,
64
+ ]
65
+
66
+ eachSeries( this.dirs, ( dir, nextDir ) => {
67
+ fs.ensureDir( dir ).then( nextDir )
68
+ }, () => {
69
+ next()
70
+ } )
71
+ }
72
+
73
+ prepareFiles = ( next ) => {
74
+ console.log( 'Preparing plugin files!!' )
75
+ const template = this.template + '/make'
76
+
77
+ eachSeries( this.files, ( file, nextFile ) => {
78
+ this.renderFile( template + file, this.folder + this.fileName, nextFile )
79
+ }, () => {
80
+ next()
81
+ } )
82
+ }
83
+
84
+ renderFile = ( src, dest, next ) => {
85
+ const content = fs.readFileSync( src, 'utf8' )
86
+ const template = Handlebars.compile( content )
87
+ const rendered = template( this.settings )
88
+
89
+ fs.outputFile( dest, rendered ).then( next )
90
+ }
91
+ }
92
+
93
+ export default ( fileName, next ) => {
94
+ const generator = new CreateFile()
95
+ generator.run( fileName, next )
96
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import chalk from 'chalk'
5
+ import { waterfall } from 'async'
6
+ import logSymbols from 'log-symbols'
7
+
8
+ /**
9
+ * Internal Dependencies
10
+ */
11
+ import { heading } from "../../utilities/index.js"
12
+ import createFile from './create-file.js'
13
+
14
+ export default function(args) {
15
+ heading('Scaffoling plugin...')
16
+ console.log('');
17
+
18
+ waterfall(
19
+ [
20
+ function( next ) {
21
+ next(null, args)
22
+ },
23
+ createFile,
24
+ ],
25
+ ( err, results ) => {
26
+ console.log( `${logSymbols.success} ${chalk.bold.green(`All done!`)}` )
27
+ }
28
+ )
29
+ }
@@ -1,9 +1,16 @@
1
- import { heading, onNewLine } from "../../helpers.js"
1
+ /**
2
+ * Internal Dependencies
3
+ */
4
+ import { heading, onNewLine } from "../../utilities/index.js"
2
5
 
3
- export function execute() {
6
+ export default function() {
4
7
  heading('Help Command Menu')
5
8
  onNewLine('List of commands')
6
9
  console.log(' npx wp-advads backup');
7
- console.log(' npx wp-advads setup');
8
- console.log(' npx wp-advads release');
10
+ console.log(' npx wp-advads make:plugin');
11
+ console.log(' npx wp-advads make:plugin --folder=my-awesome-plugin');
12
+ console.log(' npx wp-advads make:file --file="Dashboard"');
13
+ console.log(' npx wp-advads make:file --file="Admin\\Report\\Dashboard"');
14
+ console.log(' npx wp-advads make:file --file="Admin\\Report\\Dashboard" --singleton');
15
+ console.log(' npx wp-advads make:release');
9
16
  }
@@ -0,0 +1,5 @@
1
+ export { default as backup } from './backup/index.js'
2
+ export { default as makeFile } from './file/index.js'
3
+ export { default as help } from './help/index.js'
4
+ export { default as release } from './release/index.js'
5
+ export { default as setupPlugin } from './setup/index.js'
@@ -0,0 +1,124 @@
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import fs from 'fs'
5
+ import path from 'path'
6
+ import logSymbols from 'log-symbols'
7
+ import { forEach, waterfall } from 'async'
8
+
9
+ /**
10
+ * Internal Dependencies
11
+ */
12
+ import { pluginData } from './index.js'
13
+ import { heading, onSameLine, updateFileContent } from "../../utilities/index.js"
14
+
15
+ /**
16
+ * Update version in readme.txt file
17
+ *
18
+ * @example Stable tag: {version}
19
+ */
20
+ function updateReadme(next) {
21
+ updateFileContent(
22
+ './readme.txt',
23
+ {
24
+ updating: 'Updating readme file',
25
+ failed: 'Failed to update Readme file',
26
+ updated: 'Readme file updated successfully',
27
+ },
28
+ next,
29
+ (content) => {
30
+ let regex = new RegExp('^(?<prefix>Stable tag:\\h*)(?<version>(.*))$', 'mi')
31
+ regex = regex.exec(content)
32
+
33
+ if (null !== regex) {
34
+ regex = regex.groups
35
+ content = content.replace(`${regex.prefix}${regex.version}`, `${regex.prefix} ${pluginData.semver.getNextVersionString()}`)
36
+ pluginData.commitMessages.push('update: version in readme.txt')
37
+ }
38
+
39
+ return content
40
+ }
41
+ )
42
+ }
43
+
44
+ /**
45
+ * Update version in plugin PHP files at root level
46
+ *
47
+ * @example * Version: {version}
48
+ * @example * define( 'AA_VERSION', '{version}' );
49
+ */
50
+ function updatePluginFiles(next) {
51
+ process.stdout.write( 'Updating plugin files' )
52
+
53
+ fs.readdir('./', (err, files) => {
54
+ if ( null !== err ) {
55
+ onSameLine(`${logSymbols.error} Unable to fetch PHP files`)
56
+ return next(true)
57
+ }
58
+
59
+ forEach(files, (fileName, nextFile) => {
60
+ if ( '.php' === path.extname(fileName) && 'index.php' !== fileName ) {
61
+ updateFileContent(
62
+ fileName,
63
+ {
64
+ updating: `Updating ${fileName}`,
65
+ failed: `Failed to update ${fileName}`,
66
+ updated: `${fileName} updated successfully`,
67
+ },
68
+ nextFile,
69
+ (content) => {
70
+ let update = false
71
+ const version = pluginData.semver.getNextVersionString()
72
+ let versionRe = new RegExp('^(?<prefix>(?:[ \\t]*<\\?php)?[ \\t\\/*#@]*Version: +)(?<version>.*)$', 'mi')
73
+ let constantRe = new RegExp('^(?<opening>(?:[ \\t])?define.*[\\\'"].*_VERSION[\\\'"],.*[\\\'"])(?<version>.*)(?<closing>[\\\'"].*)$', 'mi')
74
+
75
+ versionRe = versionRe.exec(content)
76
+ if (null !== versionRe) {
77
+ update = true
78
+ versionRe = versionRe.groups
79
+ content = content.replace(`${versionRe.prefix}${versionRe.version}`, `${versionRe.prefix}${version}`)
80
+ }
81
+
82
+ constantRe = constantRe.exec(content)
83
+ if (null !== constantRe) {
84
+ update = true
85
+ constantRe = constantRe.groups
86
+ content = content.replace(
87
+ `${constantRe.opening}${constantRe.version}${constantRe.closing}`,
88
+ `${constantRe.opening}${version}${constantRe.closing}`,
89
+ )
90
+ }
91
+
92
+ if(update) {
93
+ pluginData.commitMessages.push('update: version in ' + fileName)
94
+ }
95
+
96
+ return content
97
+ }
98
+ )
99
+ } else {
100
+ nextFile()
101
+ }
102
+ }, () => next())
103
+ })
104
+ }
105
+
106
+ /**
107
+ * Execute routine
108
+ */
109
+ export function updateVersionNumber(next) {
110
+ heading('Updating files for new version')
111
+
112
+ const flow = []
113
+
114
+ if (!pluginData.semver.preRelease) {
115
+ flow.push(updateReadme)
116
+ }
117
+
118
+ flow.push(updatePluginFiles)
119
+
120
+ waterfall(
121
+ flow,
122
+ () => next()
123
+ )
124
+ }
@@ -0,0 +1,259 @@
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import fs from 'fs';
5
+ import logSymbols from 'log-symbols'
6
+ import { forEach, waterfall } from 'async'
7
+
8
+ /**
9
+ * Internal Dependencies
10
+ */
11
+ import { pluginData } from './index.js';
12
+ import { heading, execCommand, onSameLine, updateFileContent } from "../../utilities/index.js"
13
+
14
+ const LOCALES_CHANGELOG = {
15
+ updated: {
16
+ file: 'improvement-102',
17
+ message: 'update %s translations'
18
+ },
19
+ added: {
20
+ file: 'improvement-101',
21
+ message: 'add %s translations'
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Join list of languages
27
+ *
28
+ * @param {Array} list List of languages downloaded
29
+ *
30
+ * @returns {Array}
31
+ */
32
+ function naturalLanguageJoin(list) {
33
+ const last = list.pop()
34
+
35
+ if ( list.length > 0 ) {
36
+ return `${list.join(', ')} and ${last}`
37
+ }
38
+
39
+ return last
40
+ }
41
+
42
+ /**
43
+ * Loop through downloaded locales and categorize them as added or updated
44
+ *
45
+ * @param {Array} locales Locales downloaded from GlotPress
46
+ * @param {Array} files Files currently in branch
47
+ *
48
+ * @returns {Array}
49
+ */
50
+ function loopLocales( locales, files ) {
51
+ const changes = { updated: [], added: [] }
52
+ const localeFiles = Object.keys(locales)
53
+
54
+ localeFiles.map( (locale) => {
55
+ const action = files.includes(locale) ? 'updated' : 'added'
56
+ changes[ action ].push(locales[ locale ])
57
+ })
58
+
59
+ changes.added = [... new Set(changes.added)].sort()
60
+ changes.updated = [... new Set(changes.updated)].sort()
61
+
62
+ return changes
63
+ }
64
+
65
+ /**
66
+ * Write changes to file in .changelog folder
67
+ *
68
+ * @param {String} type Type of log
69
+ * @param {Array} changes List of changes
70
+ *
71
+ * @returns {void}
72
+ */
73
+ function writeLocalesChangelog(type, changes) {
74
+ if ( changes.length < 1 ) {
75
+ return
76
+ }
77
+
78
+ const message = LOCALES_CHANGELOG[type].message.replace('%s', naturalLanguageJoin(changes))
79
+
80
+ if (!fs.existsSync('./.changelog')) {
81
+ fs.mkdirSync('./.changelog');
82
+ }
83
+
84
+ fs.writeFileSync(
85
+ `./.changelog/${LOCALES_CHANGELOG[type].file}`,
86
+ message
87
+ )
88
+ }
89
+
90
+ /**
91
+ * Update changelog for locales
92
+ */
93
+ function updateLocalesChangelog(next) {
94
+ const { glotpress = {} } = pluginData
95
+
96
+ process.stdout.write('Generating translations changelog...')
97
+
98
+ execCommand('git ls-files ' + glotpress.destination, function(result) {
99
+ const files = result.split('\n').slice(0,-1)
100
+ const changes = loopLocales(pluginData.locales, files)
101
+
102
+ writeLocalesChangelog('added', changes.added)
103
+ writeLocalesChangelog('updated', changes.updated)
104
+
105
+ onSameLine( `${logSymbols.success} Translations changelog added` )
106
+ next()
107
+ })
108
+ }
109
+
110
+ /**
111
+ * Generate changelog entries from .changelog files
112
+ */
113
+ function generateEntries(next) {
114
+ process.stdout.write('Generating changelog entries...')
115
+
116
+ const changes = {
117
+ fix: [],
118
+ feature: [],
119
+ improvement: [],
120
+ }
121
+
122
+ const labels = {
123
+ fix: 'Fix',
124
+ feature: 'Feature',
125
+ improvement: 'Improvement',
126
+ }
127
+ const allowed = Object.keys(labels)
128
+
129
+ fs.readdir('./.changelog', (err, files) => {
130
+ if ( null !== err ) {
131
+ onSameLine(`${logSymbols.error} Unable to find .changelog directory`)
132
+ return next(true)
133
+ }
134
+
135
+ forEach(files.sort(), (fileName, nextFile) => {
136
+ const parts = fileName.split('-')
137
+
138
+ if (allowed.includes(parts[0])) {
139
+ const content = fs.readFileSync(`./.changelog/${fileName}`)
140
+
141
+ changes[ parts[0] ].push(
142
+ `- ${labels[parts[0]]}: ${content.toString().trim()}`
143
+ )
144
+ }
145
+
146
+ nextFile()
147
+ }, () => {
148
+ const currentDate = new Date();
149
+ const options = { year: 'numeric', month: 'long', day: 'numeric' };
150
+ pluginData.changelogChanges = [
151
+ ...changes['feature'],
152
+ ...changes['improvement'],
153
+ ...changes['fix'],
154
+ ]
155
+
156
+ pluginData.changelogChanges = pluginData.changelogChanges.length > 0
157
+ ? [
158
+ `= ${pluginData.semver.getNextVersionString()} (${currentDate.toLocaleDateString('en', options)}) =`,
159
+ '',
160
+ ...pluginData.changelogChanges
161
+ ] : false
162
+
163
+ onSameLine(`${logSymbols.success} Changelog entries generated successfully`)
164
+ next()
165
+ })
166
+ })
167
+ }
168
+
169
+ function writeToChangelog(next) {
170
+ updateFileContent(
171
+ './changelog.txt',
172
+ {
173
+ updating: 'Updating changelog file...',
174
+ failed: 'Failed to update changelog file',
175
+ updated: 'Changelog file updated'
176
+ },
177
+ next,
178
+ (content) => {
179
+ if(false !== pluginData.changelogChanges && !content.includes(`= ${pluginData.semver.getNextVersionString()}`)) {
180
+ content = content
181
+ .replace(
182
+ '== Changelog ==',
183
+ [
184
+ '== Changelog ==',
185
+ '',
186
+ ...pluginData.changelogChanges
187
+ ].join('\n')
188
+ )
189
+
190
+ pluginData.commitMessages.push('update: add change log to changelog.txt')
191
+ }
192
+
193
+ return content
194
+ }
195
+ )
196
+ }
197
+
198
+ function writeToReadme(next) {
199
+ updateFileContent(
200
+ './readme.txt',
201
+ {
202
+ updating: 'Updating readme file...',
203
+ failed: 'Failed to update readme file',
204
+ updated: 'Readme file updated'
205
+ },
206
+ next,
207
+ (content) => {
208
+ if(false !== pluginData.changelogChanges && !content.includes(`= ${pluginData.semver.getNextVersionString()}`)) {
209
+ content = content
210
+ .replace(
211
+ '== Changelog ==',
212
+ [
213
+ '== Changelog ==',
214
+ '',
215
+ ...pluginData.changelogChanges
216
+ ].join('\n')
217
+ )
218
+
219
+ pluginData.commitMessages.push('update: add change log to readme.txt')
220
+ }
221
+
222
+ return content
223
+ }
224
+ )
225
+ }
226
+
227
+ function cleanChangelogDirectory(next) {
228
+ process.stderr.write('Cleaning changelog directory....')
229
+
230
+ const folder = './.changelog'
231
+
232
+ if (fs.existsSync(folder)) {
233
+ fs.rmSync(folder, { recursive: true, force: true })
234
+ fs.mkdirSync(folder)
235
+ }
236
+
237
+ onSameLine(`${logSymbols.success} Changelog directory cleaned`)
238
+ next()
239
+ }
240
+
241
+ /**
242
+ * Execute routine
243
+ */
244
+ export function updateChangelog(next) {
245
+ heading('Creating changelog')
246
+
247
+ const flow = [
248
+ updateLocalesChangelog,
249
+ generateEntries
250
+ ]
251
+
252
+ if (!pluginData.semver.preRelease) {
253
+ flow.push(writeToChangelog)
254
+ flow.push(writeToReadme)
255
+ flow.push(cleanChangelogDirectory)
256
+ }
257
+
258
+ waterfall( flow, () => next() )
259
+ }