Files
TagStudio/CONTRIBUTING.md
ChloeVZ abc7cc3915 docs: improve python and venv setup instructions in CONTRIBUTING.md (#791)
* docs: refer to pyenv in CONTRIBUTING.md

This commit was made in order to account for users who may already have
a Python installation that isn't 3.12.

A good real world scenario where this may be a problem is users running
on rolling release Linux distributions, such as Arch Linux which
provides bleeding edge updates in a weekly basis.

Continuing with Arch Linux as an example, it provides Python 3.13, which
the current version of TagStudio doesn't seem to work with, an issue I
encountered myself this morning.

In some systems like Windows, this may not matter, but it is an issue
nonetheless, and users using a package manager centric system can't be
expected to downgrade/upgrade their Python version for TagStudio, as
this may cause issues in their system.

The easiest way to solve this is with pyenv, which enables users to
install other Python versions independent from each other, aside from
the system install, and allows specifying a version to use for a
directory (And its subdirectories), the current terminal session, or the
entire system if desired.

Here is a short, technical and objective summary of the changes:
- Updated `.gitignore` to to ignore `.python-version` which pyenv uses.
- Updated CONTRIBUTING.md to refer to pyenv for versioning issues.
    - pyenv is listed as a prerequisite, specifying in parenthesis that it's only for when your Python install isn't 3.12.
    - The "Creating a Python Virtual Environment" section now has an additional step at the beginning, to check that the current Python installation is 3.12.
        - As part of this added step, there are steps to use pyenv to install Python 3.12 separately from the existing Python installation, and activate it for the TagStudio root folder, in case it's not the appropriate version.
    - The numbering of the other steps was offset accordingly.
    - The "Manually Launching (Outside of an IDE)" section now refers to the above first step, should the user encounter some kind of error.

* docs: refer to alternate shells in CONTRIBUTING.md

Some users may not be using the default shell for their system, and
Linux users are the most likely to do this, though this can be seen in
macOS as well. People will often use shells like fish which is not POSIX
compliant but works very well and has great auto-completion, it's very
user friendly.

The reason why I care about this is that the instructions specify to use
.venv/bin/activate which is a bash script and will not run on fish or
csh, and if you take a look at the script, indeed it says it will only
run with bash.

Python will provide alternate scripts for other shells, and at least on
my system (CachyOS), those are scripts for Powershell, bash, fish and
csh. People using these alternate shells, who don't know this may be
confused when running the script referenced in CONTRIBUTING.md and
seeing it fail completely.

The only real change in this commit was adding under the "Linux/macOS"
command in step 3 (step 2 prior to my last commit) of the "Creating a
Python Virtual Environment" section, a short instruction to switch to
the default shell, or use the appropriate script for the user's
preferred shell if any (Since, at least on my system, there aren't
scripts for every shell, for example there is no activate.zsh file).

* fix: modal windows now have the Qt.Dialog flag

Set the Qt.Dialog flag for modal windows, such as "Add Field" so that
they will be seen as dialogs in the backend. This change is unlikely to
be at all noticeable in systems like Windows, but for users running
tiling window managers like bspwm or Sway, this will prevent these modal
windows from being tiled alongside the main window, instead they will be
floating on top, which is the expected behaviour seen on floating window
managers, like the ones used by Windows and macOS.

Added self.setWindowFlag(Qt.Dialog, on=True) # type: ignore to the
following files:
- tagstudio/src/qt/modals/add_field.py
- tagstudio/src/qt/modals/delete_unlinked.py
- tagstudio/src/qt/modals/drop_import.py
- tagstudio/src/qt/modals/file_extension.py
- tagstudio/src/qt/modals/fix_dupes.py
- tagstudio/src/qt/modals/fix_unlinked.py
- tagstudio/src/qt/modals/folders_to_tags.py
- tagstudio/src/qt/modals/mirror_entities.py
- tagstudio/src/qt/widgets/paged_panel/paged_panel.py
- tagstudio/src/qt/widgets/panel.py
- tagstudio/src/qt/widgets/progress.py

Note that without adding # type: ignore, MyPy *will* give out an error,
presumably because PySide6 is missing type hints for several things, and
this may *or* may not be a justifiable use of # type: ignore, which
throws the MyPy type checking for that line out the window.

Ref: #392, #464

* fix: I forgot to run ruff format

* revert: changes to docs and gitignore

This revert is for moving the referenced changes to their own pull request.

Refs: 15f4f38, a25ef8c

* docs: other shells and pyenv in CONTRIBUTING.md

This commit changes CONTRIBUTING.md to refer to pyenv in the case of
issues with Python versions, as well as downloading the correct version
off of the Python website alternatively. It also now elaborates on the
process of running the Python virtual environment on Linux and macOS, by
referencing activation scripts for alternative shells such as fish and
CSH.

The table added to CONTRIBUTING.md is taken from the official Python
documentation: https://docs.python.org/3.12/library/venv.html

* revert: accidental inclution of #464

Refs: a51550f, 5854ccc
2025-02-06 21:41:01 -08:00

14 KiB

Contributing to TagStudio

Last Updated: January 30th, 2025

Thank you so much for showing interest in contributing to TagStudio! Here are a set of instructions and guidelines for contributing code or documentation to the project. This document will change over time, so make sure that your contributions still line up with the requirements here before submitting a pull request.

Getting Started

  • Check the Feature Roadmap page to see what priority features there are, the FAQ, as well as the open Issues and Pull Requests.
  • If you'd like to add a feature that isn't on the feature roadmap or doesn't have an open issue, PLEASE create a feature request issue for it discussing your intentions so any feedback or important information can be given by the team first.
    • We don't want you wasting time developing a feature or making a change that can't/won't be added for any reason ranging from pre-existing refactors to design philosophy differences.
  • Please don't create pull requests that consist of large refactors, especially without discussing them with us first. These end up doing more harm than good for the project by continuously delaying progress and disrupting everyone else's work.
  • If you wish to discuss TagStudio further, feel free to join the Discord Server

Contribution Checklist

Note

If the fix is small and self-explanatory (i.e. a typo), then it doesn't require an issue to be opened first. Issue tracking is supposed to make our lives easier, not harder. Please use your best judgement to minimize the amount of work involved for everyone involved.

Creating a Development Environment

Prerequisites

  • Python 3.12
  • Ruff (Included in requirements-dev.txt)
  • Mypy (Included in requirements-dev.txt)
  • PyTest (Included in requirements-dev.txt)

Creating a Python Virtual Environment

If you wish to launch the source version of TagStudio outside of your IDE:

Important

Depending on your system, Python may be called python, py, python3, or py3. These instructions use the alias python3 for consistency. You can check to see which alias your system uses and if it's for the correct Python version by typing python3 --version (or whichever alias) into your terminal.

Tip

On Linux and macOS, you can launch the tagstudio.sh script to skip the following process, minus the requirements-dev.txt installation step. Using the script is fine if you just want to launch the program from source.

  1. Make sure you're using the correct Python version:

    • If the output matches Python 3.12.x (where the x is any number) then you're using the correct Python version and can skip to step 2. Otherwise, you can install the correct Python version from the Python website, or you can use a tool like pyenv to install the correct version without changes to your system:
    1. Follow pyenv's install instructions for your system.
    2. Install the appropriate Python version with pyenv by running pyenv install 3.12 (This will not mess with your existing Python installation).
    3. Navigate to the repository root folder in your terminal and run pyenv local 3.12.
    • You could alternatively use pyenv shell 3.12 or pyenv global 3.12 instead to set the Python version for the current terminal session or the entire system respectively, however using local is recommended.
  2. In the root repository directory, create a python virtual environment:
    python3 -m venv .venv

  3. Activate your environment:

  • Windows w/Powershell: .venv\Scripts\Activate.ps1
  • Windows w/Command Prompt: .venv\Scripts\activate.bat
  • Linux/macOS: source .venv/bin/activate Depending on your system, the regular activation script might not work on alternative shells. In this case, refer to the table below for supported shells:
    Shell Script
    Bash/ZSH .venv/bin/activate
    Fish .venv/bin/activate.fish
    CSH/TCSH .venv/bin/activate.csh
    PWSH .venv/bin/activate.ps1
  1. Install the required packages:
  • pip install -r requirements.txt
  • If developing (includes Ruff and Mypy): pip install -r requirements-dev.txt

Learn more about setting up a virtual environment here.

Manually Launching (Outside of an IDE)

If you encounter errors about the Python version, or seemingly vague script errors, pyenv may solve your issue. See step 1 of Creating a Python Virtual Environment.

  • Windows (start_win.bat)

    • To launch TagStudio, launch the start_win.bat file. You can modify this .bat file or create a shortcut and add one or more additional arguments if desired.
  • Linux/macOS (TagStudio.sh)

    • Run the "TagStudio.sh" script and the program should launch! (Make sure that the script is marked as executable if on Linux). Note that launching from the script from outside of a terminal will not launch a terminal window with any debug or crash information. If you wish to see this information, just launch the shell script directly from your terminal with ./TagStudio.sh.

    • NixOS (Nix Flake)

      • Use the provided Flake to create and enter a working environment by running nix develop. Then, run the program via python3 tagstudio/tag_studio.py from the root directory.

Warning

Support for NixOS is still a work in progress.

  • Any (No Scripts)

    • Alternatively, with the virtual environment loaded, run the python file at tagstudio\tag_studio.py from your terminal. If you're in the project's root directory, simply run python3 tagstudio/tag_studio.py.

Workflow Checks

When pushing your code, several automated workflows will check it against predefined tests and style checks. It's highly recommended that you run these checks locally beforehand to avoid having to fight back-and-forth with the workflow checks inside your pull requests.

Tip

To format the code automatically before each commit, there's a configured action available for the pre-commit hook. Install it by running pre-commit install. The hook will be executed each time on running git commit.

Ruff

A Python linter and code formatter. Ruff uses the pyproject.toml as its config file and runs whenever code is pushed or pulled into the project.

Running Locally

Inside the root repository directory:

  • Lint code with ruff check
    • Some linting suggestions can be automatically formatted with ruff check --fix
  • Format code with ruff format

Ruff should automatically discover the configuration options inside the pyproject.toml file. For more information, see the ruff configuration discovery docs.

Ruff is also available as a VS Code extension, PyCharm plugin, and more.

Mypy

Mypy is a static type checker for Python. It sure has a lot to say sometimes, but we recommend you take its advice when possible. Mypy also uses the pyproject.toml as its config file and runs whenever code is pushed or pulled into the project.

Running Locally

  • First time only: Move into the /tagstudio directory with cd tagstudio and run the following:
    • mkdir -p .mypy_cache
    • mypy --install-types --non-interactive
  • Check code by moving into the /tagstudio directory with cd tagstudio (if you aren't already inside) and running mypy --config-file ../pyproject.toml .. (Don't forget the . at the end!)

Mypy is also available as a VS Code extension, PyCharm plugin, and more.

PyTest

  • Run all tests by moving into the /tagstudio directory with cd tagstudio and running pytest tests/.

Code Style

Most of the style guidelines can be checked, fixed, and enforced via Ruff. Older code may not be adhering to all of these guidelines, in which case "do as I say, not as I do"...

  • Do your best to write clear, concise, and modular code.
  • Keep a maximum column with of no more than 100 characters.
  • Code comments should be used to help describe sections of code that can't speak for themselves.
  • Use Google style docstrings for any classes and functions you add.
    • If you're modifying an existing function that does not have docstrings, you don't have to add docstrings to it... but it would be pretty cool if you did ;)
  • Imports should be ordered alphabetically.
  • Lists of values should be ordered using their natural sort order.
    • Some files have their methods ordered alphabetically as well (i.e. thumb_renderer). If you're working in a file and notice this, please try and keep to the pattern.
  • When writing text for window titles or form titles, use "Title Case" capitalization. Your IDE may have a command to format this for you automatically, although some may incorrectly capitalize short prepositions. In a pinch you can use a website such as capitalizemytitle.com to check.
  • If it wasn't mentioned above, then stick to PEP-8!

