2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-26 18:46:44 +00:00

feat(backend): improve tag docs (#8960)

* add admindocs

* add tag export command

* add filter export

* switch to yaml

* upload meta info to artifacts

* format workflow file

* fix creation command

* keep all artifacts in schema repo

* fix namespace

* use one command for export

* include tags and filters in docs

* change default filename

* fix call

* fix itteration syntax

* clean up rendering

* fix formatting

* simple escape
This commit is contained in:
Matthias Mair 2025-01-27 23:42:13 +01:00 committed by GitHub
parent 16b03a7371
commit f7f6e27c6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 216 additions and 9 deletions

View File

@ -170,9 +170,9 @@ jobs:
id: breaking_changes
uses: oasdiff/oasdiff-action/diff@1c611ffb1253a72924624aa4fb662e302b3565d3 # pin@main
with:
base: 'api.yaml'
revision: 'src/backend/InvenTree/schema.yml'
format: 'html'
base: "api.yaml"
revision: "src/backend/InvenTree/schema.yml"
format: "html"
- name: Echoing diff to step
env:
DIFF: ${{ steps.breaking_changes.outputs.diff }}
@ -194,6 +194,23 @@ jobs:
version="$(python3 .github/scripts/version_check.py only_version 2>&1)"
echo "Version: $version"
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Extract settings / tags
run: invoke int.export-definitions
- name: Upload settings
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # pin@v4.6.0
with:
name: inventree_settings.json
path: src/backend/InvenTree/inventree_settings.json
- name: Upload tags
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # pin@v4.6.0
with:
name: inventree_tags.yml
path: src/backend/InvenTree/inventree_tags.yml
- name: Upload filters
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # pin@v4.6.0
with:
name: inventree_filters.yml
path: src/backend/InvenTree/inventree_filters.yml
schema-push:
name: Push new schema
@ -210,15 +227,20 @@ jobs:
repository: inventree/schema
token: ${{ secrets.SCHEMA_PAT }}
persist-credentials: true
- name: Create artifact directory
run: mkdir -p artifact
- name: Download schema artifact
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # pin@v4.1.8
with:
name: schema.yml
- name: Move schema to correct location
path: artifact
- name: Move files to correct location
run: |
echo "Version: $version"
mkdir export/${version}
mv schema.yml export/${version}/api.yaml
mv artifact/schema.yml export/${version}/api.yaml
mv artifact/inventree_settings.json export/${version}/inventree_settings.json
mv artifact/inventree_tags.yml export/${version}/inventree_tags.yml
mv artifact/inventree_filters.yml export/${version}/inventree_filters.yml
- uses: stefanzweifel/git-auto-commit-action@e348103e9026cc0eee72ae06630dbe30c8bf7a79 # pin@v5.1.0
name: Commit schema changes
with:
@ -518,7 +540,6 @@ jobs:
chmod +rw /home/runner/work/InvenTree/db.sqlite3
invoke migrate
platform_ui:
name: Tests - Platform UI
runs-on: ubuntu-20.04
@ -609,7 +630,7 @@ jobs:
zizmor:
name: Security [Zizmor]
runs-on: ubuntu-20.04
needs: ['pre-commit', 'paths-filter']
needs: ["pre-commit", "paths-filter"]
if: needs.paths-filter.outputs.cicd == 'true' || needs.paths-filter.outputs.force == 'true'
permissions:

View File

@ -512,3 +512,9 @@ A [Part Parameter](../part/parameter.md) has the following available attributes:
| Data | The *value* of the parameter (e.g. "123.4") |
| Units | The *units* of the parameter (e.g. "km") |
| Template | A reference to a [PartParameterTemplate](../part/parameter.md#parameter-templates) |
## List of tags and filters
The following tags and filters are available.
{{ tags_and_filters() }}

View File

@ -31,6 +31,8 @@ for key in [
# Cached settings dict values
global GLOBAL_SETTINGS
global USER_SETTINGS
global TAGS
global FILTERS
# Read in the InvenTree settings file
here = os.path.dirname(__file__)
@ -42,6 +44,13 @@ with open(settings_file, encoding='utf-8') as sf:
GLOBAL_SETTINGS = settings['global']
USER_SETTINGS = settings['user']
# Tags
with open(os.path.join(here, 'inventree_tags.yml'), encoding='utf-8') as f:
TAGS = yaml.load(f, yaml.BaseLoader)
# Filters
with open(os.path.join(here, 'inventree_filters.yml'), encoding='utf-8') as f:
FILTERS = yaml.load(f, yaml.BaseLoader)
def get_repo_url(raw=False):
"""Return the repository URL for the current project."""
@ -303,3 +312,25 @@ def define_env(env):
setting = USER_SETTINGS[key]
return rendersetting(key, setting)
@env.macro
def tags_and_filters():
"""Return a list of all tags and filters."""
global TAGS
global FILTERS
ret_data = ''
for ref in [['Tags', TAGS], ['Filters', FILTERS]]:
ret_data += f'### {ref[0]}\n\n| Namespace | Name | Description |\n| --- | --- | --- |\n'
for value in ref[1]:
title = (
value['title']
.replace('\n', ' ')
.replace('<', '&lt;')
.replace('>', '&gt;')
)
ret_data += f'| {value["library"]} | {value["name"]} | {title} |\n'
ret_data += '\n'
ret_data += '\n'
return ret_data

View File

@ -17,6 +17,6 @@ build:
- echo "Generating API schema file"
- pip install -U invoke
- invoke migrate
- invoke int.export-settings-definitions --filename docs/inventree_settings.json --overwrite
- invoke int.export-definitions --basedir "docs"
- invoke dev.schema --filename docs/schema.yml --ignore-warnings
- python docs/extract_schema.py docs/schema.yml

View File

@ -0,0 +1,58 @@
"""Custom management command to export all filters.
This is used to generate a YAML file which contains all of the filters available in InvenTree.
"""
from django.contrib.admindocs import utils
from django.core.exceptions import ImproperlyConfigured
from django.core.management.base import BaseCommand
from django.template.engine import Engine
import yaml
class Command(BaseCommand):
"""Extract filter information, and export to a YAML file."""
def add_arguments(self, parser):
"""Add custom arguments for this command."""
parser.add_argument(
'filename', type=str, help='Output filename for filter definitions'
)
def handle(self, *args, **kwargs):
"""Export filter information to a YAML file."""
filters = discover_filters()
# Write
filename = kwargs.get('filename', 'inventree_filters.yml')
with open(filename, 'w', encoding='utf-8') as f:
yaml.dump(filters, f, indent=4)
print(f"Exported InvenTree filter definitions to '{filename}'")
def discover_filters():
"""Discover all available filters.
This function is a copy of a function from the Django 'admindocs' module in django.contrib.admindocs.views.TemplateFilterIndexView
"""
filters = []
try:
engine = Engine.get_default()
except ImproperlyConfigured:
# Non-trivial TEMPLATES settings aren't supported (#24125).
pass
else:
app_libs = sorted(engine.template_libraries.items())
builtin_libs = [('', lib) for lib in engine.template_builtins]
for module_name, library in builtin_libs + app_libs:
for filter_name, filter_func in library.filters.items():
title, body, metadata = utils.parse_docstring(filter_func.__doc__)
tag_library = module_name.split('.')[-1]
filters.append({
'name': filter_name,
'title': title,
'body': body,
'meta': metadata,
'library': tag_library,
})
return filters

View File

@ -0,0 +1,59 @@
"""Custom management command to export all tags.
This is used to generate a YAML file which contains all of the tags available in InvenTree.
"""
from django.contrib.admindocs import utils
from django.core.exceptions import ImproperlyConfigured
from django.core.management.base import BaseCommand
from django.template.engine import Engine
import yaml
class Command(BaseCommand):
"""Extract tag information, and export to a YAML file."""
def add_arguments(self, parser):
"""Add custom arguments for this command."""
parser.add_argument(
'filename', type=str, help='Output filename for tag definitions'
)
def handle(self, *args, **kwargs):
"""Export tag information to a YAML file."""
tags = discover_tags()
# Write
filename = kwargs.get('filename', 'inventree_tags.yml')
with open(filename, 'w', encoding='utf-8') as f:
yaml.dump(tags, f, indent=4)
print(f"Exported InvenTree tag definitions to '{filename}'")
def discover_tags():
"""Discover all available tags.
This function is a copy of a function from the Django 'admindocs' module in django.contrib.admindocs.views.TemplateTagIndexView
"""
tags = []
try:
engine = Engine.get_default()
except ImproperlyConfigured:
# Non-trivial TEMPLATES settings aren't supported (#24125).
pass
else:
app_libs = sorted(engine.template_libraries.items())
builtin_libs = [('', lib) for lib in engine.template_builtins]
for module_name, library in builtin_libs + app_libs:
for tag_name, tag_func in library.tags.items():
title, body, metadata = utils.parse_docstring(tag_func.__doc__)
tag_library = module_name.split('.')[-1]
tags.append({
'name': tag_name,
'title': title,
'body': body,
'meta': metadata,
'library': tag_library,
})
return tags

View File

@ -255,6 +255,7 @@ INVENTREE_ADMIN_URL = get_setting(
INSTALLED_APPS = [
# Admin site integration
'django.contrib.admin',
'django.contrib.admindocs',
# InvenTree apps
'build.apps.BuildConfig',
'common.apps.CommonConfig',

View File

@ -188,6 +188,7 @@ if settings.INVENTREE_ADMIN_ENABLED:
urlpatterns += [
path(f'{admin_url}/error_log/', include('error_report.urls')),
path(f'{admin_url}/doc/', include('django.contrib.admindocs.urls')),
path(f'{admin_url}/', admin.site.urls, name='inventree-admin'),
]

View File

@ -33,6 +33,7 @@ djangorestframework-simplejwt[crypto] # JWT authentication
django-xforwardedfor-middleware # IP forwarding metadata
dj-rest-auth==7.0.0 # Authentication API endpoints # FIXED 2024-12-22 due to https://github.com/inventree/InvenTree/issues/8707
dulwich # pure Python git integration
docutils # Documentation utilities for auto admin docs
drf-spectacular # DRF API documentation
feedparser # RSS newsfeed parser
gunicorn # Gunicorn web server

View File

@ -546,6 +546,10 @@ djangorestframework-simplejwt[crypto]==5.4.0 \
--hash=sha256:7aec953db9ed4163430c16d086eecb0f028f814ce6bba62b06c25919261e9077 \
--hash=sha256:cccecce1a0e1a4a240fae80da73e5fc23055bababb8b67de88fa47cd36822320
# via -r src/backend/requirements.in
docutils==0.21.2 \
--hash=sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f \
--hash=sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2
# via -r src/backend/requirements.in
drf-spectacular==0.28.0 \
--hash=sha256:2c778a47a40ab2f5078a7c42e82baba07397bb35b074ae4680721b2805943061 \
--hash=sha256:856e7edf1056e49a4245e87a61e8da4baff46c83dbc25be1da2df77f354c7cb4

View File

@ -1194,6 +1194,30 @@ def export_settings_definitions(c, filename='inventree_settings.json', overwrite
manage(c, f'export_settings_definitions {filename}', pty=True)
@task(help={'basedir': 'Export to a base directory (default = False)'})
def export_definitions(c, basedir: str = ''):
"""Export various definitions."""
if basedir != '' and basedir.endswith('/') is False:
basedir += '/'
filenames = [
Path(basedir + 'inventree_settings.json').resolve(),
Path(basedir + 'inventree_tags.yml').resolve(),
Path(basedir + 'inventree_filters.yml').resolve(),
]
info('Exporting definitions...')
export_settings_definitions(c, overwrite=True, filename=filenames[0])
check_file_existence(filenames[1], overwrite=True)
manage(c, f'export_tags {filenames[1]}', pty=True)
check_file_existence(filenames[2], overwrite=True)
manage(c, f'export_filters {filenames[2]}', pty=True)
info('Exporting definitions complete')
@task(default=True)
def version(c):
"""Show the current version of InvenTree."""
@ -1584,6 +1608,7 @@ internal = Collection(
clean_settings,
clear_generated,
export_settings_definitions,
export_definitions,
frontend_build,
frontend_check,
frontend_compile,