@hivehub/rulebook 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +191 -0
- package/README.md +539 -0
- package/dist/agents/claude-code.d.ts +69 -0
- package/dist/agents/claude-code.d.ts.map +1 -0
- package/dist/agents/claude-code.js +180 -0
- package/dist/agents/claude-code.js.map +1 -0
- package/dist/agents/cursor-agent.d.ts +184 -0
- package/dist/agents/cursor-agent.d.ts.map +1 -0
- package/dist/agents/cursor-agent.js +299 -0
- package/dist/agents/cursor-agent.js.map +1 -0
- package/dist/agents/gemini-cli.d.ts +69 -0
- package/dist/agents/gemini-cli.d.ts.map +1 -0
- package/dist/agents/gemini-cli.js +180 -0
- package/dist/agents/gemini-cli.js.map +1 -0
- package/dist/cli/commands.d.ts +57 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +1370 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/docs-prompts.d.ts +3 -0
- package/dist/cli/docs-prompts.d.ts.map +1 -0
- package/dist/cli/docs-prompts.js +45 -0
- package/dist/cli/docs-prompts.js.map +1 -0
- package/dist/cli/prompts.d.ts +6 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +376 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/core/agent-manager.d.ts +89 -0
- package/dist/core/agent-manager.d.ts.map +1 -0
- package/dist/core/agent-manager.js +546 -0
- package/dist/core/agent-manager.js.map +1 -0
- package/dist/core/auto-fixer.d.ts +14 -0
- package/dist/core/auto-fixer.d.ts.map +1 -0
- package/dist/core/auto-fixer.js +207 -0
- package/dist/core/auto-fixer.js.map +1 -0
- package/dist/core/changelog-generator.d.ts +44 -0
- package/dist/core/changelog-generator.d.ts.map +1 -0
- package/dist/core/changelog-generator.js +222 -0
- package/dist/core/changelog-generator.js.map +1 -0
- package/dist/core/cli-bridge.d.ts +113 -0
- package/dist/core/cli-bridge.d.ts.map +1 -0
- package/dist/core/cli-bridge.js +1094 -0
- package/dist/core/cli-bridge.js.map +1 -0
- package/dist/core/config-manager.d.ts +65 -0
- package/dist/core/config-manager.d.ts.map +1 -0
- package/dist/core/config-manager.js +266 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/coverage-checker.d.ts +14 -0
- package/dist/core/coverage-checker.d.ts.map +1 -0
- package/dist/core/coverage-checker.js +176 -0
- package/dist/core/coverage-checker.js.map +1 -0
- package/dist/core/custom-templates.d.ts +27 -0
- package/dist/core/custom-templates.d.ts.map +1 -0
- package/dist/core/custom-templates.js +122 -0
- package/dist/core/custom-templates.js.map +1 -0
- package/dist/core/dependency-checker.d.ts +21 -0
- package/dist/core/dependency-checker.d.ts.map +1 -0
- package/dist/core/dependency-checker.js +247 -0
- package/dist/core/dependency-checker.js.map +1 -0
- package/dist/core/detector.d.ts +3 -0
- package/dist/core/detector.d.ts.map +1 -0
- package/dist/core/detector.js +1443 -0
- package/dist/core/detector.js.map +1 -0
- package/dist/core/docs-generator.d.ts +9 -0
- package/dist/core/docs-generator.d.ts.map +1 -0
- package/dist/core/docs-generator.js +531 -0
- package/dist/core/docs-generator.js.map +1 -0
- package/dist/core/generator.d.ts +16 -0
- package/dist/core/generator.d.ts.map +1 -0
- package/dist/core/generator.js +561 -0
- package/dist/core/generator.js.map +1 -0
- package/dist/core/gitignore-generator.d.ts +13 -0
- package/dist/core/gitignore-generator.d.ts.map +1 -0
- package/dist/core/gitignore-generator.js +307 -0
- package/dist/core/gitignore-generator.js.map +1 -0
- package/dist/core/health-scorer.d.ts +22 -0
- package/dist/core/health-scorer.d.ts.map +1 -0
- package/dist/core/health-scorer.js +395 -0
- package/dist/core/health-scorer.js.map +1 -0
- package/dist/core/logger.d.ts +116 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +289 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/merger.d.ts +6 -0
- package/dist/core/merger.d.ts.map +1 -0
- package/dist/core/merger.js +131 -0
- package/dist/core/merger.js.map +1 -0
- package/dist/core/migrator.d.ts +19 -0
- package/dist/core/migrator.d.ts.map +1 -0
- package/dist/core/migrator.js +102 -0
- package/dist/core/migrator.js.map +1 -0
- package/dist/core/minimal-scaffolder.d.ts +8 -0
- package/dist/core/minimal-scaffolder.d.ts.map +1 -0
- package/dist/core/minimal-scaffolder.js +51 -0
- package/dist/core/minimal-scaffolder.js.map +1 -0
- package/dist/core/modern-console-new.d.ts +81 -0
- package/dist/core/modern-console-new.d.ts.map +1 -0
- package/dist/core/modern-console-new.js +340 -0
- package/dist/core/modern-console-new.js.map +1 -0
- package/dist/core/modern-console.d.ts +99 -0
- package/dist/core/modern-console.d.ts.map +1 -0
- package/dist/core/modern-console.js +568 -0
- package/dist/core/modern-console.js.map +1 -0
- package/dist/core/openspec-manager.d.ts +133 -0
- package/dist/core/openspec-manager.d.ts.map +1 -0
- package/dist/core/openspec-manager.js +605 -0
- package/dist/core/openspec-manager.js.map +1 -0
- package/dist/core/openspec-migrator.d.ts +27 -0
- package/dist/core/openspec-migrator.d.ts.map +1 -0
- package/dist/core/openspec-migrator.js +255 -0
- package/dist/core/openspec-migrator.js.map +1 -0
- package/dist/core/task-manager.d.ts +65 -0
- package/dist/core/task-manager.d.ts.map +1 -0
- package/dist/core/task-manager.js +318 -0
- package/dist/core/task-manager.js.map +1 -0
- package/dist/core/test-task-manager.d.ts +49 -0
- package/dist/core/test-task-manager.d.ts.map +1 -0
- package/dist/core/test-task-manager.js +121 -0
- package/dist/core/test-task-manager.js.map +1 -0
- package/dist/core/validator.d.ts +21 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +177 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/core/version-bumper.d.ts +19 -0
- package/dist/core/version-bumper.d.ts.map +1 -0
- package/dist/core/version-bumper.js +180 -0
- package/dist/core/version-bumper.js.map +1 -0
- package/dist/core/watcher.d.ts +9 -0
- package/dist/core/watcher.d.ts.map +1 -0
- package/dist/core/watcher.js +22 -0
- package/dist/core/watcher.js.map +1 -0
- package/dist/core/workflow-generator.d.ts +10 -0
- package/dist/core/workflow-generator.d.ts.map +1 -0
- package/dist/core/workflow-generator.js +279 -0
- package/dist/core/workflow-generator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +159 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/handlers/archive-task.d.ts +17 -0
- package/dist/mcp/handlers/archive-task.d.ts.map +1 -0
- package/dist/mcp/handlers/archive-task.js +36 -0
- package/dist/mcp/handlers/archive-task.js.map +1 -0
- package/dist/mcp/handlers/create-task.d.ts +17 -0
- package/dist/mcp/handlers/create-task.d.ts.map +1 -0
- package/dist/mcp/handlers/create-task.js +56 -0
- package/dist/mcp/handlers/create-task.js.map +1 -0
- package/dist/mcp/handlers/list-tasks.d.ts +22 -0
- package/dist/mcp/handlers/list-tasks.d.ts.map +1 -0
- package/dist/mcp/handlers/list-tasks.js +42 -0
- package/dist/mcp/handlers/list-tasks.js.map +1 -0
- package/dist/mcp/handlers/show-task.d.ts +25 -0
- package/dist/mcp/handlers/show-task.d.ts.map +1 -0
- package/dist/mcp/handlers/show-task.js +43 -0
- package/dist/mcp/handlers/show-task.js.map +1 -0
- package/dist/mcp/handlers/update-task.d.ts +17 -0
- package/dist/mcp/handlers/update-task.d.ts.map +1 -0
- package/dist/mcp/handlers/update-task.js +35 -0
- package/dist/mcp/handlers/update-task.js.map +1 -0
- package/dist/mcp/handlers/validate-task.d.ts +15 -0
- package/dist/mcp/handlers/validate-task.d.ts.map +1 -0
- package/dist/mcp/handlers/validate-task.js +27 -0
- package/dist/mcp/handlers/validate-task.js.map +1 -0
- package/dist/mcp/rulebook-config.d.ts +22 -0
- package/dist/mcp/rulebook-config.d.ts.map +1 -0
- package/dist/mcp/rulebook-config.js +65 -0
- package/dist/mcp/rulebook-config.js.map +1 -0
- package/dist/mcp/rulebook-server.d.ts +4 -0
- package/dist/mcp/rulebook-server.d.ts.map +1 -0
- package/dist/mcp/rulebook-server.js +246 -0
- package/dist/mcp/rulebook-server.js.map +1 -0
- package/dist/types.d.ts +190 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file-system.d.ts +9 -0
- package/dist/utils/file-system.d.ts.map +1 -0
- package/dist/utils/file-system.js +51 -0
- package/dist/utils/file-system.js.map +1 -0
- package/dist/utils/git-hooks.d.ts +8 -0
- package/dist/utils/git-hooks.d.ts.map +1 -0
- package/dist/utils/git-hooks.js +440 -0
- package/dist/utils/git-hooks.js.map +1 -0
- package/dist/utils/rulesignore.d.ts +9 -0
- package/dist/utils/rulesignore.d.ts.map +1 -0
- package/dist/utils/rulesignore.js +42 -0
- package/dist/utils/rulesignore.js.map +1 -0
- package/package.json +106 -0
- package/templates/cli/AIDER.md +49 -0
- package/templates/cli/AMAZON_Q.md +25 -0
- package/templates/cli/AUGGIE.md +32 -0
- package/templates/cli/CLAUDE.md +32 -0
- package/templates/cli/CLAUDE_CODE.md +35 -0
- package/templates/cli/CLINE.md +32 -0
- package/templates/cli/CODEBUDDY.md +20 -0
- package/templates/cli/CODEIUM.md +20 -0
- package/templates/cli/CODEX.md +21 -0
- package/templates/cli/CONTINUE.md +34 -0
- package/templates/cli/CURSOR_CLI.md +28 -0
- package/templates/cli/FACTORY.md +18 -0
- package/templates/cli/GEMINI.md +35 -0
- package/templates/cli/KILOCODE.md +18 -0
- package/templates/cli/OPENCODE.md +18 -0
- package/templates/cli/_GENERIC_TEMPLATE.md +29 -0
- package/templates/commands/rulebook-task-apply.md +67 -0
- package/templates/commands/rulebook-task-archive.md +70 -0
- package/templates/commands/rulebook-task-create.md +93 -0
- package/templates/commands/rulebook-task-list.md +42 -0
- package/templates/commands/rulebook-task-show.md +52 -0
- package/templates/commands/rulebook-task-validate.md +53 -0
- package/templates/core/AGENT_AUTOMATION.md +184 -0
- package/templates/core/DAG.md +304 -0
- package/templates/core/DOCUMENTATION_RULES.md +37 -0
- package/templates/core/QUALITY_ENFORCEMENT.md +68 -0
- package/templates/core/RULEBOOK.md +1874 -0
- package/templates/frameworks/ANGULAR.md +36 -0
- package/templates/frameworks/DJANGO.md +83 -0
- package/templates/frameworks/ELECTRON.md +147 -0
- package/templates/frameworks/FLASK.md +38 -0
- package/templates/frameworks/FLUTTER.md +55 -0
- package/templates/frameworks/JQUERY.md +32 -0
- package/templates/frameworks/LARAVEL.md +38 -0
- package/templates/frameworks/NESTJS.md +43 -0
- package/templates/frameworks/NEXTJS.md +127 -0
- package/templates/frameworks/NUXT.md +40 -0
- package/templates/frameworks/RAILS.md +66 -0
- package/templates/frameworks/REACT.md +38 -0
- package/templates/frameworks/REACT_NATIVE.md +47 -0
- package/templates/frameworks/SPRING.md +39 -0
- package/templates/frameworks/SYMFONY.md +36 -0
- package/templates/frameworks/VUE.md +36 -0
- package/templates/frameworks/ZEND.md +35 -0
- package/templates/git/CI_CD_PATTERNS.md +661 -0
- package/templates/git/GITHUB_ACTIONS.md +728 -0
- package/templates/git/GITLAB_CI.md +730 -0
- package/templates/git/GIT_WORKFLOW.md +1157 -0
- package/templates/git/SECRETS_MANAGEMENT.md +585 -0
- package/templates/hooks/COMMIT_MSG.md +530 -0
- package/templates/hooks/POST_CHECKOUT.md +546 -0
- package/templates/hooks/PREPARE_COMMIT_MSG.md +619 -0
- package/templates/hooks/PRE_COMMIT.md +414 -0
- package/templates/hooks/PRE_PUSH.md +601 -0
- package/templates/hooks/csharp-pre-commit.sh +23 -0
- package/templates/hooks/csharp-pre-push.sh +23 -0
- package/templates/hooks/dart-pre-commit.sh +30 -0
- package/templates/hooks/dart-pre-push.sh +25 -0
- package/templates/hooks/elixir-pre-commit.sh +32 -0
- package/templates/hooks/elixir-pre-push.sh +31 -0
- package/templates/hooks/erlang-pre-commit.sh +30 -0
- package/templates/hooks/erlang-pre-push.sh +37 -0
- package/templates/hooks/go-pre-commit.sh +40 -0
- package/templates/hooks/go-pre-push.sh +31 -0
- package/templates/hooks/haskell-pre-commit.sh +41 -0
- package/templates/hooks/haskell-pre-push.sh +37 -0
- package/templates/hooks/java-pre-commit.sh +34 -0
- package/templates/hooks/java-pre-push.sh +24 -0
- package/templates/hooks/kotlin-pre-commit.sh +32 -0
- package/templates/hooks/kotlin-pre-push.sh +16 -0
- package/templates/hooks/php-pre-commit.sh +36 -0
- package/templates/hooks/php-pre-push.sh +26 -0
- package/templates/hooks/python-pre-commit.sh +51 -0
- package/templates/hooks/python-pre-push.sh +25 -0
- package/templates/hooks/ruby-pre-commit.sh +33 -0
- package/templates/hooks/ruby-pre-push.sh +32 -0
- package/templates/hooks/rust-pre-commit.sh +30 -0
- package/templates/hooks/rust-pre-push.sh +30 -0
- package/templates/hooks/scala-pre-commit.sh +32 -0
- package/templates/hooks/scala-pre-push.sh +24 -0
- package/templates/hooks/swift-pre-commit.sh +25 -0
- package/templates/hooks/swift-pre-push.sh +23 -0
- package/templates/hooks/typescript-pre-commit.sh +37 -0
- package/templates/hooks/typescript-pre-push.sh +36 -0
- package/templates/ides/COPILOT.md +37 -0
- package/templates/ides/CURSOR.md +43 -0
- package/templates/ides/JETBRAINS_AI.md +35 -0
- package/templates/ides/REPLIT.md +36 -0
- package/templates/ides/TABNINE.md +29 -0
- package/templates/ides/VSCODE.md +40 -0
- package/templates/ides/WINDSURF.md +36 -0
- package/templates/ides/ZED.md +32 -0
- package/templates/languages/ADA.md +58 -0
- package/templates/languages/C.md +333 -0
- package/templates/languages/CPP.md +743 -0
- package/templates/languages/CSHARP.md +417 -0
- package/templates/languages/DART.md +332 -0
- package/templates/languages/ELIXIR.md +454 -0
- package/templates/languages/ERLANG.md +361 -0
- package/templates/languages/GO.md +645 -0
- package/templates/languages/HASKELL.md +177 -0
- package/templates/languages/JAVA.md +607 -0
- package/templates/languages/JAVASCRIPT.md +631 -0
- package/templates/languages/JULIA.md +97 -0
- package/templates/languages/KOTLIN.md +511 -0
- package/templates/languages/LISP.md +100 -0
- package/templates/languages/LUA.md +74 -0
- package/templates/languages/OBJECTIVEC.md +90 -0
- package/templates/languages/PHP.md +416 -0
- package/templates/languages/PYTHON.md +682 -0
- package/templates/languages/R.md +350 -0
- package/templates/languages/RUBY.md +421 -0
- package/templates/languages/RUST.md +477 -0
- package/templates/languages/SAS.md +73 -0
- package/templates/languages/SCALA.md +348 -0
- package/templates/languages/SOLIDITY.md +580 -0
- package/templates/languages/SQL.md +137 -0
- package/templates/languages/SWIFT.md +466 -0
- package/templates/languages/TYPESCRIPT.md +591 -0
- package/templates/languages/ZIG.md +265 -0
- package/templates/modules/ATLASSIAN.md +255 -0
- package/templates/modules/CONTEXT7.md +54 -0
- package/templates/modules/FIGMA.md +267 -0
- package/templates/modules/GITHUB_MCP.md +64 -0
- package/templates/modules/GRAFANA.md +328 -0
- package/templates/modules/NOTION.md +247 -0
- package/templates/modules/PLAYWRIGHT.md +90 -0
- package/templates/modules/RULEBOOK_MCP.md +156 -0
- package/templates/modules/SERENA.md +337 -0
- package/templates/modules/SUPABASE.md +223 -0
- package/templates/modules/SYNAP.md +69 -0
- package/templates/modules/VECTORIZER.md +63 -0
- package/templates/services/AZURE_BLOB.md +184 -0
- package/templates/services/CASSANDRA.md +239 -0
- package/templates/services/DYNAMODB.md +308 -0
- package/templates/services/ELASTICSEARCH.md +347 -0
- package/templates/services/GCS.md +178 -0
- package/templates/services/INFLUXDB.md +265 -0
- package/templates/services/KAFKA.md +341 -0
- package/templates/services/MARIADB.md +183 -0
- package/templates/services/MEMCACHED.md +242 -0
- package/templates/services/MINIO.md +201 -0
- package/templates/services/MONGODB.md +268 -0
- package/templates/services/MYSQL.md +358 -0
- package/templates/services/NEO4J.md +247 -0
- package/templates/services/ORACLE.md +290 -0
- package/templates/services/POSTGRESQL.md +326 -0
- package/templates/services/RABBITMQ.md +286 -0
- package/templates/services/REDIS.md +292 -0
- package/templates/services/S3.md +298 -0
- package/templates/services/SQLITE.md +294 -0
- package/templates/services/SQLSERVER.md +294 -0
- package/templates/workflows/codespell.yml +31 -0
- package/templates/workflows/cpp-lint.yml +47 -0
- package/templates/workflows/cpp-publish.yml +119 -0
- package/templates/workflows/cpp-test.yml +77 -0
- package/templates/workflows/dotnet-lint.yml +29 -0
- package/templates/workflows/dotnet-publish.yml +40 -0
- package/templates/workflows/dotnet-test.yml +41 -0
- package/templates/workflows/elixir-lint.yml +45 -0
- package/templates/workflows/elixir-publish.yml +49 -0
- package/templates/workflows/elixir-test.yml +54 -0
- package/templates/workflows/erlang-lint.yml +47 -0
- package/templates/workflows/erlang-test.yml +62 -0
- package/templates/workflows/go-lint.yml +39 -0
- package/templates/workflows/go-publish.yml +95 -0
- package/templates/workflows/go-test.yml +59 -0
- package/templates/workflows/java-lint.yml +60 -0
- package/templates/workflows/java-publish.yml +120 -0
- package/templates/workflows/java-test.yml +85 -0
- package/templates/workflows/kotlin-lint.yml +34 -0
- package/templates/workflows/kotlin-publish.yml +56 -0
- package/templates/workflows/kotlin-test.yml +48 -0
- package/templates/workflows/php-lint.yml +39 -0
- package/templates/workflows/php-publish.yml +50 -0
- package/templates/workflows/php-test.yml +54 -0
- package/templates/workflows/python-lint.yml +47 -0
- package/templates/workflows/python-publish.yml +91 -0
- package/templates/workflows/python-test.yml +59 -0
- package/templates/workflows/rust-lint.yml +54 -0
- package/templates/workflows/rust-publish.yml +66 -0
- package/templates/workflows/rust-test.yml +75 -0
- package/templates/workflows/solidity-lint.yml +41 -0
- package/templates/workflows/solidity-test.yml +47 -0
- package/templates/workflows/swift-lint.yml +32 -0
- package/templates/workflows/swift-publish.yml +58 -0
- package/templates/workflows/swift-test.yml +44 -0
- package/templates/workflows/typescript-lint.yml +61 -0
- package/templates/workflows/typescript-publish.yml +60 -0
- package/templates/workflows/typescript-test.yml +73 -0
- package/templates/workflows/zig-lint.yml +27 -0
- package/templates/workflows/zig-test.yml +40 -0
|
@@ -0,0 +1,743 @@
|
|
|
1
|
+
<!-- CPP:START -->
|
|
2
|
+
# C/C++ Project Rules
|
|
3
|
+
|
|
4
|
+
## Agent Automation Commands
|
|
5
|
+
|
|
6
|
+
**CRITICAL**: Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow).
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
# Complete quality check sequence:
|
|
10
|
+
clang-format --dry-run --Werror src/**/*.cpp # Format check
|
|
11
|
+
clang-tidy src/**/*.cpp # Linting
|
|
12
|
+
make test # All tests (100% pass)
|
|
13
|
+
make # Build verification
|
|
14
|
+
|
|
15
|
+
# Additional checks:
|
|
16
|
+
cppcheck --enable=all src/ # Static analysis
|
|
17
|
+
valgrind --leak-check=full ./build/test # Memory check
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## C/C++ Configuration
|
|
21
|
+
|
|
22
|
+
**CRITICAL**: Use C++20 or C++23 with modern CMake.
|
|
23
|
+
|
|
24
|
+
- **C++ Standard**: C++20 or C++23
|
|
25
|
+
- **CMake**: 3.25+
|
|
26
|
+
- **Compiler**: GCC 11+, Clang 15+, or MSVC 19.30+
|
|
27
|
+
- **Build System**: CMake (recommended) or Meson
|
|
28
|
+
- **Package Manager**: Conan or vcpkg
|
|
29
|
+
|
|
30
|
+
### CMakeLists.txt Requirements
|
|
31
|
+
|
|
32
|
+
```cmake
|
|
33
|
+
cmake_minimum_required(VERSION 3.25)
|
|
34
|
+
project(YourProject VERSION 1.0.0 LANGUAGES CXX)
|
|
35
|
+
|
|
36
|
+
# C++ Standard
|
|
37
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
38
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
39
|
+
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
40
|
+
|
|
41
|
+
# Compiler warnings
|
|
42
|
+
if(MSVC)
|
|
43
|
+
add_compile_options(/W4 /WX)
|
|
44
|
+
else()
|
|
45
|
+
add_compile_options(-Wall -Wextra -Wpedantic -Werror)
|
|
46
|
+
endif()
|
|
47
|
+
|
|
48
|
+
# Export compile commands for tooling
|
|
49
|
+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
50
|
+
|
|
51
|
+
# Project options
|
|
52
|
+
option(BUILD_TESTING "Build tests" ON)
|
|
53
|
+
option(BUILD_DOCS "Build documentation" ON)
|
|
54
|
+
option(ENABLE_SANITIZERS "Enable sanitizers" ON)
|
|
55
|
+
|
|
56
|
+
# Dependencies (using FetchContent or find_package)
|
|
57
|
+
include(FetchContent)
|
|
58
|
+
|
|
59
|
+
FetchContent_Declare(
|
|
60
|
+
googletest
|
|
61
|
+
GIT_REPOSITORY https://github.com/google/googletest.git
|
|
62
|
+
GIT_TAG v1.14.0
|
|
63
|
+
)
|
|
64
|
+
FetchContent_MakeAvailable(googletest)
|
|
65
|
+
|
|
66
|
+
# Library
|
|
67
|
+
add_library(${PROJECT_NAME}
|
|
68
|
+
src/your_module.cpp
|
|
69
|
+
src/your_module.hpp
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
target_include_directories(${PROJECT_NAME}
|
|
73
|
+
PUBLIC
|
|
74
|
+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
|
75
|
+
$<INSTALL_INTERFACE:include>
|
|
76
|
+
PRIVATE
|
|
77
|
+
${CMAKE_CURRENT_SOURCE_DIR}/src
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Enable sanitizers in debug
|
|
81
|
+
if(ENABLE_SANITIZERS AND CMAKE_BUILD_TYPE MATCHES Debug)
|
|
82
|
+
target_compile_options(${PROJECT_NAME} PRIVATE
|
|
83
|
+
-fsanitize=address
|
|
84
|
+
-fsanitize=undefined
|
|
85
|
+
-fno-omit-frame-pointer
|
|
86
|
+
)
|
|
87
|
+
target_link_options(${PROJECT_NAME} PRIVATE
|
|
88
|
+
-fsanitize=address
|
|
89
|
+
-fsanitize=undefined
|
|
90
|
+
)
|
|
91
|
+
endif()
|
|
92
|
+
|
|
93
|
+
# Tests
|
|
94
|
+
if(BUILD_TESTING)
|
|
95
|
+
enable_testing()
|
|
96
|
+
add_subdirectory(tests)
|
|
97
|
+
endif()
|
|
98
|
+
|
|
99
|
+
# Installation
|
|
100
|
+
install(TARGETS ${PROJECT_NAME}
|
|
101
|
+
EXPORT ${PROJECT_NAME}Targets
|
|
102
|
+
LIBRARY DESTINATION lib
|
|
103
|
+
ARCHIVE DESTINATION lib
|
|
104
|
+
RUNTIME DESTINATION bin
|
|
105
|
+
INCLUDES DESTINATION include
|
|
106
|
+
)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Code Quality Standards
|
|
110
|
+
|
|
111
|
+
### Mandatory Quality Checks
|
|
112
|
+
|
|
113
|
+
**CRITICAL**: After implementing ANY feature, you MUST run these commands in order.
|
|
114
|
+
|
|
115
|
+
**IMPORTANT**: These commands MUST match your GitHub Actions workflows to prevent CI/CD failures!
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Pre-Commit Checklist (MUST match .github/workflows/*.yml)
|
|
119
|
+
|
|
120
|
+
# 1. Format check (matches workflow - use --dry-run, not -i!)
|
|
121
|
+
clang-format --dry-run --Werror src/**/*.{cpp,hpp} tests/**/*.{cpp,hpp}
|
|
122
|
+
|
|
123
|
+
# 2. Static analysis (matches workflow)
|
|
124
|
+
clang-tidy src/**/*.cpp -- -std=c++20
|
|
125
|
+
|
|
126
|
+
# 3. Build (MUST pass with no warnings - matches workflow)
|
|
127
|
+
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-Werror"
|
|
128
|
+
cmake --build build
|
|
129
|
+
|
|
130
|
+
# 4. Run all tests (MUST pass 100% - matches workflow)
|
|
131
|
+
ctest --test-dir build --output-on-failure
|
|
132
|
+
|
|
133
|
+
# 5. Check with sanitizers (matches workflow)
|
|
134
|
+
cmake -B build-asan -DENABLE_SANITIZERS=ON
|
|
135
|
+
cmake --build build-asan
|
|
136
|
+
ctest --test-dir build-asan
|
|
137
|
+
|
|
138
|
+
# 6. Check coverage (matches workflow)
|
|
139
|
+
cmake -B build-cov -DCMAKE_BUILD_TYPE=Coverage
|
|
140
|
+
cmake --build build-cov
|
|
141
|
+
ctest --test-dir build-cov
|
|
142
|
+
gcov build-cov/CMakeFiles/YourProject.dir/src/*.gcno
|
|
143
|
+
|
|
144
|
+
# If ANY fails: ❌ DO NOT COMMIT - Fix first!
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Why This Matters:**
|
|
148
|
+
- CI/CD failures happen when local commands differ from workflows
|
|
149
|
+
- Example: Using `clang-format -i` locally but `--dry-run --Werror` in CI = failure
|
|
150
|
+
- Example: Missing `-Werror` flag = warnings pass locally but fail in CI
|
|
151
|
+
- Example: Skipping sanitizers locally = CI catches memory bugs you missed
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**If ANY of these fail, you MUST fix the issues before committing.**
|
|
155
|
+
|
|
156
|
+
### Code Style
|
|
157
|
+
|
|
158
|
+
Use `.clang-format` for consistent formatting:
|
|
159
|
+
|
|
160
|
+
```yaml
|
|
161
|
+
---
|
|
162
|
+
Language: Cpp
|
|
163
|
+
BasedOnStyle: Google
|
|
164
|
+
IndentWidth: 4
|
|
165
|
+
ColumnLimit: 100
|
|
166
|
+
UseTab: Never
|
|
167
|
+
PointerAlignment: Left
|
|
168
|
+
ReferenceAlignment: Left
|
|
169
|
+
DerivePointerAlignment: false
|
|
170
|
+
|
|
171
|
+
# Includes
|
|
172
|
+
SortIncludes: CaseInsensitive
|
|
173
|
+
IncludeBlocks: Regroup
|
|
174
|
+
IncludeCategories:
|
|
175
|
+
- Regex: '^<.*\.h>'
|
|
176
|
+
Priority: 1
|
|
177
|
+
- Regex: '^<.*>'
|
|
178
|
+
Priority: 2
|
|
179
|
+
- Regex: '.*'
|
|
180
|
+
Priority: 3
|
|
181
|
+
|
|
182
|
+
# Braces
|
|
183
|
+
BreakBeforeBraces: Attach
|
|
184
|
+
AllowShortFunctionsOnASingleLine: Inline
|
|
185
|
+
AllowShortIfStatementsOnASingleLine: Never
|
|
186
|
+
|
|
187
|
+
# Spacing
|
|
188
|
+
SpaceAfterCStyleCast: false
|
|
189
|
+
SpaceAfterTemplateKeyword: true
|
|
190
|
+
SpaceBeforeParens: ControlStatements
|
|
191
|
+
|
|
192
|
+
# Modern C++
|
|
193
|
+
Standard: c++20
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Static Analysis
|
|
197
|
+
|
|
198
|
+
Use `.clang-tidy` for code analysis:
|
|
199
|
+
|
|
200
|
+
```yaml
|
|
201
|
+
---
|
|
202
|
+
Checks: >
|
|
203
|
+
*,
|
|
204
|
+
-abseil-*,
|
|
205
|
+
-altera-*,
|
|
206
|
+
-android-*,
|
|
207
|
+
-fuchsia-*,
|
|
208
|
+
-google-*,
|
|
209
|
+
-llvm-*,
|
|
210
|
+
-llvmlibc-*,
|
|
211
|
+
-zircon-*,
|
|
212
|
+
-readability-identifier-length,
|
|
213
|
+
-modernize-use-trailing-return-type
|
|
214
|
+
|
|
215
|
+
CheckOptions:
|
|
216
|
+
- key: readability-identifier-naming.NamespaceCase
|
|
217
|
+
value: lower_case
|
|
218
|
+
- key: readability-identifier-naming.ClassCase
|
|
219
|
+
value: CamelCase
|
|
220
|
+
- key: readability-identifier-naming.StructCase
|
|
221
|
+
value: CamelCase
|
|
222
|
+
- key: readability-identifier-naming.FunctionCase
|
|
223
|
+
value: camelCase
|
|
224
|
+
- key: readability-identifier-naming.VariableCase
|
|
225
|
+
value: lower_case
|
|
226
|
+
- key: readability-identifier-naming.ConstantCase
|
|
227
|
+
value: UPPER_CASE
|
|
228
|
+
- key: readability-identifier-naming.MemberCase
|
|
229
|
+
value: lower_case_
|
|
230
|
+
- key: readability-identifier-naming.PrivateMemberSuffix
|
|
231
|
+
value: '_'
|
|
232
|
+
|
|
233
|
+
WarningsAsErrors: '*'
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Testing
|
|
237
|
+
|
|
238
|
+
- **Framework**: Google Test (recommended) or Catch2
|
|
239
|
+
- **Location**: `tests/` directory
|
|
240
|
+
- **Coverage**: gcov/lcov or llvm-cov
|
|
241
|
+
- **Coverage Threshold**: 95%+
|
|
242
|
+
|
|
243
|
+
Example test with Google Test:
|
|
244
|
+
|
|
245
|
+
```cpp
|
|
246
|
+
#include <gtest/gtest.h>
|
|
247
|
+
#include "your_module.hpp"
|
|
248
|
+
|
|
249
|
+
namespace your_namespace::tests {
|
|
250
|
+
|
|
251
|
+
class DataProcessorTest : public ::testing::Test {
|
|
252
|
+
protected:
|
|
253
|
+
void SetUp() override {
|
|
254
|
+
processor = std::make_unique<DataProcessor>();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
void TearDown() override {
|
|
258
|
+
processor.reset();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
std::unique_ptr<DataProcessor> processor;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
TEST_F(DataProcessorTest, ProcessValidInput) {
|
|
265
|
+
const std::string input = "hello";
|
|
266
|
+
const auto result = processor->process(input);
|
|
267
|
+
|
|
268
|
+
EXPECT_EQ(result, "HELLO");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
TEST_F(DataProcessorTest, ProcessEmptyInputThrows) {
|
|
272
|
+
EXPECT_THROW(
|
|
273
|
+
processor->process(""),
|
|
274
|
+
std::invalid_argument
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
TEST_F(DataProcessorTest, ProcessLargeInput) {
|
|
279
|
+
const std::string input(1000, 'a');
|
|
280
|
+
const auto result = processor->process(input);
|
|
281
|
+
|
|
282
|
+
ASSERT_EQ(result.size(), 1000);
|
|
283
|
+
EXPECT_TRUE(std::all_of(result.begin(), result.end(),
|
|
284
|
+
[](char c) { return std::isupper(c); }));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
} // namespace your_namespace::tests
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Modern C++ Best Practices
|
|
291
|
+
|
|
292
|
+
- Use RAII for resource management
|
|
293
|
+
- Prefer `std::unique_ptr` and `std::shared_ptr` over raw pointers
|
|
294
|
+
- Use `const` and `constexpr` liberally
|
|
295
|
+
- Prefer `std::string_view` for read-only strings
|
|
296
|
+
- Use range-based for loops
|
|
297
|
+
- Use `auto` for type deduction when clear
|
|
298
|
+
- Avoid manual memory management
|
|
299
|
+
|
|
300
|
+
Example modern C++ code:
|
|
301
|
+
|
|
302
|
+
```cpp
|
|
303
|
+
#pragma once
|
|
304
|
+
|
|
305
|
+
#include <memory>
|
|
306
|
+
#include <string>
|
|
307
|
+
#include <string_view>
|
|
308
|
+
#include <vector>
|
|
309
|
+
#include <optional>
|
|
310
|
+
#include <expected>
|
|
311
|
+
|
|
312
|
+
namespace your_namespace {
|
|
313
|
+
|
|
314
|
+
/// @brief Processes data with various transformations
|
|
315
|
+
class DataProcessor {
|
|
316
|
+
public:
|
|
317
|
+
DataProcessor() = default;
|
|
318
|
+
~DataProcessor() = default;
|
|
319
|
+
|
|
320
|
+
// Delete copy constructor and assignment
|
|
321
|
+
DataProcessor(const DataProcessor&) = delete;
|
|
322
|
+
DataProcessor& operator=(const DataProcessor&) = delete;
|
|
323
|
+
|
|
324
|
+
// Default move constructor and assignment
|
|
325
|
+
DataProcessor(DataProcessor&&) noexcept = default;
|
|
326
|
+
DataProcessor& operator=(DataProcessor&&) noexcept = default;
|
|
327
|
+
|
|
328
|
+
/// @brief Process input string to uppercase
|
|
329
|
+
/// @param input The input string to process
|
|
330
|
+
/// @return Processed string or error
|
|
331
|
+
/// @throws std::invalid_argument if input is empty
|
|
332
|
+
[[nodiscard]] std::string process(std::string_view input) const;
|
|
333
|
+
|
|
334
|
+
/// @brief Find value in data
|
|
335
|
+
/// @param data The data to search
|
|
336
|
+
/// @param key The key to find
|
|
337
|
+
/// @return Optional value if found
|
|
338
|
+
[[nodiscard]] std::optional<std::string> findValue(
|
|
339
|
+
const std::vector<std::pair<std::string, std::string>>& data,
|
|
340
|
+
std::string_view key
|
|
341
|
+
) const;
|
|
342
|
+
|
|
343
|
+
/// @brief Process multiple items
|
|
344
|
+
/// @param items Items to process
|
|
345
|
+
/// @return Processed items
|
|
346
|
+
[[nodiscard]] std::vector<std::string> processMany(
|
|
347
|
+
const std::vector<std::string>& items
|
|
348
|
+
) const;
|
|
349
|
+
|
|
350
|
+
private:
|
|
351
|
+
mutable std::mutex mutex_;
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
} // namespace your_namespace
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Implementation:
|
|
358
|
+
|
|
359
|
+
```cpp
|
|
360
|
+
#include "your_module.hpp"
|
|
361
|
+
#include <algorithm>
|
|
362
|
+
#include <stdexcept>
|
|
363
|
+
#include <cctype>
|
|
364
|
+
|
|
365
|
+
namespace your_namespace {
|
|
366
|
+
|
|
367
|
+
std::string DataProcessor::process(std::string_view input) const {
|
|
368
|
+
if (input.empty()) {
|
|
369
|
+
throw std::invalid_argument("Input cannot be empty");
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
std::string result;
|
|
373
|
+
result.reserve(input.size());
|
|
374
|
+
|
|
375
|
+
std::transform(input.begin(), input.end(),
|
|
376
|
+
std::back_inserter(result),
|
|
377
|
+
[](unsigned char c) { return std::toupper(c); });
|
|
378
|
+
|
|
379
|
+
return result;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
std::optional<std::string> DataProcessor::findValue(
|
|
383
|
+
const std::vector<std::pair<std::string, std::string>>& data,
|
|
384
|
+
std::string_view key
|
|
385
|
+
) const {
|
|
386
|
+
auto it = std::find_if(data.begin(), data.end(),
|
|
387
|
+
[key](const auto& pair) { return pair.first == key; });
|
|
388
|
+
|
|
389
|
+
if (it != data.end()) {
|
|
390
|
+
return it->second;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return std::nullopt;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
std::vector<std::string> DataProcessor::processMany(
|
|
397
|
+
const std::vector<std::string>& items
|
|
398
|
+
) const {
|
|
399
|
+
std::vector<std::string> results;
|
|
400
|
+
results.reserve(items.size());
|
|
401
|
+
|
|
402
|
+
std::transform(items.begin(), items.end(),
|
|
403
|
+
std::back_inserter(results),
|
|
404
|
+
[this](const auto& item) { return process(item); });
|
|
405
|
+
|
|
406
|
+
return results;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
} // namespace your_namespace
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Documentation
|
|
413
|
+
|
|
414
|
+
Use Doxygen for API documentation:
|
|
415
|
+
|
|
416
|
+
```cpp
|
|
417
|
+
/**
|
|
418
|
+
* @file your_module.hpp
|
|
419
|
+
* @brief Data processing utilities
|
|
420
|
+
* @author Your Name
|
|
421
|
+
* @date 2024-10-23
|
|
422
|
+
*/
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* @class DataProcessor
|
|
426
|
+
* @brief Processes various data formats
|
|
427
|
+
*
|
|
428
|
+
* This class provides thread-safe data processing capabilities.
|
|
429
|
+
* All methods are const-correct and exception-safe.
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* @code{.cpp}
|
|
433
|
+
* DataProcessor processor;
|
|
434
|
+
* auto result = processor.process("hello");
|
|
435
|
+
* assert(result == "HELLO");
|
|
436
|
+
* @endcode
|
|
437
|
+
*/
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Doxyfile Configuration:
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
PROJECT_NAME = "Your Project"
|
|
444
|
+
PROJECT_NUMBER = 1.0.0
|
|
445
|
+
OUTPUT_DIRECTORY = docs
|
|
446
|
+
GENERATE_HTML = YES
|
|
447
|
+
GENERATE_LATEX = NO
|
|
448
|
+
EXTRACT_ALL = YES
|
|
449
|
+
EXTRACT_PRIVATE = NO
|
|
450
|
+
EXTRACT_STATIC = YES
|
|
451
|
+
SOURCE_BROWSER = YES
|
|
452
|
+
INLINE_SOURCES = YES
|
|
453
|
+
RECURSIVE = YES
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## Project Structure
|
|
457
|
+
|
|
458
|
+
```
|
|
459
|
+
project/
|
|
460
|
+
├── CMakeLists.txt # CMake configuration
|
|
461
|
+
├── .clang-format # Code formatting rules
|
|
462
|
+
├── .clang-tidy # Static analysis rules
|
|
463
|
+
├── Doxyfile # Documentation config
|
|
464
|
+
├── conanfile.txt # Conan dependencies (optional)
|
|
465
|
+
├── vcpkg.json # vcpkg dependencies (optional)
|
|
466
|
+
├── README.md # Project overview
|
|
467
|
+
├── CHANGELOG.md # Version history
|
|
468
|
+
├── LICENSE # Project license
|
|
469
|
+
├── include/
|
|
470
|
+
│ └── your_project/
|
|
471
|
+
│ └── your_module.hpp # Public headers
|
|
472
|
+
├── src/
|
|
473
|
+
│ └── your_module.cpp # Implementation
|
|
474
|
+
├── tests/
|
|
475
|
+
│ ├── CMakeLists.txt
|
|
476
|
+
│ └── test_your_module.cpp
|
|
477
|
+
├── benchmarks/ # Performance benchmarks
|
|
478
|
+
│ └── benchmark_main.cpp
|
|
479
|
+
└── docs/ # Project documentation
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
## Memory Safety
|
|
483
|
+
|
|
484
|
+
- Use RAII for all resource management
|
|
485
|
+
- Prefer stack allocation over heap
|
|
486
|
+
- Use smart pointers for heap allocation
|
|
487
|
+
- Never use raw `new`/`delete`
|
|
488
|
+
- Use containers instead of manual arrays
|
|
489
|
+
- Check all pointer dereferences
|
|
490
|
+
|
|
491
|
+
Example:
|
|
492
|
+
|
|
493
|
+
```cpp
|
|
494
|
+
// Good: RAII with smart pointers
|
|
495
|
+
class FileManager {
|
|
496
|
+
public:
|
|
497
|
+
explicit FileManager(std::string_view filename)
|
|
498
|
+
: file_(std::make_unique<std::ifstream>(filename.data())) {
|
|
499
|
+
if (!file_->is_open()) {
|
|
500
|
+
throw std::runtime_error("Failed to open file");
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// RAII - file automatically closed
|
|
505
|
+
~FileManager() = default;
|
|
506
|
+
|
|
507
|
+
[[nodiscard]] std::string readLine() {
|
|
508
|
+
std::string line;
|
|
509
|
+
if (std::getline(*file_, line)) {
|
|
510
|
+
return line;
|
|
511
|
+
}
|
|
512
|
+
throw std::runtime_error("Failed to read line");
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
private:
|
|
516
|
+
std::unique_ptr<std::ifstream> file_;
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
// Bad: Manual memory management
|
|
520
|
+
class BadFileManager {
|
|
521
|
+
public:
|
|
522
|
+
BadFileManager(const char* filename) {
|
|
523
|
+
file = new std::ifstream(filename); // ❌ Manual allocation
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
~BadFileManager() {
|
|
527
|
+
delete file; // ❌ Manual deletion (error-prone)
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
private:
|
|
531
|
+
std::ifstream* file; // ❌ Raw pointer
|
|
532
|
+
};
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
## Error Handling
|
|
536
|
+
|
|
537
|
+
- Use exceptions for exceptional cases
|
|
538
|
+
- Use `std::expected` (C++23) or `std::optional` for expected failures
|
|
539
|
+
- Create custom exception classes
|
|
540
|
+
- Document all exceptions with `@throws`
|
|
541
|
+
|
|
542
|
+
Example:
|
|
543
|
+
|
|
544
|
+
```cpp
|
|
545
|
+
#include <stdexcept>
|
|
546
|
+
#include <optional>
|
|
547
|
+
|
|
548
|
+
namespace your_namespace {
|
|
549
|
+
|
|
550
|
+
class ValidationError : public std::runtime_error {
|
|
551
|
+
public:
|
|
552
|
+
explicit ValidationError(std::string_view message, std::string_view field)
|
|
553
|
+
: std::runtime_error(std::string(message))
|
|
554
|
+
, field_(field) {}
|
|
555
|
+
|
|
556
|
+
[[nodiscard]] const std::string& field() const noexcept { return field_; }
|
|
557
|
+
|
|
558
|
+
private:
|
|
559
|
+
std::string field_;
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
class DataValidator {
|
|
563
|
+
public:
|
|
564
|
+
/// @throws ValidationError if data is invalid
|
|
565
|
+
void validate(std::string_view data) const {
|
|
566
|
+
if (data.empty()) {
|
|
567
|
+
throw ValidationError("Data cannot be empty", "data");
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/// @return Optional value if valid, nullopt otherwise
|
|
572
|
+
[[nodiscard]] std::optional<int> tryParse(std::string_view str) const noexcept {
|
|
573
|
+
try {
|
|
574
|
+
return std::stoi(std::string(str));
|
|
575
|
+
} catch (...) {
|
|
576
|
+
return std::nullopt;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
} // namespace your_namespace
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
## Threading & Concurrency
|
|
585
|
+
|
|
586
|
+
- Use `std::thread`, `std::jthread` (C++20), or `std::async`
|
|
587
|
+
- Use `std::mutex`, `std::shared_mutex` for synchronization
|
|
588
|
+
- Prefer `std::atomic` for simple shared state
|
|
589
|
+
- Use `std::lock_guard` or `std::scoped_lock`
|
|
590
|
+
|
|
591
|
+
Example:
|
|
592
|
+
|
|
593
|
+
```cpp
|
|
594
|
+
#include <mutex>
|
|
595
|
+
#include <shared_mutex>
|
|
596
|
+
#include <thread>
|
|
597
|
+
#include <atomic>
|
|
598
|
+
|
|
599
|
+
class ThreadSafeCounter {
|
|
600
|
+
public:
|
|
601
|
+
void increment() {
|
|
602
|
+
std::scoped_lock lock(mutex_);
|
|
603
|
+
++counter_;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
[[nodiscard]] int get() const {
|
|
607
|
+
std::shared_lock lock(mutex_);
|
|
608
|
+
return counter_;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
private:
|
|
612
|
+
mutable std::shared_mutex mutex_;
|
|
613
|
+
int counter_{0};
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
// For simple atomics
|
|
617
|
+
class AtomicCounter {
|
|
618
|
+
public:
|
|
619
|
+
void increment() noexcept {
|
|
620
|
+
counter_.fetch_add(1, std::memory_order_relaxed);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
[[nodiscard]] int get() const noexcept {
|
|
624
|
+
return counter_.load(std::memory_order_relaxed);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
private:
|
|
628
|
+
std::atomic<int> counter_{0};
|
|
629
|
+
};
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
## CI/CD Requirements
|
|
633
|
+
|
|
634
|
+
Must include GitHub Actions workflows for:
|
|
635
|
+
|
|
636
|
+
1. **Testing** (`cpp-test.yml`):
|
|
637
|
+
- Test on ubuntu-latest, windows-latest, macos-latest
|
|
638
|
+
- Test with GCC, Clang, MSVC
|
|
639
|
+
- Upload coverage reports
|
|
640
|
+
|
|
641
|
+
2. **Linting** (`cpp-lint.yml`):
|
|
642
|
+
- clang-format check
|
|
643
|
+
- clang-tidy analysis
|
|
644
|
+
- cppcheck static analysis
|
|
645
|
+
|
|
646
|
+
## Package Publication
|
|
647
|
+
|
|
648
|
+
### Publishing C/C++ Libraries
|
|
649
|
+
|
|
650
|
+
**Options:**
|
|
651
|
+
1. **Conan Center**: Public Conan repository
|
|
652
|
+
2. **vcpkg**: Microsoft's package manager
|
|
653
|
+
3. **GitHub Releases**: Binary releases
|
|
654
|
+
4. **Header-only**: Single-file distribution
|
|
655
|
+
|
|
656
|
+
### Conan Publication
|
|
657
|
+
|
|
658
|
+
**conanfile.py:**
|
|
659
|
+
|
|
660
|
+
```python
|
|
661
|
+
from conan import ConanFile
|
|
662
|
+
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout
|
|
663
|
+
|
|
664
|
+
class YourProjectConan(ConanFile):
|
|
665
|
+
name = "your-project"
|
|
666
|
+
version = "1.0.0"
|
|
667
|
+
license = "MIT"
|
|
668
|
+
author = "Your Name your.email@example.com"
|
|
669
|
+
url = "https://github.com/your-org/your-project"
|
|
670
|
+
description = "Short description"
|
|
671
|
+
topics = ("cpp", "library")
|
|
672
|
+
settings = "os", "compiler", "build_type", "arch"
|
|
673
|
+
|
|
674
|
+
options = {
|
|
675
|
+
"shared": [True, False],
|
|
676
|
+
"fPIC": [True, False]
|
|
677
|
+
}
|
|
678
|
+
default_options = {
|
|
679
|
+
"shared": False,
|
|
680
|
+
"fPIC": True
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
exports_sources = "CMakeLists.txt", "src/*", "include/*"
|
|
684
|
+
|
|
685
|
+
def layout(self):
|
|
686
|
+
cmake_layout(self)
|
|
687
|
+
|
|
688
|
+
def generate(self):
|
|
689
|
+
tc = CMakeToolchain(self)
|
|
690
|
+
tc.generate()
|
|
691
|
+
|
|
692
|
+
def build(self):
|
|
693
|
+
cmake = CMake(self)
|
|
694
|
+
cmake.configure()
|
|
695
|
+
cmake.build()
|
|
696
|
+
|
|
697
|
+
def package(self):
|
|
698
|
+
cmake = CMake(self)
|
|
699
|
+
cmake.install()
|
|
700
|
+
|
|
701
|
+
def package_info(self):
|
|
702
|
+
self.cpp_info.libs = ["your-project"]
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
### vcpkg Publication
|
|
706
|
+
|
|
707
|
+
**vcpkg.json:**
|
|
708
|
+
|
|
709
|
+
```json
|
|
710
|
+
{
|
|
711
|
+
"name": "your-project",
|
|
712
|
+
"version": "1.0.0",
|
|
713
|
+
"description": "Short description",
|
|
714
|
+
"homepage": "https://github.com/your-org/your-project",
|
|
715
|
+
"license": "MIT",
|
|
716
|
+
"dependencies": [
|
|
717
|
+
{
|
|
718
|
+
"name": "vcpkg-cmake",
|
|
719
|
+
"host": true
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
"name": "vcpkg-cmake-config",
|
|
723
|
+
"host": true
|
|
724
|
+
}
|
|
725
|
+
]
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
### Publishing Checklist:
|
|
730
|
+
|
|
731
|
+
- ✅ All tests passing with sanitizers
|
|
732
|
+
- ✅ clang-tidy clean
|
|
733
|
+
- ✅ clang-format applied
|
|
734
|
+
- ✅ Documentation generated
|
|
735
|
+
- ✅ Version updated in CMakeLists.txt
|
|
736
|
+
- ✅ CHANGELOG.md updated
|
|
737
|
+
- ✅ README.md with build instructions
|
|
738
|
+
- ✅ LICENSE file present
|
|
739
|
+
- ✅ CMake config for find_package support
|
|
740
|
+
- ✅ Conan recipe or vcpkg portfile
|
|
741
|
+
|
|
742
|
+
<!-- CPP:END -->
|
|
743
|
+
|