You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
5.1 KiB

  1. #!/usr/bin/env node
  2. // ===========================================
  3. // Wiki.js
  4. // 2.0
  5. // Licensed under AGPLv3
  6. // ===========================================
  7. const Promise = require('bluebird')
  8. const fs = Promise.promisifyAll(require('fs-extra'))
  9. const pm2 = Promise.promisifyAll(require('pm2'))
  10. const ora = require('ora')
  11. const path = require('path')
  12. const cluster = require('cluster')
  13. const _ = require('lodash')
  14. const chalk = require('chalk')
  15. const ROOTPATH = process.cwd()
  16. const init = {
  17. /**
  18. * Start in background mode
  19. */
  20. start () {
  21. let spinner = ora('Initializing...').start()
  22. return fs.emptyDirAsync(path.join(ROOTPATH, './logs')).then(() => {
  23. return pm2.connectAsync().then(() => {
  24. return pm2.startAsync({
  25. name: 'wiki',
  26. script: 'server',
  27. cwd: ROOTPATH,
  28. output: path.join(ROOTPATH, './logs/wiki-output.log'),
  29. error: path.join(ROOTPATH, './logs/wiki-error.log'),
  30. minUptime: 5000,
  31. maxRestarts: 5
  32. }).then(() => {
  33. spinner.succeed('Wiki.js has started successfully.')
  34. }).finally(() => {
  35. pm2.disconnect()
  36. })
  37. })
  38. }).catch(err => {
  39. spinner.fail(err)
  40. process.exit(1)
  41. })
  42. },
  43. /**
  44. * Stop Wiki.js process(es)
  45. */
  46. stop () {
  47. let spinner = ora('Shutting down Wiki.js...').start()
  48. return pm2.connectAsync().then(() => {
  49. return pm2.stopAsync('wiki').then(() => {
  50. spinner.succeed('Wiki.js has stopped successfully.')
  51. }).finally(() => {
  52. pm2.disconnect()
  53. })
  54. }).catch(err => {
  55. spinner.fail(err)
  56. process.exit(1)
  57. })
  58. },
  59. /**
  60. * Restart Wiki.js process(es)
  61. */
  62. restart: function () {
  63. return this.stop().delay(1000).then(() => {
  64. this.start()
  65. })
  66. },
  67. dev() {
  68. if (cluster.isMaster) {
  69. const webpack = require('webpack')
  70. const chokidar = require('chokidar')
  71. global.DEV = true
  72. global.WP_CONFIG = require('./dev/webpack/webpack.dev.js')
  73. global.WP = webpack(global.WP_CONFIG)
  74. global.WP_DEV = {
  75. devMiddleware: require('webpack-dev-middleware')(global.WP, {
  76. publicPath: global.WP_CONFIG.output.publicPath
  77. }),
  78. hotMiddleware: require('webpack-hot-middleware')(global.WP)
  79. }
  80. global.WP_DEV.devMiddleware.waitUntilValid(() => {
  81. console.info(chalk.yellow.bold('>>> Starting Wiki.js in DEVELOPER mode...'))
  82. require('./server')
  83. process.stdin.setEncoding('utf8')
  84. process.stdin.on('data', data => {
  85. if (_.trim(data) === 'rs') {
  86. console.warn(chalk.yellow.bold('--- >>>>>>>>>>>>>>>>>>>>>>>> ---'))
  87. console.warn(chalk.yellow.bold('--- Manual restart requested ---'))
  88. console.warn(chalk.yellow.bold('--- <<<<<<<<<<<<<<<<<<<<<<<< ---'))
  89. this.reload()
  90. }
  91. })
  92. const devWatcher = chokidar.watch([
  93. './server',
  94. '!./server/views/master.pug'
  95. ], {
  96. ignoreInitial: true,
  97. atomic: 400
  98. })
  99. devWatcher.on('ready', () => {
  100. devWatcher.on('all', () => {
  101. console.warn(chalk.yellow.bold('--- >>>>>>>>>>>>>>>>>>>>>>>>>>>> ---'))
  102. console.warn(chalk.yellow.bold('--- Changes detected: Restarting ---'))
  103. console.warn(chalk.yellow.bold('--- <<<<<<<<<<<<<<<<<<<<<<<<<<<< ---'))
  104. this.reload()
  105. })
  106. })
  107. })
  108. } else {
  109. require('./server')
  110. }
  111. },
  112. async reload() {
  113. console.warn(chalk.yellow('--- Closing DB connections...'))
  114. await global.WIKI.models.knex.destroy()
  115. console.warn(chalk.yellow('--- Closing Redis connections...'))
  116. await global.WIKI.redis.quit()
  117. await global.WIKI.redisSub.quit()
  118. console.warn(chalk.yellow('--- Closing Queue connections...'))
  119. await global.WIKI.queue.quit()
  120. console.warn(chalk.yellow('--- Closing Server connections...'))
  121. global.WIKI.server.destroy(() => {
  122. global.WIKI = {}
  123. Object.keys(require.cache).forEach(id => {
  124. if (/[/\\]server[/\\]/.test(id)) {
  125. delete require.cache[id]
  126. }
  127. })
  128. Object.keys(module.constructor._pathCache).forEach(cacheKey => {
  129. if (/[/\\]server[/\\]/.test(cacheKey)) {
  130. delete module.constructor._pathCache[cacheKey]
  131. }
  132. })
  133. require('./server')
  134. })
  135. }
  136. }
  137. require('yargs') // eslint-disable-line no-unused-expressions
  138. .usage('Usage: node $0 <cmd> [args]')
  139. .command({
  140. command: 'start',
  141. alias: ['boot', 'init'],
  142. desc: 'Start Wiki.js process',
  143. handler: argv => {
  144. init.start()
  145. }
  146. })
  147. .command({
  148. command: 'stop',
  149. alias: ['quit', 'exit'],
  150. desc: 'Stop Wiki.js process',
  151. handler: argv => {
  152. init.stop()
  153. }
  154. })
  155. .command({
  156. command: 'restart',
  157. alias: ['reload'],
  158. desc: 'Restart Wiki.js process',
  159. handler: argv => {
  160. init.restart()
  161. }
  162. })
  163. .command({
  164. command: 'dev',
  165. desc: 'Start in Developer Mode',
  166. handler: argv => {
  167. init.dev()
  168. }
  169. })
  170. .recommendCommands()
  171. .demandCommand(1, 'You must provide one of the accepted commands above.')
  172. .help()
  173. .version()
  174. .epilogue('Read the docs at https://docs.requarks.io/wiki')
  175. .argv