Repository: jhipster/generator-jhipster
Pull request #10024 (2019-07-02 22:39:25)

Update NPM version to 6.9.2
-   Please make sure the below checklist is followed for Pull Requests.

-   [x] [Travis tests](https://travis-ci.org/jhipster/generator-jhipster/pull_requests) are green
-   [x] Tests are added where necessary
-   [x] Documentation is added/updated where necessary
-   [x] Coding Rules & Commit Guidelines as per our [CONTRIBUTING.md document](https://github.com/jhipster/generator-jhipster/blob/master/CONTRIBUTING.md) are followed

<!--
Please also reference the issue number in a commit message to [automatically close the related Github issue](https://help.github.com/articles/closing-issues-via-commit-messages/)

Note: It is also possible to add `[skip ci]` to your commit message to skip Travis tests
-->



Patch:
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 27ad37a22c..7efb418ba1 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,2 +1,2 @@
 open_collective: generator-jhipster
-custom: https://www.jhipster.tech/sponsors/
+custom: https://www.jhipster.tech/sponsors/
\ No newline at end of file
diff --git a/cli/commands.js b/cli/commands.js
index cd8952375e..711096f45a 100644
--- a/cli/commands.js
+++ b/cli/commands.js
@@ -19,37 +19,20 @@
 const chalk = require('chalk');
 const jhipsterUtils = require('../generators/utils');
 
-const customCommands = loadBlueprintCommands();
+let customCommands = {};
+const indexOfBlueprintArgv = process.argv.indexOf('--blueprint');
+if (indexOfBlueprintArgv > -1) {
+    /* eslint-disable import/no-dynamic-require */
+    /* eslint-disable global-require */
 
-function loadBlueprintCommands() {
-    const blueprintNames = [];
-    const indexOfBlueprintArgv = process.argv.indexOf('--blueprint');
-    if (indexOfBlueprintArgv > -1) {
-        blueprintNames.push(process.argv[indexOfBlueprintArgv + 1]);
+    const blueprint = jhipsterUtils.normalizeBlueprintName(process.argv[indexOfBlueprintArgv + 1]);
+    try {
+        customCommands = require(`${blueprint}/cli/commands`);
+    } catch (e) {
+        const msg = `No custom command found within blueprint: ${blueprint}`;
+        /* eslint-disable no-console */
+        console.info(`${chalk.green.bold('INFO!')} ${msg}`);
     }
-    const indexOfBlueprintsArgv = process.argv.indexOf('--blueprints');
-    if (indexOfBlueprintsArgv > -1) {
-        blueprintNames.push(...process.argv[indexOfBlueprintsArgv + 1].split(','));
-    }
-    let result = {};
-    if (blueprintNames.length > 0) {
-        blueprintNames
-            .filter((v, i, a) => a.indexOf(v) === i)
-            .map(v => jhipsterUtils.normalizeBlueprintName(v))
-            .forEach(blueprint => {
-                /* eslint-disable import/no-dynamic-require */
-                /* eslint-disable global-require */
-                try {
-                    const blueprintCommands = require(`${blueprint}/cli/commands`);
-                    result = { ...result, ...blueprintCommands };
-                } catch (e) {
-                    const msg = `No custom commands found within blueprint: ${blueprint}`;
-                    /* eslint-disable no-console */
-                    console.info(`${chalk.green.bold('INFO!')} ${msg}`);
-                }
-            });
-    }
-    return result;
 }
 
 const defaultCommands = {
diff --git a/generators/app/index.js b/generators/app/index.js
index 8a420c5e58..f5fb9937e6 100644
--- a/generators/app/index.js
+++ b/generators/app/index.js
@@ -156,15 +156,9 @@ module.exports = class extends BaseGenerator {
             type: String
         });
 
-        // NOTE: Deprecated!!! Use --blueprints instead
+        // This adds support for a `--blueprint` flag which can be used to specify a blueprint to use for generation
         this.option('blueprint', {
-            desc: 'DEPRECATED: Specify a generator blueprint to use for the sub generators',
-            type: String
-        });
-        // This adds support for a `--blueprints` flag which can be used to specify one or more blueprints to use for generation
-        this.option('blueprints', {
-            desc:
-                'A comma separated list of one or more generator blueprints to use for the sub generators, e.g. --blueprints kotlin,vuejs',
+            desc: 'Specify a generator blueprint to use for the sub generators',
             type: String
         });
 
@@ -195,24 +189,8 @@ module.exports = class extends BaseGenerator {
 
         this.withEntities = this.options['with-entities'];
         this.skipChecks = this.options['skip-checks'];
-
-        let blueprints = this.options.blueprints || '';
-        // check for old single blueprint declaration
-        const blueprint = this.options.blueprint;
-        if (blueprint) {
-            this.warning('--blueprint option is deprecated. Please use --blueprints instead');
-            if (!blueprints.split(',').includes(blueprint)) {
-                blueprints = `${blueprint},${blueprints}`;
-            }
-        }
-        if (blueprints) {
-            blueprints = jhipsterUtils.parseBluePrints(blueprints);
-        } else {
-            blueprints = jhipsterUtils.loadBlueprintsFromConfiguration(this);
-        }
-
-        this.blueprints = this.configOptions.blueprints = blueprints;
-
+        const blueprint = jhipsterUtils.normalizeBlueprintName(this.options.blueprint || this.config.get('blueprint'));
+        this.blueprint = this.configOptions.blueprint = blueprint;
         this.useNpm = this.configOptions.useNpm = !this.options.yarn;
         this.useYarn = !this.useNpm;
 
@@ -232,8 +210,8 @@ module.exports = class extends BaseGenerator {
             },
 
             validateBlueprint() {
-                if (this.blueprints && !this.skipChecks) {
-                    this.blueprints.forEach(e => this.checkBlueprint(e));
+                if (this.blueprint && !this.skipChecks) {
+                    this.checkBlueprint(this.blueprint);
                 }
             },
 
@@ -276,14 +254,11 @@ module.exports = class extends BaseGenerator {
                     this.jhipsterVersion = this.config.get('jhipsterVersion');
                 }
                 this.otherModules = this.config.get('otherModules') || [];
-                if (this.blueprints && this.blueprints.length > 0) {
-                    this.blueprints.forEach(blueprint => {
-                        blueprint.version = this.findBlueprintVersion(blueprint.name) || 'latest';
-                    });
-
+                if (this.blueprint) {
+                    this.blueprintVersion = this.findBlueprintVersion(this.blueprint);
                     // Remove potential previous value to avoid duplicates
-                    this.otherModules = this.otherModules.filter(module => this.blueprints.findIndex(bp => bp.name === module.name) === -1);
-                    this.otherModules.push(...this.blueprints);
+                    this.otherModules = this.otherModules.filter(module => module.name !== this.blueprint);
+                    this.otherModules.push({ name: this.blueprint, version: this.blueprintVersion || 'latest' });
                 }
                 this.testFrameworks = this.config.get('testFrameworks');
                 this.enableTranslation = this.config.get('enableTranslation');
@@ -434,7 +409,7 @@ module.exports = class extends BaseGenerator {
                     config.nativeLanguage = this.nativeLanguage;
                     config.languages = this.languages;
                 }
-                this.blueprints && (config.blueprints = this.blueprints);
+                this.blueprint && (config.blueprint = this.blueprint);
                 this.blueprintVersion && (config.blueprintVersion = this.blueprintVersion);
                 this.reactive && (config.reactive = this.reactive);
                 this.skipClient && (config.skipClient = true);
@@ -517,11 +492,11 @@ module.exports = class extends BaseGenerator {
                         if (code === 0 && this.gitInitialized) {
                             this.gitExec('add -A', { trace: false }, () => {
                                 let commitMsg = `Initial application generated by JHipster-${this.jhipsterVersion}`;
-                                if (this.blueprints && this.blueprints.length > 0) {
-                                    const bpInfo = this.blueprints
-                                        .map(bp => `${bp.name.replace('generator-jhipster-', '')}-${bp.version}`)
-                                        .join(', ');
-                                    commitMsg += ` with blueprints: ${bpInfo}`;
+                                if (this.blueprint) {
+                                    commitMsg += ` with blueprint: ${this.blueprint.replace('generator-jhipster-', '')}`;
+                                    if (this.blueprintVersion) {
+                                        commitMsg += `-${this.blueprintVersion}`;
+                                    }
                                 }
                                 this.gitExec(`commit -am "${commitMsg}"`, { trace: false }, () => {
                                     this.log(chalk.green.bold('Application successfully committed to Git.'));
diff --git a/generators/cleanup.js b/generators/cleanup.js
index 33bf41b9ae..d629760f28 100644
--- a/generators/cleanup.js
+++ b/generators/cleanup.js
@@ -190,8 +190,4 @@ function cleanupOldServerFiles(generator, javaDir, testDir, mainResourceDir, tes
         generator.removeFolder(`${CLIENT_MAIN_SRC_DIR}app/shared/layout/header/menus`);
         generator.removeFolder(`${CLIENT_TEST_SRC_DIR}spec/app/shared/layout/header/menus`);
     }
-    if (generator.isJhipsterVersionLessThan('6.1.0')) {
-        generator.config.delete('blueprint');
-        generator.config.delete('blueprintVersion');
-    }
 }
diff --git a/generators/client/index.js b/generators/client/index.js
index fbe8f50a5b..72ef33a091 100644
--- a/generators/client/index.js
+++ b/generators/client/index.js
@@ -27,7 +27,7 @@ const packagejs = require('../../package.json');
 const constants = require('../generator-constants');
 const statistics = require('../statistics');
 
-let useBlueprints;
+let useBlueprint;
 
 module.exports = class extends BaseBlueprintGenerator {
     constructor(args, opts) {
@@ -62,8 +62,16 @@ module.exports = class extends BaseBlueprintGenerator {
         });
 
         this.setupClientOptions(this);
-
-        useBlueprints = !opts.fromBlueprint && this.instantiateBlueprints('client');
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        // use global variable since getters dont have access to instance property
+        if (!opts.fromBlueprint) {
+            useBlueprint = this.composeBlueprint(blueprint, 'client', {
+                ...this.options,
+                configOptions: this.configOptions
+            });
+        } else {
+            useBlueprint = false;
+        }
     }
 
     // Public API method used by the getter and also by Blueprints
@@ -170,7 +178,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get initializing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._initializing();
     }
 
@@ -193,7 +201,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get prompting() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._prompting();
     }
 
@@ -265,7 +273,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get configuring() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._configuring();
     }
 
@@ -349,7 +357,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get default() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._default();
     }
 
@@ -360,16 +368,16 @@ module.exports = class extends BaseBlueprintGenerator {
                 if (this.skipClient) return;
                 switch (this.clientFramework) {
                     case 'react':
-                        return writeReactFiles.call(this, useBlueprints);
+                        return writeReactFiles.call(this, useBlueprint);
                     default:
-                        return writeAngularFiles.call(this, useBlueprints);
+                        return writeAngularFiles.call(this, useBlueprint);
                 }
             }
         };
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 
@@ -401,7 +409,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get install() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._install();
     }
 
@@ -423,7 +431,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get end() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._end();
     }
 };
diff --git a/generators/common/index.js b/generators/common/index.js
index 93f2a8f3c9..5819d3b345 100644
--- a/generators/common/index.js
+++ b/generators/common/index.js
@@ -22,7 +22,7 @@ const writeFiles = require('./files').writeFiles;
 const prettierConfigFiles = require('./files').prettierConfigFiles;
 const constants = require('../generator-constants');
 
-let useBlueprints;
+let useBlueprint;
 
 module.exports = class extends BaseBlueprintGenerator {
     constructor(args, opts) {
@@ -38,8 +38,17 @@ module.exports = class extends BaseBlueprintGenerator {
 
         this.setupServerOptions(this);
         this.setupClientOptions(this);
-
-        useBlueprints = !opts.fromBlueprint && this.instantiateBlueprints('common', { 'client-hook': !this.skipClient });
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        if (!opts.fromBlueprint) {
+            // use global variable since getters dont have access to instance property
+            useBlueprint = this.composeBlueprint(blueprint, 'common', {
+                ...this.options,
+                'client-hook': !this.skipClient,
+                configOptions: this.configOptions
+            });
+        } else {
+            useBlueprint = false;
+        }
     }
 
     // Public API method used by the getter and also by Blueprints
@@ -67,7 +76,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get initializing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._initializing();
     }
 
@@ -91,7 +100,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get default() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._default();
     }
 
@@ -101,7 +110,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 };
diff --git a/generators/entity-client/index.js b/generators/entity-client/index.js
index dda20aac8f..0f7959cce3 100644
--- a/generators/entity-client/index.js
+++ b/generators/entity-client/index.js
@@ -22,7 +22,7 @@ const writeFiles = require('./files').writeFiles;
 const utils = require('../utils');
 const BaseBlueprintGenerator = require('../generator-base-blueprint');
 
-let useBlueprints;
+let useBlueprint;
 
 module.exports = class extends BaseBlueprintGenerator {
     constructor(args, opts) {
@@ -30,10 +30,18 @@ module.exports = class extends BaseBlueprintGenerator {
         utils.copyObjectProps(this, opts.context);
         this.jhipsterContext = opts.jhipsterContext || opts.context;
         this.configOptions = opts.configOptions || {};
-
-        useBlueprints =
-            !opts.fromBlueprint &&
-            this.instantiateBlueprints('entity-client', { context: opts.context, debug: opts.context.isDebugEnabled });
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        if (!opts.fromBlueprint) {
+            // use global variable since getters dont have access to instance property
+            useBlueprint = this.composeBlueprint(blueprint, 'entity-client', {
+                ...this.options,
+                context: opts.context,
+                debug: opts.context.isDebugEnabled,
+                configOptions: this.configOptions
+            });
+        } else {
+            useBlueprint = false;
+        }
     }
 
     // Public API method used by the getter and also by Blueprints
@@ -42,7 +50,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 
@@ -59,7 +67,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get end() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._end();
     }
 };
diff --git a/generators/entity-i18n/index.js b/generators/entity-i18n/index.js
index 1e30bd026c..939bdddbc3 100644
--- a/generators/entity-i18n/index.js
+++ b/generators/entity-i18n/index.js
@@ -22,7 +22,7 @@ const utils = require('../utils');
 const BaseBlueprintGenerator = require('../generator-base-blueprint');
 
 /* constants used throughout */
-let useBlueprints;
+let useBlueprint;
 
 module.exports = class extends BaseBlueprintGenerator {
     constructor(args, opts) {
@@ -30,9 +30,18 @@ module.exports = class extends BaseBlueprintGenerator {
         utils.copyObjectProps(this, opts.context);
         this.jhipsterContext = opts.jhipsterContext || opts.context;
         this.configOptions = opts.configOptions || {};
-
-        useBlueprints =
-            !opts.fromBlueprint && this.instantiateBlueprints('entity-i18n', { context: opts.context, debug: opts.context.isDebugEnabled });
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        if (!opts.fromBlueprint) {
+            // use global variable since getters dont have access to instance property
+            useBlueprint = this.composeBlueprint(blueprint, 'entity-i18n', {
+                ...this.options,
+                context: opts.context,
+                debug: opts.context.isDebugEnabled,
+                configOptions: this.configOptions
+            });
+        } else {
+            useBlueprint = false;
+        }
     }
 
     // Public API method used by the getter and also by Blueprints
@@ -41,7 +50,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 };
diff --git a/generators/entity-server/index.js b/generators/entity-server/index.js
index 9bd887c8ae..75a7318722 100644
--- a/generators/entity-server/index.js
+++ b/generators/entity-server/index.js
@@ -22,7 +22,7 @@ const utils = require('../utils');
 const BaseBlueprintGenerator = require('../generator-base-blueprint');
 
 /* constants used throughout */
-let useBlueprints;
+let useBlueprint;
 
 module.exports = class extends BaseBlueprintGenerator {
     constructor(args, opts) {
@@ -33,10 +33,18 @@ module.exports = class extends BaseBlueprintGenerator {
         if (this.databaseType === 'cassandra') {
             this.pkType = 'UUID';
         }
-
-        useBlueprints =
-            !opts.fromBlueprint &&
-            this.instantiateBlueprints('entity-server', { context: opts.context, debug: opts.context.isDebugEnabled });
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        if (!opts.fromBlueprint) {
+            // use global variable since getters dont have access to instance property
+            useBlueprint = this.composeBlueprint(blueprint, 'entity-server', {
+                ...this.options,
+                context: opts.context,
+                debug: opts.context.isDebugEnabled,
+                configOptions: this.configOptions
+            });
+        } else {
+            useBlueprint = false;
+        }
     }
 
     // Public API method used by the getter and also by Blueprints
@@ -45,7 +53,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 };
diff --git a/generators/entity/index.js b/generators/entity/index.js
index ef97e2dee6..940c5eaf9e 100644
--- a/generators/entity/index.js
+++ b/generators/entity/index.js
@@ -29,7 +29,7 @@ const statistics = require('../statistics');
 
 /* constants used throughout */
 const SUPPORTED_VALIDATION_RULES = constants.SUPPORTED_VALIDATION_RULES;
-let useBlueprints;
+let useBlueprint;
 
 class EntityGenerator extends BaseBlueprintGenerator {
     constructor(args, opts) {
@@ -124,8 +124,17 @@ class EntityGenerator extends BaseBlueprintGenerator {
 
         this.setupEntityOptions(this, this, this.context);
         this.registerPrettierTransform();
-
-        useBlueprints = !opts.fromBlueprint && this.instantiateBlueprints('entity', { arguments: [this.context.name] });
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        if (!opts.fromBlueprint) {
+            // use global variable since getters dont have access to instance property
+            useBlueprint = this.composeBlueprint(blueprint, 'entity', {
+                ...this.options,
+                configOptions: this.configOptions,
+                arguments: [this.context.name]
+            });
+        } else {
+            useBlueprint = false;
+        }
     }
 
     // Public API method used by the getter and also by Blueprints
@@ -327,7 +336,7 @@ class EntityGenerator extends BaseBlueprintGenerator {
     }
 
     get initializing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._initializing();
     }
 
@@ -351,7 +360,7 @@ class EntityGenerator extends BaseBlueprintGenerator {
     }
 
     get prompting() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._prompting();
     }
 
@@ -1079,7 +1088,7 @@ class EntityGenerator extends BaseBlueprintGenerator {
     }
 
     get configuring() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._configuring();
     }
 
@@ -1137,7 +1146,7 @@ class EntityGenerator extends BaseBlueprintGenerator {
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 
@@ -1176,7 +1185,7 @@ class EntityGenerator extends BaseBlueprintGenerator {
     }
 
     get install() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._install();
     }
 }
diff --git a/generators/generator-base-blueprint.js b/generators/generator-base-blueprint.js
index 5f202115d5..532bab2d31 100644
--- a/generators/generator-base-blueprint.js
+++ b/generators/generator-base-blueprint.js
@@ -17,7 +17,6 @@
  * limitations under the License.
  */
 /* eslint-disable consistent-return */
-const jhipsterUtils = require('./utils');
 const BaseGenerator = require('./generator-base');
 
 /**
@@ -60,39 +59,4 @@ module.exports = class extends BaseGenerator {
     _end() {
         return {};
     }
-
-    /**
-     * Instantiates the blueprint generators, if any.
-     * @param {string} subGen - sub generator
-     * @param {any} extraOptions - extra options to pass to blueprint generator
-     * @return {true} useBlueprints - true if one or more blueprints generators have been constructed; false otherwise
-     */
-    instantiateBlueprints(subGen, extraOptions) {
-        let useBlueprints = false;
-
-        const blueprints = jhipsterUtils.parseBluePrints(
-            this.options.blueprints ||
-                this.configOptions.blueprints ||
-                this.config.get('blueprints') ||
-                this.options.blueprint ||
-                this.configOptions.blueprint ||
-                this.config.get('blueprint')
-        );
-        if (blueprints && blueprints.length > 0) {
-            blueprints.forEach(blueprint => {
-                let bpOptions = {
-                    ...this.options,
-                    configOptions: this.configOptions
-                };
-                if (extraOptions) {
-                    bpOptions = { ...bpOptions, ...extraOptions };
-                }
-                const useBP = this.composeBlueprint(blueprint.name, subGen, bpOptions);
-                if (!useBlueprints && useBP) {
-                    useBlueprints = true;
-                }
-            });
-        }
-        return useBlueprints;
-    }
 };
diff --git a/generators/generator-constants.js b/generators/generator-constants.js
index fa2763c75b..56f82b530d 100644
--- a/generators/generator-constants.js
+++ b/generators/generator-constants.js
@@ -21,19 +21,19 @@
 const DOCKER_JHIPSTER_REGISTRY = 'jhipster/jhipster-registry:v5.0.2';
 const DOCKER_JAVA_JRE = 'adoptopenjdk:11-jre-hotspot';
 const DOCKER_MYSQL = 'mysql:8.0.16';
-const DOCKER_MARIADB = 'mariadb:10.4.5';
-const DOCKER_POSTGRESQL = 'postgres:11.3';
+const DOCKER_MARIADB = 'mariadb:10.4.6';
+const DOCKER_POSTGRESQL = 'postgres:11.4';
 const DOCKER_MONGODB = 'mongo:4.0.10';
 const DOCKER_COUCHBASE = 'couchbase:6.0.1';
 const DOCKER_CASSANDRA = 'cassandra:3.11.4';
 const DOCKER_MSSQL = 'microsoft/mssql-server-linux:latest';
-const DOCKER_HAZELCAST_MANAGEMENT_CENTER = 'hazelcast/management-center:3.12';
+const DOCKER_HAZELCAST_MANAGEMENT_CENTER = 'hazelcast/management-center:3.12.1';
 const DOCKER_MEMCACHED = 'memcached:1.5.16-alpine';
 const DOCKER_KEYCLOAK = 'jboss/keycloak:6.0.1';
 const DOCKER_ELASTICSEARCH = 'docker.elastic.co/elasticsearch/elasticsearch:6.4.3'; // The version should be coerent with the one from spring-data-elasticsearch project
-const DOCKER_KAFKA = 'confluentinc/cp-kafka:5.2.1';
-const DOCKER_ZOOKEEPER = 'confluentinc/cp-zookeeper:5.2.1';
-const DOCKER_SONAR = 'sonarqube:7.7-community';
+const DOCKER_KAFKA = 'confluentinc/cp-kafka:5.2.2';
+const DOCKER_ZOOKEEPER = 'confluentinc/cp-zookeeper:5.2.2';
+const DOCKER_SONAR = 'sonarqube:7.9-community';
 const DOCKER_JHIPSTER_CONSOLE = 'jhipster/jhipster-console:v4.0.0';
 const DOCKER_JHIPSTER_CURATOR = 'jhipster/jhipster-curator:v4.0.0';
 const DOCKER_JHIPSTER_ELASTICSEARCH = 'jhipster/jhipster-elasticsearch:v4.0.0';
@@ -41,15 +41,15 @@ const DOCKER_JHIPSTER_LOGSTASH = 'jhipster/jhipster-logstash:v4.0.0';
 const DOCKER_JHIPSTER_IMPORT_DASHBOARDS = 'jhipster/jhipster-import-dashboards:v4.0.0';
 const DOCKER_JHIPSTER_ZIPKIN = 'jhipster/jhipster-zipkin:v4.0.0';
 const DOCKER_TRAEFIK = 'traefik:1.7.12';
-const DOCKER_CONSUL = 'consul:1.5.1';
+const DOCKER_CONSUL = 'consul:1.5.2';
 const DOCKER_CONSUL_CONFIG_LOADER = 'jhipster/consul-config-loader:v0.3.0';
 const DOCKER_PROMETHEUS = 'prom/prometheus:v2.10.0';
 const DOCKER_PROMETHEUS_ALERTMANAGER = 'prom/alertmanager:v0.17.0';
-const DOCKER_GRAFANA = 'grafana/grafana:6.2.2';
+const DOCKER_GRAFANA = 'grafana/grafana:6.2.5';
 const DOCKER_JENKINS = 'jenkins:latest';
 const DOCKER_SWAGGER_EDITOR = 'swaggerapi/swagger-editor:latest';
 const DOCKER_COMPOSE_FORMAT_VERSION = '2';
-const DOCKER_PROMETHEUS_OPERATOR = 'quay.io/coreos/prometheus-operator:v0.30.1';
+const DOCKER_PROMETHEUS_OPERATOR = 'quay.io/coreos/prometheus-operator:v0.31.1';
 const DOCKER_GRAFANA_WATCHER = 'quay.io/coreos/grafana-watcher:v0.0.8';
 
 // Kubernetes versions
@@ -67,7 +67,7 @@ const JAVA_VERSION = '1.8'; // Java version is forced to be 1.8. We keep the var
 // version of Node, Yarn, NPM
 const NODE_VERSION = '10.16.0';
 const YARN_VERSION = '1.16.0';
-const NPM_VERSION = '6.9.0';
+const NPM_VERSION = '6.9.2';
 
 // Libraries version
 const JIB_VERSION = '1.3.0';
diff --git a/generators/languages/index.js b/generators/languages/index.js
index cf20ec88dd..a89a107227 100644
--- a/generators/languages/index.js
+++ b/generators/languages/index.js
@@ -25,7 +25,7 @@ const statistics = require('../statistics');
 
 const constants = require('../generator-constants');
 
-let useBlueprints;
+let useBlueprint;
 
 module.exports = class extends BaseBlueprintGenerator {
     constructor(args, opts) {
@@ -78,10 +78,18 @@ module.exports = class extends BaseBlueprintGenerator {
                 }
             });
         }
-
-        useBlueprints =
-            !opts.fromBlueprint &&
-            this.instantiateBlueprints('languages', { languages: this.languages, arguments: this.options.languages });
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        // use global variable since getters dont have access to instance property
+        if (!opts.fromBlueprint) {
+            useBlueprint = this.composeBlueprint(blueprint, 'languages', {
+                ...this.options,
+                languages: this.languages,
+                configOptions: this.configOptions,
+                arguments: this.options.languages
+            });
+        } else {
+            useBlueprint = false;
+        }
     }
 
     // Public API method used by the getter and also by Blueprints
@@ -126,7 +134,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get initializing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._initializing();
     }
 
@@ -138,7 +146,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get prompting() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._prompting();
     }
 
