Compare commits

..
Author SHA1 Message Date
Mikaël Capelle ca2ca66de8 Fix version in config. 2022-04-21 21:16:20 +02:00
48 changed files with 3999 additions and 19500 deletions
+36
View File
@@ -0,0 +1,36 @@
name: Build Documentation
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
persist-credentials: false
# Standard drop-in approach that should work for most people.
- uses: ammaraskar/sphinx-action@master
env:
PYTHONPATH: .
with:
pre-build-command: "apt-get update -y && apt-get install -y libgl1-mesa-glx && cp stubs/2.4.0/mobase.pyi docs/mobase.py"
docs-folder: "docs/"
- name: Install SSH Client 🔑
uses: webfactory/ssh-agent@v0.4.1
with:
ssh-private-key: ${{ secrets.DEPLOY_KEY }}
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@3.7.1
with:
SSH: true
REPOSITORY_NAME: ModOrganizer2/python-plugins-doc
BRANCH: master
FOLDER: docs/build/html
-39
View File
@@ -1,39 +0,0 @@
name: Build Documentation
on:
pull_request:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.12
- uses: abatilo/actions-poetry@v2
- name: Install
run: poetry install
- name: Install libgl1
run: sudo apt install -y libgl1 libegl1 libglib2.0-0 libxkbcommon0 libdbus-1-3
- name: Copy stubs
run: |
mkdir -p docs/src
cp -r stubs/2.5.2/mobase-stubs docs/src/mobase
- name: Build
run: poetry run sphinx-build -b html docs/source docs/build
env:
PYTHONPATH: docs
- if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
name: Deploy Documentation
uses: JamesIves/github-pages-deploy-action@v4
with:
ssh-key: ${{ secrets.DEPLOY_KEY }}
repository-name: ModOrganizer2/python-plugins-doc
branch: master
folder: docs/build
+16 -12
View File
@@ -5,16 +5,20 @@ on: [push, pull_request]
jobs:
checks:
runs-on: ubuntu-latest
strategy:
max-parallel: 4
matrix:
python-version: [3.8]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.12
- uses: abatilo/actions-poetry@v2
- name: Install
run: |
poetry install
- name: Lint
run: |
poetry run poe lint
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox
- name: Test with tox
run: tox -e py38-lint
+18
View File
@@ -0,0 +1,18 @@
name: Check Documentation
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
# Standard drop-in approach that should work for most people.
- uses: ammaraskar/sphinx-action@master
env:
PYTHONPATH: .
with:
pre-build-command: "apt-get update -y && apt-get install -y libgl1-mesa-glx && cp stubs/2.4.0/mobase.pyi docs/mobase.py"
docs-folder: "docs/"
+29 -46
View File
@@ -1,57 +1,40 @@
# This workflows will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI
name: Upload Python Package
on:
push:
tags: ["*"]
release:
types: [published]
jobs:
build:
name: Build distribution 📦
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Replace string
uses: frabert/replace-string-action@v1.1
id: version
with:
string: ${{ github.ref_name }}
pattern: "v?([0-9][.][0-9][.][0-9]).*"
replace-with: "$1"
- uses: actions/setup-python@v2
with:
python-version: 3.12
- uses: abatilo/actions-poetry@v2
- name: Build
run: |
cd stubs/setup
mkdir mobase-stubs
cp -r ../${{ steps.version.outputs.replaced }}/mobase-stubs/* mobase-stubs/
sed -i 's/__version__ = ".*"/__version__ = "${{ github.ref_name }}"/' mobase-stubs/__init__.pyi
TAG=${{ github.ref_name }}
poetry version ${TAG#v}
poetry build
- name: Store the distribution packages
uses: actions/upload-artifact@v3
with:
name: python-package-distributions
path: stubs/setup/dist/
deploy:
publish-to-pypi:
name: Publish Python 🐍 distribution 📦 to PyPI
needs:
- build
runs-on: ubuntu-latest
permissions:
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
steps:
- name: Download all the dists
uses: actions/download-artifact@v3
with:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
- uses: actions/checkout@v2
- name: Replace string
uses: frabert/replace-string-action@v1.1
id: version
with:
string: ${{ github.event.release.tag_name }}
pattern: "v?([0-9][.][0-9][.][0-9]).*"
replace-with: "$1"
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
cd stubs/setup
cp ../${{ steps.version.outputs.replaced }}/mobase.pyi mobase-stubs/__init__.pyi
python setup.py sdist bdist_wheel
twine upload dist/*
+1 -2
View File
@@ -2,10 +2,9 @@
.mypy_cache
__pycache__
.vscode
**/*.egg-info
# The 'bin/' directory:
bin
docs/build
docs/mobase.py
docs/source/api
docs/source/api
+49 -46
View File
@@ -16,12 +16,23 @@ MO2.
You can install stubs for a specific version of MO2:
```bash
pip install mobase-stubs==2.5.*
pip install mobase-stubs==2.3.2.*
```
If you want development stubs, you can install them this way:
```bash
# Clone this repository:
git clone https://github.com/ModOrganizer2/pystubs-generation.git
# Install the stubs:
cd pystubs-generation/stubs/setup
pip install .
```
Some words of warning:
- The stubs are as correct as possible, but some errors are expected.
- If you see a `InterfaceNotImplemented` class anywhere in the stubs, it means that
a proper interface is currently not available.
- Some classes are said (in the stubs) to inherit `QWidget` or `QObject`. This is true
on the C++ side but NOT on the python side. The inheritance is only added to help with
auto-completion since these classes also override `__getattr__` to dispatch to the
@@ -33,39 +44,35 @@ Some words of warning:
The stubs are generated using python by parsing the `mobase` module.
You need the version of python that matches your current MO2 installation: e.g., if you
have a `python310.dll` in your MO2 installation path, then you need **Python 3.10**.
have a `python38.dll` in your MO2 installation path, then you need **Python 3.8**.
To generate the stubs, you can run:
```bash
# install the package
poetry install
# change the output folder to whatever you want
mo2-stubs-generator -c configs/config-2.4.yml -o mobase-stubs ${MO2_INSTALL_PATH}
```
# Change the output folder to whatever you want:
python main.py -c configs\config-2.4.yml ${MO2_INSTALL_PATH}
```
Where `${MO2_INSTALL_PATH}` is the path to your MO2 installation (the one
containing `ModOrganizer.exe`).
Where `${MO2_INSTALL_PATH}` is the path to your MO2 installation (the one containing `ModOrganizer.exe`).
The stubs are generated under `stubs/setup/mobase-stubs` by default, you
can change the output file by using the `-o` option.
The stubs under `stubs/setup/mobase-stubs` should not be committed as these are
generated from the version stubs under `stubs/${VERSION}/mobase-stubs`.
The stubs are generated under `stubs/setup/mobase-stubs/__init__.pyi`, you
can change the output file by using the `-o` option
The latest stubs are kept under `stubs/setup/mobase-stubs/__init__.pyi`,
and when a new version is released, the stubs are backed-up under
`stubs/x.y.z/mobase.pyi`.
A few options are available for `mo2-stubs-generator`:
A few options are available for `main.py`:
```bash
$ mo2-stubs-generator --help
usage: stubs generator for the MO2 python interface [-h] [-o OUTPUT] [-v] [-c CONFIG] INSTALL_DIR
```
usage: Stubs generator for the MO2 python interface [-h] [-o OUTPUT] [-v] [-c CONFIG] INSTALL_DIR
positional arguments:
INSTALL_DIR installation directory of Mod Organizer 2
options:
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
output folder (default stubs/setup/mobase-stubs)
output file (default stubs/setup/mobase-stubs/__init__.pyi)
-v, --verbose verbose mode (all logs go to stderr)
-c CONFIG, --config CONFIG
configuration file
@@ -74,7 +81,19 @@ options:
The stubs generator will try hard to find a valid stubs for all classes
and methods of `mobase`.
A lot of information is available through the `-v` options. Without it,
only conversions or fixes considered "strange" will be shown.
only conversions or fixes
considered "strange" will be shown.
For instance, here is the output with the current `config-2.4.yml` file:
```
WARNING: Replacing IOrganizer::FileInfo with FileInfo.
WARNING: Replacing IOrganizer::FileInfo with FileInfo.
WARNING: Replacing IPluginInstaller::EInstallResult with InstallResult.
WARNING: Replacing IPluginInstaller::EInstallResult with InstallResult.
```
As you can see, only a few types were manually fixed (specified in
`config-2.4.yml`).
## Configuration file
@@ -83,36 +102,20 @@ deduced by `main` (or are too complex to deduce), and the documentation for ever
## Uploading the stubs to pypi
The upload of the stubs to [https://pypi.org/project/mobase-stubs/](https://pypi.org/project/mobase-stubs/)
should be done automatically when a new Github tag is pushed.
The upload of the stubs to https://pypi.org/project/mobase-stubs/ should be
done automatically when a new Github release is made.
## Extras — Using `mobase` in a Python interpreter
## Extras — Starts a python interpreter with `mobase`
It is possible to start a (i)python interpreter with `mobase` imported by running
It is possible to start a (i)python interpret with `mobase` imported by running:
```bash
python -i -m mo2.stubs.generator.loader ${MO2_INSTALL_PATH}
```
python -im generator.loader ${MO2_INSTALL_PATH}
```
You can also import `mobase` in your code using the following (after installing
this package):
This has no real usage except for MO2 developers since most classes from the `mobase` module cannot be instantiated.
```python
from mo2.stubs.generator import load_mobase
mobase = load_mobase(MO2_INSTALL_PATH)
# the above will probably not give you type-completion in your IDE or typing, so
# you can use the following (if the stubs are installed)
load_mobase(MO2_INSTALL_PATH)
import mobase
import mobase.widgets
```
**Note:** Most classes in `mobase` cannot be instantiated, so this is mostly intended
for MO2 developers.
## License
# License
The MIT License (MIT)
+86 -399
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+20
View File
@@ -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 = source
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)
+35
View File
@@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%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.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
+4
View File
@@ -0,0 +1,4 @@
sphinx-rtd-theme
sphinx-autodoc-typehints
sphinx-automodapi
PyQt5
+11 -7
View File
@@ -10,13 +10,21 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath("../../stubs/2.4.0/"))
# -- Project information -----------------------------------------------------
project = "MO2 Python Plugin API"
copyright = "2023, Holt59"
copyright = "2020, Holt59"
author = "Holt59"
# The full version, including alpha/beta/rc tags
release = "2.3rc1"
# -- General configuration ---------------------------------------------------
@@ -27,9 +35,8 @@ extensions = [
"sphinx.ext.autodoc",
"sphinx_autodoc_typehints",
"sphinx.ext.napoleon",
"autoapi.extension",
# "sphinx.ext.autosummary",
# "sphinx_automodapi.automodapi",
"sphinx_automodapi.automodapi",
]
# Add any paths that contain templates here, relative to this directory.
@@ -40,9 +47,6 @@ templates_path = ["_templates"]
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
autoapi_dirs = ["../src"]
autoapi_member_order = "groupwise"
# -- Options for HTML output -------------------------------------------------
@@ -65,5 +69,5 @@ html_favicon = "mo2.ico"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ["_static"]
html_static_path = ["_static"]
html_extra_path = [".nojekyll"]
+1
View File
@@ -18,6 +18,7 @@ This documentation is dedicated to writting MO2 **Python** plugins.
plugin-types
writing-plugins
faq
mobase
+11
View File
@@ -0,0 +1,11 @@
``mobase`` API
==============
.. currentmodule:: mobase
.. automodapi:: mobase
:no-inheritance-diagram:
:no-heading:
.. toctree::
:maxdepth: 4
+7
View File
@@ -0,0 +1,7 @@
mobase
======
.. toctree::
:maxdepth: 4
mobase
+5 -3
View File
@@ -64,8 +64,10 @@ These plugins (shall eventually) implement all the game specific features and fu
able to add support for further games.
The plugin is also responsible to help MO determine if (and where) the game is installed in the first place.
Since supporting a game properly requires extensions in many places of the UI.
To allow this without creating one huge plugin interface that involves every aspect of MO,
game plugins can register only the features they need to MO2 using :meth:`registerFeature<mobase.IGameFeatures.registerFeature>`
To allow this without creating one huge plugin interface that involves every aspect of MO, game plugins
expose a *feature list*.
The list of possible features can be found in the "game_features" project and each feature can itself be
considered a plugin interface.
As an example for a game feature take BSA invalidation: If the game requires BSA invalidation it will implement
this feature.
@@ -145,4 +147,4 @@ File Mappings
This interface allows plugins to add virtual file (or directory) links to the virtual file system in addition to the
mod files.
Profile-local save games, ini-files and load-orders are all implemented this way in MO2.
Profile-local save games, ini-files and load-orders are all implemented this way in MO2.
+8
View File
@@ -0,0 +1,8 @@
# -*- encoding: utf-8 -*-
import logging
import sys
logging.basicConfig(stream=sys.stderr, format="%(levelname)s: %(message)s")
logger = logging.getLogger(__name__)
logger.setLevel(logging.WARNING)
+94
View File
@@ -0,0 +1,94 @@
# -*- encoding: utf-8 -*-
import importlib.machinery
import importlib.util
import os
import sys
from pathlib import Path
def load_module(name: str, path: Path):
# Create the loader:
loader = importlib.machinery.ExtensionFileLoader( # type: ignore
name, path.as_posix()
)
# Extract the spec:
spec = importlib.util.spec_from_loader(name, loader)
# Create the module and execute it?
module = importlib.util.module_from_spec(spec)
if module is None:
raise ImportError(f"Failed to import module {name} from {path}.")
loader.exec_module(module)
return module
def load_mobase(path: Path, moprivate: bool = False):
"""
Load the mobase from the given MO2 installation path and
returns it.
Args:
path: Path to the MO2 installation (folder containing the ModOrganizer.exe).
moprivate: If True, the moprivate module will also be loaded and returned
alongside mobase.
Returns: The mobase module.
"""
# We need absolute path for loading DLL and modules:
path = path.resolve()
# Adding to PATH environment variable for python < 3.8 and
# via os.add_dll_directory (python >= 3.8).
# See: https://stackoverflow.com/a/58632354/2666289
if sys.version_info < (3, 8):
os.environ["PATH"] = os.pathsep.join(
[str(path), str(path.joinpath("dlls")), os.environ.get("PATH", "")]
)
else:
os.add_dll_directory(str(path)) # type: ignore[attr-defined]
os.add_dll_directory(str(path.joinpath("dlls"))) # type: ignore[attr-defined]
# We need to add plugins/data to sys.path, mainly for PyQt5
sys.path.insert(1, path.joinpath("plugins", "data").as_posix())
mobase = load_module("mobase", path.joinpath("plugins", "data", "pythonrunner.dll"))
if not moprivate:
return mobase
moprivate = load_module(
"moprivate", path.joinpath("plugins", "data", "pythonrunner.dll")
)
return mobase, moprivate
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
"Load mobase python module from MO2 installation directory"
)
parser.add_argument(
"install_dir",
metavar="INSTALL_DIR",
type=Path,
default=None,
help="installation directory of Mod Organizer 2",
)
parser.add_argument(
"-p", "--private", action="store_true", help="also load the moprivate module"
)
args = parser.parse_args()
if args.private:
mobase, moprivate = load_mobase(args.install_dir, moprivate=True)
else:
mobase = load_mobase(args.install_dir)
+713
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More