mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	Merge pull request #1433 from SchrodingersGat/coverage-workflow
Add workflow for code coverage
This commit is contained in:
		
							
								
								
									
										46
									
								
								.github/workflows/coverage.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								.github/workflows/coverage.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | # Perform CI checks, and calculate code coverage | ||||||
|  |  | ||||||
|  | name: SQLite | ||||||
|  |  | ||||||
|  | on: ["push", "pull_request"] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |  | ||||||
|  |   # Run tests on SQLite database | ||||||
|  |   # These tests are used for code coverage analysis | ||||||
|  |   coverage: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |  | ||||||
|  |     env: | ||||||
|  |       GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |       INVENTREE_DB_NAME: './test_db.sqlite' | ||||||
|  |       INVENTREE_DB_ENGINE: django.db.backends.sqlite3 | ||||||
|  |       INVENTREE_DEBUG: info | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout Code | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - name: Setup Python | ||||||
|  |         uses: actions/setup-python@v2 | ||||||
|  |         with: | ||||||
|  |           python-version: 3.7 | ||||||
|  |       - name: Install Dependencies | ||||||
|  |         run: | | ||||||
|  |           sudo apt-get update | ||||||
|  |           pip3 install invoke | ||||||
|  |           invoke install | ||||||
|  |       - name: Coverage Tests | ||||||
|  |         run: | | ||||||
|  |           invoke coverage | ||||||
|  |       - name: Data Import Export | ||||||
|  |         run: | | ||||||
|  |           invoke migrate | ||||||
|  |           invoke import-fixtures | ||||||
|  |           invoke export-records -f data.json | ||||||
|  |           rm test_db.sqlite | ||||||
|  |           invoke migrate | ||||||
|  |           invoke import-records -f data.json | ||||||
|  |       - name: Check Migration Files | ||||||
|  |         run: python3 ci/check_migration_files.py | ||||||
|  |       - name: Upload Coverage Report | ||||||
|  |         run: coveralls | ||||||
							
								
								
									
										46
									
								
								.github/workflows/mariadb.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								.github/workflows/mariadb.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | name: MariaDB | ||||||
|  |  | ||||||
|  | on: ["push", "pull_request"] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |  | ||||||
|  |   test: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |  | ||||||
|  |     env: | ||||||
|  |       # Database backend configuration | ||||||
|  |       INVENTREE_DB_ENGINE: django.db.backends.mysql | ||||||
|  |       INVENTREE_DB_NAME: inventree | ||||||
|  |       INVENTREE_DB_USER: root | ||||||
|  |       INVENTREE_DB_PASSWORD: password | ||||||
|  |       INVENTREE_DB_HOST: '127.0.0.1' | ||||||
|  |       INVENTREE_DB_PORT: 3306 | ||||||
|  |       INVENTREE_DEBUG: info | ||||||
|  |  | ||||||
|  |     services: | ||||||
|  |       mariadb: | ||||||
|  |         image: mariadb:latest | ||||||
|  |         env: | ||||||
|  |           MYSQL_ALLOW_EMPTY_PASSWORD: yes | ||||||
|  |           MYSQL_DATABASE: inventree | ||||||
|  |           MYSQL_USER: inventree | ||||||
|  |           MYSQL_PASSWORD: password | ||||||
|  |           MYSQL_ROOT_PASSWORD: password | ||||||
|  |         ports: | ||||||
|  |           - 3306:3306 | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout Code | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - name: Setup Python | ||||||
|  |         uses: actions/setup-python@v2 | ||||||
|  |         with: | ||||||
|  |           python-version: 3.7 | ||||||
|  |       - name: Install Dependencies | ||||||
|  |         run: | | ||||||
|  |           sudo apt-get install mysql-server libmysqlclient-dev | ||||||
|  |           pip3 install invoke | ||||||
|  |           pip3 install mysqlclient | ||||||
|  |           invoke install | ||||||
|  |       - name: Run Tests | ||||||
|  |         run: invoke test | ||||||
							
								
								
									
										49
									
								
								.github/workflows/mysql.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								.github/workflows/mysql.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | # MySQL Unit Testing | ||||||
|  |  | ||||||
|  | name: MySQL | ||||||
|  |  | ||||||
|  | on: ["push", "pull_request"] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |  | ||||||
|  |   test: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |  | ||||||
|  |     env: | ||||||
|  |       # Database backend configuration | ||||||
|  |       INVENTREE_DB_ENGINE: django.db.backends.mysql | ||||||
|  |       INVENTREE_DB_NAME: inventree | ||||||
|  |       INVENTREE_DB_USER: root | ||||||
|  |       INVENTREE_DB_PASSWORD: password | ||||||
|  |       INVENTREE_DB_HOST: '127.0.0.1' | ||||||
|  |       INVENTREE_DB_PORT: 3306 | ||||||
|  |       INVENTREE_DEBUG: info | ||||||
|  |  | ||||||
|  |     services: | ||||||
|  |       mysql: | ||||||
|  |         image: mysql:latest | ||||||
|  |         env: | ||||||
|  |           MYSQL_ALLOW_EMPTY_PASSWORD: yes | ||||||
|  |           MYSQL_DATABASE: inventree | ||||||
|  |           MYSQL_USER: inventree | ||||||
|  |           MYSQL_PASSWORD: password | ||||||
|  |           MYSQL_ROOT_PASSWORD: password | ||||||
|  |         options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 | ||||||
|  |         ports: | ||||||
|  |           - 3306:3306 | ||||||
|  |        | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout Code | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - name: Setup Python | ||||||
|  |         uses: actions/setup-python@v2 | ||||||
|  |         with: | ||||||
|  |           python-version: 3.7 | ||||||
|  |       - name: Install Dependencies | ||||||
|  |         run: | | ||||||
|  |           sudo apt-get install mysql-server libmysqlclient-dev | ||||||
|  |           pip3 install invoke | ||||||
|  |           pip3 install mysqlclient | ||||||
|  |           invoke install | ||||||
|  |       - name: Run Tests | ||||||
|  |         run: invoke test | ||||||
							
								
								
									
										45
									
								
								.github/workflows/postgresql.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								.github/workflows/postgresql.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | # PostgreSQL Unit Testing | ||||||