@@ -155,7 +163,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get configuring() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._configuring();
     }
 
@@ -204,7 +212,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get default() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._default();
     }
 
@@ -242,7 +250,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 };
diff --git a/generators/server/index.js b/generators/server/index.js
index 01ad39bbdd..6fb4403a2b 100644
--- a/generators/server/index.js
+++ b/generators/server/index.js
@@ -28,7 +28,7 @@ const constants = require('../generator-constants');
 const statistics = require('../statistics');
 const { getBase64Secret, getRandomHex } = require('../utils');
 
-let useBlueprints;
+let useBlueprint;
 
 module.exports = class extends BaseBlueprintGenerator {
     constructor(args, opts) {
@@ -59,9 +59,17 @@ module.exports = class extends BaseBlueprintGenerator {
         this.uaaBaseName = this.options.uaaBaseName || this.configOptions.uaaBaseName || this.config.get('uaaBaseName');
 
         this.setupServerOptions(this);
-
-        useBlueprints = !opts.fromBlueprint && this.instantiateBlueprints('server', { 'client-hook': !this.skipClient });
-
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        if (!opts.fromBlueprint) {
+            // use global variable since getters dont have access to instance property
+            useBlueprint = this.composeBlueprint(blueprint, 'server', {
+                ...this.options,
+                'client-hook': !this.skipClient,
+                configOptions: this.configOptions
+            });
+        } else {
+            useBlueprint = false;
+        }
         this.registerPrettierTransform();
     }
 
@@ -290,7 +298,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get initializing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._initializing();
     }
 
@@ -330,7 +338,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get prompting() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._prompting();
     }
 
