Skip to content

feat: add clang-format, clang-tidy, pre-commit hooks and CI lint workflow#12

Closed
deku2026 wants to merge 4 commits into
mainfrom
feat/clang-lint-ci
Closed

feat: add clang-format, clang-tidy, pre-commit hooks and CI lint workflow#12
deku2026 wants to merge 4 commits into
mainfrom
feat/clang-lint-ci

Conversation

@deku2026
Copy link
Copy Markdown

@deku2026 deku2026 commented Mar 9, 2026

Summary

  • Add .clang-format\ (Google-based, C++20, 120 col, 4-space indent)
  • Add .clang-tidy\ with comprehensive checks (bugprone, cert, modernize, performance, readability)
  • Add .pre-commit-config.yaml\ with trailing-whitespace, line-ending, codespell, clang-format, clang-tidy hooks
  • Add GitHub Actions \lint.yml\ workflow (ubuntu-24.04, LLVM 20, pre-commit/action)
  • Add \compile_commands.json\ auto-copy to \�uild/\ in CMakeLists.txt
  • Apply clang-format to all source files
  • Fix all clang-tidy warnings (narrowing conversions, deprecated headers, modernize suggestions)
  • Normalize line endings to LF across all files

Local Setup

\\�ash
pip install pre-commit
pre-commit install
\\

Tools

  • LLVM 20.1.8 (clang-format, clang-tidy)
  • pre-commit 4.x

…flow

- Add .clang-format (Google-based, C++20, 120 col, 4-space indent)
- Add .clang-tidy with comprehensive checks (bugprone, cert, modernize, performance, readability)
- Add .pre-commit-config.yaml with trailing-whitespace, line-ending, codespell, clang-format, clang-tidy hooks
- Add GitHub Actions lint.yml workflow (ubuntu-24.04, LLVM 20, pre-commit/action)
- Add compile_commands.json auto-copy to build/ in CMakeLists.txt
- Apply clang-format to all source files
- Fix all clang-tidy warnings (narrowing conversions, deprecated headers, modernize suggestions)
- Normalize line endings to LF across all files

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 9, 2026 10:22
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds repository-wide C++ linting/formatting infrastructure (clang-format/clang-tidy via pre-commit) and a GitHub Actions lint workflow, alongside codebase reformatting and minor modernization to satisfy the new tooling.

Changes:

  • Introduce .clang-format, .clang-tidy, .pre-commit-config.yaml, and CI lint workflow to run these checks automatically.
  • Update CMake to provide compile_commands.json at a stable location for tooling.
  • Apply formatting/modernization changes across source, headers, and docs (including LF normalization).

Reviewed changes

