diff --git a/.age.toml b/.age.toml new file mode 100644 index 0000000..99c9858 --- /dev/null +++ b/.age.toml @@ -0,0 +1,11 @@ +current_version = "0.0.0" + +[[files]] +path = "pyproject.toml" +search = "version = \"{{current_version}}\"" +replace = "version = \"{{new_version}}\"" + +[[files]] +path = "src/atsphinx/helpers/__init__.py" +search = "__version__ = \"{{current_version}}\"" +replace = "__version__ = \"{{new_version}}\"" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..f0427e1 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,70 @@ +name: Run CI + +on: + push: + branches: + - '**' + tags-ignore: + - '**' + pull_request: + workflow_dispatch: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version-file: '.python-version' + - name: Lint by pre-commit + run: | + pip install pre-commit + pre-commit run --all-files + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.9', '3.10', '3.11', '3.12'] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Configure venv + run: | + pip install uv + uv venv + uv pip install -r requirements-dev.lock + - name: Run tests + run: | + source .venv/bin/activate + pytest + doctest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version-file: '.python-version' + - name: Configure venv + run: | + pip install uv + uv venv + uv pip install -r requirements-dev.lock + - name: Run tests + run: | + source .venv/bin/activate + make -C doc linkcheck dirhtml + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version-file: '.python-version' + - name: Build package + run: | + pip install hatch + hatch build + ls -l dist diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..206729c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,86 @@ +name: 'Release new version' + +on: + push: + tags: + - 'v*.*.*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version-file: '.python-version' + - name: Build package + run: | + pip install hatch + hatch build + ls -l dist + - uses: actions/upload-artifact@v4 + with: + name: packages-${{ github.ref_name }} + path: dist/ + gh-release: + runs-on: ubuntu-latest + needs: [build] + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + name: packages-${{ github.ref_name }} + path: dist/ + - uses: ncipollo/release-action@v1 + with: + artifacts: 'dist/*' + bodyFile: 'CHANGESLOG.rst' + draft: false + name: Release ${{ github.ref_name }} + tag: ${{ github.ref }} + prerelease: false + publish-pypi: + runs-on: ubuntu-latest + needs: [build] + if: success() && ${{ needs.prepare.outputs.is-release }} + steps: + - uses: actions/download-artifact@v4 + with: + name: packages-${{ github.ref_name }} + path: dist/ + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + deploy-doc: + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version-file: '.python-version' + - name: Configure venv + run: | + pip install uv + uv venv + uv pip install -r requirements-dev.lock + - name: Run tests + run: | + source .venv/bin/activate + make -C doc dirhtml + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: doc/_build/dirhtml + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae8554d --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# python generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# venv +.venv diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..65c11db --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,15 @@ +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.3.0 + hooks: + # Run the linter. + - id: ruff + # Run the formatter. + - id: ruff-format + - repo: https://github.com/PyCQA/doc8 + rev: v1.0.0 + hooks: + - id: doc8 + args: + - --max-line-length=119 diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..92536a9 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12.0 diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 0000000..49e39f3 --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,4 @@ +ver 0.0.0 +========= + +:date: 2024-03-16 JST diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..f9c50c8 --- /dev/null +++ b/README.rst @@ -0,0 +1,5 @@ +================ +atsphinx-helpers +================ + + diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000..90ac735 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,2 @@ +_build +api/ diff --git a/doc/.ruff.toml b/doc/.ruff.toml new file mode 100644 index 0000000..d60ab9a --- /dev/null +++ b/doc/.ruff.toml @@ -0,0 +1,4 @@ +extend = "../pyproject.toml" + +[lint] +ignore = ["D100", "D103"] diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000..3203937 --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,16 @@ +from atsphinx.helpers import __version__ + +# -- Project information ----------------------------------------------------- +project = "atsphinx-helpers" +copyright = "2024, Kazuya Takei" +author = "Kazuya Takei" +release = __version__ + +# -- General configuration --------------------------------------------------- +extensions = [] +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# -- Options for HTML output ------------------------------------------------- +html_theme = "furo" +html_static_path = ["_static"] diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..93704a8 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,3 @@ +==== +Home +==== diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 0000000..32bb245 --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..9018898 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,64 @@ +[project] +name = "atsphinx-helpers" +version = "0.0.0" +description = "Helper for my Sphinx extension" +authors = [ + { name = "Kazuya Takei", email = "myself@attakei.net" } +] +dependencies = [ + "sphinx", +] +readme = "README.rst" +requires-python = ">= 3.9" +license = "Apache-2.0" +classifiers = [ + "Development Status :: 3 - Alpha", + "Framework :: Sphinx", + "Framework :: Sphinx :: Extension", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Documentation :: Sphinx", +] + +[project.urls] +Home = "https://github.com/atsphinx/helpers" +Repository = "https://github.com/atsphinx/helpers" +Issues = "https://github.com/atsphinx/helpers/issues" +Changelog = "https://github.com/atsphinx/helpers/blob/main/CHANGES.rst" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.rye] +managed = true +dev-dependencies = [ + "furo~=2024.1.29", + "pytest~=8.0.2", + "sphinx~=7.2.6", +] + +[tool.rye.scripts] +setup = {chain = ["setup:sync", "setup:pre-commit"]} +"setup:sync" = "rye sync --no-lock --all-features" +"setup:pre-commit" = "pre-commit install" + +[tool.ruff.lint] +select = ["C90", "D", "E", "F", "I", "W"] + +[tool.ruff.lint.pydocstyle] +convention = "pep257" + +[tool.hatch.metadata] +allow-direct-references = true + +[tool.hatch.build.targets.wheel] +packages = ["src/atsphinx"] +only-includes = ["src/atsphinx"] diff --git a/requirements-dev.lock b/requirements-dev.lock new file mode 100644 index 0000000..2d1312d --- /dev/null +++ b/requirements-dev.lock @@ -0,0 +1,68 @@ +# generated by rye +# use `rye lock` or `rye sync` to update this lockfile +# +# last locked with the following flags: +# pre: false +# features: [] +# all-features: false +# with-sources: false + +-e file:. +alabaster==0.7.16 + # via sphinx +babel==2.14.0 + # via sphinx +beautifulsoup4==4.12.3 + # via furo +certifi==2024.2.2 + # via requests +charset-normalizer==3.3.2 + # via requests +docutils==0.20.1 + # via sphinx +furo==2024.1.29 +idna==3.6 + # via requests +imagesize==1.4.1 + # via sphinx +iniconfig==2.0.0 + # via pytest +jinja2==3.1.3 + # via sphinx +markupsafe==2.1.5 + # via jinja2 +packaging==24.0 + # via pytest + # via sphinx +pluggy==1.4.0 + # via pytest +pygments==2.17.2 + # via furo + # via sphinx +pytest==8.0.2 +requests==2.31.0 + # via sphinx +snowballstemmer==2.2.0 + # via sphinx +soupsieve==2.5 + # via beautifulsoup4 +sphinx==7.2.6 + # via atsphinx-helpers + # via furo + # via sphinx-basic-ng +sphinx-basic-ng==1.0.0b2 + # via furo +sphinxcontrib-applehelp==1.0.8 + # via sphinx +sphinxcontrib-devhelp==1.0.6 + # via sphinx +sphinxcontrib-htmlhelp==2.0.5 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.7 + # via sphinx +sphinxcontrib-serializinghtml==1.1.10 + # via sphinx +urllib3==2.2.1 + # via requests diff --git a/requirements.lock b/requirements.lock new file mode 100644 index 0000000..d2471c5 --- /dev/null +++ b/requirements.lock @@ -0,0 +1,52 @@ +# generated by rye +# use `rye lock` or `rye sync` to update this lockfile +# +# last locked with the following flags: +# pre: false +# features: [] +# all-features: false +# with-sources: false + +-e file:. +alabaster==0.7.16 + # via sphinx +babel==2.14.0 + # via sphinx +certifi==2024.2.2 + # via requests +charset-normalizer==3.3.2 + # via requests +docutils==0.20.1 + # via sphinx +idna==3.6 + # via requests +imagesize==1.4.1 + # via sphinx +jinja2==3.1.3 + # via sphinx +markupsafe==2.1.5 + # via jinja2 +packaging==24.0 + # via sphinx +pygments==2.17.2 + # via sphinx +requests==2.31.0 + # via sphinx +snowballstemmer==2.2.0 + # via sphinx +sphinx==7.2.6 + # via atsphinx-helpers +sphinxcontrib-applehelp==1.0.8 + # via sphinx +sphinxcontrib-devhelp==1.0.6 + # via sphinx +sphinxcontrib-htmlhelp==2.0.5 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.7 + # via sphinx +sphinxcontrib-serializinghtml==1.1.10 + # via sphinx +urllib3==2.2.1 + # via requests diff --git a/src/atsphinx/helpers/__init__.py b/src/atsphinx/helpers/__init__.py new file mode 100644 index 0000000..18af8c5 --- /dev/null +++ b/src/atsphinx/helpers/__init__.py @@ -0,0 +1,3 @@ +# noqa: D104 + +__version__ = "0.0.0" diff --git a/tests/.ruff.toml b/tests/.ruff.toml new file mode 100644 index 0000000..d60ab9a --- /dev/null +++ b/tests/.ruff.toml @@ -0,0 +1,4 @@ +extend = "../pyproject.toml" + +[lint] +ignore = ["D100", "D103"] diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..0ab4ddd --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,12 @@ +"""Configuration for pytest.""" + +from pathlib import Path + +import pytest + +pytest_plugins = "sphinx.testing.fixtures" + + +@pytest.fixture(scope="session") +def rootdir() -> Path: # noqa: D103 + return Path(__file__).parent.resolve() diff --git a/tests/test-root/conf.py b/tests/test-root/conf.py new file mode 100644 index 0000000..d03c8b6 --- /dev/null +++ b/tests/test-root/conf.py @@ -0,0 +1 @@ +extensions = [] diff --git a/tests/test-root/index.rst b/tests/test-root/index.rst new file mode 100644 index 0000000..a53c7e2 --- /dev/null +++ b/tests/test-root/index.rst @@ -0,0 +1,2 @@ +Test doc for atsphinx-helpers +============================= diff --git a/tests/test_it.py b/tests/test_it.py new file mode 100644 index 0000000..b8bca08 --- /dev/null +++ b/tests/test_it.py @@ -0,0 +1,12 @@ +"""Standard integration tests.""" + +from io import StringIO + +import pytest +from sphinx.testing.util import SphinxTestApp + + +@pytest.mark.sphinx("html") +def test__it(app: SphinxTestApp, status: StringIO, warning: StringIO): + """Test to pass.""" + app.build()