@@ -409,7 +417,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get configuring() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._configuring();
     }
 
@@ -452,7 +460,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get default() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._default();
     }
 
@@ -462,7 +470,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 
@@ -485,7 +493,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get install() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._install();
     }
 
@@ -517,7 +525,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get end() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._end();
     }
 };
diff --git a/generators/spring-controller/index.js b/generators/spring-controller/index.js
index cba7daa76a..844cda8838 100644
--- a/generators/spring-controller/index.js
+++ b/generators/spring-controller/index.js
@@ -27,7 +27,7 @@ const statistics = require('../statistics');
 const SERVER_MAIN_SRC_DIR = constants.SERVER_MAIN_SRC_DIR;
 const SERVER_TEST_SRC_DIR = constants.SERVER_TEST_SRC_DIR;
 
-let useBlueprints;
+let useBlueprint;
 
 module.exports = class extends BaseBlueprintGenerator {
     constructor(args, opts) {
@@ -48,7 +48,17 @@ module.exports = class extends BaseBlueprintGenerator {
         });
         this.defaultOption = this.options.default;
 
-        useBlueprints = !opts.fromBlueprint && this.instantiateBlueprints('spring-controller', { arguments: [this.name] });
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        if (!opts.fromBlueprint) {
+            // use global variable since getters dont have access to instance property
+            useBlueprint = this.composeBlueprint(blueprint, 'spring-controller', {
+                ...this.options,
+                arguments: [this.name],
+                configOptions: this.configOptions
+            });
+        } else {
+            useBlueprint = false;
+        }
     }
 
     // Public API method used by the getter and also by Blueprints