|  |  | ||||||
|  | name: PostgreSQL | ||||||
|  |  | ||||||
|  | on: ["push", "pull_request"] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |    | ||||||
|  |   test: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |  | ||||||
|  |     env: | ||||||
|  |       # Database backend configuration | ||||||
|  |       INVENTREE_DB_ENGINE: django.db.backends.postgresql | ||||||
|  |       INVENTREE_DB_NAME: inventree | ||||||
|  |       INVENTREE_DB_USER: inventree | ||||||
|  |       INVENTREE_DB_PASSWORD: password | ||||||
|  |       INVENTREE_DB_HOST: '127.0.0.1' | ||||||
|  |       INVENTREE_DB_PORT: 5432 | ||||||
|  |       INVENTREE_DEBUG: info | ||||||
|  |  | ||||||
|  |     services: | ||||||
|  |       postgres: | ||||||
|  |         image: postgres | ||||||
|  |         env: | ||||||
|  |           POSTGRES_USER: inventree | ||||||
|  |           POSTGRES_PASSWORD: password | ||||||
|  |         ports: | ||||||
|  |           - 5432:5432 | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout Code | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - name: Setup Python | ||||||
|  |         uses: actions/setup-python@v2 | ||||||
|  |         with: | ||||||
|  |           python-version: 3.7 | ||||||
|  |       - name: Install Dependencies | ||||||
|  |         run: | | ||||||
|  |           sudo apt-get install libpq-dev | ||||||
|  |           pip3 install invoke | ||||||
|  |           pip3 install psycopg2 | ||||||
|  |           invoke install | ||||||
|  |       - name: Run Tests | ||||||
|  |         run: invoke test | ||||||
							
								
								
									
										8
									
								
								.github/workflows/style.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/style.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -1,10 +1,6 @@ | |||||||
