diff --git a/package.json b/package.json index a98d6ecf..a6cb9af5 100644 --- a/package.json +++ b/package.json @@ -135,6 +135,7 @@ "jaguar": "^6.0.0", "jju": "^1.3.0", "jonny": "^3.0.0", + "just-snake-case": "^1.1.0", "markdown-it": "^11.0.0", "mellow": "^2.0.0", "minimist": "^1.2.0", diff --git a/server/distribute/import.js b/server/distribute/import.js index 792114e1..e6aac17d 100644 --- a/server/distribute/import.js +++ b/server/distribute/import.js @@ -9,6 +9,7 @@ const io = require('socket.io-client'); const forEachKey = currify(require('for-each-key')); const log = require('./log'); +const env = require('../env'); const { importStr, @@ -23,6 +24,8 @@ const { logWraped, } = log; +const {entries} = Object; + const equal = (a, b) => `${a}=${b}`; const append = currify((obj, a, b) => obj.value += b && equal(a, b) + '&'); const wrapApply = (f, disconnect) => (status) => () => f(null, { @@ -62,6 +65,16 @@ const emitAuth = wraptile((importUrl, config, socket) => { socket.emit('auth', config('importToken')); }); +const updateConfig = currify((config, data) => { + for (const [key, value] of entries(data)) { + if (typeof env(key) !== 'undefined') { + continue; + } + + config(key, value); + } +}); + module.exports = (config, options, fn) => { fn = fn || options; @@ -96,7 +109,7 @@ module.exports = (config, options, fn) => { close, logWraped(isLog, importStr, `config received from ${colorUrl}`), statusStoreWraped('received'), - forEachKey(config), + updateConfig(config), ); const onError = squad( diff --git a/server/distribute/import.spec.js b/server/distribute/import.spec.js index 51f82de1..71d3f461 100644 --- a/server/distribute/import.spec.js +++ b/server/distribute/import.spec.js @@ -3,14 +3,18 @@ const test = require('supertape'); const {promisify} = require('util'); const tryToCatch = require('try-to-catch'); + const {connect} = require('../../test/before'); const {createConfigManager} = require('../cloudcmd'); + const distribute = { import: promisify(require('./import')), }; const config = createConfigManager(); +process.on('unhandledRejection', console.log); + test('distribute: import: canceled', async (t) => { const {done} = await connect({ config: { @@ -189,5 +193,95 @@ test('distribute: import: config:change: no export', async (t) => { t.end(); }); -process.on('unhandledRejection', console.log); +test('distribute: import: env', async (t) => { + const configManager = createConfigManager(); + const configManagerImport = createConfigManager(); + + const exporter = await connect({ + configManager, + config: { + name: 'bill', + import: false, + importListen: false, + export: true, + exportToken: 'a', + log: false, + editor: 'edward', + }, + }); + + const importer = await connect({ + configManager: configManagerImport, + config: { + name: 'jack', + import: true, + importToken: 'a', + export: false, + importListen: false, + log: false, + editor: 'deepword', + }, + }); + + const {cloudcmd_editor} = process.env; + process.env.cloudcmd_editor = 'some editor'; + + configManagerImport('importUrl', `http://localhost:${exporter.port}`); + + await distribute.import(configManagerImport); + + await importer.done(); + await exporter.done(); + + process.env.cloudcmd_editor = cloudcmd_editor; + + const result = configManagerImport('editor'); + const expected = 'deepword'; + + t.equal(expected, result); + t.end(); +}); +test('distribute: import: no env', async (t) => { + const configManager = createConfigManager(); + const configManagerImport = createConfigManager(); + + const exporter = await connect({ + configManager, + config: { + name: 'bill', + import: false, + importListen: false, + export: true, + exportToken: 'a', + log: false, + editor: 'edward', + }, + }); + + const importer = await connect({ + configManager: configManagerImport, + config: { + name: 'jack', + import: true, + importToken: 'a', + export: false, + importListen: false, + log: false, + editor: 'deepword', + }, + }); + + configManagerImport('importUrl', `http://localhost:${exporter.port}`); + + await distribute.import(configManagerImport); + + await importer.done(); + await exporter.done(); + + const result = configManagerImport('editor'); + const expected = 'edward'; + + t.equal(expected, result); + t.end(); +}); diff --git a/server/env.js b/server/env.js index 2a601481..d53e3e48 100644 --- a/server/env.js +++ b/server/env.js @@ -1,5 +1,7 @@ 'use strict'; +const snake = require('just-snake-case'); + const {env} = process; const up = (a) => a.toUpperCase(); @@ -15,7 +17,7 @@ module.exports.bool = (name) => { }; function parse(name) { - const small = `cloudcmd_${name}`; + const small = `cloudcmd_${snake(name)}`; const big = up(small); return env[big] || env[small]; diff --git a/server/env.spec.js b/server/env.spec.js index 2e040e90..e090f45a 100644 --- a/server/env.spec.js +++ b/server/env.spec.js @@ -21,3 +21,11 @@ test('cloudcmd: server: env: bool: upper case first', (t) => { t.end(); }); +test('cloudcmd: server: env: bool: snake_case', (t) => { + process.env.cloudcmd_config_auth = 'true'; + + const result = env.bool('configAuth'); + + t.ok(result); + t.end(); +});