@@ -79,7 +89,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get initializing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._initializing();
     }
 
@@ -91,7 +101,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get prompting() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._prompting();
     }
 
@@ -105,7 +115,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get default() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._default();
     }
 
@@ -168,7 +178,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 };
diff --git a/generators/spring-service/index.js b/generators/spring-service/index.js
index 08e3e19b0d..c600659373 100644
--- a/generators/spring-service/index.js
+++ b/generators/spring-service/index.js
@@ -24,7 +24,7 @@ const statistics = require('../statistics');
 
 const SERVER_MAIN_SRC_DIR = constants.SERVER_MAIN_SRC_DIR;
 
-let useBlueprints;
+let useBlueprint;
 module.exports = class extends BaseBlueprintGenerator {
     constructor(args, opts) {
         super(args, opts);
@@ -44,7 +44,17 @@ module.exports = class extends BaseBlueprintGenerator {
         });
         this.defaultOption = this.options.default;
 
-        useBlueprints = !opts.fromBlueprint && this.instantiateBlueprints('spring-service', { arguments: [this.name] });
+        const blueprint = this.options.blueprint || this.configOptions.blueprint || this.config.get('blueprint');
+        if (!opts.fromBlueprint) {
+            // use global variable since getters dont have access to instance property
+            useBlueprint = this.composeBlueprint(blueprint, 'spring-service', {
+                ...this.options,
+                arguments: [this.name],
+                configOptions: this.configOptions
+            });
+        } else {
+            useBlueprint = false;
+        }
     }
 
     // Public API method used by the getter and also by Blueprints
