From 54d46ec04cdc1caec56d612a3441c477d0b609e8 Mon Sep 17 00:00:00 2001 From: cha0s Date: Tue, 1 Mar 2022 01:52:56 -0600 Subject: [PATCH] refactor: CLI --- packages/core/package.json | 1 + packages/core/src/cli.js | 16 +-- packages/core/src/server/commands.js | 59 ++++++--- packages/core/src/server/index.js | 2 + packages/core/src/server/stream.js | 57 ++++++++ packages/create-app/package.json | 6 +- packages/create-app/src/build.js | 9 ++ packages/create-app/src/cli.js | 66 ++++------ packages/create-app/src/move.js | 58 ++++++++ packages/create-app/src/server.js | 5 + packages/create-app/src/tree.js | 72 ++++++++++ ...gnore.extraneous => .gitignore.noconflict} | 0 .../create-app/template/.vscode/launch.json | 7 +- ...son.extraneous => package.json.noconflict} | 5 +- packages/create-fleck/package.json | 3 +- packages/create-fleck/src/cli.js | 124 +++++++----------- ...gnore.extraneous => .gitignore.noconflict} | 0 ...son.extraneous => package.json.noconflict} | 1 + packages/fleck/src/server/commands.js | 6 +- packages/http/src/server/index.js | 15 ++- 20 files changed, 349 insertions(+), 163 deletions(-) create mode 100644 packages/core/src/server/stream.js create mode 100644 packages/create-app/src/build.js create mode 100644 packages/create-app/src/move.js create mode 100644 packages/create-app/src/server.js create mode 100644 packages/create-app/src/tree.js rename packages/create-app/template/{.gitignore.extraneous => .gitignore.noconflict} (100%) rename packages/create-app/template/{package.json.extraneous => package.json.noconflict} (57%) rename packages/create-fleck/template/{.gitignore.extraneous => .gitignore.noconflict} (100%) rename packages/create-fleck/template/{package.json.extraneous => package.json.noconflict} (96%) diff --git a/packages/core/package.json b/packages/core/package.json index 8f5c2b8..5c87c78 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -65,6 +65,7 @@ "eslint": "^7.0.0", "eslint-import-resolver-webpack": "0.13.0", "js-yaml": "3.14.0", + "jsonparse": "^1.3.1", "lodash.flatten": "^4.4.0", "lodash.get": "^4.4.2", "lodash.intersection": "^4.4.0", diff --git a/packages/core/src/cli.js b/packages/core/src/cli.js index 5e7555c..56314be 100755 --- a/packages/core/src/cli.js +++ b/packages/core/src/cli.js @@ -4,6 +4,7 @@ import {join, resolve, sep} from 'path'; import {Command} from 'commander'; import D from './debug'; +import {processCode} from './server/commands'; import Flecks from './server/flecks'; const { @@ -63,17 +64,16 @@ else { process.exitCode = child; return; } - const reject = (error) => { + try { + const code = await processCode(child); + debug('action exited with code %d', code); + process.exitCode = code; + } + catch (error) { // eslint-disable-next-line no-console console.error(error); process.exitCode = child.exitCode || 1; - }; - child.on('error', reject); - child.on('exit', (code) => { - child.off('error', reject); - debug('action exited with code %d', code); - process.exitCode = code; - }); + } }; // Initialize Commander. const program = new Command(); diff --git a/packages/core/src/server/commands.js b/packages/core/src/server/commands.js index ffc3076..d5714ad 100644 --- a/packages/core/src/server/commands.js +++ b/packages/core/src/server/commands.js @@ -14,12 +14,23 @@ const { const debug = D('@flecks/core/commands'); const flecksRoot = normalize(FLECKS_CORE_ROOT); -export const spawnWith = (cmd, localEnv, spawnArgs) => { - debug('spawning:\n%s %s\nwith local environment: %O', cmd, spawnArgs.join(' '), localEnv); - const spawnOptions = { - env: {...localEnv, ...process.env}, - }; - const child = spawn('npx', [cmd, ...spawnArgs], spawnOptions); +export const processCode = (child) => new Promise((resolve, reject) => { + child.on('error', reject); + child.on('exit', (code) => { + child.off('error', reject); + resolve(code); + }); +}); + +export const spawnWith = (cmd, opts = {}) => { + debug("spawning: '%s' with options: %O", cmd.join(' '), opts); + const child = spawn(cmd[0], cmd.slice(1), { + ...opts, + env: { + ...process.env, + ...(opts.env || {}), + }, + }); child.stderr.pipe(process.stderr); child.stdout.pipe(process.stdout); return child; @@ -97,19 +108,24 @@ export default (program, flecks) => { } = opts; debug('Building...', opts); const webpackConfig = flecks.localConfig('webpack.config.js', '@flecks/core'); - const localEnv = { - ...targetNeutrinos(flecks), - ...(target ? {FLECKS_CORE_BUILD_LIST: target} : {}), - ...(hot ? {FLECKS_ENV_FLECKS_SERVER_hot: 'true'} : {}), - }; - const spawnArgs = [ + const cmd = [ + 'npx', 'webpack', '--colors', '--config', webpackConfig, '--mode', (production && !hot) ? 'production' : 'development', ...(verbose ? ['--stats', 'verbose'] : []), ...((watch || hot) ? ['--watch'] : []), ]; - return spawnWith('webpack', localEnv, spawnArgs); + return spawnWith( + cmd, + { + env: { + ...targetNeutrinos(flecks), + ...(target ? {FLECKS_CORE_BUILD_LIST: target} : {}), + ...(hot ? {FLECKS_ENV_FLECKS_SERVER_hot: 'true'} : {}), + }, + }, + ); }, }; commands.lint = { @@ -126,7 +142,8 @@ export default (program, flecks) => { continue; } process.env.FLECKS_CORE_BUILD_TARGET = target; - const spawnArgs = [ + const cmd = [ + 'npx', 'eslint', '--config', flecks.localConfig( `${target}.eslintrc.js`, '@flecks/core', @@ -136,12 +153,16 @@ export default (program, flecks) => { '--ext', 'js', '.', ]; - const localEnv = { - FLECKS_CORE_BUILD_TARGET: target, - ...targetNeutrinos(flecks), - }; promises.push(new Promise((resolve, reject) => { - const child = spawnWith('eslint', localEnv, spawnArgs); + const child = spawnWith( + cmd, + { + env: { + FLECKS_CORE_BUILD_TARGET: target, + ...targetNeutrinos(flecks), + }, + }, + ); child.on('error', reject); child.on('exit', (code) => { child.off('error', reject); diff --git a/packages/core/src/server/index.js b/packages/core/src/server/index.js index 57fba24..1970dda 100644 --- a/packages/core/src/server/index.js +++ b/packages/core/src/server/index.js @@ -6,6 +6,7 @@ import R from '../bootstrap/require'; export { default as commands, + processCode, spawnWith, targetNeutrino, targetNeutrinos, @@ -13,6 +14,7 @@ export { export {default as Flecks} from './flecks'; export {default as require} from '../bootstrap/require'; +export {JsonStream, transform} from './stream'; export default { [Hooks]: { diff --git a/packages/core/src/server/stream.js b/packages/core/src/server/stream.js new file mode 100644 index 0000000..3475ae5 --- /dev/null +++ b/packages/core/src/server/stream.js @@ -0,0 +1,57 @@ +// eslint-disable-next-line max-classes-per-file +import JsonParse from 'jsonparse'; +import {Transform} from 'stream'; + +export class JsonStream extends Transform { + + constructor() { + super(); + const self = this; + this.done = undefined; + this.parser = new JsonParse(); + this.parser.onValue = function onValue(O) { + if (0 === this.stack.length) { + self.push(JSON.stringify(O)); + self.done(); + } + }; + } + + // eslint-disable-next-line no-underscore-dangle + _transform(chunk, encoding, done) { + this.done = done; + this.parser.write(chunk); + } + +} + +JsonStream.PrettyPrint = class extends Transform { + + constructor(indent = 2) { + super(); + this.indent = indent; + } + + // eslint-disable-next-line no-underscore-dangle + async _transform(chunk, encoding, done) { + this.push(JSON.stringify(JSON.parse(chunk), null, this.indent)); + done(); + } + +}; + +export const transform = (fn, opts = {}) => { + class EasyTransform extends Transform { + + constructor() { + super(opts); + } + + // eslint-disable-next-line no-underscore-dangle, class-methods-use-this + _transform(chunk, encoding, done) { + fn(chunk, encoding, done, this); + } + + } + return new EasyTransform(); +}; diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 6e775da..31a295e 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -22,12 +22,16 @@ "files": [ "cli.js", "cli.js.map", + "server.js", + "server.js.map", "src", "template" ], "dependencies": { "@flecks/core": "^1.1.1", - "fs-extra": "10.0.0" + "glob": "^7.2.0", + "minimatch": "^5.0.1", + "validate-npm-package-name": "^3.0.0" }, "devDependencies": { "@flecks/fleck": "^1.1.1" diff --git a/packages/create-app/src/build.js b/packages/create-app/src/build.js new file mode 100644 index 0000000..8e7e07e --- /dev/null +++ b/packages/create-app/src/build.js @@ -0,0 +1,9 @@ +import {processCode, spawnWith} from '@flecks/core/server'; + +export default async (cwd) => { + const code = await processCode(spawnWith(['yarn'], {cwd})); + if (0 !== code) { + return code; + } + return processCode(spawnWith(['yarn', 'build'], {cwd})); +}; diff --git a/packages/create-app/src/cli.js b/packages/create-app/src/cli.js index bb2430e..b7cd898 100644 --- a/packages/create-app/src/cli.js +++ b/packages/create-app/src/cli.js @@ -1,50 +1,36 @@ -import {spawn} from 'child_process'; -import {readFileSync, writeFileSync} from 'fs'; import {join, normalize} from 'path'; -import { - copySync, - mkdirpSync, - moveSync, -} from 'fs-extra'; +import {Flecks} from '@flecks/core/server'; +import validate from 'validate-npm-package-name'; -const cwd = normalize(process.cwd()); +import build from './build'; +import move from './move'; -const forwardProcessCode = (fn) => async (...args) => { - process.exitCode = await fn(args.slice(0, -2)); -}; +const { + FLECKS_CORE_ROOT = process.cwd(), +} = process.env; -const processCode = (child) => new Promise((resolve, reject) => { - child.on('error', reject); - child.on('exit', (code) => { - child.off('error', reject); - resolve(code); - }); -}); +const cwd = normalize(FLECKS_CORE_ROOT); -const create = () => async () => { +const create = async (flecks) => { const name = process.argv[2]; - const path = name.split('/').pop(); - copySync(join(__dirname, 'template'), join(cwd, path), {recursive: true}); - mkdirpSync(join(cwd, path, 'packages')); - moveSync(join(cwd, path, '.gitignore.extraneous'), join(cwd, path, '.gitignore')); - moveSync(join(cwd, path, 'package.json.extraneous'), join(cwd, path, 'package.json')); - writeFileSync( - join(cwd, path, 'package.json'), - JSON.stringify( - { - name: `@${name}/monorepo`, - ...JSON.parse(readFileSync(join(cwd, path, 'package.json')).toString()), - }, - null, - 2, - ), - ); - const code = await processCode(spawn('yarn', [], {cwd: join(cwd, path), stdio: 'inherit'})); - if (0 !== code) { - return code; + const {errors} = validate(name); + if (errors) { + throw new Error(`@flecks/create-app: invalid app name: ${errors.join(', ')}`); } - return processCode(spawn('yarn', ['build'], {cwd: join(cwd, path), stdio: 'inherit'})); + const destination = join(cwd, name); + await move(name, join(__dirname, 'template'), destination, flecks); + await build(destination); }; -forwardProcessCode(create())(); +(async () => { + const flecks = await Flecks.bootstrap(); + try { + await create(flecks); + } + catch (error) { + // eslint-disable-next-line no-console + console.error(error.message); + process.exitCode = 1; + } +})(); diff --git a/packages/create-app/src/move.js b/packages/create-app/src/move.js new file mode 100644 index 0000000..9445591 --- /dev/null +++ b/packages/create-app/src/move.js @@ -0,0 +1,58 @@ +import { + stat, +} from 'fs/promises'; +import {basename} from 'path'; + +import {JsonStream, transform} from '@flecks/core/server'; + +import FileTree from './tree'; + +const testDestination = async (destination) => { + try { + await stat(destination); + return false; + } + catch (error) { + if ('ENOENT' !== error.code) { + throw error; + } + return true; + } +}; + +export default async (name, source, destination, flecks) => { + if (!await testDestination(destination)) { + const error = new Error( + `@flecks/create-fleck: destination '${destination} already exists: aborting`, + ); + error.code = 129; + throw error; + } + const fileTree = await FileTree.loadFrom(source); + // Renamed to avoid conflicts. + const {files} = fileTree; + fileTree.glob('**/*.noconflict') + .forEach((path) => { + files[basename(path, '.noconflict')] = files[path]; + delete files[path]; + }); + // Defaults. + flecks.set('@flecks/create-fleck.packager', flecks.get('@flecks/create-fleck.packager', ['...'])); + // Send it out. + await flecks.invokeSequentialAsync('@flecks/create-fleck/packager', fileTree); + // Add project name to `package.json`. + fileTree.pipe( + 'package.json', + transform((chunk, encoding, done, stream) => { + stream.push(JSON.stringify({name, ...JSON.parse(chunk)})); + done(); + }), + ); + // Pretty print all JSON. + fileTree.glob('**/*.json') + .forEach((path) => { + fileTree.pipe(path, new JsonStream.PrettyPrint()); + }); + // Write the tree. + await fileTree.writeTo(destination); +}; diff --git a/packages/create-app/src/server.js b/packages/create-app/src/server.js new file mode 100644 index 0000000..133ecec --- /dev/null +++ b/packages/create-app/src/server.js @@ -0,0 +1,5 @@ +export {default as validate} from 'validate-npm-package-name'; + +export {default as build} from './build'; +export {default as move} from './move'; +export {default as FileTree} from './tree'; diff --git a/packages/create-app/src/tree.js b/packages/create-app/src/tree.js new file mode 100644 index 0000000..3be5b49 --- /dev/null +++ b/packages/create-app/src/tree.js @@ -0,0 +1,72 @@ +import {createReadStream, createWriteStream} from 'fs'; +import {mkdir, stat} from 'fs/promises'; + +import glob from 'glob'; +import minimatch from 'minimatch'; +import {dirname, join} from 'path'; + +export default class FileTree { + + constructor(files = {}) { + this.files = files; + } + + addDirectory(path) { + this.files[path] = null; + } + + addFile(path, stream) { + this.files[path] = stream; + } + + glob(glob) { + return Object.keys(this.files).filter((path) => minimatch(path, glob, {dot: true})); + } + + static async loadFrom(cwd) { + const paths = await new Promise((r, e) => { + glob( + '**/*', + {cwd, dot: true}, + (error, paths) => (error ? e(error) : r(paths)), + ); + }); + return new FileTree( + await paths + .reduce( + async (r, path) => { + const origin = join(cwd, path); + const stats = await stat(origin); + return { + ...await r, + [path]: stats.isDirectory() ? null : createReadStream(origin), + }; + }, + {}, + ), + ); + } + + pipe(path, stream) { + this.files[path] = this.files[path] ? this.files[path].pipe(stream) : undefined; + } + + async writeTo(destination) { + return Promise.all( + Object.entries(this.files) + .map(async ([path, stream]) => { + if (null === stream) { + return mkdir(path, {recursive: true}); + } + await mkdir(dirname(join(destination, path)), {recursive: true}); + return new Promise((resolve, reject) => { + const writer = createWriteStream(join(destination, path)); + writer.on('finish', resolve); + writer.on('error', reject); + stream.pipe(writer); + }); + }), + ); + } + +} diff --git a/packages/create-app/template/.gitignore.extraneous b/packages/create-app/template/.gitignore.noconflict similarity index 100% rename from packages/create-app/template/.gitignore.extraneous rename to packages/create-app/template/.gitignore.noconflict diff --git a/packages/create-app/template/.vscode/launch.json b/packages/create-app/template/.vscode/launch.json index 873d48c..fab575a 100644 --- a/packages/create-app/template/.vscode/launch.json +++ b/packages/create-app/template/.vscode/launch.json @@ -1,7 +1,4 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { @@ -14,11 +11,11 @@ "resolveSourceMapLocations": [], "sourceMapPathOverrides": { "webpack:///*": "${workspaceFolder}/*", - "webpack://*": "node_modules/*", + "webpack://*": "node_modules/*" }, "cwd": "${workspaceFolder}", "runtimeExecutable": "npm", - "runtimeArgs": ["run", "start"], + "runtimeArgs": ["run", "start"] } ] } \ No newline at end of file diff --git a/packages/create-app/template/package.json.extraneous b/packages/create-app/template/package.json.noconflict similarity index 57% rename from packages/create-app/template/package.json.extraneous rename to packages/create-app/template/package.json.noconflict index 9005974..92fe34b 100644 --- a/packages/create-app/template/package.json.extraneous +++ b/packages/create-app/template/package.json.noconflict @@ -2,7 +2,10 @@ "private": true, "scripts": { "build": "flecks build", - "dev": "npm run -- build -h" + "debug": "DEBUG=*,-babel* npm run dev", + "dev": "npm run -- build -h", + "repl": "npx flecks repl --rlwrap", + "start": "DEBUG=@flecks*,-@flecks/core/flecks* npm run dev", }, "dependencies": { "@flecks/core": "^1.0.0", diff --git a/packages/create-fleck/package.json b/packages/create-fleck/package.json index 7af1ccb..5420119 100644 --- a/packages/create-fleck/package.json +++ b/packages/create-fleck/package.json @@ -27,8 +27,7 @@ ], "dependencies": { "@flecks/core": "^1.1.1", - "fs-extra": "10.0.0", - "validate-npm-package-name": "^3.0.0" + "@flecks/create-app": "^1.1.1" }, "devDependencies": { "@flecks/fleck": "^1.1.1" diff --git a/packages/create-fleck/src/cli.js b/packages/create-fleck/src/cli.js index 6e1401d..213ef22 100644 --- a/packages/create-fleck/src/cli.js +++ b/packages/create-fleck/src/cli.js @@ -1,13 +1,8 @@ -import {spawn} from 'child_process'; -import { - readFileSync, - statSync, - writeFileSync, -} from 'fs'; +import {stat} from 'fs/promises'; import {join, normalize} from 'path'; -import {copySync, moveSync} from 'fs-extra'; -import validate from 'validate-npm-package-name'; +import {build, move, validate} from '@flecks/create-app/server'; +import {Flecks} from '@flecks/core/server'; const { FLECKS_CORE_ROOT = process.cwd(), @@ -15,97 +10,68 @@ const { const cwd = normalize(FLECKS_CORE_ROOT); -const forwardProcessCode = (fn) => async (...args) => { - process.exitCode = await fn(args.slice(0, -2)); +const hasPackages = async (cwd) => { + try { + await stat(join(cwd, 'packages')); + return true; + } + catch (error) { + if ('ENOENT' !== error.code) { + throw error; + } + return false; + } }; -const processCode = (child) => new Promise((resolve, reject) => { - child.on('error', reject); - child.on('exit', (code) => { - child.off('error', reject); - resolve(code); - }); -}); - -const monorepoScope = () => { +const monorepoScope = async (cwd) => { try { - statSync(join(cwd, 'packages')); const {name} = __non_webpack_require__(join(cwd, 'package.json')); const [scope] = name.split('/'); return scope; } catch (error) { - if ('ENOENT' !== error.code) { + if ('MODULE_NOT_FOUND' !== error.code) { throw error; } return undefined; } }; -const testDestination = (destination) => { - try { - statSync(destination); - return false; - } - catch (error) { - if ('ENOENT' !== error.code) { - throw error; - } - return true; - } -}; - -const create = () => async () => { - const rawname = process.argv[2]; - const {errors} = validate(rawname); +const target = async (name) => { + const {errors} = validate(name); if (errors) { - // eslint-disable-next-line no-console - console.error(`@flecks/create-fleck: invalid fleck name: ${errors.join(', ')}`); - return 128; + throw new Error(`@flecks/create-fleck: invalid fleck name: ${errors.join(', ')}`); } - const parts = rawname.split('/'); - let path = cwd; + const parts = name.split('/'); let pkg; let scope; if (1 === parts.length) { - pkg = rawname; - } - else { - [scope, pkg] = parts; - } - if (!scope) { - scope = monorepoScope(); - if (scope) { - path = join(path, 'packages'); + pkg = name; + if (await hasPackages(cwd)) { + scope = await monorepoScope(cwd); } + return [scope, pkg]; } - const name = [scope, pkg].filter((e) => !!e).join('/'); - const destination = join(path, pkg); - if (!testDestination(destination)) { - // eslint-disable-next-line no-console - console.error(`@flecks/create-fleck: destination '${destination} already exists: aborting`); - return 129; - } - // eslint-disable-next-line no-unreachable - copySync(join(__dirname, 'template'), destination, {recursive: true}); - moveSync(join(destination, '.gitignore.extraneous'), join(destination, '.gitignore')); - moveSync(join(destination, 'package.json.extraneous'), join(destination, 'package.json')); - writeFileSync( - join(destination, 'package.json'), - JSON.stringify( - { - name, - ...JSON.parse(readFileSync(join(destination, 'package.json')).toString()), - }, - null, - 2, - ), - ); - const code = await processCode(spawn('yarn', [], {cwd: destination, stdio: 'inherit'})); - if (0 !== code) { - return code; - } - return processCode(spawn('yarn', ['build'], {cwd: destination, stdio: 'inherit'})); + return parts; }; -forwardProcessCode(create())(); +const create = async (flecks) => { + const [scope, pkg] = await target(process.argv[2]); + const path = scope && (await hasPackages(cwd)) ? join(cwd, 'packages') : cwd; + const name = [scope, pkg].filter((e) => !!e).join('/'); + const destination = join(path, pkg); + await move(name, join(__dirname, 'template'), destination, flecks); + await build(destination); +}; + +(async () => { + const flecks = await Flecks.bootstrap(); + try { + await create(flecks); + } + catch (error) { + // eslint-disable-next-line no-console + console.error(error.message); + process.exitCode = 1; + } +})(); diff --git a/packages/create-fleck/template/.gitignore.extraneous b/packages/create-fleck/template/.gitignore.noconflict similarity index 100% rename from packages/create-fleck/template/.gitignore.extraneous rename to packages/create-fleck/template/.gitignore.noconflict diff --git a/packages/create-fleck/template/package.json.extraneous b/packages/create-fleck/template/package.json.noconflict similarity index 96% rename from packages/create-fleck/template/package.json.extraneous rename to packages/create-fleck/template/package.json.noconflict index 4744766..20ddac5 100644 --- a/packages/create-fleck/template/package.json.extraneous +++ b/packages/create-fleck/template/package.json.noconflict @@ -8,6 +8,7 @@ "test": "flecks test" }, "files": [ + "build", "index.js", "index.js.map", "src", diff --git a/packages/fleck/src/server/commands.js b/packages/fleck/src/server/commands.js index 180f70e..96c7663 100644 --- a/packages/fleck/src/server/commands.js +++ b/packages/fleck/src/server/commands.js @@ -55,13 +55,13 @@ export default (program, flecks) => { } } const spawnMocha = () => { - const localEnv = {}; - const spawnArgs = [ + const cmd = [ + 'npx', 'mocha', '--colors', '--reporter', 'min', testLocation, ]; - return spawnWith('mocha', localEnv, spawnArgs); + return spawnWith(cmd); }; if (!watch) { await new Promise((resolve, reject) => { diff --git a/packages/http/src/server/index.js b/packages/http/src/server/index.js index 276f6a7..15aee52 100644 --- a/packages/http/src/server/index.js +++ b/packages/http/src/server/index.js @@ -18,15 +18,20 @@ export default { return; } // Otherwise, spawn `webpack-dev-server` (WDS). - const localEnv = { - FLECKS_CORE_BUILD_LIST: 'http', - }; - const spawnArgs = [ + const cmd = [ + 'npx', 'webpack-dev-server', '--mode', 'development', '--hot', '--config', flecks.localConfig('webpack.config.js', '@flecks/core'), ]; - spawnWith('webpack-dev-server', localEnv, spawnArgs); + spawnWith( + cmd, + { + env: { + FLECKS_CORE_BUILD_LIST: 'http', + }, + }, + ); // Remove the build config since we're handing off to WDS. // eslint-disable-next-line no-param-reassign delete neutrinoConfigs.http;