From d4aac99a2161e5a2a73d979b20392b464de368e2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Dec 2025 03:44:16 +0000 Subject: [PATCH] Add Docker support and flexible build system for Drogon Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com> --- backend/CMakeLists.txt | 27 ++++--- backend/Dockerfile | 46 ++++++++++++ backend/README.md | 140 +++++++++++++++++++++++++++++++++---- backend/build.sh | 59 +++++++++++++--- backend/docker-compose.yml | 14 ++++ backend/install_drogon.sh | 51 ++++++++++++++ 6 files changed, 304 insertions(+), 33 deletions(-) create mode 100644 backend/Dockerfile create mode 100644 backend/docker-compose.yml create mode 100755 backend/install_drogon.sh diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index b250072..0bae47b 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # Find dependencies via Conan -find_package(Drogon CONFIG REQUIRED) +find_package(Drogon CONFIG QUIET) find_package(GTest QUIET) # Library sources @@ -21,13 +21,23 @@ target_include_directories(wizardmerge $ ) -# Executable -add_executable(wizardmerge-cli - src/main.cpp - src/controllers/MergeController.cc -) +# Executable (only if Drogon is found) +if(Drogon_FOUND) + add_executable(wizardmerge-cli + src/main.cpp + src/controllers/MergeController.cc + ) -target_link_libraries(wizardmerge-cli PRIVATE wizardmerge Drogon::Drogon) + target_link_libraries(wizardmerge-cli PRIVATE wizardmerge Drogon::Drogon) + + install(TARGETS wizardmerge-cli + RUNTIME DESTINATION bin + ) + + message(STATUS "Drogon found - building HTTP server") +else() + message(WARNING "Drogon not found - skipping HTTP server build. Install Drogon to build the server.") +endif() # Tests (if GTest is available) if(GTest_FOUND) @@ -42,10 +52,9 @@ if(GTest_FOUND) endif() # Install targets -install(TARGETS wizardmerge wizardmerge-cli +install(TARGETS wizardmerge LIBRARY DESTINATION lib ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin ) install(DIRECTORY include/ DESTINATION include) diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..3557658 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,46 @@ +# Dockerfile for WizardMerge Backend with Drogon +FROM ubuntu:22.04 + +# Install dependencies +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + git \ + gcc \ + g++ \ + cmake \ + ninja-build \ + libjsoncpp-dev \ + uuid-dev \ + zlib1g-dev \ + libssl-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install Drogon framework +WORKDIR /tmp +RUN git clone https://github.com/drogonframework/drogon.git && \ + cd drogon && \ + git submodule update --init && \ + mkdir build && cd build && \ + cmake .. -DCMAKE_BUILD_TYPE=Release && \ + make -j$(nproc) && \ + make install && \ + cd /tmp && rm -rf drogon + +# Set up work directory +WORKDIR /app +COPY . . + +# Build WizardMerge +RUN mkdir -p build && cd build && \ + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release && \ + ninja + +# Expose port +EXPOSE 8080 + +# Copy config to build directory +RUN cp config.json build/ + +# Run the server +WORKDIR /app/build +CMD ["./wizardmerge-cli"] diff --git a/backend/README.md b/backend/README.md index 1200a90..2e086aa 100644 --- a/backend/README.md +++ b/backend/README.md @@ -14,31 +14,79 @@ This is the C++ backend for WizardMerge implementing the core merge algorithms w ### Prerequisites +**Required:** +- C++17 compiler (GCC 7+, Clang 6+, MSVC 2017+) +- CMake 3.15+ +- Ninja build tool + +**For HTTP Server:** +- Drogon framework (see installation methods below) + +### Installation Methods + +#### Method 1: Using Installer Script (Recommended) + +```sh +# Install Drogon from source +./install_drogon.sh + +# Build WizardMerge +./build.sh +``` + +#### Method 2: Using Docker (Easiest) + +```sh +# Build and run with Docker Compose +docker-compose up --build + +# Or use Docker directly +docker build -t wizardmerge-backend . +docker run -p 8080:8080 wizardmerge-backend +``` + +#### Method 3: Using Conan + ```sh # Install Conan pip install conan -# Install CMake and Ninja -# On Ubuntu/Debian: -sudo apt-get install cmake ninja-build +# Build with Conan +./build.sh +``` -# On macOS: -brew install cmake ninja +Note: Conan requires internet access to download Drogon. + +#### Method 4: Manual CMake Build + +If you have Drogon already installed system-wide: + +```sh +mkdir build && cd build +cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release +ninja ``` ### Build Steps +The build script automatically handles dependencies and provides multiple build options: + ```sh -# Configure with Conan -conan install . --output-folder=build --build=missing +# Automatic build (tries Conan, falls back to direct CMake) +./build.sh +``` -# Build with CMake and Ninja -cd build -cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release +If Drogon is not found, the library will still build but the HTTP server will be skipped. + +### Running Without Drogon + +If you only need the merge library (not the HTTP server): + +```sh +mkdir build && cd build +cmake .. -G Ninja ninja - -# Run the HTTP server -./wizardmerge-cli +# This builds libwizardmerge.a which can be linked into other applications ``` ## Testing @@ -119,3 +167,69 @@ curl -X POST http://localhost:8080/api/merge \ "theirs": ["line1", "line2_theirs", "line3"] }' ``` + +## Deployment + +### Production Deployment with Docker + +The recommended way to deploy in production: + +```sh +# Using Docker Compose +docker-compose up -d + +# Check logs +docker-compose logs -f + +# Stop the server +docker-compose down +``` + +### Configuration + +Edit `config.json` to customize server settings: + +- `listeners[].port`: Change server port (default: 8080) +- `app.threads_num`: Number of worker threads (default: 4) +- `app.log.log_level`: Logging level (DEBUG, INFO, WARN, ERROR) +- `app.client_max_body_size`: Maximum request body size + +### Monitoring + +Logs are written to `./logs/` directory by default. Monitor with: + +```sh +tail -f logs/wizardmerge.log +``` + +## Development + +### Architecture + +The backend is now structured as a Drogon HTTP API server: + +- **Core Library** (`libwizardmerge.a`): Contains the merge algorithms +- **HTTP Server** (`wizardmerge-cli`): Drogon-based API server +- **Controllers** (`src/controllers/`): HTTP request handlers +- **Configuration** (`config.json`): Server settings + +### Adding New Endpoints + +1. Create a new controller in `src/controllers/` +2. Implement the controller methods +3. Add the controller source to CMakeLists.txt +4. Rebuild the project + +Example controller structure: + +```cpp +class MyController : public HttpController { + public: + METHOD_LIST_BEGIN + ADD_METHOD_TO(MyController::myMethod, "/api/mypath", Post); + METHOD_LIST_END + + void myMethod(const HttpRequestPtr &req, + std::function &&callback); +}; +``` diff --git a/backend/build.sh b/backend/build.sh index c75d744..5a2e46e 100755 --- a/backend/build.sh +++ b/backend/build.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Build script for WizardMerge C++ backend using Conan and Ninja +# Build script for WizardMerge C++ backend with Drogon support set -e @@ -7,21 +7,48 @@ echo "=== WizardMerge C++ Backend Build ===" echo # Check for required tools -command -v conan >/dev/null 2>&1 || { echo "Error: conan not found. Install with: pip install conan"; exit 1; } -command -v ninja >/dev/null 2>&1 || { echo "Error: ninja not found. Install with: apt-get install ninja-build / brew install ninja"; exit 1; } command -v cmake >/dev/null 2>&1 || { echo "Error: cmake not found."; exit 1; } +command -v ninja >/dev/null 2>&1 || { echo "Error: ninja not found. Install with: apt-get install ninja-build / brew install ninja"; exit 1; } + +# Check if Drogon is installed +if ! pkg-config --exists drogon 2>/dev/null && ! ldconfig -p 2>/dev/null | grep -q libdrogon; then + echo "WARNING: Drogon framework not found." + echo "The library will be built, but the HTTP server will be skipped." + echo + echo "To build the HTTP server, install Drogon first:" + echo " Option 1: Run ./install_drogon.sh" + echo " Option 2: Use Docker: docker-compose up --build" + echo " Option 3: Use Conan: conan install . --output-folder=build --build=missing" + echo + read -p "Continue building without Drogon? (y/n) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi +fi # Create build directory mkdir -p build cd build -# Install dependencies with Conan -echo "Installing dependencies with Conan..." -conan install .. --output-folder=. --build=missing - -# Configure with CMake -echo "Configuring with CMake..." -cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release +# Check if we should use Conan +if command -v conan >/dev/null 2>&1 && [ -f ../conanfile.py ]; then + echo "Installing dependencies with Conan..." + conan install .. --output-folder=. --build=missing 2>/dev/null && CONAN_SUCCESS=true || CONAN_SUCCESS=false + + if [ "$CONAN_SUCCESS" = true ]; then + echo "Configuring with CMake (Conan toolchain)..." + cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release + else + echo "Conan installation failed, trying without Conan..." + echo "Configuring with CMake..." + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release + fi +else + # Configure with CMake (without Conan) + echo "Configuring with CMake..." + cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release +fi # Build with Ninja echo "Building with Ninja..." @@ -29,4 +56,14 @@ ninja echo echo "=== Build Complete ===" -echo "Binary: build/wizardmerge-cli" +if [ -f wizardmerge-cli ]; then + echo "HTTP Server: build/wizardmerge-cli" + echo "Run with: cd build && ./wizardmerge-cli" +else + echo "Library: build/libwizardmerge.a" + echo "HTTP server not built (Drogon not found)" +fi +if [ -f wizardmerge-tests ]; then + echo "Tests: build/wizardmerge-tests" + echo "Run with: cd build && ./wizardmerge-tests" +fi diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml new file mode 100644 index 0000000..1a7e96b --- /dev/null +++ b/backend/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3.8' + +services: + wizardmerge-backend: + build: + context: . + dockerfile: Dockerfile + ports: + - "8080:8080" + volumes: + - ./logs:/app/build/logs + restart: unless-stopped + environment: + - LOG_LEVEL=INFO diff --git a/backend/install_drogon.sh b/backend/install_drogon.sh new file mode 100755 index 0000000..fc0ee3d --- /dev/null +++ b/backend/install_drogon.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Script to install Drogon framework from source +# Run this script before building WizardMerge if Drogon is not installed + +set -e + +echo "=== Installing Drogon Framework from Source ===" +echo + +# Check for required tools +command -v git >/dev/null 2>&1 || { echo "Error: git not found."; exit 1; } +command -v cmake >/dev/null 2>&1 || { echo "Error: cmake not found."; exit 1; } +command -v make >/dev/null 2>&1 || { echo "Error: make not found."; exit 1; } + +# Install system dependencies (Ubuntu/Debian) +if command -v apt-get >/dev/null 2>&1; then + echo "Installing system dependencies..." + sudo apt-get update + sudo apt-get install -y \ + libjsoncpp-dev \ + uuid-dev \ + zlib1g-dev \ + libssl-dev +fi + +# Clone Drogon +TEMP_DIR=$(mktemp -d) +cd "$TEMP_DIR" + +echo "Cloning Drogon from GitHub..." +git clone https://github.com/drogonframework/drogon.git +cd drogon +git submodule update --init + +# Build and install +echo "Building Drogon..." +mkdir build +cd build +cmake .. -DCMAKE_BUILD_TYPE=Release +make -j$(nproc) + +echo "Installing Drogon..." +sudo make install + +# Cleanup +cd / +rm -rf "$TEMP_DIR" + +echo +echo "=== Drogon Installation Complete ===" +echo "You can now build WizardMerge with: ./build.sh"