diff --git a/docs/api/salty-dog.main.md b/docs/api/salty-dog.main.md
deleted file mode 100644
index 68f4199..0000000
--- a/docs/api/salty-dog.main.md
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-[Home](./index.md) > [salty-dog](./salty-dog.md) > [main](./salty-dog.main.md)
-
-## main() function
-
-Signature:
-
-```typescript
-export declare function main(argv: Array): Promise;
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| argv | Array<string>
| |
-
-Returns:
-
-`Promise`
-
diff --git a/docs/api/salty-dog.md b/docs/api/salty-dog.md
index 72684c9..f83d612 100644
--- a/docs/api/salty-dog.md
+++ b/docs/api/salty-dog.md
@@ -4,9 +4,3 @@
## salty-dog package
-## Functions
-
-| Function | Description |
-| --- | --- |
-| [main(argv)](./salty-dog.main.md) | |
-
diff --git a/src/app.ts b/src/app.ts
new file mode 100644
index 0000000..4329cb7
--- /dev/null
+++ b/src/app.ts
@@ -0,0 +1,83 @@
+import { createLogger } from 'bunyan';
+import { showCompletionScript } from 'yargs';
+
+import { loadConfig } from './config';
+import { CONFIG_ARGS_NAME, CONFIG_ARGS_PATH, MODE, parseArgs, VALID_MODES } from './config/args';
+import { YamlParser } from './parser/YamlParser';
+import { createRuleSelector, createRuleSources, loadRules, resolveRules, visitRules } from './rule';
+import { loadSource, writeSource } from './source';
+import { VERSION_INFO } from './version';
+import { VisitorContext } from './visitor/VisitorContext';
+
+const STATUS_SUCCESS = 0;
+const STATUS_ERROR = 1;
+const STATUS_MAX = 255;
+
+export async function main(argv: Array): Promise {
+ const { args, mode } = await parseArgs(argv);
+ if (mode === MODE.complete) {
+ showCompletionScript();
+ return STATUS_SUCCESS;
+ }
+
+ const config = await loadConfig(args[CONFIG_ARGS_NAME], ...args[CONFIG_ARGS_PATH]);
+
+ const logger = createLogger(config.data.logger);
+ logger.info(VERSION_INFO, 'version info');
+ logger.info({ args, mode }, 'main arguments');
+
+ // check mode
+ if (!VALID_MODES.has(mode)) {
+ logger.error({ mode }, 'unsupported mode');
+ return STATUS_ERROR;
+ }
+
+ const ctx = new VisitorContext({
+ innerOptions: {
+ coerce: args.coerce,
+ defaults: args.defaults,
+ mutate: mode === MODE.fix,
+ },
+ logger,
+ });
+
+ const ruleSelector = createRuleSelector(args);
+ const ruleSources = createRuleSources(args);
+
+ const loadedRules = await loadRules(ruleSources, ctx);
+ const activeRules = await resolveRules(loadedRules, ruleSelector);
+
+ if (mode === MODE.list) {
+ logger.info({
+ activeCount: activeRules.length,
+ activeRules,
+ loadedCount: loadedRules.length,
+ loadedRules,
+ ruleSelector,
+ ruleSources,
+ }, 'listing active rules');
+ return STATUS_SUCCESS;
+ }
+
+ const parser = new YamlParser();
+ const source = await loadSource(args.source);
+ const docs = parser.parse(source);
+
+ for (const data of docs) {
+ await visitRules(ctx, activeRules, data);
+ }
+
+ if (ctx.errors.length === 0) {
+ logger.info('all rules passed');
+ const output = parser.dump(...docs);
+ await writeSource(args.dest, output);
+ return STATUS_SUCCESS;
+ }
+
+ logger.error({ count: ctx.errors.length, errors: ctx.errors }, 'some rules failed');
+ if (args.count) {
+ return Math.min(ctx.errors.length, STATUS_MAX);
+ }
+
+ return STATUS_ERROR;
+}
diff --git a/src/index.ts b/src/index.ts
index ca0d94b..154ca87 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,89 +1,12 @@
-import { createLogger } from 'bunyan';
-import { showCompletionScript } from 'yargs';
+import { main } from './app';
-import { loadConfig } from './config';
-import { CONFIG_ARGS_NAME, CONFIG_ARGS_PATH, MODE, parseArgs, VALID_MODES } from './config/args';
-import { YamlParser } from './parser/YamlParser';
-import { createRuleSelector, createRuleSources, loadRules, resolveRules, visitRules } from './rule';
-import { loadSource, writeSource } from './source';
-import { VERSION_INFO } from './version';
-import { VisitorContext } from './visitor/VisitorContext';
-
-const STATUS_SUCCESS = 0;
const STATUS_ERROR = 1;
-const STATUS_MAX = 255;
-export async function main(argv: Array): Promise {
- const { args, mode } = await parseArgs(argv);
- if (mode === MODE.complete) {
- showCompletionScript();
- return STATUS_SUCCESS;
- }
-
- const config = await loadConfig(args[CONFIG_ARGS_NAME], ...args[CONFIG_ARGS_PATH]);
-
- const logger = createLogger(config.data.logger);
- logger.info(VERSION_INFO, 'version info');
- logger.info({ args, mode }, 'main arguments');
-
- // check mode
- if (!VALID_MODES.has(mode)) {
- logger.error({ mode }, 'unsupported mode');
- return STATUS_ERROR;
- }
-
- const ctx = new VisitorContext({
- innerOptions: {
- coerce: args.coerce,
- defaults: args.defaults,
- mutate: mode === MODE.fix,
- },
- logger,
- });
-
- const ruleSelector = createRuleSelector(args);
- const ruleSources = createRuleSources(args);
-
- const loadedRules = await loadRules(ruleSources, ctx);
- const activeRules = await resolveRules(loadedRules, ruleSelector);
-
- if (mode === MODE.list) {
- logger.info({
- activeCount: activeRules.length,
- activeRules,
- loadedCount: loadedRules.length,
- loadedRules,
- ruleSelector,
- ruleSources,
- }, 'listing active rules');
- return STATUS_SUCCESS;
- }
-
- const parser = new YamlParser();
- const source = await loadSource(args.source);
- const docs = parser.parse(source);
-
- for (const data of docs) {
- await visitRules(ctx, activeRules, data);
- }
-
- if (ctx.errors.length === 0) {
- logger.info('all rules passed');
- const output = parser.dump(...docs);
- await writeSource(args.dest, output);
- return STATUS_SUCCESS;
- }
-
- logger.error({ count: ctx.errors.length, errors: ctx.errors }, 'some rules failed');
- if (args.count) {
- return Math.min(ctx.errors.length, STATUS_MAX);
- }
-
- return STATUS_ERROR;
-}
-
-main(process.argv).then((status) => process.exit(status)).catch((err) => {
- /* eslint-disable-next-line no-console */
+/**
+ * This is the main entry-point to the program and the only file not included in the main bundle.
+ */
+main(process.argv).then((status) => process.exit(status)).catch((err: Error) => {
+ // eslint-disable-next-line no-console
console.error('uncaught error during main:', err);
process.exit(STATUS_ERROR);
});