diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1d29edd --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[{*.py,*.py.jinja2}] +trim_trailing_whitespace = true +insert_final_newline = true + +[{*.proto,*.proto.jinja2}] +indent_size = 2 + +[*.y{ml,aml}] +indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..00a51af --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# These are explicitly windows files and should use crlf +*.bat text eol=crlf + diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml new file mode 100644 index 0000000..0eed6bf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml @@ -0,0 +1,88 @@ +name: "πŸ› PUML Bug Report" +description: Create a new ticket for a bug in the PUML repository. +title: "πŸ› [PUML BUG] - " +labels: [ + "bug" +] +projects: [ + "DevOps-MBSE" +] +body: + - type: checkboxes + id: pre-requistes + attributes: + label: "Pre-requisites" + description: Please answer the following questions for yourself before submitting an issue. + options: + - label: I checked the documentation and found no answer. + required: true + - label: I checked to make sure that this issue has not already been filed. + required: true + - type: input + id: version-pre-req + attributes: + label: "What version of AaC are you using? Check your version with the command: aac version." + placeholder: i.e. 0.1.7 + validations: + required: true + - type: input + id: plugin-version-pre-req + attributes: + label: "What version of the plugin are you using?" + placeholder: i.e. 0.1.7 + validations: + required: true + - type: textarea + id: description + attributes: + label: "Description" + placeholder: Please enter a short and explicit description of your incident. + validations: + required: true + - type: input + id: reproduction-url + attributes: + label: "Reproduction URL" + placeholder: ex. https://github.com/USERNAME/REPO-NAME + validations: + required: false + - type: textarea + id: reproduction-steps + attributes: + label: "Reproduction steps" + value: | + Please enter an explicit description of your issue + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error + render: bash + validations: + required: true + - type: textarea + id: screenshot + attributes: + label: "Screenshots" + value: | + If applicable, add screenshots to help explain your problem. + ![DESCRIPTION](LINK.png) + render: bash + validations: + required: false + - type: textarea + id: logs + attributes: + label: "Logs" + value: | + Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. + render: bash + validations: + required: false + - type: textarea + id: files + attributes: + label: "Pertinent Files" + value: | + Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/DOCUMENTATION-REQUEST.yml b/.github/ISSUE_TEMPLATE/DOCUMENTATION-REQUEST.yml new file mode 100644 index 0000000..24c6141 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/DOCUMENTATION-REQUEST.yml @@ -0,0 +1,33 @@ +name: "βœοΈπŸ“˜ PUML Documentation Request" +description: Create a new ticket for a documentation request in the PUML repository. +title: "βœοΈπŸ“˜ [PUML Documentation] - <title>" +labels: [ + "documentation" +] +projects: [ + "DevOps-MBSE" +] +body: + - type: checkboxes + id: doc-types + attributes: + label: "Documentation Types" + description: Please select the type(s) of documentation your request relates to. + options: + - label: New + - label: Expansion + - label: Correction + - type: textarea + id: documentation + attributes: + label: "Requested Documentation" + placeholder: Describe in a few lines your documentation request. + validations: + required: true + - type: textarea + id: reference_issues + attributes: + label: "Reference Issues" + placeholder: "Please include any related #<Issues IDs>" + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml new file mode 100644 index 0000000..9441415 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml @@ -0,0 +1,46 @@ +name: "πŸ’­ PUML Feature Request" +description: Create a new ticket for a new feature request in the PUML repository. +title: "πŸ’­ [PUML REQUEST] - <title>" +labels: [ + "question", + "enhancement" +] +projects: [ + "DevOps-MBSE" +] +body: + - type: textarea + id: reference_issues + attributes: + label: "Reference Issues" + placeholder: "#<Issue IDs>" + validations: + required: false + - type: textarea + id: summary + attributes: + label: "Summary" + placeholder: Describe in a few lines your feature request. + validations: + required: true + - type: textarea + id: basic_example + attributes: + label: "Basic Example" + placeholder: A few specific words about your feature request. + validations: + required: true + - type: textarea + id: drawbacks + attributes: + label: "What are the drawbacks/impacts of your feature request?" + placeholder: Identify the drawbacks and impacts while being neutral on your feature request. + validations: + required: true + - type: textarea + id: unresolved_question + attributes: + label: "Unresolved questions" + placeholder: Identify any unresolved issues. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/SIMPLE-TASK.yml b/.github/ISSUE_TEMPLATE/SIMPLE-TASK.yml new file mode 100644 index 0000000..9cb6bed --- /dev/null +++ b/.github/ISSUE_TEMPLATE/SIMPLE-TASK.yml @@ -0,0 +1,41 @@ +name: "πŸ“‹ PUML Task" +description: Create a new ticket for a task to go with a PUML feature +title: "πŸ“‹ [PUML TASK] - <title>" +labels: [ + "enhancement" +] +projects: [ + "DevOps-MBSE" +] +body: + - type: input + id: parent_feature + attributes: + label: "Parent Feature" + placeholder: "#<Issue ID>" + validations: + required: true + - type: textarea + id: summary + attributes: + label: "Task Description" + placeholder: Describe in a few lines your task that can be associated with the parent feature. + validations: + required: true + - type: textarea + id: ac + attributes: + label: "Acceptance Criteria" + placeholder: | + Provide initial criteria to determine when the work is complete and elligible for merging. + i.e. - [ ] Include unit tests for new thing + - [ ] Update documentation with new thing + validations: + required: true + - type: textarea + id: unresolved_question + attributes: + label: "Unresolved questions" + placeholder: Identify any unresolved issues. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..29ff419 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,7 @@ +blank_issues_enabled: false +contact_links: + - name: AaC Community Support + url: https://github.com/DevOps-MBSE/AaC/discussions + about: Please ask and answer questions here. + + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..e94acf9 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,40 @@ +# Description + +Include a summary of the changes and the related issue. List any dependencies that are required for this change. + +# Linked Items: + +Closes/Fixes/Resolves #XYZ + +### Added + +- _Describe any new features._ + +### Changed + +- _Describe any changes in existing functionality._ + +### Deprecated + +- _Describe any deprecated features._ + +### Removed + +- _Describe any removed features._ + +### Fixed + +- _Describe any bug fixes._ + +### Security + +- _Describe any security-related changes._ + +# Checklist: + +- [ ] I updated project documentation to reflect my changes. +- [ ] My changes generate no new warnings. +- [ ] I updated new and existing unit tests to account for my changes. +- [ ] I linked the associated item(s) to be closed. +- [ ] I bumped the version. +- [ ] I added the labels corresponding to my changes. diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..73af046 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,28 @@ +# .github/release.yml + +changelog: + categories: + - title: Added πŸ’­ + labels: + - added + - title: Changed πŸ›  + labels: + - changed + - title: Deprecated πŸ’Ύ + labels: + - deprecated + - title: Removed βœ‚οΈ + labels: + - removed + - title: Fixed πŸ› + labels: + - fixed + - title: Security πŸ”’ + labels: + - security + - title: Documentation βœοΈπŸ“˜ + labels: + - documentation + - title: Other Changes πŸ“ˆ + labels: + - "*" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..7cfb61e --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,70 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] + schedule: + - cron: '15 1 * * 1' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'python' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # πŸ“š https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/main-branch.yml b/.github/workflows/main-branch.yml new file mode 100644 index 0000000..f9b63fc --- /dev/null +++ b/.github/workflows/main-branch.yml @@ -0,0 +1,27 @@ +# This workflow is only intended to run when a pull-request is merged into the main branch +name: Main branch Workflow + +on: + push: + branches: [main] + +jobs: + build_python_artifacts: + name: Python Build + uses: ./.github/workflows/python-build-and-lint.yml + + python_tests: + name: Python Unit Tests + needs: build_python_artifacts + uses: ./.github/workflows/python-test-python-version.yml + + python_cross_platform: + name: Python Cross Platform Build & Test + uses: ./.github/workflows/python-cross-platform-support.yml + +# Commenting out from main branch workflow till permissions aspect can be resolved for +# reconnecting automated page deployment. The below workflow is able to be ran manually +# allowing for the site to stay up to date. + # build_and_deploy_documentation: + # name: Build and Deploy GitHub Pages + # uses: ./.github/workflows/sphinx.yml diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml new file mode 100644 index 0000000..ea3c20e --- /dev/null +++ b/.github/workflows/pull-requests.yml @@ -0,0 +1,19 @@ +# This workflow is intended to run for ANY pull request +name: Pull Request Workflow + +on: + pull_request: + +jobs: + build_python_artifacts: + name: Python Build + uses: ./.github/workflows/python-build-and-lint.yml + + python_tests: + name: Python Unit Tests + needs: build_python_artifacts + uses: ./.github/workflows/python-test-python-version.yml + + python_cross_platform: + name: Python Cross Platform Build & Test + uses: ./.github/workflows/python-cross-platform-support.yml diff --git a/.github/workflows/python-build-and-lint.yml b/.github/workflows/python-build-and-lint.yml new file mode 100644 index 0000000..a8f9a84 --- /dev/null +++ b/.github/workflows/python-build-and-lint.yml @@ -0,0 +1,55 @@ +on: + workflow_call: + +jobs: + + build_python_artifacts: + name: Build Artifacts + runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./python + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Set up Python 3.9.13 + uses: actions/setup-python@v4 + with: + python-version: 3.9.13 + + - name: Install requirements + run: pip install -r requirements.txt + + - name: Install the aac-puml Package + run: pip install -e . + + - name: Lint with flake8 + run: flake8 . + + - name: List Transitive Dependencies + run: python -m pipdeptree + + - name: Build distribution package + run: python -m build + + - name: Upload Python Wheel + uses: actions/upload-artifact@v3 + with: + name: aac_puml + path: python/dist + if-no-files-found: error + overwrite: true + + - name: Build Documentation + run: | + cp -R ../docs/ ./docs + cd ./docs + sphinx-build source doc_artifacts + + - name: Upload Documentation + uses: actions/upload-artifact@v3 + with: + name: aac-puml-docs + path: python/docs/doc_artifacts + overwrite: true diff --git a/.github/workflows/python-cross-platform-support.yml b/.github/workflows/python-cross-platform-support.yml new file mode 100644 index 0000000..a5a80ee --- /dev/null +++ b/.github/workflows/python-cross-platform-support.yml @@ -0,0 +1,98 @@ +on: + workflow_call: + +defaults: + run: + working-directory: ./python + +jobs: + os_build_matrix: + name: Build ${{ matrix.os }} Secure Install Air Gap + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-latest, windows-latest, macos-latest] # Annoyingly, Github actions don't support anchors + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Set up Python 3.9.13 + uses: actions/setup-python@v4 + with: + python-version: 3.9.13 + + - name: Install the AaC PUML Package + run: python -m pip install -e . + + - name: Create Dependencies Package + id: os_id + if: matrix.os != 'windows-latest' + run: | + ./secure_install/pipeline_scripts/create_install_archive.bash + + - name: Create Dependencies Package + if: matrix.os == 'windows-latest' + run: | + ./secure_install/pipeline_scripts/create_install_archive.bat + + - name: Upload Dependencies Package + uses: actions/upload-artifact@v3 + with: + name: secure_install_${{ matrix.os }} + path: python/secure_install/aac_secure_install_* + + os_test_matrix: + name: Test ${{ matrix.os }}/${{ matrix.py_version }} Secure Install Air Gap + needs: os_build_matrix + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-latest, windows-latest, macos-latest] # Annoyingly, Github actions don't support anchors + py_version: ["3.9.13"] # py_version: ["3.9.13", "3.10.0", "3.11.0"] + # exclude: + # - os: ubuntu-latest + # py_version: 3.9.13 + # - os: ubuntu-latest + # py_version: 3.10.0 + # - os: macos-latest + # py_version: 3.11.0 + + steps: + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.py_version }} + + - name: Checkout Repository # Checked-out repository is necessary to test the first party plugin generation. + uses: actions/checkout@v3 + + - name: Download Secure Install + uses: actions/download-artifact@v3 + with: + name: secure_install_${{ matrix.os }} + path: python/ + + - name: Install from Secure Install + if: matrix.os != 'windows-latest' + run: | + chmod +x ./aac_secure_install_*/install_aac_air_gap.bash + ./aac_secure_install_*/install_aac_air_gap.bash + + - name: Install from Secure Install + if: matrix.os == 'windows-latest' + run: | + cd (Get-ChildItem -Filter aac_secure_install_*) + .\install_aac_air_gap.bat + + - name: Test Plugin Commands + run: echo "Replace with testing the package commands of this repo" + + - name: Upload logs from failed runs + if: ${{ failure() }} + uses: actions/upload-artifact@v3 + with: + name: failed_test_log + path: ${{ env.pythonLocation }}/**/aac.log diff --git a/.github/workflows/python-deploy-artifacts.yml b/.github/workflows/python-deploy-artifacts.yml new file mode 100644 index 0000000..8d66d2e --- /dev/null +++ b/.github/workflows/python-deploy-artifacts.yml @@ -0,0 +1,35 @@ +name: Deploy Python Artifacts + +on: + workflow_dispatch: + # push: + # branches: + # - main + # paths: + # - python/** + +defaults: + run: + working-directory: ./python + +jobs: + build_deployment_artifacts: + name: Build Artifacts + uses: ./.github/workflows/python-build-and-lint.yml + + deploy_artifacts: + name: Deploy Artifacts + runs-on: ubuntu-22.04 + needs: build_deployment_artifacts + steps: + - name: Download Python Wheel + uses: actions/download-artifact@v3 + with: + name: aac_wheel + path: python/dist/ + + - name: Publish distribution to PyPI + uses: pypa/gh-action-pypi-publish@master + with: + password: ${{ secrets.PYPI_API_TOKEN }} + packages_dir: python/dist/ diff --git a/.github/workflows/python-test-python-version.yml b/.github/workflows/python-test-python-version.yml new file mode 100644 index 0000000..9fa95d9 --- /dev/null +++ b/.github/workflows/python-test-python-version.yml @@ -0,0 +1,54 @@ +on: + workflow_call: + +defaults: + run: + working-directory: ./python + +jobs: + python_tests: + name: Python ${{ matrix.py_version }} Unit Tests + runs-on: ubuntu-22.04 + + strategy: + matrix: + py_version: ["3.9.13"] # py_version: ["3.9.13", "3.10.5", "3.11.7"] + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.py_version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.py_version }} + + - name: Install the AaC PUML Package + run: pip install -e . + + - name: Run Tox Tests + run: tox -e $(echo py${{ matrix.py_version }} | awk -F "." '{print $1$2;}') + + - name: Upload Code Coverage Report + uses: actions/upload-artifact@v3 + with: + name: test-coverage-report + path: python/html_code_coverage/ + + # - name: Run Tox Tests With Coverage + # if: matrix.py_version == '3.11.7' + # run: tox -e py311 -- --coverage-report html + + # - name: Upload Code Coverage Report + # uses: actions/upload-artifact@v3 + # if: matrix.py_version == '3.11.7' + # with: + # name: test-coverage-report + # path: python/html_code_coverage/ + + - name: Upload logs from failed runs + if: ${{ failure() }} + uses: actions/upload-artifact@v3 + with: + name: failed_test_log + path: python/src/aac/aac.log diff --git a/.github/workflows/sphinx.yml b/.github/workflows/sphinx.yml new file mode 100644 index 0000000..116c967 --- /dev/null +++ b/.github/workflows/sphinx.yml @@ -0,0 +1,53 @@ +name: Build and Deploy Sphinx Documentation +on: + # Call from main workflow + workflow_call: + + # Manual runs + workflow_dispatch: + +# Configuring starting working directory +defaults: + run: + working-directory: ./python + +# Set token permissions +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment, skip queued between in progress and latest. +# But do NOT cancel in progress. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + #Single deploy job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Setup Pages + uses: actions/configure-pages@v3 + + - name: Build Documentation + uses: ammaraskar/sphinx-action@0.4 + with: + pre-build-command: "pip install aac-puml" + docs-folder: "docs/" + + - name: Upload Artifact + uses: actions/upload-pages-artifact@v2 + with: + path: ./docs/docs/html + + - name: Deploy to GitHub Pages + id: deploy + uses: actions/deploy-pages@v2 diff --git a/.gitignore b/.gitignore index 68bc17f..20765e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,41 @@ +# IDE/Editor files +.project +.settings/ + +# Emacs temporary files +.#* + +# Vim temporary files +*.sw[po] + +*.http + +# Occasionally created gitpod .tmp files +*.tmp + +# jekyll / GitHub Pages +*.gem +.bundle +.ruby-version +.jekyll-cache +.sass-cache +_site +Gemfile.lock +node_modules + +# TypeScript server logs +.log/ + +# Rope configuration +.ropeproject/ + +aac.log +AaC_OpenAPI_Schema.json +generated/ +state.json + +.DS_Store + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile new file mode 100644 index 0000000..0a8b379 --- /dev/null +++ b/.gitpod.Dockerfile @@ -0,0 +1,13 @@ +FROM gitpod/workspace-python + +RUN pyenv install 3.9.13 \ + && pyenv global 3.9.13 + +# # Python Dependencies +# ARG PYTHON_VERSION=3.9.13 + +# RUN sudo add-apt-repository ppa:deadsnakes/ppa -y +# RUN sudo apt install python${PYTHON_VERSION} -y +# RUN sudo apt install python${PYTHON_VERSION}-venv -y +# RUN sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python${PYTHON_VERSION} 2 +# RUN sudo pip install --upgrade pip diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..77b0869 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,29 @@ +image: + file: .gitpod.Dockerfile + +tasks: + - name: Serve Sphinx Docs + init: | + cd /workspace/aac-puml/docs/ + sleep 120 # Gitpod often takes a long time to install the python environment + source /workspace/aac-puml/python/venv/bin/activate + sphinx-build source gen_docs # Pre-build the docs so that when Gitpod opens the port it's ready to serve + command: sphinx-autobuild source gen_docs + + - name: Python Virtual Environment + init: | + cd python/ + python -m venv venv --system-site-packages + source venv/bin/activate + pip install -e . + command: cd /workspace/aac-puml/python/; source venv/bin/activate # Always launch a console with our virtual env + +vscode: + extensions: + - eamodio.gitlens + - redhat.vscode-yaml + - editorconfig.editorconfig + - ms-python.python + - samuelcolvin.jinjahtml + - streetsidesoftware.code-spell-checker + diff --git a/README.md b/README.md index a26652a..735c456 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ +[![Main branch aac-puml Workflow](https://github.com/DevOps-MBSE/aac-puml/actions/workflows/main-branch.yml/badge.svg)](https://github.com/DevOps-MBSE/aac-puml/actions/workflows/main-branch.yml) +[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/from-referrer/) + # aac-puml This will house the information pertaining to the PUML plugin for Architecture as Code. diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..07b2c6c --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,4 @@ +# Ignore the generated api docs and auto-build docs +source/api +gen_docs + diff --git a/src/aac-puml/templates/__init__.py b/docs/.nojekyll similarity index 100% rename from src/aac-puml/templates/__init__.py rename to docs/.nojekyll diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..1ed714b --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = docs + +# 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) diff --git a/docs/gen_protobuf.md b/docs/gen_protobuf.md deleted file mode 100644 index b9ffbc7..0000000 --- a/docs/gen_protobuf.md +++ /dev/null @@ -1,179 +0,0 @@ -# Generate Protobuf 3 Plugin -This plugin generates protobuf 3 messages from interface messages between Architecture-as-Code models. - -## Plugin Commands - - -### Generate Protobuf Messages -Shell command: - - `$ aac gen-protobuf` - -Command arguments: - -`-h, --help` - Shows a help message - -`architecture_file` - The Architecture-as-Code file containing the root system definition for which you want to generate Protobuf messages. - -`output_directory` - The directory to write the generated Protobuf messages to. - -## Plugin Extensions & Definitions -In order to use this plugin, you'll have to extend your `model`s to provide necessary contextual information for the Protobuf generator to identify interfaces and data structures. - -Protobuf messages will only be generated for data structures identified as interface messages between `model`s. This requires that the modeled systems and components include behaviors with defined inputs and outputs. `schema:` definitions that are referenced in `model:behavior:` fields: `input:` and `output:` are identified as interface messages. Any substructure or embedded `enum` in the interface messages will also be included in the generated Protobuf messages -- so you can nest `schema` definitions for complex user-defined messages. - -## Protobuf 3 Features - -Feature Implementation: - -| Feature | Implementation Status | -|---------|-----------------------| -| [Scalar Values](#scalar-values) | βœ… Implemented | -| [User-defined Message Types](#user-defined-message-types) | βœ… Implemented | -| [Embedded Comments](#embedded-comments) | βœ… Implemented | -| [Reserved Fields](#reserved-fields) | ❌ Not Implemented | -| [Assigning Field Numbers](#assigning-field-numbers) | ❌ Not Implemented | -| [Enums](#enums) | βœ… Implemented | -| [Reserved Types](#reserved-types) | ❌ Not Implemented | -| [OneOf](#oneof) | ❌ Not Implemented | -| [Maps](#maps) | ❌ Not Implemented | -| [Packages](#packages) | ❌ Not Implemented | -| [Defining Services](#defining-services) | ❌ Not Implemented | -| [Options](#options) | βœ… Implemented | -| [Optional Keyword](#optional-keyword) | β—οΈβŒβ—οΈ Won't Implement | - - -### Scalar Values -All primitive/scalar [Protobuf 3 value types](https://developers.google.com/protocol-buffers/docs/proto3#scalar) types are supported. -The full list can be found in the plugin's definition, [`ProtobufPrimitiveTypesExtension`](https://github.com/DevOps-MBSE/AaC/blob/main/python/src/aac/plugins/first_party/gen_protobuf/gen_protobuf.yaml). - -The scalar values are added to the `Primitives` defintion and can be used inline very easily. -```yaml -schema: - name: SomeDataMessage - fields: - - name: some_data - type: string # String is already defined as a type in the core AaC DSL - description: Some description for some_data - - name: some_numbers - type: fixed64[] # The fixed64 type is supplied by this plugin - description: A description for some_numbers -``` - -### User-defined Message Types -This plugin generates Protobuf [user-defined](https://developers.google.com/protocol-buffers/docs/proto3#adding_more_message_types) messages, one per file, for every non-primitive type referenced. For each `schema:` definition identified as an interface message, or a substructure of an interface messages, a user-defined message type is generated. - -### Embedded Comments -This plugin leverages the `description` field in AaC models to generate corresponding [comments](https://developers.google.com/protocol-buffers/docs/proto3#adding_comments) in the Protobuf messages. - -`schema:` and `enum:` definitions support generating comments for Protobuf messages by populating those definition's top-level `description` field. - -Only `schema:` definitions allow for field/value level comments. These comments are populated by defining the `description` field in the `fields` entries of a `schema:` definition. - -An example of embedding comments in the Protobuf message looks like: -```yaml -schema: - name: SomeDataMessage - description: | - Some description about my data message. - fields: - - name: some_data - type: string - description: Some description for some_data - - name: some_numbers - type: fixed64[] - description: A description for some_numbers -``` - -With the corresponding output: -```protobuf -syntax = "proto3" - -/* Some description about my data message. */ -message SomeDataMessage { - - /* Some description for some_data */ - string some_data = 1; - - /* A description for some_numbers */ - repeated fixed64 some_numbers = 2; -} -``` - -### Assigning Field Numbers -[assigning field numbers](https://developers.google.com/protocol-buffers/docs/proto3#assigning_field_numbers) isn't implemented yet. Field numbers are currently assigned by the field's position in the definition, starting at the first field being assigned the field number `1`. - - -### Reserved Fields -[Reserved Fields](https://developers.google.com/protocol-buffers/docs/proto3#reserved) aren't implemented yet. - -### Enums -Protobuf [enums](https://developers.google.com/protocol-buffers/docs/proto3#enum) can easily be defined by defining AaC enums. - -An example AaC enum definition would look like: -```{eval-rst} -.. literalinclude:: ../../../../python/model/protobuf_flow/Data.aac - :language: yaml - :lines: 75-82 -``` - -The corresponding output will look like: -```protobuf -syntax = "proto3" - -/* Enums for the various supported message types. */ -enum MessageType { - TYPE_1 = 1; - TYPE_2 = 2; - TYPE_3 = 3; -} -``` - -### Reserved Types -[Reserved Types](https://developers.google.com/protocol-buffers/docs/proto3#reserved_values) is not currently implemented. - -### OneOf -[OneOf](https://developers.google.com/protocol-buffers/docs/proto3#oneof) is not currently implemented. - -### Maps -Protobuf 3 [maps](https://developers.google.com/protocol-buffers/docs/proto3#maps) is not currently implemented. - - -[Maps Backwards compatibility](https://developers.google.com/protocol-buffers/docs/proto3#backwards_compatibility) - -### Packages -[Packages](https://developers.google.com/protocol-buffers/docs/proto3#packages) is not currently implemented. - -### Defining Services -[Defining Services](https://developers.google.com/protocol-buffers/docs/proto3#services) is not currently implemented. - -### Options -Protobuf allows for special [options](https://developers.google.com/protocol-buffers/docs/proto3#options) that provide customization and context for the Protobuf tooling. Users can specify options for Protobuf messages by defining the field `protobuf_message_options` in `schema:` or `enum:` -definitions. - -An example use of options would look like: -```{eval-rst} -.. literalinclude:: ../../../../python/model/protobuf_flow/Data.aac - :language: yaml - :lines: 5-27 - :emphasize-lines: 5-9 -``` - -The corresponding output will look like: -```protobuf -syntax = "proto3" - -option java_package = com.example.foo; - -message SomeDataMessage { - - string some_data = 1; - - repeated fixed64 some_numbers = 2; -} -``` - -### Optional Keyword -Protobuf 3.15 implemented the `optional` keyword, however, the `optional` keyword is considered a anti-pattern in Protobuf 3 messages, because all fields are inherently optional in Protobuf 3 messages. - -Because optional keywords are anti-patterns, and are used for VERY specific cases, we currently don't plan to implement the `optional` keyword for generated Protobuf 3 messages. diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 75b202b..0000000 --- a/docs/index.rst +++ /dev/null @@ -1,9 +0,0 @@ -Plugins Documentation -===================== - -.. toctree:: - :maxdepth: 1 - - AaC Plugins <plugins_index> - Plant-UML Plugin <plant_uml> - Gen-Protobuf Plugin <gen_protobuf> diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..c46cc25 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=docs + +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.https://www.sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/plant_uml.md b/docs/plant_uml.md deleted file mode 100644 index d91c55a..0000000 --- a/docs/plant_uml.md +++ /dev/null @@ -1,17 +0,0 @@ -# Plant UML AaC Plugin - -Plant UML - Generate [Plant UML](https://plantuml.com/) from your AaC model. - -## Installation -AaC requires Python 3.9 or greater to be installed prior to use. Install the Plant UML AaC plugin using pip. -```bash -pip install aac-plantuml -``` - -## Commands - -### aac puml-component - -### aac puml-object - -### aac puml-sequence diff --git a/docs/plugins_index.md b/docs/plugins_index.md deleted file mode 100644 index 2cefb57..0000000 --- a/docs/plugins_index.md +++ /dev/null @@ -1,31 +0,0 @@ -# AaC Plugins - -## Built-In Plugins for Core Commands - -AaC leverages a plugin architecture to implement the majority of its user features providing an extensible interface for the core development team and any other party interested in contributing to AaC. Built-in plugins that provide features like `Gen-Plugin` and `Gen-JSON` are maintained inside the repository and are shipped alongside the core AaC package. This support and maintenance by the core development team is why we classify these built-in plugins as "first-party". - -### JSON - -AaC includes a built-in command to convert your AaC YAML model to JSON. -```bash -aac json <aac_model.yaml> -``` - -### Plugin Generator - -AaC includes a built-in command to help you extend AaC by creating your own plugins. This is how we build all of our plugins. -```bash -aac gen-plugin <path/to/aac_plugin_model.yaml> -``` - -The plugin generator does support generating first-party and third-party plugins. The generator uses the path of AaC plugin file to identify if it is within an AaC repository, if the path contains "src/aac/plugins/" then the plugin is classified as being a first-party plugin. Otherwise, if the path doesn't contain "src/aac/plugins/" then the plugin is assumed to be third-party and is generated with an independent Python project skeleton. - -## Third Party Plugins - -AaC can be extended by anyone, wether they are part of our core team or not. We recommend any plugin developer -use the "aac-" prefix when building and publishing AaC plugins. Search (PyPI)[https://pypi.org/] for additional 3rd party Plugins. - -## AaC Core Plugins - -AaC core plugins are built and published by our team but are not part of the AaC distribution. We want AaC to be -as useful as possible, but not bloated. As we extend the functionality of AaC, expect to see more core plugins published. diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..a00d808 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,6 @@ +docutils>=0.19 +furo>=2023.05.20 +myst-parser>=2.0.0 +sphinx>=6.1.3 +sphinx-contributors>=0.2.7 +sphinx-copybutton>=0.5.2 diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..0c035c0 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,122 @@ +# 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: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- 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 +from datetime import date +from importlib import metadata + +sys.path.insert(0, os.path.abspath(".")) + + +# -- Project information ----------------------------------------------------- + +project = "Architecture-as-Code Plant-UML Plugin" +copyright = f"2021 - {str(date.today().year)} , AaC PUML Project Contributors" +author = "AaC PUML Project Contributors" + +# The full version, including alpha/beta/rc tags +release = metadata.version("aac-puml") + + +# -- 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.autosectionlabel", + "sphinx.ext.autosummary", + "sphinx.ext.coverage", + "sphinx.ext.githubpages", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "myst_parser", + "sphinx_contributors", + "sphinx_copybutton", +] + +# -- Ext: autodoc configuration ---------------------------------------------- +autodoc_default_options = { + "members": True, +} +autodoc_typehints = "both" +autodoc_preserve_defaults = True +autodoc_inherit_docstrings = True + +# -- Ext: autosummary configuration ------------------------------------------ +autosummary_generate = True +autosummary_generate_overwrite = False + +# -- Ext: Napoleon configuration --------------------------------------------- +napoleon_google_docstring = True +napoleon_include_init_with_doc = False +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True +napoleon_preprocess_types = False +napoleon_type_aliases = None +napoleon_attr_annotations = True + +# -- Ext: MYST configuration --------------------------------------------- +myst_heading_anchors = 4 + +# Add any paths that contain templates here, relative to this directory. +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 = [] + +# The master toctree document. +master_doc = 'index' + +# The file extensions of source files. Sphinx considers the files with this +# suffix as sources. The value can be a dictionary mapping file extensions +# to file types. +source_suffix = { + ".rst": "restructuredtext", + ".txt": "restructuredtext", + ".md": "markdown", +} + +# -- 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 = "furo" + +# The style name to use for Pygments highlighting of source code. If not set, +# either the theme’s default style or 'sphinx' is selected for HTML output. +pygments_style = "sphinx" +pygments_dark_style = "monokai" + +# These options are generally used to change the look and feel of the theme. +html_theme_options = {} + +# If given, this must be the name of an image file (path relative to the +# configuration directory) that is the favicon of the docs, or URL that +# points an image file for the favicon. +html_favicon = "favicon.ico" + + +# 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 = [] diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..da452c5 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,31 @@ + +AaC Plant-UML Plugin +==================== + +Plant UML - Generate `Plant UML`_ from your AaC model. + +"The AaC Plant-UML (aac-puml) Plugin is an extension of the core AaC tool and generates a diagram from an AaC model. General AaC documentation can be found `here`_. + +.. _Plant UML: https://plantuml.com +.. _here: https://arch-as-code.org + +Installation +------------ +AaC requires Python 3.9.13 installed prior to use. Install the Plant UML AaC plugin using pip:: + +pip install aac-puml + +.. code-block:: bash + +Commands +-------- + +aac puml-component +~~~~~~~~~~~~~~~~~~ + +aac puml-object +~~~~~~~~~~~~~~~ + +aac puml-sequence +~~~~~~~~~~~~~~~~~ + diff --git a/python/.pylintrc b/python/.pylintrc new file mode 100644 index 0000000..4053377 --- /dev/null +++ b/python/.pylintrc @@ -0,0 +1,564 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-whitelist= + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use. +jobs=0 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=print-statement, + parameter-unpacking, + unpacking-in-except, + old-raise-syntax, + backtick, + long-suffix, + old-ne-operator, + old-octal-literal, + import-star-module-level, + non-ascii-bytes-literal, + raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead, + apply-builtin, + basestring-builtin, + buffer-builtin, + cmp-builtin, + coerce-builtin, + execfile-builtin, + file-builtin, + long-builtin, + raw_input-builtin, + reduce-builtin, + standarderror-builtin, + unicode-builtin, + xrange-builtin, + coerce-method, + delslice-method, + getslice-method, + setslice-method, + no-absolute-import, + old-division, + dict-iter-method, + dict-view-method, + next-method-called, + metaclass-assignment, + indexing-exception, + raising-string, + reload-builtin, + oct-method, + hex-method, + nonzero-method, + cmp-method, + input-builtin, + round-builtin, + intern-builtin, + unichr-builtin, + map-builtin-not-iterating, + zip-builtin-not-iterating, + range-builtin-not-iterating, + filter-builtin-not-iterating, + using-cmp-argument, + eq-without-hash, + div-method, + idiv-method, + rdiv-method, + exception-message-attribute, + invalid-str-codec, + sys-max-int, + bad-python3-import, + deprecated-string-function, + deprecated-str-translate-call, + deprecated-itertools-function, + deprecated-types-field, + next-method-defined, + dict-items-not-iterating, + dict-keys-not-iterating, + dict-values-not-iterating, + deprecated-operator-function, + deprecated-urllib-function, + xreadlines-attribute, + deprecated-sys-function, + exception-escape, + comprehension-escape, + import-error, + logging-fstring-interpolation, + global-statement + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore. +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. +#argument-rgx= + +# Naming style matching correct attribute names. +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. +#class-attribute-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _ + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=yes + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. +#variable-rgx= + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package.. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )?<?https?://\S+>?$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=120 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[LOGGING] + +# Format style used to check logging format string. `old` means using % +# formatting, while `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[IMPORTS] + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules=optparse,tkinter.tix + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled). +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled). +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + + +[DESIGN] + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement. +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception". +overgeneral-exceptions=Exception diff --git a/python/.python-version b/python/.python-version new file mode 100644 index 0000000..21af950 --- /dev/null +++ b/python/.python-version @@ -0,0 +1 @@ +3.9.13 diff --git a/python/README.txt b/python/README.txt new file mode 100644 index 0000000..f5b0b54 --- /dev/null +++ b/python/README.txt @@ -0,0 +1,25 @@ + +PYTHON VERSION COMPATIBILITY: + Currently, Python version 3.9.13 is required to avoid certain dependency version issues. + +pyproject.toml vs setup.py + Previously, this project was built with dependency information kept in a setup.py script. + However, the preferred method is to use pyproject.toml to set the project-level options. + Required modules are kept in the requirements.in file, and then the pip-compile command is + used to add hashes to the requirements.txt file for enhanced security (see additional + instructions below). + +TO BUILD FROM TERMINAL: + cd python + pip install -e . + python -m build + +TO TEST FROM TERMINAL: + cd python + pip install -e . + tox -e py39 + +To generate a requirements.txt file populated with hashes, use: + pip install pip-tools + pip-compile requirements.in --generate-hashes + diff --git a/pyproject.toml b/python/pyproject.toml similarity index 66% rename from pyproject.toml rename to python/pyproject.toml index 30918ca..83365ef 100644 --- a/pyproject.toml +++ b/python/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=61.0", "aac"] +requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] @@ -7,10 +7,15 @@ name = "aac-puml" version = "0.0.1" authors = [ { name="Patrick Malone", email="patrick.malone@ngc.com" }, -] +] description = "PlantUML diagram output plugin for AaC (Architecture-as-Code) project" +requires-python = "== 3.9.13" +dependencies = [ + "aac" +] readme = "README.md" -requires-python = ">=3.9" +license = {text = "MIT License"} +keywords = ["SysML", "Architecture-as-Code", "System Engineering"] classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", @@ -19,4 +24,4 @@ classifiers = [ [project.urls] Homepage = "https://github.com/DevOps-MBSE/aac-puml" -Issues = "https://github.com/DevOps-MBSE/aac-puml/issues" \ No newline at end of file +Issues = "https://github.com/DevOps-MBSE/aac-puml/issues" diff --git a/python/requirements.in b/python/requirements.in new file mode 100644 index 0000000..ff575cc --- /dev/null +++ b/python/requirements.in @@ -0,0 +1,12 @@ +build==1.1.1 +pipdeptree==2.16.1 +sphinx==7.2.6 +myst-parser==2.0.0 +tox==4.14.1 +sphinx_contributors==0.2.7 +sphinx-copybutton==0.5.2 +furo==2024.1.29 +nose2==0.14.1 +coverage==7.4.3 +pyflakes==2.4 +flake8==4.0 diff --git a/python/requirements.txt b/python/requirements.txt new file mode 100644 index 0000000..33664d7 --- /dev/null +++ b/python/requirements.txt @@ -0,0 +1,497 @@ +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# pip-compile --generate-hashes requirements.in +# +alabaster==0.7.16 \ + --hash=sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65 \ + --hash=sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 + # via sphinx +babel==2.14.0 \ + --hash=sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363 \ + --hash=sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287 + # via sphinx +beautifulsoup4==4.12.3 \ + --hash=sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051 \ + --hash=sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed + # via furo +build==1.1.1 \ + --hash=sha256:8ed0851ee76e6e38adce47e4bee3b51c771d86c64cf578d0c2245567ee200e73 \ + --hash=sha256:8eea65bb45b1aac2e734ba2cc8dad3a6d97d97901a395bd0ed3e7b46953d2a31 + # via -r requirements.in +cachetools==5.3.3 \ + --hash=sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945 \ + --hash=sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105 + # via tox +certifi==2024.2.2 \ + --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ + --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 + # via requests +chardet==5.2.0 \ + --hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \ + --hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 + # via tox +charset-normalizer==3.3.2 \ + --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ + --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ + --hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \ + --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ + --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ + --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ + --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ + --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ + --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ + --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ + --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ + --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ + --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ + --hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \ + --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ + --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ + --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ + --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ + --hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \ + --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ + --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ + --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ + --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ + --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ + --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ + --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ + --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ + --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ + --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ + --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ + --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ + --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ + --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ + --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ + --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ + --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ + --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ + --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ + --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ + --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ + --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ + --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ + --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ + --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ + --hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \ + --hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \ + --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ + --hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \ + --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ + --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ + --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ + --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ + --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ + --hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \ + --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ + --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ + --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ + --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ + --hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \ + --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ + --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ + --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ + --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ + --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ + --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ + --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ + --hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \ + --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ + --hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \ + --hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \ + --hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \ + --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ + --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ + --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ + --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ + --hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \ + --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ + --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ + --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ + --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ + --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ + --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ + --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ + --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ + --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ + --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ + --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ + --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ + --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ + --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 + # via requests +colorama==0.4.6 \ + --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ + --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 + # via tox +coverage==7.4.3 \ + --hash=sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa \ + --hash=sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003 \ + --hash=sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f \ + --hash=sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c \ + --hash=sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e \ + --hash=sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0 \ + --hash=sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9 \ + --hash=sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52 \ + --hash=sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e \ + --hash=sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454 \ + --hash=sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0 \ + --hash=sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079 \ + --hash=sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352 \ + --hash=sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f \ + --hash=sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30 \ + --hash=sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe \ + --hash=sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113 \ + --hash=sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765 \ + --hash=sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc \ + --hash=sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e \ + --hash=sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501 \ + --hash=sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7 \ + --hash=sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2 \ + --hash=sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f \ + --hash=sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4 \ + --hash=sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524 \ + --hash=sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c \ + --hash=sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51 \ + --hash=sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840 \ + --hash=sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6 \ + --hash=sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee \ + --hash=sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e \ + --hash=sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45 \ + --hash=sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba \ + --hash=sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d \ + --hash=sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3 \ + --hash=sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10 \ + --hash=sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e \ + --hash=sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb \ + --hash=sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9 \ + --hash=sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a \ + --hash=sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47 \ + --hash=sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1 \ + --hash=sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3 \ + --hash=sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914 \ + --hash=sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328 \ + --hash=sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6 \ + --hash=sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d \ + --hash=sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0 \ + --hash=sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94 \ + --hash=sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc \ + --hash=sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2 + # via -r requirements.in +distlib==0.3.8 \ + --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ + --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 + # via virtualenv +docutils==0.20.1 \ + --hash=sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6 \ + --hash=sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b + # via + # myst-parser + # sphinx +filelock==3.13.1 \ + --hash=sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e \ + --hash=sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c + # via + # tox + # virtualenv +flake8==4.0.0 \ + --hash=sha256:124554bfd067e04d891258c0208a764b512ca3a94c8a3c06bea56af539dd74db \ + --hash=sha256:b52d27e627676b015340c3b1c72bc9259a6cacc9341712fb8f01ddfaaa2c651a + # via -r requirements.in +furo==2024.1.29 \ + --hash=sha256:3548be2cef45a32f8cdc0272d415fcb3e5fa6a0eb4ddfe21df3ecf1fe45a13cf \ + --hash=sha256:4d6b2fe3f10a6e36eb9cc24c1e7beb38d7a23fc7b3c382867503b7fcac8a1e02 + # via -r requirements.in +idna==3.6 \ + --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ + --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f + # via requests +imagesize==1.4.1 \ + --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \ + --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a + # via sphinx +importlib-metadata==7.0.2 \ + --hash=sha256:198f568f3230878cb1b44fbd7975f87906c22336dba2e4a7f05278c281fbd792 \ + --hash=sha256:f4bc4c0c070c490abf4ce96d715f68e95923320370efb66143df00199bb6c100 + # via + # build + # sphinx +jinja2==3.1.3 \ + --hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \ + --hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90 + # via + # myst-parser + # sphinx +markdown-it-py==3.0.0 \ + --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ + --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb + # via + # mdit-py-plugins + # myst-parser +markupsafe==2.1.5 \ + --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ + --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ + --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ + --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ + --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ + --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ + --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ + --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ + --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ + --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ + --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ + --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ + --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ + --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ + --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ + --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ + --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ + --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ + --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ + --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ + --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ + --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ + --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ + --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ + --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ + --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ + --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ + --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ + --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ + --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ + --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ + --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ + --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ + --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ + --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ + --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ + --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ + --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ + --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ + --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ + --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ + --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ + --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ + --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ + --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ + --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ + --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ + --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ + --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ + --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ + --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ + --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ + --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ + --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ + --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ + --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ + --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ + --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ + --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ + --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 + # via jinja2 +mccabe==0.6.1 \ + --hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \ + --hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f + # via flake8 +mdit-py-plugins==0.4.0 \ + --hash=sha256:b51b3bb70691f57f974e257e367107857a93b36f322a9e6d44ca5bf28ec2def9 \ + --hash=sha256:d8ab27e9aed6c38aa716819fedfde15ca275715955f8a185a8e1cf90fb1d2c1b + # via myst-parser +mdurl==0.1.2 \ + --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ + --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba + # via markdown-it-py +myst-parser==2.0.0 \ + --hash=sha256:7c36344ae39c8e740dad7fdabf5aa6fc4897a813083c6cc9990044eb93656b14 \ + --hash=sha256:ea929a67a6a0b1683cdbe19b8d2e724cd7643f8aa3e7bb18dd65beac3483bead + # via -r requirements.in +nose2==0.14.1 \ + --hash=sha256:7f8f03a21c9de2c33015933afcef72bf8e4a2d5dfec3b40092287de6e41b093a \ + --hash=sha256:dfbf0d90c98b8d7bbf47d7721c7554ffcca86828ec074c985bb6ecc83c445a4e + # via -r requirements.in +packaging==23.2 \ + --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \ + --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7 + # via + # build + # pyproject-api + # sphinx + # tox +pipdeptree==2.16.1 \ + --hash=sha256:7131023df30220678b6a42c7372ce07453b39e0b3df935b129e832f0acf96b8a \ + --hash=sha256:f1ca64ce4aff9373613711048b9c4e8106ad955dea0dd962b7974fa168d7650a + # via -r requirements.in +platformdirs==4.2.0 \ + --hash=sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068 \ + --hash=sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768 + # via + # tox + # virtualenv +pluggy==1.4.0 \ + --hash=sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981 \ + --hash=sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be + # via tox +pycodestyle==2.8.0 \ + --hash=sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20 \ + --hash=sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f + # via flake8 +pyflakes==2.4.0 \ + --hash=sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c \ + --hash=sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e + # via + # -r requirements.in + # flake8 +pygments==2.17.2 \ + --hash=sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c \ + --hash=sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367 + # via + # furo + # sphinx +pyproject-api==1.6.1 \ + --hash=sha256:1817dc018adc0d1ff9ca1ed8c60e1623d5aaca40814b953af14a9cf9a5cae538 \ + --hash=sha256:4c0116d60476b0786c88692cf4e325a9814965e2469c5998b830bba16b183675 + # via tox +pyproject-hooks==1.0.0 \ + --hash=sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8 \ + --hash=sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5 + # via build +pyyaml==6.0.1 \ + --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ + --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ + --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \ + --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ + --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ + --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ + --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ + --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ + --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ + --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ + --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \ + --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \ + --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ + --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \ + --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ + --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ + --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ + --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ + --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ + --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ + --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ + --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \ + --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ + --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ + --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ + --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \ + --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ + --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ + --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ + --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ + --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ + --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ + --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ + --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ + --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \ + --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ + --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ + --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ + --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ + --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ + --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ + --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \ + --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ + --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \ + --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ + --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ + --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ + --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ + --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ + --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f + # via myst-parser +requests==2.31.0 \ + --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ + --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 + # via sphinx +snowballstemmer==2.2.0 \ + --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 \ + --hash=sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a + # via sphinx +soupsieve==2.5 \ + --hash=sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690 \ + --hash=sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7 + # via beautifulsoup4 +sphinx==7.2.6 \ + --hash=sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560 \ + --hash=sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5 + # via + # -r requirements.in + # furo + # myst-parser + # sphinx-basic-ng + # sphinx-contributors + # sphinx-copybutton +sphinx-basic-ng==1.0.0b2 \ + --hash=sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9 \ + --hash=sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b + # via furo +sphinx-contributors==0.2.7 \ + --hash=sha256:aace731366096f2104a06eca77b9354b11768ddec149d699520c254f09cbb4f4 \ + --hash=sha256:f409295eb22f05606528ff3a9b93b4ae076d93d3153de13ff47bfcdd1c792463 + # via -r requirements.in +sphinx-copybutton==0.5.2 \ + --hash=sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd \ + --hash=sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e + # via -r requirements.in +sphinxcontrib-applehelp==1.0.8 \ + --hash=sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619 \ + --hash=sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4 + # via sphinx +sphinxcontrib-devhelp==1.0.6 \ + --hash=sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f \ + --hash=sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3 + # via sphinx +sphinxcontrib-htmlhelp==2.0.5 \ + --hash=sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015 \ + --hash=sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04 + # via sphinx +sphinxcontrib-jsmath==1.0.1 \ + --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \ + --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8 + # via sphinx +sphinxcontrib-qthelp==1.0.7 \ + --hash=sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6 \ + --hash=sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182 + # via sphinx +sphinxcontrib-serializinghtml==1.1.10 \ + --hash=sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7 \ + --hash=sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f + # via sphinx +tomli==2.0.1 \ + --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ + --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f + # via + # build + # pyproject-api + # pyproject-hooks + # tox +tox==4.14.1 \ + --hash=sha256:b03754b6ee6dadc70f2611da82b4ed8f625fcafd247e15d1d0cb056f90a06d3b \ + --hash=sha256:f0ad758c3bbf7e237059c929d3595479363c3cdd5a06ac3e49d1dd020ffbee45 + # via -r requirements.in +urllib3==2.2.1 \ + --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ + --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 + # via requests +virtualenv==20.25.1 \ + --hash=sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a \ + --hash=sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197 + # via tox +zipp==3.17.0 \ + --hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \ + --hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0 + # via importlib-metadata diff --git a/python/secure_install/README.md b/python/secure_install/README.md new file mode 100644 index 0000000..64c27ba --- /dev/null +++ b/python/secure_install/README.md @@ -0,0 +1,41 @@ +# Architecture-as-Code Secure Installation +In order to support portability of Architecture-as-Code, and to provide a secure, repeatable installation method for AaC users, we have created +this one-stop installation package for each release of the AaC python package. + +In this package we provide a couple different methods to install AaC and its dependencies, depending on your needs and environment. This installation package only supports installing AaC in environments with Python 3.9.13, 3.10, or 3.11. + +## Hash-Verified PyPI Dependencies +When we create a release of AaC, we'll include a list of the runtime dependencies for AaC and their hash values. When you install via `pip install --require-hashes -r requirements.txt` +it will pull the pinned package versions, and verify the package's hash value against the value in the requirements file for data integrity. If you prefer to avoid executing the long pip command, you can run the `install_aac_verified_index` script. The installed artifacts will be sourced from PyPI. + + +### Linux/macOS +Github's artifact archiver doesn't preserve permissions so you'll have to make the script executable. + +``` +chmod +x ./install_aac_verified_index.bash +./install_aac_verified_index.bash +``` + +### Windows + +``` +.\install_aac_verified_index.bat +``` + +## Air-Gapped Installation +For air-gapped installations without access to PyPI, or which may not want to use the indexed artifacts, we provide a PyPI-less (no index) installation method. You can execute `pip install --require-hashes -r requirements.txt --no-index --find-links ./` or the `install_aac_air_gap` script. This mode will verify the hashes of the AaC and its runtime dependencies, packaged as wheels, and then install them -- the runtime artifacts are not pulled from PyPI. + +### Linux/macOS +Github's artifact archiver doesn't preserve permissions so you'll have to make the script executable. + +``` +chmod +x ./install_aac_air_gap.bash +./install_aac_air_gap.bash +``` + +### Windows + +``` +.\install_aac_air_gap.bat +``` diff --git a/python/secure_install/install_scripts/install_aac_air_gap.bash b/python/secure_install/install_scripts/install_aac_air_gap.bash new file mode 100644 index 0000000..a1a4b05 --- /dev/null +++ b/python/secure_install/install_scripts/install_aac_air_gap.bash @@ -0,0 +1,8 @@ +#!/bin/bash + +# This script will install AaC and its dependencies via the wheel files. + +install_script_dir=$(dirname "$0") +cd $install_script_dir + +pip install --require-hashes -r requirements.txt --no-index --find-links ./ \ No newline at end of file diff --git a/python/secure_install/install_scripts/install_aac_air_gap.bat b/python/secure_install/install_scripts/install_aac_air_gap.bat new file mode 100644 index 0000000..d0ad118 --- /dev/null +++ b/python/secure_install/install_scripts/install_aac_air_gap.bat @@ -0,0 +1,7 @@ +REM This script will install AaC and its dependencies via the wheel files. + +@echo off + +cd /D "%~dp0" + +python -m pip "install" "--require-hashes" "-r" "requirements.txt" "--no-index" "--find-links" "./" \ No newline at end of file diff --git a/python/secure_install/install_scripts/install_aac_verified_index.bash b/python/secure_install/install_scripts/install_aac_verified_index.bash new file mode 100644 index 0000000..e31ddc5 --- /dev/null +++ b/python/secure_install/install_scripts/install_aac_verified_index.bash @@ -0,0 +1,8 @@ +#!/bin/bash + +# This script will install AaC and its dependencies via PyPI. + +install_script_dir=$(dirname "$0") +cd $install_script_dir + +pip install --require-hashes -r requirements.txt diff --git a/python/secure_install/install_scripts/install_aac_verified_index.bat b/python/secure_install/install_scripts/install_aac_verified_index.bat new file mode 100644 index 0000000..7b11a77 --- /dev/null +++ b/python/secure_install/install_scripts/install_aac_verified_index.bat @@ -0,0 +1,7 @@ +REM This script will install AaC and its dependencies via PyPI. + +@echo off + +cd /D "%~dp0" + +python -m pip "install" "--require-hashes" "-r" "requirements.txt" diff --git a/python/secure_install/pipeline_scripts/create_install_archive.bash b/python/secure_install/pipeline_scripts/create_install_archive.bash new file mode 100755 index 0000000..4e7ed70 --- /dev/null +++ b/python/secure_install/pipeline_scripts/create_install_archive.bash @@ -0,0 +1,28 @@ +#!/bin/bash + +# This script gathers AaC's runtime dependencies, creates a hash file, pulls in install scripts, and generally +# prepares the secure installation file. We'll delegate to Github Action's automatic zipping of artifacts to +# ultimately compress the directory into an archive. + +install_script_dir=$(dirname "$0") +cd $install_script_dir +cd ../ + +version=$(aac version | sed -e 's/\x1b\[[0-9;]*m//g') # Make sure to remove coloring from AaC command output +install_dir="aac_secure_install_$version" + +[[ -d $install_dir ]] && rm -r $install_dir +mkdir $install_dir +cp -p -r install_scripts/*.bash $install_dir +cp README.md $install_dir +cd $install_dir + +pip wheel ../../ +pip-compile --generate-hashes ../../setup.py +mv ../../requirements.txt . +pip download --python-version 3.9.13 -r requirements.txt -d . --no-deps +pip download --python-version 3.10 -r requirements.txt -d . --no-deps +pip download --python-version 3.11 -r requirements.txt -d . --no-deps +pip hash aac-*.whl | sed -r "s/l:/l \\\/g" | sed -r "s/--hash/ --hash/g" >> requirements.txt # This will only work for the main-branch pipeline that is deploying the artifact to PyPI + +echo "$install_dir" > ../install_dir_name.txt diff --git a/python/secure_install/pipeline_scripts/create_install_archive.bat b/python/secure_install/pipeline_scripts/create_install_archive.bat new file mode 100755 index 0000000..925d5e4 --- /dev/null +++ b/python/secure_install/pipeline_scripts/create_install_archive.bat @@ -0,0 +1,30 @@ +@REM https://daniel-sc.github.io/bash-shell-to-bat-converter/ +@REM This script gathers AaC's runtime dependencies, creates a hash file, pulls in install scripts, and generally +@REM prepares the secure installation file. We'll delegate to Github Action's automatic zipping of artifacts to +@REM ultimately compress the directory into an archive. +@echo off + +cd /D "%~dp0" + +SET install_script_dir="%cd%\..\" +cd "%install_script_dir%" + +For /F %%A in ('"python -m aac version"') do SET version=%%A +echo "Version %version%" +SET install_dir="%cd%\aac_secure_install_%version%" +IF EXIST "%install_dir%" ( + DEL /S "%install_dir%" +) +mkdir "%install_dir%" +for /R "%cd%\install_scripts\" %%f in (*.bat) do COPY %%f "%install_dir%\." +COPY "%cd%\README.md" "%install_dir%" +cd "%install_dir%" + +python -m piptools compile "--generate-hashes" "%CD%\..\..\setup.py" +mv "%CD%\..\..\requirements.txt" "." +python -m pip wheel "%CD%\..\.." +python -m pip download --python-version 3.9.13 -r requirements.txt -d . --no-deps +python -m pip download --python-version 3.10 -r requirements.txt -d . --no-deps +python -m pip download --python-version 3.11 -r requirements.txt -d . --no-deps +@PowerShell "(python -m pip hash 'aac-%version%-py3-none-any.whl')|%%{$_ -Replace 'l:','l \'}|%%{$_ -Replace '--hash',' --hash'}" >> .\requirements.txt +echo %install_dir% > "%CD%\install_dir_name.txt" diff --git a/src/aac-puml/__init__.py b/python/src/aac-puml/__init__.py similarity index 100% rename from src/aac-puml/__init__.py rename to python/src/aac-puml/__init__.py diff --git a/src/aac-puml/gen_plant_uml.yaml b/python/src/aac-puml/gen_plant_uml.yaml similarity index 100% rename from src/aac-puml/gen_plant_uml.yaml rename to python/src/aac-puml/gen_plant_uml.yaml diff --git a/src/aac-puml/gen_plant_uml_impl.py b/python/src/aac-puml/gen_plant_uml_impl.py similarity index 100% rename from src/aac-puml/gen_plant_uml_impl.py rename to python/src/aac-puml/gen_plant_uml_impl.py diff --git a/src/aac-puml/puml_helpers.py b/python/src/aac-puml/puml_helpers.py similarity index 100% rename from src/aac-puml/puml_helpers.py rename to python/src/aac-puml/puml_helpers.py diff --git a/src/aac-puml/puml_requirements.py b/python/src/aac-puml/puml_requirements.py similarity index 100% rename from src/aac-puml/puml_requirements.py rename to python/src/aac-puml/puml_requirements.py diff --git a/src/aac-puml/templates/component/__init__.py b/python/src/aac-puml/templates/__init__.py similarity index 100% rename from src/aac-puml/templates/component/__init__.py rename to python/src/aac-puml/templates/__init__.py diff --git a/src/aac-puml/templates/object/__init__.py b/python/src/aac-puml/templates/component/__init__.py similarity index 100% rename from src/aac-puml/templates/object/__init__.py rename to python/src/aac-puml/templates/component/__init__.py diff --git a/src/aac-puml/templates/component/component_diagram.puml.jinja2 b/python/src/aac-puml/templates/component/component_diagram.puml.jinja2 similarity index 100% rename from src/aac-puml/templates/component/component_diagram.puml.jinja2 rename to python/src/aac-puml/templates/component/component_diagram.puml.jinja2 diff --git a/src/aac-puml/templates/requirements/__init__.py b/python/src/aac-puml/templates/object/__init__.py similarity index 100% rename from src/aac-puml/templates/requirements/__init__.py rename to python/src/aac-puml/templates/object/__init__.py diff --git a/src/aac-puml/templates/object/object_diagram.puml.jinja2 b/python/src/aac-puml/templates/object/object_diagram.puml.jinja2 similarity index 100% rename from src/aac-puml/templates/object/object_diagram.puml.jinja2 rename to python/src/aac-puml/templates/object/object_diagram.puml.jinja2 diff --git a/src/aac-puml/templates/sequence/__init__.py b/python/src/aac-puml/templates/requirements/__init__.py similarity index 100% rename from src/aac-puml/templates/sequence/__init__.py rename to python/src/aac-puml/templates/requirements/__init__.py diff --git a/src/aac-puml/templates/requirements/requirements_diagram.puml.jinja2 b/python/src/aac-puml/templates/requirements/requirements_diagram.puml.jinja2 similarity index 100% rename from src/aac-puml/templates/requirements/requirements_diagram.puml.jinja2 rename to python/src/aac-puml/templates/requirements/requirements_diagram.puml.jinja2 diff --git a/python/src/aac-puml/templates/sequence/__init__.py b/python/src/aac-puml/templates/sequence/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/aac-puml/templates/sequence/sequence_diagram.puml.jinja2 b/python/src/aac-puml/templates/sequence/sequence_diagram.puml.jinja2 similarity index 100% rename from src/aac-puml/templates/sequence/sequence_diagram.puml.jinja2 rename to python/src/aac-puml/templates/sequence/sequence_diagram.puml.jinja2 diff --git a/tests/test_gen_plant_uml.py b/python/tests/test_gen_plant_uml.py similarity index 100% rename from tests/test_gen_plant_uml.py rename to python/tests/test_gen_plant_uml.py diff --git a/python/tox.ini b/python/tox.ini new file mode 100644 index 0000000..cb06bd9 --- /dev/null +++ b/python/tox.ini @@ -0,0 +1,56 @@ +[testenv] +deps = .[test] +commands = nose2 -c tox.ini {posargs} + +[flake8] +extend-select = W504 +ignore = E501, E402, D202, D401, W503, D212 +exclude = .git,__pycache__,docs/source/conf.py,old,build,dist,venv,.env,.venv,.eggs,.tox +max-complexity = 10 +# The GitHub editor is 127 chars wide +max-line-length = 127 +statistics = True +show-source = True +docstring-convention = google +count = True +per-file-ignores = + # Ignore docstring errors in tests + *tests/*:D100,D101,D102,D103,D104,D417,D200,ANN101,ANN201,W293,W291,ANN001,E731,W605 + *setup.py:D100 + *src/aac-puml/templates/**:D104 + +[unittest] +start-dir = . +code-directories = src +plugins = nose2.plugins.mp + +[multiprocess] +always-on = True +processes = 4 + +[coverage] +coverage = src +always-on = True +coverage-config = tox.ini + +[run] +branch = True +omit = + *.jinja2 + +[report] +fail_under = 90.00 +precision = 2 +show_missing = True +skip_empty = True +skip_covered = True +sort = cover + +[html] +directory = html_code_coverage +skip_covered = True + +[tox] +envlist = + py39 + py310