From ada9e966ffed16bab0973017f01827b06c70504d Mon Sep 17 00:00:00 2001
From: Yoann Schneider <yschneider@teklia.com>
Date: Tue, 7 May 2024 10:40:29 +0000
Subject: [PATCH] Pyproject packaging and last misses on Licensing

---
 .gitlab-ci.yml                  |  6 +--
 Dockerfile                      |  7 ++-
 MANIFEST.in                     |  4 --
 Makefile                        |  8 ++--
 README.md                       |  2 +-
 VERSION                         |  1 -
 doc-requirements.txt            |  3 --
 docs/get_started/development.md |  4 +-
 mlflow-requirements.txt         |  2 -
 pyproject.toml                  | 75 +++++++++++++++++++++++++++++++++
 requirements.txt                | 22 ----------
 setup.py                        | 65 ----------------------------
 tox.ini                         |  6 ++-
 13 files changed, 94 insertions(+), 111 deletions(-)
 delete mode 100644 VERSION
 delete mode 100644 mlflow-requirements.txt
 delete mode 100644 requirements.txt
 delete mode 100755 setup.py

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cec5c0e9..42793e04 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -153,10 +153,10 @@ deploy-pypi:
     - tags
 
   before_script:
-    - pip install twine
+    - pip install twine build
 
   script:
