cli.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2018 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package cli // import "miniflux.app/cli"
  5. import (
  6. "flag"
  7. "fmt"
  8. "miniflux.app/config"
  9. "miniflux.app/database"
  10. "miniflux.app/locale"
  11. "miniflux.app/logger"
  12. "miniflux.app/storage"
  13. "miniflux.app/ui/static"
  14. "miniflux.app/version"
  15. )
  16. const (
  17. flagInfoHelp = "Show application information"
  18. flagVersionHelp = "Show application version"
  19. flagMigrateHelp = "Run SQL migrations"
  20. flagFlushSessionsHelp = "Flush all sessions (disconnect users)"
  21. flagCreateAdminHelp = "Create admin user"
  22. flagResetPasswordHelp = "Reset user password"
  23. flagResetFeedErrorsHelp = "Clear all feed errors for all users"
  24. flagDebugModeHelp = "Show debug logs"
  25. flagConfigFileHelp = "Load configuration file"
  26. flagConfigDumpHelp = "Print parsed configuration values"
  27. )
  28. // Parse parses command line arguments.
  29. func Parse() {
  30. var (
  31. err error
  32. flagInfo bool
  33. flagVersion bool
  34. flagMigrate bool
  35. flagFlushSessions bool
  36. flagCreateAdmin bool
  37. flagResetPassword bool
  38. flagResetFeedErrors bool
  39. flagDebugMode bool
  40. flagConfigFile string
  41. flagConfigDump bool
  42. )
  43. flag.BoolVar(&flagInfo, "info", false, flagInfoHelp)
  44. flag.BoolVar(&flagInfo, "i", false, flagInfoHelp)
  45. flag.BoolVar(&flagVersion, "version", false, flagVersionHelp)
  46. flag.BoolVar(&flagVersion, "v", false, flagVersionHelp)
  47. flag.BoolVar(&flagMigrate, "migrate", false, flagMigrateHelp)
  48. flag.BoolVar(&flagFlushSessions, "flush-sessions", false, flagFlushSessionsHelp)
  49. flag.BoolVar(&flagCreateAdmin, "create-admin", false, flagCreateAdminHelp)
  50. flag.BoolVar(&flagResetPassword, "reset-password", false, flagResetPasswordHelp)
  51. flag.BoolVar(&flagResetFeedErrors, "reset-feed-errors", false, flagResetFeedErrorsHelp)
  52. flag.BoolVar(&flagDebugMode, "debug", false, flagDebugModeHelp)
  53. flag.StringVar(&flagConfigFile, "config-file", "", flagConfigFileHelp)
  54. flag.StringVar(&flagConfigFile, "c", "", flagConfigFileHelp)
  55. flag.BoolVar(&flagConfigDump, "config-dump", false, flagConfigDumpHelp)
  56. flag.Parse()
  57. cfg := config.NewParser()
  58. if flagConfigFile != "" {
  59. config.Opts, err = cfg.ParseFile(flagConfigFile)
  60. if err != nil {
  61. logger.Fatal("%v", err)
  62. }
  63. }
  64. config.Opts, err = cfg.ParseEnvironmentVariables()
  65. if err != nil {
  66. logger.Fatal("%v", err)
  67. }
  68. if flagConfigDump {
  69. fmt.Print(config.Opts)
  70. return
  71. }
  72. if config.Opts.LogDateTime() {
  73. logger.EnableDateTime()
  74. }
  75. if flagDebugMode || config.Opts.HasDebugMode() {
  76. logger.EnableDebug()
  77. }
  78. if flagInfo {
  79. info()
  80. return
  81. }
  82. if flagVersion {
  83. fmt.Println(version.Version)
  84. return
  85. }
  86. if config.Opts.IsDefaultDatabaseURL() {
  87. logger.Info("The default value for DATABASE_URL is used")
  88. }
  89. logger.Debug("Loading translations...")
  90. if err := locale.LoadCatalogMessages(); err != nil {
  91. logger.Fatal("Unable to load translations: %v", err)
  92. }
  93. logger.Debug("Loading static assets...")
  94. if err := static.CalculateBinaryFileChecksums(); err != nil {
  95. logger.Fatal("Unable to calculate binary files checksum: %v", err)
  96. }
  97. if err := static.GenerateStylesheetsBundles(); err != nil {
  98. logger.Fatal("Unable to generate Stylesheet bundles: %v", err)
  99. }
  100. if err := static.GenerateJavascriptBundles(); err != nil {
  101. logger.Fatal("Unable to generate Javascript bundles: %v", err)
  102. }
  103. db, err := database.NewConnectionPool(
  104. config.Opts.DatabaseURL(),
  105. config.Opts.DatabaseMinConns(),
  106. config.Opts.DatabaseMaxConns(),
  107. )
  108. if err != nil {
  109. logger.Fatal("Unable to initialize database connection pool: %v", err)
  110. }
  111. defer db.Close()
  112. store := storage.NewStorage(db)
  113. if err := store.Ping(); err != nil {
  114. logger.Fatal("Unable to connect to the database: %v", err)
  115. }
  116. if flagMigrate {
  117. database.Migrate(db)
  118. return
  119. }
  120. if flagResetFeedErrors {
  121. store.ResetFeedErrors()
  122. return
  123. }
  124. if flagFlushSessions {
  125. flushSessions(store)
  126. return
  127. }
  128. if flagCreateAdmin {
  129. createAdmin(store)
  130. return
  131. }
  132. if flagResetPassword {
  133. resetPassword(store)
  134. return
  135. }
  136. // Run migrations and start the deamon.
  137. if config.Opts.RunMigrations() {
  138. if err := database.Migrate(db); err != nil {
  139. logger.Fatal(`%v`, err)
  140. }
  141. }
  142. if err := database.IsSchemaUpToDate(db); err != nil {
  143. logger.Fatal(`You must run the SQL migrations, %v`, err)
  144. }
  145. // Create admin user and start the deamon.
  146. if config.Opts.CreateAdmin() {
  147. createAdmin(store)
  148. }
  149. startDaemon(store)
  150. }