├── .asf.yaml ├── .dockerignore ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── labeler.yml └── workflows │ ├── ci.yaml │ └── labeler.yaml ├── .gitignore ├── .markdownlint.yml ├── .pre-commit-config.yaml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile.dev ├── LICENSE ├── NOTICE ├── README.md ├── images └── kibble-logo.png ├── kibble ├── __init__.py ├── __main__.py ├── cli │ ├── __init__.py │ ├── commands │ │ ├── __init__.py │ │ ├── config_command.py │ │ ├── db_command.py │ │ ├── scanners_command.py │ │ ├── server_command.py │ │ └── version_command.py │ └── parser.py ├── database │ └── __init__.py ├── scanners │ └── __init__.py ├── server │ └── __init__.py └── version.py ├── license-templates ├── LICENSE.rst └── LICENSE.txt ├── pylintrc ├── pyproject.toml ├── scripts └── pre_commit_generate_cli_help.sh ├── setup.cfg ├── setup.py ├── tests ├── __init__.py └── cli │ ├── __init__.py │ ├── commands │ ├── __init__.py │ ├── test_config_command.py │ ├── test_db_command.py │ ├── test_scanners_command.py │ ├── test_server_command.py │ └── test_version_command.py │ └── test_parser.py └── yamllint-config.yml /.asf.yaml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | # https://cwiki.apache.org/confluence/display/INFRA/git+-+.asf.yaml+features 19 | --- 20 | github: 21 | description: "Apache Kibble - a tool to collect, aggregate and visualize data about any software project" 22 | homepage: https://kibble.apache.org/ 23 | labels: 24 | - kibble 25 | - big-data 26 | - open-source 27 | - python 28 | - visualization 29 | 30 | features: 31 | # Enable issues management 32 | issues: true 33 | # Enable wiki for documentation 34 | wiki: false 35 | # Enable projects for project management boards 36 | projects: true 37 | 38 | enabled_merge_buttons: 39 | squash: true 40 | merge: false 41 | rebase: false 42 | 43 | protected_branches: 44 | main: 45 | required_pull_request_reviews: 46 | required_approving_review_count: 1 47 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Ignore everything 2 | ** 3 | 4 | # Allow only these directories 5 | !kibble 6 | !tests 7 | !scripts 8 | !licenses 9 | 10 | # Setup/version configuration 11 | !setup.cfg 12 | !setup.py 13 | 14 | # Add required dev configs 15 | !.dockerignore 16 | !.markdownlint.yml 17 | !.pre-commit-config.yaml 18 | !pylintrc 19 | !pyproject.toml 20 | !yamllint-config.yml 21 | 22 | # Exclude python generated files 23 | **/__pycache__/ 24 | **/*.py[cod] 25 | **/*$py.class 26 | **/.pytest_cache/ 27 | **/env/ 28 | **/build/ 29 | **/develop-eggs/ 30 | **/dist/ 31 | **/downloads/ 32 | **/eggs/ 33 | **/.eggs/ 34 | **/lib/ 35 | **/lib64/ 36 | **/parts/ 37 | **/sdist/ 38 | **/var/ 39 | **/wheels/ 40 | **/*.egg-info/ 41 | **/.installed.cfg 42 | **/*.egg 43 | 44 | # Exclude temporary vi files 45 | **/*~ 46 | 47 | # Exclude output files 48 | **/*.out 49 | 50 | # Exclude auto-generated Finder files on Mac OS 51 | **/.DS_Store 52 | **/Thumbs.db 53 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # All repo 2 | * @turbaszek @michalslowikowski00 3 | 4 | # Docs stuff 5 | README.md @sharanf 6 | CODE_OF_CONDUCT.md @sharanf 7 | CONTRIBUTING.md @sharanf 8 | docs/ @sharanf 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Problems or issues with Kibble projects 4 | title: '' 5 | labels: 'kind:bug' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 19 | 20 | **Description:** 21 | 26 | 27 | **Reproduction steps:** 28 | 34 | **Actual result:** 35 | 36 | 37 | **OS:** 38 | 39 | 40 | **Logs:** 41 | 42 | 43 | **Other:** 44 | 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | blank_issues_enabled: false 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Idea or feature request 4 | title: '' 5 | labels: 'kind:feature' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 20 | 21 | **Description** 22 | 23 | 24 | **Use case** 25 | 31 | 32 | **Related Issues** 33 | 34 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | --- 2 | area:api: 3 | - 'kibble/server/*' 4 | 5 | area:cli: 6 | - 'kibble/cli/*' 7 | 8 | area:scanners: 9 | - 'kibble/scanners/*' 10 | 11 | area:ui: 12 | - 'ui/*' 13 | 14 | area:docs: 15 | - 'docs/*' 16 | - '*.md' 17 | 18 | aread:database: 19 | - 'kibble/database/*' 20 | 21 | area:dev: 22 | - '.github/*' 23 | - '.pre-commit.config.yaml' 24 | - '.asf.yaml' 25 | - 'Dockerfile*' 26 | - 'docker*' 27 | - 'setup.*' 28 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | --- 18 | name: CI 19 | on: # yamllint disable-line rule:truthy 20 | push: 21 | branches: ['main'] 22 | pull_request: 23 | branches: ['main'] 24 | 25 | jobs: 26 | statics: 27 | name: Static checks 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/checkout@v2 31 | - uses: actions/setup-python@v2 32 | - run: pip install '.[devel]' 33 | - run: pre-commit install 34 | - run: pre-commit run --all-files 35 | run-tests: 36 | name: Run Tests 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: actions/checkout@v2 40 | - uses: actions/setup-python@v2 41 | with: 42 | python-version: '3.8' 43 | - run: pip install '.[devel]' 44 | - run: pytest tests 45 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yaml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | --- 18 | name: "PR labeler" 19 | on: # yamllint disable-line rule:truthy 20 | - pull_request_target 21 | 22 | jobs: 23 | triage: 24 | name: Label 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/labeler@main 28 | with: 29 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Apache Kibble files 2 | api/yaml/kibble.yaml* 3 | kibble/api/yaml/kibble.yaml* 4 | 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | cover/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | .pybuilder/ 80 | target/ 81 | 82 | # Jupyter Notebook 83 | .ipynb_checkpoints 84 | 85 | # IPython 86 | profile_default/ 87 | ipython_config.py 88 | 89 | # pyenv 90 | # For a library or package, you might want to ignore these files since the code is 91 | # intended to run in multiple environments; otherwise, check them in: 92 | # .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 102 | __pypackages__/ 103 | 104 | # Celery stuff 105 | celerybeat-schedule 106 | celerybeat.pid 107 | 108 | # SageMath parsed files 109 | *.sage.py 110 | 111 | # Environments 112 | .env 113 | .venv 114 | env/ 115 | venv/ 116 | ENV/ 117 | env.bak/ 118 | venv.bak/ 119 | 120 | # Spyder project settings 121 | .spyderproject 122 | .spyproject 123 | 124 | # Rope project settings 125 | .ropeproject 126 | 127 | # mkdocs documentation 128 | /site 129 | 130 | # mypy 131 | .mypy_cache/ 132 | .dmypy.json 133 | dmypy.json 134 | 135 | # Pyre type checker 136 | .pyre/ 137 | 138 | # pytype static type analyzer 139 | .pytype/ 140 | 141 | # Cython debug symbols 142 | cython_debug/ 143 | 144 | # JetBrains IDE 145 | /.idea 146 | 147 | # File system 148 | .DS_Store 149 | -------------------------------------------------------------------------------- /.markdownlint.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | # 18 | --- 19 | # MD004/ul-style 20 | MD004: false 21 | 22 | # MD007/ul-indent 23 | MD007: false 24 | 25 | # MD012/no-multiple-blanks 26 | MD012: false 27 | 28 | # MD013 Line length 29 | MD013: false 30 | 31 | # MD024/no-duplicate-heading/no-duplicate-header 32 | MD024: false 33 | 34 | # MD026/no-trailing-punctuation 35 | MD026: false 36 | 37 | # MD029/ol-prefix 38 | MD029: false 39 | 40 | # MD030/list-marker-space 41 | MD030: false 42 | 43 | # MD033/no-inline-html 44 | MD033: false 45 | 46 | # MD034/no-bare-urls 47 | MD034: false 48 | 49 | # MD036/no-emphasis-as-heading/no-emphasis-as-header 50 | MD036: false 51 | 52 | # MD040/fenced-code-language 53 | MD040: false 54 | 55 | # MD041/first-line-heading/first-line-h1 56 | MD041: false 57 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # Licensed to the Apache Software Foundation (ASF) under one or more 4 | # contributor license agreements. See the NOTICE file distributed with 5 | # this work for additional information regarding copyright ownership. 6 | # The ASF licenses this file to You under the Apache License, Version 2.0 7 | # (the "License"); you may not use this file except in compliance with 8 | # the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | --- 19 | default_stages: [commit, push] 20 | default_language_version: 21 | # force all unspecified python hooks to run python3 22 | python: python3 23 | minimum_pre_commit_version: "1.20.0" 24 | 25 | repos: 26 | - repo: meta 27 | hooks: 28 | - id: identity 29 | - id: check-hooks-apply 30 | 31 | - repo: https://github.com/pre-commit/pre-commit-hooks 32 | rev: v3.4.0 33 | hooks: 34 | - id: check-merge-conflict 35 | - id: debug-statements 36 | - id: check-builtin-literals 37 | - id: detect-private-key 38 | - id: end-of-file-fixer 39 | - id: mixed-line-ending 40 | - id: check-executables-have-shebangs 41 | - id: trailing-whitespace 42 | - id: fix-encoding-pragma 43 | args: 44 | - --remove 45 | 46 | - repo: https://github.com/thlorenz/doctoc.git 47 | rev: v2.0.0 48 | hooks: 49 | - id: doctoc 50 | name: Add TOC for md files 51 | files: ^README\.md$|^CONTRIBUTING\.md$ 52 | args: 53 | - "--maxlevel" 54 | - "2" 55 | 56 | # Licenses 57 | - repo: https://github.com/Lucas-C/pre-commit-hooks 58 | rev: v1.1.9 59 | hooks: 60 | - id: insert-license 61 | name: Add license for all other files 62 | exclude: ^\.github/.*$ 63 | args: 64 | - --comment-style 65 | - "|#|" 66 | - --license-filepath 67 | - license-templates/LICENSE.txt 68 | - --fuzzy-match-generates-todo 69 | files: > 70 | \.cfg$|^Dockerfile.*$|\.sh$|\.bash$|\.py$|\.yml$|\.yaml$ 71 | - id: insert-license 72 | name: Add license for all rst files 73 | exclude: ^\.github/.*$ 74 | args: 75 | - --comment-style 76 | - "||" 77 | - --license-filepath 78 | - license-templates/LICENSE.rst 79 | - --fuzzy-match-generates-todo 80 | files: \.rst$ 81 | - id: insert-license 82 | name: Add license for all md and html files 83 | files: \.md$|\.html$ 84 | exclude: ^\.github/.*$ 85 | args: 86 | - --comment-style 87 | - "" 88 | - --license-filepath 89 | - license-templates/LICENSE.txt 90 | - --fuzzy-match-generates-todo 91 | 92 | - repo: https://github.com/psf/black 93 | rev: 20.8b1 94 | hooks: 95 | - id: black 96 | args: [--config=./pyproject.toml] 97 | 98 | - repo: https://github.com/timothycrosley/isort 99 | rev: 5.6.4 100 | hooks: 101 | - id: isort 102 | name: Run isort to sort imports 103 | files: \.py$ 104 | # To keep consistent with the global isort skip config defined in setup.cfg 105 | exclude: ^build/.*$|^.tox/.*$|^venv/.*$ 106 | 107 | - repo: https://github.com/pycqa/pydocstyle 108 | rev: 5.1.1 109 | hooks: 110 | - id: pydocstyle 111 | name: Run pydocstyle 112 | args: 113 | - --convention=pep257 114 | - --add-ignore=D100,D102,D104,D105,D107,D205,D400,D401 115 | exclude: | 116 | (?x) 117 | ^tests/.*\.py$| 118 | ^scripts/.*\.py$ 119 | 120 | - repo: https://github.com/adrienverge/yamllint 121 | rev: v1.25.0 122 | hooks: 123 | - id: yamllint 124 | name: Check yaml files with yamllint 125 | entry: yamllint -c yamllint-config.yml --strict 126 | types: [yaml] 127 | 128 | - repo: https://github.com/pre-commit/mirrors-mypy 129 | rev: "v0.812" 130 | hooks: 131 | - id: mypy 132 | 133 | - repo: local 134 | hooks: 135 | - id: pylint 136 | name: Pylint on all sources 137 | entry: pylint 138 | language: system 139 | types: [python] 140 | 141 | - id: consistent-pylint 142 | language: pygrep 143 | name: Check for inconsistent pylint disable/enable without space 144 | entry: "pylint:disable|pylint:enable" 145 | pass_filenames: true 146 | files: \.py$ 147 | 148 | - id: update-help-in-readme 149 | name: Update help in README.md 150 | entry: "./scripts/pre_commit_generate_cli_help.sh" 151 | language: system 152 | files: \.py$ 153 | 154 | - id: markdownlint 155 | name: Run markdownlint 156 | description: "Checks the style of Markdown files." 157 | entry: markdownlint 158 | language: node 159 | types: [markdown] 160 | files: \.(md|mdown|markdown)$ 161 | additional_dependencies: ['markdownlint-cli'] 162 | 163 | - id: flynt 164 | name: Convert to f-strings with flynt 165 | entry: flynt 166 | language: python 167 | language_version: python3 168 | additional_dependencies: ['flynt'] 169 | files: \.py$ 170 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 19 | 20 | # Code of Conduct 21 | 22 | The Apache Kibble project follows the 23 | [Apache Software Foundation code of conduct](https://www.apache.org/foundation/policies/conduct.html). 24 | 25 | If you observe behavior that violates those rules please follow the 26 | [ASF reporting guidelines](https://www.apache.org/foundation/policies/conduct#reporting-guidelines). 27 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 19 | 20 | # Contributing to Apache Kibble 21 | 22 | 23 | 24 | **Table of contents** 25 | 26 | - [Community](#community) 27 | - [Development installation](#development-installation) 28 | - [Testing](#testing) 29 | - [Code Quality](#code-quality) 30 | 31 | 32 | 33 | 34 | ## Community 35 | 36 | The main development and design discussion happens on our mailing lists. 37 | We have a list specifically for development and one for future user questions and feedback. 38 | 39 | To join in the discussion on the design and roadmap, you can send an email to [dev@kibble.apache.org](mailto:dev@kibble.apache.org).
40 | You can subscribe to the list by sending an email to [dev-subscribe@kibble.apache.org](mailto:dev-subscribe@kibble.apache.org).
41 | You can also browse the archives online at [lists.apache.org](https://lists.apache.org/list.html?dev@kibble.apache.org). 42 | 43 | We also have: 44 | 45 | - IRC channel, #kibble on [Freenode](https://webchat.freenode.net/?channels=#kibble) 46 | - Slack channel, #kibble on [ASF slack](https://s.apache.org/slack-invite) 47 | 48 | ## Development installation 49 | 50 | You should be able to install Apache Kibble by simply doing: 51 | 52 | ``` 53 | pip install -e ."[devel]" 54 | ``` 55 | 56 | This will install the Kibble package in editable mode together wit all requirements needed for fluent 57 | development. 58 | 59 | You may also use the development Docker file: 60 | 61 | ``` 62 | docker build -f Dockerfile.dev -t apache/kibble-dev . 63 | docker run apache/kibble-dev kibble 64 | docker run apache/kibble-dev pytest 65 | ``` 66 | 67 | ## Testing 68 | 69 | Apache Kibble project uses [pytest](https://docs.pytest.org/en/stable/) for running testing. Writing 70 | good tests help us avoid regression and unexpected issues. 71 | 72 | In order to run tests all you need to do is call pytest: 73 | 74 | ``` 75 | # Run all tests 76 | pytest 77 | 78 | # Run single test file 79 | pytest tests/cli/commands/test_config_command.py 80 | ``` 81 | 82 | The test can be also run using the dev docker image: 83 | 84 | ``` 85 | ➜ docker run apache/kibble pytest tests/cli/commands/test_config_command.py 86 | ============================= test session starts ============================== 87 | platform linux -- Python 3.8.8, pytest-6.1.1, py-1.10.0, pluggy-0.13.1 -- /usr/local/bin/python 88 | cachedir: .pytest_cache 89 | rootdir: /kibble, configfile: pyproject.toml 90 | collecting ... collected 1 item 91 | 92 | tests/cli/commands/test_config_command.py::TestConfigCommand::test_show PASSED [100%] 93 | 94 | ============================== 1 passed in 0.02s =============================== 95 | ``` 96 | 97 | ## Code Quality 98 | 99 | Apache Kibble project is using different tools to ensure the quality of the code, including: 100 | 101 | - [black](https://github.com/psf/black) 102 | - [pylint](https://www.pylint.org) 103 | - [isort](https://github.com/PyCQA/isort) 104 | - [mypy](https://github.com/python/mypy) 105 | - [pydocstyle](https://github.com/PyCQA/pydocstyle) 106 | 107 | All those tools can be automatically run using [pre-commits](https://pre-commit.com). We encourage you to 108 | use pre-commits, but it's not required to contribute. Every change is checked 109 | on CI and if it does not pass the tests it cannot be accepted. If you want to check locally then 110 | you should install Python3.6 or newer together and run: 111 | 112 | ```bash 113 | pip install pre-commit 114 | # or 115 | brew install pre-commit 116 | ``` 117 | 118 | For more installation options visit the [pre-commits](https://pre-commit.com). 119 | To turn on pre-commit checks for commit operations in git, run: 120 | 121 | ```bash 122 | pre-commit install 123 | ``` 124 | 125 | To run all checks on your staged files, run: 126 | 127 | ```bash 128 | pre-commit run 129 | ``` 130 | 131 | To run all checks on all files, run: 132 | 133 | ```bash 134 | pre-commit run --all-files 135 | ``` 136 | -------------------------------------------------------------------------------- /Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | FROM python:3.8 19 | 20 | ENV KIBBLE_DIR="/opt/kibble" 21 | 22 | # Install some dependencies 23 | RUN apt-get update \ 24 | && apt-get install dumb-init 25 | 26 | # Copy all sources (we use .dockerignore for excluding) 27 | ADD . ${KIBBLE_DIR} 28 | 29 | # Install kibble and required dev dependencies 30 | WORKDIR ${KIBBLE_DIR} 31 | 32 | RUN pip install --upgrade pip 33 | RUN pip install -e ".[devel]" 34 | 35 | # Run sanity check 36 | RUN kibble --help 37 | 38 | # Use dumb-init as entrypoint to improve signal handling 39 | # https://github.com/Yelp/dumb-init 40 | ENTRYPOINT ["/usr/bin/dumb-init", "--"] 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Apache Kibble 2 | Copyright 2017, the Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | 7 | The licenses and noticesd listed below are for intellectual property 8 | used in Apache Kibble, not covered by the Apache License. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 19 | 20 |

21 | 22 | # Apache Kibble 23 | 24 | ![CI](https://github.com/apache/kibble/workflows/CI/badge.svg) 25 | [![License](http://img.shields.io/:license-Apache%202-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0.txt) 26 | 27 | Apache Kibble is a tool to collect, aggregate and visualize data about any software project that uses commonly known 28 | tools. 29 | 30 | 31 | 32 | **Table of contents** 33 | 34 | - [Documentation](#documentation) 35 | - [Live demo](#live-demo) 36 | - [Installation](#installation) 37 | - [Contributing](#contributing) 38 | 39 | 40 | 41 | ## Documentation 42 | 43 | For information about the Kibble project and community, visit our 44 | website at [https://kibble.apache.org/](https://kibble.apache.org/). 45 | 46 | 47 | ``` 48 | Usage: kibble [OPTIONS] COMMAND [ARGS]... 49 | 50 | Manage and configure Apache Kibble instance. 51 | 52 | Options: 53 | --help Show this message and exit. 54 | 55 | Commands: 56 | config Access configuration 57 | db Manage database 58 | scanners Configure and trigger scanners 59 | server API server commands 60 | version Show Kibble version 61 | ``` 62 | 63 | 64 | ## Live demo 65 | 66 | If you want to try Kibble without installing it on your own machine try the online demo of the Kibble 67 | service: [https://demo.kibble.apache.org/](https://demo.kibble.apache.org/). 68 | 69 | 70 | ## Installation 71 | 72 | For installation steps see the [documentation](https://apache-kibble.readthedocs.io/en/latest/setup.html#installing-the-server). 73 | 74 | ## Contributing 75 | 76 | We welcome all contributions that improve the state of the Apache Kibble project. For contribution guidelines 77 | check the [CONTRIBUTING.md](/CONTRIBUTING.md). 78 | -------------------------------------------------------------------------------- /images/kibble-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/kibble/57bbe746f28871d9b0a4b3259b13d72e5cb0211d/images/kibble-logo.png -------------------------------------------------------------------------------- /kibble/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /kibble/__main__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | from kibble.cli.parser import cli 18 | 19 | 20 | def main(): 21 | """Main executable function""" 22 | cli() 23 | 24 | 25 | if __name__ == "__main__": 26 | main() 27 | -------------------------------------------------------------------------------- /kibble/cli/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /kibble/cli/commands/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /kibble/cli/commands/config_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | __all__ = ["config_group"] 19 | 20 | import click 21 | 22 | 23 | @click.group(name="config") 24 | def config_group(): 25 | """Access configuration""" 26 | 27 | 28 | @config_group.command() 29 | def show(): 30 | """Shows configuration""" 31 | click.echo("To be implemented!") 32 | -------------------------------------------------------------------------------- /kibble/cli/commands/db_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | __all__ = ["db_group"] 19 | 20 | import click 21 | 22 | 23 | @click.group(name="db") 24 | def db_group(): 25 | """Manage database""" 26 | 27 | 28 | @db_group.command(name="init") 29 | def db_init(): 30 | """Initialize database""" 31 | click.echo("To be implemented!") 32 | 33 | 34 | def _abort_reset(ctx, _, value): 35 | if not value: 36 | ctx.abort() 37 | 38 | 39 | @db_group.command(name="reset") 40 | @click.option( 41 | "--yes", 42 | is_flag=True, 43 | callback=_abort_reset, 44 | expose_value=False, 45 | prompt="This will reset database. Do you want to continue?", 46 | ) 47 | def db_reset(): 48 | """Reset database""" 49 | click.echo("To be implemented!") 50 | -------------------------------------------------------------------------------- /kibble/cli/commands/scanners_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | __all__ = ["scanners_group"] 19 | 20 | import click 21 | 22 | 23 | @click.group(name="scanners") 24 | def scanners_group(): 25 | """Configure and trigger scanners""" 26 | 27 | 28 | @scanners_group.command() 29 | def add(): 30 | """Add new scanner configuration""" 31 | click.echo("To be implemented!") 32 | 33 | 34 | @scanners_group.command(name="list") 35 | def list_scanners(): 36 | """List all available scanners""" 37 | scanners_list = ["AbcScanner", "XyzeScanner"] 38 | for scanner in scanners_list: 39 | click.echo(f"- {scanner}") 40 | 41 | 42 | @scanners_group.command() 43 | @click.argument("scanner_name") 44 | def run(scanner_name: str): 45 | """Trigger a scanning process for given scanner""" 46 | click.echo(f"Running {scanner_name}") 47 | -------------------------------------------------------------------------------- /kibble/cli/commands/server_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | __all__ = ["server_group"] 19 | 20 | import click 21 | 22 | 23 | @click.group(name="server") 24 | def server_group(): 25 | """API server commands""" 26 | 27 | 28 | @server_group.command() 29 | def start(): 30 | """Start API server""" 31 | click.echo("To be implemented!") 32 | -------------------------------------------------------------------------------- /kibble/cli/commands/version_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | __all__ = ["version_cmd"] 19 | 20 | import click 21 | 22 | from kibble.version import version 23 | 24 | 25 | @click.command(name="version") 26 | def version_cmd(): 27 | """Show Kibble version""" 28 | click.echo(version) 29 | -------------------------------------------------------------------------------- /kibble/cli/parser.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import click 19 | 20 | from kibble.cli.commands.config_command import config_group 21 | from kibble.cli.commands.db_command import db_group 22 | from kibble.cli.commands.scanners_command import scanners_group 23 | from kibble.cli.commands.server_command import server_group 24 | from kibble.cli.commands.version_command import version_cmd 25 | 26 | 27 | @click.group() 28 | def cli(): 29 | """Manage and configure Apache Kibble instance.""" 30 | 31 | 32 | # Try to keep this list sorted A-Z 33 | cli.add_command(config_group) 34 | cli.add_command(db_group) 35 | cli.add_command(server_group) 36 | cli.add_command(scanners_group) 37 | cli.add_command(version_cmd) 38 | -------------------------------------------------------------------------------- /kibble/database/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /kibble/scanners/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /kibble/server/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /kibble/version.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | __all__ = ["version"] 19 | 20 | from importlib import metadata 21 | 22 | try: 23 | version = metadata.version("apache-kibble") 24 | except metadata.PackageNotFoundError: 25 | import logging 26 | 27 | log = logging.getLogger(__name__) 28 | log.warning("Package metadata could not be found. Overriding it with version found in setup.py") 29 | from setup import VERSION as version 30 | 31 | del metadata 32 | -------------------------------------------------------------------------------- /license-templates/LICENSE.rst: -------------------------------------------------------------------------------- 1 | .. Licensed to the Apache Software Foundation (ASF) under one 2 | or more contributor license agreements. See the NOTICE file 3 | distributed with this work for additional information 4 | regarding copyright ownership. The ASF licenses this file 5 | to you under the Apache License, Version 2.0 (the 6 | "License"); you may not use this file except in compliance 7 | with the License. You may obtain a copy of the License at 8 | 9 | .. http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | .. Unless required by applicable law or agreed to in writing, 12 | software distributed under the License is distributed on an 13 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | KIND, either express or implied. See the License for the 15 | specific language governing permissions and limitations 16 | under the License. 17 | -------------------------------------------------------------------------------- /license-templates/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Licensed to the Apache Software Foundation (ASF) under one 2 | or more contributor license agreements. See the NOTICE file 3 | distributed with this work for additional information 4 | regarding copyright ownership. The ASF licenses this file 5 | to you under the Apache License, Version 2.0 (the 6 | "License"); you may not use this file except in compliance 7 | with the License. You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, 12 | software distributed under the License is distributed on an 13 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | KIND, either express or implied. See the License for the 15 | specific language governing permissions and limitations 16 | under the License. 17 | -------------------------------------------------------------------------------- /pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | 3 | # A comma-separated list of package or module names from where C extensions may 4 | # be loaded. Extensions are loading into the active Python interpreter and may 5 | # run arbitrary code. 6 | extension-pkg-whitelist= 7 | 8 | # Specify a score threshold to be exceeded before program terminates with an error. 9 | fail-under=10.0 10 | 11 | # Add files or directories to the blacklist. They should be base names, not 12 | # paths. 13 | ignore=CVS 14 | 15 | # Add files or directories matching the regex patterns to the blacklist. The 16 | # regex matches against base names, not paths. 17 | ignore-patterns=tests*,scripts* 18 | 19 | # Python code to execute, usually for sys.path manipulation such as 20 | # pygtk.require(). 21 | #init-hook= 22 | 23 | # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the 24 | # number of processors available to use. 25 | jobs=1 26 | 27 | # Control the amount of potential inferred values when inferring a single 28 | # object. This can help the performance when dealing with large functions or 29 | # complex, nested conditions. 30 | limit-inference-results=100 31 | 32 | # List of plugins (as comma-separated values of Python module names) to load, 33 | # usually to register additional checkers. 34 | load-plugins= 35 | 36 | # Pickle collected data for later comparisons. 37 | persistent=yes 38 | 39 | # When enabled, pylint would attempt to guess common misconfiguration and emit 40 | # user-friendly hints instead of false-positive error messages. 41 | suggestion-mode=yes 42 | 43 | # Allow loading of arbitrary C extensions. Extensions are imported into the 44 | # active Python interpreter and may run arbitrary code. 45 | unsafe-load-any-extension=no 46 | 47 | 48 | [MESSAGES CONTROL] 49 | 50 | # Only show warnings with the listed confidence levels. Leave empty to show 51 | # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. 52 | confidence= 53 | 54 | # Disable the message, report, category or checker with the given id(s). You 55 | # can either give multiple identifiers separated by comma (,) or put this 56 | # option multiple times (only on the command line, not in the configuration 57 | # file where it should appear only once). You can also use "--disable=all" to 58 | # disable everything first and then reenable specific checks. For example, if 59 | # you want to run only the similarities checker, you can use "--disable=all 60 | # --enable=similarities". If you only want to run the class checker, but 61 | # do not want to see warning level messages, use "--disable=all --enable=classes 62 | # --disable=W". 63 | disable=print-statement, 64 | parameter-unpacking, 65 | unpacking-in-except, 66 | old-raise-syntax, 67 | backtick, 68 | long-suffix, 69 | old-ne-operator, 70 | old-octal-literal, 71 | import-star-module-level, 72 | non-ascii-bytes-literal, 73 | raw-checker-failed, 74 | bad-inline-option, 75 | locally-disabled, 76 | file-ignored, 77 | suppressed-message, 78 | useless-suppression, 79 | deprecated-pragma, 80 | use-symbolic-message-instead, 81 | apply-builtin, 82 | basestring-builtin, 83 | buffer-builtin, 84 | cmp-builtin, 85 | coerce-builtin, 86 | execfile-builtin, 87 | file-builtin, 88 | long-builtin, 89 | raw_input-builtin, 90 | reduce-builtin, 91 | standarderror-builtin, 92 | unicode-builtin, 93 | xrange-builtin, 94 | coerce-method, 95 | delslice-method, 96 | getslice-method, 97 | setslice-method, 98 | no-absolute-import, 99 | old-division, 100 | dict-iter-method, 101 | dict-view-method, 102 | next-method-called, 103 | metaclass-assignment, 104 | indexing-exception, 105 | raising-string, 106 | reload-builtin, 107 | oct-method, 108 | hex-method, 109 | nonzero-method, 110 | cmp-method, 111 | input-builtin, 112 | round-builtin, 113 | intern-builtin, 114 | unichr-builtin, 115 | map-builtin-not-iterating, 116 | zip-builtin-not-iterating, 117 | range-builtin-not-iterating, 118 | filter-builtin-not-iterating, 119 | using-cmp-argument, 120 | eq-without-hash, 121 | div-method, 122 | idiv-method, 123 | rdiv-method, 124 | exception-message-attribute, 125 | invalid-str-codec, 126 | sys-max-int, 127 | bad-python3-import, 128 | deprecated-string-function, 129 | deprecated-str-translate-call, 130 | deprecated-itertools-function, 131 | deprecated-types-field, 132 | next-method-defined, 133 | dict-items-not-iterating, 134 | dict-keys-not-iterating, 135 | dict-values-not-iterating, 136 | deprecated-operator-function, 137 | deprecated-urllib-function, 138 | xreadlines-attribute, 139 | deprecated-sys-function, 140 | exception-escape, 141 | comprehension-escape, 142 | missing-module-docstring 143 | 144 | # Enable the message, report, category or checker with the given id(s). You can 145 | # either give multiple identifiers separated by comma (,) or put this option 146 | # multiple times (only on the command line, not in the configuration file where 147 | # it should only appear once). See also the "--disable" option for examples. 148 | enable=c-extension-no-member 149 | 150 | 151 | [REPORTS] 152 | 153 | # Python expression which should return a score less than or equal to 10. You 154 | # have access to the variables 'error', 'warning', 'refactor', and 'convention' 155 | # which contains the number of messages in each category, as well as 'statement' 156 | # which is the total number of statements analyzed. This score is used by the 157 | # global evaluation report (RP0004). 158 | evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) 159 | 160 | # Template used to display messages. This is a Python new-style format string 161 | # used to format the message information. See doc for all details. 162 | #msg-template= 163 | 164 | # Set the output format. Available formats are text, parseable, colorized, json 165 | # and msvs (visual studio). You can also give a reporter class, e.g. 166 | # mypackage.mymodule.MyReporterClass. 167 | output-format=text 168 | 169 | # Tells whether to display a full report or only the messages. 170 | reports=no 171 | 172 | # Activate the evaluation score. 173 | score=yes 174 | 175 | 176 | [REFACTORING] 177 | 178 | # Maximum number of nested blocks for function / method body 179 | max-nested-blocks=5 180 | 181 | # Complete name of functions that never return. When checking for 182 | # inconsistent-return-statements if a never returning function is called then 183 | # it will be considered an explicit return statement and no message will be 184 | # printed. 185 | never-returning-functions=sys.exit 186 | 187 | 188 | [LOGGING] 189 | 190 | # The type of string formatting that logging methods do. `old` means using % 191 | # formatting, `new` is for `{}` formatting. 192 | logging-format-style=old 193 | 194 | # Logging modules to check that the string format arguments are in logging 195 | # function parameter format. 196 | logging-modules=logging 197 | 198 | 199 | [SPELLING] 200 | 201 | # Limits count of emitted suggestions for spelling mistakes. 202 | max-spelling-suggestions=4 203 | 204 | # Spelling dictionary name. Available dictionaries: none. To make it work, 205 | # install the python-enchant package. 206 | spelling-dict= 207 | 208 | # List of comma-separated words that should not be checked. 209 | spelling-ignore-words= 210 | 211 | # A path to a file that contains the private dictionary; one word per line. 212 | spelling-private-dict-file= 213 | 214 | # Tells whether to store unknown words in the private dictionary (see the 215 | # --spelling-private-dict-file option) instead of raising a message. 216 | spelling-store-unknown-words=no 217 | 218 | 219 | [MISCELLANEOUS] 220 | 221 | # List of note tags to take into consideration, separated by a comma. 222 | notes=FIXME, 223 | XXX, 224 | TODO 225 | 226 | # Regular expression of note tags to take into consideration. 227 | #notes-rgx= 228 | 229 | 230 | [TYPECHECK] 231 | 232 | # List of decorators that produce context managers, such as 233 | # contextlib.contextmanager. Add to this list to register other decorators that 234 | # produce valid context managers. 235 | contextmanager-decorators=contextlib.contextmanager 236 | 237 | # List of members which are set dynamically and missed by pylint inference 238 | # system, and so shouldn't trigger E1101 when accessed. Python regular 239 | # expressions are accepted. 240 | generated-members= 241 | 242 | # Tells whether missing members accessed in mixin class should be ignored. A 243 | # mixin class is detected if its name ends with "mixin" (case insensitive). 244 | ignore-mixin-members=yes 245 | 246 | # Tells whether to warn about missing members when the owner of the attribute 247 | # is inferred to be None. 248 | ignore-none=yes 249 | 250 | # This flag controls whether pylint should warn about no-member and similar 251 | # checks whenever an opaque object is returned when inferring. The inference 252 | # can return multiple potential results while evaluating a Python object, but 253 | # some branches might not be evaluated, which results in partial inference. In 254 | # that case, it might be useful to still emit no-member and other checks for 255 | # the rest of the inferred objects. 256 | ignore-on-opaque-inference=yes 257 | 258 | # List of class names for which member attributes should not be checked (useful 259 | # for classes with dynamically set attributes). This supports the use of 260 | # qualified names. 261 | ignored-classes=optparse.Values,thread._local,_thread._local 262 | 263 | # List of module names for which member attributes should not be checked 264 | # (useful for modules/projects where namespaces are manipulated during runtime 265 | # and thus existing member attributes cannot be deduced by static analysis). It 266 | # supports qualified module names, as well as Unix pattern matching. 267 | ignored-modules= 268 | 269 | # Show a hint with possible names when a member name was not found. The aspect 270 | # of finding the hint is based on edit distance. 271 | missing-member-hint=yes 272 | 273 | # The minimum edit distance a name should have in order to be considered a 274 | # similar match for a missing member name. 275 | missing-member-hint-distance=1 276 | 277 | # The total number of similar names that should be taken into consideration when 278 | # showing a hint for a missing member. 279 | missing-member-max-choices=1 280 | 281 | # List of decorators that change the signature of a decorated function. 282 | signature-mutators= 283 | 284 | 285 | [VARIABLES] 286 | 287 | # List of additional names supposed to be defined in builtins. Remember that 288 | # you should avoid defining new builtins when possible. 289 | additional-builtins= 290 | 291 | # Tells whether unused global variables should be treated as a violation. 292 | allow-global-unused-variables=yes 293 | 294 | # List of strings that can identify a callback function by name. A callback 295 | # name must start or end with one of those strings. 296 | callbacks=cb_, 297 | _cb 298 | 299 | # A regular expression matching the name of dummy variables (i.e. expected to 300 | # not be used). 301 | dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ 302 | 303 | # Argument names that match this expression will be ignored. Default to name 304 | # with leading underscore. 305 | ignored-argument-names=_.*|^ignored_|^unused_|args|kwargs|^mock_|.*_mock| 306 | 307 | # Tells whether we should check for unused import in __init__ files. 308 | init-import=no 309 | 310 | # List of qualified module names which can have objects that can redefine 311 | # builtins. 312 | redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io 313 | 314 | 315 | [FORMAT] 316 | 317 | # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. 318 | expected-line-ending-format= 319 | 320 | # Regexp for a line that is allowed to be longer than the limit. 321 | ignore-long-lines=^\s*(# )??$ 322 | 323 | # Number of spaces of indent required inside a hanging or continued line. 324 | indent-after-paren=4 325 | 326 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 327 | # tab). 328 | indent-string=' ' 329 | 330 | # Maximum number of characters on a single line. 331 | max-line-length=110 332 | 333 | # Maximum number of lines in a module. 334 | max-module-lines=1000 335 | 336 | # Allow the body of a class to be on the same line as the declaration if body 337 | # contains a single statement. 338 | single-line-class-stmt=no 339 | 340 | # Allow the body of an if to be on the same line as the test if there is no 341 | # else. 342 | single-line-if-stmt=no 343 | 344 | 345 | [SIMILARITIES] 346 | 347 | # Ignore comments when computing similarities. 348 | ignore-comments=yes 349 | 350 | # Ignore docstrings when computing similarities. 351 | ignore-docstrings=yes 352 | 353 | # Ignore imports when computing similarities. 354 | ignore-imports=no 355 | 356 | # Minimum lines number of similarity. 357 | min-similarity-lines=4 358 | 359 | 360 | [BASIC] 361 | 362 | # Naming style matching correct argument names. 363 | argument-naming-style=snake_case 364 | 365 | # Regular expression matching correct argument names. Overrides argument- 366 | # naming-style. 367 | #argument-rgx= 368 | 369 | # Naming style matching correct attribute names. 370 | attr-naming-style=snake_case 371 | 372 | # Regular expression matching correct attribute names. Overrides attr-naming- 373 | # style. 374 | #attr-rgx= 375 | 376 | # Bad variable names which should always be refused, separated by a comma. 377 | bad-names=foo, 378 | bar, 379 | baz, 380 | toto, 381 | tutu, 382 | tata 383 | 384 | # Bad variable names regexes, separated by a comma. If names match any regex, 385 | # they will always be refused 386 | bad-names-rgxs= 387 | 388 | # Naming style matching correct class attribute names. 389 | class-attribute-naming-style=any 390 | 391 | # Regular expression matching correct class attribute names. Overrides class- 392 | # attribute-naming-style. 393 | #class-attribute-rgx= 394 | 395 | # Naming style matching correct class names. 396 | class-naming-style=PascalCase 397 | 398 | # Regular expression matching correct class names. Overrides class-naming- 399 | # style. 400 | #class-rgx= 401 | 402 | # Naming style matching correct constant names. 403 | const-naming-style=UPPER_CASE 404 | 405 | # Regular expression matching correct constant names. Overrides const-naming- 406 | # style. 407 | #const-rgx= 408 | 409 | # Minimum line length for functions/classes that require docstrings, shorter 410 | # ones are exempt. 411 | docstring-min-length=-1 412 | 413 | # Naming style matching correct function names. 414 | function-naming-style=snake_case 415 | 416 | # Regular expression matching correct function names. Overrides function- 417 | # naming-style. 418 | #function-rgx= 419 | 420 | # Good variable names which should always be accepted, separated by a comma. 421 | good-names=i, 422 | j, 423 | k, 424 | v, 425 | ex, 426 | _ 427 | 428 | # Good variable names regexes, separated by a comma. If names match any regex, 429 | # they will always be accepted 430 | good-names-rgxs= 431 | 432 | # Include a hint for the correct naming format with invalid-name. 433 | include-naming-hint=no 434 | 435 | # Naming style matching correct inline iteration names. 436 | inlinevar-naming-style=any 437 | 438 | # Regular expression matching correct inline iteration names. Overrides 439 | # inlinevar-naming-style. 440 | #inlinevar-rgx= 441 | 442 | # Naming style matching correct method names. 443 | method-naming-style=snake_case 444 | 445 | # Regular expression matching correct method names. Overrides method-naming- 446 | # style. 447 | #method-rgx= 448 | 449 | # Naming style matching correct module names. 450 | module-naming-style=snake_case 451 | 452 | # Regular expression matching correct module names. Overrides module-naming- 453 | # style. 454 | #module-rgx= 455 | 456 | # Colon-delimited sets of names that determine each other's naming style when 457 | # the name regexes allow several styles. 458 | name-group= 459 | 460 | # Regular expression which should only match function or class names that do 461 | # not require a docstring. 462 | no-docstring-rgx=^_ 463 | 464 | # List of decorators that produce properties, such as abc.abstractproperty. Add 465 | # to this list to register other decorators that produce valid properties. 466 | # These decorators are taken into consideration only for invalid-name. 467 | property-classes=abc.abstractproperty 468 | 469 | # Naming style matching correct variable names. 470 | variable-naming-style=snake_case 471 | 472 | # Regular expression matching correct variable names. Overrides variable- 473 | # naming-style. 474 | #variable-rgx= 475 | 476 | 477 | [STRING] 478 | 479 | # This flag controls whether inconsistent-quotes generate a warning when the 480 | # character used as a quote delimiter is used inconsistently within a module. 481 | check-quote-consistency=no 482 | 483 | # This flag controls whether the implicit-str-concat should generate a warning 484 | # on implicit string concatenation in sequences defined over several lines. 485 | check-str-concat-over-line-jumps=no 486 | 487 | 488 | [IMPORTS] 489 | 490 | # List of modules that can be imported at any level, not just the top level 491 | # one. 492 | allow-any-import-level= 493 | 494 | # Allow wildcard imports from modules that define __all__. 495 | allow-wildcard-with-all=no 496 | 497 | # Analyse import fallback blocks. This can be used to support both Python 2 and 498 | # 3 compatible code, which means that the block might have code that exists 499 | # only in one or another interpreter, leading to false positives when analysed. 500 | analyse-fallback-blocks=no 501 | 502 | # Deprecated modules which should not be used, separated by a comma. 503 | deprecated-modules=optparse,tkinter.tix 504 | 505 | # Create a graph of external dependencies in the given file (report RP0402 must 506 | # not be disabled). 507 | ext-import-graph= 508 | 509 | # Create a graph of every (i.e. internal and external) dependencies in the 510 | # given file (report RP0402 must not be disabled). 511 | import-graph= 512 | 513 | # Create a graph of internal dependencies in the given file (report RP0402 must 514 | # not be disabled). 515 | int-import-graph= 516 | 517 | # Force import order to recognize a module as part of the standard 518 | # compatibility libraries. 519 | known-standard-library= 520 | 521 | # Force import order to recognize a module as part of a third party library. 522 | known-third-party=enchant 523 | 524 | # Couples of modules and preferred modules, separated by a comma. 525 | preferred-modules= 526 | 527 | 528 | [CLASSES] 529 | 530 | # List of method names used to declare (i.e. assign) instance attributes. 531 | defining-attr-methods=__init__, 532 | __new__, 533 | setUp, 534 | __post_init__ 535 | 536 | # List of member names, which should be excluded from the protected access 537 | # warning. 538 | exclude-protected=_asdict, 539 | _fields, 540 | _replace, 541 | _source, 542 | _make 543 | 544 | # List of valid names for the first argument in a class method. 545 | valid-classmethod-first-arg=cls 546 | 547 | # List of valid names for the first argument in a metaclass class method. 548 | valid-metaclass-classmethod-first-arg=cls 549 | 550 | 551 | [DESIGN] 552 | 553 | # Maximum number of arguments for function / method. 554 | max-args=5 555 | 556 | # Maximum number of attributes for a class (see R0902). 557 | max-attributes=7 558 | 559 | # Maximum number of boolean expressions in an if statement (see R0916). 560 | max-bool-expr=5 561 | 562 | # Maximum number of branches for function / method body. 563 | max-branches=12 564 | 565 | # Maximum number of locals for function / method body. 566 | max-locals=15 567 | 568 | # Maximum number of parents for a class (see R0901). 569 | max-parents=7 570 | 571 | # Maximum number of public methods for a class (see R0904). 572 | max-public-methods=20 573 | 574 | # Maximum number of return / yield for function / method body. 575 | max-returns=6 576 | 577 | # Maximum number of statements in function / method body. 578 | max-statements=50 579 | 580 | # Minimum number of public methods for a class (see R0903). 581 | min-public-methods=2 582 | 583 | 584 | [EXCEPTIONS] 585 | 586 | # Exceptions that will emit a warning when being caught. Defaults to 587 | # "BaseException, Exception". 588 | overgeneral-exceptions=BaseException, 589 | Exception 590 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | [tool.black] 19 | line-length = 110 20 | target-version = ['py38'] 21 | 22 | [tool.pytest.ini_options] 23 | minversion = "6.0" 24 | addopts = "-rasl --verbose --color=yes" 25 | testpaths = [ 26 | "tests", 27 | ] 28 | faulthandler_timeout = 480 29 | log_level = "INFO" 30 | -------------------------------------------------------------------------------- /scripts/pre_commit_generate_cli_help.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | 19 | set -euo pipefail 20 | 21 | MY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 22 | TMP_FILE=$(mktemp) 23 | TMP_OUTPUT=$(mktemp) 24 | 25 | cd "${MY_DIR}/../" || exit; 26 | 27 | echo "\`\`\`" >"${TMP_FILE}" 28 | 29 | export MAX_SCREEN_WIDTH=100 30 | export FORCE_SCREEN_WIDTH="true" 31 | export VERBOSE="true" 32 | 33 | kibble --help | sed 's/^/ /' | sed 's/ *$//' >>"${TMP_FILE}" 34 | 35 | echo "\`\`\`" >> "${TMP_FILE}" 36 | 37 | MAX_LEN=$(awk '{ print length($0); }' "${TMP_FILE}" | sort -n | tail -1 ) 38 | 39 | README_FILE="${MY_DIR}/../README.md" 40 | 41 | LEAD='^$' 42 | TAIL='^$' 43 | 44 | BEGIN_GEN=$(grep -n "${LEAD}" <"${README_FILE}" | sed 's/\(.*\):.*/\1/g') 45 | END_GEN=$(grep -n "${TAIL}" <"${README_FILE}" | sed 's/\(.*\):.*/\1/g') 46 | cat <(head -n "${BEGIN_GEN}" "${README_FILE}") \ 47 | "${TMP_FILE}" \ 48 | <(tail -n +"${END_GEN}" "${README_FILE}") \ 49 | >"${TMP_OUTPUT}" 50 | 51 | mv "${TMP_OUTPUT}" "${README_FILE}" 52 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | [metadata] 19 | name = Kibble 20 | summary = Apache Kibble is a tool to collect, aggregate and visualize data about any software project that uses commonly known tools. 21 | description-file = README.md 22 | author = Apache Kibble 23 | author-email = dev@kibble.apache.org 24 | license = Apache License, Version 2.0 25 | license_files = 26 | LICENSE 27 | NOTICE 28 | 29 | [bdist_wheel] 30 | python-tag=py3 31 | 32 | 33 | [files] 34 | packages = kibble 35 | 36 | [easy_install] 37 | 38 | [mypy] 39 | ignore_missing_imports = True 40 | no_implicit_optional = True 41 | warn_redundant_casts = True 42 | warn_unused_ignores = False 43 | pretty = True 44 | 45 | [isort] 46 | line_length=110 47 | combine_as_imports = true 48 | default_section = THIRDPARTY 49 | known_first_party=tests 50 | # Need to be consistent with the exclude config defined in pre-commit-config.yaml 51 | skip=build,.tox,venv 52 | profile = black 53 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import os 19 | 20 | from setuptools import find_packages, setup 21 | 22 | VERSION = "2.0.0dev" 23 | 24 | BASE_PATH = os.path.dirname(os.path.realpath(__file__)) 25 | 26 | DEVEL_REQUIREMENTS = [ 27 | "black==20.8b1", 28 | "pre-commit==2.7.1", 29 | "pylint==2.6.2", 30 | "pytest==6.1.1", 31 | ] 32 | 33 | INSTALL_REQUIREMENTS = ["requests>=2.25.1"] 34 | 35 | EXTRAS_REQUIREMENTS = {"devel": DEVEL_REQUIREMENTS} 36 | 37 | 38 | def get_long_description() -> str: 39 | """Retrieves package description from README.md""" 40 | try: 41 | with open(os.path.join(BASE_PATH, "README.md")) as file: 42 | description = file.read() 43 | except FileNotFoundError: 44 | description = "" 45 | return description 46 | 47 | 48 | def do_setup() -> None: 49 | """Perform the Kibble package setup.""" 50 | setup( 51 | name="apache-kibble", 52 | description="Apache Kibble is a tool to collect, aggregate and " 53 | "visualize data about any software project.", 54 | long_description=get_long_description(), 55 | long_description_content_type="text/markdown", 56 | license="Apache License 2.0", 57 | version=VERSION, 58 | packages=find_packages(include=["kibble*"]), 59 | package_data={"kibble": ["py.typed"]}, 60 | include_package_data=True, 61 | zip_safe=False, 62 | entry_points={"console_scripts": ["kibble = kibble.__main__:main"]}, 63 | install_requires=INSTALL_REQUIREMENTS, 64 | setup_requires=["docutils", "gitpython", "setuptools", "wheel"], 65 | extras_require=EXTRAS_REQUIREMENTS, 66 | classifiers=[ 67 | "Development Status :: 5 - Production/Stable", 68 | "Environment :: Console", 69 | "Environment :: Web Environment", 70 | "Intended Audience :: Developers", 71 | "Intended Audience :: System Administrators", 72 | "License :: OSI Approved :: Apache Software License", 73 | "Programming Language :: Python :: 3.8", 74 | ], 75 | author="Apache Software Foundation", 76 | author_email="dev@kibble.apache.org", 77 | url="https://kibble.apache.org/", 78 | download_url=f"https://archive.apache.org/dist/kibble/{VERSION}", 79 | test_suite="setup.kibble_test_suite", 80 | python_requires="~=3.8", 81 | project_urls={ 82 | "Documentation": "https://kibble.apache.org/docs/", 83 | "Bug Tracker": "https://github.com/apache/kibble/issues", 84 | "Source Code": "https://github.com/apache/kibble", 85 | }, 86 | ) 87 | 88 | 89 | if __name__ == "__main__": 90 | do_setup() 91 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /tests/cli/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /tests/cli/commands/__init__.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | -------------------------------------------------------------------------------- /tests/cli/commands/test_config_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from click.testing import CliRunner 19 | 20 | from kibble.cli.commands.config_command import config_group 21 | 22 | 23 | class TestConfigCommand: 24 | def test_show(self): 25 | runner = CliRunner() 26 | result = runner.invoke(config_group, ["show"]) 27 | 28 | assert result.exit_code == 0 29 | assert result.output.strip() == "To be implemented!" 30 | -------------------------------------------------------------------------------- /tests/cli/commands/test_db_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from click.testing import CliRunner 19 | 20 | from kibble.cli.commands.db_command import db_group 21 | 22 | 23 | class TestDbCommand: 24 | def test_init(self): 25 | runner = CliRunner() 26 | result = runner.invoke(db_group, ["init"]) 27 | 28 | assert result.exit_code == 0 29 | assert result.output.strip() == "To be implemented!" 30 | 31 | def test_reset_no(self): 32 | runner = CliRunner() 33 | result = runner.invoke(db_group, ["reset"], input="N") 34 | 35 | msg = "This will reset database. Do you want to continue? [y/N]: N\nAborted!" 36 | assert result.output.strip() == msg 37 | assert result.exit_code == 1 38 | 39 | def test_reset_yes(self): 40 | runner = CliRunner() 41 | result = runner.invoke(db_group, ["reset", "--yes"]) 42 | 43 | assert result.exit_code == 0 44 | assert result.output.strip() == "To be implemented!" 45 | -------------------------------------------------------------------------------- /tests/cli/commands/test_scanners_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from click.testing import CliRunner 19 | 20 | from kibble.cli.commands.scanners_command import scanners_group 21 | 22 | 23 | class TestScannerCommand: 24 | def test_add(self): 25 | runner = CliRunner() 26 | result = runner.invoke(scanners_group, ["add"]) 27 | 28 | assert result.exit_code == 0 29 | assert result.output.strip() == "To be implemented!" 30 | 31 | def test_list(self): 32 | runner = CliRunner() 33 | result = runner.invoke(scanners_group, ["list"]) 34 | 35 | assert result.exit_code == 0 36 | assert result.output.strip() == "- AbcScanner\n- XyzeScanner" 37 | 38 | def test_run(self): 39 | runner = CliRunner() 40 | result = runner.invoke(scanners_group, ["run", "TestScanner"]) 41 | 42 | assert result.exit_code == 0 43 | assert result.output.strip() == "Running TestScanner" 44 | -------------------------------------------------------------------------------- /tests/cli/commands/test_server_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from click.testing import CliRunner 19 | 20 | from kibble.cli.commands.server_command import server_group 21 | 22 | 23 | class TestWebserverCommand: 24 | def test_start(self): 25 | runner = CliRunner() 26 | result = runner.invoke(server_group, ["start"]) 27 | 28 | assert result.exit_code == 0 29 | assert result.output.strip() == "To be implemented!" 30 | -------------------------------------------------------------------------------- /tests/cli/commands/test_version_command.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from click.testing import CliRunner 19 | 20 | from kibble.cli.commands.version_command import version_cmd 21 | from kibble.version import version 22 | 23 | 24 | class TestVersionCommand: 25 | def test_version(self): 26 | runner = CliRunner() 27 | result = runner.invoke(version_cmd) 28 | 29 | assert result.exit_code == 0 30 | assert result.output.strip() == version 31 | -------------------------------------------------------------------------------- /tests/cli/test_parser.py: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from click.testing import CliRunner 19 | 20 | from kibble.cli.parser import cli 21 | 22 | 23 | class TestCliParser: 24 | def test_commands_are_sorted_in_cli(self): 25 | cmds = cli.list_commands(None) 26 | assert cmds == sorted(cmds) 27 | 28 | def test_commands(self): 29 | runner = CliRunner() 30 | result = runner.invoke(cli) 31 | assert result.exit_code == 0 32 | -------------------------------------------------------------------------------- /yamllint-config.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | --- 18 | extends: default 19 | 20 | rules: 21 | line-length: 22 | max: 110 23 | --------------------------------------------------------------------------------