Skip to content

Commit 1debfd5

Browse files
committed
improve new command; remove Config::getInstance in CLI
2 parents 111c8c5 + 04d3f39 commit 1debfd5

2 files changed

Lines changed: 113 additions & 62 deletions

File tree

src/commands/NewCommand.cpp

Lines changed: 92 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -993,74 +993,78 @@ int main()
993993
static std::string make_readme_app(const std::string &projectName)
994994
{
995995
std::string readme;
996-
readme.reserve(7200);
996+
readme.reserve(8000);
997997

998998
readme += "# " + projectName + "\n\n";
999999
readme += "Minimal Vix.cpp application.\n\n";
10001000

1001-
readme += "## Build & Run\n\n";
1001+
// ---------------------------
1002+
// Quick start (IMPORTANT)
1003+
// ---------------------------
1004+
readme += "## Quick start\n\n";
10021005
readme += "```bash\n";
1006+
readme += "cd " + projectName + "\n";
1007+
readme += "cp .env.example .env\n";
10031008
readme += "vix build\n";
10041009
readme += "vix run\n";
10051010
readme += "```\n\n";
10061011

1012+
readme += "Then open:\n\n";
1013+
readme += "```\n";
1014+
readme += "http://localhost:8080\n";
1015+
readme += "```\n\n";
1016+
1017+
// ---------------------------
1018+
// Dependencies
1019+
// ---------------------------
10071020
readme += "## Dependencies\n\n";
1008-
readme += "This project includes a `vix.json` manifest.\n\n";
1009-
readme += "Dependency workflow:\n\n";
1010-
readme += "- `vix.json` stores declared dependency requirements\n";
1011-
readme += "- `vix.lock` stores exact resolved versions for reproducible installs\n";
1012-
readme += "- `vix add` updates both `vix.json` and `vix.lock`\n";
1013-
readme += "- `vix install` installs dependencies from `vix.lock`\n\n";
1021+
readme += "This project uses a `vix.json` manifest.\n\n";
1022+
1023+
readme += "Workflow:\n\n";
1024+
readme += "- `vix add <pkg>` → add dependency\n";
1025+
readme += "- `vix install` → install dependencies\n";
1026+
readme += "- `vix.lock` → ensures reproducible builds\n\n";
10141027

10151028
readme += "Example:\n\n";
10161029
readme += "```bash\n";
10171030
readme += "vix add gk/json@^1.0.0\n";
10181031
readme += "vix install\n";
10191032
readme += "```\n\n";
10201033

1021-
readme += "If `.vix/vix_deps.cmake` exists, local registry dependencies can be included from CMake automatically.\n\n";
1022-
1034+
// ---------------------------
1035+
// Tasks
1036+
// ---------------------------
10231037
readme += "## Tasks\n\n";
1024-
readme += "This template also defines default tasks in `vix.json`.\n\n";
1038+
readme += "Run project tasks:\n\n";
10251039

1026-
readme += "Run them with:\n\n";
10271040
readme += "```bash\n";
10281041
readme += "vix task <name>\n";
10291042
readme += "```\n\n";
10301043

1031-
readme += "Examples:\n\n";
1044+
readme += "Common tasks:\n\n";
10321045
readme += "```bash\n";
1033-
readme += "vix task fmt\n";
1034-
readme += "vix task check\n";
1035-
readme += "vix task test\n";
10361046
readme += "vix task dev\n";
1047+
readme += "vix task test\n";
10371048
readme += "vix task ci\n";
10381049
readme += "```\n\n";
10391050

1040-
readme += "The generated app manifest includes tasks such as:\n\n";
1041-
readme += "- `fmt`\n";
1042-
readme += "- `check`\n";
1043-
readme += "- `test`\n";
1044-
readme += "- `dev`\n";
1045-
readme += "- `ci`\n";
1046-
readme += "- `release`\n";
1047-
readme += "- `package`\n\n";
1048-
1049-
readme += "You can edit `vix.json` to customize commands, variables, environments, and task pipelines.\n\n";
1051+
readme += "Edit `vix.json` to customize tasks and pipelines.\n\n";
10501052

1053+
// ---------------------------
1054+
// Configuration
1055+
// ---------------------------
10511056
readme += "## Configuration\n\n";
1052-
readme += "Vix applications use `.env` files for project configuration.\n";
1053-
readme += "This lets you configure ports, database settings, logging, WebSocket options, and other runtime values without changing your C++ code.\n\n";
10541057

1055-
readme += "### Project env file\n\n";
1056-
readme += "Create a file at the project root:\n\n";
1057-
readme += "```\n";
1058-
readme += ".env\n";
1058+
readme += "Vix uses `.env` files for configuration.\n\n";
1059+
1060+
readme += "Start by copying the example:\n\n";
1061+
readme += "```bash\n";
1062+
readme += "cp .env.example .env\n";
10591063
readme += "```\n\n";
10601064

10611065
readme += "Example:\n\n";
10621066
readme += "```env\n";
1063-
readme += "SERVER_PORT=8081\n";
1067+
readme += "SERVER_PORT=8080\n";
10641068
readme += "DATABASE_ENGINE=mysql\n";
10651069
readme += "DATABASE_DEFAULT_HOST=127.0.0.1\n";
10661070
readme += "DATABASE_DEFAULT_PORT=3306\n";
@@ -1071,24 +1075,17 @@ int main()
10711075
readme += "WAF_MODE=basic\n";
10721076
readme += "```\n\n";
10731077

1074-
readme += "### Layered env files\n\n";
1075-
readme += "Vix supports layered env files.\n";
1076-
readme += "Depending on your environment, you can use files such as:\n\n";
1077-
readme += "- `.env`\n";
1078-
readme += "- `.env.local`\n";
1079-
readme += "- `.env.production`\n";
1080-
readme += "- `.env.production.local`\n\n";
1078+
// ---------------------------
1079+
// Code usage
1080+
// ---------------------------
1081+
readme += "## Using configuration in code\n\n";
10811082

1082-
readme += "This makes it easy to separate local development and production configuration.\n\n";
1083-
1084-
readme += "### Using config in code\n\n";
1085-
readme += "To use the project configuration, initialize and read it explicitly:\n\n";
10861083
readme += "```cpp\n";
10871084
readme += "#include <vix.hpp>\n";
10881085
readme += "using namespace vix;\n\n";
10891086
readme += "int main()\n";
10901087
readme += "{\n";
1091-
readme += " auto &cfg = vix::config::Config::getInstance(\".env\");\n\n";
1088+
readme += " config::Config cfg{\".env\"};\n\n";
10921089
readme += " App app;\n";
10931090
readme += " app.get(\"/\", [](Request&, Response& res) {\n";
10941091
readme += " res.send(\"Hello world\");\n";
@@ -1097,22 +1094,30 @@ int main()
10971094
readme += "}\n";
10981095
readme += "```\n\n";
10991096

1100-
readme += "### Environment variable mapping\n\n";
1101-
readme += "Internally, Vix uses logical config keys such as:\n\n";
1102-
readme += "- `server.port`\n";
1103-
readme += "- `database.default.host`\n";
1104-
readme += "- `database.default.name`\n";
1105-
readme += "- `websocket.max_message_size`\n\n";
1097+
// ---------------------------
1098+
// Env mapping
1099+
// ---------------------------
1100+
readme += "## Environment mapping\n\n";
1101+
1102+
readme += "Vix maps config keys to environment variables:\n\n";
11061103

1107-
readme += "These are mapped automatically to environment variables such as:\n\n";
1108-
readme += "- `SERVER_PORT`\n";
1109-
readme += "- `DATABASE_DEFAULT_HOST`\n";
1110-
readme += "- `DATABASE_DEFAULT_NAME`\n";
1111-
readme += "- `WEBSOCKET_MAX_MESSAGE_SIZE`\n\n";
1104+
readme += "- `server.port` → `SERVER_PORT`\n";
1105+
readme += "- `database.default.host` → `DATABASE_DEFAULT_HOST`\n";
1106+
readme += "- `database.default.name` → `DATABASE_DEFAULT_NAME`\n\n";
11121107

1113-
readme += "This keeps the C++ API clean while staying friendly to `.env` workflows.\n\n";
1108+
readme += "This keeps the C++ API clean and environment-driven.\n\n";
11141109

1115-
readme += "> Recommended: keep `.env` for development and use environment-specific files such as `.env.production` for deployment.\n";
1110+
// ---------------------------
1111+
// Layered env
1112+
// ---------------------------
1113+
readme += "## Environment layers\n\n";
1114+
1115+
readme += "You can use multiple env files:\n\n";
1116+
readme += "- `.env`\n";
1117+
readme += "- `.env.local`\n";
1118+
readme += "- `.env.production`\n\n";
1119+
1120+
readme += "Use `.env` for development and environment-specific files for deployment.\n";
11161121

11171122
return readme;
11181123
}
@@ -1807,21 +1812,46 @@ int main()
18071812
{
18081813
const fs::path srcDir = projectDir / "src";
18091814
const fs::path testsDir = projectDir / "tests";
1810-
const fs::path configDir = projectDir / "config";
1815+
static const char *kEnvExample = R"(# ----------------------------------
1816+
# Server
1817+
# ----------------------------------
1818+
SERVER_PORT=8080
1819+
1820+
# ----------------------------------
1821+
# Database
1822+
# ----------------------------------
1823+
DATABASE_ENGINE=mysql
1824+
DATABASE_DEFAULT_HOST=127.0.0.1
1825+
DATABASE_DEFAULT_PORT=3306
1826+
DATABASE_DEFAULT_USER=root
1827+
DATABASE_DEFAULT_PASSWORD=
1828+
DATABASE_DEFAULT_NAME=appdb
1829+
1830+
# ----------------------------------
1831+
# Logging
1832+
# ----------------------------------
1833+
LOGGING_ASYNC=true
1834+
1835+
# ----------------------------------
1836+
# Security / WAF
1837+
# ----------------------------------
1838+
WAF_MODE=basic
1839+
)";
18111840

