diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dea13aa --- /dev/null +++ b/Makefile @@ -0,0 +1,160 @@ +#!/usr/bin/make +# 2024 Nicolas Gampierakis + +LIBNAME=cosipy + +ifeq (, $(shell which python )) + $(error "PYTHON=$(PYTHON) not found in $(PATH)") +endif +PYTHON=$(shell which python) +PYTHON_VERSION=$(shell $(PYTHON) -c "import sys;\ + version='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));\ + sys.stdout.write(version)") +PYTHON_CHECK_MAJOR=$(shell $(PYTHON) -c 'import sys;\ + print(int(float("%d"% sys.version_info.major) >= 3))') +PYTHON_CHECK_MINOR=$(shell $(PYTHON) -c 'import sys;\ + print(int(12 >= float("%d"% sys.version_info.minor) >= 9))' ) +PYTHON_SOURCES=src/$(LIBNAME)/[a-z]*.py + +TEST_SOURCES=tests/[a-z]*.py +DOCS_SOURCES=docs + +LOG_DATE=$(shell date +%Y%m%d_%H%M%S) + +.PHONY: help +help: ## Display this help screen + @grep -hE '^[A-Za-z0-9_ \-]*?:.*##.*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: install +install: install-conda-env ## Install editable package using conda/mamba + @echo "\nInstalling editable..." + @pip install -e . + +install-conda-env: --check-python --hook-manager ## Install conda/mamba dependencies + @echo "\nInstalling dependencies (core)..." + @$(pkg-manager) install --file conda_requirements.txt -c conda-forge + +install-pip: ## Install editable package using pip + @echo "\nInstalling editable..." + $(PYTHON) -m pip install --upgrade gdal==`gdal-config --version` pybind11 + $(PYTHON) -m pip install -e . + +install-pip-tests: install-pip ## Install editable package with tests using pip + @echo "\nInstalling editable with tests..." + $(PYTHON) -m pip install --upgrade gdal==`gdal-config --version` pybind11 + @pip install -e .[tests] + +install-pip-docs: ## Install editable package with local documentation using pip + @echo "\nInstalling editable with documentation..." + $(PYTHON) -m pip install --upgrade gdal==`gdal-config --version` pybind11 + @pip install -e .[docs] + @make docs + +install-pip-all: ## Install editable package with tests & documentation using pip + @echo "\nInstalling editable with tests & documentation..." + $(PYTHON) -m pip install --upgrade gdal==`gdal-config --version` pybind11 + @pip install -e .[tests,docs] + @make docs + +install-pip-dev: --check-python --hook-manager ## Install editable package in development mode using pip + @echo "\nInstalling editable in development mode..." + $(PYTHON) -m pip install --upgrade gdal==`gdal-config --version` pybind11 + @pip install -e .[dev] + +.PHONY: tests +tests: flake8 coverage pylint ## Run tests + +.PHONY: commit +commit: tests ## Test, then commit + @echo "\nCommitting..." + @git commit + +.PHONY: docs +docs: ## Build documentation + @echo "\nBuilding documentation..." + @cd $(DOCS_SOURCES); make clean && make html + +format: isort black ## Format all python files + +setup-cosipy: ## Generate COSIPY configuration files + @$(PYTHON) -m cosipy.utilities.setup_cosipy.setup_cosipy + +create-static: + @$(PYTHON) -m cosipy.utilities.createStatic.create_static_file + +commands: ## Display help for COSIPY + @$(PYTHON) -m COSIPY.py -h + +.PHONY: run +run: commands ## Alias for `make commands` + +flake8: ## Lint with flake8 + @echo "\nLinting with flake8..." + @flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + @flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics + +.PHONY: coverage +coverage: ## Run pytest with coverage + @echo "\nRunning tests..." + @mkdir -p "./logs/coverage" + @coverage run --rcfile .coveragerc -m pytest && coverage html + +.PHONY: pylint +pylint: ## Lint with Pylint + @echo "\nLinting with pylint..." + @pylint --rcfile .pylintrc **/*.py + +black: ## Format all python files with black + @echo "\nFormatting..." + @black $(PYTHON_SOURCES) --line-length=80 + @black $(TEST_SOURCES) --line-length=80 + +isort: ## Optimise python imports + @isort $(PYTHON_SOURCES) + @isort $(TEST_SOURCES) + +.PHONY: pkg +pkg: tests docs build ## Run tests, build documentation, build package + +.PHONY: build +build: --install-build-deps ## Build COSIPY package + $(PYTHON) -m build + @twine check dist/* + +# .PHONY +# bump-version: +# @grep -Po '\bversion\s*=\s*"\K.*?(?=")' pyproject.toml + +.PHONY: +upload-pypi: # Private: upload COSIPY package + @twine check dist/* + @twine upload dist/* + + +--install-pip-deps: --check-python # Private: install core dependencies with pip + @echo "\nInstalling dependencies with pip..." + $(PYTHON) -m pip install --r requirements.txt + +--install-build-deps: --check-python --hook-manager # Private: install build dependencies + @echo "\nInstalling build dependencies..." + $(PYTHON) -m pip install --upgrade build hatchling twine + +--check-python: # Private: check Python is >=3.9 +ifeq ($(PYTHON_CHECK_MAJOR),0) + $(error "Python version is $(PYTHON_VERSION). Requires Python >= 3.9") +else ifeq ($(PYTHON_CHECK_MINOR),0) + $(error "Python version is $(PYTHON_VERSION). Requires Python >= 3.9") +endif + +--hook-manager: # Private: hook package manager +ifneq (,$(findstring mamba, ${CONDA_EXE})) +pkg-manager := @mamba +else ifneq (,$(findstring miniforge, ${CONDA_EXE})) +pkg-manager := @mamba +else ifeq (,$(findstring conda, ${CONDA_EXE})) +pkg-manager := @conda +else + $(error "No conda/mamba installation found. Try pip install -e . instead") +endif + + diff --git a/README.rst b/README.rst index cf48ef2..caba77b 100644 --- a/README.rst +++ b/README.rst @@ -39,6 +39,7 @@ Install GDAL: sudo apt-get install gdal-bin libgdal-dev pip install --upgrade gdal==`gdal-config --version` pybind11 # with pip + conda install gdal # with conda Install COSIPY with pip (for general use): @@ -48,15 +49,31 @@ Install COSIPY with pip (for general use): cosipy-setup # generate template configuration files cosipy-help # view help +Install COSIPY as an editable (recommended for development): + +.. code-block:: console + + git clone https://github.com/cryotools/cosipy.git + cd cosipy + make install # using conda/mamba + make install-pip-dev # using pip + + cosipy-help # view help + Install COSIPY from source (for development): .. code-block:: console git clone https://github.com/cryotools/cosipy.git + cd cosipy + make install-conda-envs # install using conda/mamba + conda install --file conda_requirements.txt # install with conda + pip install -r requirements.txt # install default environment pip install -r dev_requirements.txt # install dev environment - conda install --file conda_requirements.txt # install using conda/mamba + python3 COSIPY.py -h + make commands Communication and Support ------------------------- diff --git a/docs/source/documentation.rst b/docs/source/documentation.rst index 08efac6..f017399 100644 --- a/docs/source/documentation.rst +++ b/docs/source/documentation.rst @@ -42,6 +42,8 @@ Install GDAL: If you are installing dependencies with conda/mamba, use ``-c conda-forge`` if it does not already have the highest channel priority. +When you are installing from source, :ref:`the provided makefile` will install the ``gdal`` package automatically. + .. note:: If you are installing with **pip** and Python 3.11+, you will need to `compile and install richdem`_. This is not necessary when using conda/mamba. @@ -71,29 +73,51 @@ This is the recommended installation method if you do not plan to modify the sou Installation from Source ------------------------ -Activate your preferred python environment, then run: +Activate your preferred python environment, then install dependencies: .. code-block:: bash git clone https://github.com/cryotools/cosipy.git + cd cosipy + + make install-conda-envs # install using conda/mamba + conda install --file conda_requirements.txt # install with conda + pip install -r requirements.txt # install default environment pip install -r dev_requirements.txt # install dev environment - conda install --file conda_requirements.txt # install using conda/mamba + python3 COSIPY.py -h + make commands # if you prefer less typing + make setup-cosipy # generate configuration files Installation as an Editable --------------------------- Installing COSIPY as an editable allows it to run from any directory. +The :ref:`provided makefile` can simplify your workflow. +View all possible commands using ``make help``. + .. code-block:: bash git clone https://github.com/cryotools/cosipy.git cd cosipy - pip install -e . - pip install -e .[tests] # install with dependencies for tests - pip install -e .[docs] # install with dependencies for documentation - pip install -e .[dev] # install with dependencies for development + + make install # with conda/mamba + make install-pip # with pip + + cosipy-setup # generate sample configuration files + cosipy-help # view help + +That's it! +Other installation options with pip: + +.. code-block:: bash + + pip install -e . # identical to make install-pip + make install-pip-tests # install with test dependencies using pip + make install-pip-dev # install with development dependencies using pip + cosipy-setup # generate sample configuration files cosipy-help # view help @@ -146,8 +170,8 @@ Tutorial ======== For this tutorial, download or copy the sample ``data`` folder and place it in your COSIPY working directory. -If you have installed COSIPY as a package, you can use the entry point ``setup-cosipy`` to generate the sample configuration files. -Otherwise, run ``python -m cosipy.utilities.setup_cosipy.setup_cosipy``. +If you have installed COSIPY as a package, use the entry point ``setup-cosipy`` to generate the sample configuration files. +Otherwise, run ``make setup-cosipy``. Pre-Processing -------------- @@ -183,6 +207,7 @@ The static file is created using either: .. code-block:: bash + make create-static # from source python -m cosipy.utilities.createStatic.create_static_file # from source cosipy-create-static # from entry point @@ -257,7 +282,7 @@ To run COSIPY, run the following command in the root directory: python COSIPY.py # from source run-cosipy # from package -The example should take less than a minute on a workstation with 4 cores. +The example should take about a minute on a workstation with 4 cores. .. _run_usage: @@ -301,6 +326,38 @@ Available shortcuts: :run-cosipy: Alias for ``cosipy-run``. :setup-cosipy: Alias for ``cosipy-setup``. +.. _makefile: + +Makefile +-------- + +The provided makefile can simplify your workflow. +View all possible commands using ``make help``. + +Available shortcuts: + :black: Format all python files with black. + :build: Build COSIPY package. + :commands: Display help for COSIPY. + :commit: Test, then commit. + :coverage: Run pytest with coverage. + :docs: Build documentation. + :flake8: Lint with flake8. + :format: Format all python files. + :help: Display this help screen. + :install-conda-env: Install conda/mamba dependencies. + :install: Install editable package using conda/mamba. + :install-pip-all: Install editable package with tests & documentation using pip. + :install-pip-dev: Install editable package in development mode using pip. + :install-pip-docs: Install editable package with local documentation using pip. + :install-pip: Install editable package using pip. + :install-pip-tests: Install editable package with tests using pip. + :isort: Optimise python imports. + :pkg: Run tests, build documentation, build package. + :pylint: Lint with Pylint. + :run: Alias for ``make commands``. + :setup-cosipy: Generate COSIPY configuration files. + :tests: Run tests. + .. _configuration: Configuration diff --git a/pyproject.toml b/pyproject.toml index 7f0e70f..7f3ab1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -107,6 +107,7 @@ exclude = [ "data/static/Shapefiles/*.*", "data/static/DEM/*.*", "logs", + "Makefile", "*.png", "*.vtu", "*.csv",