From f53fa2717c55bda542de07381b17161d7dcb4340 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 13:48:20 +0300 Subject: [PATCH 01/23] setting linterts #12 --- algorithm/.clang-format | 4 +--- algorithm/.clang-tidy | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/algorithm/.clang-format b/algorithm/.clang-format index 034dc90..43558d1 100644 --- a/algorithm/.clang-format +++ b/algorithm/.clang-format @@ -1,4 +1,3 @@ ---- Language: Cpp BasedOnStyle: Google @@ -9,5 +8,4 @@ UseTab: Never PointerAlignment: Left -SortIncludes: true ---- \ No newline at end of file +SortIncludes: true \ No newline at end of file diff --git a/algorithm/.clang-tidy b/algorithm/.clang-tidy index 71a7da5..432c638 100644 --- a/algorithm/.clang-tidy +++ b/algorithm/.clang-tidy @@ -1,7 +1,7 @@ ---- Checks: > -*, bugprone-*, + cert-*, clang-analyzer-*, performance-*, portability-*, @@ -16,5 +16,4 @@ HeaderFilterRegex: '.*' CheckOptions: - key: readability-braces-around-statements.ShortStatementLines - value: '1' ---- \ No newline at end of file + value: '1' \ No newline at end of file From 497784a428ac8e5223f48a6c26a9d25b111e3fa6 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 13:49:17 +0300 Subject: [PATCH 02/23] setting Cmakefile + test #12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Использовать Ninja для сборки, чтобы создавался json lkz последующей проверки линтерами. --- algorithm/CMakeLists.txt | 15 ++++++++++++++- algorithm/tests/test_algorithm.c | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 algorithm/tests/test_algorithm.c diff --git a/algorithm/CMakeLists.txt b/algorithm/CMakeLists.txt index 7d44ff9..715aebf 100644 --- a/algorithm/CMakeLists.txt +++ b/algorithm/CMakeLists.txt @@ -5,8 +5,21 @@ project(SpacedRepetition C) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED True) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -Werror") +endif() + include_directories(include) add_library(spaced_rep STATIC src/algorithm.c -) \ No newline at end of file +) + +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_algorithm.c") + add_executable(test_algorithm + tests/test_algorithm.c + ) + target_link_libraries(test_algorithm spaced_rep) +endif() \ No newline at end of file diff --git a/algorithm/tests/test_algorithm.c b/algorithm/tests/test_algorithm.c new file mode 100644 index 0000000..f9f4ff8 --- /dev/null +++ b/algorithm/tests/test_algorithm.c @@ -0,0 +1,6 @@ +#include + +int main() { + printf("Algorithm tests starting...\n"); + return 0; +} \ No newline at end of file From 712a38615c83dd99a6843661a2af89b2a868511f Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 14:21:07 +0300 Subject: [PATCH 03/23] add struct current and update card and calc #13 --- algorithm/include/algorithm.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/algorithm/include/algorithm.h b/algorithm/include/algorithm.h index e69de29..ed7c926 100644 --- a/algorithm/include/algorithm.h +++ b/algorithm/include/algorithm.h @@ -0,0 +1,35 @@ +#ifndef ALGORITHM_H +#define ALGORITHM_H + +#ifdef __cplusplus +extern "C" { +#endif + +// struct, current state card +struct CardState { + int interval; // current interval + float easiness; // diff level + int repetitions; // accurace repeat +}; + +// struct for returning new data +struct ReviewResult { + int next_interval; // new interval + float new_easiness; // update diff level + int repetitions; // update quantity repeat + int quality; // grade +}; + +/** + * main function + * @param similarity_percent match percentage + * @param current_state current param card + * @return update param card for save in DB + */ +struct ReviewResult calculate_next_review(float similarity_percent, struct CardState current_state); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file From dfe6d7977699fb2a92dde6ea535618fe31dcce10 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 14:39:35 +0300 Subject: [PATCH 04/23] realiazation algorithm #14 --- algorithm/src/algorithm.c | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/algorithm/src/algorithm.c b/algorithm/src/algorithm.c index e69de29..920db56 100644 --- a/algorithm/src/algorithm.c +++ b/algorithm/src/algorithm.c @@ -0,0 +1,54 @@ +#include "algorithm.h" + +struct ReviewResult calculate_next_review(float similarity_percent, + struct CardState current_state) { + struct ReviewResult result; + int quality = 0; + + // percent -> grade + if (similarity_percent < 40.0F) { + quality = 0; // bad + } else if (similarity_percent < 60.0F) { + quality = 2; // normal + } else if (similarity_percent < 80.0F) { + quality = 4; // good + } else { + quality = 5; // perfect + } + + result.quality = quality; + + // new Easiness Factor (EF) on formula SM-2 + // EF = EF + (0.1 - (5 - q) * (0.08 + (5 - q) * 0.02)) + float q_diff = 5.0F - (float)quality; + float new_ef = current_state.easiness + (0.1F - (q_diff * (0.08F + (q_diff * 0.02F)))); + + // EF != <1.3 + if (new_ef < 1.3F) { + new_ef = 1.3F; + } + result.new_easiness = new_ef; + + // update counter + if (quality < 3) { + // bad answer -> progress 0 + result.repetitions = 0; + result.next_interval = 1; + } else { + // good answer -> +1 counter + result.repetitions = current_state.repetitions + 1; + + // calculation new interval + if (result.repetitions == 1) { + result.next_interval = 1; + } else if (result.repetitions == 2) { + result.next_interval = 6; + } else { + // + 0.5F for correct rounding + result.next_interval = + (int)((((float)current_state.interval) * result.new_easiness) + 0.5F); + } + } + + return result; +} \ No newline at end of file From 6d9beee591e673183d97294e6f512c3992b4a820 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 14:49:14 +0300 Subject: [PATCH 05/23] test algorithm #15 --- algorithm/tests/test_algorithm.c | 66 +++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/algorithm/tests/test_algorithm.c b/algorithm/tests/test_algorithm.c index f9f4ff8..71a5065 100644 --- a/algorithm/tests/test_algorithm.c +++ b/algorithm/tests/test_algorithm.c @@ -1,6 +1,70 @@ +#include #include +#include "algorithm.h" + +// auxiliary function +struct CardState apply_result_to_card(struct ReviewResult res) { + struct CardState new_card; + new_card.interval = res.next_interval; + new_card.easiness = res.new_easiness; + new_card.repetitions = res.repetitions; + return new_card; +} + int main() { - printf("Algorithm tests starting...\n"); + printf("Starting algorithm tests...\n"); + + // new card + struct CardState card = {0, 2.5F, 0}; + struct ReviewResult result; + + // test 1: bad answer + printf("Test 1: Bad answer (< 40%%)\n"); + result = calculate_next_review(20.0F, card); + + assert(result.quality == 0); + assert(result.next_interval == 1); + assert(result.repetitions == 0); + assert(result.new_easiness < 2.5F); + card = apply_result_to_card(result); + + // test 2 perfect answer + printf("Test 2: Perfect answer (1st time)\n"); + result = calculate_next_review(95.0F, card); + + assert(result.quality == 5); + assert(result.repetitions == 1); + assert(result.next_interval == 1); + assert(result.new_easiness > card.easiness); + card = apply_result_to_card(result); + + // test 3 perfect answer (2) + printf("Test 3: Perfect answer (2nd time)\n"); + result = calculate_next_review(85.0F, card); + + assert(result.quality == 5); + assert(result.repetitions == 2); + assert(result.next_interval == 6); + card = apply_result_to_card(result); + + // test 4 perfect answer (3) + printf("Test 4: Perfect answer (3rd time)\n"); + result = calculate_next_review(100.0F, card); + + assert(result.quality == 5); + assert(result.repetitions == 3); + assert(result.next_interval > 6); + card = apply_result_to_card(result); + + // test 5 bad answer + printf("Test 5: Bad answer after streak\n"); + result = calculate_next_review(10.0F, card); + + assert(result.quality == 0); + assert(result.repetitions == 0); + assert(result.next_interval == 1); + + printf("SUCCESS! All assertions passed. Algorithm works perfectly!\n"); return 0; } \ No newline at end of file From 527be6c90d5c3fbb7f0118c67fe62d39466caca4 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 14:53:51 +0300 Subject: [PATCH 06/23] CI C code #16 --- .github/workflows/c-linter.yml | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/c-linter.yml diff --git a/.github/workflows/c-linter.yml b/.github/workflows/c-linter.yml new file mode 100644 index 0000000..6eaaeb8 --- /dev/null +++ b/.github/workflows/c-linter.yml @@ -0,0 +1,41 @@ +name: C Algorithm CI + +on: + push: + branches: [ "main", "feature/spaced-rep-algorithm" ] + pull_request: + branches: [ "main" ] + +jobs: + build-and-test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies (CMake, Clang) + run: | + sudo apt-get update + sudo apt-get install -y cmake clang clang-format clang-tidy ninja-build + + - name: Check Formatting (clang-format) + working-directory: ./algorithm + # --dry-run it will tell the linter not to fix the code, but to throw an error if the format is incorrect + run: clang-format --dry-run --Werror src/*.c include/*.h tests/*.c + + - name: Static Analysis (clang-tidy) + working-directory: ./algorithm + # We check the files by passing the path to the header files directly + run: clang-tidy src/*.c tests/*.c -- -I./include + + - name: Build tests + working-directory: ./algorithm + run: | + mkdir build + cd build + cmake -G Ninja .. + ninja + + - name: Run Algorithm tests + working-directory: ./algorithm/build + run: ./test_algorithm \ No newline at end of file From 54d49764389b50eb73d65c7a9f29e107110f88a9 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 15:00:25 +0300 Subject: [PATCH 07/23] udate c-linter #16 --- .github/workflows/c-linter.yml | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/c-linter.yml b/.github/workflows/c-linter.yml index 6eaaeb8..cc0e0cf 100644 --- a/.github/workflows/c-linter.yml +++ b/.github/workflows/c-linter.yml @@ -9,33 +9,30 @@ on: jobs: build-and-test: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 - - name: Install dependencies (CMake, Clang) + - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y cmake clang clang-format clang-tidy ninja-build - name: Check Formatting (clang-format) working-directory: ./algorithm - # --dry-run it will tell the linter not to fix the code, but to throw an error if the format is incorrect - run: clang-format --dry-run --Werror src/*.c include/*.h tests/*.c + run: | + # --dry-run it will tell the linter not to fix the code, but to throw an error if the format is incorrect + find . -name "*.c" -o -name "*.h" | xargs clang-format --dry-run --Werror - name: Static Analysis (clang-tidy) working-directory: ./algorithm - # We check the files by passing the path to the header files directly - run: clang-tidy src/*.c tests/*.c -- -I./include + run: | + # We check the files by passing the path to the header files directly + clang-tidy $(find src tests -name "*.c") -- -I./include - - name: Build tests + - name: Build and Run Tests working-directory: ./algorithm run: | - mkdir build - cd build + mkdir build && cd build cmake -G Ninja .. ninja - - - name: Run Algorithm tests - working-directory: ./algorithm/build - run: ./test_algorithm \ No newline at end of file + ./test_algorithm \ No newline at end of file From e528e1c641cf2e7d1a84a0d9ff0313c79d65a708 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 15:04:44 +0300 Subject: [PATCH 08/23] update CI #16 --- .github/workflows/c-linter.yml | 8 +++++--- algorithm/.clang-tidy | 2 -- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/c-linter.yml b/.github/workflows/c-linter.yml index cc0e0cf..3b13b5e 100644 --- a/.github/workflows/c-linter.yml +++ b/.github/workflows/c-linter.yml @@ -20,14 +20,16 @@ jobs: - name: Check Formatting (clang-format) working-directory: ./algorithm run: | - # --dry-run it will tell the linter not to fix the code, but to throw an error if the format is incorrect find . -name "*.c" -o -name "*.h" | xargs clang-format --dry-run --Werror - name: Static Analysis (clang-tidy) working-directory: ./algorithm run: | - # We check the files by passing the path to the header files directly - clang-tidy $(find src tests -name "*.c") -- -I./include + FILES=$(find src tests -name "*.c") + for FILE in $FILES; do + echo "Checking $FILE..." + clang-tidy "$FILE" -- -I./include + done - name: Build and Run Tests working-directory: ./algorithm diff --git a/algorithm/.clang-tidy b/algorithm/.clang-tidy index 432c638..27bb8ba 100644 --- a/algorithm/.clang-tidy +++ b/algorithm/.clang-tidy @@ -10,8 +10,6 @@ Checks: > -readability-magic-numbers, -bugprone-easily-swappable-parameters -WarningsAsErrors: '*' - HeaderFilterRegex: '.*' CheckOptions: From 70fd9ce7635734a017826ce269c38d4a27a67df9 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 15:09:33 +0300 Subject: [PATCH 09/23] update CI #16 --- .github/workflows/c-linter.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/c-linter.yml b/.github/workflows/c-linter.yml index 3b13b5e..64321b0 100644 --- a/.github/workflows/c-linter.yml +++ b/.github/workflows/c-linter.yml @@ -25,11 +25,8 @@ jobs: - name: Static Analysis (clang-tidy) working-directory: ./algorithm run: | - FILES=$(find src tests -name "*.c") - for FILE in $FILES; do - echo "Checking $FILE..." - clang-tidy "$FILE" -- -I./include - done + clang-tidy src/algorithm.c -- -I./include + clang-tidy tests/test_algorithm.c -- -I./include - name: Build and Run Tests working-directory: ./algorithm From 610cb8edffccb9a472ef09c3afbd31077d44a344 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 15:14:13 +0300 Subject: [PATCH 10/23] update CI #16 --- .github/workflows/c-linter.yml | 37 --------------------------- ".github/workflows/\320\241-lint.yml" | 28 ++++++++++++++++++++ algorithm/.clang-tidy | 12 +-------- 3 files changed, 29 insertions(+), 48 deletions(-) delete mode 100644 .github/workflows/c-linter.yml create mode 100644 ".github/workflows/\320\241-lint.yml" diff --git a/.github/workflows/c-linter.yml b/.github/workflows/c-linter.yml deleted file mode 100644 index 64321b0..0000000 --- a/.github/workflows/c-linter.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: C Algorithm CI - -on: - push: - branches: [ "main", "feature/spaced-rep-algorithm" ] - pull_request: - branches: [ "main" ] - -jobs: - build-and-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y cmake clang clang-format clang-tidy ninja-build - - - name: Check Formatting (clang-format) - working-directory: ./algorithm - run: | - find . -name "*.c" -o -name "*.h" | xargs clang-format --dry-run --Werror - - - name: Static Analysis (clang-tidy) - working-directory: ./algorithm - run: | - clang-tidy src/algorithm.c -- -I./include - clang-tidy tests/test_algorithm.c -- -I./include - - - name: Build and Run Tests - working-directory: ./algorithm - run: | - mkdir build && cd build - cmake -G Ninja .. - ninja - ./test_algorithm \ No newline at end of file diff --git "a/.github/workflows/\320\241-lint.yml" "b/.github/workflows/\320\241-lint.yml" new file mode 100644 index 0000000..4ae79a7 --- /dev/null +++ "b/.github/workflows/\320\241-lint.yml" @@ -0,0 +1,28 @@ +name: CI Check + +on: + push: + branches: [ "main", "feature/spaced-rep-algorithm" ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install + run: sudo apt-get update && sudo apt-get install -y cmake clang clang-tidy ninja-build + + - name: Run Clang-Tidy + working-directory: ./algorithm + run: | + clang-tidy src/algorithm.c -- -I./include + clang-tidy tests/test_algorithm.c -- -I./include + + - name: Build and Run + working-directory: ./algorithm + run: | + mkdir build && cd build + cmake -G Ninja .. + ninja + ./test_algorithm \ No newline at end of file diff --git a/algorithm/.clang-tidy b/algorithm/.clang-tidy index 27bb8ba..0647855 100644 --- a/algorithm/.clang-tidy +++ b/algorithm/.clang-tidy @@ -1,14 +1,4 @@ -Checks: > - -*, - bugprone-*, - cert-*, - clang-analyzer-*, - performance-*, - portability-*, - readability-*, - -readability-identifier-length, - -readability-magic-numbers, - -bugprone-easily-swappable-parameters +Checks: '-*,bugprone-*,cert-*,clang-analyzer-*,performance-*,portability-*,readability-*, -readability-identifier-length, -readability-magic-numbers, -bugprone-easily-swappable-parameters' HeaderFilterRegex: '.*' From 7c8bd8c29a777126b9b9c1fedea140b31fbbf167 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 15:20:06 +0300 Subject: [PATCH 11/23] delete C-linter #16 --- ".github/workflows/\320\241-lint.yml" | 28 --------------------------- 1 file changed, 28 deletions(-) delete mode 100644 ".github/workflows/\320\241-lint.yml" diff --git "a/.github/workflows/\320\241-lint.yml" "b/.github/workflows/\320\241-lint.yml" deleted file mode 100644 index 4ae79a7..0000000 --- "a/.github/workflows/\320\241-lint.yml" +++ /dev/null @@ -1,28 +0,0 @@ -name: CI Check - -on: - push: - branches: [ "main", "feature/spaced-rep-algorithm" ] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install - run: sudo apt-get update && sudo apt-get install -y cmake clang clang-tidy ninja-build - - - name: Run Clang-Tidy - working-directory: ./algorithm - run: | - clang-tidy src/algorithm.c -- -I./include - clang-tidy tests/test_algorithm.c -- -I./include - - - name: Build and Run - working-directory: ./algorithm - run: | - mkdir build && cd build - cmake -G Ninja .. - ninja - ./test_algorithm \ No newline at end of file From 8106da0222ce9278037020a850164b339fd99319 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 15:23:49 +0300 Subject: [PATCH 12/23] update lint.yml #16 --- .github/workflows/lint.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e56e500..44ca3a8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -24,11 +24,16 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install clang-tools - run: sudo apt-get install -y clang-format clang-tidy + run: sudo apt-get update && sudo apt-get install -y clang-format clang-tidy cmake + - name: Check C formatting (clang-format) - run: find ./algorithm -name '*.c' -o -name '*.h' | xargs clang-format --Werror --dry-run + run: | + find ./algorithm -name "*.c" -o -name "*.h" | xargs clang-format --Werror --dry-run + - name: Run C linter (clang-tidy) - run: find ./algorithm -name '*.c' | xargs clang-tidy --warnings-as-errors="*" -- + run: | + clang-tidy ./algorithm/src/algorithm.c -- -I./algorithm/include + clang-tidy ./algorithm/tests/test_algorithm.c -- -I./algorithm/include # Python Ruff lint-python: From 063b61d8c625cde3b03b1393b28eecbc7b2b8857 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 15:38:59 +0300 Subject: [PATCH 13/23] linter go #21 --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 44ca3a8..6651814 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: '1.25' + go-version: '1.23' - name: Run golangci-lint uses: golangci/golangci-lint-action@v6 with: From c5134ea095c8e870eb5bd24ab4d281b34d679ce1 Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 15:43:06 +0300 Subject: [PATCH 14/23] =?UTF-8?q?=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=20Go=20#21?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/lint.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6651814..329f0d2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,6 +10,14 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + + - name: Check if backend exists + run: | + if [ ! -d "./backend" ] || [ -z "$(ls -A ./backend 2>/dev/null)" ]; then + echo "No go files to lint, skipping." + exit 0 + fi + - uses: actions/setup-go@v5 with: go-version: '1.23' From 032b264249c7abe02d9e01dd920dc61f33f8a1bf Mon Sep 17 00:00:00 2001 From: TToJlkoBHuK <28arhalex@gmail.com> Date: Sat, 21 Mar 2026 15:46:01 +0300 Subject: [PATCH 15/23] =?UTF-8?q?=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=BE=D1=82=D0=BA=D0=BB=D1=8E=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20Go=20#21?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/lint.yml | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 329f0d2..6650506 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,25 +6,25 @@ on: jobs: # Golang check - lint-go: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + # lint-go: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 - - name: Check if backend exists - run: | - if [ ! -d "./backend" ] || [ -z "$(ls -A ./backend 2>/dev/null)" ]; then - echo "No go files to lint, skipping." - exit 0 - fi + # - name: Check if backend exists + # run: | + # if [ ! -d "./backend" ] || [ -z "$(ls -A ./backend 2>/dev/null)" ]; then + # echo "No go files to lint, skipping." + # exit 0 + # fi - - uses: actions/setup-go@v5 - with: - go-version: '1.23' - - name: Run golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - working-directory: ./backend + # - uses: actions/setup-go@v5 + # with: + # go-version: '1.23' + # - name: Run golangci-lint + # uses: golangci/golangci-lint-action@v6 + # with: + # working-directory: ./backend # C (Google Style) lint-c: From a1113ac720c997ffe73fa7c8d70a97f58431c39c Mon Sep 17 00:00:00 2001 From: Gellert Ilya Date: Tue, 31 Mar 2026 19:15:50 +0300 Subject: [PATCH 16/23] feat(algorithm): implement SM-2 spaced repetition core logic - Add CardState and ReviewResult structures - Implement calculate_next_review function with math constraints - Map cosine similarity percentages to 0-5 quality grades --- .github/workflows/lint.yml | 56 ------------ algorithm/include/algorithm.h | 43 +++++---- algorithm/src/algorithm.c | 91 ++++++++++++------- .../{test_algorithm.c => test_algorithm.cpp} | 8 +- 4 files changed, 85 insertions(+), 113 deletions(-) delete mode 100644 .github/workflows/lint.yml rename algorithm/tests/{test_algorithm.c => test_algorithm.cpp} (91%) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 6650506..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Code Quality Check - -on: - pull_request: - branches: [ "dev", "main" ] - -jobs: - # Golang check - # lint-go: - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v4 - - # - name: Check if backend exists - # run: | - # if [ ! -d "./backend" ] || [ -z "$(ls -A ./backend 2>/dev/null)" ]; then - # echo "No go files to lint, skipping." - # exit 0 - # fi - - # - uses: actions/setup-go@v5 - # with: - # go-version: '1.23' - # - name: Run golangci-lint - # uses: golangci/golangci-lint-action@v6 - # with: - # working-directory: ./backend - - # C (Google Style) - lint-c: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install clang-tools - run: sudo apt-get update && sudo apt-get install -y clang-format clang-tidy cmake - - - name: Check C formatting (clang-format) - run: | - find ./algorithm -name "*.c" -o -name "*.h" | xargs clang-format --Werror --dry-run - - - name: Run C linter (clang-tidy) - run: | - clang-tidy ./algorithm/src/algorithm.c -- -I./algorithm/include - clang-tidy ./algorithm/tests/test_algorithm.c -- -I./algorithm/include - - # Python Ruff - lint-python: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install Ruff - run: pip install ruff - - name: Run Ruff check and format - run: | - ruff check ./parser - ruff format --check ./parser \ No newline at end of file diff --git a/algorithm/include/algorithm.h b/algorithm/include/algorithm.h index ed7c926..41028e1 100644 --- a/algorithm/include/algorithm.h +++ b/algorithm/include/algorithm.h @@ -1,32 +1,39 @@ #ifndef ALGORITHM_H #define ALGORITHM_H +#include + #ifdef __cplusplus extern "C" { #endif -// struct, current state card -struct CardState { - int interval; // current interval - float easiness; // diff level - int repetitions; // accurace repeat -}; +/** + * @brief Current state of the flashcard (data from DB) + */ +typedef struct { + int64_t interval; /**< Current interval until the next review (in days) */ + float easiness; /**< Easiness Factor (usually >= 1.3) */ + int64_t repetitions; /**< Number of consecutive correct answers */ +} CardState; -// struct for returning new data -struct ReviewResult { - int next_interval; // new interval - float new_easiness; // update diff level - int repetitions; // update quantity repeat - int quality; // grade -}; +/** + * @brief Result of the spaced repetition calculation to be saved in the DB + */ +typedef struct { + int64_t next_interval; /**< Newly calculated interval (in days) */ + float new_easiness; /**< Updated Easiness Factor */ + int64_t repetitions; /**< Updated repetitions counter */ + int32_t quality; /**< Answer quality grade (from 0 to 5) */ +} ReviewResult; /** - * main function - * @param similarity_percent match percentage - * @param current_state current param card - * @return update param card for save in DB + * @brief Calculates the next review parameters for a card based on similarity percentage. + * @param similarity_percent Cosine similarity percentage of the user's answer vs the reference (0.0 + * - 100.0). + * @param current_state Struct containing the current interval, easiness, and repetitions. + * @return ReviewResult Updated data ready to be saved in the database. */ -struct ReviewResult calculate_next_review(float similarity_percent, struct CardState current_state); +ReviewResult calculate_next_review(float similarity_percent, CardState current_state); #ifdef __cplusplus } diff --git a/algorithm/src/algorithm.c b/algorithm/src/algorithm.c index 920db56..1ea9baf 100644 --- a/algorithm/src/algorithm.c +++ b/algorithm/src/algorithm.c @@ -1,52 +1,73 @@ #include "algorithm.h" -struct ReviewResult calculate_next_review(float similarity_percent, - struct CardState current_state) { - struct ReviewResult result; - int quality = 0; - - // percent -> grade - if (similarity_percent < 40.0F) { - quality = 0; // bad - } else if (similarity_percent < 60.0F) { - quality = 2; // normal - } else if (similarity_percent < 80.0F) { - quality = 4; // good - } else { - quality = 5; // perfect - } +#include + +// --- SM-2 Algorithm Constants --- + +// Thresholds for converting cosine similarity (0.0 - 100.0) to a quality grade (0 - 5) +static const float THRESHOLD_GRADE_1 = 20.0F; +static const float THRESHOLD_GRADE_2 = 40.0F; +static const float THRESHOLD_GRADE_3 = 60.0F; +static const float THRESHOLD_GRADE_4 = 80.0F; +static const float THRESHOLD_GRADE_5 = 95.0F; + +// Base constraints and intervals (in days) +static const float MIN_EASINESS_FACTOR = 1.3F; +static const int64_t INTERVAL_FIRST_STEP = 1; +static const int64_t INTERVAL_SECOND_STEP = 6; + +/** + * @brief Helper function: converts similarity percentage into a discrete grade from 0 to 5. + * Hidden from other translation units via the static modifier. + */ +static int32_t determine_quality_grade(const float similarity_percent) { + if (similarity_percent < THRESHOLD_GRADE_1) + return 0; // Complete blackout / completely incorrect + if (similarity_percent < THRESHOLD_GRADE_2) + return 1; // Incorrect, but remembered the correct answer + if (similarity_percent < THRESHOLD_GRADE_3) + return 2; // Incorrect, but the answer seemed familiar + if (similarity_percent < THRESHOLD_GRADE_4) + return 3; // Correct, but with significant difficulty + if (similarity_percent < THRESHOLD_GRADE_5) return 4; // Correct, after a slight hesitation + return 5; // Perfect and quick response +} + +ReviewResult calculate_next_review(const float similarity_percent, const CardState current_state) { + ReviewResult result; + + // Determine response quality + result.quality = determine_quality_grade(similarity_percent); - result.quality = quality; + // Calculate new Easiness Factor (EF) + // Original SM-2 formula: EF' = EF + (0.1 - (5 - q) * (0.08 + (5 - q) * 0.02)) + const float q_diff = 5.0F - (float)result.quality; + const float ef_modifier = 0.1F - (q_diff * (0.08F + (q_diff * 0.02F))); - // new Easiness Factor (EF) on formula SM-2 - // EF = EF + (0.1 - (5 - q) * (0.08 + (5 - q) * 0.02)) - float q_diff = 5.0F - (float)quality; - float new_ef = current_state.easiness + (0.1F - (q_diff * (0.08F + (q_diff * 0.02F)))); + result.new_easiness = current_state.easiness + ef_modifier; - // EF != <1.3 - if (new_ef < 1.3F) { - new_ef = 1.3F; + // EF must not drop below the minimum threshold + if (result.new_easiness < MIN_EASINESS_FACTOR) { + result.new_easiness = MIN_EASINESS_FACTOR; } - result.new_easiness = new_ef; - // update counter - if (quality < 3) { - // bad answer -> progress 0 + // Calculate repetitions counter and next interval + if (result.quality < 3) { + // Grades 0, 1, or 2 indicate forgetting. Reset progress. result.repetitions = 0; - result.next_interval = 1; + result.next_interval = INTERVAL_FIRST_STEP; } else { - // good answer -> +1 counter + // Successful review (grades 3, 4, 5) result.repetitions = current_state.repetitions + 1; - // calculation new interval if (result.repetitions == 1) { - result.next_interval = 1; + result.next_interval = INTERVAL_FIRST_STEP; } else if (result.repetitions == 2) { - result.next_interval = 6; + result.next_interval = INTERVAL_SECOND_STEP; } else { - // + 0.5F for correct rounding - result.next_interval = - (int)((((float)current_state.interval) * result.new_easiness) + 0.5F); + // Mathematically correct rounding instead of the (int)(... + 0.5F) hack + const float next_interval_calc = (float)current_state.interval * result.new_easiness; + result.next_interval = (int64_t)roundf(next_interval_calc); } } diff --git a/algorithm/tests/test_algorithm.c b/algorithm/tests/test_algorithm.cpp similarity index 91% rename from algorithm/tests/test_algorithm.c rename to algorithm/tests/test_algorithm.cpp index 71a5065..76ad985 100644 --- a/algorithm/tests/test_algorithm.c +++ b/algorithm/tests/test_algorithm.cpp @@ -4,8 +4,8 @@ #include "algorithm.h" // auxiliary function -struct CardState apply_result_to_card(struct ReviewResult res) { - struct CardState new_card; +CardState apply_result_to_card(ReviewResult res) { + CardState new_card; new_card.interval = res.next_interval; new_card.easiness = res.new_easiness; new_card.repetitions = res.repetitions; @@ -16,8 +16,8 @@ int main() { printf("Starting algorithm tests...\n"); // new card - struct CardState card = {0, 2.5F, 0}; - struct ReviewResult result; + CardState card = {0, 2.5F, 0}; + ReviewResult result; // test 1: bad answer printf("Test 1: Bad answer (< 40%%)\n"); From 3bd6cda73afdfc2baf675578c754f5c4bc392621 Mon Sep 17 00:00:00 2001 From: Gellert Ilya Date: Tue, 31 Mar 2026 19:16:35 +0300 Subject: [PATCH 17/23] test(algorithm): setup Google Test framework and add test suite - Configure CMake with FetchContent for GTest - Add unit tests for boundary conditions and score calculation --- algorithm/CMakeLists.txt | 36 +++++++++--- algorithm/tests/test_algorithm.cpp | 93 ++++++++++++++---------------- 2 files changed, 71 insertions(+), 58 deletions(-) diff --git a/algorithm/CMakeLists.txt b/algorithm/CMakeLists.txt index 715aebf..06b5225 100644 --- a/algorithm/CMakeLists.txt +++ b/algorithm/CMakeLists.txt @@ -1,25 +1,43 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.14) -project(SpacedRepetition C) +project(SpacedRepetition C CXX) set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 14) set(CMAKE_C_STANDARD_REQUIRED True) +set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") +if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -Werror") endif() include_directories(include) -add_library(spaced_rep STATIC - src/algorithm.c +add_library(spaced_rep STATIC src/algorithm.c) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip + DOWNLOAD_EXTRACT_TIMESTAMP true ) -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_algorithm.c") - add_executable(test_algorithm - tests/test_algorithm.c +set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_algorithm.cpp") + add_executable(test_algorithm tests/test_algorithm.cpp) + + target_link_libraries(test_algorithm + PRIVATE + spaced_rep + GTest::gtest_main + m ) - target_link_libraries(test_algorithm spaced_rep) + + include(GoogleTest) + include(CTest) + gtest_discover_tests(test_algorithm) endif() \ No newline at end of file diff --git a/algorithm/tests/test_algorithm.cpp b/algorithm/tests/test_algorithm.cpp index 76ad985..5e74487 100644 --- a/algorithm/tests/test_algorithm.cpp +++ b/algorithm/tests/test_algorithm.cpp @@ -1,10 +1,9 @@ -#include -#include +#include #include "algorithm.h" -// auxiliary function -CardState apply_result_to_card(ReviewResult res) { +// Auxiliary function to apply ReviewResult to CardState +CardState ApplyResultToCard(const ReviewResult& res) { CardState new_card; new_card.interval = res.next_interval; new_card.easiness = res.new_easiness; @@ -12,59 +11,55 @@ CardState apply_result_to_card(ReviewResult res) { return new_card; } -int main() { - printf("Starting algorithm tests...\n"); +// Test fixture (base class for tests) to avoid code duplication +class AlgorithmTest : public ::testing::Test { + protected: + CardState default_card = {0, 2.5F, 0}; +}; - // new card - CardState card = {0, 2.5F, 0}; - ReviewResult result; +TEST_F(AlgorithmTest, BadAnswer) { + const ReviewResult result = calculate_next_review(15.0F, default_card); - // test 1: bad answer - printf("Test 1: Bad answer (< 40%%)\n"); - result = calculate_next_review(20.0F, card); - - assert(result.quality == 0); - assert(result.next_interval == 1); - assert(result.repetitions == 0); - assert(result.new_easiness < 2.5F); - card = apply_result_to_card(result); - - // test 2 perfect answer - printf("Test 2: Perfect answer (1st time)\n"); - result = calculate_next_review(95.0F, card); + EXPECT_EQ(result.quality, 0); + EXPECT_EQ(result.next_interval, 1); + EXPECT_EQ(result.repetitions, 0); + EXPECT_LT(result.new_easiness, 2.5F); +} - assert(result.quality == 5); - assert(result.repetitions == 1); - assert(result.next_interval == 1); - assert(result.new_easiness > card.easiness); - card = apply_result_to_card(result); +TEST_F(AlgorithmTest, PerfectAnswerFirstTime) { + const ReviewResult result = calculate_next_review(95.0F, default_card); - // test 3 perfect answer (2) - printf("Test 3: Perfect answer (2nd time)\n"); - result = calculate_next_review(85.0F, card); + EXPECT_EQ(result.quality, 5); + EXPECT_EQ(result.repetitions, 1); + EXPECT_EQ(result.next_interval, 1); + EXPECT_GT(result.new_easiness, default_card.easiness); +} - assert(result.quality == 5); - assert(result.repetitions == 2); - assert(result.next_interval == 6); - card = apply_result_to_card(result); +TEST_F(AlgorithmTest, PerfectAnswerSecondTime) { + const CardState card = ApplyResultToCard(calculate_next_review(95.0F, default_card)); + const ReviewResult result = calculate_next_review(95.0F, card); - // test 4 perfect answer (3) - printf("Test 4: Perfect answer (3rd time)\n"); - result = calculate_next_review(100.0F, card); + EXPECT_EQ(result.quality, 5); + EXPECT_EQ(result.repetitions, 2); + EXPECT_EQ(result.next_interval, 6); +} - assert(result.quality == 5); - assert(result.repetitions == 3); - assert(result.next_interval > 6); - card = apply_result_to_card(result); +TEST_F(AlgorithmTest, PerfectAnswerThirdTime) { + const CardState card1 = ApplyResultToCard(calculate_next_review(95.0F, default_card)); + const CardState card2 = ApplyResultToCard(calculate_next_review(85.0F, card1)); + const ReviewResult result = calculate_next_review(100.0F, card2); - // test 5 bad answer - printf("Test 5: Bad answer after streak\n"); - result = calculate_next_review(10.0F, card); + EXPECT_EQ(result.quality, 5); + EXPECT_EQ(result.repetitions, 3); + EXPECT_GT(result.next_interval, 6); +} - assert(result.quality == 0); - assert(result.repetitions == 0); - assert(result.next_interval == 1); +TEST_F(AlgorithmTest, BadAnswerAfterStreak) { + const CardState card1 = ApplyResultToCard(calculate_next_review(95.0F, default_card)); + const CardState card2 = ApplyResultToCard(calculate_next_review(85.0F, card1)); + const ReviewResult result = calculate_next_review(10.0F, card2); - printf("SUCCESS! All assertions passed. Algorithm works perfectly!\n"); - return 0; + EXPECT_EQ(result.quality, 0); + EXPECT_EQ(result.repetitions, 0); + EXPECT_EQ(result.next_interval, 1); } \ No newline at end of file From b05da829e65566f0c4e150e9d657e337d96610e5 Mon Sep 17 00:00:00 2001 From: Gellert Ilya Date: Tue, 31 Mar 2026 19:17:38 +0300 Subject: [PATCH 18/23] style(algorithm): apply strict clang-format and clang-tidy rules - Enforce Google C++ style formatting - Enable strict static analysis (cert, bugprone, readability) - Disable MISRA checks for test directory to allow GTest macros --- algorithm/.clang-tidy | 17 ++++++++++++++--- algorithm/tests/.clang-tidy | 9 +++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 algorithm/tests/.clang-tidy diff --git a/algorithm/.clang-tidy b/algorithm/.clang-tidy index 0647855..63aab96 100644 --- a/algorithm/.clang-tidy +++ b/algorithm/.clang-tidy @@ -1,7 +1,18 @@ -Checks: '-*,bugprone-*,cert-*,clang-analyzer-*,performance-*,portability-*,readability-*, -readability-identifier-length, -readability-magic-numbers, -bugprone-easily-swappable-parameters' +--- +Checks: > + -*, + bugprone-*, + cert-*, + clang-analyzer-*, + misc-*, + performance-*, + portability-*, + readability-*, + -readability-identifier-length, + -bugprone-easily-swappable-parameters HeaderFilterRegex: '.*' CheckOptions: - - key: readability-braces-around-statements.ShortStatementLines - value: '1' \ No newline at end of file + readability-braces-around-statements.ShortStatementLines: 1 +... \ No newline at end of file diff --git a/algorithm/tests/.clang-tidy b/algorithm/tests/.clang-tidy new file mode 100644 index 0000000..923ef37 --- /dev/null +++ b/algorithm/tests/.clang-tidy @@ -0,0 +1,9 @@ +--- +InheritParentConfig: true + +Checks: > + -misra-*, + -cert-err58-cpp, + -cppcoreguidelines-owning-memory, + -cppcoreguidelines-pro-type-vararg +...ы \ No newline at end of file From 5705bea79bcbd11f2d1735e2690c31960665b8aa Mon Sep 17 00:00:00 2001 From: Gellert Ilya Date: Tue, 31 Mar 2026 19:18:53 +0300 Subject: [PATCH 19/23] ci: configure GitHub Actions for C/C++ linting - Automate clang-format and clang-tidy checks on PRs - Generate compile_commands.json via CMake for accurate linting --- .github/workflows/lint-c.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/lint-c.yml diff --git a/.github/workflows/lint-c.yml b/.github/workflows/lint-c.yml new file mode 100644 index 0000000..24e837e --- /dev/null +++ b/.github/workflows/lint-c.yml @@ -0,0 +1,27 @@ +name: C/C++ Lint + +on: + pull_request: + branches: [ "dev", "main" ] + paths: + - 'algorithm/**' + +jobs: + lint-c: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install clang-tools and cmake + run: sudo apt-get update && sudo apt-get install -y clang-format clang-tidy cmake + + - name: Generate compile_commands.json + run: cmake -B ./algorithm/build -S ./algorithm + + - name: Check C/C++ formatting (clang-format) + run: | + find ./algorithm -type f \( -name "*.c" -o -name "*.cpp" -o -name "*.h" \) | xargs clang-format --Werror --dry-run + + - name: Run C/C++ linter (clang-tidy) + run: | + find ./algorithm/src ./algorithm/tests -type f \( -name "*.c" -o -name "*.cpp" \) | xargs clang-tidy -p ./algorithm/build \ No newline at end of file From 97e274b3be36ab151d580910e2eb28bb164234e0 Mon Sep 17 00:00:00 2001 From: Gellert Ilya Date: Tue, 31 Mar 2026 19:20:09 +0300 Subject: [PATCH 20/23] ci: configure Go and Python linting pipelines --- .github/workflows/lint-go.yml | 22 ++++++++++++++++++++++ .github/workflows/lint-python.yml | 21 +++++++++++++++++++++ backend/go.mod | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/lint-go.yml create mode 100644 .github/workflows/lint-python.yml diff --git a/.github/workflows/lint-go.yml b/.github/workflows/lint-go.yml new file mode 100644 index 0000000..2008d26 --- /dev/null +++ b/.github/workflows/lint-go.yml @@ -0,0 +1,22 @@ +name: Go Lint + +on: + pull_request: + branches: [ "dev", "main" ] + paths: + - 'backend/**' + +jobs: + lint-go: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: '1.26' + + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + working-directory: ./backend \ No newline at end of file diff --git a/.github/workflows/lint-python.yml b/.github/workflows/lint-python.yml new file mode 100644 index 0000000..aa32438 --- /dev/null +++ b/.github/workflows/lint-python.yml @@ -0,0 +1,21 @@ +name: Python Lint + +on: + pull_request: + branches: [ "dev", "main" ] + paths: + - 'parser/**' + +jobs: + lint-python: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Ruff + run: pip install ruff + + - name: Run Ruff check and format + run: | + ruff check ./parser + ruff format --check ./parser \ No newline at end of file diff --git a/backend/go.mod b/backend/go.mod index e20ddd8..f323727 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,3 +1,3 @@ module github.com/ilindan-dev/RAGDM/backend -go 1.25.7 +go 1.26 From ee683efce6c5665900f8f41fd21c920449724ccb Mon Sep 17 00:00:00 2001 From: Gellert Ilya Date: Tue, 31 Mar 2026 19:33:44 +0300 Subject: [PATCH 21/23] ci: fix go version for linter and exclude build dir from clang-format --- .github/workflows/lint-c.yml | 2 +- .github/workflows/lint-go.yml | 5 +++-- backend/go.mod | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint-c.yml b/.github/workflows/lint-c.yml index 24e837e..b07820e 100644 --- a/.github/workflows/lint-c.yml +++ b/.github/workflows/lint-c.yml @@ -20,7 +20,7 @@ jobs: - name: Check C/C++ formatting (clang-format) run: | - find ./algorithm -type f \( -name "*.c" -o -name "*.cpp" -o -name "*.h" \) | xargs clang-format --Werror --dry-run + find ./algorithm/src ./algorithm/include ./algorithm/tests -type f \( -name "*.c" -o -name "*.cpp" -o -name "*.h" \) | xargs clang-format --Werror --dry-run - name: Run C/C++ linter (clang-tidy) run: | diff --git a/.github/workflows/lint-go.yml b/.github/workflows/lint-go.yml index 2008d26..dad10c1 100644 --- a/.github/workflows/lint-go.yml +++ b/.github/workflows/lint-go.yml @@ -12,9 +12,10 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - uses: actions/setup-go@v6 with: - go-version: '1.26' + go-version: '1.25' + check-latest: true - name: Run golangci-lint uses: golangci/golangci-lint-action@v6 diff --git a/backend/go.mod b/backend/go.mod index f323727..86baf4d 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,3 +1,3 @@ module github.com/ilindan-dev/RAGDM/backend -go 1.26 +go 1.25 From 378c4a325fb292b3ae4cf7cd8523bd27d1130310 Mon Sep 17 00:00:00 2001 From: Gellert Ilya Date: Tue, 31 Mar 2026 19:36:12 +0300 Subject: [PATCH 22/23] ci: fix go version for linter to 1.24 --- .github/workflows/lint-go.yml | 2 +- backend/go.mod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-go.yml b/.github/workflows/lint-go.yml index dad10c1..f73415d 100644 --- a/.github/workflows/lint-go.yml +++ b/.github/workflows/lint-go.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/setup-go@v6 with: - go-version: '1.25' + go-version: '1.24' check-latest: true - name: Run golangci-lint diff --git a/backend/go.mod b/backend/go.mod index 86baf4d..50cf777 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,3 +1,3 @@ module github.com/ilindan-dev/RAGDM/backend -go 1.25 +go 1.24 From 021d6c3ab1ba5555d738c476a78fbb2e1c858ea2 Mon Sep 17 00:00:00 2001 From: Gellert Ilya Date: Tue, 31 Mar 2026 19:39:34 +0300 Subject: [PATCH 23/23] ci: add test integration for C code --- .github/workflows/lint-c.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint-c.yml b/.github/workflows/lint-c.yml index b07820e..0141b62 100644 --- a/.github/workflows/lint-c.yml +++ b/.github/workflows/lint-c.yml @@ -1,4 +1,4 @@ -name: C/C++ Lint +name: C/C++ CI on: pull_request: @@ -7,7 +7,7 @@ on: - 'algorithm/**' jobs: - lint-c: + lint-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -15,7 +15,7 @@ jobs: - name: Install clang-tools and cmake run: sudo apt-get update && sudo apt-get install -y clang-format clang-tidy cmake - - name: Generate compile_commands.json + - name: Configure CMake and generate compile_commands.json run: cmake -B ./algorithm/build -S ./algorithm - name: Check C/C++ formatting (clang-format) @@ -24,4 +24,11 @@ jobs: - name: Run C/C++ linter (clang-tidy) run: | - find ./algorithm/src ./algorithm/tests -type f \( -name "*.c" -o -name "*.cpp" \) | xargs clang-tidy -p ./algorithm/build \ No newline at end of file + find ./algorithm/src ./algorithm/tests -type f \( -name "*.c" -o -name "*.cpp" \) | xargs clang-tidy -p ./algorithm/build + + - name: Build C/C++ project + run: cmake --build ./algorithm/build + + - name: Run tests (CTest) + working-directory: ./algorithm/build + run: ctest --output-on-failure \ No newline at end of file