@@ -66,7 +76,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get initializing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._initializing();
     }
 
@@ -96,7 +106,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get prompting() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._prompting();
     }
 
@@ -110,7 +120,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get default() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._default();
     }
 
@@ -139,7 +149,7 @@ module.exports = class extends BaseBlueprintGenerator {
     }
 
     get writing() {
-        if (useBlueprints) return;
+        if (useBlueprint) return;
         return this._writing();
     }
 };
diff --git a/generators/upgrade/index.js b/generators/upgrade/index.js
index 1bcf96b095..03ada0425b 100644
--- a/generators/upgrade/index.js
+++ b/generators/upgrade/index.js
@@ -25,7 +25,6 @@ const gitignore = require('parse-gitignore');
 const BaseGenerator = require('../generator-base');
 const constants = require('../generator-constants');
 const statistics = require('../statistics');
-const utils = require('../utils');
 
 /* Constants used throughout */
 const GENERATOR_JHIPSTER = 'generator-jhipster';
@@ -49,9 +48,9 @@ module.exports = class extends BaseGenerator {
             desc: 'Upgrade to a specific version instead of the latest',
             type: String
         });
-        // This adds support for a `--target-blueprint-versions` flag
-        this.option('target-blueprint-versions', {
-            desc: 'Upgrade to specific blueprint versions instead of the latest, e.g. --target-blueprint-versions foo@0.0.1,bar@1.0.2',
+        // This adds support for a `--target-blueprint-version` flag
+        this.option('target-blueprint-version', {
+            desc: 'Upgrade to a specific blueprint version instead of the latest',
             type: String
         });
 
@@ -70,7 +69,7 @@ module.exports = class extends BaseGenerator {
         });
 
         this.targetJhipsterVersion = this.options['target-version'];
-        this.targetBlueprintVersions = utils.parseBluePrints(this.options['target-blueprint-versions']);
+        this.targetBlueprintVersion = this.options['target-blueprint-version'];
         this.skipInstall = this.options['skip-install'];
         this.silent = this.options.silent;
     }
