-
Notifications
You must be signed in to change notification settings - Fork 51
Development
This may need revision, ping me if you need clarification as I wrote it quickly.
- To work on Lute v3, you'll need at least Python 3.8 and pip. You'll probably want to use some kind of virtual environments; I use venv and so will write that out here.
- Note that GitHub CI tests Python versions 3.8 through 3.11, as we can't be sure what version of Python users have, so stay away from newer language features.
- Install MeCab according to your platform as described on the User Installation Page. This is required for passing unit tests irrespective of whether you are developing features relevant to the Japanese language.
# ... usual cloning steps here
git checkout develop # The main dev branch
git submodule init
git submodule update
Lute uses git submodules for the language definitions (https://github.com/LuteOrg/lute-language-defs)
python3.8 -m venv .venv # Your python version may vary
source .venv/bin/activate
python --version # sanity check only
# Install dev and prod requirements
pip install flit
flit install --only-deps --deps develop
pre-commit install # pre-commit hooks (recommended)
Lute uses python splinter and playwright, so you'll need to install ChromeDriver and Playwright browsers
MacOS:
brew install --cask chromedriver
xattr -d com.apple.quarantine /opt/homebrew/bin/chromedriver
playwright install
Copy lute/config/config.yml.example
to lute/config/config.yml
. Set the following parameters:
-
ENV
:prod
for production ordev
for development -
DBNAME
: filename for the database (must be prefixed withtest_
to run tests) -
DATAPATH
: the full path to the folder used to store data (such as/Users/xyz/Documents/lute_data
) -
BACKUP_PATH
: the full path to the folder used to store backups (such as/Users/xyz/Documents/lute_backup
)
If you're going to work on Lute, you'll need to run unit tests. The unit tests are destructive, in that they wipe and reset the configured database. To guard against mistakes:
-
ENV
must bedev
-
DATAPATH
must be set - The
DBNAME
in your config.yml must start withtest_
This ensures that you won't accidentally run the tests against your real Lute data. I work with this by having two completely separate environments: one for dev work, and one for real Lute usage. My prod data (actual data) stays in the latter.
source .venv/bin/activate # if necessary
python -m lute.main
# Open web browser to http://localhost:5000
# ... work work work ...
# When done, Ctl-C then
deactivate
Shut down your dev instance of Lute if it's running, and then run
inv full
This runs all tests and lints everything. It should complete without errors, as lute master and develop branch are always kept passing in CI.
You may/may not find the overview docs of Lute's architecture useful ... let me know.
Pre-commit hooks are installed with the pre-commit install
step, and are run on every commit. I find this useful, as it stops me from having to go back and clean up, but YMMV. You can skip a step, e.g.: SKIP=pylint git commit -m "Some non-lint-compliant commit."
Testing is done with pytest and pytest-bdd. Run them as usual:
pytest
pytest path/to/file.py
pytest -k filter_string
pytest -m somemark
pytest -s
pytest -vv
The usual notes here. Some of these guidelines are really done by "feel", so chat with devs on Discord or in PRs as needed.
- Try to keep your PR minimal, only change what you mean to change. If your PR introduces a ton of reformatting, moving around, etc, it might be rejected for sanity's sake.
- Make nice commit messages (see https://cbea.ms/git-commit/ for notes). You don't need to go overboard if the code is self-explanatory, but a brief summary is often good.
- if you make code changes, don't forget to lint your submission (
inv lint
), and keep an eye on GitHub CI failures for your branch.
Lute3 uses Invoke to run tasks. Tasks are in tasks.py
. See inv --list
for commands.
Some useful tasks:
task | desc |
---|---|
inv start | start the app on a development Flask server in dev/debug mode |
inv lint | lint |
inv accept | start a running instance of the app server if needed, and run acceptance tests |
inv playwright | start a running instance of the app server if needed, and run playwright tests |
Database migrations are managed automatically when Lute starts up. See the DB schema README for notes about how the schema changes are managed.
DB migrations are stored in /lute/db/schema/migrations
. To create a script, run inv db.newscript <somesuffix>
, and edit the file to create a Sqlite-compliant change script. See the existing scripts for examples.
When doing releases, the baseline database gets recreated as described in Releases -- if you add a migration, you don't need to recreate the baseline.
Dependencies are managed with the pyproject.toml
file, and installations of the dependencies are done using flit
:
flit install --only-deps --deps develop
IMPORTANT: Make sure that your dependencies don't introduce other unexpected dependencies (e.g. that aren't under MIT licensing, that need compilers or build tools, etc), or other huge libraries!
Todos are in the code as comments, e.g. # TODO [<group name>:] detail
, <!-- TODO ... -->
.
inv todos
collects all of these in a simple report.
The "group name" is arbitrary: it's used to group things together, which is handy when several locations need to be changed as a single unit of work.
Notes for building and running a Docker container are at ../docker/README.com.
As of v3.4.0, Lute supports a simple "language parser plugin" capability. Set up your dev environment as explained on this page, and then head over to Developing language parser plugins.
This is much tougher than it needs to be ...
To find the correct path, first build and run the container, then connect to it, and find libmecab.so.2 like this:
$ docker exec -it lute_v3-lute-1 bash
root@cid/# which mecab
/usr/bin/mecab
root@cid:/# ldd /usr/bin/mecab
...
libmecab.so.2 => /lib/aarch64-linux-gnu/libmecab.so.2 (0x0000ffff9b540000)
Different platform architectures have this in different locations. :-/
Datatables is used for the term and book listings. See lute/static/vendor/datatables/README.md for notes about getting and updating it.
It appears that killing acceptance tests mid-run results in a zombie (?) python process that keeps a handle on the db, causing it to get locked in read-only mode.
I couldn't find a better way to kill this process than do a full machine restart. Sledgehammer approach that works.
Warning during run of tests with inv accept --exitfail
:
WARNING selenium.webdriver.common.selenium_manager:selenium_manager.py:139 The chromedriver version (118.0.5993.70) detected in PATH at /opt/homebrew/bin/chromedriver might not be compatible with the detected chrome version (119.0.6045.105); currently, chromedriver 119.0.6045.105 is recommended for chrome 119.*, so it is advised to delete the driver in PATH and retry
The fix (on a Mac):
brew upgrade chromedriver
/opt/homebrew/bin/chromedriver --version
The above will show a message: "“chromedriver” can’t be opened because Apple cannot check it for malicious software." Click "Show in Finder", then in Finder, click "Open" and say "OK" when it can't be verified. Yes, this is a security risk.
This wiki is for developer documentation. User documentation is in the user manual
Thanks!