Implementation:MarketSquare Robotframework browser Inv Lint
Appearance
Document Type
API Doc -- Documents the Invoke tasks for code quality enforcement across Python, TypeScript, and Robot Framework in the robotframework-browser project.
API Summary
Four Invoke tasks handle linting:
lint-- Composite task that runs all language-specific linterslint_python-- Runs ruff (format + check) and mypy on Python codelint_node-- Runs eslint on TypeScript codelint_robot-- Runs robocop on Robot Framework test files
Source References
| File | Lines | Description |
|---|---|---|
tasks.py |
L754-756 | lint composite task
|
tasks.py |
L662-703 | lint_python task
|
tasks.py |
L706-717 | lint_node task
|
tasks.py |
L720-751 | lint_robot task
|
CLI Usage
# Run all linters
inv lint
# Python only (check mode)
inv lint-python
# Python only (fix mode - auto-format and auto-fix)
inv lint-python --fix
# Node.js only
inv lint-node
# Node.js only (force even if no changes)
inv lint-node --force
# Robot Framework only
inv lint-robot
Task: lint
@task(lint_python, lint_node, lint_robot)
def lint(c):
pass
CLI: inv lint
Dependencies: lint_python, lint_node, lint_robot
Behavior: Runs all three language-specific lint tasks in dependency order. The task body is empty because all work is done by the dependencies.
Task: lint_python
Signature
@task
def lint_python(c, fix=False):
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
fix |
bool | False | When True, auto-formats and auto-fixes code instead of just checking |
Source Code
@task
def lint_python(c, fix=False):
ruff_cmd_format = [
"ruff",
"format",
"--config",
"pyproject.toml",
"Browser/",
"bootstrap.py",
"tasks.py",
"utest",
"browser_batteries",
]
ruff_cmd_check = [
"ruff",
"check",
"--config",
"pyproject.toml",
"Browser/",
"browser_batteries/",
"bootstrap.py",
]
if fix:
ruff_cmd_check.insert(2, "--fix")
else:
ruff_cmd_format.insert(2, "--check")
print(f"Run ruff format: {ruff_cmd_format}")
c.run(" ".join(ruff_cmd_format))
print(f"Run ruff check: {ruff_cmd_check}")
c.run(" ".join(ruff_cmd_check))
print("Run mypy:")
mypy_cmd = [
"mypy",
"--exclude",
".venv",
"--config-file",
"Browser/mypy.ini",
"Browser/",
"bootstrap.py",
"browser_batteries/",
]
c.run(" ".join(mypy_cmd))
Behavior
The task runs three tools in sequence:
1. Ruff Format:
| Mode | Command |
|---|---|
| Check (default) | ruff format --check --config pyproject.toml Browser/ bootstrap.py tasks.py utest browser_batteries
|
| Fix | ruff format --config pyproject.toml Browser/ bootstrap.py tasks.py utest browser_batteries
|
2. Ruff Check:
| Mode | Command |
|---|---|
| Check (default) | ruff check --config pyproject.toml Browser/ browser_batteries/ bootstrap.py
|
| Fix | ruff check --fix --config pyproject.toml Browser/ browser_batteries/ bootstrap.py
|
3. Mypy:
mypy --exclude .venv --config-file Browser/mypy.ini Browser/ bootstrap.py browser_batteries/
Mypy always runs in check mode (there is no auto-fix for type errors).
Task: lint_node
Signature
@task
def lint_node(c, force=False):
"""Lint node files"""
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
force |
bool | False | Force linting even if no TypeScript files have changed |
Source Code
@task
def lint_node(c, force=False):
"""Lint node files
Args:
force: When set, lints node files even there is not changes.
"""
if _sources_changed(node_dir.glob("**/*.ts"), node_lint_timestamp_file) or force:
c.run("npm run lint")
node_lint_timestamp_file.touch()
else:
print("no changes in .ts files, skipping node lint")
Behavior
- Checks if any
.tsfiles innode/have been modified since the last lint run (tracked bynode/.lintedtimestamp file) - If changed (or
--force): runsnpm run lintand updates the timestamp file - If unchanged: prints a message and skips
Task: lint_robot
Signature
@task
def lint_robot(c):
Source Code
@task
def lint_robot(c):
in_ci = os.getenv("GITHUB_WORKFLOW")
print(f"Lint Robot files {'in ci' if in_ci else ''}")
atest_folder = Path("atest/").resolve()
config_file = Path("pyproject.toml").resolve()
cmd = [
"robocop",
"format",
"--config",
str(config_file),
]
if IN_CI:
cmd.insert(2, "--check")
cmd.insert(3, "--diff")
atest_11_tidy_transformer = atest_folder.joinpath(
"test", "11_tidy_transformer", "network_idle_file.robot"
)
atest_resrouces = list(atest_folder.joinpath("test").glob("*.resource"))
cmd.extend(
[
"--exclude",
str(atest_11_tidy_transformer),
"--exclude",
str(atest_resrouces[0]),
"--exclude",
str(atest_resrouces[1]),
str(atest_folder),
]
)
print(cmd)
c.run(" ".join(cmd))
Behavior
- Detects whether running in CI (via
GITHUB_WORKFLOWenvironment variable) - Builds the robocop command:
- Base:
robocop format --config pyproject.toml - In CI: adds
--check --diff(report violations, show diffs, do not modify) - In development: runs without
--check(auto-formats in place)
- Base:
- Excludes specific files:
atest/test/11_tidy_transformer/network_idle_file.robot-- Intentionally non-standard- Two
.resourcefiles from the test directory
- Targets the entire
atest/directory
Tool Summary
| Tool | Language | Check Command | Fix Command | Configuration |
|---|---|---|---|---|
| ruff format | Python | ruff format --check |
ruff format |
pyproject.toml
|
| ruff check | Python | ruff check |
ruff check --fix |
pyproject.toml
|
| mypy | Python | mypy |
N/A (no auto-fix) | Browser/mypy.ini
|
| eslint | TypeScript | npm run lint |
N/A | eslint.config.js (via npm)
|
| robocop | Robot Framework | robocop format --check --diff |
robocop format |
pyproject.toml
|
Related
- MarketSquare_Robotframework_browser_Code_Quality_Enforcement -- Principle document for code quality enforcement
- MarketSquare_Robotframework_browser_Inv_Utest_Atest -- Testing tasks that complement linting
- MarketSquare_Robotframework_browser_Inv_Build -- Build tasks in the same task file
Requires Environment
Page Connections
Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment