A professional static analysis tool for QGIS (PyQGIS) plugins
Project description
QGIS Plugin Analyzer 🛡️
👉 View Full Rules Catalog (RULES.md)
The QGIS Plugin Analyzer is a static analysis tool designed specifically for QGIS (PyQGIS) plugin developers. Its goal is to elevate plugin quality by ensuring they follow community best practices and are optimized for AI-assisted development.
✨ Main Features
- Security Core (Bandit-inspired): Professional vulnerability scanning detecting
eval,exec, shell injections, and SQL injection risks. - Deep Entropy Secret Scanner: Detects hardcoded API keys, passwords, and sensitive tokens using regex and information entropy.
- High-Performance Engine: Parallel analysis powered by
ProcessPoolExecutorwith single-pass AST traversal and shared worker context. - Project Auto-Detection: Intelligently distinguishes between official QGIS Plugins and Generic Python Projects, tailoring validation logic accordingly.
- Advanced Ignore Engine: Robust
.analyzerignoresupport with non-anchored patterns and smart default excludes (.venv,build, etc.). - Deep Semantic Analysis: Cross-file dependency graphing (Mermaid), circular import detection, and module coupling metrics.
- Interactive Auto-Fix Mode: Automatically fix common QGIS issues (GDAL imports, PyQt bridge, logging, i18n) with safety checks.
- Official Repository Compliance: Proactive validation of binaries, package size, and metadata URLs.
- Real-time Progress: CLI feedback with a progress bar and ETA tracking.
- Enhanced Configuration Profiles: Rule-level severity control (
error,warning,info,ignore) viapyproject.toml. - Integrated Ruff Analysis: Combines custom QGIS rules with the fastest linter in the Python ecosystem.
- Qt Resource Validation: Detect missing or broken resource paths (
:/plugins/...) in your code. - Extended Safety Audit: Detection of signal leaks, missing slots, and UI-blocking loops (QgsTask suggestions).
- Embedded Web Server: View reports instantly with the built-in
servecommand. - AI-Ready: Generates structured summaries and optimized contexts for LLMs.
- Zero Runtime Dependencies: Works using only the Python standard library (Ruff as an external tool).
⚖️ Why use this Analyzer? (Comparison)
| Feature | QGIS Plugin Analyzer | flake8-qgis | Ruff (Standard) | Official Repo Bot |
|---|---|---|---|---|
| Run Locally / Offline | ✅ (Your Machine) | ✅ | ✅ | ❌ (Upload Only) |
| Static Linting | ✅ (Ruff + Custom) | ✅ (flake8) | ✅ (General) | ✅ (Limited) |
| QGIS-Specific Rules | ✅ (Precise AST) | ✅ (Regex/AST) | ❌ | ✅ |
| Interactive Auto-Fix | ✅ | ❌ | ❌ | ❌ |
| Semantic Analysis | ✅ | ❌ | ❌ | ❌ |
| Security Audit | ✅ (Bandit-style) | ❌ | ❌ | ✅ (Server-side) |
| Secret Scanning | ✅ (Entropy) | ❌ | ❌ | ✅ (Server-side) |
| HTML/MD Reports | ✅ | ❌ | ❌ | ❌ |
| AI Context Gen | ✅ (Project Brain) | ❌ | ❌ | ❌ |
Key Differentiators
- Shift Left (Run Locally): The biggest advantage is being able to run the same high-standard checks as the Official Repository before you upload your plugin. No more "reject-fix-upload" loops.
- High-Performance Hybrid Engine: Combines multi-core AST processing with deep understanding of cross-file relationships and Qt-specific patterns.
- Safety-First Auto-Fixing: AST-based transformations with Git status verification and interactive diff previews.
- Zero Runtime Stack: Minimal footprint, ultra-fast execution, and easy CI integration.
- AI-Centric Design: Built to help developers and AI agents understand complex QGIS plugins instantly.
🚀 Installation and Usage
Installation with uv (Recommended):
If you have uv installed, you can install the analyzer quickly and in isolation:
1. As a global tool (isolated):
uv tool install git+https://github.com/geociencio/qgis-plugin-analyzer.git
2. Standard pip installation (Git):
pip install git+https://github.com/geociencio/qgis-plugin-analyzer.git
2. Local installation for development:
git clone https://github.com/geociencio/qgis-plugin-analyzer
cd qgis-plugin-analyzer
uv sync
Installation with pip:
pip install .
Main Commands:
1. Analyze a Plugin:
qgis-analyzer analyze /path/to/your/plugin -o ./quality_report
2. Auto-Fix issues (Dry Run):
qgis-analyzer fix /path/to/your/plugin
3. Legacy Support: The default command remains analysis if no subcommand is specified:
qgis-analyzer /path/to/your/plugin
🔄 Pre-commit Hook
You can run qgis-plugin-analyzer automatically before every commit to ensure quality. Add this to your .pre-commit-config.yaml:
- repo: https://github.com/geociencio/qgis-plugin-analyzer
rev: main # Use 'main' for latest features or a specific tag like v1.5.0
hooks:
- id: qgis-plugin-analyzer
🤖 GitHub Action
Use it directly in your CI/CD workflows:
steps:
- uses: actions/checkout@v4
- name: Run QGIS Quality Check
uses: geociencio/qgis-plugin-analyzer@main
with:
path: .
output: quality_report
args: --profile release
⚙️ Configuration (pyproject.toml)
You can customize the analyzer's behavior using a [tool.qgis-analyzer] section in your pyproject.toml.
[tool.qgis-analyzer]
# Profiles allow different settings for CI vs Local
[tool.qgis-analyzer.profiles.default]
strict = false
generate_html = false # CLI default
[tool.qgis-analyzer.profiles.release]
strict = true
fail_on_error = true
[tool.qgis-analyzer.profiles.default.rules]
QGS101 = "error" # Ban specific module imports
QGS105 = "warning" # Warn on iface usage
QGS303 = "ignore" # Ignore resource path checks
⚠️ Technical Limitations
This tool performs Static Analysis (AST & Regex parsing). It does not execute your code or load QGIS libraries.
- Dynamic Imports: Imports inside functions or conditional blocks might be analyzed differently than top-level imports.
- Runtime Validation: Checks like "Missing Resources" rely on static string analysis of
.qrcfiles and path strings. It cannot verify resources loaded dynamically at runtime. - False Positives: While we strive for accuracy, complex meta-programming or unusual patterns might trigger false positives. Use
# noqaor.analyzerignoreto handle these cases.
⌨️ Full CLI Reference
Note: The Python package is named
qgis-plugin-analyzer, but the command-line tool is installed asqgis-analyzer.
qgis-analyzer analyze
Audits an existing QGIS plugin repository.
| Argument | Description | Default |
|---|---|---|
project_path |
(Required) Path to the plugin directory to analyze. | N/A |
-o, --output |
Directory where HTML/Markdown reports will be saved. | ./analysis_results |
-r, --report |
Explicitly generate detailed HTML/Markdown reports. | False |
-p, --profile |
Configuration profile from pyproject.toml (default, release). |
default |
qgis-analyzer fix
Automatically fix common QGIS issues identified during analysis.
| Argument | Description | Default |
|---|---|---|
path |
(Required) Path to the plugin directory. | N/A |
--dry-run |
Show proposed changes without applying them. | True |
--apply |
Apply fixes to the files (disables dry-run). | False |
--auto-approve |
Apply fixes without interactive confirmation. | False |
--rules |
Comma-separated list of rule IDs to fix. | Fix all |
-o, --output |
Directory to read previous analysis from. | ./analysis_results |
qgis-analyzer summary
Shows a professional, color-coded summary of findings directly in your terminal.
| Argument | Description | Default |
|---|---|---|
-b, --by |
Granularity of the summary: total, modules, functions, classes. |
total |
-i, --input |
Path to the project_context.json file to summarize. |
analysis_results/project_context.json |
qgis-analyzer security
Performs a focused security scan on a file or directory.
| Argument | Description | Default |
|---|---|---|
path |
(Required) Path to the file or directory to scan. | N/A |
--deep |
Run more intensive (but slower) security checks. | False |
-p, --profile |
Configuration profile. | default |
qgis-analyzer version
Shows the current version of the analyzer.
Example:
# Executive summary
qgis-analyzer summary
# Identify high-complexity functions
qgis-analyzer summary --by functions
qgis-analyzer list-rules
Displays the full catalog of implemented QGIS audit rules with their severity and descriptions.
qgis-analyzer graph
Visualizes the project's dependency graph.
| Argument | Description | Default |
|---|---|---|
project_path |
Path to the plugin directory. | . |
--format |
Output format: text or mermaid. |
text |
qgis-analyzer serve
Starts a local web server to view the generated HTML reports.
| Argument | Description | Default |
|---|---|---|
path |
Path to the analysis results directory. | ./analysis_results |
--port |
Port to run the server on. | 8000 |
qgis-analyzer init
Initializes a recommended .analyzerignore file in the current directory with common Python and QGIS development exclusions.
📊 Generated Reports
project_context.json: Full structured data for external integrations.
📜 Audit Rules
For a complete list of all implemented checks, their severity, and recommendations, please refer to the:
👉 Detailed Rules Catalog (RULES.md)
📚 References and Standards
The development of this analyzer is based on official QGIS community guidelines, geospatial standards, and industry best practices:
Official QGIS Documentation
- PyQGIS Developer Cookbook: The primary resource for PyQGIS API usage and standards.
- QGIS Plugin Repository Requirements: Mandatory criteria for plugin approval in the official repository.
- QGIS Coding Standards: Core style and organization guidelines for the QGIS project.
- QGIS HIG (Human Interface Guidelines): Standards for consistent and accessible user interface design.
- QGIS Security Scanning Documentation: Official guide on automated security analysis (Bandit, detect-secrets) for plugins.
Industry & Community Standards
- flake8-qgis Rules: Community-driven linting rules for PyQGIS (QGS101-106).
- PEP 8 Style Guide: The fundamental style guide for Python code.
- PEP 257 Docstring Conventions: Standards for docstring structure and content.
- Maintainability Index (SEI): Methodology for measuring software maintainability.
- Conventional Commits: Standard for clear, machine-readable commit history.
- Keep a Changelog: Best practices for maintainable version history.
Security Standards
- Bandit (PyCQA): The security rules implemented (B1xx - B6xx) are directly derived from the Bandit project's rule set for identifying common security issues in Python code.
- CWE (Common Weakness Enumeration): Security findings are mapped to standard CWE IDs (e.g., CWE-78 Command Injection, CWE-89 SQL Injection) for industry-standard classification.
- OWASP Top 10: The "Hardcoded Secret" and "Injection" checks align with critical OWASP vulnerabilities.
Internal Resources
- Detailed Rules Catalog: Full documentation of all audit rules implemented in this analyzer.
- Standardized Scoring Metrics: Mathematical logic and thresholds for project evaluation.
- Project Roadmap: Current status and future plans for the analyzer.
- Documentation Folder: Historical release notes, competitive analysis, and modernization guides.
🛠️ Contributing
Contributions are welcome! Please refer to our Contributing Guide to learn how to report bugs, propose rules, and submit code changes.
Audit rules are located in src/analyzer/scanner.py. Feel free to add new rules following the existing pattern!
⚖️ License
This project is licensed under the GNU General Public License v3 (GPL v3). See the LICENSE file for details.
Developed for the SecInterp team and the QGIS community.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qgis_plugin_analyzer-1.7.0.tar.gz.
File metadata
- Download URL: qgis_plugin_analyzer-1.7.0.tar.gz
- Upload date:
- Size: 90.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Manjaro Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f610f0f8a4e89f4b70ae887602bab3fd9bc693eb27a17c3a06ab28b79b0e5d36
|
|
| MD5 |
846291822cbc280f932c179df6c05872
|
|
| BLAKE2b-256 |
b235d1f337f968c5bee9a11bea71d7eac08f30aa2514763f065cbb4fef7754d4
|
File details
Details for the file qgis_plugin_analyzer-1.7.0-py3-none-any.whl.
File metadata
- Download URL: qgis_plugin_analyzer-1.7.0-py3-none-any.whl
- Upload date:
- Size: 97.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Manjaro Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b1642ee5dea47f8f2288c4295d58761546d74686626eebbf1353bddab6f808a
|
|
| MD5 |
a101adfbd880699d488806fc1241deb8
|
|
| BLAKE2b-256 |
015e7e6c1728c2a936edb3460b77e42fe4adced7b6ada134b315b45155d59985
|