-    - python setup.py sdist bdist_wheel
+    - python -m build
     - twine upload -r pypi dist/*
 
 bump-python-deps:
@@ -167,7 +167,7 @@ bump-python-deps:
     - schedules
 
   script:
-    - devops python-deps requirements.txt doc-requirements.txt
+    - devops python-deps pyproject.toml doc-requirements.txt
 
 release-notes:
   stage: deploy
diff --git a/Dockerfile b/Dockerfile
index 6f5c337f..eccae7a9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -9,8 +9,7 @@ WORKDIR /src
 
 # Copy DAN data
 COPY dan dan
-COPY requirements.txt *-requirements.txt setup.py VERSION README.md ./
+COPY pyproject.toml README.md ./
 
-# Install DAN as a package with GitLab package registry
-RUN --mount=type=secret,id=netrc,target=/root/.netrc \
-    pip install . --no-cache-dir
+# Install DAN as a package
+RUN pip install . --no-cache-dir
diff --git a/MANIFEST.in b/MANIFEST.in
index d998b5e0..42e73fd3 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,7 +1,3 @@
 include LICENSE
 include LICENCE
-include requirements.txt
-include doc-requirements.txt
-include mlflow-requirements.txt
-include VERSION
 include README.md
diff --git a/Makefile b/Makefile
index 7325290c..3cd57d50 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,10 @@
 .PHONY: release
 
 release:
-	$(eval version:=$(shell cat VERSION))
-	echo $(version)
-	git commit VERSION -m "Version $(version)"
+	# Grep the version from pyproject.toml, squeeze multiple spaces, delete double and single quotes, get 3rd val.
+	# This command tolerates multiple whitespace sequences around the version number.
+	$(eval version:=$(shell grep -m 1 version pyproject.toml | tr -s ' ' | tr -d '"' | tr -d "'" | cut -d' ' -f3))
+	echo Releasing version $(version)
+	git commit pyproject.toml -m "Version $(version)"
 	git tag $(version)
 	git push origin main $(version)
diff --git a/README.md b/README.md
index 655fc156..b91da115 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 
 For more details about this package, make sure to see the documentation available at <https://atr.pages.teklia.com/dan/>.
 
-This is an open-source project, licensed using [the MIT license](https://opensource.org/license/mit/).
+This is an open-source project, licensed using [the CeCILL-C license](https://cecill.info/index.en.html).
 
 ## Inference
 
diff --git a/VERSION b/VERSION
deleted file mode 100644
index 8280595e..00000000
--- a/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.2.0rc5
diff --git a/doc-requirements.txt b/doc-requirements.txt
index 947c14d0..a49bdc8a 100644
--- a/doc-requirements.txt
+++ b/doc-requirements.txt
@@ -1,9 +1,6 @@
 black==24.3.0
-doc8==1.1.1
 # Pick a specific version because griffe==0.32.0 introduces a bug
 griffe==0.31.0
-mkdocs==1.4.2
 mkdocs-material==9.1.9
-mkdocstrings==0.20.0
 mkdocstrings-python==0.9.0
 recommonmark==0.7.1
diff --git a/docs/get_started/development.md b/docs/get_started/development.md
index f5098dc6..102abb07 100644
--- a/docs/get_started/development.md
+++ b/docs/get_started/development.md
@@ -77,11 +77,11 @@ This documentation uses [Sphinx](http://www.sphinx-doc.org/) and was generated u
 
 ### Setup
 
-Add the `docs` extra when installing `teklia-dan`:
+Install the needed dependencies through:
 
 ```shell
 # In a clone of the Git repository
-pip install .[docs]
+pip install -r doc-requirements.txt
 ```
 
 Build the documentation using `mkdocs serve -v`. You can then write in [Markdown](https://www.markdownguide.org/) in the relevant `docs/*.md` files, and see live output on http://localhost:8000.
diff --git a/mlflow-requirements.txt b/mlflow-requirements.txt
deleted file mode 100644
index 3dcc340d..00000000
--- a/mlflow-requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-mlflow-skinny==2.2.2
-pandas==2.0.0
diff --git a/pyproject.toml b/pyproject.toml
index 02f967be..fc561af2 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,3 +1,78 @@
+[build-system]
+requires = ["setuptools >= 61.0"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "atr-dan"
+version = "0.2.0rc5"
+description = "Teklia DAN"
+readme = "README.md"
+requires-python = ">=3.10"
+authors = [
+    { name = "Teklia", email = "contact@teklia.com" },
+]
+dependencies = [
+    "albumentations==1.3.1",
+    "arkindex-export==0.1.9",
+    "boto3==1.26.124",
+    "flashlight-text==0.0.7",
+    "imageio==2.26.1",
+    "imagesize==1.4.1",
+    "lxml==5.2.0",
+    "matplotlib==3.8.3",
+    "mdutils==1.6.0",
+    "nltk==3.8.1",
+    "numpy==1.24.3",
+    "PyYAML==6.0.1",
+    "scipy==1.12.0",
+    "sentencepiece==0.1.99",
+    "teklia-line-image-extractor==0.2.9",
+    "teklia-nerval==0.3.3-rc1",
+    "tenacity==8.2.3",
+    "tensorboard==2.12.2",
+    "torch==2.2.0",
+    "torchaudio==2.2.0",
+    "torchvision==0.17.0",
+    "tqdm==4.65.0",
+]
+
+keywords = ["python", "HTR", "OCR", "NER", "machine learning", "pytorch"]
+classifiers = [
+    "Development Status :: 4 - Beta",
+    "License :: CeCILL-C Free Software License Agreement (CECILL-C)",
+    # Specify the Python versions you support here.
+    "Programming Language :: Python :: 3 :: Only",
+    "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
+    # Topics
+    "Topic :: Software Development :: Libraries :: Python Modules",
+    "Topic :: Text Processing :: Linguistic",
+    "Topic :: Scientific/Engineering :: Artificial Intelligence",
+    "Topic :: Scientific/Engineering :: Image Recognition",
+]
+
+[project.optional-dependencies]
+mlflow = [
+    "mlflow-skinny==2.2.2",
+    "pandas==2.0.0",
+]
+
+[project.scripts]
+teklia-dan = "dan.cli:main"
+
+[project.urls]
+Homepage = "https://atr.pages.teklia/dan/"
+Documentation = "https://atr.pages.teklia/dan/"
+Repository = "https://gitlab.teklia.com/atr/dan"
+"Bug Tracker" = "https://gitlab.teklia.com/atr/dan/issues"
+Maintainers = "https://teklia.com"
+
+[tool.setuptools]
+license-files = ["LICENSE", "LICENCE"]
+
+[tool.setuptools.packages]
+find = {}
+
 [tool.ruff]
 exclude = [".git", "__pycache__"]
 
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 4f81b881..00000000
--- a/requirements.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-albumentations==1.3.1
-arkindex-export==0.1.9
-boto3==1.26.124
-flashlight-text==0.0.7
-imageio==2.26.1
-imagesize==1.4.1
-lxml==5.2.0
-matplotlib==3.8.3
-mdutils==1.6.0
-nltk==3.8.1
-numpy==1.24.3
-PyYAML==6.0.1
-scipy==1.12.0
-sentencepiece==0.1.99
-teklia-line-image-extractor==0.2.9
-teklia-nerval==0.3.3-rc1
-tenacity==8.2.3
-tensorboard==2.12.2
-torch==2.2.0
-torchaudio==2.2.0
-torchvision==0.17.0
-tqdm==4.65.0
diff --git a/setup.py b/setup.py
deleted file mode 100755
index 1acba06f..00000000
--- a/setup.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-# Copyright Teklia (contact@teklia.com) & Denis Coquenet
-# This code is licensed under CeCILL-C
-
-# -*- coding: utf-8 -*-
-
-from pathlib import Path
-from typing import List
-
-from setuptools import find_packages, setup
-
-
-def parse_requirements_line(line) -> str:
-    # Special case for git requirements
-    if line.startswith("git+http"):
-        assert "@" in line, "Branch should be specified with suffix (ex: @master)"
-        assert (
-            "#egg=" in line
-        ), "Package name should be specified with suffix (ex: #egg=kraken)"
-        package_name: str = line.split("#egg=")[-1]
-        return f"{package_name} @ {line}"
-    # Special case for submodule requirements
-    elif line.startswith("-e"):
-        package_path: str = line.split(" ")[-1]
-        package = Path(package_path).resolve()
-        return f"{package.name} @ file://{package}"
-    else:
-        return line
-
-
-def parse_requirements(filename: str) -> List[str]:
-    path = Path(__file__).parent.resolve() / filename
-    assert path.exists(), f"Missing requirements: {path}"
-    return list(
-        map(parse_requirements_line, map(str.strip, path.read_text().splitlines()))
-    )
-
-
-setup(
-    name="atr-dan",
-    version=Path("VERSION").read_text(),
-    description="Teklia DAN",
-    long_description=Path("README.md").read_text(),
-    long_description_content_type="text/markdown",
-    author="Teklia",
-    author_email="contact@teklia.com",
-    url="https://gitlab.teklia.com/atr/dan",
-    python_requires=">=3.10",
-    install_requires=parse_requirements("requirements.txt"),
-    packages=find_packages(),
-    entry_points={
-        "console_scripts": [
-            "teklia-dan=dan.cli:main",
-        ]
-    },
-    extras_require={
-        "docs": parse_requirements("doc-requirements.txt"),
-        "mlflow": parse_requirements("mlflow-requirements.txt"),
-    },
-    license="CeCILL-C",
-    license_files=(
-        "LICENSE",
-        "LICENCE",
-    ),
-)
diff --git a/tox.ini b/tox.ini
index c2b943f0..eba88799 100644
--- a/tox.ini
+++ b/tox.ini
@@ -10,13 +10,17 @@ wheel_build_env = .pkg
 deps =
     pytest>=6
     pytest-responses
-    -rrequirements.txt
 commands =
     pytest {tty:--color=yes} {posargs}
 
 [testenv:doc]
 extras = docs
 
+# No need to install dan in this env
+skip_install = True
+
+deps = -rdoc-requirements.txt
+
 commands =
   mkdocs build --clean --verbose --strict
 
-- 
GitLab