Skip to content

Commit 53e230a

Browse files
committed
initial commit
1 parent 113b26c commit 53e230a

40 files changed

Lines changed: 3354 additions & 602 deletions

.coveragerc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[run]
2+
branch = True
3+
data_file = build/coverage/.coverage
4+
source =
5+
netgraph_core
6+
omit =
7+
python/netgraph_core/_docs.py
8+
9+
[report]
10+
show_missing = True
11+
skip_covered = True

.gcovr.cfg

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[gcovr]
2+
root = .
3+
4+
# Object dirs for Python extension and standalone C++ test builds
5+
object-directory = build
6+
object-directory = build/cpp-tests-cov
7+
8+
# Only include our sources
9+
filter = include/netgraph
10+
filter = src
11+
12+
# Exclude tests and third-party deps
13+
exclude = tests
14+
exclude = bindings/.*
15+
exclude-directories = .*/_deps/.*
16+
exclude-directories = .*/venv/.*
17+
exclude-directories = .*/site-packages/.*
18+
19+
# Work around odd temp working dirs on macOS/pybind11
20+
gcov-ignore-errors = all

.github/workflows/tests.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
name: Unit tests (${{ matrix.os }}, py${{ matrix.python-version }})
11+
runs-on: ${{ matrix.os }}
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
os: [ubuntu-22.04, macos-13]
16+
python-version: ["3.10", "3.11", "3.12", "3.13"]
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: actions/setup-python@v5
20+
with:
21+
python-version: ${{ matrix.python-version }}
22+
- name: Install deps
23+
run: |
24+
python -m pip install -U pip wheel
25+
python -m pip install -e .[dev]
26+
- name: Run CI checks (lint + C++/Python tests)
27+
run: make check-ci
28+
29+
coverage:
30+
name: Coverage (ubuntu, py3.11)
31+
runs-on: ubuntu-22.04
32+
steps:
33+
- uses: actions/checkout@v4
34+
- uses: actions/setup-python@v5
35+
with:
36+
python-version: "3.11"
37+
- name: Install deps
38+
run: |
39+
python -m pip install -U pip wheel
40+
python -m pip install -e .[dev]
41+
- name: Generate coverage (Python + C++)
42+
run: make cov
43+
- name: Upload coverage artifacts
44+
uses: actions/upload-artifact@v4
45+
with:
46+
name: coverage-reports
47+
path: |
48+
build/coverage/coverage-python.xml
49+
build/coverage/coverage-cpp.xml
50+
build/coverage/coverage-combined.html
51+
# - name: Upload to Codecov
52+
# uses: codecov/codecov-action@v4
53+
# with:
54+
# files: |
55+
# coverage-python.xml
56+
# coverage-cpp.xml
57+
# token: ${{ secrets.CODECOV_TOKEN }}
58+
# fail_ci_if_error: false