Modules & Implementations

  • Do not modify legacy library code in the src/core/library/json/ directory
  • Avoid direct calls to os
    • Use Pathlib library instead of os.path
    • Use platform.system() instead of os.name and sys.platform
  • Don't prepend local imports with tagstudio, stick to src
  • Use the logger system instead of print statements
  • Avoid nested f-strings
  • Use HTML-like tags inside Qt widgets over stylesheets where possible

Commit and Pull Request Style

  • Use Conventional Commits as a guideline for commit messages. This allows us to easily generate changelogs for releases.
    • See some examples of what this looks like in practice.
  • Use clear and concise commit messages. If your commit does too much, either consider breaking it up into smaller commits or providing extra detail in the commit description.
  • Pull requests should have an adequate title and description which clearly outline your intentions and changes/additions. Feel free to provide screenshots, GIFs, or videos, especially for UI changes.
  • Pull requests should ideally be limited to a single feature or fix.

Important

Please do not force push if your PR is open for review!

Force pushing makes it impossible to discern which changes have already been reviewed and which haven't. This means a reviewer will then have to rereview all the already reviewed code, which is a lot of unnecessary work for reviewers.

Tip

If you're unsure where to stop the scope of your PR, ask yourself: "If I broke this up, could any parts of it still be used by the project in the meantime?"

Runtime Requirements

  • Final code must function on supported versions of Windows, macOS, and Linux:
    • Windows: 10, 11
    • macOS: 12.0+
    • Linux: Varies
  • Final code must NOT:
    • Contain superfluous or unnecessary logging statements
    • Cause unreasonable slowdowns to the program outside of a progress-indicated task
    • Cause undesirable visual glitches or artifacts on screen

Documentation Guidelines

Documentation contributions include anything inside of the docs/ folder, as well as the README.md and CONTRIBUTING.md files. Documentation inside the docs/ folder is built and hosted on our static documentation site, docs.tagstud.io.

  • Use "snake_case" for file and folder names
  • Follow the folder structure pattern
  • Don't add images or other media with excessively large file sizes
  • Provide alt text for all embedded media
  • Use "Title Case" for title capitalization

Translation Guidelines

Translations are performed on the TagStudio Weblate project.

Translation guidelines coming soon.