gancio-upstream/server/cli.js

250 lines
6.5 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
2019-07-03 16:58:24 +02:00
process.env.NODE_ENV = 'production'
2019-06-25 01:05:38 +02:00
2019-07-03 16:58:24 +02:00
const fs = require('fs')
const consola = require('consola')
const sequelize = require('sequelize')
const inquirer = require('inquirer')
const package = require('../package.json')
const firstrun = require('./firstrun')
2019-07-03 16:58:24 +02:00
const path = require('path')
2019-08-05 01:23:02 +02:00
const mkdirp = require('mkdirp')
2019-07-03 16:58:24 +02:00
const cwd = process.cwd()
// needed by nuxt
process.chdir(path.resolve(__dirname, '..'))
2019-06-26 14:44:21 +02:00
function notEmpty (value) {
return value.length>0
}
2019-08-06 01:12:05 +02:00
async function setupQuestionnaire(is_docker, db) {
const questions = []
2019-07-03 16:58:24 +02:00
questions.push({
name: 'title',
message: 'Name of your instance',
default: 'Gancio',
validate: notEmpty
})
questions.push({
message: 'Specify a baseurl for this gancio installation! (eg. http://gancio.cisti.org)',
name: 'baseurl',
2019-07-03 16:58:24 +02:00
default: 'http://localhost:13120',
2019-06-26 14:44:21 +02:00
validate: notEmpty
})
questions.push({
name: 'server.host',
message: 'address to listen to',
2019-08-05 01:23:02 +02:00
default: is_docker ? '0.0.0.0' : 'localhost',
2019-06-26 14:44:21 +02:00
validate: notEmpty
})
questions.push({
name: 'server.port',
message: 'port to listen to',
default: 13120,
})
questions.push({
name: 'db.dialect',
message: 'DB dialect',
type: 'list',
2019-08-06 01:12:05 +02:00
when: answers => !db,
choices: ['sqlite', 'postgres']
})
questions.push({
name: 'db.storage',
message: 'sqlite db path',
2019-08-05 01:23:02 +02:00
default: is_docker ? '/opt/gancio/db.sqlite' : './db.sqlite',
2019-06-26 15:56:27 +02:00
filter: p => path.resolve(cwd, p),
2019-08-06 01:12:05 +02:00
when: answers => (db && db==='sqlite') || (answers.db && answers.db.dialect === 'sqlite'),
validate: db_path => db_path.length>0 && fs.existsSync(path.dirname(db_path))
})
questions.push({
2019-06-26 14:44:21 +02:00
name: 'db.host',
message: 'Postgres host',
2019-08-05 01:23:02 +02:00
default: is_docker ? 'db' : 'localhost',
2019-08-06 01:12:05 +02:00
when: answers => (db && db==='postgresql') || (answers.db && answers.db.dialect === 'postgres'),
2019-06-26 14:44:21 +02:00
validate: notEmpty
})
questions.push({
name: 'db.database',
message: 'DB name',
default: 'gancio',
2019-08-06 01:12:05 +02:00
when: answers => (db && db==='postgresql') || (answers.db && answers.db.dialect === 'postgres'),
2019-06-26 14:44:21 +02:00
validate: notEmpty
})
questions.push({
name: 'db.username',
message: 'DB user',
default: 'gancio',
2019-08-06 01:12:05 +02:00
when: answers => (db && db==='postgresql') || (answers.db && answers.db.dialect === 'postgres'),
2019-06-26 14:44:21 +02:00
validate: notEmpty
})
questions.push({
2019-06-26 14:44:21 +02:00
name: 'db.password',
type: 'password',
2019-06-26 14:44:21 +02:00
message: 'DB password',
default: 'gancio',
2019-08-06 01:12:05 +02:00
when: answers => (db && db==='postgresql') || (answers.db && answers.db.dialect === 'postgres'),
validate: async (password, options) => {
try {
2019-06-26 14:44:21 +02:00
const db = new sequelize({ ...options.db, dialect: 'postgres' , password, logging: false })
return db.authenticate().then( () => {
2019-07-03 16:58:24 +02:00
db.close()
return true
})
} catch(e) {
consola.error(e)
return false
}
}
})
questions.push({
name: 'upload_path',
message: 'Where gancio has to store media?',
2019-08-06 01:12:05 +02:00
default: is_docker ? '/opt/gancio/uploads' : './uploads',
when: answers => !is_docker,
2019-06-26 15:56:27 +02:00
filter: p => path.resolve(cwd, p),
2019-08-05 01:23:02 +02:00
validate: async p => {
let exists = fs.existsSync(p)
if (!exists) {
consola.warn(`"${p}" does not exists, trying to create it`)
try {
mkdirp.sync(p)
} catch(e) {
console.error(String(e))
return false
}
}
return true
}
})
questions.push({
name: 'admin.email',
message: `Admin email (a first user with this username will be created)`,
2019-06-26 14:44:21 +02:00
validate: notEmpty
})
questions.push({
name: 'admin.password',
message: 'Admin password',
type: 'password',
2019-06-26 14:44:21 +02:00
validate: notEmpty
})
questions.push({
name: 'smtp.host',
message: 'SMTP Host',
validate: notEmpty,
})
questions.push({
name: 'smtp.auth.user',
message: 'SMTP User',
validate: notEmpty,
default: options => options.admin.email
})
questions.push({
name: 'smtp.auth.pass',
message: 'SMTP Password',
type: 'password',
validate: notEmpty,
})
const answers = await inquirer.prompt(questions)
return answers
}
2019-08-04 23:32:45 +02:00
async function upgrade (options) {
const Umzug = require('umzug')
const Sequelize = require('sequelize')
const config = require('config')
const db = new Sequelize(config.db)
const umzug = new Umzug({
storage: 'sequelize',
storageOptions: { sequelize: db },
migrations: {
wrap: fun => {
return () => fun(db.queryInterface, Sequelize).catch(() => false)
},
path: path.resolve(__dirname, 'migrations')
}
})
const migrations = await umzug.up()
db.close()
}
2019-07-03 16:58:24 +02:00
async function start (options) {
// is first run?
if (firstrun.check(options.config)) {
2019-08-05 01:23:02 +02:00
if (options.docker) {
consola.error('Something goes wrong, did you run "docker-compose run --rm gancio gancio setup"')
process.exit(-1)
}
2019-08-03 15:32:39 +02:00
consola.error(`Configuration file "${options.config}" not found! Use "--config <CONFIG_FILE.json>" to specify another path.
If this is your first run use 'gancio setup --config <CONFIG_FILE.json>' `)
process.exit(-1)
}
2019-08-04 23:32:45 +02:00
await upgrade(options)
2019-07-03 16:58:24 +02:00
require('./index')
}
async function setup (options) {
consola.info(`You're going to setup gancio on this machine.`)
2019-08-06 01:12:05 +02:00
const config = await setupQuestionnaire(options.docker, options.db)
const ret = await firstrun.setup(config, options.config)
if (!ret) process.exit(-1)
2019-08-05 01:41:35 +02:00
if (options.docker) {
consola.info(`You can edit ./config.json to modify your configuration.`)
consola.info(`Start the server with "docker-compose up"`)
} else {
consola.info(`You can edit '${options.config}' to modify your configuration. `)
consola.info(`Start the server with "gancio --config ${options.config}"`)
}
2019-07-29 22:40:27 +02:00
process.exit(0)
2019-07-03 16:58:24 +02:00
}
2019-07-03 16:58:24 +02:00
consola.info(`${package.name} - v${package.version} - ${package.description}`)
require('yargs')
.usage('Usage $0 <command> [options]')
2019-08-05 01:23:02 +02:00
.option('docker', {
alias: 'd',
describe: 'Inside docker',
default: false,
type: 'boolean'
})
2019-08-06 01:12:05 +02:00
.option('db', {
describe: 'Specify db type',
})
2019-08-05 01:23:02 +02:00
.option('config', {
2019-07-03 16:58:24 +02:00
alias: 'c',
describe: 'Configuration file',
2019-07-26 23:52:18 +02:00
default: '/opt/gancio/config.json',
2019-07-03 16:58:24 +02:00
})
.coerce('config', config_path => {
const absolute_config_path = path.resolve(cwd, config_path)
process.env.config_path = absolute_config_path
return absolute_config_path
})
.command(['start', 'run', '$0'], 'Start gancio', {}, start)
.command('setup', 'Setup a new instance', {}, setup)
.help('h')
.alias('h', 'help')
2019-08-03 15:32:39 +02:00
.epilog('Made with ❤ by underscore hacklab - https://gancio.org')
2019-07-03 16:58:24 +02:00
.argv