mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-09 14:25:51 +00:00
Compare commits
185 Commits
update/pre
...
update/pre
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
429753b9bb | ||
|
|
48855633b5 | ||
|
|
c26df5e1fb | ||
|
|
9fb26d77ed | ||
|
|
c3c8b2d796 | ||
|
|
2f3e9498dc | ||
|
|
d2de240389 | ||
|
|
245a808e4b | ||
|
|
586a2116a4 | ||
|
|
93919ab8b7 | ||
|
|
e92a63f4e5 | ||
|
|
5e5dd649cf | ||
|
|
fb1cdcbde5 | ||
|
|
b66d13bc74 | ||
|
|
e78ff5c442 | ||
|
|
c499f9d679 | ||
|
|
420b99cfa1 | ||
|
|
3f2ada3439 | ||
|
|
e996f2b7ab | ||
|
|
26112d17f8 | ||
|
|
e4abec4b98 | ||
|
|
503e23055b | ||
|
|
97480ce626 | ||
|
|
bd966e636e | ||
|
|
91b248e3b2 | ||
|
|
140ac78e15 | ||
|
|
f1bf423f69 | ||
|
|
dcf369e4ec | ||
|
|
56f4dc591c | ||
|
|
c40cd8154f | ||
|
|
989a0c8468 | ||
|
|
1adbed7913 | ||
|
|
490ec41083 | ||
|
|
384e79cd32 | ||
|
|
9edc26a2a3 | ||
|
|
08bb619964 | ||
|
|
26ef25f864 | ||
|
|
a62084a4f0 | ||
|
|
b8c298b734 | ||
|
|
cf4d5d649a | ||
|
|
eb2778ccad | ||
|
|
790402bcfb | ||
|
|
7c68770787 | ||
|
|
d9faf7a833 | ||
|
|
90ac03cae7 | ||
|
|
3a667f558c | ||
|
|
0a2930d861 | ||
|
|
e86178b523 | ||
|
|
10e15b524f | ||
|
|
402ab29a73 | ||
|
|
3df28f42ec | ||
|
|
0e8896ad06 | ||
|
|
ffd18049eb | ||
|
|
7413e02a05 | ||
|
|
0403248a8f | ||
|
|
e6b2f9cde7 | ||
|
|
2512a9c8e7 | ||
|
|
5e7f6bb5bd | ||
|
|
ae15bbd7b5 | ||
|
|
33c0737933 | ||
|
|
b26fcae690 | ||
|
|
60baaf921f | ||
|
|
f41e06061f | ||
|
|
c170c56a84 | ||
|
|
c9c392679d | ||
|
|
47f5ae5f12 | ||
|
|
6c34458d6c | ||
|
|
ec40cc93ff | ||
|
|
3681ef4e41 | ||
|
|
e2fbf56277 | ||
|
|
2d48de372b | ||
|
|
c780ef8a0b | ||
|
|
d833d36896 | ||
|
|
7a2090bc00 | ||
|
|
b5892dd139 | ||
|
|
a172d0b7ea | ||
|
|
e9ab081ab7 | ||
|
|
caedb51f00 | ||
|
|
e6abdda0a7 | ||
|
|
46c96654ee | ||
|
|
57ac234657 | ||
|
|
4232359dce | ||
|
|
8b1cab46e7 | ||
|
|
e05505aa4f | ||
|
|
73bc85864b | ||
|
|
373430924b | ||
|
|
8ad111655c | ||
|
|
0a8470758d | ||
|
|
1ec906addc | ||
|
|
afc0a358d9 | ||
|
|
af284dda37 | ||
|
|
7558348d14 | ||
|
|
0d262e74bc | ||
|
|
312e7be2b4 | ||
|
|
de9b79adf0 | ||
|
|
6c68360234 | ||
|
|
7e42507b9a | ||
|
|
36bfcc7543 | ||
|
|
4a5278a915 | ||
|
|
333b73e882 | ||
|
|
9420c506ca | ||
|
|
707427c63a | ||
|
|
5eea26d9ac | ||
|
|
226d386be2 | ||
|
|
c95d8f2f89 | ||
|
|
ed5dfc6c0e | ||
|
|
2600198bd5 | ||
|
|
c83be63b9c | ||
|
|
4aa2ca94de | ||
|
|
87565b685a | ||
|
|
e4d0c1ca48 | ||
|
|
498232baf8 | ||
|
|
43f4828a61 | ||
|
|
1a298dedd2 | ||
|
|
6c9c88e3fc | ||
|
|
156b858db7 | ||
|
|
cfffbfba9d | ||
|
|
97a938a2a9 | ||
|
|
63d664b9fb | ||
|
|
40824812d6 | ||
|
|
288ffb8fef | ||
|
|
a9cf781ca5 | ||
|
|
a446d85297 | ||
|
|
dc18aefb33 | ||
|
|
e312354016 | ||
|
|
ba905e38ae | ||
|
|
f35e5ac784 | ||
|
|
a9b02fb292 | ||
|
|
bc8a2c19aa | ||
|
|
46b86a5d61 | ||
|
|
3defcaecac | ||
|
|
d7888d5556 | ||
|
|
f518936e69 | ||
|
|
9e35f16be1 | ||
|
|
d048641242 | ||
|
|
f347a732a6 | ||
|
|
0e2ba4a64e | ||
|
|
4a4f8842bd | ||
|
|
a63805d631 | ||
|
|
b3beb50e8f | ||
|
|
0be712c363 | ||
|
|
ad5f0642ba | ||
|
|
4948882545 | ||
|
|
5778363689 | ||
|
|
d6fec5b5ff | ||
|
|
e380214496 | ||
|
|
1463b0e3e5 | ||
|
|
60bbe1eb72 | ||
|
|
b29e2e4c88 | ||
|
|
bcaa5f3392 | ||
|
|
3f0f20a542 | ||
|
|
00333a8d16 | ||
|
|
61c17400fe | ||
|
|
d43002b49a | ||
|
|
30880ad627 | ||
|
|
25e55ef952 | ||
|
|
579e6030ca | ||
|
|
d93b23206e | ||
|
|
1b63c3c315 | ||
|
|
a8e61204da | ||
|
|
bef24c1387 | ||
|
|
b6c1e2578b | ||
|
|
e0496aff5a | ||
|
|
2f7adfb883 | ||
|
|
0f1895947d | ||
|
|
fa693b2aff | ||
|
|
1825ea701f | ||
|
|
2ae5b13fb9 | ||
|
|
686a732fa8 | ||
|
|
4919b57466 | ||
|
|
44d39f335e | ||
|
|
bfe5b52a64 | ||
|
|
413b823976 | ||
|
|
e664f0b9ce | ||
|
|
907bd7a58f | ||
|
|
f94a9864f0 | ||
|
|
36ea0389e2 | ||
|
|
12640de22d | ||
|
|
ae4f2d9023 | ||
|
|
b7b61ef61d | ||
|
|
f391c3c899 | ||
|
|
562ea41a64 | ||
|
|
687b1e8887 | ||
|
|
cc506fd094 | ||
|
|
1fe323190a |
@@ -16,6 +16,7 @@ coverage:
|
|||||||
#
|
#
|
||||||
# More info: https://github.com/XRPLF/clio/pull/2066
|
# More info: https://github.com/XRPLF/clio/pull/2066
|
||||||
ignore:
|
ignore:
|
||||||
|
- "benchmarks"
|
||||||
- "tests"
|
- "tests"
|
||||||
- "src/data/cassandra/"
|
- "src/data/cassandra/"
|
||||||
- "src/data/CassandraBackend.hpp"
|
- "src/data/CassandraBackend.hpp"
|
||||||
|
|||||||
21
.github/actions/build_docker_image/action.yml
vendored
21
.github/actions/build_docker_image/action.yml
vendored
@@ -17,10 +17,14 @@ inputs:
|
|||||||
platforms:
|
platforms:
|
||||||
description: Platforms to build the image for (e.g. linux/amd64,linux/arm64)
|
description: Platforms to build the image for (e.g. linux/amd64,linux/arm64)
|
||||||
required: true
|
required: true
|
||||||
|
build_args:
|
||||||
|
description: List of build-time variables
|
||||||
|
required: false
|
||||||
|
|
||||||
dockerhub_repo:
|
dockerhub_repo:
|
||||||
description: DockerHub repository name
|
description: DockerHub repository name
|
||||||
required: false
|
required: false
|
||||||
|
default: ""
|
||||||
dockerhub_description:
|
dockerhub_description:
|
||||||
description: Short description of the image
|
description: Short description of the image
|
||||||
required: false
|
required: false
|
||||||
@@ -30,14 +34,14 @@ runs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
if: ${{ inputs.push_image == 'true' && inputs.dockerhub_repo != '' }}
|
if: ${{ inputs.push_image == 'true' && inputs.dockerhub_repo != '' }}
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
with:
|
with:
|
||||||
username: ${{ env.DOCKERHUB_USER }}
|
username: ${{ env.DOCKERHUB_USER }}
|
||||||
password: ${{ env.DOCKERHUB_PW }}
|
password: ${{ env.DOCKERHUB_PW }}
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
if: ${{ inputs.push_image == 'true' }}
|
if: ${{ inputs.push_image == 'true' }}
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
@@ -48,7 +52,7 @@ runs:
|
|||||||
cache-image: false
|
cache-image: false
|
||||||
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
|
|
||||||
- uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
- uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||||
id: meta
|
id: meta
|
||||||
with:
|
with:
|
||||||
images: ${{ inputs.images }}
|
images: ${{ inputs.images }}
|
||||||
@@ -61,13 +65,4 @@ runs:
|
|||||||
platforms: ${{ inputs.platforms }}
|
platforms: ${{ inputs.platforms }}
|
||||||
push: ${{ inputs.push_image == 'true' }}
|
push: ${{ inputs.push_image == 'true' }}
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
build-args: ${{ inputs.build_args }}
|
||||||
- name: Update DockerHub description
|
|
||||||
if: ${{ inputs.push_image == 'true' && inputs.dockerhub_repo != '' }}
|
|
||||||
uses: peter-evans/dockerhub-description@432a30c9e07499fd01da9f8a49f0faf9e0ca5b77 # v4.0.2
|
|
||||||
with:
|
|
||||||
username: ${{ env.DOCKERHUB_USER }}
|
|
||||||
password: ${{ env.DOCKERHUB_PW }}
|
|
||||||
repository: ${{ inputs.dockerhub_repo }}
|
|
||||||
short-description: ${{ inputs.dockerhub_description }}
|
|
||||||
readme-filepath: ${{ inputs.directory }}/README.md
|
|
||||||
|
|||||||
73
.github/actions/cmake/action.yml
vendored
Normal file
73
.github/actions/cmake/action.yml
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
name: Run CMake
|
||||||
|
description: Run CMake to generate build files
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
build_dir:
|
||||||
|
description: Build directory
|
||||||
|
required: false
|
||||||
|
default: "build"
|
||||||
|
conan_profile:
|
||||||
|
description: Conan profile name
|
||||||
|
required: true
|
||||||
|
build_type:
|
||||||
|
description: Build type for third-party libraries and clio. Could be 'Release', 'Debug'
|
||||||
|
required: true
|
||||||
|
default: "Release"
|
||||||
|
integration_tests:
|
||||||
|
description: Whether to generate target integration tests
|
||||||
|
required: true
|
||||||
|
default: "true"
|
||||||
|
benchmark:
|
||||||
|
description: Whether to generate targets for benchmarks
|
||||||
|
required: true
|
||||||
|
default: "true"
|
||||||
|
code_coverage:
|
||||||
|
description: Whether to enable code coverage
|
||||||
|
required: true
|
||||||
|
default: "false"
|
||||||
|
static:
|
||||||
|
description: Whether Clio is to be statically linked
|
||||||
|
required: true
|
||||||
|
default: "false"
|
||||||
|
time_trace:
|
||||||
|
description: Whether to enable compiler trace reports
|
||||||
|
required: true
|
||||||
|
default: "false"
|
||||||
|
package:
|
||||||
|
description: Whether to generate Debian package
|
||||||
|
required: true
|
||||||
|
default: "false"
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Run cmake
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
BUILD_TYPE: "${{ inputs.build_type }}"
|
||||||
|
SANITIZER_OPTION: |-
|
||||||
|
${{ endsWith(inputs.conan_profile, '.asan') && '-Dsan=address' ||
|
||||||
|
endsWith(inputs.conan_profile, '.tsan') && '-Dsan=thread' ||
|
||||||
|
endsWith(inputs.conan_profile, '.ubsan') && '-Dsan=undefined' ||
|
||||||
|
'' }}
|
||||||
|
INTEGRATION_TESTS: "${{ inputs.integration_tests == 'true' && 'ON' || 'OFF' }}"
|
||||||
|
BENCHMARK: "${{ inputs.benchmark == 'true' && 'ON' || 'OFF' }}"
|
||||||
|
COVERAGE: "${{ inputs.code_coverage == 'true' && 'ON' || 'OFF' }}"
|
||||||
|
STATIC: "${{ inputs.static == 'true' && 'ON' || 'OFF' }}"
|
||||||
|
TIME_TRACE: "${{ inputs.time_trace == 'true' && 'ON' || 'OFF' }}"
|
||||||
|
PACKAGE: "${{ inputs.package == 'true' && 'ON' || 'OFF' }}"
|
||||||
|
run: |
|
||||||
|
cmake \
|
||||||
|
-B ${{inputs.build_dir}} \
|
||||||
|
-S . \
|
||||||
|
-G Ninja \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
||||||
|
"${SANITIZER_OPTION}" \
|
||||||
|
-Dtests=ON \
|
||||||
|
-Dintegration_tests="${INTEGRATION_TESTS}" \
|
||||||
|
-Dbenchmark="${BENCHMARK}" \
|
||||||
|
-Dcoverage="${COVERAGE}" \
|
||||||
|
-Dstatic="${STATIC}" \
|
||||||
|
-Dtime_trace="${TIME_TRACE}" \
|
||||||
|
-Dpackage="${PACKAGE}"
|
||||||
1
.github/actions/code_coverage/action.yml
vendored
1
.github/actions/code_coverage/action.yml
vendored
@@ -15,6 +15,7 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
gcovr \
|
gcovr \
|
||||||
|
-e benchmarks \
|
||||||
-e tests \
|
-e tests \
|
||||||
-e src/data/cassandra \
|
-e src/data/cassandra \
|
||||||
-e src/data/CassandraBackend.hpp \
|
-e src/data/CassandraBackend.hpp \
|
||||||
|
|||||||
38
.github/actions/conan/action.yml
vendored
Normal file
38
.github/actions/conan/action.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
name: Run Conan
|
||||||
|
description: Run conan to install dependencies
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
build_dir:
|
||||||
|
description: Build directory
|
||||||
|
required: false
|
||||||
|
default: "build"
|
||||||
|
conan_profile:
|
||||||
|
description: Conan profile name
|
||||||
|
required: true
|
||||||
|
force_conan_source_build:
|
||||||
|
description: Whether conan should build all dependencies from source
|
||||||
|
required: true
|
||||||
|
default: "false"
|
||||||
|
build_type:
|
||||||
|
description: Build type for third-party libraries and clio. Could be 'Release', 'Debug'
|
||||||
|
required: true
|
||||||
|
default: "Release"
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Create build directory
|
||||||
|
shell: bash
|
||||||
|
run: mkdir -p "${{ inputs.build_dir }}"
|
||||||
|
|
||||||
|
- name: Run conan
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
CONAN_BUILD_OPTION: "${{ inputs.force_conan_source_build == 'true' && '*' || 'missing' }}"
|
||||||
|
run: |
|
||||||
|
conan \
|
||||||
|
install . \
|
||||||
|
-of build \
|
||||||
|
-b "$CONAN_BUILD_OPTION" \
|
||||||
|
-s "build_type=${{ inputs.build_type }}" \
|
||||||
|
--profile:all "${{ inputs.conan_profile }}"
|
||||||
79
.github/actions/generate/action.yml
vendored
79
.github/actions/generate/action.yml
vendored
@@ -1,79 +0,0 @@
|
|||||||
name: Run conan and cmake
|
|
||||||
description: Run conan and cmake
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
conan_profile:
|
|
||||||
description: Conan profile name
|
|
||||||
required: true
|
|
||||||
force_conan_source_build:
|
|
||||||
description: Whether conan should build all dependencies from source
|
|
||||||
required: true
|
|
||||||
default: "false"
|
|
||||||
build_type:
|
|
||||||
description: Build type for third-party libraries and clio. Could be 'Release', 'Debug'
|
|
||||||
required: true
|
|
||||||
default: "Release"
|
|
||||||
build_integration_tests:
|
|
||||||
description: Whether to build integration tests
|
|
||||||
required: true
|
|
||||||
default: "true"
|
|
||||||
code_coverage:
|
|
||||||
description: Whether conan's coverage option should be on or not
|
|
||||||
required: true
|
|
||||||
default: "false"
|
|
||||||
static:
|
|
||||||
description: Whether Clio is to be statically linked
|
|
||||||
required: true
|
|
||||||
default: "false"
|
|
||||||
time_trace:
|
|
||||||
description: Whether to enable compiler trace reports
|
|
||||||
required: true
|
|
||||||
default: "false"
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: composite
|
|
||||||
steps:
|
|
||||||
- name: Create build directory
|
|
||||||
shell: bash
|
|
||||||
run: mkdir -p build
|
|
||||||
|
|
||||||
- name: Run conan
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
CONAN_BUILD_OPTION: "${{ inputs.force_conan_source_build == 'true' && '*' || 'missing' }}"
|
|
||||||
CODE_COVERAGE: "${{ inputs.code_coverage == 'true' && 'True' || 'False' }}"
|
|
||||||
STATIC_OPTION: "${{ inputs.static == 'true' && 'True' || 'False' }}"
|
|
||||||
INTEGRATION_TESTS_OPTION: "${{ inputs.build_integration_tests == 'true' && 'True' || 'False' }}"
|
|
||||||
TIME_TRACE: "${{ inputs.time_trace == 'true' && 'True' || 'False' }}"
|
|
||||||
run: |
|
|
||||||
cd build
|
|
||||||
conan \
|
|
||||||
install .. \
|
|
||||||
-of . \
|
|
||||||
-b "$CONAN_BUILD_OPTION" \
|
|
||||||
-s "build_type=${{ inputs.build_type }}" \
|
|
||||||
-o "&:static=${STATIC_OPTION}" \
|
|
||||||
-o "&:tests=True" \
|
|
||||||
-o "&:integration_tests=${INTEGRATION_TESTS_OPTION}" \
|
|
||||||
-o "&:lint=False" \
|
|
||||||
-o "&:coverage=${CODE_COVERAGE}" \
|
|
||||||
-o "&:time_trace=${TIME_TRACE}" \
|
|
||||||
--profile:all "${{ inputs.conan_profile }}"
|
|
||||||
|
|
||||||
- name: Run cmake
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
BUILD_TYPE: "${{ inputs.build_type }}"
|
|
||||||
SANITIZER_OPTION: |-
|
|
||||||
${{ endsWith(inputs.conan_profile, '.asan') && '-Dsan=address' ||
|
|
||||||
endsWith(inputs.conan_profile, '.tsan') && '-Dsan=thread' ||
|
|
||||||
endsWith(inputs.conan_profile, '.ubsan') && '-Dsan=undefined' ||
|
|
||||||
'' }}
|
|
||||||
run: |
|
|
||||||
cd build
|
|
||||||
cmake \
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
|
|
||||||
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
|
||||||
"${SANITIZER_OPTION}" \
|
|
||||||
.. \
|
|
||||||
-G Ninja
|
|
||||||
77
.github/actions/prepare_runner/action.yml
vendored
77
.github/actions/prepare_runner/action.yml
vendored
@@ -1,77 +0,0 @@
|
|||||||
name: Prepare runner
|
|
||||||
description: Install packages, set environment variables, create directories
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
disable_ccache:
|
|
||||||
description: Whether ccache should be disabled
|
|
||||||
required: true
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: composite
|
|
||||||
steps:
|
|
||||||
- name: Install packages on mac
|
|
||||||
if: ${{ runner.os == 'macOS' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
brew install --quiet \
|
|
||||||
bison \
|
|
||||||
ca-certificates \
|
|
||||||
ccache \
|
|
||||||
clang-build-analyzer \
|
|
||||||
conan \
|
|
||||||
gh \
|
|
||||||
jq \
|
|
||||||
llvm@14 \
|
|
||||||
ninja \
|
|
||||||
pkg-config
|
|
||||||
echo "/opt/homebrew/opt/conan@2/bin" >> $GITHUB_PATH
|
|
||||||
|
|
||||||
- name: Install CMake 3.31.6 on mac
|
|
||||||
if: ${{ runner.os == 'macOS' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
# Uninstall any existing cmake
|
|
||||||
brew uninstall --formula cmake --ignore-dependencies || true
|
|
||||||
|
|
||||||
# Download specific cmake formula
|
|
||||||
FORMULA_URL="https://raw.githubusercontent.com/Homebrew/homebrew-core/b4e46db74e74a8c1650b38b1da222284ce1ec5ce/Formula/c/cmake.rb"
|
|
||||||
FORMULA_EXPECTED_SHA256="c7ec95d86f0657638835441871e77541165e0a2581b53b3dd657cf13ad4228d4"
|
|
||||||
|
|
||||||
mkdir -p /tmp/homebrew-formula
|
|
||||||
curl -s -L "$FORMULA_URL" -o /tmp/homebrew-formula/cmake.rb
|
|
||||||
|
|
||||||
echo "$FORMULA_EXPECTED_SHA256 /tmp/homebrew-formula/cmake.rb" | shasum -a 256 -c
|
|
||||||
|
|
||||||
# Install cmake from the specific formula with force flag
|
|
||||||
brew install --formula --quiet --force /tmp/homebrew-formula/cmake.rb
|
|
||||||
|
|
||||||
- name: Fix git permissions on Linux
|
|
||||||
if: ${{ runner.os == 'Linux' }}
|
|
||||||
shell: bash
|
|
||||||
run: git config --global --add safe.directory "$PWD"
|
|
||||||
|
|
||||||
- name: Set env variables for macOS
|
|
||||||
if: ${{ runner.os == 'macOS' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "CCACHE_DIR=${{ github.workspace }}/.ccache" >> $GITHUB_ENV
|
|
||||||
echo "CONAN_HOME=${{ github.workspace }}/.conan2" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Set env variables for Linux
|
|
||||||
if: ${{ runner.os == 'Linux' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "CCACHE_DIR=/root/.ccache" >> $GITHUB_ENV
|
|
||||||
echo "CONAN_HOME=/root/.conan2" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Set CCACHE_DISABLE=1
|
|
||||||
if: ${{ inputs.disable_ccache == 'true' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "CCACHE_DISABLE=1" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Create directories
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
mkdir -p "$CCACHE_DIR"
|
|
||||||
mkdir -p "$CONAN_HOME"
|
|
||||||
30
.github/dependabot.yml
vendored
30
.github/dependabot.yml
vendored
@@ -39,6 +39,19 @@ updates:
|
|||||||
prefix: "ci: [DEPENDABOT] "
|
prefix: "ci: [DEPENDABOT] "
|
||||||
target-branch: develop
|
target-branch: develop
|
||||||
|
|
||||||
|
- package-ecosystem: github-actions
|
||||||
|
directory: .github/actions/cmake/
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
day: monday
|
||||||
|
time: "04:00"
|
||||||
|
timezone: Etc/GMT
|
||||||
|
reviewers:
|
||||||
|
- XRPLF/clio-dev-team
|
||||||
|
commit-message:
|
||||||
|
prefix: "ci: [DEPENDABOT] "
|
||||||
|
target-branch: develop
|
||||||
|
|
||||||
- package-ecosystem: github-actions
|
- package-ecosystem: github-actions
|
||||||
directory: .github/actions/code_coverage/
|
directory: .github/actions/code_coverage/
|
||||||
schedule:
|
schedule:
|
||||||
@@ -53,7 +66,7 @@ updates:
|
|||||||
target-branch: develop
|
target-branch: develop
|
||||||
|
|
||||||
- package-ecosystem: github-actions
|
- package-ecosystem: github-actions
|
||||||
directory: .github/actions/create_issue/
|
directory: .github/actions/conan/
|
||||||
schedule:
|
schedule:
|
||||||
interval: weekly
|
interval: weekly
|
||||||
day: monday
|
day: monday
|
||||||
@@ -66,7 +79,7 @@ updates:
|
|||||||
target-branch: develop
|
target-branch: develop
|
||||||
|
|
||||||
- package-ecosystem: github-actions
|
- package-ecosystem: github-actions
|
||||||
directory: .github/actions/generate/
|
directory: .github/actions/create_issue/
|
||||||
schedule:
|
schedule:
|
||||||
interval: weekly
|
interval: weekly
|
||||||
day: monday
|
day: monday
|
||||||
@@ -104,19 +117,6 @@ updates:
|
|||||||
prefix: "ci: [DEPENDABOT] "
|
prefix: "ci: [DEPENDABOT] "
|
||||||
target-branch: develop
|
target-branch: develop
|
||||||
|
|
||||||
- package-ecosystem: github-actions
|
|
||||||
directory: .github/actions/prepare_runner/
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
day: monday
|
|
||||||
time: "04:00"
|
|
||||||
timezone: Etc/GMT
|
|
||||||
reviewers:
|
|
||||||
- XRPLF/clio-dev-team
|
|
||||||
commit-message:
|
|
||||||
prefix: "ci: [DEPENDABOT] "
|
|
||||||
target-branch: develop
|
|
||||||
|
|
||||||
- package-ecosystem: github-actions
|
- package-ecosystem: github-actions
|
||||||
directory: .github/actions/restore_cache/
|
directory: .github/actions/restore_cache/
|
||||||
schedule:
|
schedule:
|
||||||
|
|||||||
@@ -4,5 +4,8 @@ build_type=Release
|
|||||||
compiler=apple-clang
|
compiler=apple-clang
|
||||||
compiler.cppstd=20
|
compiler.cppstd=20
|
||||||
compiler.libcxx=libc++
|
compiler.libcxx=libc++
|
||||||
compiler.version=16
|
compiler.version=17
|
||||||
os=Macos
|
os=Macos
|
||||||
|
|
||||||
|
[conf]
|
||||||
|
grpc/1.50.1:tools.build:cxxflags+=["-Wno-missing-template-arg-list-after-template-kw"]
|
||||||
5
.github/scripts/conan/generate_matrix.py
vendored
5
.github/scripts/conan/generate_matrix.py
vendored
@@ -3,7 +3,7 @@ import itertools
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
LINUX_OS = ["heavy", "heavy-arm64"]
|
LINUX_OS = ["heavy", "heavy-arm64"]
|
||||||
LINUX_CONTAINERS = ['{ "image": "ghcr.io/xrplf/clio-ci:latest" }']
|
LINUX_CONTAINERS = ['{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }']
|
||||||
LINUX_COMPILERS = ["gcc", "clang"]
|
LINUX_COMPILERS = ["gcc", "clang"]
|
||||||
|
|
||||||
MACOS_OS = ["macos15"]
|
MACOS_OS = ["macos15"]
|
||||||
@@ -22,9 +22,6 @@ def generate_matrix():
|
|||||||
itertools.product(MACOS_OS, MACOS_CONTAINERS, MACOS_COMPILERS),
|
itertools.product(MACOS_OS, MACOS_CONTAINERS, MACOS_COMPILERS),
|
||||||
):
|
):
|
||||||
for sanitizer_ext, build_type in itertools.product(SANITIZER_EXT, BUILD_TYPES):
|
for sanitizer_ext, build_type in itertools.product(SANITIZER_EXT, BUILD_TYPES):
|
||||||
# libbacktrace doesn't build on arm64 with gcc.tsan
|
|
||||||
if os == "heavy-arm64" and compiler == "gcc" and sanitizer_ext == ".tsan":
|
|
||||||
continue
|
|
||||||
configurations.append(
|
configurations.append(
|
||||||
{
|
{
|
||||||
"os": os,
|
"os": os,
|
||||||
|
|||||||
9
.github/scripts/conan/init.sh
vendored
9
.github/scripts/conan/init.sh
vendored
@@ -8,7 +8,12 @@ REPO_DIR="$(cd "$CURRENT_DIR/../../../" && pwd)"
|
|||||||
CONAN_DIR="${CONAN_HOME:-$HOME/.conan2}"
|
CONAN_DIR="${CONAN_HOME:-$HOME/.conan2}"
|
||||||
PROFILES_DIR="$CONAN_DIR/profiles"
|
PROFILES_DIR="$CONAN_DIR/profiles"
|
||||||
|
|
||||||
APPLE_CLANG_PROFILE="$CURRENT_DIR/apple-clang.profile"
|
# When developers' compilers are updated, these profiles might be different
|
||||||
|
if [[ -z "$CI" ]]; then
|
||||||
|
APPLE_CLANG_PROFILE="$CURRENT_DIR/apple-clang-17.profile"
|
||||||
|
else
|
||||||
|
APPLE_CLANG_PROFILE="$CURRENT_DIR/apple-clang-17.profile"
|
||||||
|
fi
|
||||||
|
|
||||||
GCC_PROFILE="$REPO_DIR/docker/ci/conan/gcc.profile"
|
GCC_PROFILE="$REPO_DIR/docker/ci/conan/gcc.profile"
|
||||||
CLANG_PROFILE="$REPO_DIR/docker/ci/conan/clang.profile"
|
CLANG_PROFILE="$REPO_DIR/docker/ci/conan/clang.profile"
|
||||||
@@ -17,7 +22,7 @@ SANITIZER_TEMPLATE_FILE="$REPO_DIR/docker/ci/conan/sanitizer_template.profile"
|
|||||||
|
|
||||||
rm -rf "$CONAN_DIR"
|
rm -rf "$CONAN_DIR"
|
||||||
|
|
||||||
conan remote add --index 0 ripple http://18.143.149.228:8081/artifactory/api/conan/dev
|
conan remote add --index 0 xrplf https://conan.ripplex.io
|
||||||
|
|
||||||
cp "$REPO_DIR/docker/ci/conan/global.conf" "$CONAN_DIR/global.conf"
|
cp "$REPO_DIR/docker/ci/conan/global.conf" "$CONAN_DIR/global.conf"
|
||||||
|
|
||||||
|
|||||||
43
.github/workflows/build.yml
vendored
43
.github/workflows/build.yml
vendored
@@ -2,9 +2,9 @@ name: Build
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [master, release/*, develop]
|
branches: [release/*, develop]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [master, release/*, develop]
|
branches: [release/*, develop]
|
||||||
paths:
|
paths:
|
||||||
- .github/workflows/build.yml
|
- .github/workflows/build.yml
|
||||||
|
|
||||||
@@ -28,8 +28,9 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
# Only cancel in-progress jobs or runs for the current workflow - matches against branch & tags
|
# Develop branch: Each run gets unique group (using run_number) for parallel execution
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
# Other branches: Shared group with cancel-in-progress to stop old runs when new commits are pushed
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref == 'refs/heads/develop' && github.run_number || 'branch' }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -42,7 +43,10 @@ jobs:
|
|||||||
os: [heavy]
|
os: [heavy]
|
||||||
conan_profile: [gcc, clang]
|
conan_profile: [gcc, clang]
|
||||||
build_type: [Release, Debug]
|
build_type: [Release, Debug]
|
||||||
container: ['{ "image": "ghcr.io/xrplf/clio-ci:latest" }']
|
container:
|
||||||
|
[
|
||||||
|
'{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }',
|
||||||
|
]
|
||||||
static: [true]
|
static: [true]
|
||||||
|
|
||||||
include:
|
include:
|
||||||
@@ -58,6 +62,8 @@ jobs:
|
|||||||
container: ${{ matrix.container }}
|
container: ${{ matrix.container }}
|
||||||
conan_profile: ${{ matrix.conan_profile }}
|
conan_profile: ${{ matrix.conan_profile }}
|
||||||
build_type: ${{ matrix.build_type }}
|
build_type: ${{ matrix.build_type }}
|
||||||
|
download_ccache: true
|
||||||
|
upload_ccache: true
|
||||||
static: ${{ matrix.static }}
|
static: ${{ matrix.static }}
|
||||||
run_unit_tests: true
|
run_unit_tests: true
|
||||||
run_integration_tests: false
|
run_integration_tests: false
|
||||||
@@ -69,10 +75,11 @@ jobs:
|
|||||||
uses: ./.github/workflows/build_impl.yml
|
uses: ./.github/workflows/build_impl.yml
|
||||||
with:
|
with:
|
||||||
runs_on: heavy
|
runs_on: heavy
|
||||||
container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
|
container: '{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }'
|
||||||
conan_profile: gcc
|
conan_profile: gcc
|
||||||
build_type: Debug
|
build_type: Debug
|
||||||
disable_cache: false
|
download_ccache: true
|
||||||
|
upload_ccache: false
|
||||||
code_coverage: true
|
code_coverage: true
|
||||||
static: true
|
static: true
|
||||||
upload_clio_server: false
|
upload_clio_server: false
|
||||||
@@ -81,17 +88,35 @@ jobs:
|
|||||||
secrets:
|
secrets:
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
|
package:
|
||||||
|
name: Build packages
|
||||||
|
|
||||||
|
uses: ./.github/workflows/build_impl.yml
|
||||||
|
with:
|
||||||
|
runs_on: heavy
|
||||||
|
container: '{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }'
|
||||||
|
conan_profile: gcc
|
||||||
|
build_type: Release
|
||||||
|
download_ccache: true
|
||||||
|
upload_ccache: false
|
||||||
|
code_coverage: false
|
||||||
|
static: true
|
||||||
|
upload_clio_server: false
|
||||||
|
package: true
|
||||||
|
targets: package
|
||||||
|
analyze_build_time: false
|
||||||
|
|
||||||
check_config:
|
check_config:
|
||||||
name: Check Config Description
|
name: Check Config Description
|
||||||
needs: build-and-test
|
needs: build-and-test
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/xrplf/clio-ci:latest
|
image: ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: clio_server_Linux_Release_gcc
|
name: clio_server_Linux_Release_gcc
|
||||||
|
|
||||||
|
|||||||
27
.github/workflows/build_and_test.yml
vendored
27
.github/workflows/build_and_test.yml
vendored
@@ -23,8 +23,14 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
disable_cache:
|
download_ccache:
|
||||||
description: Whether ccache should be disabled
|
description: Whether to download ccache from the cache
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
|
||||||
|
upload_ccache:
|
||||||
|
description: Whether to upload ccache to the cache
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
@@ -57,6 +63,18 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
default: all
|
default: all
|
||||||
|
|
||||||
|
expected_version:
|
||||||
|
description: Expected version of the clio_server binary
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ""
|
||||||
|
|
||||||
|
package:
|
||||||
|
description: Whether to generate Debian package
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
uses: ./.github/workflows/build_impl.yml
|
uses: ./.github/workflows/build_impl.yml
|
||||||
@@ -65,12 +83,15 @@ jobs:
|
|||||||
container: ${{ inputs.container }}
|
container: ${{ inputs.container }}
|
||||||
conan_profile: ${{ inputs.conan_profile }}
|
conan_profile: ${{ inputs.conan_profile }}
|
||||||
build_type: ${{ inputs.build_type }}
|
build_type: ${{ inputs.build_type }}
|
||||||
disable_cache: ${{ inputs.disable_cache }}
|
download_ccache: ${{ inputs.download_ccache }}
|
||||||
|
upload_ccache: ${{ inputs.upload_ccache }}
|
||||||
code_coverage: false
|
code_coverage: false
|
||||||
static: ${{ inputs.static }}
|
static: ${{ inputs.static }}
|
||||||
upload_clio_server: ${{ inputs.upload_clio_server }}
|
upload_clio_server: ${{ inputs.upload_clio_server }}
|
||||||
targets: ${{ inputs.targets }}
|
targets: ${{ inputs.targets }}
|
||||||
analyze_build_time: false
|
analyze_build_time: false
|
||||||
|
expected_version: ${{ inputs.expected_version }}
|
||||||
|
package: ${{ inputs.package }}
|
||||||
|
|
||||||
test:
|
test:
|
||||||
needs: build
|
needs: build
|
||||||
|
|||||||
16
.github/workflows/build_clio_docker_image.yml
vendored
16
.github/workflows/build_clio_docker_image.yml
vendored
@@ -48,7 +48,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Download Clio binary from artifact
|
- name: Download Clio binary from artifact
|
||||||
if: ${{ inputs.artifact_name != null }}
|
if: ${{ inputs.artifact_name != null }}
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: ${{ inputs.artifact_name }}
|
name: ${{ inputs.artifact_name }}
|
||||||
path: ./docker/clio/artifact/
|
path: ./docker/clio/artifact/
|
||||||
@@ -73,7 +73,8 @@ jobs:
|
|||||||
elif [[ $artifact == *.tar.gz ]]; then
|
elif [[ $artifact == *.tar.gz ]]; then
|
||||||
tar -xvf $artifact
|
tar -xvf $artifact
|
||||||
fi
|
fi
|
||||||
mv clio_server ../
|
chmod +x ./clio_server
|
||||||
|
mv ./clio_server ../
|
||||||
cd ../
|
cd ../
|
||||||
rm -rf ./artifact
|
rm -rf ./artifact
|
||||||
|
|
||||||
@@ -82,6 +83,11 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: strip ./docker/clio/clio_server
|
run: strip ./docker/clio/clio_server
|
||||||
|
|
||||||
|
- name: Set GHCR_REPO
|
||||||
|
id: set-ghcr-repo
|
||||||
|
run: |
|
||||||
|
echo "GHCR_REPO=$(echo ghcr.io/${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> ${GITHUB_OUTPUT}
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
uses: ./.github/actions/build_docker_image
|
uses: ./.github/actions/build_docker_image
|
||||||
env:
|
env:
|
||||||
@@ -90,11 +96,11 @@ jobs:
|
|||||||
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
ghcr.io/xrplf/clio
|
ghcr.io/${{ steps.set-ghcr-repo.outputs.GHCR_REPO }}/clio
|
||||||
rippleci/clio
|
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio' || '' }}
|
||||||
push_image: ${{ inputs.publish_image }}
|
push_image: ${{ inputs.publish_image }}
|
||||||
directory: docker/clio
|
directory: docker/clio
|
||||||
tags: ${{ inputs.tags }}
|
tags: ${{ inputs.tags }}
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
dockerhub_repo: rippleci/clio
|
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio' || '' }}
|
||||||
dockerhub_description: Clio is an XRP Ledger API server.
|
dockerhub_description: Clio is an XRP Ledger API server.
|
||||||
|
|||||||
79
.github/workflows/build_impl.yml
vendored
79
.github/workflows/build_impl.yml
vendored
@@ -23,10 +23,17 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
disable_cache:
|
download_ccache:
|
||||||
description: Whether ccache should be disabled
|
description: Whether to download ccache from the cache
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
default: true
|
||||||
|
|
||||||
|
upload_ccache:
|
||||||
|
description: Whether to upload ccache to the cache
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
code_coverage:
|
code_coverage:
|
||||||
description: Whether to enable code coverage
|
description: Whether to enable code coverage
|
||||||
@@ -53,6 +60,17 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
|
expected_version:
|
||||||
|
description: Expected version of the clio_server binary
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ""
|
||||||
|
|
||||||
|
package:
|
||||||
|
description: Whether to generate Debian package
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
secrets:
|
secrets:
|
||||||
CODECOV_TOKEN:
|
CODECOV_TOKEN:
|
||||||
required: false
|
required: false
|
||||||
@@ -64,26 +82,30 @@ jobs:
|
|||||||
container: ${{ inputs.container != '' && fromJson(inputs.container) || null }}
|
container: ${{ inputs.container != '' && fromJson(inputs.container) || null }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clean workdir
|
- name: Cleanup workspace
|
||||||
if: ${{ runner.os == 'macOS' }}
|
if: ${{ runner.os == 'macOS' }}
|
||||||
uses: kuznetsss/workspace-cleanup@80b9863b45562c148927c3d53621ef354e5ae7ce # v1.0
|
uses: XRPLF/actions/.github/actions/cleanup-workspace@ea9970b7c211b18f4c8bcdb28c29f5711752029f
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
# We need to fetch tags to have correct version in the release
|
||||||
|
# The workaround is based on https://github.com/actions/checkout/issues/1467
|
||||||
|
fetch-tags: true
|
||||||
|
ref: ${{ github.ref }}
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: ./.github/actions/prepare_runner
|
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f
|
||||||
with:
|
with:
|
||||||
disable_ccache: ${{ inputs.disable_cache }}
|
disable_ccache: ${{ !inputs.download_ccache }}
|
||||||
|
|
||||||
- name: Setup conan on macOS
|
- name: Setup conan on macOS
|
||||||
if: runner.os == 'macOS'
|
if: ${{ runner.os == 'macOS' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ./.github/scripts/conan/init.sh
|
run: ./.github/scripts/conan/init.sh
|
||||||
|
|
||||||
- name: Restore cache
|
- name: Restore cache
|
||||||
if: ${{ !inputs.disable_cache }}
|
if: ${{ inputs.download_ccache }}
|
||||||
uses: ./.github/actions/restore_cache
|
uses: ./.github/actions/restore_cache
|
||||||
id: restore_cache
|
id: restore_cache
|
||||||
with:
|
with:
|
||||||
@@ -92,14 +114,21 @@ jobs:
|
|||||||
build_type: ${{ inputs.build_type }}
|
build_type: ${{ inputs.build_type }}
|
||||||
code_coverage: ${{ inputs.code_coverage }}
|
code_coverage: ${{ inputs.code_coverage }}
|
||||||
|
|
||||||
- name: Run conan and cmake
|
- name: Run conan
|
||||||
uses: ./.github/actions/generate
|
uses: ./.github/actions/conan
|
||||||
|
with:
|
||||||
|
conan_profile: ${{ inputs.conan_profile }}
|
||||||
|
build_type: ${{ inputs.build_type }}
|
||||||
|
|
||||||
|
- name: Run CMake
|
||||||
|
uses: ./.github/actions/cmake
|
||||||
with:
|
with:
|
||||||
conan_profile: ${{ inputs.conan_profile }}
|
conan_profile: ${{ inputs.conan_profile }}
|
||||||
build_type: ${{ inputs.build_type }}
|
build_type: ${{ inputs.build_type }}
|
||||||
code_coverage: ${{ inputs.code_coverage }}
|
code_coverage: ${{ inputs.code_coverage }}
|
||||||
static: ${{ inputs.static }}
|
static: ${{ inputs.static }}
|
||||||
time_trace: ${{ inputs.analyze_build_time }}
|
time_trace: ${{ inputs.analyze_build_time }}
|
||||||
|
package: ${{ inputs.package }}
|
||||||
|
|
||||||
- name: Build Clio
|
- name: Build Clio
|
||||||
uses: ./.github/actions/build_clio
|
uses: ./.github/actions/build_clio
|
||||||
@@ -122,7 +151,7 @@ jobs:
|
|||||||
path: build_time_report.txt
|
path: build_time_report.txt
|
||||||
|
|
||||||
- name: Show ccache's statistics
|
- name: Show ccache's statistics
|
||||||
if: ${{ !inputs.disable_cache }}
|
if: ${{ inputs.download_ccache }}
|
||||||
shell: bash
|
shell: bash
|
||||||
id: ccache_stats
|
id: ccache_stats
|
||||||
run: |
|
run: |
|
||||||
@@ -140,28 +169,35 @@ jobs:
|
|||||||
run: strip build/clio_integration_tests
|
run: strip build/clio_integration_tests
|
||||||
|
|
||||||
- name: Upload clio_server
|
- name: Upload clio_server
|
||||||
if: inputs.upload_clio_server && !inputs.code_coverage && !inputs.analyze_build_time
|
if: ${{ inputs.upload_clio_server && !inputs.code_coverage && !inputs.analyze_build_time }}
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: clio_server_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
name: clio_server_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
||||||
path: build/clio_server
|
path: build/clio_server
|
||||||
|
|
||||||
- name: Upload clio_tests
|
- name: Upload clio_tests
|
||||||
if: ${{ !inputs.code_coverage && !inputs.analyze_build_time }}
|
if: ${{ !inputs.code_coverage && !inputs.analyze_build_time && !inputs.package }}
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
||||||
path: build/clio_tests
|
path: build/clio_tests
|
||||||
|
|
||||||
- name: Upload clio_integration_tests
|
- name: Upload clio_integration_tests
|
||||||
if: ${{ !inputs.code_coverage && !inputs.analyze_build_time }}
|
if: ${{ !inputs.code_coverage && !inputs.analyze_build_time && !inputs.package }}
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
||||||
path: build/clio_integration_tests
|
path: build/clio_integration_tests
|
||||||
|
|
||||||
|
- name: Upload Clio Linux package
|
||||||
|
if: ${{ inputs.package }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: clio_deb_package_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
||||||
|
path: build/*.deb
|
||||||
|
|
||||||
- name: Save cache
|
- name: Save cache
|
||||||
if: ${{ !inputs.disable_cache && github.ref == 'refs/heads/develop' }}
|
if: ${{ inputs.upload_ccache && github.ref == 'refs/heads/develop' }}
|
||||||
uses: ./.github/actions/save_cache
|
uses: ./.github/actions/save_cache
|
||||||
with:
|
with:
|
||||||
conan_profile: ${{ inputs.conan_profile }}
|
conan_profile: ${{ inputs.conan_profile }}
|
||||||
@@ -174,7 +210,6 @@ jobs:
|
|||||||
|
|
||||||
# This is run as part of the build job, because it requires the following:
|
# This is run as part of the build job, because it requires the following:
|
||||||
# - source code
|
# - source code
|
||||||
# - generated source code (Build.cpp)
|
|
||||||
# - conan packages
|
# - conan packages
|
||||||
# - .gcno files in build directory
|
# - .gcno files in build directory
|
||||||
#
|
#
|
||||||
@@ -183,6 +218,18 @@ jobs:
|
|||||||
if: ${{ inputs.code_coverage }}
|
if: ${{ inputs.code_coverage }}
|
||||||
uses: ./.github/actions/code_coverage
|
uses: ./.github/actions/code_coverage
|
||||||
|
|
||||||
|
- name: Verify expected version
|
||||||
|
if: ${{ inputs.expected_version != '' }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
EXPECTED_VERSION="clio-${{ inputs.expected_version }}"
|
||||||
|
actual_version=$(./build/clio_server --version)
|
||||||
|
if [[ "$actual_version" != "$EXPECTED_VERSION" ]]; then
|
||||||
|
echo "Expected version '$EXPECTED_VERSION', but got '$actual_version'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# `codecov/codecov-action` will rerun `gcov` if it's available and build directory is present
|
# `codecov/codecov-action` will rerun `gcov` if it's available and build directory is present
|
||||||
# To prevent this from happening, we run this action in a separate workflow
|
# To prevent this from happening, we run this action in a separate workflow
|
||||||
#
|
#
|
||||||
|
|||||||
30
.github/workflows/check_libxrpl.yml
vendored
30
.github/workflows/check_libxrpl.yml
vendored
@@ -17,31 +17,36 @@ jobs:
|
|||||||
name: Build Clio / `libXRPL ${{ github.event.client_payload.version }}`
|
name: Build Clio / `libXRPL ${{ github.event.client_payload.version }}`
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/xrplf/clio-ci:latest
|
image: ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Prepare runner
|
||||||
|
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f
|
||||||
|
with:
|
||||||
|
disable_ccache: true
|
||||||
|
|
||||||
- name: Update libXRPL version requirement
|
- name: Update libXRPL version requirement
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sed -i.bak -E "s|'xrpl/[a-zA-Z0-9\\.\\-]+'|'xrpl/${{ github.event.client_payload.version }}'|g" conanfile.py
|
sed -i.bak -E "s|'xrpl/[a-zA-Z0-9\\.\\-]+'|'xrpl/${{ github.event.client_payload.conan_ref }}'|g" conanfile.py
|
||||||
rm -f conanfile.py.bak
|
rm -f conanfile.py.bak
|
||||||
|
|
||||||
- name: Update conan lockfile
|
- name: Update conan lockfile
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
conan lock create . -o '&:tests=True' -o '&:benchmark=True'
|
conan lock create . --profile:all ${{ env.CONAN_PROFILE }}
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Run conan
|
||||||
uses: ./.github/actions/prepare_runner
|
uses: ./.github/actions/conan
|
||||||
with:
|
with:
|
||||||
disable_ccache: true
|
conan_profile: ${{ env.CONAN_PROFILE }}
|
||||||
|
|
||||||
- name: Run conan and cmake
|
- name: Run CMake
|
||||||
uses: ./.github/actions/generate
|
uses: ./.github/actions/cmake
|
||||||
with:
|
with:
|
||||||
conan_profile: ${{ env.CONAN_PROFILE }}
|
conan_profile: ${{ env.CONAN_PROFILE }}
|
||||||
|
|
||||||
@@ -62,10 +67,10 @@ jobs:
|
|||||||
needs: build
|
needs: build
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/xrplf/clio-ci:latest
|
image: ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: clio_tests_check_libxrpl
|
name: clio_tests_check_libxrpl
|
||||||
|
|
||||||
@@ -95,6 +100,7 @@ jobs:
|
|||||||
labels: "compatibility,bug"
|
labels: "compatibility,bug"
|
||||||
title: "Proposed libXRPL check failed"
|
title: "Proposed libXRPL check failed"
|
||||||
body: >
|
body: >
|
||||||
Clio build or tests failed against `libXRPL ${{ github.event.client_payload.version }}`.
|
Clio build or tests failed against `libXRPL ${{ github.event.client_payload.conan_ref }}`.
|
||||||
|
|
||||||
Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
|
PR: ${{ github.event.client_payload.pr_url }}
|
||||||
|
Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
|
||||||
|
|||||||
2
.github/workflows/check_pr_title.yml
vendored
2
.github/workflows/check_pr_title.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: ytanikin/pr-conventional-commits@8267db1bacc237419f9ed0228bb9d94e94271a1d # v1.4.1
|
- uses: ytanikin/pr-conventional-commits@b72758283dcbee706975950e96bc4bf323a8d8c0 # v1.4.2
|
||||||
with:
|
with:
|
||||||
task_types: '["build","feat","fix","docs","test","ci","style","refactor","perf","chore"]'
|
task_types: '["build","feat","fix","docs","test","ci","style","refactor","perf","chore"]'
|
||||||
add_label: false
|
add_label: false
|
||||||
|
|||||||
16
.github/workflows/clang-tidy.yml
vendored
16
.github/workflows/clang-tidy.yml
vendored
@@ -1,6 +1,8 @@
|
|||||||
name: Clang-tidy check
|
name: Clang-tidy check
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
push:
|
||||||
|
branches: [develop]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 9 * * 1-5"
|
- cron: "0 9 * * 1-5"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -22,9 +24,10 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
clang_tidy:
|
clang_tidy:
|
||||||
|
if: github.event_name != 'push' || contains(github.event.head_commit.message, 'clang-tidy auto fixes')
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/xrplf/clio-ci:latest
|
image: ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@@ -37,7 +40,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: ./.github/actions/prepare_runner
|
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f
|
||||||
with:
|
with:
|
||||||
disable_ccache: true
|
disable_ccache: true
|
||||||
|
|
||||||
@@ -48,8 +51,13 @@ jobs:
|
|||||||
conan_profile: ${{ env.CONAN_PROFILE }}
|
conan_profile: ${{ env.CONAN_PROFILE }}
|
||||||
ccache_dir: ${{ env.CCACHE_DIR }}
|
ccache_dir: ${{ env.CCACHE_DIR }}
|
||||||
|
|
||||||
- name: Run conan and cmake
|
- name: Run conan
|
||||||
uses: ./.github/actions/generate
|
uses: ./.github/actions/conan
|
||||||
|
with:
|
||||||
|
conan_profile: ${{ env.CONAN_PROFILE }}
|
||||||
|
|
||||||
|
- name: Run CMake
|
||||||
|
uses: ./.github/actions/cmake
|
||||||
with:
|
with:
|
||||||
conan_profile: ${{ env.CONAN_PROFILE }}
|
conan_profile: ${{ env.CONAN_PROFILE }}
|
||||||
|
|
||||||
|
|||||||
30
.github/workflows/clang-tidy_on_fix_merged.yml
vendored
30
.github/workflows/clang-tidy_on_fix_merged.yml
vendored
@@ -1,30 +0,0 @@
|
|||||||
name: Restart clang-tidy workflow
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [develop]
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
restart_clang_tidy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
actions: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Check last commit matches clang-tidy auto fixes
|
|
||||||
id: check
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
passed=$(if [[ "$(git log -1 --pretty=format:%s | grep 'style: clang-tidy auto fixes')" ]]; then echo 'true' ; else echo 'false' ; fi)
|
|
||||||
echo "passed=\"$passed\"" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Run clang-tidy workflow
|
|
||||||
if: ${{ contains(steps.check.outputs.passed, 'true') }}
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
GH_REPO: ${{ github.repository }}
|
|
||||||
run: gh workflow run clang-tidy.yml
|
|
||||||
9
.github/workflows/docs.yml
vendored
9
.github/workflows/docs.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/xrplf/clio-ci:latest
|
image: ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -22,6 +22,11 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
lfs: true
|
lfs: true
|
||||||
|
|
||||||
|
- name: Prepare runner
|
||||||
|
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f
|
||||||
|
with:
|
||||||
|
disable_ccache: true
|
||||||
|
|
||||||
- name: Create build directory
|
- name: Create build directory
|
||||||
run: mkdir build_docs
|
run: mkdir build_docs
|
||||||
|
|
||||||
@@ -37,7 +42,7 @@ jobs:
|
|||||||
uses: actions/configure-pages@v5
|
uses: actions/configure-pages@v5
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v3
|
uses: actions/upload-pages-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: build_docs/html
|
path: build_docs/html
|
||||||
name: docs-develop
|
name: docs-develop
|
||||||
|
|||||||
17
.github/workflows/nightly.yml
vendored
17
.github/workflows/nightly.yml
vendored
@@ -39,17 +39,17 @@ jobs:
|
|||||||
conan_profile: gcc
|
conan_profile: gcc
|
||||||
build_type: Release
|
build_type: Release
|
||||||
static: true
|
static: true
|
||||||
container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
|
container: '{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }'
|
||||||
- os: heavy
|
- os: heavy
|
||||||
conan_profile: gcc
|
conan_profile: gcc
|
||||||
build_type: Debug
|
build_type: Debug
|
||||||
static: true
|
static: true
|
||||||
container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
|
container: '{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }'
|
||||||
- os: heavy
|
- os: heavy
|
||||||
conan_profile: gcc.ubsan
|
conan_profile: gcc.ubsan
|
||||||
build_type: Release
|
build_type: Release
|
||||||
static: false
|
static: false
|
||||||
container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
|
container: '{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }'
|
||||||
|
|
||||||
uses: ./.github/workflows/build_and_test.yml
|
uses: ./.github/workflows/build_and_test.yml
|
||||||
with:
|
with:
|
||||||
@@ -61,7 +61,8 @@ jobs:
|
|||||||
run_unit_tests: true
|
run_unit_tests: true
|
||||||
run_integration_tests: true
|
run_integration_tests: true
|
||||||
upload_clio_server: true
|
upload_clio_server: true
|
||||||
disable_cache: true
|
download_ccache: false
|
||||||
|
upload_ccache: false
|
||||||
|
|
||||||
analyze_build_time:
|
analyze_build_time:
|
||||||
name: Analyze Build Time
|
name: Analyze Build Time
|
||||||
@@ -72,7 +73,7 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- os: heavy
|
- os: heavy
|
||||||
conan_profile: clang
|
conan_profile: clang
|
||||||
container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
|
container: '{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }'
|
||||||
static: true
|
static: true
|
||||||
- os: macos15
|
- os: macos15
|
||||||
conan_profile: apple-clang
|
conan_profile: apple-clang
|
||||||
@@ -84,7 +85,8 @@ jobs:
|
|||||||
container: ${{ matrix.container }}
|
container: ${{ matrix.container }}
|
||||||
conan_profile: ${{ matrix.conan_profile }}
|
conan_profile: ${{ matrix.conan_profile }}
|
||||||
build_type: Release
|
build_type: Release
|
||||||
disable_cache: true
|
download_ccache: false
|
||||||
|
upload_ccache: false
|
||||||
code_coverage: false
|
code_coverage: false
|
||||||
static: ${{ matrix.static }}
|
static: ${{ matrix.static }}
|
||||||
upload_clio_server: false
|
upload_clio_server: false
|
||||||
@@ -96,11 +98,10 @@ jobs:
|
|||||||
uses: ./.github/workflows/release_impl.yml
|
uses: ./.github/workflows/release_impl.yml
|
||||||
with:
|
with:
|
||||||
overwrite_release: true
|
overwrite_release: true
|
||||||
|
prerelease: true
|
||||||
title: "Clio development (nightly) build"
|
title: "Clio development (nightly) build"
|
||||||
version: nightly
|
version: nightly
|
||||||
header: >
|
header: >
|
||||||
# Release notes
|
|
||||||
|
|
||||||
> **Note:** Please remember that this is a development release and it is not recommended for production use.
|
> **Note:** Please remember that this is a development release and it is not recommended for production use.
|
||||||
|
|
||||||
Changelog (including previous releases): <https://github.com/XRPLF/clio/commits/nightly>
|
Changelog (including previous releases): <https://github.com/XRPLF/clio/commits/nightly>
|
||||||
|
|||||||
49
.github/workflows/pre-commit-autoupdate.yml
vendored
49
.github/workflows/pre-commit-autoupdate.yml
vendored
@@ -4,44 +4,19 @@ on:
|
|||||||
# every first day of the month
|
# every first day of the month
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 1 * *"
|
- cron: "0 0 1 * *"
|
||||||
# on demand
|
pull_request:
|
||||||
|
branches: [release/*, develop]
|
||||||
|
paths:
|
||||||
|
- ".pre-commit-config.yaml"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
auto-update:
|
auto-update:
|
||||||
runs-on: ubuntu-latest
|
uses: XRPLF/actions/.github/workflows/pre-commit-autoupdate.yml@afbcbdafbe0ce5439492fb87eda6441371086386
|
||||||
|
with:
|
||||||
permissions:
|
sign_commit: true
|
||||||
contents: write
|
committer: "Clio CI <skuznetsov@ripple.com>"
|
||||||
pull-requests: write
|
reviewers: "godexsoft,kuznetsss,PeterChen13579,mathbunnyru"
|
||||||
|
secrets:
|
||||||
steps:
|
GPG_PRIVATE_KEY: ${{ secrets.ACTIONS_GPG_PRIVATE_KEY }}
|
||||||
- uses: actions/checkout@v4
|
GPG_PASSPHRASE: ${{ secrets.ACTIONS_GPG_PASSPHRASE }}
|
||||||
|
|
||||||
- uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: 3.x
|
|
||||||
|
|
||||||
- run: pip install pre-commit
|
|
||||||
- run: pre-commit autoupdate --freeze
|
|
||||||
- run: pre-commit run --all-files || true
|
|
||||||
|
|
||||||
- uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0
|
|
||||||
if: github.event_name != 'pull_request'
|
|
||||||
with:
|
|
||||||
gpg_private_key: ${{ secrets.ACTIONS_GPG_PRIVATE_KEY }}
|
|
||||||
passphrase: ${{ secrets.ACTIONS_GPG_PASSPHRASE }}
|
|
||||||
git_user_signingkey: true
|
|
||||||
git_commit_gpgsign: true
|
|
||||||
|
|
||||||
- uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
|
||||||
if: always()
|
|
||||||
env:
|
|
||||||
GH_REPO: ${{ github.repository }}
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
with:
|
|
||||||
branch: update/pre-commit-hooks
|
|
||||||
title: "style: Update pre-commit hooks"
|
|
||||||
commit-message: "style: Update pre-commit hooks"
|
|
||||||
body: Update versions of pre-commit hooks to latest version.
|
|
||||||
reviewers: "godexsoft,kuznetsss,PeterChen13579,mathbunnyru"
|
|
||||||
|
|||||||
24
.github/workflows/pre-commit.yml
vendored
24
.github/workflows/pre-commit.yml
vendored
@@ -3,26 +3,12 @@ name: Run pre-commit hooks
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches: [develop]
|
||||||
- develop
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run-hooks:
|
run-hooks:
|
||||||
runs-on: heavy
|
uses: XRPLF/actions/.github/workflows/pre-commit.yml@afbcbdafbe0ce5439492fb87eda6441371086386
|
||||||
container:
|
with:
|
||||||
image: ghcr.io/xrplf/clio-ci:latest
|
runs_on: heavy
|
||||||
|
container: '{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }'
|
||||||
steps:
|
|
||||||
- name: Checkout Repo ⚡️
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Prepare runner
|
|
||||||
uses: ./.github/actions/prepare_runner
|
|
||||||
with:
|
|
||||||
disable_ccache: true
|
|
||||||
|
|
||||||
- name: Run pre-commit ✅
|
|
||||||
run: pre-commit run --all-files
|
|
||||||
|
|||||||
11
.github/workflows/release.yml
vendored
11
.github/workflows/release.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
conan_profile: gcc
|
conan_profile: gcc
|
||||||
build_type: Release
|
build_type: Release
|
||||||
static: true
|
static: true
|
||||||
container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
|
container: '{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }'
|
||||||
|
|
||||||
uses: ./.github/workflows/build_and_test.yml
|
uses: ./.github/workflows/build_and_test.yml
|
||||||
with:
|
with:
|
||||||
@@ -41,16 +41,19 @@ jobs:
|
|||||||
run_unit_tests: true
|
run_unit_tests: true
|
||||||
run_integration_tests: true
|
run_integration_tests: true
|
||||||
upload_clio_server: true
|
upload_clio_server: true
|
||||||
disable_cache: true
|
download_ccache: false
|
||||||
|
upload_ccache: false
|
||||||
|
expected_version: ${{ github.event_name == 'push' && github.ref_name || '' }}
|
||||||
|
|
||||||
release:
|
release:
|
||||||
needs: build-and-test
|
needs: build-and-test
|
||||||
uses: ./.github/workflows/release_impl.yml
|
uses: ./.github/workflows/release_impl.yml
|
||||||
with:
|
with:
|
||||||
overwrite_release: false
|
overwrite_release: false
|
||||||
|
prerelease: ${{ contains(github.ref_name, '-') }}
|
||||||
title: "${{ github.ref_name}}"
|
title: "${{ github.ref_name}}"
|
||||||
version: "${{ github.ref_name }}"
|
version: "${{ github.ref_name }}"
|
||||||
header: >
|
header: >
|
||||||
# Introducing Clio version ${{ github.ref_name }}
|
${{ contains(github.ref_name, '-') && '> **Note:** Please remember that this is a release candidate and it is not recommended for production use.' || '' }}
|
||||||
generate_changelog: true
|
generate_changelog: ${{ !contains(github.ref_name, '-') }}
|
||||||
draft: true
|
draft: true
|
||||||
|
|||||||
37
.github/workflows/release_impl.yml
vendored
37
.github/workflows/release_impl.yml
vendored
@@ -8,6 +8,11 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
|
prerelease:
|
||||||
|
description: "Create a prerelease"
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
|
||||||
title:
|
title:
|
||||||
description: "Release title"
|
description: "Release title"
|
||||||
required: true
|
required: true
|
||||||
@@ -25,19 +30,19 @@ on:
|
|||||||
|
|
||||||
generate_changelog:
|
generate_changelog:
|
||||||
description: "Generate changelog"
|
description: "Generate changelog"
|
||||||
required: false
|
required: true
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
draft:
|
draft:
|
||||||
description: "Create a draft release"
|
description: "Create a draft release"
|
||||||
required: false
|
required: true
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/xrplf/clio-ci:latest
|
image: ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d
|
||||||
env:
|
env:
|
||||||
GH_REPO: ${{ github.repository }}
|
GH_REPO: ${{ github.repository }}
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
@@ -51,11 +56,11 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: ./.github/actions/prepare_runner
|
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f
|
||||||
with:
|
with:
|
||||||
disable_ccache: true
|
disable_ccache: true
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v5
|
||||||
with:
|
with:
|
||||||
path: release_artifacts
|
path: release_artifacts
|
||||||
pattern: clio_server_*
|
pattern: clio_server_*
|
||||||
@@ -63,34 +68,24 @@ jobs:
|
|||||||
- name: Create release notes
|
- name: Create release notes
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
printf '%s\n' "${{ inputs.header }}" > "${RUNNER_TEMP}/release_notes.md"
|
echo "# Release notes" > "${RUNNER_TEMP}/release_notes.md"
|
||||||
|
echo "" >> "${RUNNER_TEMP}/release_notes.md"
|
||||||
|
printf '%s\n' "${{ inputs.header }}" >> "${RUNNER_TEMP}/release_notes.md"
|
||||||
|
|
||||||
- name: Generate changelog
|
- name: Generate changelog
|
||||||
shell: bash
|
shell: bash
|
||||||
if: ${{ inputs.generate_changelog }}
|
if: ${{ inputs.generate_changelog }}
|
||||||
run: |
|
run: |
|
||||||
LAST_TAG="$(gh release view --json tagName -q .tagName)"
|
LAST_TAG="$(gh release view --json tagName -q .tagName --repo XRPLF/clio)"
|
||||||
LAST_TAG_COMMIT="$(git rev-parse $LAST_TAG)"
|
LAST_TAG_COMMIT="$(git rev-parse $LAST_TAG)"
|
||||||
BASE_COMMIT="$(git merge-base HEAD $LAST_TAG_COMMIT)"
|
BASE_COMMIT="$(git merge-base HEAD $LAST_TAG_COMMIT)"
|
||||||
git-cliff "${BASE_COMMIT}..HEAD" --ignore-tags "nightly|-b"
|
git-cliff "${BASE_COMMIT}..HEAD" --ignore-tags "nightly|-b|-rc"
|
||||||
cat CHANGELOG.md >> "${RUNNER_TEMP}/release_notes.md"
|
cat CHANGELOG.md >> "${RUNNER_TEMP}/release_notes.md"
|
||||||
|
|
||||||
- name: Prepare release artifacts
|
- name: Prepare release artifacts
|
||||||
shell: bash
|
shell: bash
|
||||||
run: .github/scripts/prepare-release-artifacts.sh release_artifacts
|
run: .github/scripts/prepare-release-artifacts.sh release_artifacts
|
||||||
|
|
||||||
- name: Append sha256 checksums
|
|
||||||
shell: bash
|
|
||||||
working-directory: release_artifacts
|
|
||||||
run: |
|
|
||||||
{
|
|
||||||
echo '## SHA256 checksums'
|
|
||||||
echo
|
|
||||||
echo '```'
|
|
||||||
cat *.sha256sum
|
|
||||||
echo '```'
|
|
||||||
} >> "${RUNNER_TEMP}/release_notes.md"
|
|
||||||
|
|
||||||
- name: Upload release notes
|
- name: Upload release notes
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@@ -109,7 +104,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
gh release create "${{ inputs.version }}" \
|
gh release create "${{ inputs.version }}" \
|
||||||
${{ inputs.overwrite_release && '--prerelease' || '' }} \
|
${{ inputs.prerelease && '--prerelease' || '' }} \
|
||||||
--title "${{ inputs.title }}" \
|
--title "${{ inputs.title }}" \
|
||||||
--target "${GITHUB_SHA}" \
|
--target "${GITHUB_SHA}" \
|
||||||
${{ inputs.draft && '--draft' || '' }} \
|
${{ inputs.draft && '--draft' || '' }} \
|
||||||
|
|||||||
19
.github/workflows/sanitizers.yml
vendored
19
.github/workflows/sanitizers.yml
vendored
@@ -37,22 +37,21 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
compiler: ["gcc", "clang"]
|
compiler: [gcc, clang]
|
||||||
sanitizer_ext: [".asan", ".tsan", ".ubsan"]
|
sanitizer_ext: [.asan, .tsan, .ubsan]
|
||||||
exclude:
|
build_type: [Release, Debug]
|
||||||
# Currently, clang.tsan unit tests hang
|
|
||||||
- compiler: clang
|
|
||||||
sanitizer_ext: .tsan
|
|
||||||
|
|
||||||
uses: ./.github/workflows/build_and_test.yml
|
uses: ./.github/workflows/build_and_test.yml
|
||||||
with:
|
with:
|
||||||
runs_on: heavy
|
runs_on: heavy
|
||||||
container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
|
container: '{ "image": "ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d" }'
|
||||||
disable_cache: true
|
download_ccache: false
|
||||||
|
upload_ccache: false
|
||||||
conan_profile: ${{ matrix.compiler }}${{ matrix.sanitizer_ext }}
|
conan_profile: ${{ matrix.compiler }}${{ matrix.sanitizer_ext }}
|
||||||
build_type: Release
|
build_type: ${{ matrix.build_type }}
|
||||||
static: false
|
static: false
|
||||||
run_unit_tests: true
|
# Currently, both gcc.tsan and clang.tsan unit tests hang
|
||||||
|
run_unit_tests: ${{ matrix.sanitizer_ext != '.tsan' }}
|
||||||
run_integration_tests: false
|
run_integration_tests: false
|
||||||
upload_clio_server: false
|
upload_clio_server: false
|
||||||
targets: clio_tests clio_integration_tests
|
targets: clio_tests clio_integration_tests
|
||||||
|
|||||||
30
.github/workflows/test_impl.yml
vendored
30
.github/workflows/test_impl.yml
vendored
@@ -39,22 +39,22 @@ jobs:
|
|||||||
runs-on: ${{ inputs.runs_on }}
|
runs-on: ${{ inputs.runs_on }}
|
||||||
container: ${{ inputs.container != '' && fromJson(inputs.container) || null }}
|
container: ${{ inputs.container != '' && fromJson(inputs.container) || null }}
|
||||||
|
|
||||||
if: inputs.run_unit_tests
|
if: ${{ inputs.run_unit_tests }}
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# TODO: remove completely when we have fixed all currently existing issues with sanitizers
|
# TODO: remove completely when we have fixed all currently existing issues with sanitizers
|
||||||
SANITIZER_IGNORE_ERRORS: ${{ endsWith(inputs.conan_profile, '.asan') || endsWith(inputs.conan_profile, '.tsan') }}
|
SANITIZER_IGNORE_ERRORS: ${{ endsWith(inputs.conan_profile, '.tsan') || inputs.conan_profile == 'clang.asan' || (inputs.conan_profile == 'gcc.asan' && inputs.build_type == 'Release') }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clean workdir
|
- name: Cleanup workspace
|
||||||
if: ${{ runner.os == 'macOS' }}
|
if: ${{ runner.os == 'macOS' }}
|
||||||
uses: kuznetsss/workspace-cleanup@80b9863b45562c148927c3d53621ef354e5ae7ce # v1.0
|
uses: XRPLF/actions/.github/actions/cleanup-workspace@ea9970b7c211b18f4c8bcdb28c29f5711752029f
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
||||||
|
|
||||||
@@ -63,15 +63,15 @@ jobs:
|
|||||||
run: chmod +x ./clio_tests
|
run: chmod +x ./clio_tests
|
||||||
|
|
||||||
- name: Run clio_tests (regular)
|
- name: Run clio_tests (regular)
|
||||||
if: env.SANITIZER_IGNORE_ERRORS == 'false'
|
if: ${{ env.SANITIZER_IGNORE_ERRORS == 'false' }}
|
||||||
run: ./clio_tests
|
run: ./clio_tests
|
||||||
|
|
||||||
- name: Run clio_tests (sanitizer errors ignored)
|
- name: Run clio_tests (sanitizer errors ignored)
|
||||||
if: env.SANITIZER_IGNORE_ERRORS == 'true'
|
if: ${{ env.SANITIZER_IGNORE_ERRORS == 'true' }}
|
||||||
run: ./.github/scripts/execute-tests-under-sanitizer ./clio_tests
|
run: ./.github/scripts/execute-tests-under-sanitizer ./clio_tests
|
||||||
|
|
||||||
- name: Check for sanitizer report
|
- name: Check for sanitizer report
|
||||||
if: env.SANITIZER_IGNORE_ERRORS == 'true'
|
if: ${{ env.SANITIZER_IGNORE_ERRORS == 'true' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
id: check_report
|
id: check_report
|
||||||
run: |
|
run: |
|
||||||
@@ -82,15 +82,15 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Upload sanitizer report
|
- name: Upload sanitizer report
|
||||||
if: env.SANITIZER_IGNORE_ERRORS == 'true' && steps.check_report.outputs.found_report == 'true'
|
if: ${{ env.SANITIZER_IGNORE_ERRORS == 'true' && steps.check_report.outputs.found_report == 'true' }}
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ inputs.conan_profile }}_report
|
name: sanitizer_report_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
||||||
path: .sanitizer-report/*
|
path: .sanitizer-report/*
|
||||||
include-hidden-files: true
|
include-hidden-files: true
|
||||||
|
|
||||||
- name: Create an issue
|
- name: Create an issue
|
||||||
if: false && env.SANITIZER_IGNORE_ERRORS == 'true' && steps.check_report.outputs.found_report == 'true'
|
if: ${{ false && env.SANITIZER_IGNORE_ERRORS == 'true' && steps.check_report.outputs.found_report == 'true' }}
|
||||||
uses: ./.github/actions/create_issue
|
uses: ./.github/actions/create_issue
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
@@ -108,7 +108,7 @@ jobs:
|
|||||||
runs-on: ${{ inputs.runs_on }}
|
runs-on: ${{ inputs.runs_on }}
|
||||||
container: ${{ inputs.container != '' && fromJson(inputs.container) || null }}
|
container: ${{ inputs.container != '' && fromJson(inputs.container) || null }}
|
||||||
|
|
||||||
if: inputs.run_integration_tests
|
if: ${{ inputs.run_integration_tests }}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
scylladb:
|
scylladb:
|
||||||
@@ -120,9 +120,9 @@ jobs:
|
|||||||
--health-retries 5
|
--health-retries 5
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clean workdir
|
- name: Cleanup workspace
|
||||||
if: ${{ runner.os == 'macOS' }}
|
if: ${{ runner.os == 'macOS' }}
|
||||||
uses: kuznetsss/workspace-cleanup@80b9863b45562c148927c3d53621ef354e5ae7ce # v1.0
|
uses: XRPLF/actions/.github/actions/cleanup-workspace@ea9970b7c211b18f4c8bcdb28c29f5711752029f
|
||||||
|
|
||||||
- name: Spin up scylladb
|
- name: Spin up scylladb
|
||||||
if: ${{ runner.os == 'macOS' }}
|
if: ${{ runner.os == 'macOS' }}
|
||||||
@@ -144,7 +144,7 @@ jobs:
|
|||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
|
||||||
|
|
||||||
|
|||||||
208
.github/workflows/update_docker_ci.yml
vendored
208
.github/workflows/update_docker_ci.yml
vendored
@@ -29,88 +29,110 @@ concurrency:
|
|||||||
cancel-in-progress: false
|
cancel-in-progress: false
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GHCR_REPO: ghcr.io/${{ github.repository_owner }}
|
CLANG_MAJOR_VERSION: 19
|
||||||
|
GCC_MAJOR_VERSION: 15
|
||||||
|
GCC_VERSION: 15.2.0
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
repo:
|
||||||
|
name: Calculate repo name
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
GHCR_REPO: ${{ steps.set-ghcr-repo.outputs.GHCR_REPO }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set GHCR_REPO
|
||||||
|
id: set-ghcr-repo
|
||||||
|
run: |
|
||||||
|
echo "GHCR_REPO=$(echo ghcr.io/${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> ${GITHUB_OUTPUT}
|
||||||
|
|
||||||
gcc-amd64:
|
gcc-amd64:
|
||||||
name: Build and push GCC docker image (amd64)
|
name: Build and push GCC docker image (amd64)
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
|
needs: repo
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get changed files
|
- name: Get changed files
|
||||||
id: changed-files
|
id: changed-files
|
||||||
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
|
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0
|
||||||
with:
|
with:
|
||||||
files: "docker/compilers/gcc/**"
|
files: "docker/compilers/gcc/**"
|
||||||
|
|
||||||
- uses: ./.github/actions/build_docker_image
|
- uses: ./.github/actions/build_docker_image
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
||||||
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
${{ env.GHCR_REPO }}/clio-gcc
|
${{ needs.repo.outputs.GHCR_REPO }}/clio-gcc
|
||||||
rippleci/clio_gcc
|
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_gcc' || '' }}
|
||||||
push_image: ${{ github.event_name != 'pull_request' }}
|
push_image: ${{ github.event_name != 'pull_request' }}
|
||||||
directory: docker/compilers/gcc
|
directory: docker/compilers/gcc
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=amd64-latest
|
type=raw,value=amd64-latest
|
||||||
type=raw,value=amd64-12
|
type=raw,value=amd64-${{ env.GCC_MAJOR_VERSION }}
|
||||||
type=raw,value=amd64-12.3.0
|
type=raw,value=amd64-${{ env.GCC_VERSION }}
|
||||||
type=raw,value=amd64-${{ github.sha }}
|
type=raw,value=amd64-${{ github.sha }}
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
dockerhub_repo: rippleci/clio_gcc
|
build_args: |
|
||||||
|
GCC_MAJOR_VERSION=${{ env.GCC_MAJOR_VERSION }}
|
||||||
|
GCC_VERSION=${{ env.GCC_VERSION }}
|
||||||
|
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_gcc' || '' }}
|
||||||
dockerhub_description: GCC compiler for XRPLF/clio.
|
dockerhub_description: GCC compiler for XRPLF/clio.
|
||||||
|
|
||||||
gcc-arm64:
|
gcc-arm64:
|
||||||
name: Build and push GCC docker image (arm64)
|
name: Build and push GCC docker image (arm64)
|
||||||
runs-on: heavy-arm64
|
runs-on: heavy-arm64
|
||||||
|
needs: repo
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get changed files
|
- name: Get changed files
|
||||||
id: changed-files
|
id: changed-files
|
||||||
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
|
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0
|
||||||
with:
|
with:
|
||||||
files: "docker/compilers/gcc/**"
|
files: "docker/compilers/gcc/**"
|
||||||
|
|
||||||
- uses: ./.github/actions/build_docker_image
|
- uses: ./.github/actions/build_docker_image
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
||||||
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
${{ env.GHCR_REPO }}/clio-gcc
|
${{ needs.repo.outputs.GHCR_REPO }}/clio-gcc
|
||||||
rippleci/clio_gcc
|
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_gcc' || '' }}
|
||||||
push_image: ${{ github.event_name != 'pull_request' }}
|
push_image: ${{ github.event_name != 'pull_request' }}
|
||||||
directory: docker/compilers/gcc
|
directory: docker/compilers/gcc
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=arm64-latest
|
type=raw,value=arm64-latest
|
||||||
type=raw,value=arm64-12
|
type=raw,value=arm64-${{ env.GCC_MAJOR_VERSION }}
|
||||||
type=raw,value=arm64-12.3.0
|
type=raw,value=arm64-${{ env.GCC_VERSION }}
|
||||||
type=raw,value=arm64-${{ github.sha }}
|
type=raw,value=arm64-${{ github.sha }}
|
||||||
platforms: linux/arm64
|
platforms: linux/arm64
|
||||||
dockerhub_repo: rippleci/clio_gcc
|
build_args: |
|
||||||
|
GCC_MAJOR_VERSION=${{ env.GCC_MAJOR_VERSION }}
|
||||||
|
GCC_VERSION=${{ env.GCC_VERSION }}
|
||||||
|
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_gcc' || '' }}
|
||||||
dockerhub_description: GCC compiler for XRPLF/clio.
|
dockerhub_description: GCC compiler for XRPLF/clio.
|
||||||
|
|
||||||
gcc-merge:
|
gcc-merge:
|
||||||
name: Merge and push multi-arch GCC docker image
|
name: Merge and push multi-arch GCC docker image
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
needs: [gcc-amd64, gcc-arm64]
|
needs: [repo, gcc-amd64, gcc-arm64]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get changed files
|
- name: Get changed files
|
||||||
id: changed-files
|
id: changed-files
|
||||||
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
|
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0
|
||||||
with:
|
with:
|
||||||
files: "docker/compilers/gcc/**"
|
files: "docker/compilers/gcc/**"
|
||||||
|
|
||||||
@@ -118,101 +140,176 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
if: github.event_name != 'pull_request'
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
if: github.event_name != 'pull_request'
|
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' }}
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USER }}
|
username: ${{ secrets.DOCKERHUB_USER }}
|
||||||
password: ${{ secrets.DOCKERHUB_PW }}
|
password: ${{ secrets.DOCKERHUB_PW }}
|
||||||
|
|
||||||
- name: Make GHCR_REPO lowercase
|
|
||||||
run: |
|
|
||||||
echo "GHCR_REPO_LC=$(echo ${{env.GHCR_REPO}} | tr '[:upper:]' '[:lower:]')" >> ${GITHUB_ENV}
|
|
||||||
|
|
||||||
- name: Create and push multi-arch manifest
|
- name: Create and push multi-arch manifest
|
||||||
if: github.event_name != 'pull_request' && steps.changed-files.outputs.any_changed == 'true'
|
if: ${{ github.event_name != 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
for image in ${{ env.GHCR_REPO_LC }}/clio-gcc rippleci/clio_gcc; do
|
push_image() {
|
||||||
|
image=$1
|
||||||
|
|
||||||
docker buildx imagetools create \
|
docker buildx imagetools create \
|
||||||
-t $image:latest \
|
-t $image:latest \
|
||||||
-t $image:12 \
|
-t $image:${{ env.GCC_MAJOR_VERSION }} \
|
||||||
-t $image:12.3.0 \
|
-t $image:${{ env.GCC_VERSION }} \
|
||||||
-t $image:${{ github.sha }} \
|
-t $image:${{ github.sha }} \
|
||||||
$image:arm64-latest \
|
$image:arm64-latest \
|
||||||
$image:amd64-latest
|
$image:amd64-latest
|
||||||
done
|
}
|
||||||
|
push_image ${{ needs.repo.outputs.GHCR_REPO }}/clio-gcc
|
||||||
|
if [[ ${{ github.repository_owner }} == 'XRPLF' ]]; then
|
||||||
|
push_image rippleci/clio_clang
|
||||||
|
fi
|
||||||
|
|
||||||
clang:
|
clang:
|
||||||
name: Build and push Clang docker image
|
name: Build and push Clang docker image
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
|
needs: repo
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get changed files
|
- name: Get changed files
|
||||||
id: changed-files
|
id: changed-files
|
||||||
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
|
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0
|
||||||
with:
|
with:
|
||||||
files: "docker/compilers/clang/**"
|
files: "docker/compilers/clang/**"
|
||||||
|
|
||||||
- uses: ./.github/actions/build_docker_image
|
- uses: ./.github/actions/build_docker_image
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
||||||
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
${{ env.GHCR_REPO }}/clio-clang
|
${{ needs.repo.outputs.GHCR_REPO }}/clio-clang
|
||||||
rippleci/clio_clang
|
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_clang' || '' }}
|
||||||
push_image: ${{ github.event_name != 'pull_request' }}
|
push_image: ${{ github.event_name != 'pull_request' }}
|
||||||
directory: docker/compilers/clang
|
directory: docker/compilers/clang
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest
|
type=raw,value=latest
|
||||||
type=raw,value=16
|
type=raw,value=${{ env.CLANG_MAJOR_VERSION }}
|
||||||
type=raw,value=${{ github.sha }}
|
type=raw,value=${{ github.sha }}
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
dockerhub_repo: rippleci/clio_clang
|
build_args: |
|
||||||
|
CLANG_MAJOR_VERSION=${{ env.CLANG_MAJOR_VERSION }}
|
||||||
|
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_clang' || '' }}
|
||||||
dockerhub_description: Clang compiler for XRPLF/clio.
|
dockerhub_description: Clang compiler for XRPLF/clio.
|
||||||
|
|
||||||
tools:
|
tools-amd64:
|
||||||
name: Build and push tools docker image
|
name: Build and push tools docker image (amd64)
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
|
needs: [repo, gcc-merge]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get changed files
|
- name: Get changed files
|
||||||
id: changed-files
|
id: changed-files
|
||||||
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
|
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0
|
||||||
with:
|
with:
|
||||||
files: "docker/tools/**"
|
files: "docker/tools/**"
|
||||||
|
|
||||||
- uses: ./.github/actions/build_docker_image
|
- uses: ./.github/actions/build_docker_image
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
${{ env.GHCR_REPO }}/clio-tools
|
${{ needs.repo.outputs.GHCR_REPO }}/clio-tools
|
||||||
push_image: ${{ github.event_name != 'pull_request' }}
|
push_image: ${{ github.event_name != 'pull_request' }}
|
||||||
directory: docker/tools
|
directory: docker/tools
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest
|
type=raw,value=amd64-latest
|
||||||
type=raw,value=${{ github.sha }}
|
type=raw,value=amd64-${{ github.sha }}
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64
|
||||||
|
build_args: |
|
||||||
|
GHCR_REPO=${{ needs.repo.outputs.GHCR_REPO }}
|
||||||
|
GCC_VERSION=${{ env.GCC_VERSION }}
|
||||||
|
|
||||||
|
tools-arm64:
|
||||||
|
name: Build and push tools docker image (arm64)
|
||||||
|
runs-on: heavy-arm64
|
||||||
|
needs: [repo, gcc-merge]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Get changed files
|
||||||
|
id: changed-files
|
||||||
|
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0
|
||||||
|
with:
|
||||||
|
files: "docker/tools/**"
|
||||||
|
|
||||||
|
- uses: ./.github/actions/build_docker_image
|
||||||
|
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
${{ needs.repo.outputs.GHCR_REPO }}/clio-tools
|
||||||
|
push_image: ${{ github.event_name != 'pull_request' }}
|
||||||
|
directory: docker/tools
|
||||||
|
tags: |
|
||||||
|
type=raw,value=arm64-latest
|
||||||
|
type=raw,value=arm64-${{ github.sha }}
|
||||||
|
platforms: linux/arm64
|
||||||
|
build_args: |
|
||||||
|
GHCR_REPO=${{ needs.repo.outputs.GHCR_REPO }}
|
||||||
|
GCC_VERSION=${{ env.GCC_VERSION }}
|
||||||
|
|
||||||
|
tools-merge:
|
||||||
|
name: Merge and push multi-arch tools docker image
|
||||||
|
runs-on: heavy
|
||||||
|
needs: [repo, tools-amd64, tools-arm64]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Get changed files
|
||||||
|
id: changed-files
|
||||||
|
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0
|
||||||
|
with:
|
||||||
|
files: "docker/tools/**"
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Create and push multi-arch manifest
|
||||||
|
if: ${{ github.event_name != 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
|
||||||
|
run: |
|
||||||
|
image=${{ needs.repo.outputs.GHCR_REPO }}/clio-tools
|
||||||
|
docker buildx imagetools create \
|
||||||
|
-t $image:latest \
|
||||||
|
-t $image:${{ github.sha }} \
|
||||||
|
$image:arm64-latest \
|
||||||
|
$image:amd64-latest
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
name: Build and push CI docker image
|
name: Build and push CI docker image
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
needs: [gcc-merge, clang, tools]
|
needs: [repo, gcc-merge, clang, tools-merge]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -223,14 +320,19 @@ jobs:
|
|||||||
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
${{ env.GHCR_REPO }}/clio-ci
|
${{ needs.repo.outputs.GHCR_REPO }}/clio-ci
|
||||||
rippleci/clio_ci
|
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_ci' || '' }}
|
||||||
push_image: ${{ github.event_name != 'pull_request' }}
|
push_image: ${{ github.event_name != 'pull_request' }}
|
||||||
directory: docker/ci
|
directory: docker/ci
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest
|
type=raw,value=latest
|
||||||
type=raw,value=gcc_12_clang_16
|
type=raw,value=gcc_${{ env.GCC_MAJOR_VERSION }}_clang_${{ env.CLANG_MAJOR_VERSION }}
|
||||||
type=raw,value=${{ github.sha }}
|
type=raw,value=${{ github.sha }}
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
dockerhub_repo: rippleci/clio_ci
|
build_args: |
|
||||||
|
GHCR_REPO=${{ needs.repo.outputs.GHCR_REPO }}
|
||||||
|
CLANG_MAJOR_VERSION=${{ env.CLANG_MAJOR_VERSION }}
|
||||||
|
GCC_MAJOR_VERSION=${{ env.GCC_MAJOR_VERSION }}
|
||||||
|
GCC_VERSION=${{ env.GCC_VERSION }}
|
||||||
|
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_ci' || '' }}
|
||||||
dockerhub_description: CI image for XRPLF/clio.
|
dockerhub_description: CI image for XRPLF/clio.
|
||||||
|
|||||||
40
.github/workflows/upload_conan_deps.yml
vendored
40
.github/workflows/upload_conan_deps.yml
vendored
@@ -10,29 +10,28 @@ on:
|
|||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
force_upload:
|
||||||
|
description: "Force upload of all dependencies"
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches: [develop]
|
||||||
- develop
|
|
||||||
paths:
|
paths:
|
||||||
- .github/workflows/upload_conan_deps.yml
|
- .github/workflows/upload_conan_deps.yml
|
||||||
|
|
||||||
- .github/actions/generate/action.yml
|
- .github/actions/conan/action.yml
|
||||||
- .github/actions/prepare_runner/action.yml
|
- ".github/scripts/conan/**"
|
||||||
- .github/scripts/conan/generate_matrix.py
|
|
||||||
- .github/scripts/conan/init.sh
|
|
||||||
|
|
||||||
- conanfile.py
|
- conanfile.py
|
||||||
- conan.lock
|
- conan.lock
|
||||||
push:
|
push:
|
||||||
branches:
|
branches: [develop]
|
||||||
- develop
|
|
||||||
paths:
|
paths:
|
||||||
- .github/workflows/upload_conan_deps.yml
|
- .github/workflows/upload_conan_deps.yml
|
||||||
|
|
||||||
- .github/actions/generate/action.yml
|
- .github/actions/conan/action.yml
|
||||||
- .github/actions/prepare_runner/action.yml
|
- ".github/scripts/conan/**"
|
||||||
- .github/scripts/conan/generate_matrix.py
|
|
||||||
- .github/scripts/conan/init.sh
|
|
||||||
|
|
||||||
- conanfile.py
|
- conanfile.py
|
||||||
- conan.lock
|
- conan.lock
|
||||||
@@ -61,6 +60,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
|
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
|
||||||
|
max-parallel: 10
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
container: ${{ matrix.container != '' && fromJson(matrix.container) || null }}
|
container: ${{ matrix.container != '' && fromJson(matrix.container) || null }}
|
||||||
@@ -72,20 +72,20 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Prepare runner
|
- name: Prepare runner
|
||||||
uses: ./.github/actions/prepare_runner
|
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f
|
||||||
with:
|
with:
|
||||||
disable_ccache: true
|
disable_ccache: true
|
||||||
|
|
||||||
- name: Setup conan on macOS
|
- name: Setup conan on macOS
|
||||||
if: runner.os == 'macOS'
|
if: ${{ runner.os == 'macOS' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ./.github/scripts/conan/init.sh
|
run: ./.github/scripts/conan/init.sh
|
||||||
|
|
||||||
- name: Show conan profile
|
- name: Show conan profile
|
||||||
run: conan profile show --profile:all ${{ env.CONAN_PROFILE }}
|
run: conan profile show --profile:all ${{ env.CONAN_PROFILE }}
|
||||||
|
|
||||||
- name: Run conan and cmake
|
- name: Run conan
|
||||||
uses: ./.github/actions/generate
|
uses: ./.github/actions/conan
|
||||||
with:
|
with:
|
||||||
conan_profile: ${{ env.CONAN_PROFILE }}
|
conan_profile: ${{ env.CONAN_PROFILE }}
|
||||||
# We check that everything builds fine from source on scheduled runs
|
# We check that everything builds fine from source on scheduled runs
|
||||||
@@ -94,9 +94,9 @@ jobs:
|
|||||||
build_type: ${{ matrix.build_type }}
|
build_type: ${{ matrix.build_type }}
|
||||||
|
|
||||||
- name: Login to Conan
|
- name: Login to Conan
|
||||||
if: github.event_name != 'pull_request'
|
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' }}
|
||||||
run: conan remote login -p ${{ secrets.CONAN_PASSWORD }} ripple ${{ secrets.CONAN_USERNAME }}
|
run: conan remote login -p ${{ secrets.CONAN_PASSWORD }} xrplf ${{ secrets.CONAN_USERNAME }}
|
||||||
|
|
||||||
- name: Upload Conan packages
|
- name: Upload Conan packages
|
||||||
if: github.event_name != 'pull_request' && github.event_name != 'schedule'
|
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' && github.event_name != 'schedule' }}
|
||||||
run: conan upload "*" -r=ripple --confirm
|
run: conan upload "*" -r=xrplf --confirm ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }}
|
||||||
|
|||||||
4
.github/workflows/upload_coverage_report.yml
vendored
4
.github/workflows/upload_coverage_report.yml
vendored
@@ -18,14 +18,14 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Download report artifact
|
- name: Download report artifact
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v5
|
||||||
with:
|
with:
|
||||||
name: coverage-report.xml
|
name: coverage-report.xml
|
||||||
path: build
|
path: build
|
||||||
|
|
||||||
- name: Upload coverage report
|
- name: Upload coverage report
|
||||||
if: ${{ hashFiles('build/coverage_report.xml') != '' }}
|
if: ${{ hashFiles('build/coverage_report.xml') != '' }}
|
||||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
|
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
|
||||||
with:
|
with:
|
||||||
files: build/coverage_report.xml
|
files: build/coverage_report.xml
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,4 +9,3 @@
|
|||||||
.sanitizer-report
|
.sanitizer-report
|
||||||
CMakeUserPresets.json
|
CMakeUserPresets.json
|
||||||
config.json
|
config.json
|
||||||
src/util/build/Build.cpp
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ exclude: ^(docs/doxygen-awesome-theme/|conan\.lock$)
|
|||||||
repos:
|
repos:
|
||||||
# `pre-commit sample-config` default hooks
|
# `pre-commit sample-config` default hooks
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # frozen: v5.0.0
|
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
- id: check-executables-have-shebangs
|
- id: check-executables-have-shebangs
|
||||||
@@ -26,18 +26,18 @@ repos:
|
|||||||
|
|
||||||
# Autoformat: YAML, JSON, Markdown, etc.
|
# Autoformat: YAML, JSON, Markdown, etc.
|
||||||
- repo: https://github.com/rbubley/mirrors-prettier
|
- repo: https://github.com/rbubley/mirrors-prettier
|
||||||
rev: 787fb9f542b140ba0b2aced38e6a3e68021647a3 # frozen: v3.5.3
|
rev: 5ba47274f9b181bce26a5150a725577f3c336011 # frozen: v3.6.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: prettier
|
- id: prettier
|
||||||
|
|
||||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||||
rev: 586c3ea3f51230da42bab657c6a32e9e66c364f0 # frozen: v0.44.0
|
rev: 192ad822316c3a22fb3d3cc8aa6eafa0b8488360 # frozen: v0.45.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: markdownlint-fix
|
- id: markdownlint-fix
|
||||||
exclude: LICENSE.md
|
exclude: LICENSE.md
|
||||||
|
|
||||||
- repo: https://github.com/hadolint/hadolint
|
- repo: https://github.com/hadolint/hadolint
|
||||||
rev: c3dc18df7a501f02a560a2cc7ba3c69a85ca01d3 # frozen: v2.13.1-beta
|
rev: 4e697ba704fd23b2409b947a319c19c3ee54d24f # frozen: v2.14.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: hadolint-docker
|
- id: hadolint-docker
|
||||||
# hadolint-docker is a special hook that runs hadolint in a Docker container
|
# hadolint-docker is a special hook that runs hadolint in a Docker container
|
||||||
@@ -80,7 +80,7 @@ repos:
|
|||||||
language: script
|
language: script
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
rev: f9a52e87b6cdcb01b0a62b8611d9ba9f2dad0067 # frozen: v19.1.7
|
rev: 719856d56a62953b8d2839fb9e851f25c3cfeef8 # frozen: v21.1.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: clang-format
|
- id: clang-format
|
||||||
args: [--style=file]
|
args: [--style=file]
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
set(CMAKE_PROJECT_INCLUDE_BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ClioVersion.cmake)
|
|
||||||
|
|
||||||
project(clio VERSION ${CLIO_VERSION} HOMEPAGE_URL "https://github.com/XRPLF/clio"
|
project(clio VERSION ${CLIO_VERSION} HOMEPAGE_URL "https://github.com/XRPLF/clio"
|
||||||
DESCRIPTION "An XRP Ledger API Server"
|
DESCRIPTION "An XRP Ledger API Server"
|
||||||
)
|
)
|
||||||
@@ -13,7 +11,7 @@ option(integration_tests "Build integration tests" FALSE)
|
|||||||
option(benchmark "Build benchmarks" FALSE)
|
option(benchmark "Build benchmarks" FALSE)
|
||||||
option(docs "Generate doxygen docs" FALSE)
|
option(docs "Generate doxygen docs" FALSE)
|
||||||
option(coverage "Build test coverage report" FALSE)
|
option(coverage "Build test coverage report" FALSE)
|
||||||
option(packaging "Create distribution packages" FALSE)
|
option(package "Create distribution packages" FALSE)
|
||||||
option(lint "Run clang-tidy checks during compilation" FALSE)
|
option(lint "Run clang-tidy checks during compilation" FALSE)
|
||||||
option(static "Statically linked Clio" FALSE)
|
option(static "Statically linked Clio" FALSE)
|
||||||
option(snapshot "Build snapshot tool" FALSE)
|
option(snapshot "Build snapshot tool" FALSE)
|
||||||
@@ -31,6 +29,7 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
|||||||
include(Ccache)
|
include(Ccache)
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
include(ClangTidy)
|
include(ClangTidy)
|
||||||
|
include(Linker)
|
||||||
|
|
||||||
add_library(clio_options INTERFACE)
|
add_library(clio_options INTERFACE)
|
||||||
target_compile_features(clio_options INTERFACE cxx_std_23) # Clio needs c++23 but deps can remain c++20 for now
|
target_compile_features(clio_options INTERFACE cxx_std_23) # Clio needs c++23 but deps can remain c++20 for now
|
||||||
@@ -40,11 +39,6 @@ if (verbose)
|
|||||||
set(CMAKE_VERBOSE_MAKEFILE TRUE)
|
set(CMAKE_VERBOSE_MAKEFILE TRUE)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (packaging)
|
|
||||||
add_definitions(-DPKG=1)
|
|
||||||
target_compile_definitions(clio_options INTERFACE PKG=1)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# Clio tweaks and checks
|
# Clio tweaks and checks
|
||||||
include(CheckCompiler)
|
include(CheckCompiler)
|
||||||
include(Settings)
|
include(Settings)
|
||||||
@@ -58,6 +52,7 @@ include(deps/Threads)
|
|||||||
include(deps/libfmt)
|
include(deps/libfmt)
|
||||||
include(deps/cassandra)
|
include(deps/cassandra)
|
||||||
include(deps/libbacktrace)
|
include(deps/libbacktrace)
|
||||||
|
include(deps/spdlog)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
@@ -69,15 +64,17 @@ endif ()
|
|||||||
# Enable selected sanitizer if enabled via `san`
|
# Enable selected sanitizer if enabled via `san`
|
||||||
if (san)
|
if (san)
|
||||||
set(SUPPORTED_SANITIZERS "address" "thread" "memory" "undefined")
|
set(SUPPORTED_SANITIZERS "address" "thread" "memory" "undefined")
|
||||||
list(FIND SUPPORTED_SANITIZERS "${san}" INDEX)
|
if (NOT san IN_LIST SUPPORTED_SANITIZERS)
|
||||||
if (INDEX EQUAL -1)
|
|
||||||
message(FATAL_ERROR "Error: Unsupported sanitizer '${san}'. Supported values are: ${SUPPORTED_SANITIZERS}.")
|
message(FATAL_ERROR "Error: Unsupported sanitizer '${san}'. Supported values are: ${SUPPORTED_SANITIZERS}.")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
target_compile_options(
|
# Sanitizers recommend minimum of -O1 for reasonable performance so we enable it for debug builds
|
||||||
clio_options INTERFACE # Sanitizers recommend minimum of -O1 for reasonable performance
|
set(SAN_OPTIMIZATION_FLAG "")
|
||||||
$<$<CONFIG:Debug>:-O1> ${SAN_FLAG} -fno-omit-frame-pointer
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
)
|
set(SAN_OPTIMIZATION_FLAG -O1)
|
||||||
|
endif ()
|
||||||
|
target_compile_options(clio_options INTERFACE ${SAN_OPTIMIZATION_FLAG} ${SAN_FLAG} -fno-omit-frame-pointer)
|
||||||
|
|
||||||
target_compile_definitions(
|
target_compile_definitions(
|
||||||
clio_options INTERFACE $<$<STREQUAL:${san},address>:SANITIZER=ASAN> $<$<STREQUAL:${san},thread>:SANITIZER=TSAN>
|
clio_options INTERFACE $<$<STREQUAL:${san},address>:SANITIZER=ASAN> $<$<STREQUAL:${san},thread>:SANITIZER=TSAN>
|
||||||
$<$<STREQUAL:${san},memory>:SANITIZER=MSAN> $<$<STREQUAL:${san},undefined>:SANITIZER=UBSAN>
|
$<$<STREQUAL:${san},memory>:SANITIZER=MSAN> $<$<STREQUAL:${san},undefined>:SANITIZER=UBSAN>
|
||||||
@@ -91,8 +88,8 @@ if (docs)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
include(install/install)
|
include(install/install)
|
||||||
if (packaging)
|
if (package)
|
||||||
include(cmake/packaging.cmake) # This file exists only in build runner
|
include(ClioPackage)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (snapshot)
|
if (snapshot)
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ target_sources(
|
|||||||
Playground.cpp
|
Playground.cpp
|
||||||
# ExecutionContext
|
# ExecutionContext
|
||||||
util/async/ExecutionContextBenchmarks.cpp
|
util/async/ExecutionContextBenchmarks.cpp
|
||||||
|
# Logger
|
||||||
|
util/log/LoggerBenchmark.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
include(deps/gbench)
|
include(deps/gbench)
|
||||||
|
|
||||||
target_include_directories(clio_benchmark PRIVATE .)
|
target_include_directories(clio_benchmark PRIVATE .)
|
||||||
target_link_libraries(clio_benchmark PUBLIC clio_etl benchmark::benchmark_main)
|
target_link_libraries(clio_benchmark PUBLIC clio_util benchmark::benchmark_main spdlog::spdlog)
|
||||||
set_target_properties(clio_benchmark PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
set_target_properties(clio_benchmark PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||||
|
|||||||
149
benchmarks/util/log/LoggerBenchmark.cpp
Normal file
149
benchmarks/util/log/LoggerBenchmark.cpp
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of clio: https://github.com/XRPLF/clio
|
||||||
|
Copyright (c) 2025, the clio developers.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include "util/config/ConfigDefinition.hpp"
|
||||||
|
#include "util/log/Logger.hpp"
|
||||||
|
#include "util/prometheus/Prometheus.hpp"
|
||||||
|
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <spdlog/async.h>
|
||||||
|
#include <spdlog/async_logger.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <barrier>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace util;
|
||||||
|
|
||||||
|
static constexpr auto kLOG_FORMAT = "%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v";
|
||||||
|
|
||||||
|
struct BenchmarkLoggingInitializer {
|
||||||
|
[[nodiscard]] static std::shared_ptr<spdlog::sinks::sink>
|
||||||
|
createFileSink(LogService::FileLoggingParams const& params)
|
||||||
|
{
|
||||||
|
return LogService::createFileSink(params, kLOG_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Logger
|
||||||
|
getLogger(std::shared_ptr<spdlog::logger> logger)
|
||||||
|
{
|
||||||
|
return Logger(std::move(logger));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::string
|
||||||
|
uniqueLogDir()
|
||||||
|
{
|
||||||
|
auto const epochTime = std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||||
|
auto const tmpDir = std::filesystem::temp_directory_path();
|
||||||
|
std::string const dirName =
|
||||||
|
fmt::format("logs_{}", std::chrono::duration_cast<std::chrono::microseconds>(epochTime).count());
|
||||||
|
return tmpDir / "clio_benchmark" / dirName;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
static void
|
||||||
|
benchmarkConcurrentFileLogging(benchmark::State& state)
|
||||||
|
{
|
||||||
|
auto const numThreads = static_cast<size_t>(state.range(0));
|
||||||
|
auto const messagesPerThread = static_cast<size_t>(state.range(1));
|
||||||
|
|
||||||
|
PrometheusService::init(config::getClioConfig());
|
||||||
|
|
||||||
|
auto const logDir = uniqueLogDir();
|
||||||
|
for (auto _ : state) {
|
||||||
|
state.PauseTiming();
|
||||||
|
|
||||||
|
std::filesystem::create_directories(logDir);
|
||||||
|
static constexpr size_t kQUEUE_SIZE = 8192;
|
||||||
|
static constexpr size_t kTHREAD_COUNT = 1;
|
||||||
|
spdlog::init_thread_pool(kQUEUE_SIZE, kTHREAD_COUNT);
|
||||||
|
|
||||||
|
auto fileSink = BenchmarkLoggingInitializer::createFileSink({
|
||||||
|
.logDir = logDir,
|
||||||
|
.rotationSizeMB = 5,
|
||||||
|
.dirMaxFiles = 25,
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
threads.reserve(numThreads);
|
||||||
|
|
||||||
|
std::chrono::high_resolution_clock::time_point start;
|
||||||
|
std::barrier barrier(numThreads, [&state, &start]() {
|
||||||
|
state.ResumeTiming();
|
||||||
|
start = std::chrono::high_resolution_clock::now();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (size_t threadNum = 0; threadNum < numThreads; ++threadNum) {
|
||||||
|
threads.emplace_back([threadNum, messagesPerThread, fileSink, &barrier]() {
|
||||||
|
std::string const channel = fmt::format("Thread_{}", threadNum);
|
||||||
|
auto logger = std::make_shared<spdlog::async_logger>(
|
||||||
|
channel, fileSink, spdlog::thread_pool(), spdlog::async_overflow_policy::block
|
||||||
|
);
|
||||||
|
spdlog::register_logger(logger);
|
||||||
|
Logger const threadLogger = BenchmarkLoggingInitializer::getLogger(std::move(logger));
|
||||||
|
|
||||||
|
barrier.arrive_and_wait();
|
||||||
|
|
||||||
|
for (size_t messageNum = 0; messageNum < messagesPerThread; ++messageNum) {
|
||||||
|
LOG(threadLogger.info()) << "Test log message #" << messageNum;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& thread : threads) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
spdlog::shutdown();
|
||||||
|
|
||||||
|
auto const end = std::chrono::high_resolution_clock::now();
|
||||||
|
state.SetIterationTime(std::chrono::duration_cast<std::chrono::duration<double>>(end - start).count());
|
||||||
|
|
||||||
|
std::filesystem::remove_all(logDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const totalMessages = numThreads * messagesPerThread;
|
||||||
|
state.counters["TotalMessagesRate"] = benchmark::Counter(totalMessages, benchmark::Counter::kIsRate);
|
||||||
|
state.counters["Threads"] = numThreads;
|
||||||
|
state.counters["MessagesPerThread"] = messagesPerThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
// One line of log message is around 110 bytes
|
||||||
|
// So, 100K messages is around 10.5MB
|
||||||
|
|
||||||
|
BENCHMARK(benchmarkConcurrentFileLogging)
|
||||||
|
->ArgsProduct({
|
||||||
|
// Number of threads
|
||||||
|
{1, 2, 4, 8},
|
||||||
|
// Messages per thread
|
||||||
|
{10'000, 100'000, 500'000, 1'000'000, 10'000'000},
|
||||||
|
})
|
||||||
|
->UseManualTime()
|
||||||
|
->Unit(benchmark::kMillisecond);
|
||||||
8
cmake/ClioPackage.cmake
Normal file
8
cmake/ClioPackage.cmake
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/ClioVersion.cmake")
|
||||||
|
|
||||||
|
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/clio")
|
||||||
|
set(CPACK_PACKAGE_VERSION "${CLIO_VERSION}")
|
||||||
|
set(CPACK_STRIP_FILES TRUE)
|
||||||
|
|
||||||
|
include(pkg/deb)
|
||||||
|
include(CPack)
|
||||||
@@ -1,42 +1,43 @@
|
|||||||
#[===================================================================[
|
|
||||||
write version to source
|
|
||||||
#]===================================================================]
|
|
||||||
|
|
||||||
find_package(Git REQUIRED)
|
find_package(Git REQUIRED)
|
||||||
|
|
||||||
set(GIT_COMMAND rev-parse --short HEAD)
|
set(GIT_COMMAND describe --tags --exact-match)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE REV
|
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND}
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE TAG
|
||||||
|
RESULT_VARIABLE RC
|
||||||
|
ERROR_VARIABLE ERR
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
set(GIT_COMMAND branch --show-current)
|
if (RC EQUAL 0)
|
||||||
execute_process(
|
message(STATUS "Found tag '${TAG}' in git. Will use it as Clio version")
|
||||||
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE BRANCH
|
set(CLIO_VERSION "${TAG}")
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
set(DOC_CLIO_VERSION "${TAG}")
|
||||||
)
|
else ()
|
||||||
|
message(STATUS "Error finding tag in git: ${ERR}")
|
||||||
|
message(STATUS "Will use 'YYYYMMDDHMS-<branch>-<git-rev>' as Clio version")
|
||||||
|
|
||||||
if (BRANCH STREQUAL "")
|
|
||||||
set(BRANCH "dev")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (NOT (BRANCH MATCHES master OR BRANCH MATCHES release/*)) # for develop and any other branch name
|
|
||||||
# YYYYMMDDHMS-<branch>-<git-rev>
|
|
||||||
set(GIT_COMMAND show -s --date=format:%Y%m%d%H%M%S --format=%cd)
|
set(GIT_COMMAND show -s --date=format:%Y%m%d%H%M%S --format=%cd)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE DATE
|
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE DATE
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(GIT_COMMAND branch --show-current)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE BRANCH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
|
||||||
|
set(GIT_COMMAND rev-parse --short HEAD)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE REV
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
|
||||||
set(CLIO_VERSION "${DATE}-${BRANCH}-${REV}")
|
set(CLIO_VERSION "${DATE}-${BRANCH}-${REV}")
|
||||||
set(DOC_CLIO_VERSION "develop")
|
set(DOC_CLIO_VERSION "develop")
|
||||||
else ()
|
|
||||||
set(GIT_COMMAND describe --tags)
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE CLIO_TAG_VERSION
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
set(CLIO_VERSION "${CLIO_TAG_VERSION}")
|
|
||||||
set(DOC_CLIO_VERSION "${CLIO_TAG_VERSION}")
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
@@ -44,5 +45,3 @@ if (CMAKE_BUILD_TYPE MATCHES Debug)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
message(STATUS "Build version: ${CLIO_VERSION}")
|
message(STATUS "Build version: ${CLIO_VERSION}")
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/Build.cpp.in ${CMAKE_CURRENT_LIST_DIR}/../src/util/build/Build.cpp)
|
|
||||||
|
|||||||
11
cmake/Linker.cmake
Normal file
11
cmake/Linker.cmake
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
if (DEFINED CMAKE_LINKER_TYPE)
|
||||||
|
message(STATUS "Custom linker is already set: ${CMAKE_LINKER_TYPE}")
|
||||||
|
return()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
find_program(MOLD_PATH mold)
|
||||||
|
|
||||||
|
if (MOLD_PATH AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
message(STATUS "Using Mold linker: ${MOLD_PATH}")
|
||||||
|
set(CMAKE_LINKER_TYPE MOLD)
|
||||||
|
endif ()
|
||||||
5
cmake/deps/spdlog.cmake
Normal file
5
cmake/deps/spdlog.cmake
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
find_package(spdlog REQUIRED)
|
||||||
|
|
||||||
|
if (NOT TARGET spdlog::spdlog)
|
||||||
|
message(FATAL_ERROR "spdlog::spdlog target not found")
|
||||||
|
endif ()
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Clio XRPL API server
|
|
||||||
Documentation=https://github.com/XRPLF/clio.git
|
|
||||||
|
|
||||||
After=network-online.target
|
|
||||||
Wants=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
ExecStart=@CLIO_INSTALL_DIR@/bin/clio_server @CLIO_INSTALL_DIR@/etc/config.json
|
|
||||||
Restart=on-failure
|
|
||||||
User=clio
|
|
||||||
Group=clio
|
|
||||||
LimitNOFILE=65536
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
set(CLIO_INSTALL_DIR "/opt/clio")
|
set(CLIO_INSTALL_DIR "/opt/clio")
|
||||||
set(CMAKE_INSTALL_PREFIX ${CLIO_INSTALL_DIR})
|
set(CMAKE_INSTALL_PREFIX "${CLIO_INSTALL_DIR}" CACHE PATH "Install prefix" FORCE)
|
||||||
|
|
||||||
install(TARGETS clio_server DESTINATION bin)
|
set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
install(TARGETS clio_server DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||||
|
|
||||||
file(READ docs/examples/config/example-config.json config)
|
file(READ docs/examples/config/example-config.json config)
|
||||||
string(REGEX REPLACE "./clio_log" "/var/log/clio/" config "${config}")
|
string(REGEX REPLACE "./clio_log" "/var/log/clio/" config "${config}")
|
||||||
file(WRITE ${CMAKE_BINARY_DIR}/install-config.json "${config}")
|
file(WRITE ${CMAKE_BINARY_DIR}/install-config.json "${config}")
|
||||||
install(FILES ${CMAKE_BINARY_DIR}/install-config.json DESTINATION etc RENAME config.json)
|
install(FILES ${CMAKE_BINARY_DIR}/install-config.json DESTINATION etc RENAME config.json)
|
||||||
|
|
||||||
configure_file("${CMAKE_SOURCE_DIR}/cmake/install/clio.service.in" "${CMAKE_BINARY_DIR}/clio.service")
|
|
||||||
|
|
||||||
install(FILES "${CMAKE_BINARY_DIR}/clio.service" DESTINATION /lib/systemd/system)
|
|
||||||
|
|||||||
12
cmake/pkg/deb.cmake
Normal file
12
cmake/pkg/deb.cmake
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
set(CPACK_GENERATOR "DEB")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/XRPLF/clio")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Ripple Labs Inc. <support@ripple.com>")
|
||||||
|
|
||||||
|
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
|
||||||
|
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||||
|
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA ${CMAKE_SOURCE_DIR}/cmake/pkg/postinst)
|
||||||
|
|
||||||
|
# We must replace "-" with "~" otherwise dpkg will sort "X.Y.Z-b1" as greater than "X.Y.Z"
|
||||||
|
string(REPLACE "-" "~" git "${CPACK_PACKAGE_VERSION}")
|
||||||
46
cmake/pkg/postinst
Executable file
46
cmake/pkg/postinst
Executable file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
USER_NAME=clio
|
||||||
|
GROUP_NAME="${USER_NAME}"
|
||||||
|
CLIO_EXECUTABLE="clio_server"
|
||||||
|
CLIO_PREFIX="/opt/clio"
|
||||||
|
CLIO_BIN="$CLIO_PREFIX/bin/${CLIO_EXECUTABLE}"
|
||||||
|
CLIO_CONFIG="$CLIO_PREFIX/etc/config.json"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
configure)
|
||||||
|
if ! id -u "$USER_NAME" >/dev/null 2>&1; then
|
||||||
|
# Users who should not have a home directory should have their home directory set to /nonexistent
|
||||||
|
# https://www.debian.org/doc/debian-policy/ch-opersys.html#non-existent-home-directories
|
||||||
|
useradd \
|
||||||
|
--system \
|
||||||
|
--home-dir /nonexistent \
|
||||||
|
--no-create-home \
|
||||||
|
--shell /usr/sbin/nologin \
|
||||||
|
--comment "system user for ${CLIO_EXECUTABLE}" \
|
||||||
|
--user-group \
|
||||||
|
${USER_NAME}
|
||||||
|
fi
|
||||||
|
|
||||||
|
install -d -o "$USER_NAME" -g "$GROUP_NAME" /var/log/clio
|
||||||
|
|
||||||
|
if [ -f "$CLIO_CONFIG" ]; then
|
||||||
|
chown "$USER_NAME:$GROUP_NAME" "$CLIO_CONFIG"
|
||||||
|
fi
|
||||||
|
|
||||||
|
chown -R "$USER_NAME:$GROUP_NAME" "$CLIO_PREFIX"
|
||||||
|
|
||||||
|
ln -sf "$CLIO_BIN" "/usr/bin/${CLIO_EXECUTABLE}"
|
||||||
|
|
||||||
|
;;
|
||||||
|
abort-upgrade|abort-remove|abort-deconfigure)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "postinst called with unknown argument \`$1'" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
72
conan.lock
72
conan.lock
@@ -1,49 +1,49 @@
|
|||||||
{
|
{
|
||||||
"version": "0.5",
|
"version": "0.5",
|
||||||
"requires": [
|
"requires": [
|
||||||
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1750263732.782",
|
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1756234269.497",
|
||||||
"xxhash/0.8.2#7856c968c985b2981b707ee8f2413b2b%1750263730.908",
|
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1756234289.683",
|
||||||
"xrpl/2.5.0#7880d1696f11fceb1d498570f1a184c8%1751035267.743",
|
"xrpl/2.6.1-rc2#c14c6a4092fb2b97d3a93906dcee87b7%1759161400.392",
|
||||||
"sqlite3/3.47.0#7a0904fd061f5f8a2366c294f9387830%1750263721.79",
|
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1756234266.869",
|
||||||
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1750263717.455",
|
"spdlog/1.15.3#3ca0e9e6b83af4d0151e26541d140c86%1754401846.61",
|
||||||
"re2/20230301#dfd6e2bf050eb90ddd8729cfb4c844a4%1750263715.145",
|
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1756234262.318",
|
||||||
"rapidjson/cci.20220822#1b9d8c2256876a154172dc5cfbe447c6%1750263713.526",
|
"re2/20230301#dfd6e2bf050eb90ddd8729cfb4c844a4%1756234257.976",
|
||||||
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1750263698.841",
|
"rapidjson/cci.20220822#1b9d8c2256876a154172dc5cfbe447c6%1754325007.656",
|
||||||
"openssl/1.1.1v#216374e4fb5b2e0f5ab1fb6f27b5b434%1750263685.885",
|
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1756234251.614",
|
||||||
"nudb/2.0.8#63990d3e517038e04bf529eb8167f69f%1750263683.814",
|
"openssl/1.1.1w#a8f0792d7c5121b954578a7149d23e03%1756223730.729",
|
||||||
"minizip/1.2.13#9e87d57804bd372d6d1e32b1871517a3%1750263681.745",
|
"nudb/2.0.9#c62cfd501e57055a7e0d8ee3d5e5427d%1756234237.107",
|
||||||
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1750263679.891",
|
"minizip/1.2.13#9e87d57804bd372d6d1e32b1871517a3%1754325004.374",
|
||||||
"libuv/1.46.0#78565d142ac7102776256328a26cdf60%1750263677.819",
|
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1756234228.999",
|
||||||
"libiconv/1.17#1ae2f60ab5d08de1643a22a81b360c59%1750257497.552",
|
"libuv/1.46.0#dc28c1f653fa197f00db5b577a6f6011%1754325003.592",
|
||||||
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1750263675.748",
|
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1756223727.64",
|
||||||
"libarchive/3.7.6#e0453864b2a4d225f06b3304903cb2b7%1750263671.05",
|
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1756230911.03",
|
||||||
"http_parser/2.9.4#98d91690d6fd021e9e624218a85d9d97%1750263668.751",
|
"libarchive/3.8.1#5cf685686322e906cb42706ab7e099a8%1756234256.696",
|
||||||
"gtest/1.14.0#f8f0757a574a8dd747d16af62d6eb1b7%1750263666.833",
|
"http_parser/2.9.4#98d91690d6fd021e9e624218a85d9d97%1754325001.385",
|
||||||
"grpc/1.50.1#02291451d1e17200293a409410d1c4e1%1750263646.614",
|
"gtest/1.14.0#f8f0757a574a8dd747d16af62d6eb1b7%1754325000.842",
|
||||||
"fmt/11.2.0#579bb2cdf4a7607621beea4eb4651e0f%1746298708.362",
|
"grpc/1.50.1#02291451d1e17200293a409410d1c4e1%1756234248.958",
|
||||||
"fmt/10.1.1#021e170cf81db57da82b5f737b6906c1%1750263644.741",
|
"fmt/11.2.0#579bb2cdf4a7607621beea4eb4651e0f%1754324999.086",
|
||||||
"date/3.0.3#cf28fe9c0aab99fe12da08aa42df65e1%1750263643.099",
|
"doctest/2.4.11#a4211dfc329a16ba9f280f9574025659%1756234220.819",
|
||||||
"cassandra-cpp-driver/2.17.0#e50919efac8418c26be6671fd702540a%1750263632.157",
|
"date/3.0.4#f74bbba5a08fa388256688743136cb6f%1756234217.493",
|
||||||
"c-ares/1.34.5#b78b91e7cfb1f11ce777a285bbf169c6%1750263630.06",
|
"cassandra-cpp-driver/2.17.0#e50919efac8418c26be6671fd702540a%1754324997.363",
|
||||||
"bzip2/1.0.8#00b4a4658791c1f06914e087f0e792f5%1750263627.95",
|
"c-ares/1.34.5#b78b91e7cfb1f11ce777a285bbf169c6%1756234217.915",
|
||||||
"boost/1.83.0#8eb22f36ddfb61f54bbc412c4555bd66%1750263616.444",
|
"bzip2/1.0.8#00b4a4658791c1f06914e087f0e792f5%1756234261.716",
|
||||||
"benchmark/1.8.3#1a2ce62c99e2b3feaa57b1f0c15a8c46%1724323740.181",
|
"boost/1.83.0#5d975011d65b51abb2d2f6eb8386b368%1754325043.336",
|
||||||
"abseil/20230802.1#f0f91485b111dc9837a68972cb19ca7b%1750263609.776"
|
"benchmark/1.9.4#ce4403f7a24d3e1f907cd9da4b678be4%1754578869.672",
|
||||||
|
"abseil/20230802.1#f0f91485b111dc9837a68972cb19ca7b%1756234220.907"
|
||||||
],
|
],
|
||||||
"build_requires": [
|
"build_requires": [
|
||||||
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1750263732.782",
|
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1756234269.497",
|
||||||
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1750263698.841",
|
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1756234251.614",
|
||||||
"protobuf/3.21.9#64ce20e1d9ea24f3d6c504015d5f6fa8%1750263690.822",
|
"cmake/3.31.8#dde3bde00bb843687e55aea5afa0e220%1756234232.89",
|
||||||
"cmake/3.31.7#57c3e118bcf267552c0ea3f8bee1e7d5%1749863707.208",
|
"b2/5.3.3#107c15377719889654eb9a162a673975%1756234226.28"
|
||||||
"b2/5.3.2#7b5fabfe7088ae933fb3e78302343ea0%1750263614.565"
|
|
||||||
],
|
],
|
||||||
"python_requires": [],
|
"python_requires": [],
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"boost/1.83.0": [
|
"boost/1.83.0": [
|
||||||
null,
|
null,
|
||||||
"boost/1.83.0#8eb22f36ddfb61f54bbc412c4555bd66"
|
"boost/1.83.0#5d975011d65b51abb2d2f6eb8386b368"
|
||||||
],
|
],
|
||||||
"protobuf/3.21.9": [
|
"protobuf/3.21.12": [
|
||||||
null,
|
null,
|
||||||
"protobuf/3.21.12"
|
"protobuf/3.21.12"
|
||||||
],
|
],
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
"lz4/1.10.0"
|
"lz4/1.10.0"
|
||||||
],
|
],
|
||||||
"sqlite3/3.44.2": [
|
"sqlite3/3.44.2": [
|
||||||
"sqlite3/3.47.0"
|
"sqlite3/3.49.1"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"config_requires": []
|
"config_requires": []
|
||||||
|
|||||||
41
conanfile.py
41
conanfile.py
@@ -9,19 +9,7 @@ class ClioConan(ConanFile):
|
|||||||
url = 'https://github.com/xrplf/clio'
|
url = 'https://github.com/xrplf/clio'
|
||||||
description = 'Clio RPC server'
|
description = 'Clio RPC server'
|
||||||
settings = 'os', 'compiler', 'build_type', 'arch'
|
settings = 'os', 'compiler', 'build_type', 'arch'
|
||||||
options = {
|
options = {}
|
||||||
'static': [True, False], # static linkage
|
|
||||||
'verbose': [True, False],
|
|
||||||
'tests': [True, False], # build unit tests; create `clio_tests` binary
|
|
||||||
'integration_tests': [True, False], # build integration tests; create `clio_integration_tests` binary
|
|
||||||
'benchmark': [True, False], # build benchmarks; create `clio_benchmarks` binary
|
|
||||||
'docs': [True, False], # doxygen API docs; create custom target 'docs'
|
|
||||||
'packaging': [True, False], # create distribution packages
|
|
||||||
'coverage': [True, False], # build for test coverage report; create custom target `clio_tests-ccov`
|
|
||||||
'lint': [True, False], # run clang-tidy checks during compilation
|
|
||||||
'snapshot': [True, False], # build export/import snapshot tool
|
|
||||||
'time_trace': [True, False] # build using -ftime-trace to create compiler trace reports
|
|
||||||
}
|
|
||||||
|
|
||||||
requires = [
|
requires = [
|
||||||
'boost/1.83.0',
|
'boost/1.83.0',
|
||||||
@@ -29,25 +17,14 @@ class ClioConan(ConanFile):
|
|||||||
'fmt/11.2.0',
|
'fmt/11.2.0',
|
||||||
'protobuf/3.21.12',
|
'protobuf/3.21.12',
|
||||||
'grpc/1.50.1',
|
'grpc/1.50.1',
|
||||||
'openssl/1.1.1v',
|
'openssl/1.1.1w',
|
||||||
'xrpl/2.5.0',
|
'xrpl/2.6.1-rc2',
|
||||||
'zlib/1.3.1',
|
'zlib/1.3.1',
|
||||||
'libbacktrace/cci.20210118'
|
'libbacktrace/cci.20210118',
|
||||||
|
'spdlog/1.15.3',
|
||||||
]
|
]
|
||||||
|
|
||||||
default_options = {
|
default_options = {
|
||||||
'static': False,
|
|
||||||
'verbose': False,
|
|
||||||
'tests': False,
|
|
||||||
'integration_tests': False,
|
|
||||||
'benchmark': False,
|
|
||||||
'packaging': False,
|
|
||||||
'coverage': False,
|
|
||||||
'lint': False,
|
|
||||||
'docs': False,
|
|
||||||
'snapshot': False,
|
|
||||||
'time_trace': False,
|
|
||||||
|
|
||||||
'xrpl/*:tests': False,
|
'xrpl/*:tests': False,
|
||||||
'xrpl/*:rocksdb': False,
|
'xrpl/*:rocksdb': False,
|
||||||
'cassandra-cpp-driver/*:shared': False,
|
'cassandra-cpp-driver/*:shared': False,
|
||||||
@@ -68,10 +45,8 @@ class ClioConan(ConanFile):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def requirements(self):
|
def requirements(self):
|
||||||
if self.options.tests or self.options.integration_tests:
|
self.requires('gtest/1.14.0')
|
||||||
self.requires('gtest/1.14.0')
|
self.requires('benchmark/1.9.4')
|
||||||
if self.options.benchmark:
|
|
||||||
self.requires('benchmark/1.8.3')
|
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
if self.settings.compiler == 'apple-clang':
|
if self.settings.compiler == 'apple-clang':
|
||||||
@@ -87,8 +62,6 @@ class ClioConan(ConanFile):
|
|||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
tc = CMakeToolchain(self)
|
tc = CMakeToolchain(self)
|
||||||
for option_name, option_value in self.options.items():
|
|
||||||
tc.variables[option_name] = option_value
|
|
||||||
tc.generate()
|
tc.generate()
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
FROM ghcr.io/xrplf/clio-gcc:12.3.0 AS clio-gcc
|
ARG GHCR_REPO=invalid
|
||||||
FROM ghcr.io/xrplf/clio-tools:latest AS clio-tools
|
ARG CLANG_MAJOR_VERSION=invalid
|
||||||
|
ARG GCC_VERSION=invalid
|
||||||
|
|
||||||
FROM ghcr.io/xrplf/clio-clang:16
|
FROM ${GHCR_REPO}/clio-gcc:${GCC_VERSION} AS clio-gcc
|
||||||
|
FROM ${GHCR_REPO}/clio-tools:latest AS clio-tools
|
||||||
|
|
||||||
|
FROM ${GHCR_REPO}/clio-clang:${CLANG_MAJOR_VERSION}
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
@@ -16,80 +20,102 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
|||||||
USER root
|
USER root
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|
||||||
ARG LLVM_TOOLS_VERSION=20
|
# Install common tools and dependencies
|
||||||
|
|
||||||
# Add repositories
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
curl \
|
curl \
|
||||||
|
dpkg-dev \
|
||||||
|
file \
|
||||||
|
git \
|
||||||
|
git-lfs \
|
||||||
gnupg \
|
gnupg \
|
||||||
|
graphviz \
|
||||||
|
jq \
|
||||||
|
# libgmp, libmpfr and libncurses are gdb dependencies
|
||||||
|
libgmp-dev \
|
||||||
|
libmpfr-dev \
|
||||||
|
libncurses-dev \
|
||||||
|
make \
|
||||||
|
ninja-build \
|
||||||
wget \
|
wget \
|
||||||
|
zip \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Python tools
|
||||||
|
ARG PYTHON_VERSION=3.13
|
||||||
|
|
||||||
|
RUN add-apt-repository ppa:deadsnakes/ppa \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
|
python${PYTHON_VERSION} \
|
||||||
|
python${PYTHON_VERSION}-venv \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${LLVM_TOOLS_VERSION} main" >> /etc/apt/sources.list \
|
&& curl -sS https://bootstrap.pypa.io/get-pip.py | python${PYTHON_VERSION}
|
||||||
|
|
||||||
|
# Create a virtual environment for python tools
|
||||||
|
RUN python${PYTHON_VERSION} -m venv /opt/venv
|
||||||
|
ENV PATH="/opt/venv/bin:$PATH"
|
||||||
|
|
||||||
|
RUN pip install -q --no-cache-dir \
|
||||||
|
cmake \
|
||||||
|
conan==2.20.1 \
|
||||||
|
gcovr \
|
||||||
|
pre-commit
|
||||||
|
|
||||||
|
# Install LLVM tools
|
||||||
|
ARG LLVM_TOOLS_VERSION=20
|
||||||
|
|
||||||
|
RUN echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${LLVM_TOOLS_VERSION} main" >> /etc/apt/sources.list \
|
||||||
&& wget --progress=dot:giga -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
&& wget --progress=dot:giga -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||||
|
|
||||||
# Install packages
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
clang-tidy-${LLVM_TOOLS_VERSION} \
|
clang-tidy-${LLVM_TOOLS_VERSION} \
|
||||||
clang-tools-${LLVM_TOOLS_VERSION} \
|
clang-tools-${LLVM_TOOLS_VERSION} \
|
||||||
git \
|
|
||||||
git-lfs \
|
|
||||||
graphviz \
|
|
||||||
jq \
|
|
||||||
make \
|
|
||||||
ninja-build \
|
|
||||||
python3 \
|
|
||||||
python3-pip \
|
|
||||||
zip \
|
|
||||||
&& pip3 install -q --upgrade --no-cache-dir pip \
|
|
||||||
&& pip3 install -q --no-cache-dir \
|
|
||||||
# TODO: Remove this once we switch to newer Ubuntu base image
|
|
||||||
# lxml 6.0.0 is not compatible with our image
|
|
||||||
'lxml<6.0.0' \
|
|
||||||
\
|
|
||||||
cmake==3.31.6 \
|
|
||||||
conan==2.17.0 \
|
|
||||||
gcovr \
|
|
||||||
pre-commit \
|
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Install gcc-12 and make ldconfig aware of the new libstdc++ location (for gcc)
|
ARG GCC_MAJOR_VERSION=invalid
|
||||||
|
|
||||||
|
# Install custom-built gcc and make ldconfig aware of the new libstdc++ location (for gcc)
|
||||||
# Note: Clang is using libc++ instead
|
# Note: Clang is using libc++ instead
|
||||||
COPY --from=clio-gcc /gcc12.deb /
|
COPY --from=clio-gcc /gcc${GCC_MAJOR_VERSION}.deb /
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
binutils \
|
binutils \
|
||||||
libc6-dev \
|
libc6-dev \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& dpkg -i /gcc12.deb \
|
&& dpkg -i /gcc${GCC_MAJOR_VERSION}.deb \
|
||||||
&& rm -rf /gcc12.deb \
|
&& rm -rf /gcc${GCC_MAJOR_VERSION}.deb \
|
||||||
&& ldconfig
|
&& ldconfig
|
||||||
|
|
||||||
# Rewire to use gcc-12 as default compiler
|
# Rewire to use our custom-built gcc as default compiler
|
||||||
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 100 \
|
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCC_MAJOR_VERSION} 100 \
|
||||||
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-12 100 \
|
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-${GCC_MAJOR_VERSION} 100 \
|
||||||
&& update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 \
|
&& update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_MAJOR_VERSION} 100 \
|
||||||
&& update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-12 100 \
|
&& update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-${GCC_MAJOR_VERSION} 100 \
|
||||||
&& update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-12 100 \
|
&& update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-${GCC_MAJOR_VERSION} 100 \
|
||||||
&& update-alternatives --install /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-12 100 \
|
&& update-alternatives --install /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-${GCC_MAJOR_VERSION} 100 \
|
||||||
&& update-alternatives --install /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-12 100
|
&& update-alternatives --install /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-${GCC_MAJOR_VERSION} 100
|
||||||
|
|
||||||
COPY --from=clio-tools \
|
COPY --from=clio-tools \
|
||||||
|
/usr/local/bin/mold \
|
||||||
|
/usr/local/bin/ld.mold \
|
||||||
/usr/local/bin/ccache \
|
/usr/local/bin/ccache \
|
||||||
/usr/local/bin/doxygen \
|
/usr/local/bin/doxygen \
|
||||||
/usr/local/bin/ClangBuildAnalyzer \
|
/usr/local/bin/ClangBuildAnalyzer \
|
||||||
/usr/local/bin/git-cliff \
|
/usr/local/bin/git-cliff \
|
||||||
/usr/local/bin/gh \
|
/usr/local/bin/gh \
|
||||||
|
/usr/local/bin/gdb \
|
||||||
/usr/local/bin/
|
/usr/local/bin/
|
||||||
|
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|
||||||
# Setup conan
|
# Setup conan
|
||||||
RUN conan remote add --index 0 ripple http://18.143.149.228:8081/artifactory/api/conan/dev
|
RUN conan remote add --index 0 xrplf https://conan.ripplex.io
|
||||||
|
|
||||||
WORKDIR /root/.conan2
|
WORKDIR /root/.conan2
|
||||||
COPY conan/global.conf ./global.conf
|
COPY conan/global.conf ./global.conf
|
||||||
|
|||||||
@@ -6,13 +6,16 @@ It is used in [Clio Github Actions](https://github.com/XRPLF/clio/actions) but c
|
|||||||
The image is based on Ubuntu 20.04 and contains:
|
The image is based on Ubuntu 20.04 and contains:
|
||||||
|
|
||||||
- ccache 4.11.3
|
- ccache 4.11.3
|
||||||
- clang 16.0.6
|
- Clang 19
|
||||||
- ClangBuildAnalyzer 1.6.0
|
- ClangBuildAnalyzer 1.6.0
|
||||||
- conan 2.17.0
|
- Conan 2.20.1
|
||||||
- doxygen 1.12
|
- Doxygen 1.12
|
||||||
- gcc 12.3.0
|
- GCC 15.2.0
|
||||||
|
- GDB 16.3
|
||||||
- gh 2.74
|
- gh 2.74
|
||||||
- git-cliff 2.9.1
|
- git-cliff 2.9.1
|
||||||
|
- mold 2.40.1
|
||||||
|
- Python 3.13
|
||||||
- and some other useful tools
|
- and some other useful tools
|
||||||
|
|
||||||
Conan is set up to build Clio without any additional steps.
|
Conan is set up to build Clio without any additional steps.
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ build_type=Release
|
|||||||
compiler=clang
|
compiler=clang
|
||||||
compiler.cppstd=20
|
compiler.cppstd=20
|
||||||
compiler.libcxx=libc++
|
compiler.libcxx=libc++
|
||||||
compiler.version=16
|
compiler.version=19
|
||||||
os=Linux
|
os=Linux
|
||||||
|
|
||||||
[conf]
|
[conf]
|
||||||
tools.build:compiler_executables={"c": "/usr/bin/clang-16", "cpp": "/usr/bin/clang++-16"}
|
tools.build:compiler_executables={"c": "/usr/bin/clang-19", "cpp": "/usr/bin/clang++-19"}
|
||||||
|
grpc/1.50.1:tools.build:cxxflags+=["-Wno-missing-template-arg-list-after-template-kw"]
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ build_type=Release
|
|||||||
compiler=gcc
|
compiler=gcc
|
||||||
compiler.cppstd=20
|
compiler.cppstd=20
|
||||||
compiler.libcxx=libstdc++11
|
compiler.libcxx=libstdc++11
|
||||||
compiler.version=12
|
compiler.version=15
|
||||||
os=Linux
|
os=Linux
|
||||||
|
|
||||||
[conf]
|
[conf]
|
||||||
tools.build:compiler_executables={"c": "/usr/bin/gcc-12", "cpp": "/usr/bin/g++-12"}
|
tools.build:compiler_executables={"c": "/usr/bin/gcc-15", "cpp": "/usr/bin/g++-15"}
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
FROM ubuntu:22.04
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
|
libatomic1 \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN groupadd -g 10001 clio \
|
||||||
|
&& useradd -u 10000 -g 10001 -s /bin/bash clio
|
||||||
|
|
||||||
COPY ./clio_server /opt/clio/bin/clio_server
|
COPY ./clio_server /opt/clio/bin/clio_server
|
||||||
|
|
||||||
RUN ln -s /opt/clio/bin/clio_server /usr/local/bin/clio_server \
|
RUN ln -s /opt/clio/bin/clio_server /usr/local/bin/clio_server \
|
||||||
&& mkdir -p /opt/clio/etc/ \
|
&& mkdir -p /opt/clio/etc/ \
|
||||||
&& mkdir -p /opt/clio/log/ \
|
&& mkdir -p /opt/clio/log/ \
|
||||||
&& groupadd -g 10001 clio \
|
&& chown clio:clio /opt/clio/log
|
||||||
&& useradd -u 10000 -g 10001 -s /bin/bash clio \
|
|
||||||
&& chown clio:clio /opt/clio/log \
|
|
||||||
&& apt-get update \
|
|
||||||
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
|
||||||
libatomic1 \
|
|
||||||
&& apt-get clean \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
USER clio
|
USER clio
|
||||||
ENTRYPOINT ["/opt/clio/bin/clio_server"]
|
ENTRYPOINT ["/opt/clio/bin/clio_server"]
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ Clio repository provides an [example](https://github.com/XRPLF/clio/blob/develop
|
|||||||
|
|
||||||
Config file recommendations:
|
Config file recommendations:
|
||||||
|
|
||||||
- Set `log_to_console` to `false` if you want to avoid logs being written to `stdout`.
|
- Set `log.enable_console` to `false` if you want to avoid logs being written to `stdout`.
|
||||||
- Set `log_directory` to `/opt/clio/log` to store logs in a volume.
|
- Set `log.directory` to `/opt/clio/log` to store logs in a volume.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ SHELL ["/bin/bash", "-c"]
|
|||||||
USER root
|
USER root
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|
||||||
ARG CLANG_VERSION=16
|
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
wget \
|
wget \
|
||||||
@@ -18,13 +16,17 @@ RUN apt-get update \
|
|||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
ARG CLANG_MAJOR_VERSION=invalid
|
||||||
|
# Bump this version to force rebuild of the image
|
||||||
|
ARG BUILD_VERSION=1
|
||||||
|
|
||||||
RUN wget --progress=dot:giga https://apt.llvm.org/llvm.sh \
|
RUN wget --progress=dot:giga https://apt.llvm.org/llvm.sh \
|
||||||
&& chmod +x llvm.sh \
|
&& chmod +x llvm.sh \
|
||||||
&& ./llvm.sh ${CLANG_VERSION} \
|
&& ./llvm.sh ${CLANG_MAJOR_VERSION} \
|
||||||
&& rm -rf llvm.sh \
|
&& rm -rf llvm.sh \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
libc++-${CLANG_VERSION}-dev \
|
libc++-${CLANG_MAJOR_VERSION}-dev \
|
||||||
libc++abi-${CLANG_VERSION}-dev \
|
libc++abi-${CLANG_MAJOR_VERSION}-dev \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
ARG UBUNTU_VERSION=20.04
|
ARG UBUNTU_VERSION=20.04
|
||||||
|
|
||||||
ARG GCC_MAJOR_VERSION=12
|
ARG GCC_MAJOR_VERSION=invalid
|
||||||
|
|
||||||
FROM ubuntu:$UBUNTU_VERSION AS build
|
FROM ubuntu:$UBUNTU_VERSION AS build
|
||||||
|
|
||||||
ARG UBUNTU_VERSION
|
ARG UBUNTU_VERSION
|
||||||
|
|
||||||
ARG GCC_MAJOR_VERSION
|
ARG GCC_MAJOR_VERSION
|
||||||
ARG GCC_MINOR_VERSION=3
|
|
||||||
ARG GCC_PATCH_VERSION=0
|
ARG BUILD_VERSION=1
|
||||||
ARG GCC_VERSION=${GCC_MAJOR_VERSION}.${GCC_MINOR_VERSION}.${GCC_PATCH_VERSION}
|
|
||||||
ARG BUILD_VERSION=6
|
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
@@ -27,6 +25,8 @@ RUN apt-get update \
|
|||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
ARG GCC_VERSION
|
||||||
|
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
RUN wget --progress=dot:giga https://gcc.gnu.org/pub/gcc/releases/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz \
|
RUN wget --progress=dot:giga https://gcc.gnu.org/pub/gcc/releases/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz \
|
||||||
&& tar xf gcc-$GCC_VERSION.tar.gz
|
&& tar xf gcc-$GCC_VERSION.tar.gz
|
||||||
@@ -68,12 +68,13 @@ RUN /gcc-$GCC_VERSION/configure \
|
|||||||
--enable-checking=release
|
--enable-checking=release
|
||||||
|
|
||||||
RUN make -j "$(nproc)"
|
RUN make -j "$(nproc)"
|
||||||
|
RUN make install-strip DESTDIR=/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION
|
||||||
|
|
||||||
RUN make install-strip DESTDIR=/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION \
|
RUN export GDB_AUTOLOAD_DIR="/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/share/gdb/auto-load/usr/lib64" \
|
||||||
&& mkdir -p /gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/share/gdb/auto-load/usr/lib64 \
|
&& mkdir -p "$GDB_AUTOLOAD_DIR" \
|
||||||
&& mv \
|
&& mv \
|
||||||
/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/lib64/libstdc++.so.6.0.30-gdb.py \
|
/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/lib64/libstdc++.so.*-gdb.py \
|
||||||
/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.30-gdb.py
|
$GDB_AUTOLOAD_DIR/
|
||||||
|
|
||||||
# Generate deb
|
# Generate deb
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Package: gcc-12-ubuntu-UBUNTUVERSION
|
Package: gcc-15-ubuntu-UBUNTUVERSION
|
||||||
Version: VERSION
|
Version: VERSION
|
||||||
Architecture: TARGETARCH
|
Architecture: TARGETARCH
|
||||||
Maintainer: Alex Kremer <akremer@ripple.com>
|
Maintainer: Alex Kremer <akremer@ripple.com>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
clio_develop:
|
clio_develop:
|
||||||
image: ghcr.io/xrplf/clio-ci:latest
|
image: ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d
|
||||||
volumes:
|
volumes:
|
||||||
- clio_develop_conan_data:/root/.conan2/p
|
- clio_develop_conan_data:/root/.conan2/p
|
||||||
- clio_develop_ccache:/root/.ccache
|
- clio_develop_ccache:/root/.ccache
|
||||||
|
|||||||
@@ -1,24 +1,39 @@
|
|||||||
FROM ubuntu:20.04
|
ARG GHCR_REPO=invalid
|
||||||
|
ARG GCC_VERSION=invalid
|
||||||
|
|
||||||
|
FROM ${GHCR_REPO}/clio-gcc:${GCC_VERSION}
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||||
|
|
||||||
|
ARG BUILD_VERSION=2
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
bison \
|
|
||||||
build-essential \
|
|
||||||
cmake \
|
|
||||||
flex \
|
|
||||||
ninja-build \
|
ninja-build \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
software-properties-common \
|
software-properties-common \
|
||||||
wget \
|
wget \
|
||||||
|
&& pip3 install -q --no-cache-dir \
|
||||||
|
cmake \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
|
ARG MOLD_VERSION=2.40.1
|
||||||
|
RUN wget --progress=dot:giga "https://github.com/rui314/mold/archive/refs/tags/v${MOLD_VERSION}.tar.gz" \
|
||||||
|
&& tar xf "v${MOLD_VERSION}.tar.gz" \
|
||||||
|
&& cd "mold-${MOLD_VERSION}" \
|
||||||
|
&& mkdir build \
|
||||||
|
&& cd build \
|
||||||
|
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
|
||||||
|
&& ninja install \
|
||||||
|
&& rm -rf /tmp/* /var/tmp/*
|
||||||
|
|
||||||
ARG CCACHE_VERSION=4.11.3
|
ARG CCACHE_VERSION=4.11.3
|
||||||
RUN wget --progress=dot:giga "https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}.tar.gz" \
|
RUN wget --progress=dot:giga "https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}.tar.gz" \
|
||||||
&& tar xf "ccache-${CCACHE_VERSION}.tar.gz" \
|
&& tar xf "ccache-${CCACHE_VERSION}.tar.gz" \
|
||||||
@@ -26,9 +41,16 @@ RUN wget --progress=dot:giga "https://github.com/ccache/ccache/releases/download
|
|||||||
&& mkdir build \
|
&& mkdir build \
|
||||||
&& cd build \
|
&& cd build \
|
||||||
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTING=False .. \
|
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTING=False .. \
|
||||||
&& cmake --build . --target install \
|
&& ninja install \
|
||||||
&& rm -rf /tmp/* /var/tmp/*
|
&& rm -rf /tmp/* /var/tmp/*
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
|
bison \
|
||||||
|
flex \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
ARG DOXYGEN_VERSION=1.12.0
|
ARG DOXYGEN_VERSION=1.12.0
|
||||||
RUN wget --progress=dot:giga "https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.src.tar.gz" \
|
RUN wget --progress=dot:giga "https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.src.tar.gz" \
|
||||||
&& tar xf "doxygen-${DOXYGEN_VERSION}.src.tar.gz" \
|
&& tar xf "doxygen-${DOXYGEN_VERSION}.src.tar.gz" \
|
||||||
@@ -36,7 +58,7 @@ RUN wget --progress=dot:giga "https://github.com/doxygen/doxygen/releases/downlo
|
|||||||
&& mkdir build \
|
&& mkdir build \
|
||||||
&& cd build \
|
&& cd build \
|
||||||
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
|
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
|
||||||
&& cmake --build . --target install \
|
&& ninja install \
|
||||||
&& rm -rf /tmp/* /var/tmp/*
|
&& rm -rf /tmp/* /var/tmp/*
|
||||||
|
|
||||||
ARG CLANG_BUILD_ANALYZER_VERSION=1.6.0
|
ARG CLANG_BUILD_ANALYZER_VERSION=1.6.0
|
||||||
@@ -46,7 +68,7 @@ RUN wget --progress=dot:giga "https://github.com/aras-p/ClangBuildAnalyzer/archi
|
|||||||
&& mkdir build \
|
&& mkdir build \
|
||||||
&& cd build \
|
&& cd build \
|
||||||
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
|
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
|
||||||
&& cmake --build . --target install \
|
&& ninja install \
|
||||||
&& rm -rf /tmp/* /var/tmp/*
|
&& rm -rf /tmp/* /var/tmp/*
|
||||||
|
|
||||||
ARG GIT_CLIFF_VERSION=2.9.1
|
ARG GIT_CLIFF_VERSION=2.9.1
|
||||||
@@ -61,4 +83,22 @@ RUN wget --progress=dot:giga "https://github.com/cli/cli/releases/download/v${GH
|
|||||||
&& mv gh_${GH_VERSION}_linux_${TARGETARCH}/bin/gh /usr/local/bin/gh \
|
&& mv gh_${GH_VERSION}_linux_${TARGETARCH}/bin/gh /usr/local/bin/gh \
|
||||||
&& rm -rf /tmp/* /var/tmp/*
|
&& rm -rf /tmp/* /var/tmp/*
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||||
|
libgmp-dev \
|
||||||
|
libmpfr-dev \
|
||||||
|
libncurses-dev \
|
||||||
|
make \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
ARG GDB_VERSION=16.3
|
||||||
|
RUN wget --progress=dot:giga "https://sourceware.org/pub/gdb/releases/gdb-${GDB_VERSION}.tar.gz" \
|
||||||
|
&& tar xf "gdb-${GDB_VERSION}.tar.gz" \
|
||||||
|
&& cd "gdb-${GDB_VERSION}" \
|
||||||
|
&& ./configure --prefix=/usr/local \
|
||||||
|
&& make -j "$(nproc)" \
|
||||||
|
&& make install-gdb \
|
||||||
|
&& rm -rf /tmp/* /var/tmp/*
|
||||||
|
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ PROJECT_LOGO = ${SOURCE}/docs/img/xrpl-logo.svg
|
|||||||
PROJECT_NUMBER = ${DOC_CLIO_VERSION}
|
PROJECT_NUMBER = ${DOC_CLIO_VERSION}
|
||||||
PROJECT_BRIEF = The XRP Ledger API server.
|
PROJECT_BRIEF = The XRP Ledger API server.
|
||||||
|
|
||||||
|
DOT_GRAPH_MAX_NODES = 100
|
||||||
|
|
||||||
EXTRACT_ALL = NO
|
EXTRACT_ALL = NO
|
||||||
EXTRACT_PRIVATE = NO
|
EXTRACT_PRIVATE = NO
|
||||||
EXTRACT_PACKAGE = YES
|
EXTRACT_PACKAGE = YES
|
||||||
@@ -32,12 +34,18 @@ SORT_MEMBERS_CTORS_1ST = YES
|
|||||||
GENERATE_TREEVIEW = YES
|
GENERATE_TREEVIEW = YES
|
||||||
DISABLE_INDEX = NO
|
DISABLE_INDEX = NO
|
||||||
FULL_SIDEBAR = NO
|
FULL_SIDEBAR = NO
|
||||||
HTML_HEADER = ${SOURCE}/docs/doxygen-awesome-theme/header.html
|
HTML_HEADER = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/header.html
|
||||||
HTML_EXTRA_STYLESHEET = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome.css \
|
HTML_EXTRA_STYLESHEET = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome.css \
|
||||||
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-sidebar-only.css \
|
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-sidebar-only.css \
|
||||||
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-sidebar-only-darkmode-toggle.css
|
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-sidebar-only-darkmode-toggle.css \
|
||||||
|
${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/custom.css \
|
||||||
|
${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/theme-robot.css \
|
||||||
|
${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/theme-round.css \
|
||||||
|
${SOURCE}/docs/github-corner-disable.css
|
||||||
HTML_EXTRA_FILES = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-darkmode-toggle.js \
|
HTML_EXTRA_FILES = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-darkmode-toggle.js \
|
||||||
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-interactive-toc.js
|
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-fragment-copy-button.js \
|
||||||
|
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-interactive-toc.js \
|
||||||
|
${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/toggle-alternative-theme.js
|
||||||
|
|
||||||
HTML_COLORSTYLE = LIGHT
|
HTML_COLORSTYLE = LIGHT
|
||||||
HTML_COLORSTYLE_HUE = 209
|
HTML_COLORSTYLE_HUE = 209
|
||||||
|
|||||||
@@ -6,16 +6,22 @@
|
|||||||
## Minimum Requirements
|
## Minimum Requirements
|
||||||
|
|
||||||
- [Python 3.7](https://www.python.org/downloads/)
|
- [Python 3.7](https://www.python.org/downloads/)
|
||||||
- [Conan 2.17.0](https://conan.io/downloads.html)
|
- [Conan 2.20.1](https://conan.io/downloads.html)
|
||||||
- [CMake 3.20, <4.0](https://cmake.org/download/)
|
- [CMake 3.20](https://cmake.org/download/)
|
||||||
- [**Optional**] [GCovr](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html): needed for code coverage generation
|
- [**Optional**] [GCovr](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html): needed for code coverage generation
|
||||||
- [**Optional**] [CCache](https://ccache.dev/): speeds up compilation if you are going to compile Clio often
|
- [**Optional**] [CCache](https://ccache.dev/): speeds up compilation if you are going to compile Clio often
|
||||||
|
|
||||||
|
We use our Docker image `ghcr.io/XRPLF/clio-ci` to build `Clio`, see [Building Clio with Docker](#building-clio-with-docker).
|
||||||
|
You can find information about exact compiler versions and tools in the [image's README](https://github.com/XRPLF/clio/blob/develop/docker/ci/README.md).
|
||||||
|
|
||||||
|
The following compiler version are guaranteed to work.
|
||||||
|
Any compiler with lower version may not be able to build Clio:
|
||||||
|
|
||||||
| Compiler | Version |
|
| Compiler | Version |
|
||||||
| ----------- | ------- |
|
| ----------- | ------- |
|
||||||
| GCC | 12.3 |
|
| GCC | 15.2 |
|
||||||
| Clang | 16 |
|
| Clang | 19 |
|
||||||
| Apple Clang | 15 |
|
| Apple Clang | 17 |
|
||||||
|
|
||||||
### Conan Configuration
|
### Conan Configuration
|
||||||
|
|
||||||
@@ -35,7 +41,7 @@ The default profile is the file in `~/.conan2/profiles/default`.
|
|||||||
|
|
||||||
Here are some examples of possible profiles:
|
Here are some examples of possible profiles:
|
||||||
|
|
||||||
**Mac apple-clang 16 example**:
|
**Mac apple-clang 17 example**:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[settings]
|
[settings]
|
||||||
@@ -44,7 +50,7 @@ build_type=Release
|
|||||||
compiler=apple-clang
|
compiler=apple-clang
|
||||||
compiler.cppstd=20
|
compiler.cppstd=20
|
||||||
compiler.libcxx=libc++
|
compiler.libcxx=libc++
|
||||||
compiler.version=16
|
compiler.version=17
|
||||||
os=Macos
|
os=Macos
|
||||||
|
|
||||||
[conf]
|
[conf]
|
||||||
@@ -84,7 +90,7 @@ core.upload:parallel={{os.cpu_count()}}
|
|||||||
Make sure artifactory is setup with Conan.
|
Make sure artifactory is setup with Conan.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
conan remote add --index 0 ripple http://18.143.149.228:8081/artifactory/api/conan/dev
|
conan remote add --index 0 xrplf https://conan.ripplex.io
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you should be able to download the prebuilt dependencies (including `xrpl` package) on supported platforms.
|
Now you should be able to download the prebuilt dependencies (including `xrpl` package) on supported platforms.
|
||||||
@@ -98,79 +104,100 @@ It is implicitly used when running `conan` commands, you don't need to specify i
|
|||||||
|
|
||||||
You have to update this file every time you add a new dependency or change a revision or version of an existing dependency.
|
You have to update this file every time you add a new dependency or change a revision or version of an existing dependency.
|
||||||
|
|
||||||
To do that, run the following command in the repository root:
|
> [!NOTE]
|
||||||
|
> Conan uses local cache by default when creating a lockfile.
|
||||||
|
>
|
||||||
|
> To ensure, that lockfile creation works the same way on all developer machines, you should clear the local cache before creating a new lockfile.
|
||||||
|
|
||||||
|
To create a new lockfile, run the following commands in the repository root:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
conan lock create . -o '&:tests=True' -o '&:benchmark=True'
|
conan remove '*' --confirm
|
||||||
|
rm conan.lock
|
||||||
|
# This ensure that xrplf remote is the first to be consulted
|
||||||
|
conan remote add --force --index 0 xrplf https://conan.ripplex.io
|
||||||
|
conan lock create .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> If some dependencies are exclusive for some OS, you may need to run the last command for them adding `--profile:all <PROFILE>`.
|
||||||
|
|
||||||
## Building Clio
|
## Building Clio
|
||||||
|
|
||||||
Navigate to Clio's root directory and run:
|
1. Navigate to Clio's root directory and run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
# You can also specify profile explicitly by adding `--profile:all <PROFILE_NAME>`
|
```
|
||||||
conan install .. --output-folder . --build missing --settings build_type=Release -o '&:tests=True'
|
|
||||||
# You can also add -GNinja to use Ninja build system instead of Make
|
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release ..
|
|
||||||
cmake --build . --parallel 8 # or without the number if you feel extra adventurous
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!TIP]
|
2. Install dependencies through conan.
|
||||||
> You can omit the `-o '&:tests=True'` if you don't want to build `clio_tests`.
|
|
||||||
|
|
||||||
If successful, `conan install` will find the required packages and `cmake` will do the rest. You should see `clio_server` and `clio_tests` in the `build` directory (the current directory).
|
```sh
|
||||||
|
conan install .. --output-folder . --build missing --settings build_type=Release
|
||||||
|
```
|
||||||
|
|
||||||
> [!TIP]
|
> You can add `--profile:all <PROFILE_NAME>` to choose a specific conan profile.
|
||||||
> To generate a Code Coverage report, include `-o '&:coverage=True'` in the `conan install` command above, along with `-o '&:tests=True'` to enable tests.
|
|
||||||
> After running the `cmake` commands, execute `make clio_tests-ccov`.
|
|
||||||
> The coverage report will be found at `clio_tests-llvm-cov/index.html`.
|
|
||||||
|
|
||||||
<!-- markdownlint-disable-line MD028 -->
|
3. Configure and generate build files with CMake.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||||
|
```
|
||||||
|
|
||||||
|
> You can add `-GNinja` to use the Ninja build system (instead of Make).
|
||||||
|
|
||||||
|
4. Now, you can build all targets or specific ones:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# builds all targets
|
||||||
|
cmake --build . --parallel 8
|
||||||
|
# builds only clio_server target
|
||||||
|
cmake --build . --parallel 8 --target clio_server
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see `clio_server` and `clio_tests` in the current directory.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> If you've built Clio before and the build is now failing, it's likely due to updated dependencies. Try deleting the build folder and then rerunning the Conan and CMake commands mentioned above.
|
> If you've built Clio before and the build is now failing, it's likely due to updated dependencies. Try deleting the build folder and then rerunning the Conan and CMake commands mentioned above.
|
||||||
|
|
||||||
|
### CMake options
|
||||||
|
|
||||||
|
There are several CMake options you can use to customize the build:
|
||||||
|
|
||||||
|
| CMake Option | Default | CMake Target | Description |
|
||||||
|
| --------------------- | ------- | -------------------------------------------------------- | ------------------------------------- |
|
||||||
|
| `-Dcoverage` | OFF | `clio_tests-ccov` | Enables code coverage generation |
|
||||||
|
| `-Dtests` | OFF | `clio_tests` | Enables unit tests |
|
||||||
|
| `-Dintegration_tests` | OFF | `clio_integration_tests` | Enables integration tests |
|
||||||
|
| `-Dbenchmark` | OFF | `clio_benchmark` | Enables benchmark executable |
|
||||||
|
| `-Ddocs` | OFF | `docs` | Enables API documentation generation |
|
||||||
|
| `-Dlint` | OFF | See [#clang-tidy](#using-clang-tidy-for-static-analysis) | Enables `clang-tidy` static analysis |
|
||||||
|
| `-Dsan` | N/A | N/A | Enables Sanitizer (asan, tsan, ubsan) |
|
||||||
|
| `-Dpackage` | OFF | N/A | Creates a debian package |
|
||||||
|
|
||||||
### Generating API docs for Clio
|
### Generating API docs for Clio
|
||||||
|
|
||||||
The API documentation for Clio is generated by [Doxygen](https://www.doxygen.nl/index.html). If you want to generate the API documentation when building Clio, make sure to install Doxygen 1.12.0 on your system.
|
The API documentation for Clio is generated by [Doxygen](https://www.doxygen.nl/index.html). If you want to generate the API documentation when building Clio, make sure to install Doxygen 1.12.0 on your system.
|
||||||
|
|
||||||
To generate the API docs:
|
To generate the API docs, please use CMake option `-Ddocs=ON` as described above and build the `docs` target.
|
||||||
|
|
||||||
1. First, include `-o '&:docs=True'` in the conan install command. For example:
|
To view the generated files, go to `build/docs/html`.
|
||||||
|
Open the `index.html` file in your browser to see the documentation pages.
|
||||||
|
|
||||||
```sh
|

|
||||||
mkdir build && cd build
|
|
||||||
conan install .. --output-folder . --build missing --settings build_type=Release -o '&:tests=True' -o '&:docs=True'
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Once that has completed successfully, run the `cmake` command and add the `--target docs` option:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release ..
|
|
||||||
cmake --build . --parallel 8 --target docs
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Go to `build/docs/html` to view the generated files.
|
|
||||||
|
|
||||||
Open the `index.html` file in your browser to see the documentation pages.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Building Clio with Docker
|
## Building Clio with Docker
|
||||||
|
|
||||||
It is also possible to build Clio using [Docker](https://www.docker.com/) if you don't want to install all the dependencies on your machine.
|
It is also possible to build Clio using [Docker](https://www.docker.com/) if you don't want to install all the dependencies on your machine.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker run -it ghcr.io/xrplf/clio-ci:latest
|
docker run -it ghcr.io/xrplf/clio-ci:384e79cd32f5f6c0ab9be3a1122ead41c5a7e67d
|
||||||
git clone https://github.com/XRPLF/clio
|
git clone https://github.com/XRPLF/clio
|
||||||
mkdir build && cd build
|
cd clio
|
||||||
conan install .. --output-folder . --build missing --settings build_type=Release -o '&:tests=True'
|
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release ..
|
|
||||||
cmake --build . --parallel 8 # or without the number if you feel extra adventurous
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Follow the same steps in the [Building Clio](#building-clio) section. You can use `--profile:all gcc` or `--profile:all clang` with the `conan install` command to choose the desired compiler.
|
||||||
|
|
||||||
## Developing against `rippled` in standalone mode
|
## Developing against `rippled` in standalone mode
|
||||||
|
|
||||||
If you wish to develop against a `rippled` instance running in standalone mode there are a few quirks of both Clio and `rippled` that you need to keep in mind. You must:
|
If you wish to develop against a `rippled` instance running in standalone mode there are a few quirks of both Clio and `rippled` that you need to keep in mind. You must:
|
||||||
@@ -223,10 +250,10 @@ Sometimes, during development, you need to build against a custom version of `li
|
|||||||
## Using `clang-tidy` for static analysis
|
## Using `clang-tidy` for static analysis
|
||||||
|
|
||||||
Clang-tidy can be run by CMake when building the project.
|
Clang-tidy can be run by CMake when building the project.
|
||||||
To achieve this, you just need to provide the option `-o '&:lint=True'` for the `conan install` command:
|
To achieve this, you just need to provide the option `-Dlint=ON` when generating CMake files:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
conan install .. --output-folder . --build missing --settings build_type=Release -o '&:tests=True' -o '&:lint=True' --profile:all clang
|
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -Dlint=ON ..
|
||||||
```
|
```
|
||||||
|
|
||||||
By default CMake will try to find `clang-tidy` automatically in your system.
|
By default CMake will try to find `clang-tidy` automatically in your system.
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
This document provides a list of all available Clio configuration properties in detail.
|
This document provides a list of all available Clio configuration properties in detail.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Dot notation in configuration key names represents nested fields. For example, **database.scylladb** refers to the _scylladb_ field inside the _database_ object. If a key name includes "[]", it indicates that the nested field is an array (e.g., etl_sources.[]).
|
> Dot notation in configuration key names represents nested fields.
|
||||||
|
> For example, **database.scylladb** refers to the _scylladb_ field inside the _database_ object.
|
||||||
|
> If a key name includes "[]", it indicates that the nested field is an array (e.g., etl_sources.[]).
|
||||||
|
|
||||||
## Configuration Details
|
## Configuration Details
|
||||||
|
|
||||||
@@ -155,7 +157,7 @@ This document provides a list of all available Clio configuration properties in
|
|||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: boolean
|
- **Type**: boolean
|
||||||
- **Default value**: `True`
|
- **Default value**: `False`
|
||||||
- **Constraints**: None
|
- **Constraints**: None
|
||||||
- **Description**: If set to `True`, allows Clio to start without any ETL source.
|
- **Description**: If set to `True`, allows Clio to start without any ETL source.
|
||||||
|
|
||||||
@@ -327,11 +329,27 @@ This document provides a list of all available Clio configuration properties in
|
|||||||
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
|
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
|
||||||
- **Description**: Maximum queue size for sending subscription data to clients. This queue buffers data when a client is slow to receive it, ensuring delivery once the client is ready.
|
- **Description**: Maximum queue size for sending subscription data to clients. This queue buffers data when a client is slow to receive it, ensuring delivery once the client is ready.
|
||||||
|
|
||||||
|
### server.proxy.ips.[]
|
||||||
|
|
||||||
|
- **Required**: True
|
||||||
|
- **Type**: string
|
||||||
|
- **Default value**: None
|
||||||
|
- **Constraints**: None
|
||||||
|
- **Description**: List of proxy ip addresses. When Clio receives a request from proxy it will use `Forwarded` value (if any) as client ip. When this option is used together with `server.proxy.tokens` Clio will identify proxy by ip or by token.
|
||||||
|
|
||||||
|
### server.proxy.tokens.[]
|
||||||
|
|
||||||
|
- **Required**: True
|
||||||
|
- **Type**: string
|
||||||
|
- **Default value**: None
|
||||||
|
- **Constraints**: None
|
||||||
|
- **Description**: List of tokens in identifying request as a request from proxy. Token should be provided in `X-Proxy-Token` header, e.g. `X-Proxy-Token: <very_secret_token>'. When Clio receives a request from proxy it will use 'Forwarded` value (if any) to get client ip. When this option is used together with 'server.proxy.ips' Clio will identify proxy by ip or by token.
|
||||||
|
|
||||||
### prometheus.enabled
|
### prometheus.enabled
|
||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: boolean
|
- **Type**: boolean
|
||||||
- **Default value**: `False`
|
- **Default value**: `True`
|
||||||
- **Constraints**: None
|
- **Constraints**: None
|
||||||
- **Description**: Enables or disables Prometheus metrics.
|
- **Description**: Enables or disables Prometheus metrics.
|
||||||
|
|
||||||
@@ -339,7 +357,7 @@ This document provides a list of all available Clio configuration properties in
|
|||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: boolean
|
- **Type**: boolean
|
||||||
- **Default value**: `False`
|
- **Default value**: `True`
|
||||||
- **Constraints**: None
|
- **Constraints**: None
|
||||||
- **Description**: Enables or disables compression of Prometheus responses.
|
- **Description**: Enables or disables compression of Prometheus responses.
|
||||||
|
|
||||||
@@ -415,7 +433,7 @@ This document provides a list of all available Clio configuration properties in
|
|||||||
- **Constraints**: The value must be one of the following: `sync`, `async`, `none`.
|
- **Constraints**: The value must be one of the following: `sync`, `async`, `none`.
|
||||||
- **Description**: The strategy used for Cache loading.
|
- **Description**: The strategy used for Cache loading.
|
||||||
|
|
||||||
### log_channels.[].channel
|
### log.channels.[].channel
|
||||||
|
|
||||||
- **Required**: False
|
- **Required**: False
|
||||||
- **Type**: string
|
- **Type**: string
|
||||||
@@ -423,39 +441,63 @@ This document provides a list of all available Clio configuration properties in
|
|||||||
- **Constraints**: The value must be one of the following: `General`, `WebServer`, `Backend`, `RPC`, `ETL`, `Subscriptions`, `Performance`, `Migration`.
|
- **Constraints**: The value must be one of the following: `General`, `WebServer`, `Backend`, `RPC`, `ETL`, `Subscriptions`, `Performance`, `Migration`.
|
||||||
- **Description**: The name of the log channel.
|
- **Description**: The name of the log channel.
|
||||||
|
|
||||||
### log_channels.[].log_level
|
### log.channels.[].level
|
||||||
|
|
||||||
- **Required**: False
|
- **Required**: False
|
||||||
- **Type**: string
|
- **Type**: string
|
||||||
- **Default value**: None
|
- **Default value**: None
|
||||||
- **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`, `count`.
|
- **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`.
|
||||||
- **Description**: The log level for the specific log channel.
|
- **Description**: The log level for the specific log channel.
|
||||||
|
|
||||||
### log_level
|
### log.level
|
||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: string
|
- **Type**: string
|
||||||
- **Default value**: `info`
|
- **Default value**: `info`
|
||||||
- **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`, `count`.
|
- **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`.
|
||||||
- **Description**: The general logging level of Clio. This level is applied to all log channels that do not have an explicitly defined logging level.
|
- **Description**: The general logging level of Clio. This level is applied to all log channels that do not have an explicitly defined logging level.
|
||||||
|
|
||||||
### log_format
|
### log.format
|
||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: string
|
- **Type**: string
|
||||||
- **Default value**: `%TimeStamp% (%SourceLocation%) [%ThreadID%] %Channel%:%Severity% %Message%`
|
- **Default value**: `%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v`
|
||||||
- **Constraints**: None
|
- **Constraints**: None
|
||||||
- **Description**: The format string for log messages. The format is described here: <https://www.boost.org/doc/libs/1_83_0/libs/log/doc/html/log/tutorial/formatters.html>.
|
- **Description**: The format string for log messages using spdlog format patterns.
|
||||||
|
|
||||||
### log_to_console
|
Each of the variables expands like so:
|
||||||
|
|
||||||
|
- `%Y-%m-%d %H:%M:%S.%f`: The full date and time of the log entry with microsecond precision
|
||||||
|
- `%^`: Start color range
|
||||||
|
- `%3!l`: The severity (aka log level) the entry was sent at stripped to 3 characters
|
||||||
|
- `%n`: The logger name (channel) that this log entry was sent to
|
||||||
|
- `%$`: End color range
|
||||||
|
- `%v`: The actual log message
|
||||||
|
|
||||||
|
Some additional variables that might be useful:
|
||||||
|
|
||||||
|
- `%@`: A partial path to the C++ file and the line number in the said file (`src/file/path:linenumber`)
|
||||||
|
- `%t`: The ID of the thread the log entry is written from
|
||||||
|
|
||||||
|
Documentation can be found at: <https://github.com/gabime/spdlog/wiki/Custom-formatting>.
|
||||||
|
|
||||||
|
### log.is_async
|
||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: boolean
|
- **Type**: boolean
|
||||||
- **Default value**: `True`
|
- **Default value**: `True`
|
||||||
- **Constraints**: None
|
- **Constraints**: None
|
||||||
|
- **Description**: Whether spdlog is asynchronous or not.
|
||||||
|
|
||||||
|
### log.enable_console
|
||||||
|
|
||||||
|
- **Required**: True
|
||||||
|
- **Type**: boolean
|
||||||
|
- **Default value**: `False`
|
||||||
|
- **Constraints**: None
|
||||||
- **Description**: Enables or disables logging to the console.
|
- **Description**: Enables or disables logging to the console.
|
||||||
|
|
||||||
### log_directory
|
### log.directory
|
||||||
|
|
||||||
- **Required**: False
|
- **Required**: False
|
||||||
- **Type**: string
|
- **Type**: string
|
||||||
@@ -463,7 +505,7 @@ This document provides a list of all available Clio configuration properties in
|
|||||||
- **Constraints**: None
|
- **Constraints**: None
|
||||||
- **Description**: The directory path for the log files.
|
- **Description**: The directory path for the log files.
|
||||||
|
|
||||||
### log_rotation_size
|
### log.rotation_size
|
||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: int
|
- **Type**: int
|
||||||
@@ -471,23 +513,15 @@ This document provides a list of all available Clio configuration properties in
|
|||||||
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
|
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
|
||||||
- **Description**: The log rotation size in megabytes. When the log file reaches this particular size, a new log file starts.
|
- **Description**: The log rotation size in megabytes. When the log file reaches this particular size, a new log file starts.
|
||||||
|
|
||||||
### log_directory_max_size
|
### log.directory_max_files
|
||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: int
|
- **Type**: int
|
||||||
- **Default value**: `51200`
|
- **Default value**: `25`
|
||||||
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
|
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
|
||||||
- **Description**: The maximum size of the log directory in megabytes.
|
- **Description**: The maximum number of log files in the directory.
|
||||||
|
|
||||||
### log_rotation_hour_interval
|
### log.tag_style
|
||||||
|
|
||||||
- **Required**: True
|
|
||||||
- **Type**: int
|
|
||||||
- **Default value**: `12`
|
|
||||||
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
|
|
||||||
- **Description**: Represents the interval (in hours) for log rotation. If the current log file reaches this value in logging, a new log file starts.
|
|
||||||
|
|
||||||
### log_tag_style
|
|
||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: string
|
- **Type**: string
|
||||||
@@ -507,7 +541,7 @@ This document provides a list of all available Clio configuration properties in
|
|||||||
|
|
||||||
- **Required**: True
|
- **Required**: True
|
||||||
- **Type**: boolean
|
- **Type**: boolean
|
||||||
- **Default value**: `True`
|
- **Default value**: `False`
|
||||||
- **Constraints**: None
|
- **Constraints**: None
|
||||||
- **Description**: Indicates if the server is allowed to write data to the database.
|
- **Description**: Indicates if the server is allowed to write data to the database.
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
Clio needs access to a `rippled` server in order to work. The following configurations are required for Clio and `rippled` to communicate:
|
Clio needs access to a `rippled` server in order to work. The following configurations are required for Clio and `rippled` to communicate:
|
||||||
|
|
||||||
1. In the Clio config file, provide the following:
|
1. In the Clio config file, provide the following:
|
||||||
|
|
||||||
- The IP of the `rippled` server
|
- The IP of the `rippled` server
|
||||||
|
|
||||||
- The port on which `rippled` is accepting unencrypted WebSocket connections
|
- The port on which `rippled` is accepting unencrypted WebSocket connections
|
||||||
@@ -13,7 +12,6 @@ Clio needs access to a `rippled` server in order to work. The following configur
|
|||||||
- The port on which `rippled` is handling gRPC requests
|
- The port on which `rippled` is handling gRPC requests
|
||||||
|
|
||||||
2. In the `rippled` config file, you need to open:
|
2. In the `rippled` config file, you need to open:
|
||||||
|
|
||||||
- A port to accept unencrypted WebSocket connections
|
- A port to accept unencrypted WebSocket connections
|
||||||
|
|
||||||
- A port to handle gRPC requests, with the IP(s) of Clio specified in the `secure_gateway` entry
|
- A port to handle gRPC requests, with the IP(s) of Clio specified in the `secure_gateway` entry
|
||||||
@@ -90,13 +88,15 @@ Exactly equal password gains admin rights for the request or a websocket connect
|
|||||||
Clio can cache requests to ETL sources to reduce the load on the ETL source.
|
Clio can cache requests to ETL sources to reduce the load on the ETL source.
|
||||||
Only following commands are cached: `server_info`, `server_state`, `server_definitions`, `fee`, `ledger_closed`.
|
Only following commands are cached: `server_info`, `server_state`, `server_definitions`, `fee`, `ledger_closed`.
|
||||||
By default the forwarding cache is off.
|
By default the forwarding cache is off.
|
||||||
To enable the caching for a source, `forwarding_cache_timeout` value should be added to the configuration file, e.g.:
|
To enable the caching for a source, `forwarding.cache_timeout` value should be added to the configuration file, e.g.:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"forwarding_cache_timeout": 0.250,
|
"forwarding": {
|
||||||
|
"cache_timeout": 0.250,
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`forwarding_cache_timeout` defines for how long (in seconds) a cache entry will be valid after being placed into the cache.
|
`forwarding.cache_timeout` defines for how long (in seconds) a cache entry will be valid after being placed into the cache.
|
||||||
Zero value turns off the cache feature.
|
Zero value turns off the cache feature.
|
||||||
|
|
||||||
## Graceful shutdown (not fully implemented yet)
|
## Graceful shutdown (not fully implemented yet)
|
||||||
|
|||||||
@@ -1,29 +1,10 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
/**
|
/**
|
||||||
|
|
||||||
Doxygen Awesome
|
Doxygen Awesome
|
||||||
https://github.com/jothepro/doxygen-awesome-css
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
MIT License
|
Copyright (c) 2021 - 2025 jothepro
|
||||||
|
|
||||||
Copyright (c) 2021 - 2023 jothepro
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
/**
|
||||||
|
|
||||||
|
Doxygen Awesome
|
||||||
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
|
Copyright (c) 2022 - 2025 jothepro
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DoxygenAwesomeFragmentCopyButton extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.onclick=this.copyContent
|
||||||
|
}
|
||||||
|
static title = "Copy to clipboard"
|
||||||
|
static copyIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M23.04,10.322c0,-2.582 -2.096,-4.678 -4.678,-4.678l-6.918,-0c-2.582,-0 -4.678,2.096 -4.678,4.678c0,-0 0,8.04 0,8.04c0,2.582 2.096,4.678 4.678,4.678c0,-0 6.918,-0 6.918,-0c2.582,-0 4.678,-2.096 4.678,-4.678c0,-0 0,-8.04 0,-8.04Zm-2.438,-0l-0,8.04c-0,1.236 -1.004,2.24 -2.24,2.24l-6.918,-0c-1.236,-0 -2.239,-1.004 -2.239,-2.24l-0,-8.04c-0,-1.236 1.003,-2.24 2.239,-2.24c0,0 6.918,0 6.918,0c1.236,0 2.24,1.004 2.24,2.24Z"/><path d="M5.327,16.748c-0,0.358 -0.291,0.648 -0.649,0.648c0,0 0,0 0,0c-2.582,0 -4.678,-2.096 -4.678,-4.678c0,0 0,-8.04 0,-8.04c0,-2.582 2.096,-4.678 4.678,-4.678l6.918,0c2.168,0 3.994,1.478 4.523,3.481c0.038,0.149 0.005,0.306 -0.09,0.428c-0.094,0.121 -0.239,0.191 -0.392,0.191c-0.451,0.005 -1.057,0.005 -1.457,0.005c-0.238,0 -0.455,-0.14 -0.553,-0.357c-0.348,-0.773 -1.128,-1.31 -2.031,-1.31c-0,0 -6.918,0 -6.918,0c-1.236,0 -2.24,1.004 -2.24,2.24l0,8.04c0,1.236 1.004,2.24 2.24,2.24l0,-0c0.358,-0 0.649,0.29 0.649,0.648c-0,0.353 -0,0.789 -0,1.142Z" style="fill-opacity:0.6;"/></svg>`
|
||||||
|
static successIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M8.084,16.111c-0.09,0.09 -0.212,0.141 -0.34,0.141c-0.127,-0 -0.249,-0.051 -0.339,-0.141c-0.746,-0.746 -2.538,-2.538 -3.525,-3.525c-0.375,-0.375 -0.983,-0.375 -1.357,0c-0.178,0.178 -0.369,0.369 -0.547,0.547c-0.375,0.375 -0.375,0.982 -0,1.357c1.135,1.135 3.422,3.422 4.75,4.751c0.27,0.27 0.637,0.421 1.018,0.421c0.382,0 0.749,-0.151 1.019,-0.421c2.731,-2.732 10.166,-10.167 12.454,-12.455c0.375,-0.375 0.375,-0.982 -0,-1.357c-0.178,-0.178 -0.369,-0.369 -0.547,-0.547c-0.375,-0.375 -0.982,-0.375 -1.357,0c-2.273,2.273 -9.567,9.567 -11.229,11.229Z"/></svg>`
|
||||||
|
static successDuration = 980
|
||||||
|
static init() {
|
||||||
|
$(function() {
|
||||||
|
$(document).ready(function() {
|
||||||
|
if(navigator.clipboard) {
|
||||||
|
const fragments = document.getElementsByClassName("fragment")
|
||||||
|
for(const fragment of fragments) {
|
||||||
|
const fragmentWrapper = document.createElement("div")
|
||||||
|
fragmentWrapper.className = "doxygen-awesome-fragment-wrapper"
|
||||||
|
const fragmentCopyButton = document.createElement("doxygen-awesome-fragment-copy-button")
|
||||||
|
fragmentCopyButton.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon
|
||||||
|
fragmentCopyButton.title = DoxygenAwesomeFragmentCopyButton.title
|
||||||
|
|
||||||
|
fragment.parentNode.replaceChild(fragmentWrapper, fragment)
|
||||||
|
fragmentWrapper.appendChild(fragment)
|
||||||
|
fragmentWrapper.appendChild(fragmentCopyButton)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
copyContent() {
|
||||||
|
const content = this.previousSibling.cloneNode(true)
|
||||||
|
// filter out line number from file listings
|
||||||
|
content.querySelectorAll(".lineno, .ttc").forEach((node) => {
|
||||||
|
node.remove()
|
||||||
|
})
|
||||||
|
let textContent = content.textContent
|
||||||
|
// remove trailing newlines that appear in file listings
|
||||||
|
let numberOfTrailingNewlines = 0
|
||||||
|
while(textContent.charAt(textContent.length - (numberOfTrailingNewlines + 1)) == '\n') {
|
||||||
|
numberOfTrailingNewlines++;
|
||||||
|
}
|
||||||
|
textContent = textContent.substring(0, textContent.length - numberOfTrailingNewlines)
|
||||||
|
navigator.clipboard.writeText(textContent);
|
||||||
|
this.classList.add("success")
|
||||||
|
this.innerHTML = DoxygenAwesomeFragmentCopyButton.successIcon
|
||||||
|
window.setTimeout(() => {
|
||||||
|
this.classList.remove("success")
|
||||||
|
this.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon
|
||||||
|
}, DoxygenAwesomeFragmentCopyButton.successDuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("doxygen-awesome-fragment-copy-button", DoxygenAwesomeFragmentCopyButton)
|
||||||
@@ -1,29 +1,10 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
/**
|
/**
|
||||||
|
|
||||||
Doxygen Awesome
|
Doxygen Awesome
|
||||||
https://github.com/jothepro/doxygen-awesome-css
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
MIT License
|
Copyright (c) 2022 - 2025 jothepro
|
||||||
|
|
||||||
Copyright (c) 2022 - 2023 jothepro
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -55,9 +36,7 @@ class DoxygenAwesomeInteractiveToc {
|
|||||||
headerNode: document.getElementById(id)
|
headerNode: document.getElementById(id)
|
||||||
})
|
})
|
||||||
|
|
||||||
document.getElementById("doc-content")?.addEventListener("scroll", () => {
|
document.getElementById("doc-content")?.addEventListener("scroll",this.throttle(DoxygenAwesomeInteractiveToc.update, 100))
|
||||||
DoxygenAwesomeInteractiveToc.update()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
DoxygenAwesomeInteractiveToc.update()
|
DoxygenAwesomeInteractiveToc.update()
|
||||||
}
|
}
|
||||||
@@ -78,4 +57,16 @@ class DoxygenAwesomeInteractiveToc {
|
|||||||
active?.classList.add("active")
|
active?.classList.add("active")
|
||||||
active?.classList.remove("aboveActive")
|
active?.classList.remove("aboveActive")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
static throttle(func, delay) {
|
||||||
|
let lastCall = 0;
|
||||||
|
return function (...args) {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
if (now - lastCall < delay) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastCall = now;
|
||||||
|
return setTimeout(() => {func(...args)}, delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,30 +1,10 @@
|
|||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
/**
|
/**
|
||||||
|
|
||||||
Doxygen Awesome
|
Doxygen Awesome
|
||||||
https://github.com/jothepro/doxygen-awesome-css
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
MIT License
|
Copyright (c) 2021 - 2025 jothepro
|
||||||
|
|
||||||
Copyright (c) 2021 - 2023 jothepro
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,10 @@
|
|||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
/**
|
/**
|
||||||
|
|
||||||
Doxygen Awesome
|
Doxygen Awesome
|
||||||
https://github.com/jothepro/doxygen-awesome-css
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
MIT License
|
Copyright (c) 2021 - 2025 jothepro
|
||||||
|
|
||||||
Copyright (c) 2021 - 2023 jothepro
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -60,10 +41,6 @@ html {
|
|||||||
height: calc(100vh - var(--top-height)) !important;
|
height: calc(100vh - var(--top-height)) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-tree {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#top {
|
#top {
|
||||||
display: block;
|
display: block;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
@@ -73,22 +50,24 @@ html {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: var(--side-nav-background);
|
background: var(--side-nav-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
#main-nav {
|
#main-nav {
|
||||||
float: left;
|
float: left;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-resizable-handle {
|
.ui-resizable-handle {
|
||||||
cursor: default;
|
display: none;
|
||||||
width: 1px !important;
|
}
|
||||||
background: var(--separator-color);
|
|
||||||
box-shadow: 0 calc(-2 * var(--top-height)) 0 0 var(--separator-color);
|
.ui-resizable-e {
|
||||||
|
width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-path {
|
#nav-path {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 0;
|
right: 0;
|
||||||
left: var(--side-nav-fixed-width);
|
left: calc(var(--side-nav-fixed-width) + 1px);
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
@@ -113,4 +92,14 @@ html {
|
|||||||
left: var(--spacing-medium) !important;
|
left: var(--spacing-medium) !important;
|
||||||
right: auto;
|
right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#nav-sync {
|
||||||
|
bottom: 4px;
|
||||||
|
right: auto;
|
||||||
|
left: 300px;
|
||||||
|
width: 35px;
|
||||||
|
top: auto !important;
|
||||||
|
user-select: none;
|
||||||
|
position: fixed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,10 @@
|
|||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
/**
|
/**
|
||||||
|
|
||||||
Doxygen Awesome
|
Doxygen Awesome
|
||||||
https://github.com/jothepro/doxygen-awesome-css
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
MIT License
|
Copyright (c) 2021 - 2025 jothepro
|
||||||
|
|
||||||
Copyright (c) 2021 - 2023 jothepro
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -32,6 +13,9 @@ html {
|
|||||||
--primary-color: #1779c4;
|
--primary-color: #1779c4;
|
||||||
--primary-dark-color: #335c80;
|
--primary-dark-color: #335c80;
|
||||||
--primary-light-color: #70b1e9;
|
--primary-light-color: #70b1e9;
|
||||||
|
--on-primary-color: #ffffff;
|
||||||
|
|
||||||
|
--link-color: var(--primary-color);
|
||||||
|
|
||||||
/* page base colors */
|
/* page base colors */
|
||||||
--page-background-color: #ffffff;
|
--page-background-color: #ffffff;
|
||||||
@@ -42,14 +26,15 @@ html {
|
|||||||
--separator-color: #dedede;
|
--separator-color: #dedede;
|
||||||
|
|
||||||
/* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */
|
/* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */
|
||||||
--border-radius-large: 8px;
|
--border-radius-large: 10px;
|
||||||
--border-radius-small: 4px;
|
--border-radius-small: 5px;
|
||||||
--border-radius-medium: 6px;
|
--border-radius-medium: 8px;
|
||||||
|
|
||||||
/* default spacings. Most components reference these values for spacing, to provide uniform spacing on the page. */
|
/* default spacings. Most components reference these values for spacing, to provide uniform spacing on the page. */
|
||||||
--spacing-small: 5px;
|
--spacing-small: 5px;
|
||||||
--spacing-medium: 10px;
|
--spacing-medium: 10px;
|
||||||
--spacing-large: 16px;
|
--spacing-large: 16px;
|
||||||
|
--spacing-xlarge: 20px;
|
||||||
|
|
||||||
/* default box shadow used for raising an element above the normal content. Used in dropdowns, search result, ... */
|
/* default box shadow used for raising an element above the normal content. Used in dropdowns, search result, ... */
|
||||||
--box-shadow: 0 2px 8px 0 rgba(0,0,0,.075);
|
--box-shadow: 0 2px 8px 0 rgba(0,0,0,.075);
|
||||||
@@ -113,7 +98,7 @@ html {
|
|||||||
*/
|
*/
|
||||||
--menu-display: block;
|
--menu-display: block;
|
||||||
|
|
||||||
--menu-focus-foreground: var(--page-background-color);
|
--menu-focus-foreground: var(--on-primary-color);
|
||||||
--menu-focus-background: var(--primary-color);
|
--menu-focus-background: var(--primary-color);
|
||||||
--menu-selected-background: rgba(0,0,0,.05);
|
--menu-selected-background: rgba(0,0,0,.05);
|
||||||
|
|
||||||
@@ -310,10 +295,11 @@ body {
|
|||||||
font-size: var(--page-font-size);
|
font-size: var(--page-font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
body, table, div, p, dl, #nav-tree .label, .title,
|
body, table, div, p, dl, #nav-tree .label, #nav-tree a, .title,
|
||||||
.sm-dox a, .sm-dox a:hover, .sm-dox a:focus, #projectname,
|
.sm-dox a, .sm-dox a:hover, .sm-dox a:focus, #projectname,
|
||||||
.SelectItem, #MSearchField, .navpath li.navelem a,
|
.SelectItem, #MSearchField, .navpath li.navelem a,
|
||||||
.navpath li.navelem a:hover, p.reference, p.definition, div.toc li, div.toc h3 {
|
.navpath li.navelem a:hover, p.reference, p.definition, div.toc li, div.toc h3,
|
||||||
|
#page-nav ul.page-outline li a {
|
||||||
font-family: var(--font-family);
|
font-family: var(--font-family);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,8 +318,13 @@ p.reference, p.definition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a:link, a:visited, a:hover, a:focus, a:active {
|
a:link, a:visited, a:hover, a:focus, a:active {
|
||||||
color: var(--primary-color) !important;
|
color: var(--link-color) !important;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.anchor {
|
a.anchor {
|
||||||
@@ -348,6 +339,8 @@ a.anchor {
|
|||||||
#top {
|
#top {
|
||||||
background: var(--header-background);
|
background: var(--header-background);
|
||||||
border-bottom: 1px solid var(--separator-color);
|
border-bottom: 1px solid var(--separator-color);
|
||||||
|
position: relative;
|
||||||
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 768px) {
|
@media screen and (min-width: 768px) {
|
||||||
@@ -362,6 +355,7 @@ a.anchor {
|
|||||||
#main-nav {
|
#main-nav {
|
||||||
flex-grow: 5;
|
flex-grow: 5;
|
||||||
padding: var(--spacing-small) var(--spacing-medium);
|
padding: var(--spacing-small) var(--spacing-medium);
|
||||||
|
border-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#titlearea {
|
#titlearea {
|
||||||
@@ -441,19 +435,36 @@ a.anchor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sm-dox a span.sub-arrow {
|
.sm-dox a span.sub-arrow {
|
||||||
border-color: var(--header-foreground) transparent transparent transparent;
|
top: 15px;
|
||||||
|
right: 10px;
|
||||||
|
box-sizing: content-box;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
display: inline-block;
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
border-width: 0;
|
||||||
|
border-right: 2px solid var(--header-foreground);
|
||||||
|
border-bottom: 2px solid var(--header-foreground);
|
||||||
|
background: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm-dox a:hover span.sub-arrow {
|
.sm-dox a:hover span.sub-arrow {
|
||||||
border-color: var(--menu-focus-foreground) transparent transparent transparent;
|
border-color: var(--menu-focus-foreground);
|
||||||
|
background: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm-dox ul a span.sub-arrow {
|
.sm-dox ul a span.sub-arrow {
|
||||||
border-color: transparent transparent transparent var(--page-foreground-color);
|
transform: rotate(-45deg);
|
||||||
|
border-width: 0;
|
||||||
|
border-right: 2px solid var(--header-foreground);
|
||||||
|
border-bottom: 2px solid var(--header-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm-dox ul a:hover span.sub-arrow {
|
.sm-dox ul a:hover span.sub-arrow {
|
||||||
border-color: transparent transparent transparent var(--menu-focus-foreground);
|
border-color: var(--menu-focus-foreground);
|
||||||
|
background: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,7 +491,7 @@ a.anchor {
|
|||||||
|
|
||||||
.sm-dox ul a {
|
.sm-dox ul a {
|
||||||
color: var(--page-foreground-color) !important;
|
color: var(--page-foreground-color) !important;
|
||||||
background: var(--page-background-color);
|
background: none;
|
||||||
font-size: var(--navigation-font-size);
|
font-size: var(--navigation-font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,6 +563,13 @@ a.anchor {
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.sm-dox li {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* until Doxygen 1.9.4 */
|
/* until Doxygen 1.9.4 */
|
||||||
@@ -573,6 +591,17 @@ a.anchor {
|
|||||||
padding-left: 0
|
padding-left: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Doxygen 1.14.0 */
|
||||||
|
.search-icon::before {
|
||||||
|
background: none;
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-icon::after {
|
||||||
|
background: none;
|
||||||
|
top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.SelectionMark {
|
.SelectionMark {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
@@ -776,12 +805,15 @@ html.dark-mode iframe#MSearchResults {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#side-nav {
|
#side-nav {
|
||||||
padding: 0 !important;
|
|
||||||
background: var(--side-nav-background);
|
|
||||||
min-width: 8px;
|
min-width: 8px;
|
||||||
max-width: 50vw;
|
max-width: 50vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#nav-tree, #top {
|
||||||
|
border-right: 1px solid var(--separator-color);
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 767px) {
|
@media screen and (max-width: 767px) {
|
||||||
#side-nav {
|
#side-nav {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -790,34 +822,95 @@ html.dark-mode iframe#MSearchResults {
|
|||||||
#doc-content {
|
#doc-content {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#top {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-tree {
|
#nav-tree {
|
||||||
background: transparent;
|
background: var(--side-nav-background);
|
||||||
margin-right: 1px;
|
margin-right: -1px;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-tree .label {
|
#nav-tree .label {
|
||||||
font-size: var(--navigation-font-size);
|
font-size: var(--navigation-font-size);
|
||||||
|
line-height: var(--tree-item-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-tree span.label a:hover {
|
||||||
|
background: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-tree .item {
|
#nav-tree .item {
|
||||||
height: var(--tree-item-height);
|
height: var(--tree-item-height);
|
||||||
line-height: var(--tree-item-height);
|
line-height: var(--tree-item-height);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-tree-contents {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-menu > li:last-child {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-tree .item > a:focus {
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-sync {
|
#nav-sync {
|
||||||
bottom: 12px;
|
bottom: var(--spacing-medium);
|
||||||
right: 12px;
|
right: var(--spacing-medium) !important;
|
||||||
top: auto !important;
|
top: auto !important;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.nav-sync-icon {
|
||||||
|
border: 1px solid var(--separator-color);
|
||||||
|
border-radius: var(--border-radius-medium);
|
||||||
|
background: var(--page-background-color);
|
||||||
|
width: 30px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.nav-sync-icon:hover {
|
||||||
|
background: var(--page-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
span.sync-icon-left, div.nav-sync-icon:hover span.sync-icon-left {
|
||||||
|
border-left: 2px solid var(--primary-color);
|
||||||
|
border-top: 2px solid var(--primary-color);
|
||||||
|
top: 5px;
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
span.sync-icon-right, div.nav-sync-icon:hover span.sync-icon-right {
|
||||||
|
border-right: 2px solid var(--primary-color);
|
||||||
|
border-bottom: 2px solid var(--primary-color);
|
||||||
|
top: 5px;
|
||||||
|
left: initial;
|
||||||
|
right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.nav-sync-icon.active::after, div.nav-sync-icon.active:hover::after {
|
||||||
|
border-top: 2px solid var(--primary-color);
|
||||||
|
top: 9px;
|
||||||
|
left: 6px;
|
||||||
|
width: 19px;
|
||||||
|
}
|
||||||
|
|
||||||
#nav-tree .selected {
|
#nav-tree .selected {
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
background-image: none;
|
background-image: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
color: var(--primary-color) !important;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-tree .selected::after {
|
#nav-tree .selected::after {
|
||||||
@@ -843,9 +936,27 @@ html.dark-mode iframe#MSearchResults {
|
|||||||
|
|
||||||
#nav-tree .arrow {
|
#nav-tree .arrow {
|
||||||
opacity: var(--side-nav-arrow-opacity);
|
opacity: var(--side-nav-arrow-opacity);
|
||||||
|
background: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow {
|
#nav-tree span.arrowhead {
|
||||||
|
margin: 0 0 1px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.arrowhead {
|
||||||
|
border-color: var(--primary-light-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected span.arrowhead {
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-tree ul li:first-child > div > a {
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents .arrow {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 45%;
|
font-size: 45%;
|
||||||
@@ -853,7 +964,7 @@ html.dark-mode iframe#MSearchResults {
|
|||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
font-family: serif;
|
font-family: serif;
|
||||||
height: auto;
|
height: auto;
|
||||||
text-align: right;
|
padding-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-tree div.item:hover .arrow, #nav-tree a:focus .arrow {
|
#nav-tree div.item:hover .arrow, #nav-tree a:focus .arrow {
|
||||||
@@ -867,9 +978,11 @@ html.dark-mode iframe#MSearchResults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ui-resizable-e {
|
.ui-resizable-e {
|
||||||
width: 4px;
|
background: none;
|
||||||
background: transparent;
|
}
|
||||||
box-shadow: inset -1px 0 0 0 var(--separator-color);
|
|
||||||
|
.ui-resizable-e:hover {
|
||||||
|
background: var(--separator-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -878,7 +991,7 @@ html.dark-mode iframe#MSearchResults {
|
|||||||
|
|
||||||
div.header {
|
div.header {
|
||||||
border-bottom: 1px solid var(--separator-color);
|
border-bottom: 1px solid var(--separator-color);
|
||||||
background-color: var(--page-background-color);
|
background: none;
|
||||||
background-image: none;
|
background-image: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,7 +1030,7 @@ div.headertitle {
|
|||||||
div.header .title {
|
div.header .title {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 225%;
|
font-size: 225%;
|
||||||
padding: var(--spacing-medium) var(--spacing-large);
|
padding: var(--spacing-medium) var(--spacing-xlarge);
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -934,9 +1047,10 @@ td.memSeparator {
|
|||||||
|
|
||||||
span.mlabel {
|
span.mlabel {
|
||||||
background: var(--primary-color);
|
background: var(--primary-color);
|
||||||
|
color: var(--on-primary-color);
|
||||||
border: none;
|
border: none;
|
||||||
padding: 4px 9px;
|
padding: 4px 9px;
|
||||||
border-radius: 12px;
|
border-radius: var(--border-radius-large);
|
||||||
margin-right: var(--spacing-medium);
|
margin-right: var(--spacing-medium);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -945,7 +1059,7 @@ span.mlabel:last-of-type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.contents {
|
div.contents {
|
||||||
padding: 0 var(--spacing-large);
|
padding: 0 var(--spacing-xlarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.contents p, div.contents li {
|
div.contents p, div.contents li {
|
||||||
@@ -956,6 +1070,16 @@ div.contents div.dyncontent {
|
|||||||
margin: var(--spacing-medium) 0;
|
margin: var(--spacing-medium) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
div.contents {
|
||||||
|
padding: 0 var(--spacing-large);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.header .title {
|
||||||
|
padding: var(--spacing-medium) var(--spacing-large);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
html:not(.light-mode) div.contents div.dyncontent img,
|
html:not(.light-mode) div.contents div.dyncontent img,
|
||||||
html:not(.light-mode) div.contents center img,
|
html:not(.light-mode) div.contents center img,
|
||||||
@@ -979,7 +1103,7 @@ html.dark-mode div.contents .dotgraph iframe
|
|||||||
filter: brightness(89%) hue-rotate(180deg) invert();
|
filter: brightness(89%) hue-rotate(180deg) invert();
|
||||||
}
|
}
|
||||||
|
|
||||||
h2.groupheader {
|
td h2.groupheader, h2.groupheader {
|
||||||
border-bottom: 0px;
|
border-bottom: 0px;
|
||||||
color: var(--page-foreground-color);
|
color: var(--page-foreground-color);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
@@ -1040,7 +1164,7 @@ blockquote::after {
|
|||||||
blockquote p {
|
blockquote p {
|
||||||
margin: var(--spacing-small) 0 var(--spacing-medium) 0;
|
margin: var(--spacing-small) 0 var(--spacing-medium) 0;
|
||||||
}
|
}
|
||||||
.paramname {
|
.paramname, .paramname em {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--primary-dark-color);
|
color: var(--primary-dark-color);
|
||||||
}
|
}
|
||||||
@@ -1090,7 +1214,7 @@ div.contents .toc {
|
|||||||
border: 0;
|
border: 0;
|
||||||
border-left: 1px solid var(--separator-color);
|
border-left: 1px solid var(--separator-color);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background-color: transparent;
|
background-color: var(--page-background-color);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: var(--toc-sticky-top);
|
top: var(--toc-sticky-top);
|
||||||
@@ -1198,24 +1322,115 @@ div.toc li a.aboveActive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Page Outline (Doxygen >= 1.14.0)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#page-nav {
|
||||||
|
background: var(--page-background-color);
|
||||||
|
border-left: 1px solid var(--separator-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav #page-nav-resize-handle {
|
||||||
|
background: var(--separator-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav #page-nav-resize-handle::after {
|
||||||
|
border-left: 1px solid var(--primary-color);
|
||||||
|
border-right: 1px solid var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav #page-nav-tree #page-nav-contents {
|
||||||
|
top: var(--spacing-large);
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline li a {
|
||||||
|
font-size: var(--toc-font-size) !important;
|
||||||
|
color: var(--page-secondary-foreground-color) !important;
|
||||||
|
display: inline-block;
|
||||||
|
line-height: calc(2 * var(--toc-font-size));
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline li a a.anchorlink {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline li.vis ~ * a {
|
||||||
|
color: var(--page-foreground-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline li.vis:not(.vis ~ .vis) a, #page-nav ul.page-outline li a:hover {
|
||||||
|
color: var(--primary-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline .vis {
|
||||||
|
background: var(--page-background-color);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline .vis::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 4px;
|
||||||
|
background: var(--page-secondary-foreground-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline .vis:not(.vis ~ .vis)::after {
|
||||||
|
top: 1px;
|
||||||
|
border-top-right-radius: var(--border-radius-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline .vis:not(:has(~ .vis))::after {
|
||||||
|
bottom: 1px;
|
||||||
|
border-bottom-right-radius: var(--border-radius-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#page-nav ul.page-outline .arrow {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav ul.page-outline .arrow span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
#container {
|
||||||
|
grid-template-columns: initial !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-nav {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Code & Fragments
|
Code & Fragments
|
||||||
*/
|
*/
|
||||||
|
|
||||||
code, div.fragment, pre.fragment {
|
code, div.fragment, pre.fragment, span.tt {
|
||||||
border-radius: var(--border-radius-small);
|
|
||||||
border: 1px solid var(--separator-color);
|
border: 1px solid var(--separator-color);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code, span.tt {
|
||||||
display: inline;
|
display: inline;
|
||||||
background: var(--code-background);
|
background: var(--code-background);
|
||||||
color: var(--code-foreground);
|
color: var(--code-foreground);
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
|
border-radius: var(--border-radius-small);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.fragment, pre.fragment {
|
div.fragment, pre.fragment {
|
||||||
|
border-radius: var(--border-radius-medium);
|
||||||
margin: var(--spacing-medium) 0;
|
margin: var(--spacing-medium) 0;
|
||||||
padding: calc(var(--spacing-large) - (var(--spacing-large) / 6)) var(--spacing-large);
|
padding: calc(var(--spacing-large) - (var(--spacing-large) / 6)) var(--spacing-large);
|
||||||
background: var(--fragment-background);
|
background: var(--fragment-background);
|
||||||
@@ -1273,7 +1488,7 @@ div.fragment, pre.fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span {
|
code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span, span.tt {
|
||||||
font-family: var(--font-family-monospace);
|
font-family: var(--font-family-monospace);
|
||||||
font-size: var(--code-font-size) !important;
|
font-size: var(--code-font-size) !important;
|
||||||
}
|
}
|
||||||
@@ -1347,6 +1562,10 @@ div.line.glow {
|
|||||||
dl warning, attention, note, deprecated, bug, ...
|
dl warning, attention, note, deprecated, bug, ...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
dl {
|
||||||
|
line-height: calc(1.65 * var(--page-font-size));
|
||||||
|
}
|
||||||
|
|
||||||
dl.bug dt a, dl.deprecated dt a, dl.todo dt a {
|
dl.bug dt a, dl.deprecated dt a, dl.todo dt a {
|
||||||
font-weight: bold !important;
|
font-weight: bold !important;
|
||||||
}
|
}
|
||||||
@@ -1512,6 +1731,7 @@ div.memitem {
|
|||||||
border-top-right-radius: var(--border-radius-medium);
|
border-top-right-radius: var(--border-radius-medium);
|
||||||
border-bottom-right-radius: var(--border-radius-medium);
|
border-bottom-right-radius: var(--border-radius-medium);
|
||||||
border-bottom-left-radius: var(--border-radius-medium);
|
border-bottom-left-radius: var(--border-radius-medium);
|
||||||
|
border-top-left-radius: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
@@ -1743,7 +1963,7 @@ table.fieldtable th {
|
|||||||
color: var(--tablehead-foreground);
|
color: var(--tablehead-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
table.fieldtable td.fieldtype, .fieldtable td.fieldname, .fieldtable td.fielddoc, .fieldtable th {
|
table.fieldtable td.fieldtype, .fieldtable td.fieldname, .fieldtable td.fieldinit, .fieldtable td.fielddoc, .fieldtable th {
|
||||||
border-bottom: 1px solid var(--separator-color);
|
border-bottom: 1px solid var(--separator-color);
|
||||||
border-right: 1px solid var(--separator-color);
|
border-right: 1px solid var(--separator-color);
|
||||||
}
|
}
|
||||||
@@ -1778,8 +1998,10 @@ table.memberdecls tr[class^='memitem'] .memTemplParams {
|
|||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.memberdecls .memItemLeft,
|
table.memberdecls tr.heading + tr[class^='memitem'] td.memItemLeft,
|
||||||
table.memberdecls .memItemRight,
|
table.memberdecls tr.heading + tr[class^='memitem'] td.memItemRight,
|
||||||
|
table.memberdecls td.memItemLeft,
|
||||||
|
table.memberdecls td.memItemRight,
|
||||||
table.memberdecls .memTemplItemLeft,
|
table.memberdecls .memTemplItemLeft,
|
||||||
table.memberdecls .memTemplItemRight,
|
table.memberdecls .memTemplItemRight,
|
||||||
table.memberdecls .memTemplParams {
|
table.memberdecls .memTemplParams {
|
||||||
@@ -1791,8 +2013,34 @@ table.memberdecls .memTemplParams {
|
|||||||
background-color: var(--fragment-background);
|
background-color: var(--fragment-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
|
||||||
|
tr.heading + tr[class^='memitem'] td.memItemRight, tr.groupHeader + tr[class^='memitem'] td.memItemRight, tr.inherit_header + tr[class^='memitem'] td.memItemRight {
|
||||||
|
border-top-right-radius: var(--border-radius-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.memberdecls tr:last-child td.memItemRight, table.memberdecls tr:last-child td.mdescRight, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemRight, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemRight, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescRight, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescRight {
|
||||||
|
border-bottom-right-radius: var(--border-radius-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.memberdecls tr:last-child td.memItemLeft, table.memberdecls tr:last-child td.mdescLeft, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemLeft, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescLeft {
|
||||||
|
border-bottom-left-radius: var(--border-radius-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.heading + tr[class^='memitem'] td.memItemLeft, tr.groupHeader + tr[class^='memitem'] td.memItemLeft, tr.inherit_header + tr[class^='memitem'] td.memItemLeft {
|
||||||
|
border-top-left-radius: var(--border-radius-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
table.memname td.memname {
|
||||||
|
font-size: var(--memname-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
table.memberdecls .memTemplItemLeft,
|
table.memberdecls .memTemplItemLeft,
|
||||||
table.memberdecls .memTemplItemRight {
|
table.memberdecls .template .memItemLeft,
|
||||||
|
table.memberdecls .memTemplItemRight,
|
||||||
|
table.memberdecls .template .memItemRight {
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1804,13 +2052,13 @@ table.memberdecls .memTemplParams {
|
|||||||
padding-bottom: var(--spacing-small);
|
padding-bottom: var(--spacing-small);
|
||||||
}
|
}
|
||||||
|
|
||||||
table.memberdecls .memTemplItemLeft {
|
table.memberdecls .memTemplItemLeft, table.memberdecls .template .memItemLeft {
|
||||||
border-radius: 0 0 0 var(--border-radius-small);
|
border-radius: 0 0 0 var(--border-radius-small);
|
||||||
border-left: 1px solid var(--separator-color);
|
border-left: 1px solid var(--separator-color);
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.memberdecls .memTemplItemRight {
|
table.memberdecls .memTemplItemRight, table.memberdecls .template .memItemRight {
|
||||||
border-radius: 0 0 var(--border-radius-small) 0;
|
border-radius: 0 0 var(--border-radius-small) 0;
|
||||||
border-right: 1px solid var(--separator-color);
|
border-right: 1px solid var(--separator-color);
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
@@ -1836,8 +2084,14 @@ table.memberdecls .mdescLeft, table.memberdecls .mdescRight {
|
|||||||
background: none;
|
background: none;
|
||||||
color: var(--page-foreground-color);
|
color: var(--page-foreground-color);
|
||||||
padding: var(--spacing-small) 0;
|
padding: var(--spacing-small) 0;
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.memberdecls [class^="memdesc"] {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
table.memberdecls .memItemLeft,
|
table.memberdecls .memItemLeft,
|
||||||
table.memberdecls .memTemplItemLeft {
|
table.memberdecls .memTemplItemLeft {
|
||||||
padding-right: var(--spacing-medium);
|
padding-right: var(--spacing-medium);
|
||||||
@@ -1860,6 +2114,10 @@ table.memberdecls .inherit_header td {
|
|||||||
color: var(--page-secondary-foreground-color);
|
color: var(--page-secondary-foreground-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.memberdecls span.dynarrow {
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
table.memberdecls img[src="closed.png"],
|
table.memberdecls img[src="closed.png"],
|
||||||
table.memberdecls img[src="open.png"],
|
table.memberdecls img[src="open.png"],
|
||||||
div.dynheader img[src="open.png"],
|
div.dynheader img[src="open.png"],
|
||||||
@@ -1876,6 +2134,10 @@ div.dynheader img[src="closed.png"] {
|
|||||||
transition: transform var(--animation-duration) ease-out;
|
transition: transform var(--animation-duration) ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr.heading + tr[class^='memitem'] td.memItemLeft, tr.groupHeader + tr[class^='memitem'] td.memItemLeft, tr.inherit_header + tr[class^='memitem'] td.memItemLeft, tr.heading + tr[class^='memitem'] td.memItemRight, tr.groupHeader + tr[class^='memitem'] td.memItemRight, tr.inherit_header + tr[class^='memitem'] td.memItemRight {
|
||||||
|
border-top: 1px solid var(--separator-color);
|
||||||
|
}
|
||||||
|
|
||||||
table.memberdecls img {
|
table.memberdecls img {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
@@ -1900,7 +2162,10 @@ div.dynheader img[src="closed.png"] {
|
|||||||
table.memberdecls .mdescRight,
|
table.memberdecls .mdescRight,
|
||||||
table.memberdecls .memTemplItemLeft,
|
table.memberdecls .memTemplItemLeft,
|
||||||
table.memberdecls .memTemplItemRight,
|
table.memberdecls .memTemplItemRight,
|
||||||
table.memberdecls .memTemplParams {
|
table.memberdecls .memTemplParams,
|
||||||
|
table.memberdecls .template .memItemLeft,
|
||||||
|
table.memberdecls .template .memItemRight,
|
||||||
|
table.memberdecls .template .memParams {
|
||||||
display: block;
|
display: block;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding-left: var(--spacing-large);
|
padding-left: var(--spacing-large);
|
||||||
@@ -1913,12 +2178,14 @@ div.dynheader img[src="closed.png"] {
|
|||||||
|
|
||||||
table.memberdecls .memItemLeft,
|
table.memberdecls .memItemLeft,
|
||||||
table.memberdecls .mdescLeft,
|
table.memberdecls .mdescLeft,
|
||||||
table.memberdecls .memTemplItemLeft {
|
table.memberdecls .memTemplItemLeft,
|
||||||
border-bottom: 0;
|
table.memberdecls .template .memItemLeft {
|
||||||
padding-bottom: 0;
|
border-bottom: 0 !important;
|
||||||
|
padding-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.memberdecls .memTemplItemLeft {
|
table.memberdecls .memTemplItemLeft,
|
||||||
|
table.memberdecls .template .memItemLeft {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1928,10 +2195,12 @@ div.dynheader img[src="closed.png"] {
|
|||||||
|
|
||||||
table.memberdecls .memItemRight,
|
table.memberdecls .memItemRight,
|
||||||
table.memberdecls .mdescRight,
|
table.memberdecls .mdescRight,
|
||||||
table.memberdecls .memTemplItemRight {
|
table.memberdecls .memTemplItemRight,
|
||||||
border-top: 0;
|
table.memberdecls .template .memItemRight {
|
||||||
padding-top: 0;
|
border-top: 0 !important;
|
||||||
|
padding-top: 0 !important;
|
||||||
padding-right: var(--spacing-large);
|
padding-right: var(--spacing-large);
|
||||||
|
padding-bottom: var(--spacing-medium);
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1966,6 +2235,22 @@ div.dynheader img[src="closed.png"] {
|
|||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr.heading + tr[class^='memitem'] td.memItemRight, tr.groupHeader + tr[class^='memitem'] td.memItemRight, tr.inherit_header + tr[class^='memitem'] td.memItemRight {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.memberdecls tr:last-child td.memItemRight, table.memberdecls tr:last-child td.mdescRight, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemRight, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemRight, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescRight, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescRight {
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.memberdecls tr:last-child td.memItemLeft, table.memberdecls tr:last-child td.mdescLeft, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemLeft, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescLeft {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.heading + tr[class^='memitem'] td.memItemLeft, tr.groupHeader + tr[class^='memitem'] td.memItemLeft, tr.inherit_header + tr[class^='memitem'] td.memItemLeft {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1982,14 +2267,16 @@ hr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.contents hr {
|
.contents hr {
|
||||||
box-shadow: 100px 0 0 var(--separator-color),
|
box-shadow: 100px 0 var(--separator-color),
|
||||||
-100px 0 0 var(--separator-color),
|
-100px 0 var(--separator-color),
|
||||||
500px 0 0 var(--separator-color),
|
500px 0 var(--separator-color),
|
||||||
-500px 0 0 var(--separator-color),
|
-500px 0 var(--separator-color),
|
||||||
1500px 0 0 var(--separator-color),
|
900px 0 var(--separator-color),
|
||||||
-1500px 0 0 var(--separator-color),
|
-900px 0 var(--separator-color),
|
||||||
2000px 0 0 var(--separator-color),
|
1400px 0 var(--separator-color),
|
||||||
-2000px 0 0 var(--separator-color);
|
-1400px 0 var(--separator-color),
|
||||||
|
1900px 0 var(--separator-color),
|
||||||
|
-1900px 0 var(--separator-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.contents img, .contents .center, .contents center, .contents div.image object {
|
.contents img, .contents .center, .contents center, .contents div.image object {
|
||||||
@@ -2152,9 +2439,7 @@ div.qindex {
|
|||||||
background: var(--page-background-color);
|
background: var(--page-background-color);
|
||||||
border: none;
|
border: none;
|
||||||
border-top: 1px solid var(--separator-color);
|
border-top: 1px solid var(--separator-color);
|
||||||
border-bottom: 1px solid var(--separator-color);
|
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
box-shadow: 0 0.75px 0 var(--separator-color);
|
|
||||||
font-size: var(--navigation-font-size);
|
font-size: var(--navigation-font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2183,6 +2468,10 @@ address.footer {
|
|||||||
color: var(--primary-color) !important;
|
color: var(--primary-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.navpath li.navelem a:hover {
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
.navpath li.navelem b {
|
.navpath li.navelem b {
|
||||||
color: var(--primary-dark-color);
|
color: var(--primary-dark-color);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@@ -2201,7 +2490,11 @@ li.navelem:first-child:before {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-path li.navelem:after {
|
#nav-path ul {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-path li.navelem:has(.el):after {
|
||||||
content: '';
|
content: '';
|
||||||
border: 5px solid var(--page-background-color);
|
border: 5px solid var(--page-background-color);
|
||||||
border-bottom-color: transparent;
|
border-bottom-color: transparent;
|
||||||
@@ -2212,7 +2505,21 @@ li.navelem:first-child:before {
|
|||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-path li.navelem:before {
|
#nav-path li.navelem:not(:has(.el)):after {
|
||||||
|
background: var(--page-background-color);
|
||||||
|
box-shadow: 1px -1px 0 1px var(--separator-color);
|
||||||
|
border-radius: 0 var(--border-radius-medium) 0 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-path li.navelem:not(:has(.el)) {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-path li.navelem:not(:has(.el)):hover, #nav-path li.navelem:not(:has(.el)):hover:after {
|
||||||
|
background-color: var(--separator-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-path li.navelem:has(.el):before {
|
||||||
content: '';
|
content: '';
|
||||||
border: 5px solid var(--separator-color);
|
border: 5px solid var(--separator-color);
|
||||||
border-bottom-color: transparent;
|
border-bottom-color: transparent;
|
||||||
@@ -2338,7 +2645,7 @@ doxygen-awesome-dark-mode-toggle {
|
|||||||
height: var(--searchbar-height);
|
height: var(--searchbar-height);
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: var(--searchbar-height);
|
border-radius: var(--searchbar-border-radius);
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: var(--searchbar-height);
|
line-height: var(--searchbar-height);
|
||||||
@@ -2523,6 +2830,7 @@ h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a.
|
|||||||
float: left;
|
float: left;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
font-family: var(--font-family);
|
||||||
padding: calc(var(--spacing-large) / 2) var(--spacing-large);
|
padding: calc(var(--spacing-large) / 2) var(--spacing-large);
|
||||||
border-radius: var(--border-radius-medium);
|
border-radius: var(--border-radius-medium);
|
||||||
transition: background-color var(--animation-duration) ease-in-out, font-weight var(--animation-duration) ease-in-out;
|
transition: background-color var(--animation-duration) ease-in-out, font-weight var(--animation-duration) ease-in-out;
|
||||||
@@ -2667,3 +2975,46 @@ h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a.
|
|||||||
border-radius: 0 var(--border-radius-medium) var(--border-radius-medium) 0;
|
border-radius: 0 var(--border-radius-medium) var(--border-radius-medium) 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bordered image
|
||||||
|
*/
|
||||||
|
|
||||||
|
html.dark-mode .darkmode_inverted_image img, /* < doxygen 1.9.3 */
|
||||||
|
html.dark-mode .darkmode_inverted_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ {
|
||||||
|
filter: brightness(89%) hue-rotate(180deg) invert();
|
||||||
|
}
|
||||||
|
|
||||||
|
.bordered_image {
|
||||||
|
border-radius: var(--border-radius-small);
|
||||||
|
border: 1px solid var(--separator-color);
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bordered_image:empty {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark-mode .bordered_image img, /* < doxygen 1.9.3 */
|
||||||
|
html.dark-mode .bordered_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ {
|
||||||
|
border-radius: var(--border-radius-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Button
|
||||||
|
*/
|
||||||
|
|
||||||
|
.primary-button {
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: var(--page-background-color) !important;
|
||||||
|
border-radius: var(--border-radius-medium);
|
||||||
|
padding: var(--spacing-small) var(--spacing-medium);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary-button:hover {
|
||||||
|
background: var(--primary-dark-color);
|
||||||
|
}
|
||||||
129
docs/doxygen-awesome-theme/doxygen-custom/custom.css
Normal file
129
docs/doxygen-awesome-theme/doxygen-custom/custom.css
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
.github-corner svg {
|
||||||
|
fill: var(--primary-light-color);
|
||||||
|
color: var(--page-background-color);
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.github-corner svg {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
#projectnumber {
|
||||||
|
margin-right: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title_screenshot {
|
||||||
|
filter: drop-shadow(0px 3px 10px rgba(0,0,0,0.22));
|
||||||
|
max-width: 500px;
|
||||||
|
margin: var(--spacing-large) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title_screenshot .caption {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-selection {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
background: var(--side-nav-background);
|
||||||
|
padding: 5px 2px 5px 8px;
|
||||||
|
box-shadow: 0 -4px 4px -2px var(--side-nav-background);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-selection label {
|
||||||
|
border: 1px solid var(--separator-color);
|
||||||
|
border-right: 0;
|
||||||
|
color: var(--page-foreground-color);
|
||||||
|
font-size: var(--toc-font-size);
|
||||||
|
padding: 0 8px;
|
||||||
|
display: inline-block;
|
||||||
|
height: 22px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: var(--border-radius-medium) 0 0 var(--border-radius-medium);
|
||||||
|
line-height: 20px;
|
||||||
|
background: var(--page-background-color);
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html:not(.light-mode) #theme-select {
|
||||||
|
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23aaaaaa'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat;
|
||||||
|
background-size: 8px;
|
||||||
|
background-position: calc(100% - 6px) 65%;
|
||||||
|
background-color: var(--page-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark-mode #theme-select {
|
||||||
|
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23aaaaaa'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat;
|
||||||
|
background-size: 8px;
|
||||||
|
background-position: calc(100% - 6px) 65%;
|
||||||
|
background-color: var(--page-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-select {
|
||||||
|
border: 1px solid var(--separator-color);
|
||||||
|
border-radius: 0 var(--border-radius-medium) var(--border-radius-medium) 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 22px;
|
||||||
|
font-size: var(--toc-font-size);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
width: 215px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
border-left: 0;
|
||||||
|
display: inline-block;
|
||||||
|
opacity: 0.7;
|
||||||
|
outline: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23888888'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat;
|
||||||
|
background-size: 8px;
|
||||||
|
background-position: calc(100% - 6px) 65%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-color: var(--page-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-selection:hover #theme-select, #theme-selection:hover label {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-tree-contents {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
#theme-selection {
|
||||||
|
box-shadow: none;
|
||||||
|
background: none;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-select {
|
||||||
|
width: 80px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#theme-selection label {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-path ul li.navelem:first-child {
|
||||||
|
margin-left: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li.footer:not(:first-child) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-path {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
background: var(--page-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
98
docs/doxygen-awesome-theme/doxygen-custom/header.html
Normal file
98
docs/doxygen-awesome-theme/doxygen-custom/header.html
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||||
|
<meta name="generator" content="Doxygen $doxygenversion"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
|
||||||
|
<!-- BEGIN opengraph metadata -->
|
||||||
|
<meta property="og:title" content="Doxygen Awesome" />
|
||||||
|
<meta property="og:image" content="https://repository-images.githubusercontent.com/348492097/4f16df80-88fb-11eb-9d31-4015ff22c452" />
|
||||||
|
<meta property="og:description" content="Custom CSS theme for doxygen html-documentation with lots of customization parameters." />
|
||||||
|
<meta property="og:url" content="https://jothepro.github.io/doxygen-awesome-css/" />
|
||||||
|
<!-- END opengraph metadata -->
|
||||||
|
|
||||||
|
<!-- BEGIN twitter metadata -->
|
||||||
|
<meta name="twitter:image:src" content="https://repository-images.githubusercontent.com/348492097/4f16df80-88fb-11eb-9d31-4015ff22c452" />
|
||||||
|
<meta name="twitter:title" content="Doxygen Awesome" />
|
||||||
|
<meta name="twitter:description" content="Custom CSS theme for doxygen html-documentation with lots of customization parameters." />
|
||||||
|
<!-- END twitter metadata -->
|
||||||
|
|
||||||
|
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
||||||
|
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
||||||
|
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="logo.drawio.svg"/>
|
||||||
|
<script type="text/javascript" src="$relpath^jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
||||||
|
<script type="text/javascript" src="$relpath^doxygen-awesome-darkmode-toggle.js"></script>
|
||||||
|
<script type="text/javascript" src="$relpath^doxygen-awesome-fragment-copy-button.js"></script>
|
||||||
|
<script type="text/javascript" src="$relpath^doxygen-awesome-paragraph-link.js"></script>
|
||||||
|
<script type="text/javascript" src="$relpath^doxygen-awesome-interactive-toc.js"></script>
|
||||||
|
<script type="text/javascript" src="$relpath^doxygen-awesome-tabs.js"></script>
|
||||||
|
<script type="text/javascript" src="$relpath^toggle-alternative-theme.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
DoxygenAwesomeFragmentCopyButton.init()
|
||||||
|
DoxygenAwesomeDarkModeToggle.init()
|
||||||
|
DoxygenAwesomeParagraphLink.init()
|
||||||
|
DoxygenAwesomeInteractiveToc.init()
|
||||||
|
DoxygenAwesomeTabs.init()
|
||||||
|
</script>
|
||||||
|
$treeview
|
||||||
|
$search
|
||||||
|
$mathjax
|
||||||
|
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||||
|
$extrastylesheet
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- https://tholman.com/github-corners/ -->
|
||||||
|
<a href="https://github.com/jothepro/doxygen-awesome-css" class="github-corner" title="View source on GitHub" target="_blank" rel="noopener noreferrer">
|
||||||
|
<svg viewBox="0 0 250 250" width="40" height="40" style="position: absolute; top: 0; border: 0; right: 0; z-index: 99;" aria-hidden="true">
|
||||||
|
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||||
|
|
||||||
|
<!--BEGIN TITLEAREA-->
|
||||||
|
<div id="titlearea">
|
||||||
|
<table cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr style="height: 56px;">
|
||||||
|
<!--BEGIN PROJECT_LOGO-->
|
||||||
|
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
|
||||||
|
<!--END PROJECT_LOGO-->
|
||||||
|
<!--BEGIN PROJECT_NAME-->
|
||||||
|
<td id="projectalign" style="padding-left: 0.5em;">
|
||||||
|
<div id="projectname">$projectname
|
||||||
|
<!--BEGIN PROJECT_NUMBER--> <span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
|
||||||
|
</div>
|
||||||
|
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
|
||||||
|
</td>
|
||||||
|
<!--END PROJECT_NAME-->
|
||||||
|
<!--BEGIN !PROJECT_NAME-->
|
||||||
|
<!--BEGIN PROJECT_BRIEF-->
|
||||||
|
<td style="padding-left: 0.5em;">
|
||||||
|
<div id="projectbrief">$projectbrief</div>
|
||||||
|
</td>
|
||||||
|
<!--END PROJECT_BRIEF-->
|
||||||
|
<!--END !PROJECT_NAME-->
|
||||||
|
<!--BEGIN DISABLE_INDEX-->
|
||||||
|
<!--BEGIN SEARCHENGINE-->
|
||||||
|
<td>$searchbox</td>
|
||||||
|
<!--END SEARCHENGINE-->
|
||||||
|
<!--END DISABLE_INDEX-->
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div id="theme-selection">
|
||||||
|
<label for="theme-select">Theme:</label>
|
||||||
|
<select id="theme-select">
|
||||||
|
<option value="theme-default">Default</option>
|
||||||
|
<option value="theme-round">Round</option>
|
||||||
|
<option value="theme-robot">Robot</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--END TITLEAREA-->
|
||||||
|
<!-- end header part -->
|
||||||
62
docs/doxygen-awesome-theme/doxygen-custom/theme-robot.css
Normal file
62
docs/doxygen-awesome-theme/doxygen-custom/theme-robot.css
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
html.theme-robot {
|
||||||
|
/* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */
|
||||||
|
--primary-color: #1c89a4;
|
||||||
|
--primary-dark-color: #1a6f84;
|
||||||
|
--primary-light-color: #5abcd4;
|
||||||
|
--primary-lighter-color: #cae1f1;
|
||||||
|
--primary-lightest-color: #e9f1f8;
|
||||||
|
|
||||||
|
--fragment-background: #ececec;
|
||||||
|
--code-background: #ececec;
|
||||||
|
|
||||||
|
/* page base colors */
|
||||||
|
--page-background-color: white;
|
||||||
|
--page-foreground-color: #2c3e50;
|
||||||
|
--page-secondary-foreground-color: #67727e;
|
||||||
|
|
||||||
|
|
||||||
|
--border-radius-large: 0px;
|
||||||
|
--border-radius-small: 0px;
|
||||||
|
--border-radius-medium: 0px;
|
||||||
|
|
||||||
|
--spacing-small: 3px;
|
||||||
|
--spacing-medium: 6px;
|
||||||
|
--spacing-large: 12px;
|
||||||
|
|
||||||
|
--top-height: 125px;
|
||||||
|
|
||||||
|
--side-nav-background: var(--page-background-color);
|
||||||
|
--side-nav-foreground: var(--page-foreground-color);
|
||||||
|
--header-foreground: var(--side-nav-foreground);
|
||||||
|
--searchbar-border-radius: var(--border-radius-medium);
|
||||||
|
--header-background: var(--side-nav-background);
|
||||||
|
--header-foreground: var(--side-nav-foreground);
|
||||||
|
|
||||||
|
--toc-background: rgb(243, 240, 252);
|
||||||
|
--toc-foreground: var(--page-foreground-color);
|
||||||
|
|
||||||
|
--font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
|
||||||
|
--page-font-size: 14px;
|
||||||
|
--box-shadow: none;
|
||||||
|
--separator-color: #cdcdcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.theme-robot.dark-mode {
|
||||||
|
color-scheme: dark;
|
||||||
|
|
||||||
|
--primary-color: #49cad3;
|
||||||
|
--primary-dark-color: #8ed2d7;
|
||||||
|
--primary-light-color: #377479;
|
||||||
|
--primary-lighter-color: #191e21;
|
||||||
|
--primary-lightest-color: #191a1c;
|
||||||
|
|
||||||
|
--fragment-background: #000000;
|
||||||
|
--code-background: #000000;
|
||||||
|
|
||||||
|
--page-background-color: #161616;
|
||||||
|
--page-foreground-color: #d2dbde;
|
||||||
|
--page-secondary-foreground-color: #555555;
|
||||||
|
--separator-color: #545454;
|
||||||
|
--toc-background: #20142C;
|
||||||
|
|
||||||
|
}
|
||||||
55
docs/doxygen-awesome-theme/doxygen-custom/theme-round.css
Normal file
55
docs/doxygen-awesome-theme/doxygen-custom/theme-round.css
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
html.theme-round {
|
||||||
|
/* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */
|
||||||
|
--primary-color: #AF7FE4;
|
||||||
|
--primary-dark-color: #9270E4;
|
||||||
|
--primary-light-color: #d2b7ef;
|
||||||
|
--primary-lighter-color: #cae1f1;
|
||||||
|
--primary-lightest-color: #e9f1f8;
|
||||||
|
|
||||||
|
/* page base colors */
|
||||||
|
--page-background-color: white;
|
||||||
|
--page-foreground-color: #2c3e50;
|
||||||
|
--page-secondary-foreground-color: #67727e;
|
||||||
|
|
||||||
|
|
||||||
|
--border-radius-large: 22px;
|
||||||
|
--border-radius-small: 9px;
|
||||||
|
--border-radius-medium: 14px;
|
||||||
|
--spacing-small: 8px;
|
||||||
|
--spacing-medium: 14px;
|
||||||
|
--spacing-large: 19px;
|
||||||
|
--spacing-xlarge: 21px;
|
||||||
|
|
||||||
|
--top-height: 125px;
|
||||||
|
|
||||||
|
--side-nav-background: #324067;
|
||||||
|
--side-nav-foreground: #F1FDFF;
|
||||||
|
--header-foreground: var(--side-nav-foreground);
|
||||||
|
--searchbar-background: var(--side-nav-foreground);
|
||||||
|
--searchbar-border-radius: var(--border-radius-medium);
|
||||||
|
--header-background: var(--side-nav-background);
|
||||||
|
--header-foreground: var(--side-nav-foreground);
|
||||||
|
|
||||||
|
--toc-background: rgb(243, 240, 252);
|
||||||
|
--toc-foreground: var(--page-foreground-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
html.theme-round.dark-mode {
|
||||||
|
color-scheme: dark;
|
||||||
|
|
||||||
|
--primary-color: #AF7FE4;
|
||||||
|
--primary-dark-color: #715292;
|
||||||
|
--primary-light-color: #ae97c7;
|
||||||
|
--primary-lighter-color: #191e21;
|
||||||
|
--primary-lightest-color: #191a1c;
|
||||||
|
|
||||||
|
--page-background-color: #1C1D1F;
|
||||||
|
--page-foreground-color: #d2dbde;
|
||||||
|
--page-secondary-foreground-color: #859399;
|
||||||
|
--separator-color: #3a3246;
|
||||||
|
--side-nav-background: #171D32;
|
||||||
|
--side-nav-foreground: #F1FDFF;
|
||||||
|
--toc-background: #20142C;
|
||||||
|
--searchbar-background: var(--page-background-color);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
// Toggle zwischen drei Theme-Zuständen und speichere im localStorage
|
||||||
|
const THEME_CLASSES = ['theme-default', 'theme-round', 'theme-robot'];
|
||||||
|
// Ermögliche das Umschalten per Button/Funktion (z.B. für onclick im HTML)
|
||||||
|
function toggleThemeVariant() {
|
||||||
|
let idx = getCurrentThemeIndex();
|
||||||
|
idx = (idx + 1) % THEME_CLASSES.length;
|
||||||
|
applyThemeClass(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funktion global verfügbar machen
|
||||||
|
window.toggleThemeVariant = toggleThemeVariant;
|
||||||
|
|
||||||
|
function getCurrentThemeIndex() {
|
||||||
|
const stored = localStorage.getItem('theme-variant');
|
||||||
|
if (stored === null) return 0;
|
||||||
|
const idx = THEME_CLASSES.indexOf(stored);
|
||||||
|
return idx === -1 ? 0 : idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyThemeClass(idx) {
|
||||||
|
document.documentElement.classList.remove(...THEME_CLASSES);
|
||||||
|
if (THEME_CLASSES[idx] && THEME_CLASSES[idx] !== 'theme-default') {
|
||||||
|
document.documentElement.classList.add(THEME_CLASSES[idx]);
|
||||||
|
}
|
||||||
|
localStorage.setItem('theme-variant', THEME_CLASSES[idx] || 'theme-default');
|
||||||
|
// Select synchronisieren, falls vorhanden
|
||||||
|
const select = document.getElementById('theme-select');
|
||||||
|
if (select) select.value = THEME_CLASSES[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
function setThemeByName(themeName) {
|
||||||
|
const idx = THEME_CLASSES.indexOf(themeName);
|
||||||
|
applyThemeClass(idx === -1 ? 0 : idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const select = document.getElementById('theme-select');
|
||||||
|
if (select) {
|
||||||
|
// Initialisiere Auswahl aus localStorage
|
||||||
|
const idx = getCurrentThemeIndex();
|
||||||
|
select.value = THEME_CLASSES[idx];
|
||||||
|
applyThemeClass(idx);
|
||||||
|
// Theme bei Auswahl ändern
|
||||||
|
select.addEventListener('change', e => {
|
||||||
|
setThemeByName(e.target.value);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback: Theme trotzdem setzen
|
||||||
|
applyThemeClass(getCurrentThemeIndex());
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
<!-- HTML header for doxygen 1.9.7-->
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="$langISO">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
|
|
||||||
<meta name="generator" content="Doxygen $doxygenversion"/>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
||||||
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
|
||||||
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
|
||||||
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
|
|
||||||
<!--BEGIN DISABLE_INDEX-->
|
|
||||||
<!--BEGIN FULL_SIDEBAR-->
|
|
||||||
<script type="text/javascript">var page_layout=1;</script>
|
|
||||||
<!--END FULL_SIDEBAR-->
|
|
||||||
<!--END DISABLE_INDEX-->
|
|
||||||
<script type="text/javascript" src="$relpath^jquery.js"></script>
|
|
||||||
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
|
||||||
$treeview
|
|
||||||
$search
|
|
||||||
$mathjax
|
|
||||||
$darkmode
|
|
||||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
|
||||||
$extrastylesheet
|
|
||||||
<script type="text/javascript" src="$relpath^doxygen-awesome-darkmode-toggle.js"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
DoxygenAwesomeDarkModeToggle.init()
|
|
||||||
</script>
|
|
||||||
<script type="text/javascript" src="$relpath^doxygen-awesome-interactive-toc.js"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
DoxygenAwesomeInteractiveToc.init()
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!--BEGIN DISABLE_INDEX-->
|
|
||||||
<!--BEGIN FULL_SIDEBAR-->
|
|
||||||
<div id="side-nav" class="ui-resizable side-nav-resizable"><!-- do not remove this div, it is closed by doxygen! -->
|
|
||||||
<!--END FULL_SIDEBAR-->
|
|
||||||
<!--END DISABLE_INDEX-->
|
|
||||||
|
|
||||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
||||||
|
|
||||||
<!--BEGIN TITLEAREA-->
|
|
||||||
<div id="titlearea">
|
|
||||||
<table cellspacing="0" cellpadding="0">
|
|
||||||
<tbody>
|
|
||||||
<tr id="projectrow">
|
|
||||||
<!--BEGIN PROJECT_LOGO-->
|
|
||||||
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
|
|
||||||
<!--END PROJECT_LOGO-->
|
|
||||||
<!--BEGIN PROJECT_NAME-->
|
|
||||||
<td id="projectalign">
|
|
||||||
<div id="projectname">$projectname<!--BEGIN PROJECT_NUMBER--><span id="projectnumber"> $projectnumber</span><!--END PROJECT_NUMBER-->
|
|
||||||
</div>
|
|
||||||
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
|
|
||||||
</td>
|
|
||||||
<!--END PROJECT_NAME-->
|
|
||||||
<!--BEGIN !PROJECT_NAME-->
|
|
||||||
<!--BEGIN PROJECT_BRIEF-->
|
|
||||||
<td>
|
|
||||||
<div id="projectbrief">$projectbrief</div>
|
|
||||||
</td>
|
|
||||||
<!--END PROJECT_BRIEF-->
|
|
||||||
<!--END !PROJECT_NAME-->
|
|
||||||
<!--BEGIN DISABLE_INDEX-->
|
|
||||||
<!--BEGIN SEARCHENGINE-->
|
|
||||||
<!--BEGIN !FULL_SIDEBAR-->
|
|
||||||
<td>$searchbox</td>
|
|
||||||
<!--END !FULL_SIDEBAR-->
|
|
||||||
<!--END SEARCHENGINE-->
|
|
||||||
<!--END DISABLE_INDEX-->
|
|
||||||
</tr>
|
|
||||||
<!--BEGIN SEARCHENGINE-->
|
|
||||||
<!--BEGIN FULL_SIDEBAR-->
|
|
||||||
<tr><td colspan="2">$searchbox</td></tr>
|
|
||||||
<!--END FULL_SIDEBAR-->
|
|
||||||
<!--END SEARCHENGINE-->
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<!--END TITLEAREA-->
|
|
||||||
<!-- end header part -->
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"etl_sources": [
|
"etl_sources": [
|
||||||
{
|
{
|
||||||
"ip": "127.0.0.1",
|
"ip": "127.0.0.1",
|
||||||
"ws_port": "6005",
|
"ws_port": "6006",
|
||||||
"grpc_port": "50051"
|
"grpc_port": "50051"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -76,38 +76,60 @@
|
|||||||
"parallel_requests_limit": 10, // Optional parameter, used only if "processing_strategy" is "parallel". It limits the number of requests for one client connection processed in parallel. Infinite if not specified.
|
"parallel_requests_limit": 10, // Optional parameter, used only if "processing_strategy" is "parallel". It limits the number of requests for one client connection processed in parallel. Infinite if not specified.
|
||||||
// Max number of responses to queue up before sent successfully. If a client's waiting queue is too long, the server will close the connection.
|
// Max number of responses to queue up before sent successfully. If a client's waiting queue is too long, the server will close the connection.
|
||||||
"ws_max_sending_queue_size": 1500,
|
"ws_max_sending_queue_size": 1500,
|
||||||
"__ng_web_server": false // Use ng web server. This is a temporary setting which will be deleted after switching to ng web server
|
"__ng_web_server": false, // Use ng web server. This is a temporary setting which will be deleted after switching to ng web server
|
||||||
|
"proxy": {
|
||||||
|
"ips": [],
|
||||||
|
"tokens": []
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// Time in seconds for graceful shutdown. Defaults to 10 seconds. Not fully implemented yet.
|
// Time in seconds for graceful shutdown. Defaults to 10 seconds. Not fully implemented yet.
|
||||||
"graceful_period": 10.0,
|
"graceful_period": 10.0,
|
||||||
// Overrides log level on a per logging channel.
|
"log": {
|
||||||
// Defaults to global "log_level" for each unspecified channel.
|
// Overrides log level on a per logging channel.
|
||||||
"log_channels": [
|
// Defaults to global "log.level" for each unspecified channel.
|
||||||
{
|
"channels": [
|
||||||
"channel": "Backend",
|
{
|
||||||
"log_level": "fatal"
|
"channel": "Backend",
|
||||||
},
|
"level": "fatal"
|
||||||
{
|
},
|
||||||
"channel": "WebServer",
|
{
|
||||||
"log_level": "info"
|
"channel": "WebServer",
|
||||||
},
|
"level": "info"
|
||||||
{
|
},
|
||||||
"channel": "Subscriptions",
|
{
|
||||||
"log_level": "info"
|
"channel": "Subscriptions",
|
||||||
},
|
"level": "info"
|
||||||
{
|
},
|
||||||
"channel": "RPC",
|
{
|
||||||
"log_level": "error"
|
"channel": "RPC",
|
||||||
},
|
"level": "error"
|
||||||
{
|
},
|
||||||
"channel": "ETL",
|
{
|
||||||
"log_level": "debug"
|
"channel": "ETL",
|
||||||
},
|
"level": "debug"
|
||||||
{
|
},
|
||||||
"channel": "Performance",
|
{
|
||||||
"log_level": "trace"
|
"channel": "Performance",
|
||||||
}
|
"level": "trace"
|
||||||
],
|
}
|
||||||
|
],
|
||||||
|
// The general logging level of Clio. This level is applied to all log channels that do not have an explicitly defined logging level.
|
||||||
|
"level": "info",
|
||||||
|
// Log format using spdlog format patterns (this is the default format)
|
||||||
|
"format": "%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v",
|
||||||
|
// Whether spdlog is asynchronous or not.
|
||||||
|
"is_async": true,
|
||||||
|
// Enables or disables logging to the console.
|
||||||
|
"enable_console": true,
|
||||||
|
// Clio logs to file in the specified directory only if "log.directory" is set
|
||||||
|
// "directory": "./clio_log",
|
||||||
|
// The log rotation size in megabytes. When the log file reaches this particular size, a new log file starts.
|
||||||
|
"rotation_size": 2048,
|
||||||
|
// The maximum number of log files in the directory.
|
||||||
|
"directory_max_files": 25,
|
||||||
|
// Log tags style to use
|
||||||
|
"tag_style": "uint"
|
||||||
|
},
|
||||||
"cache": {
|
"cache": {
|
||||||
// Configure this to use either "num_diffs", "num_cursors_from_diff", or "num_cursors_from_account". By default, Clio uses "num_diffs".
|
// Configure this to use either "num_diffs", "num_cursors_from_diff", or "num_cursors_from_account". By default, Clio uses "num_diffs".
|
||||||
"num_diffs": 32, // Generate the cursors from the latest ledger diff, then use the cursors to partition the ledger to load concurrently. The cursors number is affected by the busyness of the network.
|
"num_diffs": 32, // Generate the cursors from the latest ledger diff, then use the cursors to partition the ledger to load concurrently. The cursors number is affected by the busyness of the network.
|
||||||
@@ -121,16 +143,6 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"compress_reply": true
|
"compress_reply": true
|
||||||
},
|
},
|
||||||
"log_level": "info",
|
|
||||||
// Log format (this is the default format)
|
|
||||||
"log_format": "%TimeStamp% (%SourceLocation%) [%ThreadID%] %Channel%:%Severity% %Message%",
|
|
||||||
"log_to_console": true,
|
|
||||||
// Clio logs to file in the specified directory only if "log_directory" is set
|
|
||||||
// "log_directory": "./clio_log",
|
|
||||||
"log_rotation_size": 2048,
|
|
||||||
"log_directory_max_size": 51200,
|
|
||||||
"log_rotation_hour_interval": 12,
|
|
||||||
"log_tag_style": "uint",
|
|
||||||
"extractor_threads": 8,
|
"extractor_threads": 8,
|
||||||
"read_only": false,
|
"read_only": false,
|
||||||
// "start_sequence": [integer] the ledger index to start from,
|
// "start_sequence": [integer] the ledger index to start from,
|
||||||
|
|||||||
3
docs/github-corner-disable.css
Normal file
3
docs/github-corner-disable.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.github-corner {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
# Logging
|
|
||||||
|
|
||||||
Clio provides several logging options, which all are configurable via the config file. These are detailed in the following sections.
|
|
||||||
|
|
||||||
## `log_level`
|
|
||||||
|
|
||||||
The minimum level of severity at which the log message will be outputted by default. Severity options are `trace`, `debug`, `info`, `warning`, `error`, `fatal`. Defaults to `info`.
|
|
||||||
|
|
||||||
## `log_format`
|
|
||||||
|
|
||||||
The format of log lines produced by Clio. Defaults to `"%TimeStamp% (%SourceLocation%) [%ThreadID%] %Channel%:%Severity% %Message%"`.
|
|
||||||
|
|
||||||
Each of the variables expands like so:
|
|
||||||
|
|
||||||
- `TimeStamp`: The full date and time of the log entry
|
|
||||||
- `SourceLocation`: A partial path to the c++ file and the line number in said file (`source/file/path:linenumber`)
|
|
||||||
- `ThreadID`: The ID of the thread the log entry is written from
|
|
||||||
- `Channel`: The channel that this log entry was sent to
|
|
||||||
- `Severity`: The severity (aka log level) the entry was sent at
|
|
||||||
- `Message`: The actual log message
|
|
||||||
|
|
||||||
## `log_channels`
|
|
||||||
|
|
||||||
An array of JSON objects, each overriding properties for a logging `channel`.
|
|
||||||
|
|
||||||
> [!IMPORTANT]
|
|
||||||
> At the time of writing, only `log_level` can be overridden using this mechanism.
|
|
||||||
|
|
||||||
Each object is of this format:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel": "Backend",
|
|
||||||
"log_level": "fatal"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If no override is present for a given channel, that channel will log at the severity specified by the global `log_level`.
|
|
||||||
|
|
||||||
The log channels that can be overridden are: `Backend`, `WebServer`, `Subscriptions`, `RPC`, `ETL` and `Performance`.
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> See [example-config.json](../docs/examples/config/example-config.json) for more details.
|
|
||||||
|
|
||||||
## `log_to_console`
|
|
||||||
|
|
||||||
Enable or disable log output to console. Options are `true`/`false`. This option defaults to `true`.
|
|
||||||
|
|
||||||
## `log_directory`
|
|
||||||
|
|
||||||
Path to the directory where log files are stored. If such directory doesn't exist, Clio will create it.
|
|
||||||
|
|
||||||
If the option is not specified, the logs are not written to a file.
|
|
||||||
|
|
||||||
## `log_rotation_size`
|
|
||||||
|
|
||||||
The max size of the log file in **megabytes** before it will rotate into a smaller file. Defaults to 2GB.
|
|
||||||
|
|
||||||
## `log_directory_max_size`
|
|
||||||
|
|
||||||
The max size of the log directory in **megabytes** before old log files will be deleted to free up space. Defaults to 50GB.
|
|
||||||
|
|
||||||
## `log_rotation_hour_interval`
|
|
||||||
|
|
||||||
The time interval in **hours** after the last log rotation to automatically rotate the current log file. Defaults to 12 hours.
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> Log rotation based on time occurs in conjunction with size-based log rotation. For example, if a size-based log rotation occurs, the timer for the time-based rotation will reset.
|
|
||||||
|
|
||||||
## `log_tag_style`
|
|
||||||
|
|
||||||
Tag implementation to use. Must be one of:
|
|
||||||
|
|
||||||
- `uint`: Lock free and threadsafe but outputs just a simple unsigned integer
|
|
||||||
- `uuid`: Threadsafe and outputs a UUID tag
|
|
||||||
- `none`: Doesn't use tagging at all
|
|
||||||
@@ -5,11 +5,14 @@ import re
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
PATTERN = r'R"JSON\((.*?)\)JSON"'
|
||||||
|
|
||||||
|
|
||||||
|
def use_uppercase(cpp_content: str) -> str:
|
||||||
|
return cpp_content.replace('R"json(', 'R"JSON(').replace(')json"', ')JSON"')
|
||||||
|
|
||||||
|
|
||||||
def fix_json_style(cpp_content: str) -> str:
|
def fix_json_style(cpp_content: str) -> str:
|
||||||
cpp_content = cpp_content.replace('R"json(', 'R"JSON(').replace(')json"', ')JSON"')
|
|
||||||
|
|
||||||
pattern = r'R"JSON\((.*?)\)JSON"'
|
|
||||||
|
|
||||||
def replace_json(match):
|
def replace_json(match):
|
||||||
raw_json = match.group(1)
|
raw_json = match.group(1)
|
||||||
|
|
||||||
@@ -29,12 +32,51 @@ def fix_json_style(cpp_content: str) -> str:
|
|||||||
raw_json = raw_json.replace(f'":{digit}', f'": {digit}')
|
raw_json = raw_json.replace(f'":{digit}', f'": {digit}')
|
||||||
return f'R"JSON({raw_json})JSON"'
|
return f'R"JSON({raw_json})JSON"'
|
||||||
|
|
||||||
return re.sub(pattern, replace_json, cpp_content, flags=re.DOTALL)
|
return re.sub(PATTERN, replace_json, cpp_content, flags=re.DOTALL)
|
||||||
|
|
||||||
|
|
||||||
|
def fix_colon_spacing(cpp_content: str) -> str:
|
||||||
|
def replace_json(match):
|
||||||
|
raw_json = match.group(1)
|
||||||
|
raw_json = re.sub(r'":\n\s*(\[|\{)', r'": \1', raw_json)
|
||||||
|
return f'R"JSON({raw_json})JSON"'
|
||||||
|
return re.sub(PATTERN, replace_json, cpp_content, flags=re.DOTALL)
|
||||||
|
|
||||||
|
|
||||||
|
def fix_indentation(cpp_content: str) -> str:
|
||||||
|
lines = cpp_content.splitlines()
|
||||||
|
|
||||||
|
def find_indentation(line: str) -> int:
|
||||||
|
return len(line) - len(line.lstrip())
|
||||||
|
|
||||||
|
for (line_num, (line, next_line)) in enumerate(zip(lines[:-1], lines[1:])):
|
||||||
|
if "JSON(" in line and ")JSON" not in line:
|
||||||
|
indent = find_indentation(line)
|
||||||
|
next_indent = find_indentation(next_line)
|
||||||
|
|
||||||
|
by_how_much = next_indent - (indent + 4)
|
||||||
|
if by_how_much != 0:
|
||||||
|
print(
|
||||||
|
f"Indentation error at line: {line_num + 2}: expected {indent + 4} spaces, found {next_indent} spaces"
|
||||||
|
)
|
||||||
|
|
||||||
|
for i in range(line_num + 1, len(lines)):
|
||||||
|
if ")JSON" in lines[i]:
|
||||||
|
lines[i] = " " * indent + lines[i].lstrip()
|
||||||
|
break
|
||||||
|
lines[i] = lines[i][by_how_much:] if by_how_much > 0 else " " * (-by_how_much) + lines[i]
|
||||||
|
|
||||||
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
|
|
||||||
def process_file(file_path: Path, dry_run: bool) -> bool:
|
def process_file(file_path: Path, dry_run: bool) -> bool:
|
||||||
content = file_path.read_text(encoding="utf-8")
|
content = file_path.read_text(encoding="utf-8")
|
||||||
new_content = fix_json_style(content)
|
|
||||||
|
new_content = content
|
||||||
|
new_content = use_uppercase(new_content)
|
||||||
|
new_content = fix_json_style(new_content)
|
||||||
|
new_content = fix_colon_spacing(new_content)
|
||||||
|
new_content = fix_indentation(new_content)
|
||||||
|
|
||||||
if new_content != content:
|
if new_content != content:
|
||||||
print(f"Processing file: {file_path}")
|
print(f"Processing file: {file_path}")
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ target_link_libraries(
|
|||||||
clio_web
|
clio_web
|
||||||
clio_rpc
|
clio_rpc
|
||||||
clio_migration
|
clio_migration
|
||||||
|
PRIVATE Boost::program_options
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "util/build/Build.hpp"
|
#include "util/build/Build.hpp"
|
||||||
#include "util/config/ConfigDescription.hpp"
|
#include "util/config/ConfigDescription.hpp"
|
||||||
|
|
||||||
|
#include <boost/program_options/errors.hpp>
|
||||||
#include <boost/program_options/options_description.hpp>
|
#include <boost/program_options/options_description.hpp>
|
||||||
#include <boost/program_options/parsers.hpp>
|
#include <boost/program_options/parsers.hpp>
|
||||||
#include <boost/program_options/positional_options.hpp>
|
#include <boost/program_options/positional_options.hpp>
|
||||||
@@ -56,12 +57,22 @@ CliArgs::parse(int argc, char const* argv[])
|
|||||||
po::positional_options_description positional;
|
po::positional_options_description positional;
|
||||||
positional.add("conf", 1);
|
positional.add("conf", 1);
|
||||||
|
|
||||||
|
auto const printHelp = [&description]() {
|
||||||
|
std::cout << "Clio server " << util::build::getClioFullVersionString() << "\n\n" << description;
|
||||||
|
};
|
||||||
|
|
||||||
po::variables_map parsed;
|
po::variables_map parsed;
|
||||||
po::store(po::command_line_parser(argc, argv).options(description).positional(positional).run(), parsed);
|
try {
|
||||||
po::notify(parsed);
|
po::store(po::command_line_parser(argc, argv).options(description).positional(positional).run(), parsed);
|
||||||
|
po::notify(parsed);
|
||||||
|
} catch (po::error const& e) {
|
||||||
|
std::cerr << "Error: " << e.what() << std::endl << std::endl;
|
||||||
|
printHelp();
|
||||||
|
return Action{Action::Exit{EXIT_FAILURE}};
|
||||||
|
}
|
||||||
|
|
||||||
if (parsed.contains("help")) {
|
if (parsed.contains("help")) {
|
||||||
std::cout << "Clio server " << util::build::getClioFullVersionString() << "\n\n" << description;
|
printHelp();
|
||||||
return Action{Action::Exit{EXIT_SUCCESS}};
|
return Action{Action::Exit{EXIT_SUCCESS}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
#include "util/build/Build.hpp"
|
#include "util/build/Build.hpp"
|
||||||
#include "util/config/ConfigDefinition.hpp"
|
#include "util/config/ConfigDefinition.hpp"
|
||||||
#include "util/log/Logger.hpp"
|
#include "util/log/Logger.hpp"
|
||||||
#include "util/prometheus/Prometheus.hpp"
|
|
||||||
#include "web/AdminVerificationStrategy.hpp"
|
#include "web/AdminVerificationStrategy.hpp"
|
||||||
#include "web/RPCServerHandler.hpp"
|
#include "web/RPCServerHandler.hpp"
|
||||||
#include "web/Server.hpp"
|
#include "web/Server.hpp"
|
||||||
@@ -91,7 +90,6 @@ ClioApplication::ClioApplication(util::config::ClioConfigDefinition const& confi
|
|||||||
: config_(config), signalsHandler_{config_}
|
: config_(config), signalsHandler_{config_}
|
||||||
{
|
{
|
||||||
LOG(util::LogService::info()) << "Clio version: " << util::build::getClioFullVersionString();
|
LOG(util::LogService::info()) << "Clio version: " << util::build::getClioFullVersionString();
|
||||||
PrometheusService::init(config);
|
|
||||||
signalsHandler_.subscribeToStop([this]() { appStopper_.stop(); });
|
signalsHandler_.subscribeToStop([this]() { appStopper_.stop(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +178,9 @@ ClioApplication::run(bool const useNgWebServer)
|
|||||||
}
|
}
|
||||||
auto const adminVerifier = std::move(expectedAdminVerifier).value();
|
auto const adminVerifier = std::move(expectedAdminVerifier).value();
|
||||||
|
|
||||||
auto httpServer = web::ng::makeServer(config_, OnConnectCheck{dosGuard}, DisconnectHook{dosGuard}, ioc);
|
auto httpServer = web::ng::makeServer(
|
||||||
|
config_, OnConnectCheck{dosGuard}, IpChangeHook{dosGuard}, DisconnectHook{dosGuard}, ioc
|
||||||
|
);
|
||||||
|
|
||||||
if (not httpServer.has_value()) {
|
if (not httpServer.has_value()) {
|
||||||
LOG(util::LogService::error()) << "Error creating web server: " << httpServer.error();
|
LOG(util::LogService::error()) << "Error creating web server: " << httpServer.error();
|
||||||
@@ -189,6 +189,7 @@ ClioApplication::run(bool const useNgWebServer)
|
|||||||
|
|
||||||
httpServer->onGet("/metrics", MetricsHandler{adminVerifier});
|
httpServer->onGet("/metrics", MetricsHandler{adminVerifier});
|
||||||
httpServer->onGet("/health", HealthCheckHandler{});
|
httpServer->onGet("/health", HealthCheckHandler{});
|
||||||
|
httpServer->onGet("/cache_state", CacheStateHandler{cache});
|
||||||
auto requestHandler = RequestHandler{adminVerifier, handler};
|
auto requestHandler = RequestHandler{adminVerifier, handler};
|
||||||
httpServer->onPost("/", requestHandler);
|
httpServer->onPost("/", requestHandler);
|
||||||
httpServer->onWs(std::move(requestHandler));
|
httpServer->onWs(std::move(requestHandler));
|
||||||
@@ -214,7 +215,7 @@ ClioApplication::run(bool const useNgWebServer)
|
|||||||
// Init the web server
|
// Init the web server
|
||||||
auto handler = std::make_shared<web::RPCServerHandler<RPCEngineType>>(config_, backend, rpcEngine, etl, dosGuard);
|
auto handler = std::make_shared<web::RPCServerHandler<RPCEngineType>>(config_, backend, rpcEngine, etl, dosGuard);
|
||||||
|
|
||||||
auto const httpServer = web::makeHttpServer(config_, ioc, dosGuard, handler);
|
auto const httpServer = web::makeHttpServer(config_, ioc, dosGuard, handler, cache);
|
||||||
|
|
||||||
// Blocks until stopped.
|
// Blocks until stopped.
|
||||||
// When stopped, shared_ptrs fall out of scope
|
// When stopped, shared_ptrs fall out of scope
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include "app/Stopper.hpp"
|
#include "app/Stopper.hpp"
|
||||||
|
|
||||||
|
#include "util/Spawn.hpp"
|
||||||
|
|
||||||
#include <boost/asio/spawn.hpp>
|
#include <boost/asio/spawn.hpp>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@@ -36,7 +38,7 @@ Stopper::~Stopper()
|
|||||||
void
|
void
|
||||||
Stopper::setOnStop(std::function<void(boost::asio::yield_context)> cb)
|
Stopper::setOnStop(std::function<void(boost::asio::yield_context)> cb)
|
||||||
{
|
{
|
||||||
boost::asio::spawn(ctx_, std::move(cb));
|
util::spawn(ctx_, std::move(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ public:
|
|||||||
|
|
||||||
ioc.stop();
|
ioc.stop();
|
||||||
LOG(util::LogService::info()) << "io_context stopped";
|
LOG(util::LogService::info()) << "io_context stopped";
|
||||||
|
|
||||||
|
util::LogService::shutdown();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ parseConfig(std::string_view configPath)
|
|||||||
std::cerr << "Error parsing json from config: " << configPath << "\n" << json.error().error << std::endl;
|
std::cerr << "Error parsing json from config: " << configPath << "\n" << json.error().error << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto const errors = gClioConfig.parse(json.value());
|
auto const errors = getClioConfig().parse(json.value());
|
||||||
if (errors.has_value()) {
|
if (errors.has_value()) {
|
||||||
for (auto const& err : errors.value()) {
|
for (auto const& err : errors.value()) {
|
||||||
std::cerr << "Issues found in provided config '" << configPath << "':\n";
|
std::cerr << "Issues found in provided config '" << configPath << "':\n";
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@@ -54,6 +55,17 @@ OnConnectCheck::operator()(web::ng::Connection const& connection)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IpChangeHook::IpChangeHook(web::dosguard::DOSGuardInterface& dosguard) : dosguard_(dosguard)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IpChangeHook::operator()(std::string const& oldIp, std::string const& newIp)
|
||||||
|
{
|
||||||
|
dosguard_.get().decrement(oldIp);
|
||||||
|
dosguard_.get().increment(newIp);
|
||||||
|
}
|
||||||
|
|
||||||
DisconnectHook::DisconnectHook(web::dosguard::DOSGuardInterface& dosguard) : dosguard_{dosguard}
|
DisconnectHook::DisconnectHook(web::dosguard::DOSGuardInterface& dosguard) : dosguard_{dosguard}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -97,7 +109,7 @@ HealthCheckHandler::operator()(
|
|||||||
boost::asio::yield_context
|
boost::asio::yield_context
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
static auto constexpr kHEALTH_CHECK_HTML = R"html(
|
static constexpr auto kHEALTH_CHECK_HTML = R"html(
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head><title>Test page for Clio</title></head>
|
<head><title>Test page for Clio</title></head>
|
||||||
@@ -108,4 +120,34 @@ HealthCheckHandler::operator()(
|
|||||||
return web::ng::Response{boost::beast::http::status::ok, kHEALTH_CHECK_HTML, request};
|
return web::ng::Response{boost::beast::http::status::ok, kHEALTH_CHECK_HTML, request};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
web::ng::Response
|
||||||
|
CacheStateHandler::operator()(
|
||||||
|
web::ng::Request const& request,
|
||||||
|
web::ng::ConnectionMetadata&,
|
||||||
|
web::SubscriptionContextPtr,
|
||||||
|
boost::asio::yield_context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
static constexpr auto kCACHE_CHECK_LOADED_HTML = R"html(
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head><title>Cache state</title></head>
|
||||||
|
<body><h1>Cache state</h1><p>Cache is fully loaded</p></body>
|
||||||
|
</html>
|
||||||
|
)html";
|
||||||
|
|
||||||
|
static constexpr auto kCACHE_CHECK_NOT_LOADED_HTML = R"html(
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head><title>Cache state</title></head>
|
||||||
|
<body><h1>Cache state</h1><p>Cache is not yet loaded</p></body>
|
||||||
|
</html>
|
||||||
|
)html";
|
||||||
|
|
||||||
|
if (cache_.get().isFull())
|
||||||
|
return web::ng::Response{boost::beast::http::status::ok, kCACHE_CHECK_LOADED_HTML, request};
|
||||||
|
|
||||||
|
return web::ng::Response{boost::beast::http::status::service_unavailable, kCACHE_CHECK_NOT_LOADED_HTML, request};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "data/LedgerCacheInterface.hpp"
|
||||||
#include "rpc/Errors.hpp"
|
#include "rpc/Errors.hpp"
|
||||||
#include "util/log/Logger.hpp"
|
#include "util/log/Logger.hpp"
|
||||||
#include "web/AdminVerificationStrategy.hpp"
|
#include "web/AdminVerificationStrategy.hpp"
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@@ -64,6 +66,31 @@ public:
|
|||||||
operator()(web::ng::Connection const& connection);
|
operator()(web::ng::Connection const& connection);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A function object that is called when the IP of a connection changes (usually if proxy detected).
|
||||||
|
* This is used to update the DOS guard.
|
||||||
|
*/
|
||||||
|
class IpChangeHook {
|
||||||
|
std::reference_wrapper<web::dosguard::DOSGuardInterface> dosguard_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Construct a new IpChangeHook object.
|
||||||
|
*
|
||||||
|
* @param dosguard The DOS guard to use.
|
||||||
|
*/
|
||||||
|
IpChangeHook(web::dosguard::DOSGuardInterface& dosguard);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The call of the function object.
|
||||||
|
*
|
||||||
|
* @param oldIp The old IP of the connection.
|
||||||
|
* @param newIp The new IP of the connection.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
operator()(std::string const& oldIp, std::string const& newIp);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A function object to be called when a connection is disconnected.
|
* @brief A function object to be called when a connection is disconnected.
|
||||||
*/
|
*/
|
||||||
@@ -137,6 +164,37 @@ public:
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A function object that handles the cache state check endpoint.
|
||||||
|
*/
|
||||||
|
class CacheStateHandler {
|
||||||
|
std::reference_wrapper<data::LedgerCacheInterface const> cache_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Construct a new CacheStateHandler object.
|
||||||
|
*
|
||||||
|
* @param cache The ledger cache to use.
|
||||||
|
*/
|
||||||
|
CacheStateHandler(data::LedgerCacheInterface const& cache) : cache_{cache}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The call of the function object.
|
||||||
|
*
|
||||||
|
* @param request The request to handle.
|
||||||
|
* @return The response to the request
|
||||||
|
*/
|
||||||
|
web::ng::Response
|
||||||
|
operator()(
|
||||||
|
web::ng::Request const& request,
|
||||||
|
web::ng::ConnectionMetadata&,
|
||||||
|
web::SubscriptionContextPtr,
|
||||||
|
boost::asio::yield_context
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A function object that handles the websocket endpoint.
|
* @brief A function object that handles the websocket endpoint.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -21,10 +21,16 @@
|
|||||||
|
|
||||||
#include "cluster/ClioNode.hpp"
|
#include "cluster/ClioNode.hpp"
|
||||||
#include "data/BackendInterface.hpp"
|
#include "data/BackendInterface.hpp"
|
||||||
|
#include "util/Assert.hpp"
|
||||||
|
#include "util/Spawn.hpp"
|
||||||
#include "util/log/Logger.hpp"
|
#include "util/log/Logger.hpp"
|
||||||
|
|
||||||
|
#include <boost/asio/bind_cancellation_slot.hpp>
|
||||||
|
#include <boost/asio/cancellation_type.hpp>
|
||||||
|
#include <boost/asio/error.hpp>
|
||||||
#include <boost/asio/spawn.hpp>
|
#include <boost/asio/spawn.hpp>
|
||||||
#include <boost/asio/steady_timer.hpp>
|
#include <boost/asio/steady_timer.hpp>
|
||||||
|
#include <boost/asio/use_future.hpp>
|
||||||
#include <boost/json/parse.hpp>
|
#include <boost/json/parse.hpp>
|
||||||
#include <boost/json/serialize.hpp>
|
#include <boost/json/serialize.hpp>
|
||||||
#include <boost/json/value.hpp>
|
#include <boost/json/value.hpp>
|
||||||
@@ -35,11 +41,16 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <latch>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr auto kTOTAL_WORKERS = 2uz; // 1 reading and 1 writing worker (coroutines)
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace cluster {
|
namespace cluster {
|
||||||
|
|
||||||
ClusterCommunicationService::ClusterCommunicationService(
|
ClusterCommunicationService::ClusterCommunicationService(
|
||||||
@@ -50,6 +61,7 @@ ClusterCommunicationService::ClusterCommunicationService(
|
|||||||
: backend_(std::move(backend))
|
: backend_(std::move(backend))
|
||||||
, readInterval_(readInterval)
|
, readInterval_(readInterval)
|
||||||
, writeInterval_(writeInterval)
|
, writeInterval_(writeInterval)
|
||||||
|
, finishedCountdown_(kTOTAL_WORKERS)
|
||||||
, selfData_{ClioNode{
|
, selfData_{ClioNode{
|
||||||
.uuid = std::make_shared<boost::uuids::uuid>(boost::uuids::random_generator{}()),
|
.uuid = std::make_shared<boost::uuids::uuid>(boost::uuids::random_generator{}()),
|
||||||
.updateTime = std::chrono::system_clock::time_point{}
|
.updateTime = std::chrono::system_clock::time_point{}
|
||||||
@@ -62,22 +74,42 @@ ClusterCommunicationService::ClusterCommunicationService(
|
|||||||
void
|
void
|
||||||
ClusterCommunicationService::run()
|
ClusterCommunicationService::run()
|
||||||
{
|
{
|
||||||
boost::asio::spawn(strand_, [this](boost::asio::yield_context yield) {
|
ASSERT(not running_ and not stopped_, "Can only be ran once");
|
||||||
|
running_ = true;
|
||||||
|
|
||||||
|
util::spawn(strand_, [this](boost::asio::yield_context yield) {
|
||||||
boost::asio::steady_timer timer(yield.get_executor());
|
boost::asio::steady_timer timer(yield.get_executor());
|
||||||
while (true) {
|
boost::system::error_code ec;
|
||||||
|
|
||||||
|
while (running_) {
|
||||||
timer.expires_after(readInterval_);
|
timer.expires_after(readInterval_);
|
||||||
timer.async_wait(yield);
|
auto token = cancelSignal_.slot();
|
||||||
|
timer.async_wait(boost::asio::bind_cancellation_slot(token, yield[ec]));
|
||||||
|
|
||||||
|
if (ec == boost::asio::error::operation_aborted or not running_)
|
||||||
|
break;
|
||||||
|
|
||||||
doRead(yield);
|
doRead(yield);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finishedCountdown_.count_down(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
boost::asio::spawn(strand_, [this](boost::asio::yield_context yield) {
|
util::spawn(strand_, [this](boost::asio::yield_context yield) {
|
||||||
boost::asio::steady_timer timer(yield.get_executor());
|
boost::asio::steady_timer timer(yield.get_executor());
|
||||||
while (true) {
|
boost::system::error_code ec;
|
||||||
|
|
||||||
|
while (running_) {
|
||||||
doWrite();
|
doWrite();
|
||||||
timer.expires_after(writeInterval_);
|
timer.expires_after(writeInterval_);
|
||||||
timer.async_wait(yield);
|
auto token = cancelSignal_.slot();
|
||||||
|
timer.async_wait(boost::asio::bind_cancellation_slot(token, yield[ec]));
|
||||||
|
|
||||||
|
if (ec == boost::asio::error::operation_aborted or not running_)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finishedCountdown_.count_down(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +124,19 @@ ClusterCommunicationService::stop()
|
|||||||
if (stopped_)
|
if (stopped_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx_.stop();
|
|
||||||
ctx_.join();
|
|
||||||
stopped_ = true;
|
stopped_ = true;
|
||||||
|
|
||||||
|
// for ASAN to see through concurrency correctly we need to exit all coroutines before joining the ctx
|
||||||
|
running_ = false;
|
||||||
|
|
||||||
|
// cancelSignal_ is not thread safe so we execute emit on the same strand
|
||||||
|
boost::asio::spawn(
|
||||||
|
strand_, [this](auto&&) { cancelSignal_.emit(boost::asio::cancellation_type::all); }, boost::asio::use_future
|
||||||
|
)
|
||||||
|
.wait();
|
||||||
|
finishedCountdown_.wait();
|
||||||
|
|
||||||
|
ctx_.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<boost::uuids::uuid>
|
std::shared_ptr<boost::uuids::uuid>
|
||||||
@@ -108,7 +150,7 @@ ClioNode
|
|||||||
ClusterCommunicationService::selfData() const
|
ClusterCommunicationService::selfData() const
|
||||||
{
|
{
|
||||||
ClioNode result{};
|
ClioNode result{};
|
||||||
boost::asio::spawn(strand_, [this, &result](boost::asio::yield_context) { result = selfData_; });
|
util::spawn(strand_, [this, &result](boost::asio::yield_context) { result = selfData_; });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +161,7 @@ ClusterCommunicationService::clusterData() const
|
|||||||
return std::unexpected{"Service is not healthy"};
|
return std::unexpected{"Service is not healthy"};
|
||||||
}
|
}
|
||||||
std::vector<ClioNode> result;
|
std::vector<ClioNode> result;
|
||||||
boost::asio::spawn(strand_, [this, &result](boost::asio::yield_context) {
|
util::spawn(strand_, [this, &result](boost::asio::yield_context) {
|
||||||
result = otherNodesData_;
|
result = otherNodesData_;
|
||||||
result.push_back(selfData_);
|
result.push_back(selfData_);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,12 +27,15 @@
|
|||||||
#include "util/prometheus/Gauge.hpp"
|
#include "util/prometheus/Gauge.hpp"
|
||||||
#include "util/prometheus/Prometheus.hpp"
|
#include "util/prometheus/Prometheus.hpp"
|
||||||
|
|
||||||
|
#include <boost/asio/cancellation_signal.hpp>
|
||||||
#include <boost/asio/spawn.hpp>
|
#include <boost/asio/spawn.hpp>
|
||||||
#include <boost/asio/strand.hpp>
|
#include <boost/asio/strand.hpp>
|
||||||
#include <boost/asio/thread_pool.hpp>
|
#include <boost/asio/thread_pool.hpp>
|
||||||
#include <boost/uuid/uuid.hpp>
|
#include <boost/uuid/uuid.hpp>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <latch>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -65,11 +68,14 @@ class ClusterCommunicationService : public ClusterCommunicationServiceInterface
|
|||||||
std::chrono::steady_clock::duration readInterval_;
|
std::chrono::steady_clock::duration readInterval_;
|
||||||
std::chrono::steady_clock::duration writeInterval_;
|
std::chrono::steady_clock::duration writeInterval_;
|
||||||
|
|
||||||
|
boost::asio::cancellation_signal cancelSignal_;
|
||||||
|
std::latch finishedCountdown_;
|
||||||
|
std::atomic_bool running_ = false;
|
||||||
|
bool stopped_ = false;
|
||||||
|
|
||||||
ClioNode selfData_;
|
ClioNode selfData_;
|
||||||
std::vector<ClioNode> otherNodesData_;
|
std::vector<ClioNode> otherNodesData_;
|
||||||
|
|
||||||
bool stopped_ = false;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr std::chrono::milliseconds kDEFAULT_READ_INTERVAL{2100};
|
static constexpr std::chrono::milliseconds kDEFAULT_READ_INTERVAL{2100};
|
||||||
static constexpr std::chrono::milliseconds kDEFAULT_WRITE_INTERVAL{1200};
|
static constexpr std::chrono::milliseconds kDEFAULT_WRITE_INTERVAL{1200};
|
||||||
|
|||||||
@@ -78,17 +78,20 @@ WritingAmendmentKey::WritingAmendmentKey(std::string amendmentName) : AmendmentK
|
|||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
AmendmentKey::operator std::string const&() const
|
AmendmentKey::
|
||||||
|
operator std::string const&() const
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
AmendmentKey::operator std::string_view() const
|
AmendmentKey::
|
||||||
|
operator std::string_view() const
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
AmendmentKey::operator ripple::uint256() const
|
AmendmentKey::
|
||||||
|
operator ripple::uint256() const
|
||||||
{
|
{
|
||||||
return Amendment::getAmendmentId(name);
|
return Amendment::getAmendmentId(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ struct Amendments {
|
|||||||
|
|
||||||
/** @cond */
|
/** @cond */
|
||||||
// NOLINTBEGIN(readability-identifier-naming)
|
// NOLINTBEGIN(readability-identifier-naming)
|
||||||
REGISTER(OwnerPaysFee);
|
|
||||||
REGISTER(Flow);
|
REGISTER(Flow);
|
||||||
REGISTER(FlowCross);
|
REGISTER(FlowCross);
|
||||||
REGISTER(fix1513);
|
REGISTER(fix1513);
|
||||||
@@ -145,6 +144,9 @@ struct Amendments {
|
|||||||
REGISTER(TokenEscrow);
|
REGISTER(TokenEscrow);
|
||||||
REGISTER(fixAMMv1_3);
|
REGISTER(fixAMMv1_3);
|
||||||
REGISTER(fixEnforceNFTokenTrustlineV2);
|
REGISTER(fixEnforceNFTokenTrustlineV2);
|
||||||
|
REGISTER(fixAMMClawbackRounding);
|
||||||
|
REGISTER(fixMPTDeliveredAmount);
|
||||||
|
REGISTER(fixPriceOracleOrder);
|
||||||
|
|
||||||
// Obsolete but supported by libxrpl
|
// Obsolete but supported by libxrpl
|
||||||
REGISTER(CryptoConditionsSuite);
|
REGISTER(CryptoConditionsSuite);
|
||||||
@@ -153,6 +155,7 @@ struct Amendments {
|
|||||||
REGISTER(fixNFTokenNegOffer);
|
REGISTER(fixNFTokenNegOffer);
|
||||||
|
|
||||||
// Retired amendments
|
// Retired amendments
|
||||||
|
REGISTER(OwnerPaysFee); // Removed in xrpl 2.6.0 (https://github.com/XRPLF/rippled/pull/5435)
|
||||||
REGISTER(MultiSign);
|
REGISTER(MultiSign);
|
||||||
REGISTER(TrustSetAuth);
|
REGISTER(TrustSetAuth);
|
||||||
REGISTER(FeeEscalation);
|
REGISTER(FeeEscalation);
|
||||||
|
|||||||
@@ -49,35 +49,45 @@ durationInMillisecondsSince(std::chrono::steady_clock::time_point const startTim
|
|||||||
using namespace util::prometheus;
|
using namespace util::prometheus;
|
||||||
|
|
||||||
BackendCounters::BackendCounters()
|
BackendCounters::BackendCounters()
|
||||||
: tooBusyCounter_(PrometheusService::counterInt(
|
: tooBusyCounter_(
|
||||||
"backend_too_busy_total_number",
|
PrometheusService::counterInt(
|
||||||
Labels(),
|
"backend_too_busy_total_number",
|
||||||
"The total number of times the backend was too busy to process a request"
|
Labels(),
|
||||||
))
|
"The total number of times the backend was too busy to process a request"
|
||||||
, writeSyncCounter_(PrometheusService::counterInt(
|
)
|
||||||
"backend_operations_total_number",
|
)
|
||||||
Labels({Label{"operation", "write_sync"}}),
|
, writeSyncCounter_(
|
||||||
"The total number of times the backend had to write synchronously"
|
PrometheusService::counterInt(
|
||||||
))
|
"backend_operations_total_number",
|
||||||
, writeSyncRetryCounter_(PrometheusService::counterInt(
|
Labels({Label{"operation", "write_sync"}}),
|
||||||
"backend_operations_total_number",
|
"The total number of times the backend had to write synchronously"
|
||||||
Labels({Label{"operation", "write_sync_retry"}}),
|
)
|
||||||
"The total number of times the backend had to retry a synchronous write"
|
)
|
||||||
))
|
, writeSyncRetryCounter_(
|
||||||
|
PrometheusService::counterInt(
|
||||||
|
"backend_operations_total_number",
|
||||||
|
Labels({Label{"operation", "write_sync_retry"}}),
|
||||||
|
"The total number of times the backend had to retry a synchronous write"
|
||||||
|
)
|
||||||
|
)
|
||||||
, asyncWriteCounters_{"write_async"}
|
, asyncWriteCounters_{"write_async"}
|
||||||
, asyncReadCounters_{"read_async"}
|
, asyncReadCounters_{"read_async"}
|
||||||
, readDurationHistogram_(PrometheusService::histogramInt(
|
, readDurationHistogram_(
|
||||||
"backend_duration_milliseconds_histogram",
|
PrometheusService::histogramInt(
|
||||||
Labels({Label{"operation", "read"}}),
|
"backend_duration_milliseconds_histogram",
|
||||||
kHISTOGRAM_BUCKETS,
|
Labels({Label{"operation", "read"}}),
|
||||||
"The duration of backend read operations including retries"
|
kHISTOGRAM_BUCKETS,
|
||||||
))
|
"The duration of backend read operations including retries"
|
||||||
, writeDurationHistogram_(PrometheusService::histogramInt(
|
)
|
||||||
"backend_duration_milliseconds_histogram",
|
)
|
||||||
Labels({Label{"operation", "write"}}),
|
, writeDurationHistogram_(
|
||||||
kHISTOGRAM_BUCKETS,
|
PrometheusService::histogramInt(
|
||||||
"The duration of backend write operations including retries"
|
"backend_duration_milliseconds_histogram",
|
||||||
))
|
Labels({Label{"operation", "write"}}),
|
||||||
|
kHISTOGRAM_BUCKETS,
|
||||||
|
"The duration of backend write operations including retries"
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,26 +180,34 @@ BackendCounters::report() const
|
|||||||
|
|
||||||
BackendCounters::AsyncOperationCounters::AsyncOperationCounters(std::string name)
|
BackendCounters::AsyncOperationCounters::AsyncOperationCounters(std::string name)
|
||||||
: name_(std::move(name))
|
: name_(std::move(name))
|
||||||
, pendingCounter_(PrometheusService::gaugeInt(
|
, pendingCounter_(
|
||||||
"backend_operations_current_number",
|
PrometheusService::gaugeInt(
|
||||||
Labels({{"operation", name_}, {"status", "pending"}}),
|
"backend_operations_current_number",
|
||||||
"The current number of pending " + name_ + " operations"
|
Labels({{"operation", name_}, {"status", "pending"}}),
|
||||||
))
|
"The current number of pending " + name_ + " operations"
|
||||||
, completedCounter_(PrometheusService::counterInt(
|
)
|
||||||
"backend_operations_total_number",
|
)
|
||||||
Labels({{"operation", name_}, {"status", "completed"}}),
|
, completedCounter_(
|
||||||
"The total number of completed " + name_ + " operations"
|
PrometheusService::counterInt(
|
||||||
))
|
"backend_operations_total_number",
|
||||||
, retryCounter_(PrometheusService::counterInt(
|
Labels({{"operation", name_}, {"status", "completed"}}),
|
||||||
"backend_operations_total_number",
|
"The total number of completed " + name_ + " operations"
|
||||||
Labels({{"operation", name_}, {"status", "retry"}}),
|
)
|
||||||
"The total number of retried " + name_ + " operations"
|
)
|
||||||
))
|
, retryCounter_(
|
||||||
, errorCounter_(PrometheusService::counterInt(
|
PrometheusService::counterInt(
|
||||||
"backend_operations_total_number",
|
"backend_operations_total_number",
|
||||||
Labels({{"operation", name_}, {"status", "error"}}),
|
Labels({{"operation", name_}, {"status", "retry"}}),
|
||||||
"The total number of errored " + name_ + " operations"
|
"The total number of retried " + name_ + " operations"
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
, errorCounter_(
|
||||||
|
PrometheusService::counterInt(
|
||||||
|
"backend_operations_total_number",
|
||||||
|
Labels({{"operation", name_}, {"status", "error"}}),
|
||||||
|
"The total number of errored " + name_ + " operations"
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,11 +43,6 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// local to compilation unit loggers
|
|
||||||
namespace {
|
|
||||||
util::Logger gLog{"Backend"};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This namespace implements the data access layer and related components.
|
* @brief This namespace implements the data access layer and related components.
|
||||||
*
|
*
|
||||||
@@ -58,10 +53,10 @@ namespace data {
|
|||||||
bool
|
bool
|
||||||
BackendInterface::finishWrites(std::uint32_t const ledgerSequence)
|
BackendInterface::finishWrites(std::uint32_t const ledgerSequence)
|
||||||
{
|
{
|
||||||
LOG(gLog.debug()) << "Want finish writes for " << ledgerSequence;
|
LOG(log_.debug()) << "Want finish writes for " << ledgerSequence;
|
||||||
auto commitRes = doFinishWrites();
|
auto commitRes = doFinishWrites();
|
||||||
if (commitRes) {
|
if (commitRes) {
|
||||||
LOG(gLog.debug()) << "Successfully committed. Updating range now to " << ledgerSequence;
|
LOG(log_.debug()) << "Successfully committed. Updating range now to " << ledgerSequence;
|
||||||
updateRange(ledgerSequence);
|
updateRange(ledgerSequence);
|
||||||
}
|
}
|
||||||
return commitRes;
|
return commitRes;
|
||||||
@@ -89,15 +84,15 @@ BackendInterface::fetchLedgerObject(
|
|||||||
{
|
{
|
||||||
auto obj = cache_.get().get(key, sequence);
|
auto obj = cache_.get().get(key, sequence);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
LOG(gLog.trace()) << "Cache hit - " << ripple::strHex(key);
|
LOG(log_.trace()) << "Cache hit - " << ripple::strHex(key);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dbObj = doFetchLedgerObject(key, sequence, yield);
|
auto dbObj = doFetchLedgerObject(key, sequence, yield);
|
||||||
if (!dbObj) {
|
if (!dbObj) {
|
||||||
LOG(gLog.trace()) << "Missed cache and missed in db";
|
LOG(log_.trace()) << "Missed cache and missed in db";
|
||||||
} else {
|
} else {
|
||||||
LOG(gLog.trace()) << "Missed cache but found in db";
|
LOG(log_.trace()) << "Missed cache but found in db";
|
||||||
}
|
}
|
||||||
return dbObj;
|
return dbObj;
|
||||||
}
|
}
|
||||||
@@ -111,7 +106,7 @@ BackendInterface::fetchLedgerObjectSeq(
|
|||||||
{
|
{
|
||||||
auto seq = doFetchLedgerObjectSeq(key, sequence, yield);
|
auto seq = doFetchLedgerObjectSeq(key, sequence, yield);
|
||||||
if (!seq)
|
if (!seq)
|
||||||
LOG(gLog.trace()) << "Missed in db";
|
LOG(log_.trace()) << "Missed in db";
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +128,7 @@ BackendInterface::fetchLedgerObjects(
|
|||||||
misses.push_back(keys[i]);
|
misses.push_back(keys[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG(gLog.trace()) << "Cache hits = " << keys.size() - misses.size() << " - cache misses = " << misses.size();
|
LOG(log_.trace()) << "Cache hits = " << keys.size() - misses.size() << " - cache misses = " << misses.size();
|
||||||
|
|
||||||
if (!misses.empty()) {
|
if (!misses.empty()) {
|
||||||
auto objs = doFetchLedgerObjects(misses, sequence, yield);
|
auto objs = doFetchLedgerObjects(misses, sequence, yield);
|
||||||
@@ -158,9 +153,9 @@ BackendInterface::fetchSuccessorKey(
|
|||||||
{
|
{
|
||||||
auto succ = cache_.get().getSuccessor(key, ledgerSequence);
|
auto succ = cache_.get().getSuccessor(key, ledgerSequence);
|
||||||
if (succ) {
|
if (succ) {
|
||||||
LOG(gLog.trace()) << "Cache hit - " << ripple::strHex(key);
|
LOG(log_.trace()) << "Cache hit - " << ripple::strHex(key);
|
||||||
} else {
|
} else {
|
||||||
LOG(gLog.trace()) << "Cache miss - " << ripple::strHex(key);
|
LOG(log_.trace()) << "Cache miss - " << ripple::strHex(key);
|
||||||
}
|
}
|
||||||
return succ ? succ->key : doFetchSuccessorKey(key, ledgerSequence, yield);
|
return succ ? succ->key : doFetchSuccessorKey(key, ledgerSequence, yield);
|
||||||
}
|
}
|
||||||
@@ -210,7 +205,7 @@ BackendInterface::fetchBookOffers(
|
|||||||
numSucc++;
|
numSucc++;
|
||||||
succMillis += getMillis(mid2 - mid1);
|
succMillis += getMillis(mid2 - mid1);
|
||||||
if (!offerDir || offerDir->key >= bookEnd) {
|
if (!offerDir || offerDir->key >= bookEnd) {
|
||||||
LOG(gLog.trace()) << "offerDir.has_value() " << offerDir.has_value() << " breaking";
|
LOG(log_.trace()) << "offerDir.has_value() " << offerDir.has_value() << " breaking";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uTipIndex = offerDir->key;
|
uTipIndex = offerDir->key;
|
||||||
@@ -223,7 +218,7 @@ BackendInterface::fetchBookOffers(
|
|||||||
keys.insert(keys.end(), indexes.begin(), indexes.end());
|
keys.insert(keys.end(), indexes.begin(), indexes.end());
|
||||||
auto next = sle.getFieldU64(ripple::sfIndexNext);
|
auto next = sle.getFieldU64(ripple::sfIndexNext);
|
||||||
if (next == 0u) {
|
if (next == 0u) {
|
||||||
LOG(gLog.trace()) << "Next is empty. breaking";
|
LOG(log_.trace()) << "Next is empty. breaking";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto nextKey = ripple::keylet::page(uTipIndex, next);
|
auto nextKey = ripple::keylet::page(uTipIndex, next);
|
||||||
@@ -238,13 +233,13 @@ BackendInterface::fetchBookOffers(
|
|||||||
auto mid = std::chrono::system_clock::now();
|
auto mid = std::chrono::system_clock::now();
|
||||||
auto objs = fetchLedgerObjects(keys, ledgerSequence, yield);
|
auto objs = fetchLedgerObjects(keys, ledgerSequence, yield);
|
||||||
for (size_t i = 0; i < keys.size() && i < limit; ++i) {
|
for (size_t i = 0; i < keys.size() && i < limit; ++i) {
|
||||||
LOG(gLog.trace()) << "Key = " << ripple::strHex(keys[i]) << " blob = " << ripple::strHex(objs[i])
|
LOG(log_.trace()) << "Key = " << ripple::strHex(keys[i]) << " blob = " << ripple::strHex(objs[i])
|
||||||
<< " ledgerSequence = " << ledgerSequence;
|
<< " ledgerSequence = " << ledgerSequence;
|
||||||
ASSERT(!objs[i].empty(), "Ledger object can't be empty");
|
ASSERT(!objs[i].empty(), "Ledger object can't be empty");
|
||||||
page.offers.push_back({keys[i], objs[i]});
|
page.offers.push_back({keys[i], objs[i]});
|
||||||
}
|
}
|
||||||
auto end = std::chrono::system_clock::now();
|
auto end = std::chrono::system_clock::now();
|
||||||
LOG(gLog.debug()) << "Fetching " << std::to_string(keys.size()) << " offers took "
|
LOG(log_.debug()) << "Fetching " << std::to_string(keys.size()) << " offers took "
|
||||||
<< std::to_string(getMillis(mid - begin)) << " milliseconds. Fetching next dir took "
|
<< std::to_string(getMillis(mid - begin)) << " milliseconds. Fetching next dir took "
|
||||||
<< std::to_string(succMillis) << " milliseconds. Fetched next dir " << std::to_string(numSucc)
|
<< std::to_string(succMillis) << " milliseconds. Fetched next dir " << std::to_string(numSucc)
|
||||||
<< " times"
|
<< " times"
|
||||||
@@ -275,14 +270,17 @@ BackendInterface::updateRange(uint32_t newMax)
|
|||||||
{
|
{
|
||||||
std::scoped_lock const lck(rngMtx_);
|
std::scoped_lock const lck(rngMtx_);
|
||||||
|
|
||||||
ASSERT(
|
if (range_.has_value() && newMax < range_->maxSequence) {
|
||||||
!range_ || newMax >= range_->maxSequence,
|
ASSERT(
|
||||||
"Range shouldn't exist yet or newMax should be greater. newMax = {}, range->maxSequence = {}",
|
false,
|
||||||
newMax,
|
"Range shouldn't exist yet or newMax should be at least range->maxSequence. newMax = {}, "
|
||||||
range_->maxSequence
|
"range->maxSequence = {}",
|
||||||
);
|
newMax,
|
||||||
|
range_->maxSequence
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!range_) {
|
if (!range_.has_value()) {
|
||||||
range_ = {.minSequence = newMax, .maxSequence = newMax};
|
range_ = {.minSequence = newMax, .maxSequence = newMax};
|
||||||
} else {
|
} else {
|
||||||
range_->maxSequence = newMax;
|
range_->maxSequence = newMax;
|
||||||
@@ -338,13 +336,13 @@ BackendInterface::fetchLedgerPage(
|
|||||||
if (!objects[i].empty()) {
|
if (!objects[i].empty()) {
|
||||||
page.objects.push_back({keys[i], std::move(objects[i])});
|
page.objects.push_back({keys[i], std::move(objects[i])});
|
||||||
} else if (!outOfOrder) {
|
} else if (!outOfOrder) {
|
||||||
LOG(gLog.error()) << "Deleted or non-existent object in successor table. key = " << ripple::strHex(keys[i])
|
LOG(log_.error()) << "Deleted or non-existent object in successor table. key = " << ripple::strHex(keys[i])
|
||||||
<< " - seq = " << ledgerSequence;
|
<< " - seq = " << ledgerSequence;
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
for (size_t j = 0; j < objects.size(); ++j) {
|
for (size_t j = 0; j < objects.size(); ++j) {
|
||||||
msg << " - " << ripple::strHex(keys[j]);
|
msg << " - " << ripple::strHex(keys[j]);
|
||||||
}
|
}
|
||||||
LOG(gLog.error()) << msg.str();
|
LOG(log_.error()) << msg.str();
|
||||||
|
|
||||||
if (corruptionDetector_.has_value())
|
if (corruptionDetector_.has_value())
|
||||||
corruptionDetector_->onCorruptionDetected();
|
corruptionDetector_->onCorruptionDetected();
|
||||||
@@ -365,7 +363,7 @@ BackendInterface::fetchFees(std::uint32_t const seq, boost::asio::yield_context
|
|||||||
auto bytes = fetchLedgerObject(key, seq, yield);
|
auto bytes = fetchLedgerObject(key, seq, yield);
|
||||||
|
|
||||||
if (!bytes) {
|
if (!bytes) {
|
||||||
LOG(gLog.error()) << "Could not find fees";
|
LOG(log_.error()) << "Could not find fees";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "data/LedgerCacheInterface.hpp"
|
#include "data/LedgerCacheInterface.hpp"
|
||||||
#include "data/Types.hpp"
|
#include "data/Types.hpp"
|
||||||
#include "etl/CorruptionDetector.hpp"
|
#include "etl/CorruptionDetector.hpp"
|
||||||
|
#include "util/Spawn.hpp"
|
||||||
#include "util/log/Logger.hpp"
|
#include "util/log/Logger.hpp"
|
||||||
|
|
||||||
#include <boost/asio/executor_work_guard.hpp>
|
#include <boost/asio/executor_work_guard.hpp>
|
||||||
@@ -108,14 +109,12 @@ synchronous(FnType&& func)
|
|||||||
using R = typename boost::result_of<FnType(boost::asio::yield_context)>::type;
|
using R = typename boost::result_of<FnType(boost::asio::yield_context)>::type;
|
||||||
if constexpr (!std::is_same_v<R, void>) {
|
if constexpr (!std::is_same_v<R, void>) {
|
||||||
R res;
|
R res;
|
||||||
boost::asio::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func, &res](auto yield) {
|
util::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func, &res](auto yield) { res = func(yield); });
|
||||||
res = func(yield);
|
|
||||||
});
|
|
||||||
|
|
||||||
ctx.run();
|
ctx.run();
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
boost::asio::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func](auto yield) { func(yield); });
|
util::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func](auto yield) { func(yield); });
|
||||||
ctx.run();
|
ctx.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,6 +138,7 @@ synchronousAndRetryOnTimeout(FnType&& func)
|
|||||||
*/
|
*/
|
||||||
class BackendInterface {
|
class BackendInterface {
|
||||||
protected:
|
protected:
|
||||||
|
util::Logger log_{"Backend"};
|
||||||
mutable std::shared_mutex rngMtx_;
|
mutable std::shared_mutex rngMtx_;
|
||||||
std::optional<LedgerRange> range_;
|
std::optional<LedgerRange> range_;
|
||||||
std::reference_wrapper<LedgerCacheInterface> cache_;
|
std::reference_wrapper<LedgerCacheInterface> cache_;
|
||||||
@@ -234,8 +234,12 @@ public:
|
|||||||
* @return A vector of ripple::uint256 representing the account roots
|
* @return A vector of ripple::uint256 representing the account roots
|
||||||
*/
|
*/
|
||||||
virtual std::vector<ripple::uint256>
|
virtual std::vector<ripple::uint256>
|
||||||
fetchAccountRoots(std::uint32_t number, std::uint32_t pageSize, std::uint32_t seq, boost::asio::yield_context yield)
|
fetchAccountRoots(
|
||||||
const = 0;
|
std::uint32_t number,
|
||||||
|
std::uint32_t pageSize,
|
||||||
|
std::uint32_t seq,
|
||||||
|
boost::asio::yield_context yield
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Updates the range of sequences that are stored in the DB.
|
* @brief Updates the range of sequences that are stored in the DB.
|
||||||
@@ -459,8 +463,11 @@ public:
|
|||||||
* @return The sequence in unit32_t on success; nullopt otherwise
|
* @return The sequence in unit32_t on success; nullopt otherwise
|
||||||
*/
|
*/
|
||||||
virtual std::optional<std::uint32_t>
|
virtual std::optional<std::uint32_t>
|
||||||
doFetchLedgerObjectSeq(ripple::uint256 const& key, std::uint32_t sequence, boost::asio::yield_context yield)
|
doFetchLedgerObjectSeq(
|
||||||
const = 0;
|
ripple::uint256 const& key,
|
||||||
|
std::uint32_t sequence,
|
||||||
|
boost::asio::yield_context yield
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The database-specific implementation for fetching ledger objects.
|
* @brief The database-specific implementation for fetching ledger objects.
|
||||||
|
|||||||
@@ -361,8 +361,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ripple::uint256>
|
std::vector<ripple::uint256>
|
||||||
fetchAllTransactionHashesInLedger(std::uint32_t const ledgerSequence, boost::asio::yield_context yield)
|
fetchAllTransactionHashesInLedger(
|
||||||
const override
|
std::uint32_t const ledgerSequence,
|
||||||
|
boost::asio::yield_context yield
|
||||||
|
) const override
|
||||||
{
|
{
|
||||||
auto start = std::chrono::system_clock::now();
|
auto start = std::chrono::system_clock::now();
|
||||||
auto const res = executor_.read(yield, schema_->selectAllTransactionHashesInLedger, ledgerSequence);
|
auto const res = executor_.read(yield, schema_->selectAllTransactionHashesInLedger, ledgerSequence);
|
||||||
@@ -392,8 +394,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<NFT>
|
std::optional<NFT>
|
||||||
fetchNFT(ripple::uint256 const& tokenID, std::uint32_t const ledgerSequence, boost::asio::yield_context yield)
|
fetchNFT(
|
||||||
const override
|
ripple::uint256 const& tokenID,
|
||||||
|
std::uint32_t const ledgerSequence,
|
||||||
|
boost::asio::yield_context yield
|
||||||
|
) const override
|
||||||
{
|
{
|
||||||
auto const res = executor_.read(yield, schema_->selectNFT, tokenID, ledgerSequence);
|
auto const res = executor_.read(yield, schema_->selectNFT, tokenID, ledgerSequence);
|
||||||
if (not res)
|
if (not res)
|
||||||
@@ -554,10 +559,9 @@ public:
|
|||||||
selectNFTStatements.reserve(nftIDs.size());
|
selectNFTStatements.reserve(nftIDs.size());
|
||||||
|
|
||||||
std::transform(
|
std::transform(
|
||||||
std::cbegin(nftIDs),
|
std::cbegin(nftIDs), std::cend(nftIDs), std::back_inserter(selectNFTStatements), [&](auto const& nftID) {
|
||||||
std::cend(nftIDs),
|
return schema_->selectNFT.bind(nftID, ledgerSequence);
|
||||||
std::back_inserter(selectNFTStatements),
|
}
|
||||||
[&](auto const& nftID) { return schema_->selectNFT.bind(nftID, ledgerSequence); }
|
|
||||||
);
|
);
|
||||||
|
|
||||||
auto const nftInfos = executor_.readEach(yield, selectNFTStatements);
|
auto const nftInfos = executor_.readEach(yield, selectNFTStatements);
|
||||||
@@ -566,10 +570,9 @@ public:
|
|||||||
selectNFTURIStatements.reserve(nftIDs.size());
|
selectNFTURIStatements.reserve(nftIDs.size());
|
||||||
|
|
||||||
std::transform(
|
std::transform(
|
||||||
std::cbegin(nftIDs),
|
std::cbegin(nftIDs), std::cend(nftIDs), std::back_inserter(selectNFTURIStatements), [&](auto const& nftID) {
|
||||||
std::cend(nftIDs),
|
return schema_->selectNFTURI.bind(nftID, ledgerSequence);
|
||||||
std::back_inserter(selectNFTURIStatements),
|
}
|
||||||
[&](auto const& nftID) { return schema_->selectNFTURI.bind(nftID, ledgerSequence); }
|
|
||||||
);
|
);
|
||||||
|
|
||||||
auto const nftUris = executor_.readEach(yield, selectNFTURIStatements);
|
auto const nftUris = executor_.readEach(yield, selectNFTURIStatements);
|
||||||
@@ -626,8 +629,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Blob>
|
std::optional<Blob>
|
||||||
doFetchLedgerObject(ripple::uint256 const& key, std::uint32_t const sequence, boost::asio::yield_context yield)
|
doFetchLedgerObject(
|
||||||
const override
|
ripple::uint256 const& key,
|
||||||
|
std::uint32_t const sequence,
|
||||||
|
boost::asio::yield_context yield
|
||||||
|
) const override
|
||||||
{
|
{
|
||||||
LOG(log_.debug()) << "Fetching ledger object for seq " << sequence << ", key = " << ripple::to_string(key);
|
LOG(log_.debug()) << "Fetching ledger object for seq " << sequence << ", key = " << ripple::to_string(key);
|
||||||
if (auto const res = executor_.read(yield, schema_->selectObject, key, sequence); res) {
|
if (auto const res = executor_.read(yield, schema_->selectObject, key, sequence); res) {
|
||||||
@@ -645,8 +651,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::uint32_t>
|
std::optional<std::uint32_t>
|
||||||
doFetchLedgerObjectSeq(ripple::uint256 const& key, std::uint32_t const sequence, boost::asio::yield_context yield)
|
doFetchLedgerObjectSeq(
|
||||||
const override
|
ripple::uint256 const& key,
|
||||||
|
std::uint32_t const sequence,
|
||||||
|
boost::asio::yield_context yield
|
||||||
|
) const override
|
||||||
{
|
{
|
||||||
LOG(log_.debug()) << "Fetching ledger object for seq " << sequence << ", key = " << ripple::to_string(key);
|
LOG(log_.debug()) << "Fetching ledger object for seq " << sequence << ", key = " << ripple::to_string(key);
|
||||||
if (auto const res = executor_.read(yield, schema_->selectObject, key, sequence); res) {
|
if (auto const res = executor_.read(yield, schema_->selectObject, key, sequence); res) {
|
||||||
@@ -680,8 +689,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ripple::uint256>
|
std::optional<ripple::uint256>
|
||||||
doFetchSuccessorKey(ripple::uint256 key, std::uint32_t const ledgerSequence, boost::asio::yield_context yield)
|
doFetchSuccessorKey(
|
||||||
const override
|
ripple::uint256 key,
|
||||||
|
std::uint32_t const ledgerSequence,
|
||||||
|
boost::asio::yield_context yield
|
||||||
|
) const override
|
||||||
{
|
{
|
||||||
if (auto const res = executor_.read(yield, schema_->selectSuccessor, key, ledgerSequence); res) {
|
if (auto const res = executor_.read(yield, schema_->selectSuccessor, key, ledgerSequence); res) {
|
||||||
if (auto const result = res->template get<ripple::uint256>(); result) {
|
if (auto const result = res->template get<ripple::uint256>(); result) {
|
||||||
@@ -714,10 +726,9 @@ public:
|
|||||||
auto const timeDiff = util::timed([this, yield, &results, &hashes, &statements]() {
|
auto const timeDiff = util::timed([this, yield, &results, &hashes, &statements]() {
|
||||||
// TODO: seems like a job for "hash IN (list of hashes)" instead?
|
// TODO: seems like a job for "hash IN (list of hashes)" instead?
|
||||||
std::transform(
|
std::transform(
|
||||||
std::cbegin(hashes),
|
std::cbegin(hashes), std::cend(hashes), std::back_inserter(statements), [this](auto const& hash) {
|
||||||
std::cend(hashes),
|
return schema_->selectTransaction.bind(hash);
|
||||||
std::back_inserter(statements),
|
}
|
||||||
[this](auto const& hash) { return schema_->selectTransaction.bind(hash); }
|
|
||||||
);
|
);
|
||||||
|
|
||||||
auto const entries = executor_.readEach(yield, statements);
|
auto const entries = executor_.readEach(yield, statements);
|
||||||
@@ -761,18 +772,14 @@ public:
|
|||||||
|
|
||||||
// TODO: seems like a job for "key IN (list of keys)" instead?
|
// TODO: seems like a job for "key IN (list of keys)" instead?
|
||||||
std::transform(
|
std::transform(
|
||||||
std::cbegin(keys),
|
std::cbegin(keys), std::cend(keys), std::back_inserter(statements), [this, &sequence](auto const& key) {
|
||||||
std::cend(keys),
|
return schema_->selectObject.bind(key, sequence);
|
||||||
std::back_inserter(statements),
|
}
|
||||||
[this, &sequence](auto const& key) { return schema_->selectObject.bind(key, sequence); }
|
|
||||||
);
|
);
|
||||||
|
|
||||||
auto const entries = executor_.readEach(yield, statements);
|
auto const entries = executor_.readEach(yield, statements);
|
||||||
std::transform(
|
std::transform(
|
||||||
std::cbegin(entries),
|
std::cbegin(entries), std::cend(entries), std::back_inserter(results), [](auto const& res) -> Blob {
|
||||||
std::cend(entries),
|
|
||||||
std::back_inserter(results),
|
|
||||||
[](auto const& res) -> Blob {
|
|
||||||
if (auto const maybeValue = res.template get<Blob>(); maybeValue)
|
if (auto const maybeValue = res.template get<Blob>(); maybeValue)
|
||||||
return *maybeValue;
|
return *maybeValue;
|
||||||
|
|
||||||
@@ -785,8 +792,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ripple::uint256>
|
std::vector<ripple::uint256>
|
||||||
fetchAccountRoots(std::uint32_t number, std::uint32_t pageSize, std::uint32_t seq, boost::asio::yield_context yield)
|
fetchAccountRoots(
|
||||||
const override
|
std::uint32_t number,
|
||||||
|
std::uint32_t pageSize,
|
||||||
|
std::uint32_t seq,
|
||||||
|
boost::asio::yield_context yield
|
||||||
|
) const override
|
||||||
{
|
{
|
||||||
std::vector<ripple::uint256> liveAccounts;
|
std::vector<ripple::uint256> liveAccounts;
|
||||||
std::optional<ripple::AccountID> lastItem;
|
std::optional<ripple::AccountID> lastItem;
|
||||||
|
|||||||
@@ -198,39 +198,6 @@ struct MPTHolderData {
|
|||||||
ripple::AccountID holder;
|
ripple::AccountID holder;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check whether the supplied object is an offer.
|
|
||||||
*
|
|
||||||
* @param object The object to check
|
|
||||||
* @return true if the object is an offer; false otherwise
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
inline bool
|
|
||||||
isOffer(T const& object)
|
|
||||||
{
|
|
||||||
static constexpr short kOFFER_OFFSET = 0x006f;
|
|
||||||
static constexpr short kSHIFT = 8;
|
|
||||||
|
|
||||||
short offerBytes = (object[1] << kSHIFT) | object[2];
|
|
||||||
return offerBytes == kOFFER_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check whether the supplied hex represents an offer object.
|
|
||||||
*
|
|
||||||
* @param object The object to check
|
|
||||||
* @return true if the object is an offer; false otherwise
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
inline bool
|
|
||||||
isOfferHex(T const& object)
|
|
||||||
{
|
|
||||||
auto blob = ripple::strUnHex(4, object.begin(), object.begin() + 4);
|
|
||||||
if (blob)
|
|
||||||
return isOffer(*blob);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check whether the supplied object is a dir node.
|
* @brief Check whether the supplied object is a dir node.
|
||||||
*
|
*
|
||||||
@@ -241,6 +208,10 @@ template <typename T>
|
|||||||
inline bool
|
inline bool
|
||||||
isDirNode(T const& object)
|
isDirNode(T const& object)
|
||||||
{
|
{
|
||||||
|
static constexpr auto kMIN_SIZE_REQUIRED = 3;
|
||||||
|
if (std::size(object) < kMIN_SIZE_REQUIRED)
|
||||||
|
return false;
|
||||||
|
|
||||||
static constexpr short kDIR_NODE_SPACE_KEY = 0x0064;
|
static constexpr short kDIR_NODE_SPACE_KEY = 0x0064;
|
||||||
short const spaceKey = (object.data()[1] << 8) | object.data()[2];
|
short const spaceKey = (object.data()[1] << 8) | object.data()[2];
|
||||||
return spaceKey == kDIR_NODE_SPACE_KEY;
|
return spaceKey == kDIR_NODE_SPACE_KEY;
|
||||||
@@ -264,23 +235,6 @@ isBookDir(T const& key, R const& object)
|
|||||||
return !sle[~ripple::sfOwner].has_value();
|
return !sle[~ripple::sfOwner].has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the book out of an offer object.
|
|
||||||
*
|
|
||||||
* @param offer The offer to get the book for
|
|
||||||
* @return Book as ripple::uint256
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
inline ripple::uint256
|
|
||||||
getBook(T const& offer)
|
|
||||||
{
|
|
||||||
ripple::SerialIter it{offer.data(), offer.size()};
|
|
||||||
ripple::SLE const sle{it, {}};
|
|
||||||
ripple::uint256 book = sle.getFieldH256(ripple::sfBookDirectory);
|
|
||||||
|
|
||||||
return book;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the book base.
|
* @brief Get the book base.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ To support additional database types, you can create new classes that implement
|
|||||||
|
|
||||||
## Data Model
|
## Data Model
|
||||||
|
|
||||||
The data model used by Clio to read and write ledger data is different from what `rippled` uses. `rippled` uses a novel data structure named [_SHAMap_](https://github.com/ripple/rippled/blob/master/src/ripple/shamap/README.md), which is a combination of a Merkle Tree and a Radix Trie. In a SHAMap, ledger objects are stored in the root vertices of the tree. Thus, looking up a record located at the leaf node of the SHAMap executes a tree search, where the path from the root node to the leaf node is the key of the record.
|
The data model used by Clio to read and write ledger data is different from what `rippled` uses. `rippled` uses a novel data structure named [_SHAMap_](https://github.com/XRPLF/rippled/blob/develop/src/xrpld/shamap/README.md), which is a combination of a Merkle Tree and a Radix Trie. In a SHAMap, ledger objects are stored in the root vertices of the tree. Thus, looking up a record located at the leaf node of the SHAMap executes a tree search, where the path from the root node to the leaf node is the key of the record.
|
||||||
|
|
||||||
`rippled` nodes can also generate a proof-tree by forming a subtree with all the path nodes and their neighbors, which can then be used to prove the existence of the leaf node data to other `rippled` nodes. In short, the main purpose of the SHAMap data structure is to facilitate the fast validation of data integrity between different decentralized `rippled` nodes.
|
`rippled` nodes can also generate a proof-tree by forming a subtree with all the path nodes and their neighbors, which can then be used to prove the existence of the leaf node data to other `rippled` nodes. In short, the main purpose of the SHAMap data structure is to facilitate the fast validation of data integrity between different decentralized `rippled` nodes.
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
connect() const;
|
connect() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Connect to the the specified keyspace asynchronously.
|
* @brief Connect to the specified keyspace asynchronously.
|
||||||
*
|
*
|
||||||
* @param keyspace The keyspace to use
|
* @param keyspace The keyspace to use
|
||||||
* @return A future
|
* @return A future
|
||||||
@@ -137,7 +137,7 @@ public:
|
|||||||
disconnect() const;
|
disconnect() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reconnect to the the specified keyspace asynchronously.
|
* @brief Reconnect to the specified keyspace asynchronously.
|
||||||
*
|
*
|
||||||
* @param keyspace The keyspace to use
|
* @param keyspace The keyspace to use
|
||||||
* @return A future
|
* @return A future
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,8 +25,8 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace data::cassandra {
|
namespace data::cassandra {
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
struct Settings;
|
struct Settings;
|
||||||
class Session;
|
class Session;
|
||||||
class Cluster;
|
class Cluster;
|
||||||
@@ -36,6 +36,7 @@ struct Result;
|
|||||||
class Statement;
|
class Statement;
|
||||||
class PreparedStatement;
|
class PreparedStatement;
|
||||||
struct Batch;
|
struct Batch;
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
using Settings = impl::Settings;
|
using Settings = impl::Settings;
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ Cluster::Cluster(Settings const& settings) : ManagedObject{cass_cluster_new(), k
|
|||||||
|
|
||||||
cass_cluster_set_token_aware_routing(*this, cass_true);
|
cass_cluster_set_token_aware_routing(*this, cass_true);
|
||||||
if (auto const rc = cass_cluster_set_protocol_version(*this, CASS_PROTOCOL_VERSION_V4); rc != CASS_OK) {
|
if (auto const rc = cass_cluster_set_protocol_version(*this, CASS_PROTOCOL_VERSION_V4); rc != CASS_OK) {
|
||||||
throw std::runtime_error(fmt::format("Error setting cassandra protocol version to v4: {}", cass_error_desc(rc))
|
throw std::runtime_error(
|
||||||
|
fmt::format("Error setting cassandra protocol version to v4: {}", cass_error_desc(rc))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/asio/associated_executor.hpp>
|
#include <boost/asio/associated_executor.hpp>
|
||||||
|
#include <boost/asio/executor_work_guard.hpp>
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
#include <boost/asio/io_service.hpp>
|
|
||||||
#include <boost/asio/spawn.hpp>
|
#include <boost/asio/spawn.hpp>
|
||||||
#include <boost/json/object.hpp>
|
#include <boost/json/object.hpp>
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ class DefaultExecutionStrategy {
|
|||||||
std::condition_variable syncCv_;
|
std::condition_variable syncCv_;
|
||||||
|
|
||||||
boost::asio::io_context ioc_;
|
boost::asio::io_context ioc_;
|
||||||
std::optional<boost::asio::io_service::work> work_;
|
std::optional<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> work_;
|
||||||
|
|
||||||
std::reference_wrapper<HandleType const> handle_;
|
std::reference_wrapper<HandleType const> handle_;
|
||||||
std::thread thread_;
|
std::thread thread_;
|
||||||
@@ -107,7 +107,7 @@ public:
|
|||||||
: maxWriteRequestsOutstanding_{settings.maxWriteRequestsOutstanding}
|
: maxWriteRequestsOutstanding_{settings.maxWriteRequestsOutstanding}
|
||||||
, maxReadRequestsOutstanding_{settings.maxReadRequestsOutstanding}
|
, maxReadRequestsOutstanding_{settings.maxReadRequestsOutstanding}
|
||||||
, writeBatchSize_{settings.writeBatchSize}
|
, writeBatchSize_{settings.writeBatchSize}
|
||||||
, work_{ioc_}
|
, work_{boost::asio::make_work_guard(ioc_)}
|
||||||
, handle_{std::cref(handle)}
|
, handle_{std::cref(handle)}
|
||||||
, thread_{[this]() { ioc_.run(); }}
|
, thread_{[this]() { ioc_.run(); }}
|
||||||
, counters_{std::move(counters)}
|
, counters_{std::move(counters)}
|
||||||
@@ -334,7 +334,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto res = boost::asio::async_compose<CompletionTokenType, void(ResultOrErrorType)>(
|
auto res = boost::asio::async_compose<CompletionTokenType, void(ResultOrErrorType)>(
|
||||||
init, token, boost::asio::get_associated_executor(token)
|
std::move(init), token, boost::asio::get_associated_executor(token)
|
||||||
);
|
);
|
||||||
numReadRequestsOutstanding_ -= numStatements;
|
numReadRequestsOutstanding_ -= numStatements;
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto res = boost::asio::async_compose<CompletionTokenType, void(ResultOrErrorType)>(
|
auto res = boost::asio::async_compose<CompletionTokenType, void(ResultOrErrorType)>(
|
||||||
init, token, boost::asio::get_associated_executor(token)
|
std::move(init), token, boost::asio::get_associated_executor(token)
|
||||||
);
|
);
|
||||||
--numReadRequestsOutstanding_;
|
--numReadRequestsOutstanding_;
|
||||||
|
|
||||||
@@ -456,7 +456,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
boost::asio::async_compose<CompletionTokenType, void()>(
|
boost::asio::async_compose<CompletionTokenType, void()>(
|
||||||
init, token, boost::asio::get_associated_executor(token)
|
std::move(init), token, boost::asio::get_associated_executor(token)
|
||||||
);
|
);
|
||||||
numReadRequestsOutstanding_ -= statements.size();
|
numReadRequestsOutstanding_ -= statements.size();
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,13 @@ public:
|
|||||||
* @brief Create a new retry policy instance with the io_context provided
|
* @brief Create a new retry policy instance with the io_context provided
|
||||||
*/
|
*/
|
||||||
ExponentialBackoffRetryPolicy(boost::asio::io_context& ioc)
|
ExponentialBackoffRetryPolicy(boost::asio::io_context& ioc)
|
||||||
: retry_(util::makeRetryExponentialBackoff(
|
: retry_(
|
||||||
std::chrono::milliseconds(1),
|
util::makeRetryExponentialBackoff(
|
||||||
std::chrono::seconds(1),
|
std::chrono::milliseconds(1),
|
||||||
boost::asio::make_strand(ioc)
|
std::chrono::seconds(1),
|
||||||
))
|
boost::asio::make_strand(ioc)
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user