galaxy-linting
Persona: You are a senior Galaxy developer specializing in code quality, style enforcement, and CI compliance.
Arguments:
- $ARGUMENTS - Optional task specifier: "check", "fix", "python", "client", "mypy", "full" Examples: "", "check", "fix", "python", "mypy"
Parse $ARGUMENTS to determine which guidance to provide.
Quick Reference: Galaxy Linting & Formatting
Galaxy uses multiple linting tools enforced through CI:
- Python: ruff (lint + format), black, isort, flake8, darker (incremental formatting), mypy (type checking)
- Client: ESLint, Prettier
- CI commands:
tox -e lint,tox -e format,tox -e mypy,tox -e lint_docstring_include_list
Tools Overview
| Tool | Purpose | Config File | Check Command | Fix Command |
|---|---|---|---|---|
| ruff | Fast Python linter + formatter | pyproject.toml |
ruff check . |
ruff check --fix . |
| black | Python code formatter | pyproject.toml |
black --check . |
black . |
| isort | Python import sorter | pyproject.toml |
isort --check . |
isort . |
| flake8 | Python linter (legacy) | .flake8 |
flake8 . |
N/A (manual) |
| darker | Incremental formatter | N/A | N/A | make diff-format |
| autoflake | Remove unused imports | N/A | N/A | make remove-unused-imports |
| pyupgrade | Modernize Python syntax | N/A | N/A | make pyupgrade |
| mypy | Type checker | pyproject.toml |
tox -e mypy |
N/A (manual) |
| ESLint | JavaScript/TypeScript linter | client/.eslintrc.js |
make client-lint |
make client-format |
| Prettier | JS/TS/CSS formatter | client/.prettierrc.yml |
make client-lint |
make client-format |
If $ARGUMENTS is empty or "check": Quick Lint Check
Run the fastest feedback loop to catch most issues:
# 1. Check formatting (fast - shows what would change)
tox -e format
# 2. Check linting (catches style violations)
tox -e lint
What these check:
tox -e format: Runs black, isort checks (no changes, just reports)tox -e lint: Runs ruff and flake8 (reports violations)
If you see errors, use /galaxy-linting fix to auto-fix, or /galaxy-linting python for detailed guidance.
Note: These commands run in tox environments, which may take ~10-20 seconds to set up on first run. Subsequent runs are faster.
If $ARGUMENTS is "fix": Auto-Fix Formatting
Galaxy provides multiple ways to auto-fix formatting issues.
Recommended: Incremental Formatting (Faster)
Fix only changed lines using darker (via Makefile):
# Fix formatting for uncommitted changes only
make diff-format
What it does:
- Runs black and isort only on lines you modified
- Compares against
origin/devbranch - Much faster than formatting entire codebase
- Recommended for daily development
Full Formatting (Comprehensive)
Format entire codebase:
# Format all Python files
make format
What it does:
- Runs black on all Python files
- Runs isort on all Python imports
- Takes longer but ensures full compliance
- Recommended before final commit
Specific Fixes
Fix ruff auto-fixable issues:
ruff check --fix .
Remove unused imports:
make remove-unused-imports
Modernize Python syntax (pyupgrade):
make pyupgrade
Converts old-style Python patterns to Python 3.8/3.9 idioms (e.g., typing.List → list, adds walrus operators where appropriate). Skips vendored/generated paths.
Fix client-side formatting:
make client-format
Workflow Recommendation
# During development (fast):
make diff-format
# Before committing (thorough):
make format
tox -e lint # Verify no remaining issues
If $ARGUMENTS is "python": Python Linting Details
Galaxy's Python linting stack consists of multiple tools, each with a specific purpose.
Ruff (Primary Linter)
Fast, modern Python linter that replaces many tools.
Check for issues:
ruff check .
Auto-fix issues:
ruff check --fix .
Configuration: pyproject.toml under [tool.ruff] and [tool.ruff.lint]
Key rule categories:
- F: Pyflakes errors (undefined names, unused imports)
- E, W: PEP 8 style violations
- I: Import sorting (isort-compatible)
- N: Naming conventions
- UP: Modernization (e.g., use
list[int]instead ofList[int]) - B: Bugbear (likely bugs)
- A: Avoid shadowing builtins
Common errors and fixes:
F401- Unused import → Remove import or use# noqa: F401F841- Unused variable → Remove or rename to_E501- Line too long (>120 chars) → Break into multiple linesUP- Use modern syntax → Let ruff auto-fix with--fix
Black (Code Formatter)
Opinionated code formatter - ensures consistent style.
Check what would change:
black --check .
Format files:
black .
Configuration: pyproject.toml under [tool.black]
- Line length: 120 characters
- Target version: Python 3.9+
Common scenarios:
- "black would reformat" error in CI → Run
black .locally - String formatting → Black enforces double quotes
- Multiline expressions → Black has strong opinions on line breaks
isort (Import Sorter)
Sorts and organizes imports into groups.
Check import order:
isort --check .
Fix import order:
isort .
Configuration: pyproject.toml under [tool.isort]
- Profile: "black" (compatible with black formatting)
- Line length: 120
Import groups (in order):
- Standard library imports
- Third-party imports
- Local application imports
Example:
# Standard library
import os
from typing import Optional
# Third-party
from fastapi import APIRouter
from pydantic import BaseModel
# Local
from galaxy.managers.workflows import WorkflowsManager
from galaxy.schema.schema import WorkflowSummary
Flake8 (Legacy Linter)
Traditional Python linter - still used alongside ruff.
Run flake8:
flake8 .
Configuration: .flake8 file in repository root
Note: Ruff covers most flake8 checks. Galaxy maintains flake8 for specific rules not yet in ruff.
Darker (Incremental Formatter)
Applies black/isort only to changed lines.
Format changed code:
make diff-format
How it works:
- Compares working tree to
origin/dev - Runs black and isort only on modified lines
- Much faster than full formatting
- Ideal for daily development
Use when:
- Working on large files with many unchanged lines
- Want fast formatting feedback
- Developing features incrementally
CI Integration
GitHub Actions runs these checks:
.github/workflows/lint.yamldefines CI linting pipeline- Four tox environments:
format,lint,mypy,lint_docstring_include_list
To match CI locally:
tox -e format # Check formatting
tox -e lint # Check linting
Configuration Files
Python linting configuration:
pyproject.toml- ruff, black, isort, mypy config.flake8- flake8 rules and exclusionstox.ini- tox environment definitions
Read these files to understand specific rules:
# View ruff config
grep -A 20 '\[tool.ruff\]' pyproject.toml
# View black config
grep -A 10 '\[tool.black\]' pyproject.toml
# View flake8 config
cat .flake8
If $ARGUMENTS is "client": Client-Side Linting
Galaxy's client-side code (Vue.js, TypeScript) uses ESLint and Prettier.
Prerequisites
Ensure Node.js dependencies are installed:
make client-node-deps
This installs ESLint, Prettier, and related packages in client/node_modules/.
ESLint (JavaScript/TypeScript Linter)
Check for linting issues:
make client-lint
Configuration: client/.eslintrc.js
Rules enforced:
- Vue.js best practices
- TypeScript type safety
- Unused variables
- Console statements (warnings)
- Naming conventions
Common issues:
- Unused variables → Remove or prefix with
_ - Missing types → Add TypeScript type annotations
- Vue template issues → Check component syntax
- Console.log statements → Remove or justify with comments
Prettier (Code Formatter)
Format client code:
make client-format
Configuration: client/.prettierrc.yml
Formats:
- JavaScript/TypeScript files
- Vue single-file components
- CSS/SCSS files
- JSON files
Integration with ESLint:
- Prettier handles formatting (indentation, quotes, line breaks)
- ESLint handles code quality (unused vars, type safety)
- ESLint config includes
prettierplugin to avoid conflicts
Granular Makefile Targets
Galaxy's Makefile provides fine-grained control over client linting:
Run only ESLint (no Prettier check):
make client-eslint
Run only Prettier check (no ESLint):
make client-format-check
Auto-fix ESLint errors with --fix (no Prettier):
make client-lint-autofix
Pre-commit hook linting (for specific file paths):
make client-eslint-precommit
This is used by Git hooks and operates on specific file paths rather than glob patterns.
Important distinctions:
make client-lint=make client-eslint+make client-format-check(runs both tools)make client-format=make client-lint-autofix+ Prettier write (auto-fixes everything)
Manual Commands
Run ESLint directly:
cd client
npm run eslint
Run Prettier directly:
cd client
npm run prettier:check # Check
npm run prettier:write # Fix
Client Lint Workflow
# 1. Install dependencies (if needed)
make client-node-deps
# 2. Check for issues
make client-lint
# 3. Auto-fix formatting
make client-format
# 4. Manually fix remaining ESLint issues
# (Edit files based on lint output)
# 5. Verify fixed
make client-lint
If $ARGUMENTS is "mypy": Type Checking
Galaxy uses mypy for static type checking with strict mode enabled.
Running Type Checks
Check types across codebase:
tox -e mypy
Check specific file or directory:
mypy lib/galaxy/managers/workflows.py
mypy lib/galaxy/schema/
Configuration: pyproject.toml under [tool.mypy]
Strict mode enabled:
disallow_untyped_defs- All functions must have type hintsdisallow_any_generics- Must specify generic types (e.g.,List[str]notList)warn_return_any- Warn on returningAnywarn_unused_ignores- Warn on unnecessary# type: ignorecomments
Common Type Errors
Error: "Function is missing a type annotation"
# Bad
def process_workflow(workflow_id):
...
# Good
def process_workflow(workflow_id: int) -> dict:
...
Error: "Need type annotation for variable"
# Bad
workflows = []
# Good
workflows: List[Workflow] = []
Error: "Incompatible return value type"
# Bad
def get_workflow() -> Workflow:
return None # Error: None is not Workflow
# Good
from typing import Optional
def get_workflow() -> Optional[Workflow]:
return None # OK: Optional[Workflow] allows None
Error: "Incompatible types in assignment"
# Bad
workflow_id: int = "123" # Error: str is not int
# Good
workflow_id: int = 123
Error: "Cannot determine type of variable"
# Bad (mypy can't infer type)
result = get_complex_data()
# Good (explicit annotation)
result: Dict[str, Any] = get_complex_data()
Type Ignoring (Use Sparingly)
When mypy is wrong or you're working with untyped libraries:
# Ignore specific line
result = third_party_function() # type: ignore[misc]
# Ignore entire function
def legacy_function(): # type: ignore
...
Best practice: Add an issue comment explaining why you're ignoring types.
Common Typing Patterns
Optional values:
from typing import Optional
def find_workflow(workflow_id: int) -> Optional[Workflow]:
# Returns Workflow or None if not found
...
Union types:
from typing import Union
def process_input(data: Union[str, int]) -> str:
return str(data)
Generic collections:
from typing import List, Dict, Set, Tuple
workflows: List[Workflow] = []
metadata: Dict[str, str] = {}
tags: Set[str] = set()
coord: Tuple[int, int] = (10, 20)
Callable types:
from typing import Callable
def apply_function(func: Callable[[int], str], value: int) -> str:
return func(value)
Type Stubs
Galaxy provides type stubs for untyped dependencies in lib/galaxy/type_stubs/.
If $ARGUMENTS is "full": Complete Lint Suite
Run all CI checks locally to ensure your code will pass:
Recommended Order
# 1. Format check (fast)
tox -e format
# If issues found, fix formatting:
make diff-format # or make format
# 2. Lint check (fast)
tox -e lint
# If issues found, fix with:
ruff check --fix .
# 3. Type check (medium speed)
tox -e mypy
# Fix type errors manually (see /galaxy-linting mypy)
# 4. Docstring check (fast)
tox -e lint_docstring_include_list
# 5. Client lint (if you changed client code)
make client-lint
make client-format
All-in-One Command
Run all Python checks:
tox -e format && tox -e lint && tox -e mypy && tox -e lint_docstring_include_list
Why this order:
- Formatting first - Cheapest to fix, may resolve some lint issues
- Linting second - Many auto-fixable issues
- Type checking third - Requires manual fixes, benefits from clean lint
- Docstring check last - Specific to certain files
Tox Environment Details
tox -e format:
- Runs: black --check, isort --check
- Purpose: Verify formatting compliance
- Fix with:
make formatormake diff-format
tox -e lint:
- Runs: ruff check, flake8
- Purpose: Catch code style violations
- Fix with:
ruff check --fix .+ manual fixes
tox -e mypy:
- Runs: mypy on selected directories
- Purpose: Type checking
- Fix with: Add type hints manually
tox -e lint_docstring_include_list:
- Runs: ruff on docstring_include_list modules
- Purpose: Enforce docstring standards on core modules
- Fix with: Add/improve docstrings
CI Workflow File
See the full CI setup:
cat .github/workflows/lint.yaml
This shows exactly what CI runs. Match these checks locally to avoid CI failures.
Other Lint Targets
Galaxy's Makefile includes additional linting targets for specialized use cases:
API Schema Linting
Lint OpenAPI schema:
make lint-api-schema
Builds the OpenAPI schema, then lints it with Redocly CLI and checks spelling with codespell. Useful when modifying API endpoints or Pydantic schemas.
XSD Schema Formatting
Format Galaxy's tool XSD schema:
make format-xsd
Formats Galaxy's tool XSD schema (lib/galaxy/tool_util/xsd/galaxy.xsd) with xmllint. Use when modifying tool schema definitions.
Configuration File Linting
Lint Galaxy configuration files:
make config-lint # Lint galaxy.yml
make tool-shed-config-lint # Lint tool_shed.yml
make reports-config-lint # Lint reports.yml
Validates YAML configuration files for syntax and structure issues. Run these when modifying Galaxy configuration schemas.
File Sources Validation
Validate file sources configuration:
make files-sources-lint # Validate file sources config
make files-sources-lint-verbose # Verbose output with details
Use when working with file sources plugins or configuration.
Update Lint Requirements
Update pinned lint dependency versions:
make update-lint-requirements
Updates pinned lint dependency versions in lib/galaxy/dependencies/. Run this when upgrading linting tools or resolving dependency conflicts.
Troubleshooting
"black would reformat" Error
Symptom: CI fails with "would reformat X files"
Solution:
# Run black locally
black .
# Or for changed files only
make diff-format
# Commit the formatting changes
git add -u
git commit -m "Apply black formatting"
Ruff Errors Won't Auto-Fix
Symptom: ruff check --fix doesn't fix all issues
Cause: Some ruff rules require manual fixes (e.g., undefined names, logic errors)
Solution:
- Run
ruff check .to see remaining issues - Read error messages carefully
- Fix manually based on error codes
- Common manual fixes:
F821(undefined name) → Import or define the nameE501(line too long) → Break line manuallyBrules (bugbear) → Logic changes required
Flake8 Errors After Passing Ruff
Symptom: Ruff passes but flake8 fails in CI
Cause: Flake8 has some rules ruff doesn't cover yet
Solution:
# Run flake8 locally
flake8 .
# Fix issues manually
# (Common: line length, docstring issues, specific style rules)
Tox Environment Creation Fails
Symptom: tox -e lint fails to create environment
Cause: Dependency conflicts or outdated tox cache
Solution:
# Recreate tox environment
tox -e lint --recreate
# If still failing, clear tox cache
rm -rf .tox/
tox -e lint
Mypy Errors in Unchanged Code
Symptom: Type errors in files you didn't modify
Cause: Your changes altered types used elsewhere
Solution:
- Check imports - did you change a function signature?
- Run mypy on specific file to see full context:
mypy lib/galaxy/managers/your_file.py - Fix type annotations to match your changes
- Consider if your change needs broader type updates
Missing Linting Tools
Symptom: Command not found (ruff, black, etc.)
Cause: Tools not installed in current environment
Solution:
# Install dev dependencies
pip install -r lib/galaxy/dependencies/dev-requirements.txt
# Or use tox (recommended)
tox -e lint # Tox creates isolated environments with correct dependencies
Conflicting Formatting Between Tools
Symptom: Black and isort disagree on formatting
Cause: Misconfigured tool settings
Solution:
- Galaxy's config already handles this (
pyproject.tomlsets isort profile to "black") - If you see conflicts, ensure you're using repo's config:
# Check config is being read black --verbose . isort --check-only --verbose .
Client Lint Failures
Symptom: make client-lint fails with many errors
Solution:
# 1. Ensure dependencies installed
make client-node-deps
# 2. Auto-fix formatting
make client-format
# 3. Check remaining issues
make client-lint
# 4. Fix ESLint issues manually
# (Usually: remove unused vars, add types, fix Vue template issues)
Additional Resources
Configuration files:
pyproject.toml- ruff, black, isort, mypy settings.flake8- flake8 configurationtox.ini- tox environment definitionsclient/.eslintrc.js- ESLint rulesclient/.prettierrc.yml- Prettier settings
Makefile targets:
# View all linting-related targets
grep -A 2 'format\|lint' Makefile
CI workflow:
# See what CI runs
cat .github/workflows/lint.yaml
Tool documentation:
- Ruff: https://docs.astral.sh/ruff/
- Black: https://black.readthedocs.io/
- mypy: https://mypy.readthedocs.io/
- ESLint: https://eslint.org/docs/
- Prettier: https://prettier.io/docs/
Galaxy-specific patterns:
- Code style guide:
doc/source/dev/style_guide.md(if exists) - Type hints guide:
doc/source/dev/type_hints.md(if exists)
Quick Command Reference
Most common workflows:
# Quick check before committing
tox -e format && tox -e lint
# Fix formatting issues
make diff-format # Incremental (fast)
make format # Full (thorough)
# Fix auto-fixable lint issues
ruff check --fix .
# Modernize Python syntax
make pyupgrade
# Full CI simulation
tox -e format && tox -e lint && tox -e mypy && tox -e lint_docstring_include_list
# Client-side
make client-lint
make client-format
# Client-side (granular)
make client-eslint # ESLint only
make client-format-check # Prettier check only
make client-lint-autofix # Auto-fix ESLint
# Lint API schema (after endpoint changes)
make lint-api-schema
# Lint config files
make config-lint
make tool-shed-config-lint
make reports-config-lint
Remember: Run make diff-format frequently during development to keep code formatted incrementally!