Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/frontend-linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ jobs:

- name: Run linting
working-directory: frontend
run: npm run lint
run: npm run lint

- name: Check for forbidden Unicode characters
run: bash backend/ci/forbidden_chars_check.sh frontend/ --ext .ts .tsx .js .jsx .json .html .css

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Forgot to commit the script?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure what the script is doing, but would this be captured by using RUFF preview rules like RUF001-3 (maybe in preview)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, the script was in my .gitignore....
I will check tomorrow if we can use RUF001 for /docs and /frontend (.rst, .js etc...).
For now, short answer i get from the google is "no"

5 changes: 4 additions & 1 deletion .github/workflows/linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ jobs:
run: ruff format --check backend/

- name: Check linting with ruff
run: ruff check backend/
run: ruff check backend/

- name: Check for forbidden Unicode characters
run: bash backend/ci/forbidden_chars_check.sh backend/ docs/ --ext .py .rst
152 changes: 152 additions & 0 deletions backend/ci/forbidden_chars_check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/usr/bin/env bash
set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

CHARS=(
$'\u2013' $'\u2014' $'\u2212' $'\u2018' $'\u2019'
$'\u201C' $'\u201D' $'\u2026' $'\u00A0' $'\u200B'
$'\u200C' $'\u200D' $'\u2060' $'\uFEFF' $'\u00AD'
$'\u2022' $'\u00D7' $'\u00F7' $'\u2190' $'\u2192'
$'\u21D2' $'\u2260' $'\u2264' $'\u2265'
)

DESCS=(
"EN DASH (–)"
"EM DASH (—)"
"UNICODE MINUS (−)"
"LEFT SINGLE QUOTATION MARK (‘)"
"RIGHT SINGLE QUOTATION MARK (’)"
"LEFT DOUBLE QUOTATION MARK (“)"
"RIGHT DOUBLE QUOTATION MARK (”)"
"HORIZONTAL ELLIPSIS (…)"
"NON-BREAKING SPACE (NBSP)"
"ZERO WIDTH SPACE"
"ZERO WIDTH NON-JOINER"
"ZERO WIDTH JOINER"
"WORD JOINER"
"ZERO WIDTH NO-BREAK SPACE (BOM)"
"SOFT HYPHEN"
"BULLET (•)"
"MULTIPLICATION SIGN (×)"
"DIVISION SIGN (÷)"
"LEFT ARROW (←)"
"RIGHT ARROW (→)"
"RIGHTWARDS DOUBLE ARROW (⇒)"
"NOT EQUAL TO (≠)"
"LESS-THAN OR EQUAL TO (≤)"
"GREATER-THAN OR EQUAL TO (≥)"
)

EXCLUDED_DIRS=(
__pycache__ .pytest_cache .mypy_cache .ruff_cache
.tox .venv venv ibex_venv imaspy_venv imas_core_develop_venv
build dist node_modules .git .webpack out ci generated _build
)

DIRS=()
EXTS=()
AFTER_EXT=false

for arg in "$@"; do
if [ "$arg" = "--help" ] || [ "$arg" = "-h" ]; then
echo "Usage: $(basename "$0") [directories...] [--ext extensions...]"
echo ""
echo "Scan source files for forbidden Unicode characters."
echo ""
echo "Arguments:"
echo " directories One or more directories to scan (default: ../ and ../../frontend)"
echo " --ext File extensions to check (default: all files)"
echo ""
echo "Examples:"
echo " $(basename "$0") Scan backend/ and frontend/"
echo " $(basename "$0") backend/ --ext .py Scan only .py files in backend/"
echo " $(basename "$0") frontend/ --ext .ts .tsx .js Scan only TS/JS files in frontend/"
echo " $(basename "$0") src/ docs/ --ext .py .md Scan custom dirs with custom extensions"
exit 0
elif [ "$arg" = "--ext" ]; then
AFTER_EXT=true
elif [ "$AFTER_EXT" = true ]; then
EXTS+=("$arg")
else
DIRS+=("$arg")
fi
done