.github/workflows/wheels.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Build wheels
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
pull_request:
8+
9+
jobs:
10+
build_wheels:
11+
name: Build wheels on ${{ matrix.os }}
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
matrix:
15+
os: [ubuntu-22.04, macos-13]
16+
py: ['cp310', 'cp311', 'cp312', 'cp313']
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: pypa/cibuildwheel@v2.21.3
20+
env:
21+
CIBW_BUILD: ${{ matrix.py }}-*
22+
CIBW_SKIP: pp* *-musllinux_*
23+
CIBW_ARCHS_MACOS: universal2
24+
CIBW_TEST_COMMAND: python -c "import netgraph_core; print(netgraph_core.__version__)"
25+
- uses: actions/upload-artifact@v4
26+
with:
27+
name: wheels-${{ matrix.os }}-${{ matrix.py }}
28+
path: wheelhouse/*.whl

.gitignore

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ coverage.xml
5151
.pytest_cache/
5252
cover/
5353

54+
# Consolidated coverage artifacts
55+
build/coverage/
56+
57+
# CTest output if created in project root
58+
Testing/
59+
CTestTestfile.cmake
60+
5461
# Translations
5562
*.mo
5663
*.pot
@@ -182,11 +189,11 @@ cython_debug/
182189
.abstra/
183190

184191
# Visual Studio Code
185-
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
192+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186193
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187-
# and can be added to the global gitignore or merged into this file. However, if you prefer,
194+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
188195
# you could uncomment the following to ignore the entire vscode folder
189-
# .vscode/
196+
.vscode/
190197

191198
# Ruff stuff:
192199
.ruff_cache/
@@ -201,6 +208,13 @@ cython_debug/
201208
.cursorignore
202209
.cursorindexingignore
203210

211+
# OS-specific
212+
.DS_Store
213+
214+
# IDEs
215+
.idea/
216+
*.code-workspace
217+
204218
# Marimo
205219
marimo/_static/
206220
marimo/_lsp/

.pre-commit-config.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v5.0.0
4+
hooks:
5+
- id: check-merge-conflict
6+
- id: check-yaml
7+
- id: end-of-file-fixer
8+
- id: trailing-whitespace
9+
- id: mixed-line-ending
10+
- id: debug-statements
11+
12+
- repo: https://github.com/astral-sh/ruff-pre-commit
13+
rev: v0.11.13
14+
hooks:
15+
- id: ruff
16+
args: ["--fix"]
17+
- id: ruff-format
18+
19+
- repo: https://github.com/RobertCraigie/pyright-python
20+
rev: v1.1.401
21+
hooks:
22+
- id: pyright
23+
additional_dependencies: ["numpy>=1.22"]
24+
# Pyright reads configuration from pyproject.toml

CMakeLists.txt

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
cmake_minimum_required(VERSION 3.23)
2+
project(netgraph_core LANGUAGES CXX)
3+
# Optional C++ tests
4+
option(NETGRAPH_CORE_BUILD_TESTS "Build C++ unit tests" OFF)
5+
if(NETGRAPH_CORE_BUILD_TESTS)
6+
include(FetchContent)
7+
FetchContent_Declare(
8+
googletest
9+
URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
10+
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
11+
)
12+
FetchContent_MakeAvailable(googletest)
13+
enable_testing()
14+
add_executable(netgraph_core_tests tests/cpp/smoke_test.cpp)
15+
target_link_libraries(netgraph_core_tests PRIVATE netgraph_core GTest::gtest_main)
16+
if(NETGRAPH_CORE_COVERAGE AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang"))
17+
target_compile_options(netgraph_core_tests PRIVATE -O0 -g --coverage)
18+
target_link_options(netgraph_core_tests PRIVATE --coverage)
19+
endif()
20+
include(GoogleTest)
21+
gtest_discover_tests(netgraph_core_tests)
22+
endif()
23+
24+
set(CMAKE_CXX_STANDARD 20)
25+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
26+
set(CMAKE_CXX_EXTENSIONS OFF)
27+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
28+
29+
# Dependencies
30+
find_package(pybind11 CONFIG QUIET)
31+
if(NOT pybind11_FOUND)
32+
message(STATUS "pybind11 not found via config; using FetchContent")
33+
include(FetchContent)
34+
FetchContent_Declare(
35+
pybind11
36+
GIT_REPOSITORY https://github.com/pybind/pybind11.git
37+
GIT_TAG v2.12.0
38+
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
39+
)
40+
FetchContent_MakeAvailable(pybind11)
41+
endif()
42+
43+
add_library(netgraph_core STATIC
44+
src/strict_multidigraph.cpp
45+
src/shortest_paths.cpp
46+
src/k_shortest_paths.cpp
47+
src/max_flow.cpp
48+
src/cpu_backend.cpp
49+
)
50+
target_include_directories(netgraph_core PUBLIC
51+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
52+
$<INSTALL_INTERFACE:include>
53+
)
54+
target_compile_definitions(netgraph_core PRIVATE _USE_MATH_DEFINES)
55+
## C++ standard is set globally above.
56+
target_compile_features(netgraph_core PUBLIC cxx_std_20)
57+
58+
# Warnings
59+
if(MSVC)
60+
target_compile_options(netgraph_core PRIVATE /W4 /permissive-)
61+
else()
62+
target_compile_options(netgraph_core PRIVATE -Wall -Wextra -Wpedantic)
63+
endif()
64+
65+
# Python extension
66+
pybind11_add_module(_netgraph_core bindings/python/module.cpp)
67+
target_link_libraries(_netgraph_core PRIVATE netgraph_core)
68+
target_compile_features(_netgraph_core PRIVATE cxx_std_20)
69+
70+
# Optional coverage instrumentation for GCC/Clang
71+
option(NETGRAPH_CORE_COVERAGE "Enable C++ coverage instrumentation" OFF)
72+
if(NETGRAPH_CORE_COVERAGE)
73+
message(STATUS "Enabling coverage instrumentation for C++ targets")
74+
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
75+
foreach(tgt netgraph_core _netgraph_core)
76+
# Use no optimizations and include debug info for accurate line mapping
77+
target_compile_options(${tgt} PRIVATE -O0 -g --coverage)
78+
# Link coverage runtime
79+
target_link_options(${tgt} PRIVATE --coverage)
80+
endforeach()
81+
else()
82+
message(WARNING "NETGRAPH_CORE_COVERAGE is set but compiler '${CMAKE_CXX_COMPILER_ID}' is not supported")
83+
endif()
84+
endif()
85+
86+
# Optional sanitizers for debug testing
87+
option(NETGRAPH_CORE_SANITIZE "Enable Address/Undefined sanitizers" OFF)
88+
if(NETGRAPH_CORE_SANITIZE)
89+
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
90+
set(SAN_FLAGS "-fsanitize=address,undefined -fno-omit-frame-pointer")
91+
foreach(tgt netgraph_core _netgraph_core)
92+
target_compile_options(${tgt} PRIVATE ${SAN_FLAGS})
93+
target_link_options(${tgt} PRIVATE ${SAN_FLAGS})
94+
endforeach()
95+
else()
96+
message(WARNING "NETGRAPH_CORE_SANITIZE is set but compiler '${CMAKE_CXX_COMPILER_ID}' is not supported")
97+
endif()
98+
endif()
99+
100+
# Install
101+
install(TARGETS _netgraph_core
102+
LIBRARY DESTINATION .
103+
RUNTIME DESTINATION .
104+
)

0 commit comments

Comments
 (0)