Compare commits

..

1 Commits

Author SHA1 Message Date
Bart
de22922517 ci: Run PR title and description checks on staging and release branches (#7331)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-27 17:16:21 +00:00
56 changed files with 401 additions and 800 deletions

View File

@@ -37,12 +37,12 @@ runs:
run: |
echo 'Installing dependencies.'
conan install \
--profile ci \
--build="${BUILD_OPTION}" \
--options:host='&:tests=True' \
--options:host='&:xrpld=True' \
--settings:all build_type="${BUILD_TYPE}" \
--conf:all tools.build:jobs=${BUILD_NPROC} \
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
.
--profile ci \
--build="${BUILD_OPTION}" \
--options:host='&:tests=True' \
--options:host='&:xrpld=True' \
--settings:all build_type="${BUILD_TYPE}" \
--conf:all tools.build:jobs=${BUILD_NPROC} \
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
.

View File

@@ -15,7 +15,7 @@ runs:
shell: bash
env:
VERSION: ${{ github.ref_name }}
run: echo "VERSION=${VERSION}" >>"${GITHUB_ENV}"
run: echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
# When a tag is not pushed, then the version (e.g. 1.2.3-b0) is extracted
# from the BuildInfo.cpp file and the shortened commit hash appended to it.
@@ -28,17 +28,17 @@ runs:
echo 'Extracting version from BuildInfo.cpp.'
VERSION="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')"
if [[ -z "${VERSION}" ]]; then
echo 'Unable to extract version from BuildInfo.cpp.'
exit 1
echo 'Unable to extract version from BuildInfo.cpp.'
exit 1
fi
echo 'Appending shortened commit hash to version.'
SHA='${{ github.sha }}'
VERSION="${VERSION}+${SHA:0:7}"
echo "VERSION=${VERSION}" >>"${GITHUB_ENV}"
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
- name: Output version
id: version
shell: bash
run: echo "version=${VERSION}" >>"${GITHUB_OUTPUT}"
run: echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"

View File

@@ -1,403 +0,0 @@
#!/usr/bin/env python3
"""
Format embedded shell snippets using the shfmt hook configured in
.pre-commit-config.yaml.
Two shapes are recognised:
* YAML workflow/action files: literal block-scalar runs (`run: |`) and
single-line runs (`run: some command`). A single-line run is upgraded to
a `run: |` block scalar if shfmt's output spans multiple lines.
* Markdown files: ``` ```bash ``` fenced code blocks.
Any block that shfmt cannot parse is skipped with a warning on stderr, so
the file is left untouched and surrounding blocks still get formatted.
For each occurrence the body is dedented, written to a temp .sh file,
formatted via `pre-commit run shfmt --files <temp>` (falling back to
`prek`), then re-indented and written back in place.
When invoked without arguments, every .yml/.yaml under .github/ plus every
.md file in the repo is scanned. When invoked with file arguments (the
pre-commit case), only those files are processed.
"""
from __future__ import annotations
import re
import shutil
import subprocess
import sys
import tempfile
from dataclasses import dataclass
from pathlib import Path
from typing import Union
REPO = Path(__file__).resolve().parents[2]
_HOOK_RUNNER = next((cmd for cmd in ("pre-commit", "prek") if shutil.which(cmd)), None)
if _HOOK_RUNNER is None:
sys.exit("error: neither `pre-commit` nor `prek` found on PATH")
RUN_BLOCK_RE = re.compile(r"^(?P<prefix>[ \t]*(?:- )?)run:[ \t]*\|[+-]?[ \t]*$")
RUN_INLINE_RE = re.compile(
r"^(?P<prefix>[ \t]*(?:- )?)run:[ \t]+" r"(?P<value>(?!\|[+-]?[ \t]*$)\S.*?)[ \t]*$"
)
MD_BASH_OPEN_RE = re.compile(r"^(?P<indent>[ ]{0,3})`{3}bash[ \t]*$")
MD_FENCE_CLOSE_RE = re.compile(r"^[ ]{0,3}`{3,}[ \t]*$")
@dataclass(frozen=True)
class BlockRun:
"""A `run: |` block scalar; `body_start:body_end` slices into `lines`."""
body_start: int
body_end: int
body_indent: int
@dataclass(frozen=True)
class InlineRun:
"""A single-line `run: value` at `line_idx`."""
line_idx: int
prefix: str
value: str
@dataclass(frozen=True)
class MdBashBlock:
"""A markdown ``` ```bash ``` fenced code block.
`body_start:body_end` slices into the file's lines; `open_line_idx`
points at the opening fence line.
"""
open_line_idx: int
body_start: int
body_end: int
body_indent: int
RunItem = Union[BlockRun, InlineRun]
def _scan_block_body(
lines: list[str], body_start: int, run_col: int
) -> tuple[int | None, int]:
"""Locate the body of a `run: |` block scalar starting at `body_start`.
Returns `(body_indent, scan_end)`. `scan_end` is the line index where the
outer scanner should resume. `body_indent` is `None` when no body is
present (the scalar is empty, or the next non-blank line has indent
`<= run_col`).
"""
body_indent: int | None = None
scan_end = len(lines)
for idx in range(body_start, len(lines)):
line = lines[idx]
if line.strip() == "":
continue
indent = len(line) - len(line.lstrip(" "))
if body_indent is None:
if indent > run_col:
body_indent = indent
else:
scan_end = idx
break
elif indent < body_indent:
scan_end = idx
break
if body_indent is not None:
while scan_end > body_start and lines[scan_end - 1].strip() == "":
scan_end -= 1
if scan_end <= body_start:
body_indent = None
return body_indent, scan_end
def find_run_blocks(lines: list[str]) -> list[RunItem]:
"""Return run items in document order."""
items: list[RunItem] = []
line_idx = 0
while line_idx < len(lines):
line = lines[line_idx]
if block_match := RUN_BLOCK_RE.match(line):
run_col = len(block_match.group("prefix"))
body_start = line_idx + 1
body_indent, scan_end = _scan_block_body(lines, body_start, run_col)
if body_indent is not None:
items.append(
BlockRun(
body_start=body_start,
body_end=scan_end,
body_indent=body_indent,
)
)
line_idx = scan_end
continue
if inline_match := RUN_INLINE_RE.match(line):
items.append(
InlineRun(
line_idx=line_idx,
prefix=inline_match.group("prefix"),
value=inline_match.group("value"),
)
)
line_idx += 1
return items
def find_md_bash_blocks(lines: list[str]) -> list[MdBashBlock]:
"""Return ``` ```bash ``` fenced code blocks in document order."""
blocks: list[MdBashBlock] = []
line_idx = 0
while line_idx < len(lines):
open_match = MD_BASH_OPEN_RE.match(lines[line_idx])
if not open_match:
line_idx += 1
continue
body_start = line_idx + 1
close_idx = next(
(
j
for j in range(body_start, len(lines))
if MD_FENCE_CLOSE_RE.match(lines[j])
),
None,
)
if close_idx is None:
line_idx = body_start
continue
body = lines[body_start:close_idx]
non_blank = [b for b in body if b.strip()]
body_indent = (
min(len(b) - len(b.lstrip(" ")) for b in non_blank)
if non_blank
else len(open_match.group("indent"))
)
blocks.append(
MdBashBlock(
open_line_idx=line_idx,
body_start=body_start,
body_end=close_idx,
body_indent=body_indent,
)
)
line_idx = close_idx + 1
return blocks
def dedent(lines: list[str], n: int) -> list[str]:
pad = " " * n
return [
(
""
if line.strip() == ""
else (line[n:] if line.startswith(pad) else line.lstrip(" "))
)
for line in lines
]
def reindent(lines: list[str], n: int) -> list[str]:
pad = " " * n
return [pad + line if line else "" for line in lines]
_SHFMT_ERR_RE = re.compile(r"\.sh:\d+:\d+:\s")
_GHA_EXPR_RE = re.compile(r"\$\{\{.*?\}\}", re.DOTALL)
_GHA_PLACEHOLDER_RE = re.compile(r"__GHA_EXPR_(\d+)__")
def _encode_gha_exprs(text: str) -> tuple[str, list[str]]:
"""Replace `${{ ... }}` expressions with bash-safe placeholder identifiers."""
exprs: list[str] = []
def repl(match: re.Match[str]) -> str:
exprs.append(match.group(0))
return f"__GHA_EXPR_{len(exprs) - 1}__"
return _GHA_EXPR_RE.sub(repl, text), exprs
def _decode_gha_exprs(text: str, exprs: list[str]) -> str:
"""Restore `${{ ... }}` expressions from placeholder identifiers."""
return _GHA_PLACEHOLDER_RE.sub(lambda m: exprs[int(m.group(1))], text)
def shfmt_via_hook(tmp_path: Path) -> tuple[bool, str]:
# `${{ ... }}` is not valid shell, so swap it for a placeholder identifier
# that shfmt can parse, then restore it after formatting.
encoded, exprs = _encode_gha_exprs(tmp_path.read_text())
if exprs:
tmp_path.write_text(encoded)
res = subprocess.run(
[_HOOK_RUNNER, "run", "shfmt", "--files", str(tmp_path)],
cwd=REPO,
capture_output=True,
text=True,
)
output = res.stdout + res.stderr
# shfmt emits parse errors as "<path>:<line>:<col>: <message>".
parse_err = bool(_SHFMT_ERR_RE.search(output))
# A non-zero exit that is neither a parse error nor pre-commit's "I had
# to modify files" signal means the hook itself failed to run (missing
# binary, install failure, bad config, ...). Surface that loudly rather
# than silently treating it as a no-op.
if (
res.returncode != 0
and not parse_err
and "files were modified by this hook" not in output
):
sys.exit(
f"error: `{_HOOK_RUNNER} run shfmt` failed with exit {res.returncode}:\n{output}"
)
if exprs and not parse_err:
tmp_path.write_text(_decode_gha_exprs(tmp_path.read_text(), exprs))
return not parse_err, output
def _skip(path: Path, where: int, kind: str, output: str) -> None:
print(
f" shfmt could not parse {kind} at {path}:{where + 1} — skipped",
file=sys.stderr,
)
print(f" {output.strip()}", file=sys.stderr)
def process_yaml_file(path: Path, tmp_path: Path) -> int:
text = path.read_text()
had_nl = text.endswith("\n")
lines = text.split("\n")
if had_nl:
lines = lines[:-1]
items = find_run_blocks(lines)
if not items:
return 0
changed = 0
# Process in reverse so earlier indices remain valid as we splice.
for item in reversed(items):
if isinstance(item, BlockRun):
body = lines[item.body_start : item.body_end]
tmp_path.write_text("\n".join(dedent(body, item.body_indent)) + "\n")
ok, output = shfmt_via_hook(tmp_path)
if not ok:
_skip(path, item.body_start, "block", output)
continue
formatted = tmp_path.read_text().rstrip("\n")
new_body = reindent(formatted.split("\n"), item.body_indent)
if new_body != body:
lines[item.body_start : item.body_end] = new_body
changed += 1
else:
tmp_path.write_text(item.value + "\n")
ok, output = shfmt_via_hook(tmp_path)
if not ok:
_skip(path, item.line_idx, "inline run", output)
continue
formatted = tmp_path.read_text().rstrip("\n")
if formatted == item.value:
continue
formatted_lines = formatted.split("\n")
if len(formatted_lines) == 1:
lines[item.line_idx] = f"{item.prefix}run: {formatted}"
else:
body_indent = len(item.prefix) + 2
lines[item.line_idx : item.line_idx + 1] = [
f"{item.prefix}run: |",
*reindent(formatted_lines, body_indent),
]
changed += 1
new_text = "\n".join(lines) + ("\n" if had_nl else "")
if new_text != text:
path.write_text(new_text)
return changed
def process_md_file(path: Path, tmp_path: Path) -> int:
text = path.read_text()
had_nl = text.endswith("\n")
lines = text.split("\n")
if had_nl:
lines = lines[:-1]
blocks = find_md_bash_blocks(lines)
if not blocks:
return 0
changed = 0
for block in reversed(blocks):
body = lines[block.body_start : block.body_end]
tmp_path.write_text("\n".join(dedent(body, block.body_indent)) + "\n")
ok, output = shfmt_via_hook(tmp_path)
if not ok:
_skip(path, block.open_line_idx, "```bash block", output)
continue
formatted = tmp_path.read_text().rstrip("\n")
formatted_lines = formatted.split("\n") if formatted else []
new_body = reindent(formatted_lines, block.body_indent)
if new_body != body:
lines[block.body_start : block.body_end] = new_body
changed += 1
new_text = "\n".join(lines) + ("\n" if had_nl else "")
if new_text != text:
path.write_text(new_text)
return changed
def process_file(path: Path, tmp_path: Path) -> int:
if path.suffix in (".yml", ".yaml"):
return process_yaml_file(path, tmp_path)
if path.suffix == ".md":
return process_md_file(path, tmp_path)
return 0
def gather_files(argv: list[str]) -> list[Path]:
"""Return YAML workflow/action files and markdown files that we should
process — either the paths in `argv` or, when `argv` is empty, every
such file in the repo (skipping `external/`)."""
if argv:
candidates: list[Path] = [
(REPO / a).resolve() if not Path(a).is_absolute() else Path(a) for a in argv
]
else:
gh = REPO / ".github"
candidates = [
*gh.rglob("*.yml"),
*gh.rglob("*.yaml"),
*(
p
for p in REPO.rglob("*.md")
if "external" not in p.relative_to(REPO).parts
),
]
return sorted(
p
for p in candidates
if p.exists()
and (
(p.suffix in (".yml", ".yaml") and ".github" in p.parts)
or p.suffix == ".md"
)
)
def main(argv: list[str]) -> int:
files = gather_files(argv)
if not files:
return 0
with tempfile.TemporaryDirectory(prefix="format-inline-bash-") as tmpdir:
tmp_path = Path(tmpdir) / "shfmt.sh"
total = 0
for f in files:
n = process_file(f, tmp_path)
if n:
print(f"{f.relative_to(REPO)}: reformatted {n} block(s)")
total += n
return 1 if total else 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))