| name: Style Checks | name: Style Checks | ||||||
|  |  | ||||||
| on: | on: ["push", "pull_request"] | ||||||
|   push: |  | ||||||
|     branches: [ $default-branch ] |  | ||||||
|   pull_request: |  | ||||||
|     branches: [ $default-branch ] |  | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   style: |   style: | ||||||
| @@ -26,4 +22,6 @@ jobs: | |||||||
|         run: | |         run: | | ||||||
|           pip install flake8==3.8.3 |           pip install flake8==3.8.3 | ||||||
|           pip install pep8-naming==0.11.1 |           pip install pep8-naming==0.11.1 | ||||||
|  |       - name: flake8 | ||||||
|  |         run: | | ||||||
|           flake8 InvenTree |           flake8 InvenTree | ||||||
|   | |||||||
							
								
								
									
										53
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -1,53 +0,0 @@ | |||||||
| dist: xenial |  | ||||||
|  |  | ||||||
| services: |  | ||||||
|     - mysql |  | ||||||
|     - postgresql |  | ||||||
|  |  | ||||||
| language: python |  | ||||||
| python: |  | ||||||
|     - 3.6 |  | ||||||
|     - 3.7 |  | ||||||
|  |  | ||||||
| addons: |  | ||||||
|     apt-packages: |  | ||||||
|         - sqlite3 |  | ||||||
|  |  | ||||||
| before_install: |  | ||||||
|     - sudo apt-get update |  | ||||||
|     - sudo apt-get install gettext |  | ||||||
|     - sudo apt-get install mysql-server libmysqlclient-dev |  | ||||||
|     - sudo apt-get install libpq-dev |  | ||||||
|     - pip3 install invoke |  | ||||||
|     - pip3 install mysqlclient |  | ||||||
|     - pip3 install psycopg2 |  | ||||||
|     - invoke install |  | ||||||
|     - invoke migrate |  | ||||||
|     - cd InvenTree && python3 manage.py createsuperuser --username InvenTreeAdmin --email admin@inventree.com --noinput && cd .. |  | ||||||
|     - psql -c 'create database inventree_test_db;' -U postgres |  | ||||||
|     - mysql -e 'CREATE DATABASE inventree_test_db;' |  | ||||||
|  |  | ||||||
| script: |  | ||||||
|     - cd InvenTree && python3 manage.py makemigrations && cd .. |  | ||||||
|     - python3 ci/check_migration_files.py |  | ||||||
|     # Run unit testing / code coverage tests |  | ||||||
|     - invoke coverage |  | ||||||
|     # Run unit test for SQL database backend |  | ||||||
|     - cd InvenTree && python3 manage.py test --settings=InvenTree.ci_mysql && cd .. |  | ||||||
|     # Run unit test for PostgreSQL database backend |  | ||||||
|     - cd InvenTree && python3 manage.py test --settings=InvenTree.ci_postgresql && cd .. |  | ||||||
|     - invoke translate |  | ||||||
|     - invoke style |  | ||||||
|     # Create an empty database and fill it with test data |  | ||||||
|     - rm inventree_default_db.sqlite3 |  | ||||||
|     - invoke migrate |  | ||||||
|     - invoke import-fixtures |  | ||||||
|     # Export database records |  | ||||||
|     - invoke export-records -f data.json |  | ||||||
|     # Create a new empty database and import the saved data |  | ||||||
|     - rm inventree_default_db.sqlite3 |  | ||||||
|     - invoke migrate |  | ||||||
|     - invoke import-records -f data.json |  | ||||||
|  |  | ||||||
| after_success: |  | ||||||
|     - coveralls |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| """ |  | ||||||
| Configuration file for running tests against a MySQL database. |  | ||||||
| """ |  | ||||||
|  |  | ||||||
| from InvenTree.settings import * |  | ||||||
|  |  | ||||||
| # Override the 'test' database |  | ||||||
| if 'test' in sys.argv: |  | ||||||
|     print('InvenTree: Running tests - Using MySQL test database') |  | ||||||
|      |  | ||||||
|     DATABASES['default'] = { |  | ||||||
|         # Ensure mysql backend is being used |  | ||||||
|         'ENGINE': 'django.db.backends.mysql', |  | ||||||
|         'NAME': 'inventree_test_db', |  | ||||||
|         'USER': 'travis', |  | ||||||
|         'PASSWORD': '', |  | ||||||
|         'HOST': '127.0.0.1' |  | ||||||
|     } |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| """ |  | ||||||
| Configuration file for running tests against a MySQL database. |  | ||||||
| """ |  | ||||||
|  |  | ||||||
| from InvenTree.settings import * |  | ||||||
|  |  | ||||||
| # Override the 'test' database |  | ||||||
| if 'test' in sys.argv: |  | ||||||
|     print('InvenTree: Running tests - Using PostGreSQL test database') |  | ||||||
|      |  | ||||||
|     DATABASES['default'] = { |  | ||||||
|         # Ensure postgresql backend is being used |  | ||||||
|         'ENGINE': 'django.db.backends.postgresql', |  | ||||||
|         'NAME': 'inventree_test_db', |  | ||||||
|         'USER': 'postgres', |  | ||||||
|         'PASSWORD': '', |  | ||||||
|     } |  | ||||||
| @@ -319,83 +319,68 @@ MARKDOWNIFY_BLEACH = False | |||||||
| DATABASES = {} | DATABASES = {} | ||||||
|  |  | ||||||
| """ | """ | ||||||
| When running unit tests, enforce usage of sqlite3 database, | Configure the database backend based on the user-specified values. | ||||||
| so that the tests can be run in RAM without any setup requirements |  | ||||||
|  | - Primarily this configuration happens in the config.yaml file | ||||||
|  | - However there may be reason to configure the DB via environmental variables | ||||||
|  | - The following code lets the user "mix and match" database configuration | ||||||
| """ | """ | ||||||
| if 'test' in sys.argv: |  | ||||||
|     logger.info('InvenTree: Running tests - Using sqlite3 memory database') |  | ||||||
|     DATABASES['default'] = { |  | ||||||
|         # Ensure sqlite3 backend is being used |  | ||||||
|         'ENGINE': 'django.db.backends.sqlite3', |  | ||||||
|         # Doesn't matter what the database is called, it is executed in RAM |  | ||||||
|         'NAME': 'ram_test_db.sqlite3', |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| # Database backend selection | logger.info("Configuring database backend:") | ||||||
| else: |  | ||||||
|     """ |  | ||||||
|     Configure the database backend based on the user-specified values. |  | ||||||
|      |  | ||||||
|     - Primarily this configuration happens in the config.yaml file |  | ||||||
|     - However there may be reason to configure the DB via environmental variables |  | ||||||
|     - The following code lets the user "mix and match" database configuration |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|     logger.info("Configuring database backend:") | # Extract database configuration from the config.yaml file | ||||||
|  | db_config = CONFIG.get('database', {}) | ||||||
|  |  | ||||||
|     # Extract database configuration from the config.yaml file | # Environment variables take preference over config file! | ||||||
|     db_config = CONFIG.get('database', {}) |  | ||||||
|  |  | ||||||
|     # If a particular database option is not specified in the config file, | db_keys = ['ENGINE', 'NAME', 'USER', 'PASSWORD', 'HOST', 'PORT'] | ||||||
|     # look for it in the environmental variables |  | ||||||
|     # e.g. INVENTREE_DB_NAME / INVENTREE_DB_USER / etc |  | ||||||
|  |  | ||||||
|     db_keys = ['ENGINE', 'NAME', 'USER', 'PASSWORD', 'HOST', 'PORT'] | for key in db_keys: | ||||||
|  |     # First, check the environment variables | ||||||
|  |     env_key = f"INVENTREE_DB_{key}" | ||||||
|  |     env_var = os.environ.get(env_key, None) | ||||||
|  |  | ||||||
|     for key in db_keys: |     if env_var: | ||||||
|         if key not in db_config: |         logger.info(f"{env_key}={env_var}") | ||||||
|             logger.debug(f" - Missing {key} value: Looking for environment variable INVENTREE_DB_{key}") |         # Override configuration value | ||||||
|             env_key = f'INVENTREE_DB_{key}' |         db_config[key] = env_var | ||||||
|             env_var = os.environ.get(env_key, None) |  | ||||||
|  |  | ||||||
|             if env_var is not None: | # Check that required database configuration options are specified | ||||||
|                 logger.info(f'Using environment variable INVENTREE_DB_{key}') | reqiured_keys = ['ENGINE', 'NAME'] | ||||||
|                 db_config[key] = env_var |  | ||||||
|             else: |  | ||||||
|                 logger.debug(f'    INVENTREE_DB_{key} not found in environment variables') |  | ||||||
|  |  | ||||||
|     # Check that required database configuration options are specified | for key in reqiured_keys: | ||||||
|     reqiured_keys = ['ENGINE', 'NAME'] |     if key not in db_config: | ||||||
|  |         error_msg = f'Missing required database configuration value {key} in config.yaml' | ||||||
|  |         logger.error(error_msg) | ||||||
|  |  | ||||||
|     for key in reqiured_keys: |         print('Error: ' + error_msg) | ||||||
|         if key not in db_config: |         sys.exit(-1) | ||||||
|             error_msg = f'Missing required database configuration value {key} in config.yaml' |  | ||||||
|             logger.error(error_msg) |  | ||||||
|  |  | ||||||
|             print('Error: ' + error_msg) | """ | ||||||
|             sys.exit(-1) | Special considerations for the database 'ENGINE' setting. | ||||||
|  | It can be specified in config.yaml (or envvar) as either (for example): | ||||||
|  | - sqlite3 | ||||||
|  | - django.db.backends.sqlite3 | ||||||
|  | - django.db.backends.postgresql | ||||||
|  | """ | ||||||
|  |  | ||||||
|     """ | db_engine = db_config['ENGINE'] | ||||||
|     Special considerations for the database 'ENGINE' setting. |  | ||||||
|     It can be specified in config.yaml (or envvar) as either (for example): |  | ||||||
|     - sqlite3 |  | ||||||
|     - django.db.backends.sqlite3 |  | ||||||
|     - django.db.backends.postgresql |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|     db_engine = db_config['ENGINE'] | if db_engine.lower() in ['sqlite3', 'postgresql', 'mysql']: | ||||||
|  |     # Prepend the required python module string | ||||||
|  |     db_engine = f'django.db.backends.{db_engine.lower()}' | ||||||
|  |     db_config['ENGINE'] = db_engine | ||||||
|  |  | ||||||
|     if db_engine.lower() in ['sqlite3', 'postgresql', 'mysql']: | db_name = db_config['NAME'] | ||||||
|         # Prepend the required python module string | db_host = db_config.get('HOST', "''") | ||||||
|         db_engine = f'django.db.backends.{db_engine.lower()}' |  | ||||||
|         db_config['ENGINE'] = db_engine |  | ||||||
|  |  | ||||||
|     db_name = db_config['NAME'] | print("InvenTree Database Configuration") | ||||||
|  | print("================================") | ||||||
|  | print(f"ENGINE: {db_engine}") | ||||||
|  | print(f"NAME: {db_name}") | ||||||
|  | print(f"HOST: {db_host}") | ||||||
|  |  | ||||||
|     logger.info(f"Database ENGINE: '{db_engine}'") | DATABASES['default'] = db_config | ||||||
|     logger.info(f"Database NAME: '{db_name}'") |  | ||||||
|  |  | ||||||
|     DATABASES['default'] = db_config |  | ||||||
|  |  | ||||||
| CACHES = { | CACHES = { | ||||||
|     'default': { |     'default': { | ||||||
|   | |||||||
| @@ -1,4 +1,10 @@ | |||||||
| [](https://opensource.org/licenses/MIT) [](https://travis-ci.org/inventree/InvenTree) [](https://coveralls.io/github/inventree/InvenTree) | [](https://opensource.org/licenses/MIT) | ||||||
|  | [](https://coveralls.io/github/inventree/InvenTree) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| <img src="images/logo/inventree.png" alt="InvenTree" width="128"/> | <img src="images/logo/inventree.png" alt="InvenTree" width="128"/> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,19 +0,0 @@ | |||||||
| # Minimal makefile for Sphinx documentation |  | ||||||
| # |  | ||||||
|  |  | ||||||
| # You can set these variables from the command line. |  | ||||||
| SPHINXOPTS    = |  | ||||||
| SPHINXBUILD   = sphinx-build |  | ||||||
| SOURCEDIR     = . |  | ||||||
| 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) |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								docs/_static/img/api_doc.png
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/_static/img/api_doc.png
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 73 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docs/_static/img/api_http.png
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/_static/img/api_http.png
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 49 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docs/_static/img/modal_form.png
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/_static/img/modal_form.png
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 65 KiB | 
							
								
								
									
										100
									
								
								docs/conf.py
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								docs/conf.py
									
									
									
									
									
								
							| @@ -1,100 +0,0 @@ | |||||||
| # Configuration file for the Sphinx documentation builder. |  | ||||||
| # |  | ||||||
| # This file only contains a selection of the most common options. For a full |  | ||||||
| # list see the documentation: |  | ||||||
| # http://www.sphinx-doc.org/en/master/config |  | ||||||
|  |  | ||||||
| # -- Path setup -------------------------------------------------------------- |  | ||||||
|  |  | ||||||
| # If extensions (or modules to document with autodoc) are in another directory, |  | ||||||
| # 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('../')) |  | ||||||
| sys.path.append(os.path.abspath('../InvenTree')) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # -- Project information ----------------------------------------------------- |  | ||||||
|  |  | ||||||
| project = 'InvenTree' |  | ||||||
| copyright = '2019, InvenTree' |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # -- General configuration --------------------------------------------------- |  | ||||||
|  |  | ||||||
| # Add any Sphinx extension module names here, as strings. They can be |  | ||||||
| # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom |  | ||||||
| # ones. |  | ||||||
| extensions = [ |  | ||||||
|     'sphinx.ext.autodoc', |  | ||||||
|     'sphinx.ext.napoleon', |  | ||||||
|     'autoapi.extension', |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| napoleon_google_docstring = True |  | ||||||
| napoleon_numpy_docstring = False |  | ||||||
|  |  | ||||||
| autoapi_dirs = [ |  | ||||||
|     '../InvenTree', |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| autoapi_options = [ |  | ||||||
|     'members', |  | ||||||
|     'private-members', |  | ||||||
|     'special-members', |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| autoapi_type = 'python' |  | ||||||
|  |  | ||||||
| autoapi_ignore = [ |  | ||||||
|     '*migrations*', |  | ||||||
|     '**/test*.py', |  | ||||||
|     '**/manage.py', |  | ||||||
|     '**/apps.py', |  | ||||||
|     '**/admin.py', |  | ||||||
|     '**/middleware.py', |  | ||||||
|     '**/utils.py', |  | ||||||
|     '**/wsgi.py', |  | ||||||
|     '**/templates/', |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| # Add any paths that contain templates here, relative to this directory. |  | ||||||
| autoapi_template_dir = 'templates' |  | ||||||
| autoapi_root = 'docs' |  | ||||||
| autoapi_add_toctree_entry = False |  | ||||||
|  |  | ||||||
| templates_path = ['templates'] |  | ||||||
|  |  | ||||||
| # List of patterns, relative to source directory, that match files and |  | ||||||
| # directories to ignore when looking for source files. |  | ||||||
| # This pattern also affects html_static_path and html_extra_path. |  | ||||||
| exclude_patterns = [ |  | ||||||
|     '_build', |  | ||||||
|     'Thumbs.db', |  | ||||||
|     '.DS_Store', |  | ||||||
|     'manage.rst',  # Ignore django management file |  | ||||||
|     '**/*.migrations*.rst',  # Ignore migration files |  | ||||||
| ] |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # -- Options for HTML output ------------------------------------------------- |  | ||||||
|  |  | ||||||
| # The theme to use for HTML and HTML Help pages.  See the documentation for |  | ||||||
| # a list of builtin themes. |  | ||||||
| # |  | ||||||
| html_theme = 'sphinx_rtd_theme' |  | ||||||
|  |  | ||||||
| # 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'] |  | ||||||
|  |  | ||||||
| # Table of contents in sidebar |  | ||||||
| html_sidebars = {'**': [ |  | ||||||
|     'globaltoc.html', |  | ||||||
|     'relations.html', |  | ||||||
|     'sourcelink.html', |  | ||||||
|     'searchbox.html' |  | ||||||
| ]} |  | ||||||
| @@ -1,57 +0,0 @@ | |||||||
| InvenTree Modal Forms |  | ||||||
| ===================== |  | ||||||
|  |  | ||||||
| .. toctree:: |  | ||||||
|    :titlesonly: |  | ||||||
|    :maxdepth: 2 |  | ||||||
|    :caption: Modal Forms |  | ||||||
|    :hidden: |  | ||||||
|  |  | ||||||
|  |  | ||||||
| The InvenTree web interface uses modal forms for user input. InvenTree defines a wrapper layer around the Django form classes to provide a mechanism for retrieving and rendering forms via jQuery and AJAX. |  | ||||||
|  |  | ||||||
| .. image:: _static/img/modal_form.png |  | ||||||
|  |  | ||||||
| Forms are rendered to a Bootstrap modal window, allowing in-page data input and live page updating. |  | ||||||
|  |  | ||||||
| Crispy Forms |  | ||||||
| ------------ |  | ||||||
|  |  | ||||||
| Django provides native form rendering tools which are very powerful, allowing form rendering, input validation, and display of error messages for each field. |  | ||||||
|  |  | ||||||
| InvenTree makes use of the `django-crispy-forms <https://github.com/django-crispy-forms/django-crispy-forms>`_ extension to reduce the amount of boilerplate required to convert a Django model to a HTML form. |  | ||||||
|  |  | ||||||
| Form Rendering |  | ||||||
| -------------- |  | ||||||
|  |  | ||||||
| The InvenTree front-end web interface is implemented using jQuery and Bootstrap. Forms are rendered using Django `class-based forms <https://docs.djangoproject.com/en/2.2/topics/class-based-views/generic-editing/>`_ using standard Django methods.  |  | ||||||
|  |  | ||||||
| The main point of difference is that instead of rendering a HTTP response (and displaying a static form page) form data are requested via AJAX, and the form contents are injected into the modal window. |  | ||||||
|  |  | ||||||
| A set of javascript/jQuery functions handle the client/server interactions, and manage GET and POST requests. |  | ||||||
|  |  | ||||||
| Sequence of Events |  | ||||||
| ------------------ |  | ||||||
|  |  | ||||||
| #. User presses a button or other element which initiates form loading |  | ||||||
| #. jQuery function sends AJAX GET request to InvenTree server, requesting form at a specified URL |  | ||||||
| #. Django renders form (according to specific model/view rules) |  | ||||||
| #. Django returns rendered form as a JSON object |  | ||||||
| #. Client displays the modal window and injects the form contents into the modal |  | ||||||
| #. User fills in form data, presses the 'Submit' button |  | ||||||
| #. Client sends the completed form to server via POST |  | ||||||
| #. Django backend handles POST request, specifically determines if the form is valid |  | ||||||
| #. Return a JSON object containing status of form validity |  | ||||||
|   * If the form is valid, return (at minimum) ``{form_valid: true}``. Client will close the modal. |  | ||||||
|   * If the form is invalid, re-render the form and send back to the client. Process repeats |  | ||||||
|  |  | ||||||
| At the end of this process (i.e. after successful processing of the form) the client closes the modal and runs any optional post-processes (depending on the implementation). |  | ||||||
|  |  | ||||||
| Further Reading |  | ||||||
| --------------- |  | ||||||
|  |  | ||||||
| For a better understanding of the modal form architecture, refer to the relevant source files: |  | ||||||
|  |  | ||||||
| **Server Side:** Refer to ``./InvenTree/InvenTree/views.py`` for AJAXified Django Views |  | ||||||
|  |  | ||||||
| **Client Side:** Refer to ``./InvenTree/static/script/inventree/modals.js`` for client-side javascript |  | ||||||
| @@ -1,38 +0,0 @@ | |||||||
| InvenTree Source Documentation |  | ||||||
| ================================ |  | ||||||
|  |  | ||||||
| .. toctree:: |  | ||||||
|    :titlesonly: |  | ||||||
|    :maxdepth: 2 |  | ||||||
|    :caption: Index |  | ||||||
|    :hidden: |  | ||||||
|     |  | ||||||
|    Translations<translate> |  | ||||||
|    Modal Forms<forms> |  | ||||||
|    Tables<tables> |  | ||||||
|    REST API<rest> |  | ||||||
|    InvenTree Modules <modules> |  | ||||||
|    Module Reference<reference> |  | ||||||
|  |  | ||||||
| The documentation found here is provided to be useful for developers working on the InvenTree codebase. User documentation can be found on the `InvenTree website <https://inventree.github.io>`_. |  | ||||||
|  |  | ||||||
| Documentation for the Python modules is auto-generated from the `InvenTree codebase <https://github.com/InvenTree/InvenTree>`_. |  | ||||||
|  |  | ||||||
| Code Structure |  | ||||||
| -------------- |  | ||||||
|  |  | ||||||
| **Backend** |  | ||||||
|  |  | ||||||
| InvenTree is developed using the `django web framework <https://www.djangoproject.com/>`_, a powerful toolkit for making web applications in Python. |  | ||||||
|  |  | ||||||
| The database management code and business logic is written in Python 3. Core functionality is separated into individual modules (or *apps* using the django nomenclature). |  | ||||||
|  |  | ||||||
| Each *app* is located in a separate directory under InvenTree. Each *app* contains python modules named according to the standard django configuration. |  | ||||||
|  |  | ||||||
| **Frontend** |  | ||||||
|  |  | ||||||
| The web frontend rendered using a mixture of technologies. |  | ||||||
|  |  | ||||||
| Base HTML code is rendered using the `django templating language <https://docs.djangoproject.com/en/2.2/topics/templates/>`_ which provides low-level access to the underlying database models. |  | ||||||
|  |  | ||||||
| jQuery is also used to implement front-end logic, and desponse to user input. A REST API is provided to facilitate client-server communication. |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| @ECHO OFF |  | ||||||
|  |  | ||||||
| pushd %~dp0 |  | ||||||
|  |  | ||||||
| REM Command file for Sphinx documentation |  | ||||||
|  |  | ||||||
| if "%SPHINXBUILD%" == "" ( |  | ||||||
| 	set SPHINXBUILD=sphinx-build |  | ||||||
| ) |  | ||||||
| set SOURCEDIR=. |  | ||||||
| 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% |  | ||||||
| goto end |  | ||||||
|  |  | ||||||
| :help |  | ||||||
| %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% |  | ||||||
|  |  | ||||||
| :end |  | ||||||
| popd |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| InvenTree Modules |  | ||||||
| ================= |  | ||||||
|  |  | ||||||
| .. toctree:: |  | ||||||
|    :titlesonly: |  | ||||||
|    :maxdepth: 2 |  | ||||||
|    :caption: App Modules |  | ||||||
|    :hidden: |  | ||||||
|  |  | ||||||
|    docs/InvenTree/index |  | ||||||
|    docs/build/index |  | ||||||
|    docs/common/index |  | ||||||
|    docs/company/index |  | ||||||
|    docs/part/index |  | ||||||
|    docs/order/index |  | ||||||
|    docs/stock/index |  | ||||||
|  |  | ||||||
| The InvenTree Django ecosystem provides the following 'apps' for core functionality: |  | ||||||
|     |  | ||||||
| * `InvenTree <docs/InvenTree/index.html>`_ - High level management functions |  | ||||||
| * `Build <docs/build/index.html>`_ - Part build projects |  | ||||||
| * `Common <docs/common/index.html>`_ - Common modules used by various apps |  | ||||||
| * `Company <docs/company/index.html>`_ - Company management (suppliers / customers) |  | ||||||
| * `Part <docs/part/index.html>`_ - Part management |  | ||||||
| * `Order <docs/order/index.html>`_ - Order management |  | ||||||
| * `Stock <docs/stock/index.html>`_ - Stock management  |  | ||||||
| @@ -1,14 +0,0 @@ | |||||||
| Module Reference |  | ||||||
| =================== |  | ||||||
|  |  | ||||||
| .. toctree:: |  | ||||||
|    :titlesonly: |  | ||||||
|    :maxdepth: 2 |  | ||||||
|    :caption: Module Reference |  | ||||||
|    :hidden: |  | ||||||
|  |  | ||||||
|  |  | ||||||
| The complete reference indexes are found below: |  | ||||||
|  |  | ||||||
| * :ref:`modindex` |  | ||||||
| * :ref:`genindex` |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| Sphinx>=2.0.1 |  | ||||||
| sphinx-autoapi==1.0.0 |  | ||||||
| sphinx-rtd-theme==0.4.3 |  | ||||||
| @@ -1,42 +0,0 @@ | |||||||
| REST API |  | ||||||
| ======== |  | ||||||
|  |  | ||||||
| .. toctree:: |  | ||||||
|    :titlesonly: |  | ||||||
|    :maxdepth: 2 |  | ||||||
|    :caption: REST API |  | ||||||
|    :hidden: |  | ||||||
|  |  | ||||||
| InvenTree provides a REST API which serves data to the web client and also provides data access to third-party applications. The REST API is implemented using the `Django REST framework (DRF) <https://www.django-rest-framework.org/>`_ which provides the following features out of the box: |  | ||||||
|  |  | ||||||
| * AJAX REST API |  | ||||||
| * Web-browseable REST |  | ||||||
| * User authentication  |  | ||||||
| * Database model serialization and validation |  | ||||||
|  |  | ||||||
| API Access |  | ||||||
| ---------- |  | ||||||
|  |  | ||||||
| The API is accessible from the root URL ``/api/``. It requires user authentication. |  | ||||||
|  |  | ||||||
| * Requesting data via AJAX query will return regular JSON objects.  |  | ||||||
| * Directing a browser to the API endpoints provides a web-browsable interface |  | ||||||
|  |  | ||||||
| .. image:: _static/img/api_http.png |  | ||||||
|  |  | ||||||
| API Documentation |  | ||||||
| ----------------- |  | ||||||
|  |  | ||||||
| API documentation is provided by DRF autodoc tools, and is available for browsing at ``/api-doc/`` |  | ||||||
|  |  | ||||||
| .. image:: _static/img/api_doc.png |  | ||||||
|  |  | ||||||
| API Code |  | ||||||
| -------- |  | ||||||
|  |  | ||||||
| Javascript/jQuery code for interacting with the server via the REST API can be found under ``InvenTree/static/script/InvenTree``. |  | ||||||
|  |  | ||||||
| Python interface |  | ||||||
| ---------------- |  | ||||||
|  |  | ||||||
| A Python library for interacting with the InvenTree API is provided on `GitHub <https://github.com/inventree/inventree-python>`_ |  | ||||||
| @@ -1,14 +0,0 @@ | |||||||
| Table Management |  | ||||||
| ================ |  | ||||||
|  |  | ||||||
| .. toctree:: |  | ||||||
|    :titlesonly: |  | ||||||
|    :maxdepth: 2 |  | ||||||
|    :caption: Tables |  | ||||||
|    :hidden: |  | ||||||
|  |  | ||||||
| InvenTree uses `Bootstrap Table <https://bootstrap-table.com/>`_ to manage tabulated data in the web front-end. The ability to tabulate data from read via an AJAX request allows tables to be updated on-the-fly (without a full page reload). |  | ||||||
|  |  | ||||||
| Bootstrap Table also provides integrated tools for table searching, filtering, and advanced rendering. |  | ||||||
|  |  | ||||||
| Frontend code for table functionality can be found at ``InvenTree/static/script/inventree/tables.js``. |  | ||||||
							
								
								
									
										97
									
								
								docs/templates/python/module.rst
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										97
									
								
								docs/templates/python/module.rst
									
									
									
									
										vendored
									
									
								
							| @@ -1,97 +0,0 @@ | |||||||
| {% if not obj.display %} |  | ||||||
| :orphan: |  | ||||||
|  |  | ||||||
| {% endif %} |  | ||||||
| :mod:`{{ obj.name }}` |  | ||||||
| ======={{ "=" * obj.name|length }} |  | ||||||
|  |  | ||||||
| .. py:module:: {{ obj.name }} |  | ||||||
|  |  | ||||||
| {% if obj.docstring %} |  | ||||||
| .. autoapi-nested-parse:: |  | ||||||
|  |  | ||||||
|    {{ obj.docstring|prepare_docstring|indent(3) }} |  | ||||||
|  |  | ||||||
| {% endif %} |  | ||||||
|  |  | ||||||
| {% block subpackages %} |  | ||||||
| {% set visible_subpackages = obj.subpackages|selectattr("display")|list %} |  | ||||||
| {% if visible_subpackages %} |  | ||||||
| Subpackages |  | ||||||
| ----------- |  | ||||||
| .. toctree:: |  | ||||||
|    :titlesonly: |  | ||||||
|    :maxdepth: 3 |  | ||||||
|  |  | ||||||
| {% for subpackage in visible_subpackages %} |  | ||||||
|    {{ subpackage.short_name }}/index.rst |  | ||||||
| {% endfor %} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| {% endif %} |  | ||||||
| {% endblock %} |  | ||||||
| {% block submodules %} |  | ||||||
| {% set visible_submodules = obj.submodules|selectattr("display")|list %} |  | ||||||
| {% if visible_submodules %} |  | ||||||
| Submodules |  | ||||||
| ---------- |  | ||||||
|  |  | ||||||
| The {{ obj.name }} module contains the following submodules |  | ||||||
|  |  | ||||||
| .. toctree:: |  | ||||||
|    :titlesonly: |  | ||||||
|    :maxdepth: 1 |  | ||||||
|  |  | ||||||
| {% for submodule in visible_submodules %} |  | ||||||
|    {{ submodule.short_name }}/index.rst |  | ||||||
| {% endfor %} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| {% endif %} |  | ||||||
| {% endblock %} |  | ||||||
| {% block content %} |  | ||||||
| {% set visible_children = obj.children|selectattr("display")|list %} |  | ||||||
| {% if visible_children %} |  | ||||||
| {{ obj.type|title }} Contents |  | ||||||
| {{ "-" * obj.type|length }}--------- |  | ||||||
|  |  | ||||||
| {% set visible_classes = visible_children|selectattr("type", "equalto", "class")|list %} |  | ||||||
| {% set visible_functions = visible_children|selectattr("type", "equalto", "function")|list %} |  | ||||||
| {% if include_summaries and (visible_classes or visible_functions) %} |  | ||||||
| {% block classes %} |  | ||||||
| {% if visible_classes %} |  | ||||||
| Classes |  | ||||||
| ~~~~~~~ |  | ||||||
|  |  | ||||||
| .. autoapisummary:: |  | ||||||
|  |  | ||||||
| {% for klass in visible_classes %} |  | ||||||
|    {{ klass.id }} |  | ||||||
| {% endfor %} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| {% endif %} |  | ||||||
| {% endblock %} |  | ||||||
|  |  | ||||||
| {% block functions %} |  | ||||||
| {% if visible_functions %} |  | ||||||
| Functions |  | ||||||
| ~~~~~~~~~ |  | ||||||
|  |  | ||||||
| .. autoapisummary:: |  | ||||||
|  |  | ||||||
| {% for function in visible_functions %} |  | ||||||
|    {{ function.id }} |  | ||||||
| {% endfor %} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| {% endif %} |  | ||||||
| {% endblock %} |  | ||||||
| {% endif %} |  | ||||||
| {% for obj_item in visible_children %} |  | ||||||
| {% if obj.all is none or obj_item.short_name in obj.all %} |  | ||||||
| {{ obj_item.rendered|indent(0) }} |  | ||||||
| {% endif %} |  | ||||||
| {% endfor %} |  | ||||||
| {% endif %} |  | ||||||
| {% endblock %} |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| Translations |  | ||||||
| ============ |  | ||||||
|  |  | ||||||
| .. toctree:: |  | ||||||
|    :titlesonly: |  | ||||||
|    :maxdepth: 2 |  | ||||||
|    :caption: Language Translation |  | ||||||
|    :hidden: |  | ||||||
|  |  | ||||||
| InvenTree supports multi-language translation using the `Django Translation Framework <https://docs.djangoproject.com/en/2.2/topics/i18n/translation/>`_ |  | ||||||
|  |  | ||||||
| Translation strings are located in the `InvenTree/locales/` directory, and translation files can be easily added here. |  | ||||||
|  |  | ||||||
| To set the default language, change the `language` setting in the `config.yaml` settings file. |  | ||||||
|  |  | ||||||
| To recompile the translation files (after adding new translation strings), run the command ``make translate`` from the root directory. |  | ||||||
		Reference in New Issue
	
	Block a user