Skip to content

Commit

Permalink
Support environmental variables in CLI (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
pkosiec committed Sep 12, 2018
1 parent 9ac5934 commit be91354
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 21 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -35,6 +35,7 @@ It's great for:
There are many tools for MongoDB data import out there, including the official one - `mongoimport`. Why should you choose Mongo Seeding?

### Problem #1: JSON used for import data definition

Every tool I found before creating Mongo Seeding support only JSON files. In my opinion, that is not the most convenient way of data definition. The biggest problems are data redundancy and lack of ability to write logic.

Imagine that you want to import 10 very similar documents into `authors` collection. Every document is identical - except the name:
Expand Down Expand Up @@ -195,6 +196,7 @@ The Mongo Seeding CLI and Mongo Seeding Docker Image have TypeScript runtime bui
You can use Mongo Seeding library in your projects with TypeScript runtime and enable importing TS files as well.

### Problem #3: No ultimate solution

Tools like this should be as flexible as possible. Some developers need just CLI tool, and some want to import data programmatically. Before writing Mongo Seeding, I needed a ready-to-use Docker image and found none. Dockerizing an application is easy, but it takes time.

That's why Mongo Seeding consists of:
Expand Down
53 changes: 41 additions & 12 deletions cli/README.md
Expand Up @@ -4,7 +4,9 @@

[![npm version](https://badge.fury.io/js/mongo-seeding-cli.svg)](https://npmjs.org/package/mongo-seeding-cli) [![David](https://img.shields.io/david/pkosiec/mongo-seeding.svg?path=cli)]() [![David](https://img.shields.io/david/dev/pkosiec/mongo-seeding.svg?path=cli)]()

The ultimate solution for populating your MongoDB database. Define the data in JSON or JavaScript. Import collections and documents using command line interface!
The ultimate CLI tool for populating your MongoDB database :rocket:

Define MongoDB documents in JSON, JavaScript or even TypeScript file(s). Import them with command line interface.

## Installation

Expand All @@ -24,29 +26,56 @@ In order to seed your database with data from current directory using default co
seed
```

You can specify custom settings with parameters. The following example imports data from `./example/data` directory using MongoDB connection URI `mongodb://127.0.0.1:27017/mydb`.
You can specify custom settings with command line parameters. The following example imports data from `./example/data` directory using MongoDB connection URI `mongodb://127.0.0.1:27017/mydb`:

```bash
seed -u 'mongodb://127.0.0.1:27017/mydb' -d ./example/data
```

Full configuration options are described in [Command line parameters](#command-line-parameters) section.
You can also use environmental variables to configure the CLI. For example:

```bash
DB_URI='mongodb://127.0.0.1:27017/mydb' seed -d ./example/data
```

Full configuration options are described in [Configuration](#configuration) section.

## Configuration
You can configure data import with command line parameters or environmental variables.

> **Note:** Command line parameters have always a higher priority over environmental variables.
## Command line parameters
You can use the following parameters while using `seed` binary:
You can use the following parameters while using `seed` tool:

| Name | Default Value | Description |
|-------------|----------------|---------------------|
| `--data $PATH` or `-d $PATH` | current directory | Path to directory containing import data |
| `--db-uri $URI` or `-u $URI` | *`undefined`* | If defined, the URI will be used for establishing connection to database, ignoring values defined via other `db-*` parameters (e.g. `db-name`, `db-host`, etc.)
| `--db-protocol $DB_PROTOCOL` | `mongodb` | MongoDB database protocol |
| `--db-host $DB_HOST` | `127.0.0.1` | MongoDB database host |
| `--db-port $DB_PORT` | `27017` | MongoDB database port |
| `--db-name $DB_NAME` | `database` | Name of the database |
| `--db-username $DB_USERNAME` | database | Username for connecting with database that requires authentication |
| `--db-password $DB_PASSWORD` | database | Password for connecting with database that requires authentication |
| `--data {PATH}` or `-d {PATH}` | current directory | Path to directory containing import data |
| `--db-uri {URI}` or `-u {URI}` | *`undefined`* | If defined, the URI will be used for establishing connection to database, ignoring values defined via other `db-*` parameters (e.g. `db-name`, `db-host`, etc.)
| `--db-protocol {DB_PROTOCOL}` | `mongodb` | MongoDB database protocol |
| `--db-host {DB_HOST}` | `127.0.0.1` | MongoDB database host |
| `--db-port {DB_PORT}` | `27017` | MongoDB database port |
| `--db-name {DB_NAME}` | `database` | Name of the database |
| `--db-username {DB_USERNAME}` | *`undefined`* | Username for connecting with database that requires authentication |
| `--db-password {DB_PASSWORD}` | *`undefined`* | Password for connecting with database that requires authentication |
| `--drop-database` | `false` | Dropping entire database before data import |
| `--drop-collection` | `false` | Dropping every collection that is being imported |
| `--replace-id` | `false` | Replacing `id` property with `_id` for every document during data import |
| `--reconnect-timeout` | `10` (seconds) | Maximum time of waiting for successful MongoDB connection|
| `--help` or `-h` | n/a | Help

## Environmental variables
You can use the following environmental variables while using `seed` tool:

| Name | Default Value | Description |
|-------------|----------------|---------------------|
| DB_URI | *`undefined`* | If defined, the URI is used for establishing connection to database, ignoring values given in `DB_*` environmental variables (e.g. `DB_HOST`, `DB_PORT`, etc.).
| DB_HOST | `127.0.0.1` | MongoDB database host |
| DB_PORT | `27017` | MongoDB database port |
| DB_NAME | `database` | Name of the database |
| DB_USERNAME | *`undefined`* | Username for connecting with database that requires authentication |
| DB_PASSWORD | *`undefined`* | Password for connecting with database that requires authentication |
| DROP_DATABASE | `false` | Dropping entire database before data import |
| DROP_COLLECTION | `false` | Dropping every collection that is being imported |
| REPLACE_ID | `false` | Replacing `id` property with `_id` for every document during import; useful for ORMs |
| RECONNECT_TIMEOUT | `10` | Maximum time, in which app should keep trying connecting to database |
6 changes: 6 additions & 0 deletions cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion cli/package.json
Expand Up @@ -59,11 +59,13 @@
"@types/node": "^10.9.0",
"command-line-args": "^5.0.0",
"command-line-usage": "^5.0.0",
"extend": "^3.0.2",
"mongo-seeding": "^2.2.0",
"ts-node": "^7.0.1",
"typescript": "^3.0.0"
},
"devDependencies": {
"@types/command-line-args": "^5.0.0"
"@types/command-line-args": "^5.0.0",
"@types/extend": "^3.0.0"
}
}
24 changes: 18 additions & 6 deletions cli/src/index.ts
@@ -1,37 +1,49 @@
// Enable debug output for Mongo Seeding
process.env.DEBUG = 'mongo-seeding';

import * as commandLineArgs from 'command-line-args';
import * as extend from 'extend';
import { seedDatabase } from 'mongo-seeding';
import {
populateOptions,
populateCommandLineOptions,
optionsDefinition,
shouldShowHelp,
CommandLineOptions,
validateOptions,
populateEnvOptions,
} from './options';
import { showHelp } from './help';

import * as commandLineArgs from "command-line-args";
import { AppConfig, DeepPartial } from 'mongo-seeding/dist/common';

export const run = async () => {
const options: CommandLineOptions = commandLineArgs(optionsDefinition) as CommandLineOptions;
const options: CommandLineOptions = commandLineArgs(
optionsDefinition,
) as CommandLineOptions;

if (shouldShowHelp(options)) {
showHelp();
return;
}

const partialConfig = populateOptions(options);
const config = getConfig(options);

try {
validateOptions(options);
await seedDatabase(partialConfig);
await seedDatabase(config);
} catch (err) {
printError(err);
}

process.exit(0);
};

const getConfig = (options: CommandLineOptions): DeepPartial<AppConfig> => {
const commandLineConfig = populateCommandLineOptions(options);
const envConfig = populateEnvOptions();
const config = {};
return extend(true, config, envConfig, commandLineConfig);
};

const printError = (err: Error) => {
console.error(`Error ${err.name}: ${err.message}`);
};
27 changes: 25 additions & 2 deletions cli/src/options.ts
Expand Up @@ -120,7 +120,7 @@ const validatePositiveNumber = (variable: number | undefined, name: string) => {
}
};

export const populateOptions = (
export const populateCommandLineOptions = (
options: CommandLineOptions,
): DeepPartial<AppConfig> => ({
database: {
Expand All @@ -137,5 +137,28 @@ export const populateOptions = (
dropCollection: options['drop-collection'],
replaceIdWithUnderscoreId: options['replace-id'],
reconnectTimeoutInSeconds: options['reconnect-timeout'],
supportedExtensions: ["js", "json", "ts"]
});

export const populateEnvOptions = (): DeepPartial<AppConfig> => {
const env = process.env;
const envOptions: DeepPartial<AppConfig> = {
database: {
protocol: env.DB_PROTOCOL ? String(env.DB_PROTOCOL) : undefined,
host: env.DB_HOST ? String(env.DB_HOST) : undefined,
port: env.DB_PORT ? Number(env.DB_PORT) : undefined,
name: env.DB_NAME ? String(env.DB_NAME) : undefined,
username: env.DB_USERNAME ? String(env.DB_USERNAME) : undefined,
password: env.DB_PASSWORD ? String(env.DB_PASSWORD) : undefined,
},
databaseConnectionUri: env.DB_URI ? String(env.DB_URI) : undefined,
dropDatabase: env.DROP_DATABASE === 'true',
dropCollection: env.DROP_COLLECTION === 'true',
replaceIdWithUnderscoreId: env.REPLACE_ID === 'true',
supportedExtensions: ['ts', 'js', 'json'],
reconnectTimeoutInSeconds: env.RECONNECT_TIMEOUT
? Number(env.RECONNECT_TIMEOUT)
: undefined,
};

return envOptions;
};

0 comments on commit be91354

Please sign in to comment.