Add a CLI to your JHipster blueprint
Tags: jhipster, cli, generator
Published: 2021-08-13 10:53:37

Hello my fellow hipsters. Who has never dreamt to have his own CLI for his blueprint? This is what I want to show you today.

## JHipster versions and your blueprint

If like me, you like to play with many JHipster versions, switching between your fork and official JHipster releases you probably struggle with version management. How to be sure my JHipster command will launch the version I need? And how I’ll be sure my users will not have bad experiences when using my blueprint?

## How a CLI can improve your blueprint experience

When you generate a project with the JHipster command line with your blueprint you type that:
``` bash
jhipster --blueprint myBlueprint
```

This means you want to launch JHipster with a blueprint called “myBlueprint” using a global JHipster installation, or the local one. In both cases you can’t be sure the good version will be used and your blueprint as compatibility with a specific version.

## Create your blueprint and its CLI

First, you need to start by creating your own blueprint, you can use the blueprint generator here : [https://github.com/jhipster/generator-jhipster-blueprint](https://github.com/jhipster/generator-jhipster-blueprint)

Then we need to add a cli folder that will contain the node.js code. I split it into two files, the app.js (which will launch JHipster for us) and the utils.js (which will contain some functions).

* app.js

``` bash
    #!/usr/bin/env node
    
    **const **fork = require('child_process').fork;
    **const **utils = require('./utils');
    
    **const **jhipsterPath = utils.generateJHipsterPath('../node_modules/generator-jhipster/cli/jhipster');
    **const **args = utils.initArguments('--blueprint', 'myBlueprint');
    
    utils.printBanner();
    fork(jhipsterPath, args);
```

* utils.js

``` bash
    #!/usr/bin/env node
    
    **const **p = require('path');
    **const **chalk = require('chalk');
    
    **function **generateJHipsterPath(relativePath) {
        **const **absolutePath = p.join(__dirname, relativePath);
        **return **p.normalize(absolutePath);
    }
    
    **function **initArguments(...args) {
        **const **inputArgs = _removeNodeArgsInProcessArgv();
    
        **return **args.concat(inputArgs);
    }
    
    **function **_removeNodeArgsInProcessArgv() {
        **return **process.argv ? process.argv.slice(2) : [];
    }
    
    **function **printBanner() {
        /* eslint-disable no-console */
        console.log('\n');
        console.log(`${chalk.yellow('Welcome to myBlueprint JHipster Generator')}\n`);
    
        console.log('This CLI will call JHipster with myBlueprint blueprint for you. You could use all JHipster CLI options.\n');
    
        console.log(`${chalk.redBright('Ready ?... ')}${chalk.blueBright("Let's go!")}\n`);
    
        console.log(
            chalk.green(' _______________________________________________________________________________________________________________\n')
        );
        /* eslint-enable no-console */
    }
    
    module.exports = {
        generateJHipsterPath,
        initArguments,
        printBanner
    };
```

This code will generate the right JHipster path (from our node_modules) and launch it with the follow argument (and print a personal header before the JHipster’s one):
`-- blueprint myBlueprint`

When this is done, we just need to register the node.js code as “bin” in our package.json :

``` json
    "bin": {
      "myBlueprint": "./cli/app.js"
    }
```

And add the cli folder in the “files” entry (to add it when doing a npm publish):
``` json
    "files": [
      "generators",
      "cli"
    ]
```

## Link your blueprint

As long as your blueprint is not published in the npm registry you need to link it.
`npm link`

for yours final users a simple install is necessary
`npm i -g generator-jhipster-myBlueprint`

## Use your CLI

In a terminal, create a new folder and type your blueprint command
`myBlueprint`

![We can see that the JHipster version used is 5.4.0, same as our package.json](https://cdn-images-1.medium.com/max/5480/1*jgNFpO8u19yXqhdghTgb2g.png)*We can see that the JHipster version used is 5.4.0, same as our package.json*

You can, of course, add options like we used to do with the original JHipster CLI:
`myBlueprint --skip-client --skip-git --skip-checks`

## Conclusion

I hope this article will help you, you can find all the source code in my github repository here:
[https://github.com/avdev4j/myBlueprint](https://github.com/avdev4j/myBlueprint)

Feel free to use it and contribute to jhipster.tech and [https://github.com/jhipster](https://github.com/jhipster)