Copilot reviewed 30 out of 39 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/util/value.cpp Namespace formatting cleanup.
src/util/timerange.cpp Reformat + minor modernizations (brace-init, moves, casts).
src/util/timecodefunctions.cpp Reformat + minor modernizations/casts.
src/util/tests.cpp Switch to C++ header <cstdarg> + reformat.
src/util/stringutils.cpp Switch to <cstdarg> + reformat/modernize returns.
src/util/rational.cpp Switch to <cmath> + reformat/modernize operator=.
src/util/color.cpp Header modernization (<cstdint>, <cmath>) + reformat.
src/util/bezier.cpp Reformat/condense trivial constructors and expressions.
src/render/samplebuffer.cpp Header modernization (<cstring>, <utility>) + reformat/move usage.
src/render/audioparams.cpp Reformat + cast changes to satisfy tidy.
include/arcvideo/foundation/util/value.h Header modernization + reformat constructors.
include/arcvideo/foundation/util/timerange.h Reformat + API tweaks (iterator ctor takes list by value).
include/arcvideo/foundation/util/timecodefunctions.h Reformat + line wrapping for declarations.
include/arcvideo/foundation/util/tests.h Reformat + minor type spacing changes.
include/arcvideo/foundation/util/stringutils.h Reformat + minor signature/inline formatting changes.
include/arcvideo/foundation/util/rational.h Reformat + make assignment operator return rational&.
include/arcvideo/foundation/util/math.h Simplify empty namespace formatting.
include/arcvideo/foundation/util/log.h Reformat and condense trivial methods.
include/arcvideo/foundation/util/cpuoptimize.h Comment spacing normalization.
include/arcvideo/foundation/util/color.h Reformat; keep operators inline; preserve API.
include/arcvideo/foundation/util/bezier.h Reformat and wrap long signatures.
include/arcvideo/foundation/render/sampleformat.h Reformat + add [[nodiscard]] to some accessors.
include/arcvideo/foundation/render/samplebuffer.h Reformat + constructors now take AudioParams by value.
include/arcvideo/foundation/render/pixelformat.h Reformat and condense enum/utility methods.
include/arcvideo/foundation/render/audioparams.h Reformat and inline many trivial getters/setters.
include/arcvideo/foundation/foundation.h Header guard comment spacing normalization.
docs/BUILD_GUIDE.md LF normalization + Markdown separator normalization.
SECURITY.md Trailing whitespace fix.
README.md LF normalization + Markdown separator normalization.
CMakePresets.json LF normalization (no functional changes apparent).
CMakeLists.txt Add compile_commands copy target + LF normalization.
.pre-commit-config.yaml Add pre-commit hooks for whitespace/codespell/clang-format/clang-tidy.
.gitignore LF normalization.
.github/workflows/lint.yml Add CI workflow that installs LLVM/vcpkg deps and runs pre-commit.
.github/dependabot.yml Trailing newline cleanup.
.clang-tidy Add clang-tidy check configuration.
.clang-format Add clang-format style configuration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CMakeLists.txt
Comment on lines +37 to +46
# Copy compile_commands.json to project root for clangd / clang-tidy
if(CMAKE_EXPORT_COMPILE_COMMANDS)
add_custom_target(copy-compile-commands ALL
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_SOURCE_DIR}/build"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_BINARY_DIR}/compile_commands.json"
"${CMAKE_SOURCE_DIR}/build/compile_commands.json"
COMMENT "Copying compile_commands.json to build/"
)
endif()
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy-compile-commands unconditionally copies ${CMAKE_BINARY_DIR}/compile_commands.json whenever CMAKE_EXPORT_COMPILE_COMMANDS is ON. Some generators (notably Visual Studio) don't generate compile_commands.json, so this target can fail the build by trying to copy a non-existent file. Consider guarding on generator support and/or performing the copy via a small cmake -P script that checks file existence before copying.

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/lint.yml Outdated
Comment on lines +18 to +23
- name: Install LLVM 20 and build tools
run: |
sudo apt-get update
sudo apt-get install -y nasm pkg-config
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-20 main" | sudo tee /etc/apt/sources.list.d/llvm-20.list
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow uses apt-key to add the LLVM APT signing key. apt-key is deprecated on Ubuntu and may stop working in future runner images; prefer installing the key into /etc/apt/keyrings and using signed-by= in the deb entry (and consider using https://apt.llvm.org/...).

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +5 to +8
**Pure C++20 Core Library for AI-Powered Video Editing**

[![C++20](https://img.shields.io/badge/C%2B%2B-20-blue?logo=cplusplus)](https://isocpp.org/)
[![CMake](https://img.shields.io/badge/CMake-4.2+-064F8C?logo=cmake)](https://cmake.org/)
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README claims the project is C++20 (badge/text), but the build config sets CMAKE_CXX_STANDARD 23 and uses cxx_std_23 in CMakeLists.txt. This is confusing for users and tool configuration (e.g., .clang-format sets Standard: c++20). Please align the documentation and tooling with the actual language standard (either update docs to C++23 or switch the project/tooling back to C++20).

Copilot uses AI. Check for mistakes.
Comment thread src/util/color.cpp
Comment on lines +74 to +77
if (fDelta > 0) {
if (fCMax == red()) {
*hue = static_cast<DataType>(60 * (fmod(((green() - blue()) / fDelta), 6)));
} else if (fCMax == green()) {
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After switching to <cmath>, fmod isn't guaranteed to be available in the global namespace. This can cause portability/compile issues; use std::fmod (or using std::fmod;) here.

Copilot uses AI. Check for mistakes.
Comment thread src/util/rational.cpp
Comment on lines +32 to +36
rational rational::fromDouble(const double &flt, bool *ok) {
if (isnan(flt)) {
// Return NaN rational
if (ok) *ok = false;
return NaN;
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<cmath> doesn't guarantee isnan is available in the global namespace; this can break compilation on some standard libraries. Use std::isnan (or using std::isnan;) here after switching from <math.h> to <cmath>.

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +71
Value(int64_t v) : type_(INT) {
data_.resize(sizeof(int64_t));
memcpy(data_.data(), &v, sizeof(int64_t));
}

Value(double v) : type_(FLOAT) {
data_.resize(sizeof(double));
memcpy(data_.data(), &v, sizeof(double));
}

Value(const char *s) {
if (!s) {
type_ = NONE;
return;
}
size_t sz = strlen(s);
data_.resize(sz);
memcpy(data_.data(), s, sz);
type_ = STRING;
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After switching to <cstring>, relying on unqualified memcpy/strlen is non-portable (these functions are only guaranteed in std::). Please qualify them (std::memcpy, std::strlen) or include the corresponding C headers if you intentionally want the global versions.

Copilot uses AI. Check for mistakes.
Comment on lines +225 to 247
for (int i = 0; i < audio_params().channel_count(); i++) {
memset(reinterpret_cast<char *>(data_[i].data()) + start_byte, 0, end_byte - start_byte);
}
}

void SampleBuffer::set(int channel, const float *data, size_t sample_offset, size_t sample_length)
{
if (!is_allocated()) {
Log::Warning() << "Tried to fill an unallocated sample buffer";
return;
}
void SampleBuffer::set(int channel, const float *data, size_t sample_offset, size_t sample_length) {
if (!is_allocated()) {
Log::Warning() << "Tried to fill an unallocated sample buffer";
return;
}

if (channel < 0 || channel >= audio_params_.channel_count()) {
Log::Warning() << "Tried to set data on out-of-range channel";
return;
}
if (channel < 0 || channel >= audio_params_.channel_count()) {
Log::Warning() << "Tried to set data on out-of-range channel";
return;
}

if (sample_offset + sample_length > static_cast<size_t>(sample_count_per_channel_)) {
Log::Warning() << "Tried to set data beyond sample buffer bounds";
return;
}
if (sample_offset + sample_length > static_cast<size_t>(sample_count_per_channel_)) {
Log::Warning() << "Tried to set data beyond sample buffer bounds";
return;
}

memcpy(&data_[channel].data()[sample_offset], data, sizeof(float) * sample_length);
memcpy(&data_[channel].data()[sample_offset], data, sizeof(float) * sample_length);
}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memset/memcpy are used unqualified after switching to <cstring>. These are only guaranteed to be available as std::memset/std::memcpy, so this can fail to compile on some platforms/standard libraries.

Copilot uses AI. Check for mistakes.
Comment on lines +94 to 96
rational AudioParams::samples_to_time(const int64_t &samples) const {
return sample_rate_as_time_base() * static_cast<int>(samples);
}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This narrows int64_t samples to int before converting to rational, which will truncate/overflow for long durations. If rational is limited to int, consider clamping/validating (assert(samples <= INT_MAX)) or computing the time via a representation that can handle int64_t (e.g., rational::fromDouble(static_cast<double>(samples) / sample_rate())).

Copilot uses AI. Check for mistakes.
deku2026 and others added 2 commits March 9, 2026 18:41
- Use std::isnan, std::fmod, std::memcpy, std::memset, std::strlen
- Fix samples_to_time int64_t overflow via rational::fromDouble
- Delete standalone lint.yml, add pre-commit step to linux-ci.yml
- Add [[nodiscard]] to sampleformat.h member functions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The CMake configure step generates compile_commands.json in
build/linux-ci/ but pre-commit clang-tidy expects it at build/.
Add explicit copy step between configure and lint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@deku2026 deku2026 closed this Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants