npm package: @korabo/genversion-plus
Description: A command line utility to read version from package.json and attach it into your module as a property
Author: TAKEUCHI Shinichi
Latest version: 1.0.1

# genversion-plus

[![npm version](https://badge.fury.io/js/%40korabo%2Fgenversion-plus.svg)](https://badge.fury.io/js/%40korabo%2Fgenversion-plus)

![Logo](doc/logo.png?raw=true "Abracadabra...and behold!")

So you want `yourmodule.version+` to follow the version in package.json but are tired of updating it manually every time the version changes? On server side, you could just `require('package.json').version` but on client side and/or build deployments from typescript however, that would expose the versions of your dependencies and possibly other sensitive data too, so [it is usually a naughty thing to do](https://stackoverflow.com/a/10855054/638546)! How to import only the version+? Genversion-plus to the rescue!

## Try it out

Usage is simple:

    $ cd yourmodule
    $ npm install -g @korabo/genversion-plus
    $ genversion-plus lib/version.js

Voilà! The new lib/version.js:

    exports.version = '0.9.1'
    exports.buildTime = '2021-02-08T11:43:32.651Z'
    exports.comment = ''
    exports.author = 'TAKEUCHI Shinichi'

Use flags to match your coding style. `$ genversion-plus --gen es6 --semi lib/version.ts`  creates:

    export const version = '0.9.1';
    export const buildTime = '2021-02-08T11:43:32.651Z';
    export const comment = '';
    export const author = 'TAKEUCHI Shinichi';

By default, genversion-plus reads the version from the `package.json` nearest to the target `version.js`. In case your project contains multiple `package.json` files along the target path you can specify the one with `--source <path>` parameter. An custom template can be used to generate `version.js` or `version.ts`

## Integrate to your build

First install via [NPM repository](https://www.npmjs.com/package/@korabo/genversion-plus).

    $ npm install @korabo/genversion-plus --save-dev

Genversion-plus works by first reading the current version from package.json and then generating a simple CommonJS module file that exports the version string. For safety, the version file begins with a signature that tells genversion-plus that the file can be overwritten.

    // generated by genversion-plus
    exports.version = '1.2.3'


Now, your job is to 1) choose a path for the version file, 2) require() the new file into your module, and 3) add genversion-plus as a part of your build or release pipeline. For example, let us choose the path 'lib/version.js' and require it in yourmodule/index.js:

    ...
    var myversion = require('./lib/version')
    exports.version = myversion.version
    ...

If you use `--es6` flag:

    ...
    import { version } from './lib/version'
    export const version
    ...

Then, let us integrate genversion-plus into your build task.

    "scripts": {
      "build": "genversion-plus lib/version.js && other build stuff"
    }

The target path is given as the first argument. If the file already exists and has been previously created by genversion-plus, it is replaced with the new one.

Finished! Now your module has a version property that matches with package.json and is updated every time you build the project.

    > var yourmodule = require('yourmodule')
    > yourmodule.version
    '1.2.3'

Great! Having a version property in your module is very convenient for debugging. More than once we have needed to painstakingly debug a module, just to find out that it was a cached old version that caused the error. An inspectable version property would have helped a big time.


## Command line API

Directly from `$ genversion-plus --help`:

    Usage: genversion-plus [options] <target>

    Generates a version module at the target filepath.

    Options:
      -V, --version              output the version number
      -v, --verbose              output the new version
      -s, --semi                 use semicolons in generated code
      -g, --gen <cjs|es6>        use cjs or es6 ,,, syntax in generating code
      -p, --source <path>        search for package.json along a custom path
      -t, --template <filepath>  use given file as generation template
      -m, --message <comment>    build comment to be generated
      -a, --author <author>      author name to be generated
      -h, --help                 output usage information

## Node API

You can also use genversion-plus within your code:

    var gv = require('genversion-plus');

The available properties and functions are listed below.


### genversion-plus.check(targetPath, callback)

Check if it is possible to generate the version module into `targetPath`.

**Parameters:**

- *targetPath:* string. An absolute or relative file path. Relative to `process.cwd()`.
- *callback:* function (err, doesExist, isByGenversion). Parameter *doesExist* is a boolean that is true if a file at targetPath already exists. Parameter *isByGenversion* is a boolean that is true if the existing file seems like it has been generated by genversion-plus.

**Example:**

    gv.check('lib/version.js', function (err, doesExist, isByGenversion) {
      if (err) {
        throw err;
      }

      if (isByGenversion) {
        gv.generate(...)
      }
      ...
    });


### genversion-plus.generate(targetPath, opts, callback)

Read the version property from the nearest `package.json` along the `targetPath` and then generate a version module file at `targetPath`. A custom path to `package.json` can be specified with `opts.source`.

**Parameters:**

- *targetPath:* string. An absolute or relative file path. Relative to `process.cwd()`.
- *opts:* optional options. Available keys are:
  - *source:* optional string. An absolute or relative path to a file or directory. Defaults to the value of `targetPath`.
  - *useSemicolon:* optional boolean. Defaults to `false`.
  - *genSyntax:* optional string <cjs|es6>. Defaults to `cjs`.
  - *template:* optional string. An absolute or relative path to a template-file. Defaults to the value of `module-source:lib/template.txt`.
- *callback:* function (err, version). Parameter *version* is the version string read from `package.json`. Parameter *err* is non-null if `package.json` cannot be found, its version is not a string, or writing the module fails.

**Examples:**

    gv.generate('lib/version.js', function (err, version) {
      if (err) {
        throw err;
      }
      console.log('Sliding into', version, 'like a sledge.');
    });

    gv.generate('src/v.js', { useSemicolon: true }, function (err) {
      if (err) { throw err }
      console.log('Generated version file with a semicolon.')
    })



### genversion-plus.version

The version string of genversion-plus module in [semantic versioning](http://semver.org/) format. Generated with genversion-plus itself, of course.


## Projects using genversion-plus

- [genversion-plus](https://www.npmjs.com/package/@korabo/genversion-plus)

Do you use genversion-plus in your project? We are happy to mention it in the list. Just hit us with an issue or a pull request.

## Related projects

- [genversion](https://www.npmjs.com/package/genversion)
- [versiony](https://github.com/ciena-blueplanet/versiony) for version increments
- [package-json-versionify](https://github.com/nolanlawson/package-json-versionify) for browserify builds


## For developers

Run test suite:

    $ pnpm run test

To make release, bump the version in `package.json` and run:

    $ pnpm run release && npm public-publish


## License

[MIT](LICENSE)