2024-05-09 10:35:54 +08:00
.PHONY : clean deepclean install init -qlib -env dev constraints black isort mypy ruff toml -sort lint pre -commit test -run test build upload docs -autobuild changelog docs -gen docs -mypy docs -coverage docs
#You can modify it according to your terminal
SHELL := /bin/bash
########################################################################################
# Variables
########################################################################################
# Determine whether to invoke pipenv based on CI environment variable and the availability of pipenv.
PIPRUN := $( shell [ " $$ CI" != "true" ] && command -v pipenv > /dev/null 2>& 1 && echo "pipenv run" )
# Get the Python version in `major.minor` format, using the environment variable or the virtual environment if exists.
PYTHON_VERSION := $( shell echo $$ { PYTHON_VERSION:-$$ ( python -V 2>& 1 | cut -d ' ' -f 2) } | cut -d '.' -f 1,2)
# Determine the constraints file based on the Python version.
CONSTRAINTS_FILE := constraints/$( PYTHON_VERSION) .txt
# Documentation target directory, will be adapted to specific folder for readthedocs.
PUBLIC_DIR := $( shell [ " $$ READTHEDOCS" = "True" ] && echo " $$ READTHEDOCS_OUTPUT/html" || echo "public" )
# URL and Path of changelog source code.
2024-06-18 11:50:03 +08:00
CHANGELOG_URL := $( shell echo $$ { CI_PAGES_URL:-https://microsoft.github.io/rdagent} /_sources/changelog.md.txt)
2024-05-09 10:35:54 +08:00
CHANGELOG_PATH := docs/changelog.md
########################################################################################
# Development Environment Management
########################################################################################
# Remove common intermediate files.
clean :
-rm -rf \
$( PUBLIC_DIR) \
.coverage \
.mypy_cache \
.pytest_cache \
.ruff_cache \
Pipfile* \
coverage.xml \
dist \
release-notes.md
find . -name '*.egg-info' -print0 | xargs -0 rm -rf
find . -name '*.pyc' -print0 | xargs -0 rm -f
find . -name '*.swp' -print0 | xargs -0 rm -f
find . -name '.DS_Store' -print0 | xargs -0 rm -f
find . -name '__pycache__' -print0 | xargs -0 rm -rf
# Remove pre-commit hook, virtual environment alongside itermediate files.
deepclean : clean
if command -v pre-commit > /dev/null 2>& 1; then pre-commit uninstall --hook-type pre-push; fi
if command -v pipenv >/dev/null 2>& 1 && pipenv --venv >/dev/null 2>& 1; then pipenv --rm; fi
# Install the package in editable mode.
install :
$( PIPRUN) pip install -e . -c $( CONSTRAINTS_FILE)
# Install the package in editable mode with specific optional dependencies.
dev-% :
$( PIPRUN) pip install -e .[ $* ] -c $( CONSTRAINTS_FILE)
# Prepare the development environment.
# Build submodules.
# Install the pacakge in editable mode with all optional dependencies and pre-commit hook.
init-qlib-env :
# note: You may need to install torch manually
# todo: downgrade ruamel.yaml in pyqlib
2024-06-18 11:50:03 +08:00
conda create -n qlibRDAgent python = 3.8 -y
@source $$ ( conda info --base) /etc/profile.d/conda.sh && conda activate qlibRDAgent && which pip && pip install pyqlib && pip install ruamel-yaml== 0.17.21 && pip install torch == 2.1.1 && pip install catboost == 0.24.3 && conda deactivate
2024-05-09 10:35:54 +08:00
dev :
2025-11-20 10:51:20 +08:00
$( PIPRUN) pip install -U pip setuptools wheel
2024-05-09 10:35:54 +08:00
$( PIPRUN) pip install -e .[ docs,lint,package,test] -c $( CONSTRAINTS_FILE)
2025-03-16 00:50:17 +08:00
$( PIPRUN) pip install -U kaggle
2024-05-09 10:35:54 +08:00
if [ " $( CI) " != "true" ] && command -v pre-commit > /dev/null 2>& 1; then pre-commit install --hook-type pre-push; fi
# Generate constraints for current Python version.
constraints : deepclean
$( PIPRUN) --python $( PYTHON_VERSION) pip install --upgrade -e .[ docs,lint,package,test]
$( PIPRUN) pip freeze --exclude-editable > $( CONSTRAINTS_FILE)
########################################################################################
# Lint and pre-commit
########################################################################################
# Check lint with black.
black :
2026-03-18 14:04:52 +08:00
$( PIPRUN) python -m black --check --diff . --extend-exclude "(test/scripts|test/notebook/testfiles|git_ignore_folder|web)" -l 120
2024-07-15 20:17:12 +08:00
2024-05-09 10:35:54 +08:00
# Check lint with isort.
isort :
2026-03-18 14:04:52 +08:00
$( PIPRUN) python -m isort --check . -s git_ignore_folder -s test/scripts -s test/notebook/testfiles -s web
2024-05-09 10:35:54 +08:00
# Check lint with mypy.
2024-07-25 15:20:04 +08:00
# First deal with the core folder, and then gradually increase the scope of detection,
# and eventually realize the detection of the complete project.
2024-05-09 10:35:54 +08:00
mypy :
2025-06-06 18:52:19 +08:00
$( PIPRUN) python -m mypy rdagent/core
2024-05-09 10:35:54 +08:00
# Check lint with ruff.
2024-07-25 15:20:04 +08:00
# First deal with the core folder, and then gradually increase the scope of detection,
# and eventually realize the detection of the complete project.
2024-05-09 10:35:54 +08:00
ruff :
2026-03-02 19:04:10 +08:00
$( PIPRUN) ruff check rdagent/core --ignore FBT001,FBT002,I001,E501 # --exclude rdagent/scripts,git_ignore_folder
2024-05-09 10:35:54 +08:00
# Check lint with toml-sort.
toml-sort :
$( PIPRUN) toml-sort --check pyproject.toml
# Check lint with all linters.
2024-07-26 12:12:16 +08:00
# Prioritize fixing isort, then black, otherwise you'll get weird and unfixable black errors.
# lint: mypy ruff
lint : mypy ruff isort black toml -sort
2024-05-09 10:35:54 +08:00
# Run pre-commit with autofix against all files.
pre-commit :
pre-commit run --all-files
2024-07-26 12:12:16 +08:00
########################################################################################
# Auto Lint
########################################################################################
# Auto lint with black.
auto-black :
2026-03-18 14:04:52 +08:00
$( PIPRUN) python -m black . --extend-exclude "(test/scripts|test/notebook/testfiles|git_ignore_folder|.venv|web)" -l 120
2024-07-26 12:12:16 +08:00
# Auto lint with isort.
auto-isort :
2026-03-18 14:04:52 +08:00
$( PIPRUN) python -m isort . -s git_ignore_folder -s test/scripts -s test/notebook/testfiles -s .venv -s web
2024-07-26 12:12:16 +08:00
# Auto lint with toml-sort.
auto-toml-sort :
$( PIPRUN) toml-sort pyproject.toml
# Auto lint with all linters.
auto-lint : auto -isort auto -black auto -toml -sort
2024-05-09 10:35:54 +08:00
########################################################################################
# Test
########################################################################################
# Clean and run test with coverage.
test-run :
$( PIPRUN) python -m coverage erase
2024-06-18 11:50:03 +08:00
$( PIPRUN) python -m coverage run --concurrency= multiprocessing -m pytest --ignore test/scripts
2024-05-09 10:35:54 +08:00
$( PIPRUN) python -m coverage combine
2024-09-06 17:18:52 +08:00
test-run-offline :
# some test that does not require api calling
$( PIPRUN) python -m coverage erase
$( PIPRUN) python -m coverage run --concurrency= multiprocessing -m pytest -m "offline" --ignore test/scripts
$( PIPRUN) python -m coverage combine
2024-05-09 10:35:54 +08:00
# Generate coverage report for terminal and xml.
2024-09-06 17:18:52 +08:00
# TODO: we may have higher coverage rate if we have more test
2024-05-09 10:35:54 +08:00
test : test -run
2024-09-06 17:18:52 +08:00
$( PIPRUN) python -m coverage report --fail-under 20 # 80
$( PIPRUN) python -m coverage xml --fail-under 20 # 80
test-offline : test -run -offline
$( PIPRUN) python -m coverage report --fail-under 20 # 80
$( PIPRUN) python -m coverage xml --fail-under 20 # 80
2024-05-09 10:35:54 +08:00
########################################################################################
# Package
########################################################################################
# Build the package.
build :
$( PIPRUN) python -m build
# Upload the package.
upload :
$( PIPRUN) python -m twine upload dist/*
########################################################################################
# Documentation
########################################################################################
# Generate documentation with auto build when changes happen.
docs-autobuild :
$( PIPRUN) python -m sphinx_autobuild docs $( PUBLIC_DIR) \
--watch README.md \
--watch rdagent
# Generate changelog from git commits.
2024-08-02 12:57:34 +08:00
# The -c and -s arguments should match
# If -c uses Basic (default, inherits from base class), -s optional argument: # If -c uses conventional (inherits from base class), -s optional parameter: add,fix,change,remove,merge,doc
# If -c uses conventional (inherits from base class), -s is optional: build,chore,ci,deps,doc,docs,feat,fix,perf,ref,refactor,revert,style,test,tests
# If -c uses angular (inherits from conventional), -s optional argument: build,chore,ci,deps,doc,docs,feat,fix,perf,ref,refactor,revert,style,test,tests
2024-05-09 10:35:54 +08:00
# NOTE(xuan.hu): Need to be run before document generation to take effect.
2024-08-02 12:57:34 +08:00
# $(PIPRUN) git-changelog -ETrio $(CHANGELOG_PATH) -c conventional -s build,chore,ci,docs,feat,fix,perf,refactor,revert,style,test
2024-05-09 10:35:54 +08:00
changelog :
@if wget -q --spider $( CHANGELOG_URL) ; then \
echo "Existing Changelog found at ' $( CHANGELOG_URL) ', download for incremental generation." ; \
wget -q -O $( CHANGELOG_PATH) $( CHANGELOG_URL) ; \
fi
2024-08-02 12:57:34 +08:00
$( PIPRUN) LATEST_TAG = $$ ( git tag --sort= -creatordate | head -n 1) ; \
git-changelog --bump $$ LATEST_TAG -Tio docs/changelog.md -c conventional -s build,chore,ci,deps,doc,docs,feat,fix,perf,ref,refactor,revert,style,test,tests
2024-05-09 10:35:54 +08:00
# Generate release notes from changelog.
release-notes :
@$( PIPRUN) git-changelog --input $( CHANGELOG_PATH) --release-notes
# Build documentation only from rdagent.
docs-gen :
2024-08-09 15:23:56 +08:00
$( PIPRUN) python -m sphinx.cmd.build -W docs $( PUBLIC_DIR)
2024-05-09 10:35:54 +08:00
# Generate mypy reports.
docs-mypy : docs -gen
2024-06-18 11:50:03 +08:00
$( PIPRUN) python -m mypy rdagent test --exclude git_ignore_folder --exclude rdagent/scripts --html-report $( PUBLIC_DIR) /reports/mypy
2024-05-09 10:35:54 +08:00
# Generate html coverage reports with badge.
docs-coverage : test -run docs -gen
$( PIPRUN) python -m coverage html -d $( PUBLIC_DIR) /reports/coverage --fail-under 80
$( PIPRUN) bash scripts/generate-coverage-badge.sh $( PUBLIC_DIR) /_static/badges
# Generate all documentation with reports.
docs : changelog docs -gen docs -mypy docs -coverage
########################################################################################
# End
########################################################################################