View File

@@ -100,8 +100,8 @@ jobs:
- name: Create multi-arch manifests
run: |
for tag in $(jq -cr '.tags[]' <<<"$DOCKER_METADATA_OUTPUT_JSON"); do
docker buildx imagetools create -t "$tag" "${tag}-amd64" "${tag}-arm64"
for tag in $(jq -cr '.tags[]' <<< "$DOCKER_METADATA_OUTPUT_JSON"); do
docker buildx imagetools create -t "$tag" "${tag}-amd64" "${tag}-arm64"
done
- name: Inspect image

View File

@@ -5,8 +5,17 @@ on:
types:
- checks_requested
pull_request:
types: [opened, edited, reopened, synchronize, ready_for_review]
branches: [develop]
types:
- opened
- edited
- reopened
- synchronize
- ready_for_review
branches:
- develop
- "release-*"
- "release/*"
- "staging/*"
jobs:
check_description:
@@ -20,11 +29,11 @@ jobs:
env:
PR_BODY: ${{ github.event.pull_request.body }}
if: ${{ github.event_name == 'pull_request' }}
run: printenv PR_BODY >pr_body.md
run: printenv PR_BODY > pr_body.md
- name: Check PR description differs from template
if: ${{ github.event_name == 'pull_request' }}
run: |
python .github/scripts/check-pr-description.py \
--template-file .github/pull_request_template.md \
--pr-body-file pr_body.md
run: >
python .github/scripts/check-pr-description.py
--template-file .github/pull_request_template.md
--pr-body-file pr_body.md

View File

@@ -5,10 +5,19 @@ on:
types:
- checks_requested
pull_request:
types: [opened, edited, reopened, synchronize, ready_for_review]
branches: [develop]
types:
- opened
- edited
- reopened
- synchronize
- ready_for_review
branches:
- develop
- "release-*"
- "release/*"
- "staging/*"
jobs:
check_title:
if: ${{ github.event.pull_request.draft != true }}
uses: XRPLF/actions/.github/workflows/check-pr-title.yml@cba1f0891650baf1a9c88624dc2d72573be2eb81
uses: XRPLF/actions/.github/workflows/check-pr-title.yml@291206777251b4d493641b5afbdf7c23009d2988

View File

@@ -98,7 +98,7 @@ jobs:
READY: ${{ contains(github.event.pull_request.labels.*.name, 'Ready to merge') }}
MERGE: ${{ github.event_name == 'merge_group' }}
run: |
echo "go=${{ (env.DRAFT != 'true' && env.READY == 'true') || env.FILES == 'true' || env.MERGE == 'true' }}" >>"${GITHUB_OUTPUT}"
echo "go=${{ (env.DRAFT != 'true' && env.READY == 'true') || env.FILES == 'true' || env.MERGE == 'true' }}" >> "${GITHUB_OUTPUT}"
cat "${GITHUB_OUTPUT}"
outputs:
go: ${{ steps.go.outputs.go == 'true' }}
@@ -168,9 +168,9 @@ jobs:
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
/repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
-F "client_payload[ref]=${{ needs.upload-recipe.outputs.recipe_ref }}" \
-F "client_payload[pr_url]=${PR_URL}"
/repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
-F "client_payload[ref]=${{ needs.upload-recipe.outputs.recipe_ref }}" \
-F "client_payload[pr_url]=${PR_URL}"
passed:
if: failure() || cancelled()

View File

@@ -14,7 +14,7 @@ on:
jobs:
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@cba1f0891650baf1a9c88624dc2d72573be2eb81
uses: XRPLF/actions/.github/workflows/pre-commit.yml@5e942d61bf32f7557a7c159cfac4712a687b3e3a
with:
runs_on: ubuntu-latest
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-41ec7c1" }'

View File

@@ -53,7 +53,7 @@ jobs:
env:
PLATFORM: ${{ inputs.platform }}
run: |
echo "arch=${PLATFORM##*/}" >>$GITHUB_OUTPUT
echo "arch=${PLATFORM##*/}" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0

View File