# checks for forbidden chars in ../. (backend), ../../docs, and ../../frontend by default
# if no --ext given, all files are checked
if [ ${#DIRS[@]} -eq 0 ]; then
DIRS=("$SCRIPT_DIR/../" "$SCRIPT_DIR/../../docs" "$SCRIPT_DIR/../../frontend")
fi

find_args=()

for dir in "${DIRS[@]}"; do
if [ ! -d "$dir" ]; then
echo "Directory not found: $dir" >&2
exit 1
fi

find_args+=("$(cd "$dir" && pwd)")
done

find_args=("${find_args[@]}" -type f)

if [ ${#EXTS[@]} -gt 0 ]; then
find_args+=("(")
find_args+=(-name "*${EXTS[0]}")
for ((i=1; i<${#EXTS[@]}; i++)); do
find_args+=(-o -name "*${EXTS[i]}")
done
find_args+=(")")
fi

for d in "${EXCLUDED_DIRS[@]}"; do
find_args+=(! -path "*/$d/*")
done

# Collect all matching files
all_files=()
while IFS= read -r -d '' file; do
all_files+=("$file")
done < <(find "${find_args[@]}" -print0 2>/dev/null)

file_count=${#all_files[@]}

if [ "$file_count" -eq 0 ]; then
echo "No files to check."
exit 0
fi

echo "Checking $file_count files..."

errors=0

for ((i=0; i<${#CHARS[@]}; i++)); do
char="${CHARS[i]}"
desc="${DESCS[i]}"

matches=$(printf '%s\0' "${all_files[@]}" | xargs -0 grep -In "$char" 2>/dev/null) || true
if [ -n "$matches" ]; then
while IFS= read -r grep_line; do
file="${grep_line%%:*}"
rest="${grep_line#*:}"
lineno="${rest%%:*}"
content="${rest#*:}"

prefix="${content%%$char*}"
col=$(( ${#prefix} + 1 ))

echo "$file:$lineno:$col: $desc"
done <<< "$matches"
((errors++)) || true
fi
done

if [ "$errors" -gt 0 ]; then
echo ""
echo "❌ Forbidden Unicode characters found in $errors file(s)."
exit 1
fi

echo "✅ No forbidden Unicode characters found."
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@


# -- Project information -----------------------------------------------------
# The documented projects name
# The documented project's name
project = src_project = PROJECT = "ibex"
PACKAGE = "ibex"
src_group = GROUP = "IMEX"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Backend structure

The IBEX backend is structured into three distinct layers, each represented by a corresponding directory within the ibex Python package:

* endpoints Defines all HTTP API endpoints. This layer is strictly limited to request handling and routing, and does not contain any business logic.
* core Serves as an abstraction layer between the endpoints and data_sources layers. Its primary role is to decouple application logic from specific data source implementations, enabling interchangeability. May include minimal logic when necessary.
* data_sources Implements the core application logic. This layer is responsible for all communication with data sources (IMAS-Python) and constructs the JSON responses returned to frontend.
* endpoints - Defines all HTTP API endpoints. This layer is strictly limited to request handling and routing, and does not contain any business logic.
* core - Serves as an abstraction layer between the endpoints and data_sources layers. Its primary role is to decouple application logic from specific data source implementations, enabling interchangeability. May include minimal logic when necessary.
* data_sources - Implements the core application logic. This layer is responsible for all communication with data sources (IMAS-Python) and constructs the JSON responses returned to frontend.

Endpoints discovering and testing
-----------------------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Ibex Manual
=============

IBEX is a web-based application designed for efficient traversal and visualization of data stored in the Integrated Data Structure (IDS).
The application follows a clientserver architecture, consisting of a frontend for interactive data exploration and a backend responsible for
The application follows a client-server architecture, consisting of a frontend for interactive data exploration and a backend responsible for
data processing and communication with data sources. The backend leverages the `IMAS Python <https://github.com/iterorganization/IMAS-Python>`_ to access, parse, and manipulate IDS data,
enabling seamless integration with existing IMAS-compatible databases.
IBEX features a modular and extensible architecture, with the IMAS Python API encapsulated as a replaceable component, allowing it to be substituted with an alternative data access layer if needed.
Expand Down
Loading