18121841
if (!ensure_dir(srcDir, err))
18131842
return false;
18141843
if (!ensure_dir(testsDir, err))
18151844
return false;
1816-
if (!ensure_dir(configDir, err))
1817-
return false;
18181845

18191846
if (!write_text_file(srcDir / "main.cpp", kMainCpp, err))
18201847
return false;
18211848
if (!write_text_file(testsDir / "test_basic.cpp", kBasicTestCpp_App, err))
18221849
return false;
18231850

1824-
if (!write_text_file(configDir / "config.json", kAppConfigJson, err))
1851+
if (!write_text_file(projectDir / ".env.example", kEnvExample, err))
1852+
return false;
1853+
1854+
if (!write_text_file(projectDir / ".env", kEnvExample, err))
18251855
return false;
18261856

18271857
if (!write_text_file(projectDir / "CMakeLists.txt", make_cmakelists_app(projName, features), err))

src/commands/RunCommand.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,25 @@ namespace
6565
return s;
6666
}
6767

68+
static void warn_if_env_file_missing(const fs::path &projectDir)
69+
{
70+
std::error_code ec;
71+
72+
const fs::path envFile = projectDir / ".env";
73+
if (fs::exists(envFile, ec) && !ec)
74+
return;
75+
76+
const fs::path envExample = projectDir / ".env.example";
77+
if (fs::exists(envExample, ec) && !ec)
78+
{
79+
hint(".env not found.");
80+
step("cp .env.example .env");
81+
return;
82+
}
83+
84+
hint(".env not found.");
85+
}
86+
6887
std::string to_dep_folder_name(const std::string &pkg)
6988
{
7089
std::string s = pkg;
@@ -1226,6 +1245,8 @@ namespace vix::commands::RunCommand
12261245
step(projectDir.string());
12271246
}
12281247

1248+
warn_if_env_file_missing(projectDir);
1249+
12291250
if (!opt.singleCpp && opt.watch)
12301251
{
12311252
#ifndef _WIN32

0 commit comments

Comments
 (0)