@@ -113,7 +113,7 @@ jobs:
- name: Set ccache log file
if: ${{ inputs.ccache_enabled && runner.debug == '1' }}
run: echo "CCACHE_LOGFILE=${{ runner.temp }}/ccache.log" >>"${GITHUB_ENV}"
run: echo "CCACHE_LOGFILE=${{ runner.temp }}/ccache.log" >> "${GITHUB_ENV}"
- name: Print build environment
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
@@ -146,11 +146,11 @@ jobs:
CMAKE_ARGS: ${{ inputs.cmake_args }}
run: |
cmake \
-G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
${CMAKE_ARGS} \
..
-G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
${CMAKE_ARGS} \
..
- name: Check protocol autogen files are up-to-date
working-directory: ${{ env.BUILD_DIR }}
@@ -172,10 +172,10 @@ jobs:
cmake --build . --target code_gen
DIFF=$(git -C .. status --porcelain -- include/xrpl/protocol_autogen src/tests/libxrpl/protocol_autogen)
if [ -n "${DIFF}" ]; then
echo "::error::Generated protocol files are out of date"
git -C .. diff -- include/xrpl/protocol_autogen src/tests/libxrpl/protocol_autogen
echo "${MESSAGE}"
exit 1
echo "::error::Generated protocol files are out of date"
git -C .. diff -- include/xrpl/protocol_autogen src/tests/libxrpl/protocol_autogen
echo "${MESSAGE}"
exit 1
fi
- name: Build the binary
@@ -186,18 +186,18 @@ jobs:
CMAKE_TARGET: ${{ inputs.cmake_target }}
run: |
cmake \
--build . \
--config "${BUILD_TYPE}" \
--parallel "${BUILD_NPROC}" \
--target "${CMAKE_TARGET}"
--build . \
--config "${BUILD_TYPE}" \
--parallel "${BUILD_NPROC}" \
--target "${CMAKE_TARGET}"
- name: Show ccache statistics
if: ${{ inputs.ccache_enabled }}
run: |
ccache --show-stats -vv
if [ '${{ runner.debug }}' = '1' ]; then
cat "${CCACHE_LOGFILE}"
curl ${CCACHE_REMOTE_STORAGE%|*}/status || true
cat "${CCACHE_LOGFILE}"
curl ${CCACHE_REMOTE_STORAGE%|*}/status || true
fi
- name: Upload the binary (Linux)
@@ -214,7 +214,7 @@ jobs:
working-directory: ${{ env.BUILD_DIR }}
run: |
set -o pipefail
./xrpld --definitions | python3 -m json.tool >server_definitions.json
./xrpld --definitions | python3 -m json.tool > server_definitions.json
- name: Upload server definitions
if: ${{ github.event.repository.visibility == 'public' && inputs.config_name == 'debian-bookworm-gcc-13-amd64-release' }}
@@ -231,10 +231,10 @@ jobs:
run: |
ldd ./xrpld
if [ "$(ldd ./xrpld | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then
echo 'The binary is statically linked.'
echo 'The binary is statically linked.'
else
echo 'The binary is dynamically linked.'
exit 1
echo 'The binary is dynamically linked.'
exit 1
fi
- name: Verify presence of instrumentation (Linux)
@@ -250,12 +250,12 @@ jobs:
run: |
ASAN_OPTS="include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-asan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp"
if [[ "${CONFIG_NAME}" == *gcc* ]]; then
ASAN_OPTS="${ASAN_OPTS}:alloc_dealloc_mismatch=0"
ASAN_OPTS="${ASAN_OPTS}:alloc_dealloc_mismatch=0"
fi
echo "ASAN_OPTIONS=${ASAN_OPTS}" >>${GITHUB_ENV}
echo "TSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-tsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >>${GITHUB_ENV}
echo "UBSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >>${GITHUB_ENV}
echo "LSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-lsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >>${GITHUB_ENV}
echo "ASAN_OPTIONS=${ASAN_OPTS}" >> ${GITHUB_ENV}
echo "TSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-tsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV}
echo "UBSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV}
echo "LSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-lsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV}
- name: Run the separate tests
if: ${{ !inputs.build_only }}
@@ -266,9 +266,9 @@ jobs:
PARALLELISM: ${{ runner.os == 'Windows' && '1' || steps.nproc.outputs.nproc }}
run: |
ctest \
--output-on-failure \
-C "${BUILD_TYPE}" \
-j "${PARALLELISM}"
--output-on-failure \
-C "${BUILD_TYPE}" \
-j "${PARALLELISM}"
- name: Run the embedded tests
if: ${{ !inputs.build_only }}
@@ -278,7 +278,7 @@ jobs:
run: |
set -o pipefail
# Coverage builds are slower due to instrumentation; use fewer parallel jobs to avoid flakiness
[ "$COVERAGE_ENABLED" = "true" ] && BUILD_NPROC=$((BUILD_NPROC - 2))
[ "$COVERAGE_ENABLED" = "true" ] && BUILD_NPROC=$(( BUILD_NPROC - 2 ))
./xrpld --unittest --unittest-jobs "${BUILD_NPROC}" 2>&1 | tee unittest.log
- name: Show test failure summary
@@ -287,19 +287,19 @@ jobs:
WORKING_DIR: ${{ runner.os == 'Windows' && format('{0}\{1}', env.BUILD_DIR, inputs.build_type) || env.BUILD_DIR }}
run: |
if [ ! -d "${WORKING_DIR}" ]; then
echo "Working directory '${WORKING_DIR}' does not exist."
exit 0
echo "Working directory '${WORKING_DIR}' does not exist."
exit 0
fi
cd "${WORKING_DIR}"
if [ ! -f unittest.log ]; then
echo "unittest.log not found; embedded tests may not have run."
exit 0
echo "unittest.log not found; embedded tests may not have run."
exit 0
fi
if ! grep -E "failed" unittest.log; then
echo "Log present but no failure lines found in unittest.log."
echo "Log present but no failure lines found in unittest.log."
fi
- name: Debug failure (Linux)
if: ${{ failure() && runner.os == 'Linux' && !inputs.build_only }}
@@ -317,10 +317,10 @@ jobs:
BUILD_TYPE: ${{ inputs.build_type }}
run: |
cmake \
--build . \
--config "${BUILD_TYPE}" \
--parallel "${BUILD_NPROC}" \
--target coverage
--build . \
--config "${BUILD_TYPE}" \
--parallel "${BUILD_NPROC}" \
--target coverage
- name: Upload coverage report
if: ${{ github.repository == 'XRPLF/rippled' && !inputs.build_only && env.COVERAGE_ENABLED == 'true' }}

View File

@@ -38,9 +38,9 @@ jobs:
run: |
DIFF=$(git status --porcelain)
if [ -n "${DIFF}" ]; then
# Print the differences to give the contributor a hint about what to
# expect when running levelization on their own machine.
git diff
echo "${MESSAGE}"
exit 1
# Print the differences to give the contributor a hint about what to
# expect when running levelization on their own machine.
git diff
echo "${MESSAGE}"
exit 1
fi

View File

@@ -48,9 +48,9 @@ jobs:
run: |
DIFF=$(git status --porcelain)
if [ -n "${DIFF}" ]; then
# Print the differences to give the contributor a hint about what to
# expect when running the renaming scripts on their own machine.
git diff
echo "${MESSAGE}"
exit 1
# Print the differences to give the contributor a hint about what to
# expect when running the renaming scripts on their own machine.
git diff
echo "${MESSAGE}"
exit 1
fi

View File

@@ -70,13 +70,13 @@ jobs:
working-directory: ${{ env.BUILD_DIR }}
run: |
cmake \
-G 'Ninja' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
-Dtests=ON \
-Dwerr=ON \
-Dxrpld=ON \
..
-G 'Ninja' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
-Dtests=ON \
-Dwerr=ON \
-Dxrpld=ON \
..
# clang-tidy needs headers generated from proto files
- name: Build libxrpl.libpb
@@ -133,7 +133,7 @@ jobs:
- name: Write issue header
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
cat >"${ISSUE_FILE}" <<EOF
cat > "${ISSUE_FILE}" <<EOF
## Clang-tidy Check Failed
### Clang-tidy Output:
@@ -144,30 +144,30 @@ jobs:
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
if [ -f "${OUTPUT_FILE}" ]; then
# Extract lines containing 'error:', 'warning:', or 'note:'
grep -E '(error:|warning:|note:)' "${OUTPUT_FILE}" >filtered-output.txt || true
# Extract lines containing 'error:', 'warning:', or 'note:'
grep -E '(error:|warning:|note:)' "${OUTPUT_FILE}" > filtered-output.txt || true
# If filtered output is empty, use original (might be a different error format)
if [ ! -s filtered-output.txt ]; then
cp "${OUTPUT_FILE}" filtered-output.txt
fi
# If filtered output is empty, use original (might be a different error format)
if [ ! -s filtered-output.txt ]; then
cp "${OUTPUT_FILE}" filtered-output.txt
fi
# Truncate if too large
head -c 60000 filtered-output.txt >>"${ISSUE_FILE}"
if [ "$(wc -c <filtered-output.txt)" -gt 60000 ]; then
echo "" >>"${ISSUE_FILE}"
echo "... (output truncated, see artifacts for full output)" >>"${ISSUE_FILE}"
fi
# Truncate if too large
head -c 60000 filtered-output.txt >> "${ISSUE_FILE}"
if [ "$(wc -c < filtered-output.txt)" -gt 60000 ]; then
echo "" >> "${ISSUE_FILE}"
echo "... (output truncated, see artifacts for full output)" >> "${ISSUE_FILE}"
fi
rm filtered-output.txt
rm filtered-output.txt
else
echo "No output file found" >>"${ISSUE_FILE}"
echo "No output file found" >> "${ISSUE_FILE}"
fi
- name: Append issue footer
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
cat >>"${ISSUE_FILE}" <<EOF
cat >> "${ISSUE_FILE}" <<EOF
\`\`\`
---
@@ -176,7 +176,7 @@ jobs:
- name: Create issue
if: ${{ steps.run_clang_tidy.outcome != 'success' && inputs.create_issue_on_failure }}
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
uses: XRPLF/actions/create-issue@36d450d12d301e8410c1b7936e5de70c291cbe36
with:
title: "Clang-tidy check failed"
body_file: ${{ env.ISSUE_FILE }}

View File

@@ -39,7 +39,7 @@ jobs:
id: generate
working-directory: .github/scripts/strategy-matrix
run: |
./generate.py --packaging --config=linux.json >>"${GITHUB_OUTPUT}"
./generate.py --packaging --config=linux.json >> "${GITHUB_OUTPUT}"
generate-version:
runs-on: ubuntu-latest

View File

@@ -42,4 +42,4 @@ jobs:
env:
GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }}
GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }}
run: ./generate.py ${GENERATE_OPTION} ${GENERATE_CONFIG} >>"${GITHUB_OUTPUT}"
run: ./generate.py ${GENERATE_OPTION} ${GENERATE_CONFIG} >> "${GITHUB_OUTPUT}"

View File

@@ -66,19 +66,6 @@ repos:
- id: shfmt
args: [--write, --indent=4, --case-indent=true]
- repo: local
hooks:
- id: format-inline-bash-workflows
name: "format `run:` blocks in workflows/actions"
entry: ./.github/scripts/format-inline-bash.py
language: python
files: ^\.github/(workflows|actions)/.*\.ya?ml$
- id: format-inline-bash-markdown
name: "format ```bash blocks in markdown"
entry: ./.github/scripts/format-inline-bash.py
language: python
files: \.md$
- repo: https://github.com/streetsidesoftware/cspell-cli
rev: 4643f154907327ee0a2c7038f0296e0dd77d9776 # frozen: v10.0.0
hooks:

View File

@@ -151,8 +151,8 @@ git init
git remote add origin git@github.com:XRPLF/conan-center-index.git
git sparse-checkout init
for recipe in "${recipes[@]}"; do
echo "Checking out recipe '${recipe}'..."
git sparse-checkout add recipes/${recipe}
echo "Checking out recipe '${recipe}'..."
git sparse-checkout add recipes/${recipe}
done
git fetch origin master
git checkout master
@@ -180,7 +180,7 @@ the new recipe will be automatically pulled from the official Conan Center.
If you see an error similar to the following after running `conan profile show`:
```text
```bash
ERROR: Invalid setting '17' is not a valid 'settings.compiler.version' value.
Possible values are ['5.0', '5.1', '6.0', '6.1', '7.0', '7.3', '8.0', '8.1',
'9.0', '9.1', '10.0', '11.0', '12.0', '13', '13.0', '13.1', '14', '14.0', '15',

View File

@@ -93,7 +93,6 @@ words:
- daria
- dcmake
- dearmor
- dedented
- deleteme
- demultiplexer
- deserializaton

View File

@@ -1,6 +1,6 @@
#pragma once
#include <filesystem>
#include <boost/filesystem.hpp>
namespace xrpl {
@@ -12,6 +12,6 @@ namespace xrpl {
@throws runtime_error
*/
void
extractTarLz4(std::filesystem::path const& src, std::filesystem::path const& dst);
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst);
} // namespace xrpl

View File

@@ -1,22 +1,22 @@
#pragma once
#include <filesystem>
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
#include <optional>
#include <string>
#include <system_error>
namespace xrpl {
std::string
getFileContents(
std::error_code& ec,
std::filesystem::path const& sourcePath,
boost::system::error_code& ec,
boost::filesystem::path const& sourcePath,
std::optional<std::size_t> maxSize = std::nullopt);
void
writeFileContents(
std::error_code& ec,
std::filesystem::path const& destPath,
boost::system::error_code& ec,
boost::filesystem::path const& destPath,
std::string const& contents);
} // namespace xrpl

View File

@@ -4,8 +4,8 @@
#include <xrpl/beast/utility/Journal.h>
#include <boost/beast/core/string.hpp>
#include <boost/filesystem.hpp>
#include <filesystem>
#include <fstream>
#include <map>
#include <memory>
@@ -76,7 +76,7 @@ private:
@return `true` if the file was opened.
*/
bool
open(std::filesystem::path const& path);
open(boost::filesystem::path const& path);
/** Close and re-open the system file associated with the log
This assists in interoperating with external log management tools.
@@ -118,7 +118,7 @@ private:
private:
std::unique_ptr<std::ofstream> stream_;
std::filesystem::path path_;
boost::filesystem::path path_;
};
std::mutex mutable mutex_;
@@ -137,7 +137,7 @@ public:
virtual ~Logs() = default;
bool
open(std::filesystem::path const& pathToLogFile);
open(boost::filesystem::path const& pathToLogFile);
beast::Journal::Sink&
get(std::string const& name);

View File

@@ -6,10 +6,10 @@
#include <xrpl/beast/unit_test/runner.h>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/throw_exception.hpp>
#include <filesystem>
#include <ostream>
#include <sstream>
#include <string>
@@ -25,7 +25,7 @@ makeReason(String const& reason, char const* file, int line)
std::string s(reason);
if (!s.empty())
s.append(": ");
namespace fs = std::filesystem;
namespace fs = boost::filesystem;
s.append(fs::path{file}.filename().string());
s.append("(");
s.append(boost::lexical_cast<std::string>(line));

View File

@@ -1,56 +1,19 @@
#pragma once
#include <filesystem>
#include <iomanip>
#include <random>
#include <sstream>
#include <stdexcept>
#include <boost/filesystem.hpp>
#include <string>
#include <system_error>
namespace beast {
/** Generate a unique, non-existing path under @p base with an optional @p prefix
and a random hex suffix.
Attempts up to @p maxAttempts paths. Throws `std::runtime_error` if a
unique path cannot be found or if the filesystem returns an error while
checking for existence.
*/
inline std::filesystem::path
uniqueRandomPath(
std::filesystem::path const& base,
std::size_t maxAttempts = 100,
std::string const& prefix = "")
{
std::random_device rd;
for (std::size_t attempt = 0; attempt < maxAttempts; ++attempt)
{
std::ostringstream oss;
oss << prefix << std::hex << std::setfill('0') << std::setw(8) << rd() << std::setw(8)
<< rd();
auto candidate = base / oss.str();
std::error_code ec;
bool const exists = std::filesystem::exists(candidate, ec);
if (ec)
{
throw std::runtime_error(
"Unable to check path '" + candidate.string() + "': " + ec.message());
}
if (!exists)
return candidate;
}
throw std::runtime_error("Unable to generate a unique path under '" + base.string() + "'");
}
/** RAII temporary directory.
The directory and all its contents are deleted when
the instance of `TempDir` is destroyed.
the instance of `temp_dir` is destroyed.
*/
class TempDir
{
std::filesystem::path path_;
boost::filesystem::path path_;
public:
#if !GENERATING_DOCS
@@ -62,16 +25,20 @@ public:
/// Construct a temporary directory.
TempDir()
{
path_ = uniqueRandomPath(std::filesystem::temp_directory_path());
std::filesystem::create_directory(path_);
auto const dir = boost::filesystem::temp_directory_path();
do
{
path_ = dir / boost::filesystem::unique_path();
} while (boost::filesystem::exists(path_));
boost::filesystem::create_directory(path_);
}
/// Destroy a temporary directory.
~TempDir()
{
// use non-throwing calls in the destructor
std::error_code ec;
std::filesystem::remove_all(path_, ec);
boost::system::error_code ec;
boost::filesystem::remove_all(path_, ec);
// TODO: warn/notify if ec set ?
}

View File

@@ -4,9 +4,10 @@
#include <xrpl/core/JobTypes.h>
#include <xrpl/json/json_value.h>
#include <boost/filesystem.hpp>
#include <chrono>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <memory>
#include <string>
@@ -42,7 +43,7 @@ public:
*/
struct Setup
{
std::filesystem::path perfLog;
boost::filesystem::path perfLog;
// log_interval is in milliseconds to support faster testing.
milliseconds logInterval{seconds(1)};
};
@@ -147,7 +148,7 @@ public:
};
PerfLog::Setup
setupPerfLog(Section const& section, std::filesystem::path const& configDir);
setupPerfLog(Section const& section, boost::filesystem::path const& configDir);
std::unique_ptr<PerfLog>
makePerfLog(

View File

@@ -15,7 +15,7 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FIX (Cleanup3_2_0, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_2_0, Supported::No, VoteBehavior::DefaultNo)
XRPL_FEATURE(MPTokensV2, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_1_3, Supported::Yes, VoteBehavior::DefaultYes)
XRPL_FIX (BatchInnerSigs, Supported::No, VoteBehavior::DefaultNo)

View File

@@ -15,8 +15,8 @@ Generation requires a one-time setup step to create a virtual environment
and install Python dependencies, followed by running the generation target:
```bash
cmake --build . --target setup_code_gen # create venv and install dependencies (once)
cmake --build . --target code_gen # generate code
cmake --build . --target setup_code_gen # create venv and install dependencies (once)
cmake --build . --target code_gen # generate code
```
By default, `CODEGEN_VENV_DIR` points to `.venv` in the project root. The

View File

@@ -6,7 +6,8 @@
#include <xrpl/rdb/DBInit.h>
#include <xrpl/rdb/SociDB.h>
#include <filesystem>
#include <boost/filesystem/path.hpp>
#include <mutex>
#include <optional>
#include <string>
@@ -71,7 +72,7 @@ public:
StartUpType startUp = StartUpType::Normal;
bool standAlone = false;
std::filesystem::path dataDir;
boost::filesystem::path dataDir;
// Indicates whether or not to return the `globalPragma`
// from commonPragma()
bool useGlobalPragma = false;
@@ -134,7 +135,7 @@ public:
template <std::size_t N, std::size_t M>
DatabaseCon(
std::filesystem::path const& dataDir,
boost::filesystem::path const& dataDir,
std::string const& dbName,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
@@ -146,7 +147,7 @@ public:
// Use this constructor to setup checkpointing
template <std::size_t N, std::size_t M>
DatabaseCon(
std::filesystem::path const& dataDir,
boost::filesystem::path const& dataDir,
std::string const& dbName,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
@@ -181,7 +182,7 @@ private:
template <std::size_t N, std::size_t M>
DatabaseCon(
std::filesystem::path const& pPath,
boost::filesystem::path const& pPath,
std::vector<std::string> const* commonPragma,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,

View File

@@ -10,6 +10,7 @@
#include <xrpl/protocol/TxSearched.h>
#include <xrpl/rdb/DatabaseCon.h>
#include <boost/filesystem.hpp>
#include <boost/variant.hpp>
namespace xrpl {

View File

@@ -4,6 +4,8 @@
#include <xrpl/rdb/DatabaseCon.h>
#include <xrpl/server/Manifest.h>
#include <boost/filesystem.hpp>
namespace xrpl {
struct SavedState

View File

@@ -74,10 +74,10 @@ VERSION=2.4.0-local
PKG_RELEASE=1
docker run --rm \
-v "$(pwd):/src" \
-w /src \
"$IMAGE" \
./package/build_pkg.sh --pkg-version "$VERSION" --pkg-release "$PKG_RELEASE"
-v "$(pwd):/src" \
-w /src \
"$IMAGE" \
./package/build_pkg.sh --pkg-version "$VERSION" --pkg-release "$PKG_RELEASE"
# Output:
# build/debbuild/*.deb (DEB + dbgsym .ddeb)
@@ -92,12 +92,12 @@ needed, but the host toolchain replaces the pinned CI image:
```bash
cmake \
-Dxrpld=ON \
-Dxrpld_version=2.4.0-local \
-Dtests=OFF \
..
-Dxrpld=ON \
-Dxrpld_version=2.4.0-local \
-Dtests=OFF \
..
cmake --build . --target package # deb on Debian/Ubuntu, rpm on RHEL
cmake --build . --target package # deb on Debian/Ubuntu, rpm on RHEL
```
The `cmake/XrplPackaging.cmake` module defines the target only if at least one

View File

@@ -2,20 +2,22 @@
#include <xrpl/basics/contract.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <archive.h>
#include <archive_entry.h>
#include <cstddef>
#include <filesystem>
#include <memory>
#include <stdexcept>
namespace xrpl {
void
extractTarLz4(std::filesystem::path const& src, std::filesystem::path const& dst)
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst)
{
if (!std::filesystem::is_regular_file(src))
if (!is_regular_file(src))
Throw<std::runtime_error>("Invalid source file");
using archive_ptr = std::unique_ptr<struct archive, void (*)(struct archive*)>;

View File

@@ -1,24 +1,29 @@
#include <xrpl/basics/FileUtilities.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/detail/errc.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/errc.hpp>
#include <cerrno>
#include <cstddef>
#include <filesystem>
#include <fstream>
#include <ios>
#include <iterator>
#include <optional>
#include <string>
#include <system_error>
namespace xrpl {
std::string
getFileContents(
std::error_code& ec,
std::filesystem::path const& sourcePath,
boost::system::error_code& ec,
boost::filesystem::path const& sourcePath,
std::optional<std::size_t> maxSize)
{
using namespace std::filesystem;
using namespace boost::filesystem;
using namespace boost::system::errc;
path const fullPath{canonical(sourcePath, ec)};
if (ec)
@@ -27,15 +32,15 @@ getFileContents(
if (maxSize && (file_size(fullPath, ec) > *maxSize || ec))
{
if (!ec)
ec = make_error_code(std::errc::file_too_large);
ec = make_error_code(file_too_large);
return {};
}
std::ifstream fileStream(fullPath, std::ios::in);
std::ifstream fileStream(fullPath.string(), std::ios::in);
if (!fileStream)
{
ec.assign(errno, std::generic_category());
ec = make_error_code(static_cast<errc_t>(errno));
return {};
}
@@ -44,7 +49,7 @@ getFileContents(
if (fileStream.bad())
{
ec.assign(errno, std::generic_category());
ec = make_error_code(static_cast<errc_t>(errno));
return {};
}
@@ -53,15 +58,18 @@ getFileContents(
void
writeFileContents(
std::error_code& ec,
std::filesystem::path const& destPath,
boost::system::error_code& ec,
boost::filesystem::path const& destPath,
std::string const& contents)
{
std::ofstream fileStream(destPath, std::ios::out | std::ios::trunc);
using namespace boost::filesystem;
using namespace boost::system::errc;
std::ofstream fileStream(destPath.string(), std::ios::out | std::ios::trunc);
if (!fileStream)
{
ec.assign(errno, std::generic_category());
ec = make_error_code(static_cast<errc_t>(errno));
return;
}
@@ -69,7 +77,7 @@ writeFileContents(
if (fileStream.bad())
{
ec.assign(errno, std::generic_category());
ec = make_error_code(static_cast<errc_t>(errno));
return;
}
}

View File

@@ -5,10 +5,10 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/path.hpp>
#include <chrono>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <functional>
#include <iostream>
@@ -54,7 +54,7 @@ Logs::File::isOpen() const noexcept
}
bool
Logs::File::open(std::filesystem::path const& path)
Logs::File::open(boost::filesystem::path const& path)
{
close();
@@ -113,7 +113,7 @@ Logs::Logs(beast::Severity thresh) : thresh_(thresh) // default severity
}
bool
Logs::open(std::filesystem::path const& pathToLogFile)
Logs::open(boost::filesystem::path const& pathToLogFile)
{
return file_.open(pathToLogFile);
}

View File

@@ -15,6 +15,8 @@
#include <xrpl/nodestore/detail/EncodedBlob.h>
#include <xrpl/nodestore/detail/codec.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/detail/errc.hpp>
#include <nudb/context.hpp>
@@ -33,14 +35,12 @@
#include <cstdint>
#include <cstdio>
#include <exception>
#include <filesystem>
#include <functional>
#include <memory>
#include <optional>
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <utility>
namespace xrpl::NodeStore {
@@ -130,7 +130,7 @@ public:
void
open(bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt) override
{
using namespace std::filesystem;
using namespace boost::filesystem;
if (db.is_open())
{
// LCOV_EXCL_START
@@ -193,12 +193,11 @@ public:
if (deletePath)
{
std::error_code fsec;
std::filesystem::remove_all(name, fsec);
if (fsec)
boost::filesystem::remove_all(name, ec);
if (ec)
{
JLOG(j.fatal()) << "Filesystem remove_all of " << name
<< " failed with: " << fsec.message();
JLOG(j.fatal())
<< "Filesystem remove_all of " << name << " failed with: " << ec.message();
}
}
}
@@ -352,7 +351,7 @@ private:
static std::size_t
parseBlockSize(std::string const& name, Section const& keyValues, beast::Journal journal)
{
using namespace std::filesystem;
using namespace boost::filesystem;
auto const folder = path(name);
auto const kp = (folder / "nudb.key").string();

View File

@@ -8,6 +8,9 @@
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Types.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <rocksdb/advanced_options.h>
#include <rocksdb/cache.h>
#include <rocksdb/compression_type.h>
@@ -23,7 +26,6 @@
#include <bit>
#include <cstddef>
#include <filesystem>
#include <functional>
#include <stdexcept>
#include <string>
@@ -260,8 +262,8 @@ public:
db.reset();
if (deletePath_)
{
std::filesystem::path const dir = name;
std::filesystem::remove_all(dir);
boost::filesystem::path const dir = name;
boost::filesystem::remove_all(dir);
}
}
}

View File

@@ -23,7 +23,7 @@ namespace {
//------------------------------------------------------------------------------
// clang-format off
// NOLINTNEXTLINE(readability-identifier-naming)
char const* const versionString = "3.2.0-rc2"
char const* const versionString = "3.2.0-b7"
// clang-format on
;

View File

@@ -4,11 +4,13 @@
#include <xrpl/core/JobQueue.h>
#include <xrpl/core/ServiceRegistry.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <soci/blob.h>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <mutex>
#include <stdexcept>
#include <string>
@@ -42,8 +44,8 @@ getSociSqliteInit(std::string const& name, std::string const& dir, std::string c
Throw<std::runtime_error>(
"Sqlite databases must specify a dir and a name. Name: " + name + " Dir: " + dir);
}
std::filesystem::path file(dir);
if (std::filesystem::is_directory(file))
boost::filesystem::path file(dir);
if (is_directory(file))
file /= name + ext;
return file.string();
}

View File

@@ -5,12 +5,13 @@
#include <xrpl/rdb/DBInit.h>
#include <xrpl/rdb/DatabaseCon.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp> // IWYU pragma: keep
#include <soci/into.h>
#include <cstdint>
#include <filesystem>
#include <iostream>
#include <memory>
@@ -19,12 +20,12 @@ namespace xrpl {
bool
doVacuumDB(DatabaseCon::Setup const& setup, beast::Journal j)
{
std::filesystem::path const dbPath = setup.dataDir / kTxDbName;
boost::filesystem::path const dbPath = setup.dataDir / kTxDbName;
uintmax_t const dbSize = std::filesystem::file_size(dbPath);
uintmax_t const dbSize = file_size(dbPath);
XRPL_ASSERT(dbSize != static_cast<uintmax_t>(-1), "xrpl::doVacuumDB : file_size succeeded");
if (auto available = std::filesystem::space(dbPath.parent_path()).available; available < dbSize)
if (auto available = space(dbPath.parent_path()).available; available < dbSize)
{
std::cerr << "The database filesystem must have at least as "
"much free space as the size of "

View File

@@ -4,10 +4,11 @@
#include <xrpld/core/ConfigSections.h>
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/beast/utility/temp_dir.h>
#include <xrpl/proto/org/xrpl/rpc/v1/get_ledger.pb.h>
#include <xrpl/proto/org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h>
#include <boost/filesystem/operations.hpp>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/grpcpp.h>
@@ -17,7 +18,6 @@
#include <chrono>
#include <filesystem>
#include <fstream>
#include <ios>
#include <memory>
#include <stdexcept>
#include <string>
@@ -255,8 +255,10 @@ public:
TemporaryTLSCertificates()
{
tempDir_ = beast::uniqueRandomPath(
std::filesystem::temp_directory_path(), 100, std::string(kCertsDirPrefix));
auto tmpDir = std::filesystem::temp_directory_path();
auto uniqueDirName =
boost::filesystem::unique_path(std::string(kCertsDirPrefix) + "%%%%%%%%");
tempDir_ = tmpDir / uniqueDirName.string();
std::filesystem::create_directories(tempDir_);
writeFile(tempDir_ / kCaCertFilename, kCaCertContent);

View File

@@ -18,16 +18,16 @@
#include <xrpl/protocol/jss.h>
#include <boost/algorithm/string/erase.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/system/detail/error_code.hpp>
#include <cassert>
#include <filesystem>
#include <fstream>
#include <ios>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <system_error>
namespace xrpl {
@@ -139,7 +139,7 @@ class LedgerLoad_test : public beast::unit_test::Suite
{
testcase("Load ledger: Bad Files");
using namespace test::jtx;
using namespace std::filesystem;
using namespace boost::filesystem;
// empty path
except([&] {
@@ -161,8 +161,8 @@ class LedgerLoad_test : public beast::unit_test::Suite
});
// make a corrupted version of the ledger file (last 10 bytes removed).
std::error_code ec;
auto ledgerFileCorrupt = std::filesystem::path{sd.dbPath} / "ledgerdata_bad.json";
boost::system::error_code ec;
auto ledgerFileCorrupt = boost::filesystem::path{sd.dbPath} / "ledgerdata_bad.json";
copy_file(sd.ledgerFile, ledgerFileCorrupt, copy_options::overwrite_existing, ec);
if (!BEAST_EXPECTS(!ec, ec.message()))
return;

View File

@@ -21,12 +21,14 @@
#include <xrpl/server/Manifest.h>
#include <xrpl/server/Wallet.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <exception>
#include <filesystem>
#include <limits>
#include <memory>
#include <optional>
@@ -53,18 +55,18 @@ private:
}
static void
cleanupDatabaseDir(std::filesystem::path const& dbPath)
cleanupDatabaseDir(boost::filesystem::path const& dbPath)
{
using namespace std::filesystem;
using namespace boost::filesystem;
if (!exists(dbPath) || !is_directory(dbPath) || !is_empty(dbPath))
return;
remove(dbPath);
}
static void
setupDatabaseDir(std::filesystem::path const& dbPath)
setupDatabaseDir(boost::filesystem::path const& dbPath)
{
using namespace std::filesystem;
using namespace boost::filesystem;
if (!exists(dbPath))
{
create_directory(dbPath);
@@ -77,10 +79,10 @@ private:
Throw<std::runtime_error>("Cannot create directory: " + dbPath.string());
}
}
static std::filesystem::path
static boost::filesystem::path
getDatabasePath()
{
return std::filesystem::current_path() / "manifest_test_databases";
return boost::filesystem::current_path() / "manifest_test_databases";
}
public:
@@ -349,7 +351,7 @@ public:
BEAST_EXPECT(loaded.revoked(pk));
}
}
std::filesystem::remove(getDatabasePath() / std::filesystem::path(dbName));
boost::filesystem::remove(getDatabasePath() / boost::filesystem::path(dbName));
}
void

View File

@@ -21,9 +21,10 @@
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol/jss.h>
#include <boost/filesystem/path.hpp>
#include <atomic>
#include <cstdint>
#include <filesystem>
#include <limits>
#include <map>
#include <memory>
@@ -490,7 +491,7 @@ public:
makeBackendRotating(jtx::Env& env, NodeStoreScheduler& scheduler, std::string path)
{
Section section{env.app().config().section(ConfigSection::nodeDatabase())};
std::filesystem::path newPath;
boost::filesystem::path newPath;
if (!BEAST_EXPECT(path.size()))
return {};

View File

@@ -15,12 +15,13 @@
#include <xrpl/protocol/jss.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/filesystem/directory.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <date/date.h>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <memory>
#include <ostream>
@@ -600,7 +601,7 @@ public:
detail::kDefaultEffectiveOverlap,
60 * 24}}); // max of 24 hours
}
using namespace std::filesystem;
using namespace boost::filesystem;
for (auto const& file : directory_iterator(good.subdir()))
{
remove_all(file);

View File

@@ -4,7 +4,8 @@
#include <xrpl/basics/FileUtilities.h>
#include <xrpl/beast/unit_test/suite.h>
#include <system_error>
#include <boost/system/detail/errc.hpp>
#include <boost/system/detail/error_code.hpp>
namespace xrpl {
@@ -15,6 +16,7 @@ public:
testGetFileContents()
{
using namespace xrpl::detail;
using namespace boost::system;
static constexpr char const* kExpectedContents =
"This file is very short. That's all we need.";
@@ -22,7 +24,7 @@ public:
FileDirGuard const file(
*this, "test_file", "test.txt", "This is temporary text that should get overwritten");
std::error_code ec;
error_code ec;
auto const path = file.file();
writeFileContents(ec, path, kExpectedContents);
@@ -45,7 +47,7 @@ public:
{
// Test with small max
auto const bad = getFileContents(ec, path, 16);
BEAST_EXPECT(ec && ec == std::errc::file_too_large);
BEAST_EXPECT(ec && ec.value() == boost::system::errc::file_too_large);
BEAST_EXPECT(bad.empty());
}
}

View File

@@ -15,10 +15,14 @@
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/jss.h>
#include <boost/filesystem/file_status.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/detail/error_code.hpp>
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <ios>
#include <iterator>
@@ -27,7 +31,6 @@
#include <ostream>
#include <random>
#include <string>
#include <system_error>
#include <thread>
#include <utility>
#include <vector>
@@ -40,7 +43,7 @@ class PerfLog_test : public beast::unit_test::Suite
{
enum class WithFile : bool { No = false, Yes = true };
using path = std::filesystem::path;
using path = boost::filesystem::path;
// We're only using Env for its Journal. That Journal gives better
// coverage in unit tests.
@@ -63,14 +66,14 @@ class PerfLog_test : public beast::unit_test::Suite
// The error code is intentionally ignored: if the path doesn't
// exist (the common case on a clean runner) remove_all returns
// an error, and that's fine — there's nothing to clean up.
using namespace std::filesystem;
std::error_code ec;
using namespace boost::filesystem;
boost::system::error_code ec;
remove_all(logDir(), ec);
}
~Fixture()
{
using namespace std::filesystem;
using namespace boost::filesystem;
auto const dir{logDir()};
auto const file{logFile()};
@@ -93,7 +96,7 @@ class PerfLog_test : public beast::unit_test::Suite
static path
logDir()
{
using namespace std::filesystem;
using namespace boost::filesystem;
return temp_directory_path() / "perf_log_test_dir";
}
@@ -126,7 +129,7 @@ class PerfLog_test : public beast::unit_test::Suite
static void
wait()
{
using namespace std::filesystem;
using namespace boost::filesystem;
auto const path = logFile();
if (!exists(path))
@@ -198,7 +201,7 @@ public:
void
testFileCreation()
{
using namespace std::filesystem;
using namespace boost::filesystem;
{
// Verify a PerfLog creates its file when constructed.
@@ -253,23 +256,22 @@ public:
// Construct and write protect a file to prevent PerfLog
// from creating its file.
std::error_code ec;
std::filesystem::create_directories(fixture.logDir(), ec);
boost::system::error_code ec;
boost::filesystem::create_directories(fixture.logDir(), ec);
if (!BEAST_EXPECT(!ec))
return;
auto fileWriteable = [](std::filesystem::path const& p) -> bool {
return std::ofstream{p, std::ios::out | std::ios::app}.is_open();
auto fileWriteable = [](boost::filesystem::path const& p) -> bool {
return std::ofstream{p.c_str(), std::ios::out | std::ios::app}.is_open();
};
if (!BEAST_EXPECT(fileWriteable(fixture.logFile())))
return;
std::filesystem::permissions(
boost::filesystem::permissions(
fixture.logFile(),
std::filesystem::perms::owner_write | std::filesystem::perms::others_write |
std::filesystem::perms::group_write,
std::filesystem::perm_options::remove);
perms::remove_perms | perms::owner_write | perms::others_write |
perms::group_write);
// If the test is running as root, then the write protect may have
// no effect. Make sure write protect worked before proceeding.
@@ -293,11 +295,9 @@ public:
perfLog->stop();
// Fix file permissions so the file can be cleaned up.
std::filesystem::permissions(
boost::filesystem::permissions(
fixture.logFile(),
std::filesystem::perms::owner_write | std::filesystem::perms::others_write |
std::filesystem::perms::group_write,
std::filesystem::perm_options::add);
perms::add_perms | perms::owner_write | perms::others_write | perms::group_write);
}
}
@@ -962,7 +962,7 @@ public:
// We can't fully test rotate because unit tests must run on Windows,
// and Windows doesn't (may not?) support rotate. But at least call
// the interface and see that it doesn't crash.
using namespace std::filesystem;
using namespace boost::filesystem;
Fixture fixture{env_.app(), j_};
BEAST_EXPECT(!exists(fixture.logDir()));

View File

@@ -10,6 +10,7 @@
#include <xrpl/protocol/SystemParameters.h> // IWYU pragma: keep
#include <xrpl/server/Port.h>
#include <boost/filesystem/operations.hpp>
#include <boost/format.hpp> // IWYU pragma: keep
#include <boost/format/free_funcs.hpp>
#include <boost/lexical_cast/bad_lexical_cast.hpp>
@@ -19,7 +20,6 @@
#include <cstdint>
#include <cstdlib>
#include <exception>
#include <filesystem>
#include <fstream>
#include <optional>
#include <ostream>
@@ -179,7 +179,7 @@ public:
[[nodiscard]] bool
dataDirExists() const
{
return std::filesystem::is_directory(dataDir_);
return boost::filesystem::is_directory(dataDir_);
}
[[nodiscard]] bool
@@ -192,7 +192,7 @@ public:
{
try
{
using namespace std::filesystem;
using namespace boost::filesystem;
if (rmDataDir_)
rmDir(dataDir_);
}
@@ -273,7 +273,7 @@ public:
class Config_test final : public TestSuite
{
private:
using path = std::filesystem::path;
using path = boost::filesystem::path;
public:
void
@@ -309,7 +309,7 @@ port_wss_admin
{
testcase("config_file");
using namespace std::filesystem;
using namespace boost::filesystem;
auto const cwd = current_path();
// Test both config file names.
@@ -425,7 +425,7 @@ port_wss_admin
{
testcase("database_path");
using namespace std::filesystem;
using namespace boost::filesystem;
{
boost::format cc("[database_path]\n%1%\n");
@@ -601,7 +601,7 @@ main
{
testcase("validators_file");
using namespace std::filesystem;
using namespace boost::filesystem;
{
// load should throw for missing specified validators file
boost::format cc("[validators_file]\n%1%\n");

View File

@@ -18,7 +18,6 @@
#include <cstdint>
#include <cstring>
#include <exception>
#include <filesystem>
#include <iterator>
#include <limits>
#include <stdexcept>
@@ -31,7 +30,7 @@ class SociDB_test final : public TestSuite
{
private:
static void
setupSQLiteConfig(BasicConfig& config, std::filesystem::path const& dbPath)
setupSQLiteConfig(BasicConfig& config, boost::filesystem::path const& dbPath)
{
config.overwrite("sqdb", "backend", "sqlite");
auto value = dbPath.string();
@@ -40,18 +39,18 @@ private:
}
static void
cleanupDatabaseDir(std::filesystem::path const& dbPath)
cleanupDatabaseDir(boost::filesystem::path const& dbPath)
{
using namespace std::filesystem;
using namespace boost::filesystem;
if (!exists(dbPath) || !is_directory(dbPath) || !is_empty(dbPath))
return;
remove(dbPath);
}
static void
setupDatabaseDir(std::filesystem::path const& dbPath)
setupDatabaseDir(boost::filesystem::path const& dbPath)
{
using namespace std::filesystem;
using namespace boost::filesystem;
if (!exists(dbPath))
{
create_directory(dbPath);
@@ -64,10 +63,10 @@ private:
Throw<std::runtime_error>("Cannot create directory: " + dbPath.string());
}
}
static std::filesystem::path
static boost::filesystem::path
getDatabasePath()
{
return std::filesystem::current_path() / "socidb_test_databases";
return boost::filesystem::current_path() / "socidb_test_databases";
}
public:
@@ -157,7 +156,7 @@ public:
checkValues(s);
}
{
namespace bfs = std::filesystem;
namespace bfs = boost::filesystem;
// Remove the database
bfs::path const dbPath(sc.connectionString());
if (bfs::is_regular_file(dbPath))
@@ -287,7 +286,7 @@ public:
#endif
}
{
namespace bfs = std::filesystem;
namespace bfs = boost::filesystem;
// Remove the database
bfs::path const dbPath(sc.connectionString());
if (bfs::is_regular_file(dbPath))
@@ -339,7 +338,7 @@ public:
s << "SELECT LedgerSeq FROM Ledgers;", soci::into(ledgersLS);
BEAST_EXPECT(ledgersLS.size() == numRows);
}
namespace bfs = std::filesystem;
namespace bfs = boost::filesystem;
// Remove the database
bfs::path const dbPath(sc.connectionString());
if (bfs::is_regular_file(dbPath))

View File

@@ -4,7 +4,8 @@
#include <xrpl/basics/contract.h>
#include <filesystem>
#include <boost/filesystem.hpp>
#include <fstream>
namespace xrpl::detail {
@@ -15,7 +16,7 @@ namespace xrpl::detail {
class DirGuard
{
protected:
using path = std::filesystem::path;
using path = boost::filesystem::path;
private:
path subDir_;
@@ -42,7 +43,7 @@ public:
DirGuard(beast::unit_test::Suite& test, path subDir, bool useCounter = true)
: subDir_(std::move(subDir)), test_(test)
{
using namespace std::filesystem;
using namespace boost::filesystem;
static auto kSubDirCounter = 0;
if (useCounter)
@@ -68,7 +69,7 @@ public:
{
try
{
using namespace std::filesystem;
using namespace boost::filesystem;
if (rmSubDir_)
rmDir(subDir_);
@@ -125,7 +126,7 @@ public:
{
try
{
using namespace std::filesystem;
using namespace boost::filesystem;
if (exists(file_))
{
remove(file_);
@@ -155,7 +156,7 @@ public:
[[nodiscard]] bool
fileExists() const
{
return std::filesystem::exists(file_);
return boost::filesystem::exists(file_);
}
};

View File

@@ -48,7 +48,6 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <utility>
#include <vector>
@@ -615,7 +614,7 @@ GRPCServerImpl::createServerCredentials()
try
{
std::error_code ec;
boost::system::error_code ec;
grpc::SslServerCredentialsOptions sslOpts;
grpc::SslServerCredentialsOptions::PemKeyCertPair keyCertPair;

View File

@@ -13,7 +13,6 @@
#include <xrpl/beast/core/CurrentThreadName.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/beast/utility/temp_dir.h>
#include <xrpl/ledger/Ledger.h>
#include <xrpl/nodestore/Database.h>
#include <xrpl/nodestore/Scheduler.h>
@@ -25,12 +24,13 @@
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/directory.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <algorithm>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <ios>
#include <limits>
#include <memory>
#include <mutex>
@@ -368,11 +368,11 @@ void
SHAMapStoreImp::dbPaths()
{
Section const section{app_.config().section(ConfigSection::nodeDatabase())};
std::filesystem::path dbPath = get(section, "path");
boost::filesystem::path dbPath = get(section, "path");
if (std::filesystem::exists(dbPath))
if (boost::filesystem::exists(dbPath))
{
if (!std::filesystem::is_directory(dbPath))
if (!boost::filesystem::is_directory(dbPath))
{
journal_.error() << "node db path must be a directory. " << dbPath.string();
Throw<std::runtime_error>("node db path must be a directory.");
@@ -380,7 +380,7 @@ SHAMapStoreImp::dbPaths()
}
else
{
std::filesystem::create_directories(dbPath);
boost::filesystem::create_directories(dbPath);
}
SavedState state = stateDb_.getState();
@@ -391,8 +391,8 @@ SHAMapStoreImp::dbPaths()
return false;
// Check if configured "path" matches stored directory path
using namespace std::filesystem;
auto const stored{std::filesystem::path(sPath)};
using namespace boost::filesystem;
auto const stored{path(sPath)};
if (stored.parent_path() == dbPath)
return false;
@@ -410,9 +410,9 @@ SHAMapStoreImp::dbPaths()
bool writableDbExists = false;
bool archiveDbExists = false;
std::vector<std::filesystem::path> pathsToDelete;
for (std::filesystem::directory_iterator it(dbPath);
it != std::filesystem::directory_iterator();
std::vector<boost::filesystem::path> pathsToDelete;
for (boost::filesystem::directory_iterator it(dbPath);
it != boost::filesystem::directory_iterator();
++it)
{
if (state.writableDb.compare(it->path().string()) == 0)
@@ -433,7 +433,7 @@ SHAMapStoreImp::dbPaths()
(!archiveDbExists && !state.archiveDb.empty()) || (writableDbExists != archiveDbExists) ||
state.writableDb.empty() != state.archiveDb.empty())
{
std::filesystem::path stateDbPathName = app_.config().legacy("database_path");
boost::filesystem::path stateDbPathName = app_.config().legacy("database_path");
stateDbPathName /= dbName_;
stateDbPathName += "*";
@@ -455,15 +455,15 @@ SHAMapStoreImp::dbPaths()
}
// The necessary directories exist. Now, remove any others.
for (std::filesystem::path const& p : pathsToDelete)
std::filesystem::remove_all(p);
for (boost::filesystem::path const& p : pathsToDelete)
boost::filesystem::remove_all(p);
}
std::unique_ptr<NodeStore::Backend>
SHAMapStoreImp::makeBackendRotating(std::string path)
{
Section section{app_.config().section(ConfigSection::nodeDatabase())};
std::filesystem::path newPath;
boost::filesystem::path newPath;
if (!path.empty())
{
@@ -471,7 +471,10 @@ SHAMapStoreImp::makeBackendRotating(std::string path)
}
else
{
newPath = beast::uniqueRandomPath(get(section, "path"), 100, dbPrefix_ + ".");
boost::filesystem::path p = get(section, "path");
p /= dbPrefix_;
p += ".%%%%";
newPath = boost::filesystem::unique_path(p);
}
section.set("path", newPath.string());

View File

@@ -12,7 +12,6 @@
#include <boost/thread/shared_mutex.hpp>
#include <filesystem>
#include <mutex>
#include <shared_mutex>
@@ -205,7 +204,7 @@ class ValidatorList
ManifestCache& validatorManifests_;
ManifestCache& publisherManifests_;
TimeKeeper& timeKeeper_;
std::filesystem::path const dataPath_;
boost::filesystem::path const dataPath_;
beast::Journal const j_;
std::shared_mutex mutable mutex_;
using scoped_lock = std::scoped_lock<decltype(mutex_)>;
@@ -804,7 +803,7 @@ private:
/** Get the filename used for caching UNLs
*/
std::filesystem::path
boost::filesystem::path
getCacheFileName(scoped_lock const&, PublicKey const& pubKey) const;
/** Build a Json representation of the collection, suitable for

View File

@@ -29,8 +29,12 @@
#include <xrpl/server/Manifest.h>
#include <xrpl/server/NetworkOPs.h>
#include <boost/filesystem/operations.hpp>
#include <boost/regex/v5/regex.hpp>
#include <boost/regex/v5/regex_match.hpp>
#include <boost/system/detail/errc.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/errc.hpp>
#include <xrpl.pb.h>
@@ -39,7 +43,6 @@
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <iterator>
#include <limits>
@@ -51,7 +54,6 @@
#include <shared_mutex>
#include <string>
#include <string_view>
#include <system_error>
#include <utility>
#include <vector>
@@ -286,7 +288,7 @@ ValidatorList::load(
return true;
}
std::filesystem::path
boost::filesystem::path
ValidatorList::getCacheFileName(ValidatorList::scoped_lock const&, PublicKey const& pubKey) const
{
return dataPath_ / (kFilePrefix + strHex(pubKey));
@@ -370,9 +372,9 @@ ValidatorList::cacheValidatorFile(ValidatorList::scoped_lock const& lock, Public
if (dataPath_.empty())
return;
std::filesystem::path const filename = getCacheFileName(lock, pubKey);
boost::filesystem::path const filename = getCacheFileName(lock, pubKey);
std::error_code ec;
boost::system::error_code ec;
json::Value value = buildFileData(strHex(pubKey), publisherLists_.at(pubKey), j_);
// xrpld should be the only process writing to this file, so
@@ -1281,7 +1283,8 @@ std::vector<std::string>
ValidatorList::loadLists()
{
using namespace std::string_literals;
using namespace std::filesystem;
using namespace boost::filesystem;
using namespace boost::system::errc;
std::scoped_lock const lock{mutex_};
@@ -1289,12 +1292,12 @@ ValidatorList::loadLists()
sites.reserve(publisherLists_.size());
for (auto const& [pubKey, publisherCollection] : publisherLists_)
{
std::error_code ec;
boost::system::error_code ec;
if (publisherCollection.status == PublisherStatus::Available)
continue;
std::filesystem::path const filename = getCacheFileName(lock, pubKey);
boost::filesystem::path const filename = getCacheFileName(lock, pubKey);
auto const fullPath{canonical(filename, ec)};
if (ec)
@@ -1305,7 +1308,7 @@ ValidatorList::loadLists()
{
// Treat an empty file as a missing file, because
// nobody else is going to write it.
ec = make_error_code(std::errc::no_such_file_or_directory);
ec = make_error_code(no_such_file_or_directory);
}
if (ec)
continue;

View File

@@ -37,6 +37,7 @@
#include <xrpl/rdb/RelationalDatabase.h>
#include <xrpl/rdb/SociDB.h>
#include <boost/filesystem/operations.hpp>
#include <boost/format/free_funcs.hpp>
#include <boost/optional/optional.hpp> // IWYU pragma: keep
#include <boost/system/detail/error_code.hpp>
@@ -52,7 +53,6 @@
#include <cstddef>
#include <cstdint>
#include <exception>
#include <filesystem>
#include <functional>
#include <limits>
#include <map>
@@ -61,7 +61,6 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <utility>
#include <variant>
#include <vector>
@@ -1291,8 +1290,8 @@ getTransaction(
bool
dbHasSpace(soci::session& session, Config const& config, beast::Journal j)
{
std::filesystem::space_info const space =
std::filesystem::space(config.legacy("database_path"));
boost::filesystem::space_info const space =
boost::filesystem::space(config.legacy("database_path"));
if (space.available < megabytes(512))
{
@@ -1303,9 +1302,9 @@ dbHasSpace(soci::session& session, Config const& config, beast::Journal j)
if (config.useTxTables())
{
DatabaseCon::Setup const dbSetup = setupDatabaseCon(config);
std::filesystem::path const dbPath = dbSetup.dataDir / kTxDbName;
std::error_code ec;
std::optional<std::uint64_t> dbSize = std::filesystem::file_size(dbPath, ec);
boost::filesystem::path const dbPath = dbSetup.dataDir / kTxDbName;
boost::system::error_code ec;
std::optional<std::uint64_t> dbSize = boost::filesystem::file_size(dbPath, ec);
if (ec)
{
JLOG(j.error()) << "Error checking transaction db file size: " << ec.message();

View File

@@ -9,8 +9,9 @@
#include <xrpl/protocol/SystemParameters.h> // VFALCO Breaks levelization
#include <xrpl/rdb/DatabaseCon.h>
#include <boost/filesystem.hpp> // VFALCO FIX: This include should not be here
#include <cstdint>
#include <filesystem>
#include <optional>
#include <string>
#include <unordered_set>
@@ -81,17 +82,17 @@ public:
static char const* const kValidatorsFileName;
/** Returns the full path and filename of the debug log file. */
[[nodiscard]] std::filesystem::path
[[nodiscard]] boost::filesystem::path
getDebugLogFile() const;
private:
std::filesystem::path configFile_;
boost::filesystem::path configFile_;
public:
std::filesystem::path configDir;
boost::filesystem::path configDir;
private:
std::filesystem::path debugLogfile_;
boost::filesystem::path debugLogfile_;
void
load();

View File

@@ -22,19 +22,21 @@
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/format/free_funcs.hpp>
#include <boost/multiprecision/detail/endian.hpp>
#include <boost/predef.h>
#include <boost/regex.hpp> // IWYU pragma: keep
#include <boost/regex/v5/regex.hpp>
#include <boost/regex/v5/regex_match.hpp>
#include <boost/system/detail/error_code.hpp>
#include <algorithm>
#include <array>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <iterator>
#include <limits>
@@ -44,7 +46,6 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <thread>
#include <type_traits>
#include <utility>
@@ -313,13 +314,13 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
// directory, use the current working directory as the
// config directory and that with "db" as the data
// directory.
std::filesystem::path dataDir;
boost::filesystem::path dataDir;
if (!strConf.empty())
{
// --conf=<path> : everything is relative that file.
configFile_ = strConf;
configDir = std::filesystem::absolute(configFile_);
configDir = boost::filesystem::absolute(configFile_);
configDir.remove_filename();
dataDir = configDir / kDatabaseDirName;
}
@@ -330,13 +331,13 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
// Check if either of the config files exist in the current working
// directory, in which case the databases will be stored in a
// subdirectory.
configDir = std::filesystem::current_path();
configDir = boost::filesystem::current_path();
dataDir = configDir / kDatabaseDirName;
configFile_ = configDir / kConfigFileName;
if (std::filesystem::exists(configFile_))
if (boost::filesystem::exists(configFile_))
break;
configFile_ = configDir / kConfigLegacyName;
if (std::filesystem::exists(configFile_))
if (boost::filesystem::exists(configFile_))
break;
// Check if the home directory is set, and optionally the XDG config
@@ -363,10 +364,10 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
dataDir = strXdgDataHome + "/" + systemName();
configDir = strXdgConfigHome + "/" + systemName();
configFile_ = configDir / kConfigFileName;
if (std::filesystem::exists(configFile_))
if (boost::filesystem::exists(configFile_))
break;
configFile_ = configDir / kConfigLegacyName;
if (std::filesystem::exists(configFile_))
if (boost::filesystem::exists(configFile_))
break;
}
@@ -374,7 +375,7 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
dataDir = "/var/lib/" + systemName();
configDir = "/etc/" + systemName();
configFile_ = configDir / kConfigFileName;
if (std::filesystem::exists(configFile_))
if (boost::filesystem::exists(configFile_))
break;
configFile_ = configDir / kConfigLegacyName;
} while (false);
@@ -387,7 +388,7 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
std::string const dbPath(legacy("database_path"));
if (!dbPath.empty())
{
dataDir = std::filesystem::path(dbPath);
dataDir = boost::filesystem::path(dbPath);
}
else if (runStandalone_)
{
@@ -397,13 +398,13 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
if (!dataDir.empty())
{
std::error_code ec;
std::filesystem::create_directories(dataDir, ec);
boost::system::error_code ec;
boost::filesystem::create_directories(dataDir, ec);
if (ec)
Throw<std::runtime_error>(boost::str(boost::format("Can not create %s") % dataDir));
legacy("database_path", std::filesystem::absolute(dataDir).string());
legacy("database_path", boost::filesystem::absolute(dataDir).string());
}
HTTPClient::initializeSSLContext(this->sslVerifyDir, this->sslVerifyFile, this->sslVerify, j_);
@@ -455,7 +456,7 @@ Config::load()
if (!quiet_)
std::cerr << "Loading: " << configFile_ << "\n";
std::error_code ec;
boost::system::error_code ec;
auto const fileContents = getFileContents(ec, configFile_);
if (ec)
@@ -508,8 +509,8 @@ Config::loadFromString(std::string const& fileContents)
std::string dbPath;
if (getSingleSection(secConfig, "database_path", dbPath, j_))
{
std::filesystem::path const p(dbPath);
legacy("database_path", std::filesystem::absolute(p).string());
boost::filesystem::path const p(dbPath);
legacy("database_path", boost::filesystem::absolute(p).string());
}
}
@@ -951,7 +952,7 @@ Config::loadFromString(std::string const& fileContents)
// If no path was specified, then look for validators.txt
// in the same directory as the config file, but don't complain
// if we can't find it.
std::filesystem::path validatorsFile;
boost::filesystem::path validatorsFile;
if (getSingleSection(secConfig, SECTION_VALIDATORS_FILE, strTemp, j_))
{
@@ -966,7 +967,7 @@ Config::loadFromString(std::string const& fileContents)
if (!validatorsFile.is_absolute() && !configDir.empty())
validatorsFile = configDir / validatorsFile;
if (!std::filesystem::exists(validatorsFile))
if (!boost::filesystem::exists(validatorsFile))
{
Throw<std::runtime_error>(
"The file specified in [" SECTION_VALIDATORS_FILE
@@ -975,8 +976,8 @@ Config::loadFromString(std::string const& fileContents)
validatorsFile.string());
}
else if (
!std::filesystem::is_regular_file(validatorsFile) &&
!std::filesystem::is_symlink(validatorsFile))
!boost::filesystem::is_regular_file(validatorsFile) &&
!boost::filesystem::is_symlink(validatorsFile))
{
Throw<std::runtime_error>(
"Invalid file specified in [" SECTION_VALIDATORS_FILE "]: " +
@@ -989,24 +990,24 @@ Config::loadFromString(std::string const& fileContents)
if (!validatorsFile.empty())
{
if (!std::filesystem::exists(validatorsFile))
if (!boost::filesystem::exists(validatorsFile))
{
validatorsFile.clear();
}
else if (
!std::filesystem::is_regular_file(validatorsFile) &&
!std::filesystem::is_symlink(validatorsFile))
!boost::filesystem::is_regular_file(validatorsFile) &&
!boost::filesystem::is_symlink(validatorsFile))
{
validatorsFile.clear();
}
}
}
if (!validatorsFile.empty() && std::filesystem::exists(validatorsFile) &&
(std::filesystem::is_regular_file(validatorsFile) ||
std::filesystem::is_symlink(validatorsFile)))
if (!validatorsFile.empty() && boost::filesystem::exists(validatorsFile) &&
(boost::filesystem::is_regular_file(validatorsFile) ||
boost::filesystem::is_symlink(validatorsFile)))
{
std::error_code ec;
boost::system::error_code ec;
auto const data = getFileContents(ec, validatorsFile);
if (ec)
{
@@ -1132,7 +1133,7 @@ Config::loadFromString(std::string const& fileContents)
}
}
std::filesystem::path
boost::filesystem::path
Config::getDebugLogFile() const
{
auto logFile = debugLogfile_;
@@ -1141,17 +1142,17 @@ Config::getDebugLogFile() const
{
// Unless an absolute path for the log file is specified, the
// path is relative to the config file directory.
logFile = std::filesystem::absolute(configDir / logFile);
logFile = boost::filesystem::absolute(logFile, configDir);
}
if (!logFile.empty())
{
auto logDir = logFile.parent_path();
if (!std::filesystem::is_directory(logDir))
if (!boost::filesystem::is_directory(logDir))
{
std::error_code ec;
std::filesystem::create_directories(logDir, ec);
boost::system::error_code ec;
boost::filesystem::create_directories(logDir, ec);
// If we fail, we warn but continue so that the calling code can
// decide how to handle this situation.

View File

@@ -13,9 +13,11 @@
#include <xrpl/json/json_writer.h>
#include <xrpl/protocol/jss.h>
#include <boost/filesystem/operations.hpp>
#include <boost/system/detail/error_code.hpp>
#include <chrono>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <ios>
#include <memory>
@@ -23,7 +25,6 @@
#include <ostream>
#include <set>
#include <string>
#include <system_error>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -215,10 +216,10 @@ PerfLogImp::openLog()
logFile_.close();
auto logDir = setup_.perfLog.parent_path();
if (!std::filesystem::is_directory(logDir))
if (!boost::filesystem::is_directory(logDir))
{
std::error_code ec;
std::filesystem::create_directories(logDir, ec);
boost::system::error_code ec;
boost::filesystem::create_directories(logDir, ec);
if (ec)
{
JLOG(j_.fatal()) << "Unable to create performance log "
@@ -473,17 +474,17 @@ PerfLogImp::stop()
//-----------------------------------------------------------------------------
PerfLog::Setup
setupPerfLog(Section const& section, std::filesystem::path const& configDir)
setupPerfLog(Section const& section, boost::filesystem::path const& configDir)
{
PerfLog::Setup setup;
std::string perfLog;
set(perfLog, "perf_log", section);
if (!perfLog.empty())
{
setup.perfLog = std::filesystem::path(perfLog);
setup.perfLog = boost::filesystem::path(perfLog);
if (setup.perfLog.is_relative())
{
setup.perfLog = std::filesystem::absolute(configDir / setup.perfLog);
setup.perfLog = boost::filesystem::absolute(setup.perfLog, configDir);
}
}