writes to xo-camke/etc/xo/subsystem-edges; rejects if build directory doesn't enable all the dependency-unlocking feature flags.
86 lines
3.4 KiB
Bash
86 lines
3.4 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# xo-gen-clang-format - generate a .clang-format from an xo subsystem-edges file
|
|
#
|
|
# Emits (to stdout) a .clang-format whose IncludeCategories encode the xo
|
|
# include-ordering policy:
|
|
#
|
|
# 0 self (the translation unit's own header; matched automatically)
|
|
# 1 self-subsystem (same-repo, "quoted" includes)
|
|
# 2+ other xo (one category per subsystem, DESCENDING topological order)
|
|
# electives (third-party packages: catch2, pybind11, replxx, ...)
|
|
# C++ stdlib (<vector>, <iostream>, ...)
|
|
# platform (<time.h>, <sys/mman.h>, ...)
|
|
#
|
|
# The xo block is derived from EDGES_FILE (tsort format, "dep self" pairs, the
|
|
# same file xo_emit_dependency_edges() writes). Reversed tsort order puts
|
|
# higher-level subsystems first, matching the "descending topo" policy.
|
|
#
|
|
# Usage:
|
|
# xo-gen-clang-format [EDGES_FILE] > .clang-format
|
|
#
|
|
# EDGES_FILE defaults to the snapshot installed alongside xo-cmake, so this is
|
|
# runnable outside a build tree (e.g. to regenerate .clang-format from
|
|
# xo-cmake/etc/xo/subsystem-edges).
|
|
|
|
set -euo pipefail
|
|
|
|
# baked at configure time, like xo-deps' INSTALLED_EDGES_FILE
|
|
INSTALLED_EDGES_FILE=@CMAKE_INSTALL_FULL_DATADIR@/etc/xo/subsystem-edges
|
|
|
|
edges_file="${1:-$INSTALLED_EDGES_FILE}"
|
|
|
|
if [[ ! -r "$edges_file" ]]; then
|
|
echo "xo-gen-clang-format: cannot read edges file: $edges_file" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# tsort yields dependencies-first (bottom-up); reverse (tac) for descending topo
|
|
# order, so higher-level subsystems get earlier categories.
|
|
order=$(tsort "$edges_file" | tac)
|
|
|
|
emit_xo_categories() {
|
|
local prio=100
|
|
local repo prefix
|
|
for repo in $order; do
|
|
prefix="${repo#xo-}" # xo-indentlog -> indentlog (=> <xo/indentlog/...>)
|
|
printf " - { Regex: '^<xo/%s/',%*sPriority: %d }\n" \
|
|
"$prefix" $(( 18 - ${#prefix} > 1 ? 18 - ${#prefix} : 1 )) "" "$prio"
|
|
prio=$((prio + 1))
|
|
done
|
|
}
|
|
|
|
cat <<'HEADER'
|
|
# GENERATED by xo-gen-clang-format. DO NOT EDIT.
|
|
#
|
|
# Regenerate from the committed snapshot:
|
|
# xo-gen-clang-format > .clang-format
|
|
# or from a build tree's edge list:
|
|
# xo-gen-clang-format path/to/build/subsystem-edges > .clang-format
|
|
#
|
|
# Only include ordering (+ preprocessor-directive indentation) is specified
|
|
# here; other formatting is left to defaults.
|
|
Language: Cpp
|
|
SortIncludes: CaseSensitive
|
|
# Merge (not Regroup): order includes by the categories below in one block,
|
|
# without forcing a blank line between every category (per-subsystem categories
|
|
# would otherwise scatter blank lines through the xo block).
|
|
IncludeBlocks: Merge
|
|
IncludeIsMainRegex: '(\.test|_test|_utest)?$'
|
|
# Preprocessor-guarded includes: indent one space per nesting level after '#',
|
|
# so #ifdef X / # include ... / #endif is preserved (not flattened to #include).
|
|
# NB this ENFORCES that indentation on nested #-directives, not just preserves it.
|
|
IndentPPDirectives: AfterHash
|
|
PPIndentWidth: 1
|
|
IncludeCategories:
|
|
- { Regex: '^"', Priority: 1 } # self-subsystem (same-repo, quoted)
|
|
HEADER
|
|
|
|
emit_xo_categories
|
|
|
|
cat <<'TAIL'
|
|
- { Regex: '^<xo/', Priority: 500 } # any other xo (fallback / not in graph)
|
|
- { Regex: '^<(catch2|pybind11|replxx|Eigen|nlohmann|websocketpp|boost|json)', Priority: 600 } # electives
|
|
- { Regex: '^<[A-Za-z0-9_]+>', Priority: 700 } # C++ standard library (angle, no dot/slash)
|
|
- { Regex: '^<.*\.h>', Priority: 800 } # platform / C headers
|
|
TAIL
|