@@ -89,7 +88,8 @@ module.exports = class extends BaseGenerator {
             loadConfig() {
                 this.config = this.getAllJhipsterConfig(this, true);
                 this.currentJhipsterVersion = this.config.get('jhipsterVersion');
-                this.blueprints = utils.loadBlueprintsFromConfiguration(this);
+                this.blueprint = this.config.get('blueprint');
+                this.currentBlueprintVersion = this.config.get('blueprintVersion');
                 this.clientPackageManager = this.config.get('clientPackageManager');
                 this.clientFramework = this.config.get('clientFramework');
             }
@@ -116,7 +116,8 @@ module.exports = class extends BaseGenerator {
         this.success('Cleaned up project directory');
     }
 
-    _generate(jhipsterVersion, blueprintInfo, callback) {
+    _generate(jhipsterVersion, blueprintVersion, callback) {
+        const blueprintInfo = this.blueprint ? ` and ${this.blueprint} ${blueprintVersion}` : '';
         this.log(`Regenerating application with JHipster ${jhipsterVersion}${blueprintInfo}...`);
         let generatorCommand = 'yo jhipster';
         if (semver.gte(jhipsterVersion, FIRST_CLI_SUPPORTED_VERSION)) {
@@ -153,11 +154,12 @@ module.exports = class extends BaseGenerator {
         });
     }
 
-    _regenerate(jhipsterVersion, blueprintInfo, callback) {
-        this._generate(jhipsterVersion, blueprintInfo, () => {
+    _regenerate(jhipsterVersion, blueprintVersion, callback) {
+        this._generate(jhipsterVersion, blueprintVersion, () => {
             const keystore = `${SERVER_MAIN_RES_DIR}config/tls/keystore.p12`;
             this.info(`Removing ${keystore}`);
             shelljs.rm('-Rf', keystore);
+            const blueprintInfo = this.blueprint ? ` and ${this.blueprint} ${blueprintVersion}` : '';
             this._gitCommitAll(`Generated with JHipster ${jhipsterVersion}${blueprintInfo}`, () => {
                 callback();
             });
@@ -209,58 +211,34 @@ module.exports = class extends BaseGenerator {
                 });
             },
 
-            checkLatestBlueprintVersions() {
-                if (!this.blueprints || this.blueprints.length < 0) {
-                    this.log('No blueprints detected, skipping check of last blueprint version');
+            checkLatestBlueprintVersion() {
+                if (!this.blueprint) {
+                    this.log('No blueprint detected, skipping check of last blueprint version');
+                    return;
+                }
+                if (!this.currentBlueprintVersion) {
+                    this.error('No blueprintVersion defined in .yo-rc.json, unable to upgrade');
+                }
+                if (this.targetBlueprintVersion) {
+                    this.log(`Upgrading to the target blueprint version: ${this.targetBlueprintVersion}`);
+                    this.latestBlueprintVersion = this.targetBlueprintVersion;
                     return;
                 }
-
-                this.success('Checking for new blueprint versions');
                 const done = this.async();
-                Promise.all(
-                    this.blueprints
-                        .filter(blueprint => {
-                            if (this.targetBlueprintVersions && this.targetBlueprintVersions.length > 0) {
-                                const targetBlueprint = this.targetBlueprintVersions.find(elem => {
-                                    return elem.name === blueprint.name;
-                                });
-                                if (targetBlueprint && targetBlueprint.version && targetBlueprint.version !== 'latest') {
-                                    this.log(
-                                        `Blueprint ${targetBlueprint.name} will be upgraded to target version: ${targetBlueprint.version}`
-                                    );
-                                    blueprint.latestBlueprintVersion = targetBlueprint.version;
-                                    return false;
-                                }
-                            }
-                            return true;
-                        })
-                        .map(blueprint => {
-                            return new Promise(resolve => {
-                                this._retrieveLatestVersion(blueprint.name, latestVersion => {
-                                    blueprint.latestBlueprintVersion = latestVersion;
-                                    if (semver.lt(blueprint.version, blueprint.latestBlueprintVersion)) {
-                                        this.newBlueprintVersionFound = true;
-                                        this.success(`New ${blueprint.name} version found: ${this.latestBlueprintVersion}`);
-                                    } else if (this.force) {
-                                        this.newBlueprintVersionFound = true;
-                                        this.log(chalk.yellow('Forced re-generation'));
-                                    } else {
-                                        if (this.newBlueprintVersionFound === undefined) {
-                                            this.newBlueprintVersionFound = false;
-                                        }
-                                        this.warning(
-                                            `${chalk.green(
-                                                'No update available.'
-                                            )} Application has already been generated with latest version for blueprint: ${blueprint.name}`
-                                        );
-                                    }
-                                    this.success(`Done checking for new version for blueprint ${blueprint.name}`);
-                                    resolve();
-                                });
-                            });
-                        })
-                ).then(() => {
-                    this.success('Done checking for new version of blueprints');
+                this._retrieveLatestVersion(this.blueprint, latestVersion => {
+                    this.latestBlueprintVersion = latestVersion;
+                    if (semver.lt(this.currentBlueprintVersion, this.latestBlueprintVersion)) {
+                        this.newBlueprintVersionFound = true;
+                        this.success(`New ${this.blueprint} version found: ${this.latestBlueprintVersion}`);
+                    } else if (this.force) {
+                        this.newBlueprintVersionFound = true;
+                        this.log(chalk.yellow('Forced re-generation'));
+                    } else {
+                        this.newBlueprintVersionFound = false;
+                        this.warning(
+                            `${chalk.green('No update available.')} Application has already been generated with latest blueprint version.`
+                        );
+                    }
                     done();
                 });
             },
@@ -361,38 +339,20 @@ module.exports = class extends BaseGenerator {
                     this._installNpmPackageLocally(GENERATOR_JHIPSTER, version, callback);
                 };
 
-                const installBlueprintsLocally = callback => {
-                    if (!this.blueprints || this.blueprints.length < 1) {
+                const installBlueprintLocally = (version, callback) => {
+                    if (!this.blueprint) {
                         this.log('Skipping local blueprint installation since no blueprint has been detected');
                         callback();
                         return;
                     }
-
-                    this.success('Installing blueprints locally...');
-                    Promise.all(
-                        this.blueprints.map(blueprint => {
-                            return new Promise(resolve => {
-                                this._installNpmPackageLocally(blueprint.name, blueprint.version, () => {
-                                    this.success(`Done installing blueprint: ${blueprint.name}@${blueprint.version}`);
-                                    resolve();
-                                });
-                            });
-                        })
-                    ).then(() => {
-                        this.success('Done installing blueprints locally');
-                        callback();
-                    });
+                    this._installNpmPackageLocally(this.blueprint, version, callback);
                 };
 
                 const regenerate = () => {
                     this._cleanUp();
                     installJhipsterLocally(this.currentJhipsterVersion, () => {
-                        installBlueprintsLocally(() => {
-                            const blueprintInfo =
-                                this.blueprints && this.blueprints.length > 0
-                                    ? ` and ${this.blueprints.map(bp => bp.name + bp.version).join(', ')} `
-                                    : '';
-                            this._regenerate(this.currentJhipsterVersion, blueprintInfo, () => {
+                        installBlueprintLocally(this.currentBlueprintVersion, () => {
+                            this._regenerate(this.currentJhipsterVersion, this.currentBlueprintVersion, () => {
                                 this._gitCheckout(this.sourceBranch, () => {
                                     // consider code up-to-date
                                     recordCodeHasBeenGenerated();
@@ -434,37 +394,19 @@ module.exports = class extends BaseGenerator {
                 this._installNpmPackageLocally(GENERATOR_JHIPSTER, this.latestJhipsterVersion, done);
             },
 
-            updateBlueprints() {
-                if (!this.blueprints || this.blueprints.length < 1) {
+            updateBlueprint() {
+                if (!this.blueprint) {
                     this.log('Skipping blueprint update since no blueprint has been detected');
                     return;
                 }
-
-                this.success('Upgrading blueprints...');
                 const done = this.async();
-                Promise.all(
-                    this.blueprints.map(blueprint => {
-                        return new Promise(resolve => {
-                            this._installNpmPackageLocally(blueprint.name, blueprint.latestBlueprintVersion, () => {
-                                this.success(`Done upgrading blueprint ${blueprint.name} to version ${blueprint.latestBlueprintVersion}`);
-                                resolve();
-                            });
-                        });
-                    })
-                ).then(() => {
-                    this.success('Done upgrading blueprints');
-                    done();
-                });
+                this._installNpmPackageLocally(this.blueprint, this.latestBlueprintVersion, done);
             },
 
             generateWithLatestVersion() {
                 const done = this.async();
                 this._cleanUp();
-
-                const blueprintInfo = this.blueprints
-                    ? ` and ${this.blueprints.map(bp => bp.name + bp.latestBlueprintVersion).join(', ')} `
-                    : '';
-                this._regenerate(this.latestJhipsterVersion, blueprintInfo, done);
+                this._regenerate(this.latestJhipsterVersion, this.latestBlueprintVersion, done);
             },
 
             checkoutSourceBranch() {
@@ -480,7 +422,6 @@ module.exports = class extends BaseGenerator {
                     done();
                 });
             },
-
             checkConflictsInPackageJson() {
                 const done = this.async();
                 this.gitExec(['diff', '--name-only', '--diff-filter=U', 'package.json'], { silent: this.silent }, (code, msg, err) => {
diff --git a/generators/utils.js b/generators/utils.js
index 4e4fac8388..c632130b35 100644
--- a/generators/utils.js
+++ b/generators/utils.js
@@ -47,8 +47,6 @@ module.exports = {
     getBase64Secret,
     getRandomHex,
     checkStringInFile,
-    loadBlueprintsFromConfiguration,
-    parseBluePrints,
     normalizeBlueprintName
 };
 
@@ -424,21 +422,9 @@ function getAllJhipsterConfig(generator, force, basePath = '') {
     if ((force || !configuration.baseName) && jhiCore.FileUtils.doesFileExist(filePath)) {
         const yoRc = JSON.parse(fs.readFileSync(filePath, { encoding: 'utf-8' }));
         configuration = yoRc['generator-jhipster'];
-
-        // merge the blueprint configs if available
-        const oldBlueprintName = configuration.blueprint;
-        const blueprints = configuration.blueprints || [];
-        if (oldBlueprintName && blueprints.indexOf(oldBlueprintName) === -1) {
-            const oldBlueprintVersion = configuration.blueprintVersion || 'latest';
-            blueprints.push({
-                name: oldBlueprintName,
-                version: oldBlueprintVersion
-            });
-        }
-        const blueprintConfigs = blueprints.map(bp => yoRc[bp.name]).filter(el => el !== null && el !== undefined);
-        if (blueprintConfigs.length > 0) {
-            const mergedConfigs = Object.assign(...blueprintConfigs);
-            configuration = { ...configuration, ...mergedConfigs };
+        // merge the blueprint config if available
+        if (configuration.blueprint) {
+            configuration = { ...configuration, ...yoRc[configuration.blueprint] };
         }
     }
     if (!configuration.get || typeof configuration.get !== 'function') {
@@ -486,63 +472,9 @@ function checkStringInFile(path, search, generator) {
     return fileContent.includes(search);
 }
 
-/**
- * Loads the blueprint information from the configuration of the specified generator.
- * @param config - the generator's configuration object.
- * @returns {Array} an array that contains the info for each blueprint
- */
-function loadBlueprintsFromConfiguration(generator) {
-    // load blueprints from config file
-    const blueprints = generator.config.get('blueprints') || [];
-
-    const oldBlueprintName = generator.config.get('blueprint');
-    if (oldBlueprintName && blueprints.findIndex(e => e.name === oldBlueprintName) === -1) {
-        const version = generator.config.get('blueprintVersion') || 'latest';
-        blueprints.push(parseBlueprintInfo(`${oldBlueprintName}@${version}`));
-    }
-    return blueprints;
-}
-
-/**
- * Splits and normalizes a comma separated list of blueprint names with optional versions.
- * @param {string} blueprints - comma separated list of blueprint names, e.g kotlin,vuewjs@1.0.1. If an array then
- * no processing is performed and it is returned as is.
- * @returns {Array} an array that contains the info for each blueprint
- */
-function parseBluePrints(blueprints) {
-    if (blueprints && !Array.isArray(blueprints)) {
-        return blueprints
-            .split(',')
-            .filter(el => el != null && el.length > 0)
-            .map(blueprint => parseBlueprintInfo(blueprint));
-    }
-    return blueprints;
-}
-
-/**
- * Normalize blueprint name if needed and also extracts version if defined. If no version is defined then `latest`
- * is used by default.
- * @param {string} blueprint - name of the blueprint and optionally a version, e.g kotlin[@0.8.1]
- * @returns {object} containing the name and version of the blueprint
- */
-function parseBlueprintInfo(blueprint) {
-    let bpName = normalizeBlueprintName(blueprint);
-    let version = 'latest';
-    const idx = bpName.lastIndexOf('@');
-    if (idx > 0) {
-        version = bpName.slice(idx + 1);
-        bpName = bpName.slice(0, idx);
-    }
-    return {
-        name: bpName,
-        version
-    };
-}
-
 /**
  * Normalize blueprint name: prepend 'generator-jhipster-' if needed
  * @param {string} blueprint - name of the blueprint
- * @returns {string} the normalized blueprint name
  */
 function normalizeBlueprintName(blueprint) {
     if (blueprint && blueprint.startsWith('@')) {


Test patch:
diff --git a/test/blueprint/app-blueprint.spec.js b/test/blueprint/app-blueprint.spec.js
index 14af723803..2ceeda46fc 100644
--- a/test/blueprint/app-blueprint.spec.js
+++ b/test/blueprint/app-blueprint.spec.js
@@ -60,9 +60,7 @@ describe('JHipster application generator with blueprint', () => {
         });
 
         it('blueprint version is saved in .yo-rc.json', () => {
-            assert.JSONFileContent('.yo-rc.json', {
-                'generator-jhipster': { blueprints: [{ name: 'generator-jhipster-myblueprint', version: '9.9.9' }] }
-            });
+            assert.fileContent('.yo-rc.json', /"blueprintVersion": "9.9.9"/);
         });
         it('blueprint module and version are in package.json', () => {
             assert.fileContent('package.json', /"generator-jhipster-myblueprint": "9.9.9"/);
diff --git a/test/blueprint/multiple-blueprints.spec.js b/test/blueprint/multiple-blueprints.spec.js
deleted file mode 100644
index aa3b178c59..0000000000
--- a/test/blueprint/multiple-blueprints.spec.js
+++ /dev/null
@@ -1,162 +0,0 @@
-const path = require('path');
-const assert = require('yeoman-assert');
-const helpers = require('yeoman-test');
-const expectedFiles = require('../utils/expected-files');
-const ClientGenerator = require('../../generators/client');
-const ServerGenerator = require('../../generators/server');
-
-const mockClientBlueprintSubGen = class extends ClientGenerator {
-    constructor(args, opts) {
-        super(args, Object.assign({ fromBlueprint: true }, opts)); // fromBlueprint variable is important
-    }
-
-    get initializing() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._initializing();
-    }
-
-    get prompting() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._prompting();
-    }
-
-    get configuring() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._configuring();
-    }
-
-    get default() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._default();
-    }
-
-    get writing() {
-        const phaseFromJHipster = super._writing();
-        const customPhaseSteps = {
-            addDummyProperty() {
-                this.addNpmDependency('dummy-blueprint-property', '2.0');
-            }
-        };
-        return {
-            ...phaseFromJHipster,
-            ...customPhaseSteps
-        };
-    }
-
-    get install() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._install();
-    }
-
-    get end() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._end();
-    }
-};
-
-const mockServerBlueprintSubGen = class extends ServerGenerator {
-    constructor(args, opts) {
-        super(args, Object.assign({ fromBlueprint: true }, opts)); // fromBlueprint variable is important
-    }
-
-    get initializing() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._initializing();
-    }
-
-    get writing() {
-        const phaseFromJHipster = super._writing();
-        const customPhaseSteps = {
-            addDummyProperty() {
-                this.addMavenProperty('dummy-blueprint-property', 'foo');
-            }
-        };
-        return {
-            ...phaseFromJHipster,
-            ...customPhaseSteps
-        };
-    }
-
-    get prompting() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._prompting();
-    }
-
-    get configuring() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._configuring();
-    }
-
-    get default() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._default();
-    }
-
-    get install() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._install();
-    }
-
-    get end() {
-        // Here we are not overriding this phase and hence its being handled by JHipster
-        return super._end();
-    }
-};
-
-describe('JHipster entity generator with multiple blueprints', () => {
-    const blueprintNames = [
-        'generator-jhipster-my-client-blueprint,generator-jhipster-my-server-blueprint',
-        'my-client-blueprint,my-server-blueprint'
-    ];
-
-    blueprintNames.forEach(blueprints => {
-        describe(`generate entity with multiple blueprints option '${blueprints}'`, () => {
-            before(done => {
-                helpers
-                    .run(path.join(__dirname, '../../generators/app'))
-                    .withOptions({
-                        'from-cli': true,
-                        skipInstall: true,
-                        skipChecks: true,
-                        blueprints
-                    })
-                    .withGenerators([
-                        [mockClientBlueprintSubGen, 'jhipster-my-client-blueprint:client'],
-                        [mockServerBlueprintSubGen, 'jhipster-my-server-blueprint:server']
-                    ])
-                    .withPrompts({
-                        baseName: 'jhipster',
-                        clientFramework: 'angularX',
-                        packageName: 'com.mycompany.myapp',
-                        packageFolder: 'com/mycompany/myapp',
-                        serviceDiscoveryType: false,
-                        authenticationType: 'jwt',
-                        cacheProvider: 'ehcache',
-                        enableHibernateCache: true,
-                        databaseType: 'sql',
-                        devDatabaseType: 'h2Memory',
-                        prodDatabaseType: 'mysql',
-                        enableTranslation: true,
-                        nativeLanguage: 'en',
-                        languages: ['fr']
-                    })
-                    .on('end', done);
-            });
-
-            it('creates expected files from jhipster app generator', () => {
-                assert.file(expectedFiles.common);
-                assert.file(expectedFiles.server);
-                assert.file(expectedFiles.maven);
-                assert.file(expectedFiles.client);
-            });
-
-            it('contains the specific change added by the client blueprint', () => {
-                assert.fileContent('package.json', /dummy-blueprint-property/);
-            });
-
-            it('contains the specific change added by the server blueprint', () => {
-                assert.fileContent('pom.xml', /dummy-blueprint-property/);
-            });
-        });
-    });
-});
diff --git a/test/blueprint/scoped-blueprint.spec.js b/test/blueprint/scoped-blueprint.spec.js
index fca3d75caf..1f1f0f3e2f 100644
--- a/test/blueprint/scoped-blueprint.spec.js
+++ b/test/blueprint/scoped-blueprint.spec.js
@@ -60,9 +60,7 @@ describe('JHipster application generator with scoped blueprint', () => {
         });
 
         it('blueprint version is saved in .yo-rc.json', () => {
-            assert.JSONFileContent('.yo-rc.json', {
-                'generator-jhipster': { blueprints: [{ name: '@jhipster/generator-jhipster-scoped-blueprint', version: '9.9.9' }] }
-            });
+            assert.fileContent('.yo-rc.json', /"blueprintVersion": "9.9.9"/);
         });
         it('blueprint module and version are in package.json', () => {
             assert.fileContent('package.json', /"@jhipster\/generator-jhipster-scoped-blueprint": "9.9.9"/);
diff --git a/test/cli/cli.spec.js b/test/cli/cli.spec.js
index 445d08894b..eb1e1169f5 100644
--- a/test/cli/cli.spec.js
+++ b/test/cli/cli.spec.js
@@ -45,23 +45,8 @@ describe('jhipster cli test', () => {
             expect(error).to.not.be.null;
             expect(error.code).to.equal(1);
             /* eslint-disable prettier/prettier */
-            expect(stdout.includes('No custom commands found within blueprint: generator-jhipster-bar')).to.be.true;
-            expect(stderr.includes('foo is not a known command')).to.be.true;
-            done();
-        });
-    });
-
-    it('should delegate to blueprint on multiple blueprints command but will not find it', function(done) {
-        this.timeout(4000);
-
-        exec(`${cmd} foo --blueprints bar,baz`, (error, stdout, stderr) => {
-            console.log(error);
-            expect(error).to.not.be.null;
-            expect(error.code).to.equal(1);
-            /* eslint-disable prettier/prettier */
-            expect(stdout.includes('No custom commands found within blueprint: generator-jhipster-bar')).to.be.true;
-            expect(stdout.includes('No custom commands found within blueprint: generator-jhipster-baz')).to.be.true;
-            expect(stderr.includes('foo is not a known command')).to.be.true;
+            expect(stdout.includes('No custom command found within blueprint')).to.be.true;
+            expect(stderr.includes('is not a known command')).to.be.true;
             done();
         });
     });
diff --git a/test/upgrade.spec.js b/test/upgrade.spec.js
index 40159ba87a..7ca02ef770 100644
--- a/test/upgrade.spec.js
+++ b/test/upgrade.spec.js
@@ -164,9 +164,8 @@ describe('JHipster upgrade generator', function() {
         });
 
         it('still contains blueprint information', () => {
-            assert.JSONFileContent('.yo-rc.json', {
-                'generator-jhipster': { blueprints: [{ name: blueprintName, version: blueprintVersion }] }
-            });
+            assert.fileContent('.yo-rc.json', new RegExp(`"blueprint": "${blueprintName}"`));
+            assert.fileContent('.yo-rc.json', new RegExp(`"blueprintVersion": "${blueprintVersion}"`));
             assert.fileContent('package.json', new RegExp(`"${blueprintName}": "${blueprintVersion}"`));
         });
 
diff --git a/test/utils.spec.js b/test/utils.spec.js
index eafc5b106f..4fbb273e70 100644
--- a/test/utils.spec.js
+++ b/test/utils.spec.js
@@ -75,37 +75,6 @@ describe('JHipster Utils', () => {
             });
         });
     });
-    describe('::parseBluePrints', () => {
-        it('does nothing if an array', () => {
-            const expected = [{ name: 'generator-jhipster-foo', version: 'latest' }];
-            const actual = utils.parseBluePrints(expected);
-            assert.deepStrictEqual(actual, expected);
-        });
-        it('adds generator-jhipster prefix if it is absent', () => {
-            const expected = [{ name: 'generator-jhipster-foo', version: 'latest' }];
-            const actual = utils.parseBluePrints('foo');
-            assert.deepStrictEqual(actual, expected);
-        });
-        it('keeps generator-jhipster prefix if it is present', () => {
-            const expected = [{ name: 'generator-jhipster-foo', version: '1.0.1' }];
-            const actual = utils.parseBluePrints('generator-jhipster-foo@1.0.1');
-            assert.deepStrictEqual(actual, expected);
-        });
-        it("doesn't modify scoped package and extracts version", () => {
-            const expected = [{ name: '@corp/foo', version: '1.0.1' }];
-            const actual = utils.parseBluePrints('@corp/foo@1.0.1');
-            assert.deepStrictEqual(actual, expected);
-        });
-        it('parses comma separated list', () => {
-            const expected = [
-                { name: 'generator-jhipster-foo', version: 'latest' },
-                { name: 'generator-jhipster-bar', version: '1.0.1' },
-                { name: '@corp/foo', version: 'latest' }
-            ];
-            const actual = utils.parseBluePrints('foo,bar@1.0.1,@corp/foo');
-            assert.deepStrictEqual(actual, expected);
-        });
-    });
     describe('::normalizeBlueprintName', () => {
         it('adds generator-jhipster prefix if it is absent', () => {
             const generatorName = utils.normalizeBlueprintName('foo');