diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000..186c684 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,2 @@ +This is the minimal devcontainers configuration e.g. for use in VSCode or CLion. +If you don't use devcontainers, feel free to delete this directory. diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..46cd079 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,47 @@ +{ + "image": "ghcr.io/userver-framework/ubuntu-22.04-userver-pg-dev", + "remoteUser": "user", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/user/service_template,type=bind", + "workspaceFolder": "/home/user/service_template", + "runArgs": [ + "--cap-add=SYS_PTRACE", + "--security-opt", + "seccomp=unconfined" + ], + "forwardPorts": [ + 8080 + ], + "containerEnv": { + "SHELL": "/bin/bash", + "PREFIX": "${PREFIX:-~/.local}", + "CCACHE_DIR": "/home/user/service_template/.ccache", + "CORES_DIR": "/cores" + }, + "customizations": { + "vscode": { + "extensions": [ + "llvm-vs-code-extensions.vscode-clangd", + "ms-vscode.cmake-tools", + "ms-vscode.makefile-tools", + "vadimcn.vscode-lldb", + "ms-azuretools.vscode-docker" + ], + "settings": { + "cmake.automaticReconfigure": false, + "cmake.configureOnEdit": false, + "cmake.configureOnOpen": false, + "cmake.copyCompileCommands": "${workspaceFolder}/.vscode/compile_commands.json", + "clangd.path": "/usr/bin/clangd", + "clangd.arguments": [ + "--background-index", + "--compile-commands-dir=.vscode", + "--clang-tidy", + "--completion-style=detailed", + "--header-insertion=never" + ] + } + } + }, + "onCreateCommand": "sudo git config --global --add safe.directory /home/user/service_template", + "mounts": [] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01db7be..8429e1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,17 +72,17 @@ jobs: - name: Test run after install if: matrix.make == 'test-release' run: >- - ./local_installation/bin/pg_service_template - --config=./local_installation/etc/pg_service_template/static_config.yaml - --config_vars=./local_installation/etc/pg_service_template/config_vars.yaml + ./local_installation/bin/service_template + --config=./local_installation/etc/service_template/static_config.yaml + --config_vars=./local_installation/etc/service_template/config_vars.yaml & - name: Check work run service if: matrix.make == 'test-release' run: | - ps aux | grep pg_service_template | grep config && curl http://localhost:8080/ping -v + ps aux | grep service_template | grep config && curl http://localhost:8080/ping -v - name: Stop all if: matrix.make == 'test-release' run: | - killall pg_service_template + killall service_template diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 104528a..a495916 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -33,7 +33,7 @@ jobs: sudo apt install --allow-downgrades -y docker-compose - name: Setup ccache - run: docker-compose run --rm pg_service_template-container bash -c 'ccache -M 2.0GB && ccache -s' + run: docker-compose run --rm service_template-container bash -c 'ccache -M 2.0GB && ccache -s' - name: Cmake run: make docker-cmake-release diff --git a/.vscode/cmake-variants.yaml b/.vscode/cmake-variants.yaml deleted file mode 100644 index 955a8f2..0000000 --- a/.vscode/cmake-variants.yaml +++ /dev/null @@ -1,17 +0,0 @@ -buildType: - default: debug - choices: - debug: - short: Debug - long: Unoptimized debug build with sanitizers - buildType: Debug - settings: - CMAKE_EXPORT_COMPILE_COMMANDS: ON - USERVER_SANITIZE: addr ub - - release: - short: Release - long: Optimized build - buildType: Release - settings: - CMAKE_EXPORT_COMPILE_COMMANDS: ON diff --git a/CMakeLists.txt b/CMakeLists.txt index cd3ad10..d8ce354 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.12) -project(pg_service_template CXX) +project(service_template CXX) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(DownloadUserver) diff --git a/CMakePresets.json b/CMakePresets.json index e7c9e50..145fd18 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -13,7 +13,7 @@ "inherits": [ "common-flags" ], - "binaryDir": "${sourceDir}/build_debug", + "binaryDir": "${sourceDir}/build-debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "USERVER_SANITIZE": "addr;ub" @@ -26,7 +26,7 @@ "inherits": [ "common-flags" ], - "binaryDir": "${sourceDir}/build_release", + "binaryDir": "${sourceDir}/build-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } diff --git a/Makefile b/Makefile index ad5d9f5..c19c8c2 100644 --- a/Makefile +++ b/Makefile @@ -1,67 +1,54 @@ -CMAKE_COMMON_FLAGS ?= -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -CMAKE_DEBUG_FLAGS ?= --preset debug -CMAKE_RELEASE_FLAGS ?= --preset release +PROJECT_NAME = service_template NPROCS ?= $(shell nproc) CLANG_FORMAT ?= clang-format DOCKER_COMPOSE ?= docker-compose - -# NOTE: use Makefile.local to override the options defined above. --include Makefile.local - -CMAKE_DEBUG_FLAGS += -DCMAKE_BUILD_TYPE=Debug $(CMAKE_COMMON_FLAGS) -CMAKE_RELEASE_FLAGS += -DCMAKE_BUILD_TYPE=Release $(CMAKE_COMMON_FLAGS) +PRESETS ?= debug release debug-custom release-custom .PHONY: all all: test-debug test-release # Run cmake -.PHONY: cmake-debug -cmake-debug: - cmake -B build_debug $(CMAKE_DEBUG_FLAGS) - -.PHONY: cmake-release -cmake-release: - cmake -B build_release $(CMAKE_RELEASE_FLAGS) +.PHONY: $(addprefix cmake-, $(PRESETS)) +$(addprefix cmake-, $(PRESETS)): cmake-%: + cmake --preset $* -build_debug/CMakeCache.txt: cmake-debug -build_release/CMakeCache.txt: cmake-release +$(addsuffix /CMakeCache.txt, $(addprefix build-, $(PRESETS))): build-%/CMakeCache.txt: cmake-% # Build using cmake -.PHONY: build-debug build-release -build-debug build-release: build-%: build_%/CMakeCache.txt - cmake --build build_$* -j $(NPROCS) --target pg_service_template +.PHONY: $(addprefix build-, $(PRESETS)) +$(addprefix build-, $(PRESETS)): build-%: build-%/CMakeCache.txt + cmake --build build-$* -j $(NPROCS) --target $(PROJECT_NAME) # Test -.PHONY: test-debug test-release -test-debug test-release: test-%: build-% - cmake --build build_$* -j $(NPROCS) --target pg_service_template_unittest - cmake --build build_$* -j $(NPROCS) --target pg_service_template_benchmark - cd build_$* && ((test -t 1 && GTEST_COLOR=1 PYTEST_ADDOPTS="--color=yes" ctest -V) || ctest -V) +.PHONY: $(addprefix test-, $(PRESETS)) +$(addprefix test-, $(PRESETS)): test-%: build-%/CMakeCache.txt + cmake --build build-$* -j $(NPROCS) + cd build-$* && ((test -t 1 && GTEST_COLOR=1 PYTEST_ADDOPTS="--color=yes" ctest -V) || ctest -V) pycodestyle tests # Start the service (via testsuite service runner) -.PHONY: start-debug start-release -start-debug start-release: start-%: build-% - cmake --build build_$* -v --target start-pg_service_template - -.PHONY: service-start-debug service-start-release -service-start-debug service-start-release: service-start-%: start-% +.PHONY: $(addprefix start-, $(PRESETS)) +$(addprefix start-, $(PRESETS)): start-%: + cmake --build build-$* -v --target start-$(PROJECT_NAME) # Cleanup data -.PHONY: clean-debug clean-release -clean-debug clean-release: clean-%: - cmake --build build_$* --target clean +.PHONY: $(addprefix clean-, $(PRESETS)) +$(addprefix clean-, $(PRESETS)): clean-%: + cmake --build build-$* --target clean .PHONY: dist-clean dist-clean: - rm -rf build_* + rm -rf build* rm -rf tests/__pycache__/ rm -rf tests/.pytest_cache/ + rm -rf .ccache + rm -rf .vscode/.cache + rm -rf .vscode/compile_commands.json # Install -.PHONY: install-debug install-release -install-debug install-release: install-%: build-% - cmake --install build_$* -v --component pg_service_template +.PHONY: $(addprefix install-, $(PRESETS)) +$(addprefix install-, $(PRESETS)): install-%: build-% + cmake --install build-$* -v --component $(PROJECT_NAME) .PHONY: install install: install-release @@ -76,24 +63,22 @@ format: export DB_CONNECTION := postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@service-postgres:5432/${POSTGRES_DB} # Internal hidden targets that are used only in docker environment ---in-docker-start-debug --in-docker-start-release: --in-docker-start-%: install-% +.PHONY: $(addprefix --in-docker-start-, $(PRESETS)) +$(addprefix --in-docker-start-, $(PRESETS)): --in-docker-start-%: install-% psql ${DB_CONNECTION} -f ./postgresql/data/initial_data.sql - /home/user/.local/bin/pg_service_template \ - --config /home/user/.local/etc/pg_service_template/static_config.yaml \ - --config_vars /home/user/.local/etc/pg_service_template/config_vars.docker.yaml + /home/user/.local/bin/$(PROJECT_NAME) \ + --config /home/user/.local/etc/$(PROJECT_NAME)/static_config.yaml \ + --config_vars /home/user/.local/etc/$(PROJECT_NAME)/config_vars.docker.yaml # Build and run service in docker environment -.PHONY: docker-start-debug docker-start-release +.PHONY: $(addprefix docker-start-, $(PRESETS)) docker-start-debug docker-start-release: docker-start-%: - $(DOCKER_COMPOSE) run -p 8080:8080 --rm pg_service_template-container make -- --in-docker-start-$* - -.PHONY: docker-start-service-debug docker-start-service-release -docker-start-service-debug docker-start-service-release: docker-start-service-%: docker-start-% + $(DOCKER_COMPOSE) run -p 8080:8080 --rm service_template-container make -- --in-docker-start-$* # Start targets makefile in docker environment -.PHONY: docker-cmake-debug docker-build-debug docker-test-debug docker-clean-debug docker-install-debug docker-cmake-release docker-build-release docker-test-release docker-clean-release docker-install-release -docker-cmake-debug docker-build-debug docker-test-debug docker-clean-debug docker-install-debug docker-cmake-release docker-build-release docker-test-release docker-clean-release docker-install-release: docker-%: - $(DOCKER_COMPOSE) run --rm pg_service_template-container make $* +.PHONY: $(addprefix docker-cmake-, $(PRESETS)) $(addprefix docker-build-, $(PRESETS)) $(addprefix docker-test-, $(PRESETS)) $(addprefix docker-clean-, $(PRESETS)) $(addprefix docker-install-, $(PRESETS)) +$(addprefix docker-cmake-, $(PRESETS)) $(addprefix docker-build-, $(PRESETS)) $(addprefix docker-test-, $(PRESETS)) $(addprefix docker-clean-, $(PRESETS)) $(addprefix docker-install-, $(PRESETS)): docker-%: + $(DOCKER_COMPOSE) run --rm $(PROJECT_NAME)-container make $* # Stop docker container and remove PG data .PHONY: docker-clean-data diff --git a/README.md b/README.md index 0e3518a..f473eb1 100644 --- a/README.md +++ b/README.md @@ -7,38 +7,29 @@ Template of a C++ service that uses [userver framework](https://github.com/userv To create your own userver-based service follow the following steps: -1. Press the green "Use this template button" at the top of this github page +1. Press the "Use this template button" at the top right of this GitHub page 2. Clone the service `git clone your-service-repo && cd your-service-repo` -3. Give a propper name to your service and replace all the occurences of "pg_service_template" string with that name - (could be done via `find . -not -path "./third_party/*" -not -path ".git/*" -not -path './build_*' -type f | xargs sed -i 's/pg_service_template/YOUR_SERVICE_NAME/g'`). +3. Give a proper name to your service and replace all the occurrences of "service_template" string with that name + (could be done via `find . -not -path "./third_party/*" -not -path ".git/*" -not -path './build_*' -type f | xargs sed -i 's/service_template/YOUR_SERVICE_NAME/g'`). 4. Feel free to tweak, adjust or fully rewrite the source code of your service. ## Makefile -Makefile contains typicaly useful targets for development: - -* `make build-debug` - debug build of the service with all the assertions and sanitizers enabled -* `make build-release` - release build of the service with LTO -* `make test-debug` - does a `make build-debug` and runs all the tests on the result -* `make test-release` - does a `make build-release` and runs all the tests on the result -* `make start-debug` - builds the service in debug mode and starts it -* `make start-release` - builds the service in release mode and starts it -* `make` or `make all` - builds and runs all the tests in release and debug modes -* `make format` - autoformat all the C++ and Python sources -* `make clean-` - cleans the object files -* `make dist-clean` - clean all, including the CMake cached configurations -* `make install` - does a `make build-release` and runs install in directory set in environment `PREFIX` -* `make install-debug` - does a `make build-debug` and runs install in directory set in environment `PREFIX` +`PRESET` is either `debug`, `release`, or if you've added custom presets in `CMakeUserPresets.json`, it +can also be `debug-custom`, `release-custom`. + +* `make cmake-PRESET` - run cmake configure, update cmake options and source file lists +* `make build-PRESET` - build the service +* `make test-PRESET` - build the service and run all tests +* `make start-PRESET` - build the service, start it in testsuite environment and leave it running +* `make install-PRESET` - build the service and install it in directory set in environment `PREFIX` +* `make` or `make all` - build and run all tests in `debug` and `release` modes +* `make format` - reformat all C++ and Python sources +* `make dist-clean` - clean build files and cmake cache * `make docker-COMMAND` - run `make COMMAND` in docker environment -* `make docker-build-debug` - debug build of the service with all the assertions and sanitizers enabled in docker environment -* `make docker-test-debug` - does a `make build-debug` and runs all the tests on the result in docker environment -* `make docker-start-release` - does a `make install-release` and runs service in docker environment -* `make docker-start-debug` - does a `make install-debug` and runs service in docker environment * `make docker-clean-data` - stop docker containers and clean database data -Edit `Makefile.local` to change the default configuration and build options. - ## License diff --git a/configs/config_vars.testing.yaml b/configs/config_vars.testing.yaml index d10069b..579c3c5 100644 --- a/configs/config_vars.testing.yaml +++ b/configs/config_vars.testing.yaml @@ -6,5 +6,5 @@ is-testing: true server-port: 8080 -# pg_service_template_db_1 is the service name + _ + filename of the db_1.sql -dbconnection: 'postgresql://testsuite@localhost:15433/pg_service_template_db_1' +# service_template_db_1 is the service name + _ + filename of the db_1.sql +dbconnection: 'postgresql://testsuite@localhost:15433/service_template_db_1' diff --git a/configs/config_vars.yaml b/configs/config_vars.yaml index 9eb01e2..7bed93f 100644 --- a/configs/config_vars.yaml +++ b/configs/config_vars.yaml @@ -6,4 +6,4 @@ is-testing: false server-port: 8080 -dbconnection: 'postgresql://pg_service_template_user:password@localhost:5432/pg_service_template_db_1' +dbconnection: 'postgresql://service_template_user:password@localhost:5432/service_template_db_1' diff --git a/docker-compose.yml b/docker-compose.yml index 12873d4..b6ed639 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,7 +5,7 @@ services: container_name: service-postgres image: postgres:12 environment: &db_env - POSTGRES_DB: pg_service_template_db_1 + POSTGRES_DB: service_template_db_1 POSTGRES_USER: user POSTGRES_PASSWORD: password ports: @@ -16,20 +16,20 @@ services: networks: - postgres - pg_service_template-container: + service_template-container: image: ghcr.io/userver-framework/ubuntu-22.04-userver-pg:latest privileged: true environment: <<: *db_env PREFIX: ${PREFIX:-~/.local} - CCACHE_DIR: /pg_service_template/.ccache + CCACHE_DIR: /service_template/.ccache CORES_DIR: /cores volumes: - - .:/pg_service_template:rw + - .:/service_template:rw - ${TC_CORES_DIR:-./.cores}:/cores:rw ports: - 8080:8080 - working_dir: /pg_service_template + working_dir: /service_template entrypoint: - ./tests/run_as_user.sh depends_on: diff --git a/src/hello.cpp b/src/hello.cpp index f4de57a..35d42fb 100644 --- a/src/hello.cpp +++ b/src/hello.cpp @@ -9,7 +9,7 @@ #include #include -namespace pg_service_template { +namespace service_template { namespace { @@ -45,7 +45,7 @@ class Hello final : public userver::server::handlers::HttpHandlerBase { } } - return pg_service_template::SayHelloTo(name, user_type); + return service_template::SayHelloTo(name, user_type); } userver::storages::postgres::ClusterPtr pg_cluster_; @@ -74,4 +74,4 @@ void AppendHello(userver::components::ComponentList& component_list) { component_list.Append(); } -} // namespace pg_service_template +} // namespace service_template diff --git a/src/hello.hpp b/src/hello.hpp index 2b5055a..a524119 100644 --- a/src/hello.hpp +++ b/src/hello.hpp @@ -5,11 +5,11 @@ #include -namespace pg_service_template { +namespace service_template { enum class UserType { kFirstTime, kKnown }; std::string SayHelloTo(std::string_view name, UserType type); void AppendHello(userver::components::ComponentList& component_list); -} // namespace pg_service_template +} // namespace service_template diff --git a/src/hello_benchmark.cpp b/src/hello_benchmark.cpp index d094da5..c310460 100644 --- a/src/hello_benchmark.cpp +++ b/src/hello_benchmark.cpp @@ -14,8 +14,8 @@ void HelloBenchmark(benchmark::State& state) { for (auto _ : state) { const auto name = kNames[i++ % std::size(kNames)]; - auto result = pg_service_template::SayHelloTo( - name, pg_service_template::UserType::kFirstTime); + auto result = service_template::SayHelloTo( + name, service_template::UserType::kFirstTime); benchmark::DoNotOptimize(result); } }); diff --git a/src/hello_test.cpp b/src/hello_test.cpp index d30c231..289d12d 100644 --- a/src/hello_test.cpp +++ b/src/hello_test.cpp @@ -3,8 +3,8 @@ #include UTEST(SayHelloTo, Basic) { - using pg_service_template::SayHelloTo; - using pg_service_template::UserType; + using service_template::SayHelloTo; + using service_template::UserType; EXPECT_EQ(SayHelloTo("Developer", UserType::kFirstTime), "Hello, Developer!\n"); diff --git a/src/main.cpp b/src/main.cpp index 128bc4e..fc1e174 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,7 +14,7 @@ int main(int argc, char* argv[]) { .Append() .Append(); - pg_service_template::AppendHello(component_list); + service_template::AppendHello(component_list); return userver::utils::DaemonMain(argc, argv, component_list); } diff --git a/tests/conftest.py b/tests/conftest.py index b5e7f2d..c394938 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -26,7 +26,7 @@ def initial_data_path(service_source_dir): def pgsql_local(service_source_dir, pgsql_local_create): """Create schemas databases for tests""" databases = discover.find_schemas( - 'pg_service_template', # service name that goes to the DB connection + 'service_template', # service name that goes to the DB connection [service_source_dir.joinpath('postgresql/schemas')], ) return pgsql_local_create(list(databases.values()))