0

I have recently created a GitHub Actions workflow to lint/reformat the code of my repo and create documentation HTML pages using pdoc. The last step is problematic, because pdoc runs the .py files to create the documentation. For one of the files (file.py) the ServiceNow ODBC driver needs to be set up and it's unfeasible to do on every workflow. That is why I decided to try using pdoc with pre-commit. Locally the pdoc command only works if pdoc is in the same directory as file.py, that is why a virtual env has to be activated before running the command

My configuration is Windows 10 and Python 3.9. These are the commands:

.\env\Scripts\activate
pdoc ./file.py -o ./docs

This is the .pre-commit-config.yaml I tried:


repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
    -   id: check-yaml

-   repo: local
    hooks:
    - id: env
      name: Activate env
      language: system
      entry: .\env\Scripts\activate

-   repo: local
    hooks:
    - id: pdoc
      name: Run pdoc
      language: system
      entry: pdoc ./file.py -o ./docs


# Output:

check yaml...............................................................Passed
Activate env.............................................................Failed
- hook id: env
- exit code: 1
Executable `.envScriptsactivate` not found
Run pdoc.................................................................Failed
- hook id: pdoc
- exit code: 1
Executable `pdoc` not found

This may not be intuitive use of pre-commit, but I need a way to run the pdoc commands before every commit. This is intended for use inside the same organization, so the set up will be the same on every device.

Edit 1: I tried one of the suggestions from anthony sottile, but there are still some errors because of unexpected arguments.

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
    -   id: check-yaml

-   repo: local
    hooks:
    - id: env
      name: Activate env
      language: system
      entry: ./env/Scripts/pdoc.exe file.py -o ./packages

# Output:

check yaml...............................................................Passed
Activate env.............................................................Failed
- hook id: env
- exit code: 2
usage: pdoc.exe [-o DIR] [-d {markdown,google,numpy,restructuredtext}]
                [-e module=url] [--favicon URL] [--footer-text TEXT]
                [--logo URL] [--logo-link URL] [--math | --no-math]
                [--search | --no-search] [--show-source | --no-show-source]
                [-t DIR] [-h HOST] [-p PORT] [-n] [--help] [--version]
                [module ...]
pdoc.exe: error: unrecognized arguments: .idea/misc.xml .idea/inspectionProfiles/profiles_settings.xml .pre-commit-config.yaml file.py
jordp1
  • 1
  • 3
  • Since you tagged this with `github-actions`, it's also worth pointing out that pdoc has a tutorial for building docs as part of CI and pushing them to GitHub Pages: https://pdoc.dev/docs/pdoc.html#deploying-to-github-pages – Maximilian Hils Dec 27 '22 at 12:18
  • @MaximilianHils I already tried running it like in the example in the pdoc documentation and it worked for most of my Python files. Some files need to use the ServiceNow ODBC driver, which I can't setup in github actions and only runs locally. That means those files would be left out of the automatic documentation. Since you're involved with making pdoc, do you think it would be possible to add an option to create documentation even if there are errors running the code? Or maybe to create a pre-commit hook for pdoc? – jordp1 Jan 04 '23 at 11:20
  • pdoc has a strong focus on simplicity, so it's unlikely that I will add an additional option for this. The best (dare I say correct) approach here is to install dependencies in CI. If that's really not possible you could write a small Python script that mocks them and then uses pdoc as a library. – Maximilian Hils Jan 04 '23 at 15:08

2 Answers2

0

"activating" a virtualenv is simply prepending PATH (and VIRTUAL_ENV, though this usually doesn't do anything)

the activate script isn't something you execute, it's something you source as it has to modify the shell environment

fortunately, you don't need to actually source it -- you can just run the executable as normal

you've got a couple options -- the first is to access the executable directly:

        entry: venv\Scripts\pdoc -o docs

this is kind of a bad idea though as it's non-portable -- Scripts is only a thing on windows

a better option would be to assume it's already on the PATH and put nothing in your pre-commit configuration:

        entry: pdoc -o docs

and then add to the PATH in your github actions steps:

    - run: echo "$PWD/venv/Scripts" >> "$GITHUB_PATH"
      shell: bash

even this isn't great because it means you always need to have pdoc on the PATH when working locally (meaning you can't commit without your virtualenv activated). this kind of goes against the design of pre-commit where it manages your tools so you don't have to. you may be able to use additional_dependencies to install pdoc such that you don't need to depend on the state of things that are installed -- but I suspect pdoc needs the rest of your dependencies to properly generate its output -- this usually is an indicator that what you're trying to do isn't a good fit for pre-commit in the first place


disclaimer: I wrote pre-commit

anthony sottile
  • 61,815
  • 15
  • 148
  • 207
  • Thank you for the quick and detailed answer! I tried one of your suggestions as you can see in the edit. But in general I agree that it might not be a good fit for pre-commit. Do you know a more appropriate method to achieve my goal of running pdoc locally with every commit? – jordp1 Dec 21 '22 at 15:37
  • well your next step would be to read the documentation about _why_ you're getting extra files and [how to control that behaviour](https://pre-commit.com/#hooks-pass_filenames) – anthony sottile Dec 21 '22 at 16:08
  • I changed pass_filenames to false and it worked, thank you! – jordp1 Dec 22 '22 at 10:00
0

With the suggestions of anthony sottile the following changes to the .pre-commit-config.yaml worked for me:

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
    -   id: check-yaml

-   repo: local
    hooks:
    - id: env
      name: Activate env
      language: system
      pass_filenames: false
      entry: ./env/Scripts/pdoc.exe ./file.py -o ./packages
jordp1
  • 1
  • 3