Skip to content

Commit 661c4c0

Browse files
committed
feat: added runCli function
1 parent 8a6a7f1 commit 661c4c0

5 files changed

Lines changed: 126 additions & 100 deletions

File tree

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@axonotes/axogen",
3-
"version": "0.4.1",
3+
"version": "0.4.2",
44
"description": "TypeScript-native configuration system that unifies typed environment variables, code generation, and task management for any project",
55
"type": "module",
66
"main": "dist/index.cjs",
@@ -27,8 +27,8 @@
2727
],
2828
"scripts": {
2929
"build": "bun run build.ts",
30-
"preview": "bun run format && bun run build && bun link",
31-
"publish": "bun run format && bun run build && bun publish",
30+
"preview": "bun run format && bun test && bun run build && bun link",
31+
"publish": "bun run format && bun test && bun run build && bun publish",
3232
"test:local": "bun run build && ./bin/axogen --version",
3333
"docs:start": "cd website && bun run start",
3434
"docs:build": "cd website && bun run build",

src/cli-helpers/index.ts

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,108 @@
1+
import {Command} from "commander";
2+
13
export * from "./runner";
24

35
import {spawn} from "node:child_process";
4-
import {pretty} from "../utils/pretty";
6+
import {
7+
configurePretty,
8+
LogLevel,
9+
pretty,
10+
setTheme,
11+
themes,
12+
} from "../utils/pretty";
13+
import {getVersion} from "../version.ts";
14+
import type {ThemeName} from "../utils/themes.ts";
15+
import type {ZodAxogenConfig} from "../config/types";
16+
import {loadConfig} from "../config/loader.ts";
17+
import {createGenerateCommand} from "./commands/generate.ts";
18+
import {createThemeCommand} from "./commands/theme.ts";
19+
import {buildDynamicCommands} from "./builder.ts";
20+
21+
/**
22+
* Creates and configures the main CLI application with all commands and options.
23+
* Sets up global options, pre-action hooks for configuration, and dynamic commands.
24+
* @returns Promise that resolves to the configured Command instance
25+
*/
26+
export async function createCLI(): Promise<Command> {
27+
const cli = new Command();
28+
29+
cli.name("axogen")
30+
.description("TypeScript-native configuration and task management")
31+
.version(getVersion());
32+
33+
// Global options
34+
cli.option("--verbose", "Enable verbose logging");
35+
cli.option("--quiet", "Suppress non-essential output");
36+
cli.option("--no-color", "Disable colored output");
37+
cli.option(
38+
"--theme <name>",
39+
`Color theme to use (${Object.keys(themes).join(", ")})`,
40+
process.env.AXOGEN_THEME || "doom-one" // Default theme
41+
);
42+
43+
// Configure pretty printing based on global options early
44+
cli.hook("preAction", (thisCommand) => {
45+
const opts = thisCommand.optsWithGlobals();
46+
47+
// Validate and set theme
48+
if (opts.theme && !(opts.theme in themes)) {
49+
console.error(
50+
`❌ Invalid theme "${opts.theme}". Available themes: ${Object.keys(themes).join(", ")}`
51+
);
52+
process.exit(1);
53+
}
54+
55+
configurePretty({
56+
verbose: opts.verbose || false,
57+
logLevel: opts.quiet
58+
? LogLevel.WARN
59+
: opts.verbose
60+
? LogLevel.DEBUG
61+
: LogLevel.INFO,
62+
colorEnabled:
63+
!opts.noColor && !process.env.NO_COLOR && process.stdout.isTTY,
64+
theme: opts.theme as ThemeName,
65+
});
66+
67+
if (opts.theme) {
68+
setTheme(opts.theme as ThemeName);
69+
}
70+
});
71+
72+
// Load config once
73+
let config: ZodAxogenConfig;
74+
try {
75+
config = await loadConfig();
76+
} catch (error) {
77+
// If config fails to load, still allow basic commands
78+
pretty.warn(
79+
`Could not load config: ${error instanceof Error ? error.message : error}`
80+
);
81+
config = {};
82+
}
83+
84+
// Add built-in commands (pass config to them)
85+
cli.addCommand(createGenerateCommand(config));
86+
cli.addCommand(createThemeCommand());
87+
88+
// Add dynamic commands from config to the "run" command
89+
const runCommand = new Command("run").description(
90+
"Run custom commands defined in configuration"
91+
);
92+
93+
if (config.commands && Object.keys(config.commands).length > 0) {
94+
buildDynamicCommands(runCommand, config);
95+
} else {
96+
// Add a default action to show available commands or a helpful message
97+
runCommand.action(() => {
98+
pretty.info("No commands defined in config");
99+
});
100+
}
101+
102+
cli.addCommand(runCommand);
103+
104+
return cli;
105+
}
5106

6107
/**
7108
* Execute a shell command and capture output.

src/cli.ts

Lines changed: 2 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -4,101 +4,8 @@
44
* options, and hooks for logging, theming, and configuration loading.
55
*/
66

7-
import {Command} from "commander";
8-
import {getVersion} from "./version";
9-
import {loadConfig} from "./config/loader.ts";
10-
import {buildDynamicCommands} from "./cli-helpers/builder";
11-
import {createGenerateCommand} from "./cli-helpers/commands/generate";
12-
import {createThemeCommand} from "./cli-helpers/commands/theme";
13-
import {pretty, configurePretty, LogLevel, setTheme} from "./utils/pretty";
14-
import {themes, type ThemeName} from "./utils/themes";
15-
import type {ZodAxogenConfig} from "./config/types";
16-
17-
/**
18-
* Creates and configures the main CLI application with all commands and options.
19-
* Sets up global options, pre-action hooks for configuration, and dynamic commands.
20-
* @returns Promise that resolves to the configured Command instance
21-
*/
22-
async function createCLI(): Promise<Command> {
23-
const cli = new Command();
24-
25-
cli.name("axogen")
26-
.description("TypeScript-native configuration and task management")
27-
.version(getVersion());
28-
29-
// Global options
30-
cli.option("--verbose", "Enable verbose logging");
31-
cli.option("--quiet", "Suppress non-essential output");
32-
cli.option("--no-color", "Disable colored output");
33-
cli.option(
34-
"--theme <name>",
35-
`Color theme to use (${Object.keys(themes).join(", ")})`,
36-
process.env.AXOGEN_THEME || "doom-one" // Default theme
37-
);
38-
39-
// Configure pretty printing based on global options early
40-
cli.hook("preAction", (thisCommand) => {
41-
const opts = thisCommand.optsWithGlobals();
42-
43-
// Validate and set theme
44-
if (opts.theme && !(opts.theme in themes)) {
45-
console.error(
46-
`❌ Invalid theme "${opts.theme}". Available themes: ${Object.keys(themes).join(", ")}`
47-
);
48-
process.exit(1);
49-
}
50-
51-
configurePretty({
52-
verbose: opts.verbose || false,
53-
logLevel: opts.quiet
54-
? LogLevel.WARN
55-
: opts.verbose
56-
? LogLevel.DEBUG
57-
: LogLevel.INFO,
58-
colorEnabled:
59-
!opts.noColor && !process.env.NO_COLOR && process.stdout.isTTY,
60-
theme: opts.theme as ThemeName,
61-
});
62-
63-
if (opts.theme) {
64-
setTheme(opts.theme as ThemeName);
65-
}
66-
});
67-
68-
// Load config once
69-
let config: ZodAxogenConfig;
70-
try {
71-
config = await loadConfig();
72-
} catch (error) {
73-
// If config fails to load, still allow basic commands
74-
pretty.warn(
75-
`Could not load config: ${error instanceof Error ? error.message : error}`
76-
);
77-
config = {};
78-
}
79-
80-
// Add built-in commands (pass config to them)
81-
cli.addCommand(createGenerateCommand(config));
82-
cli.addCommand(createThemeCommand());
83-
84-
// Add dynamic commands from config to the "run" command
85-
const runCommand = new Command("run").description(
86-
"Run custom commands defined in configuration"
87-
);
88-
89-
if (config.commands && Object.keys(config.commands).length > 0) {
90-
buildDynamicCommands(runCommand, config);
91-
} else {
92-
// Add a default action to show available commands or a helpful message
93-
runCommand.action(() => {
94-
pretty.info("No commands defined in config");
95-
});
96-
}
97-
98-
cli.addCommand(runCommand);
99-
100-
return cli;
101-
}
7+
import {pretty} from "./utils/pretty";
8+
import {createCLI} from "./cli-helpers";
1029

10310
// Run CLI
10411
createCLI()

src/index.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@
44
* commands, and target generation.
55
*/
66

7+
import {createCLI} from "./cli-helpers";
8+
import {pretty} from "./utils/pretty.ts";
9+
10+
/**
11+
* Runs the CLI with the provided arguments (or process.argv if not provided).
12+
* This function can be imported and called from other packages.
13+
* @param argv Optional array of command line arguments
14+
*/
15+
export async function runCLI(argv?: string[]): Promise<void> {
16+
try {
17+
const cli = await createCLI();
18+
await cli.parseAsync(argv || process.argv);
19+
} catch (error) {
20+
pretty.error(`Failed to initialize CLI: ${error}`);
21+
process.exit(1);
22+
}
23+
}
24+
725
/** Core CLI helper functions for command execution */
826
export {exec, executeCommand, liveExec} from "./cli-helpers";
927

website/docs/roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
- [x] `schema` validation option
137137
- [x] `condition` conditional generation
138138
- [x] `generate_meta` metadata comments
139-
- [ ] `backup` file backup option
139+
- [x] `backup` file backup option
140140
- [x] Template-specific options
141141

142142
### Enhanced CLI Features

0 commit comments

Comments
 (0)