Skip to content

Commit ccdc5c4

Browse files
committed
feat: linting, formating and CI updates
1 parent bebf066 commit ccdc5c4

16 files changed

Lines changed: 170 additions & 77 deletions

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
branches:
55
- main
66
tags:
7-
- '**'
7+
- "**"
88
release:
99
types:
1010
- published

.github/workflows/python_lint_and_test.yaml

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ jobs:
2020
uses: actions/setup-python@v5
2121
with:
2222
python-version: ${{ matrix.python-version }}
23-
cache: 'pip'
24-
cache-dependency-path: '**/requirements.txt'
23+
cache: "pip"
24+
cache-dependency-path: "**/requirements.txt"
2525
# architecture: x64
2626
- name: Install dependencies
2727
run: |
@@ -32,16 +32,8 @@ jobs:
3232
- name: Run python style and linting tools
3333
run: |
3434
err=0
35-
echo autoflake:
36-
autoflake --check-diff . || err=$?
37-
echo black:
38-
black --check . || err=$?
39-
echo docformatter:
40-
docformatter . || err=$?
41-
echo flake8:
42-
flake8 . || err=$?
43-
echo isort:
44-
isort --check . || err=$?
35+
pre-commit install
36+
pre-commit run --all-files --hook-stage pre-commit || err=$?
4537
exit $err
4638
- name: Run tests with coverage
4739
run: |

.github/workflows/requirements.txt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
autoflake
2-
black
31
coverage[toml]
4-
docformatter
5-
flake8
6-
isort
2+
pre-commit
3+

.pre-commit-config.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# This file contains 2 stages
2+
# pre-commit stage - runs by default pre-commit
3+
# manual stage - runs the same tools but modifies files
4+
# run as: pre-commit run --all-files --hook-stage manual
5+
repos:
6+
# See README.md for more information on this pre-commit hook
7+
# Please uncomment this hook if you are a Red Hat employee, and make sure you don't commit it back upstream
8+
# - repo: https://gitlab.cee.redhat.com/infosec-public/developer-workbench/tools.git
9+
# rev: rh-pre-commit-2.3.0
10+
# hooks:
11+
# # If you have not run this hook on your system before, it may prompt you to
12+
# # log in for patterns, and you will need to try again.
13+
# #
14+
# # Docs: https://source.redhat.com/departments/it/it-information-security/leaktk/leaktk_components/rh_pre_commit
15+
# - id: rh-pre-commit
16+
# name: Red Hat pre-commit (check)
17+
# # - id: rh-pre-commit.commit-msg # Optional for commit-msg attestation
18+
- repo: https://github.com/PyCQA/docformatter
19+
rev: v1.7.7
20+
hooks:
21+
- id: docformatter
22+
name: docformatter (check)
23+
additional_dependencies: [tomli]
24+
args: [--check, --config, ./pyproject.toml]
25+
stages: [pre-commit]
26+
- id: docformatter
27+
name: docformatter (fix)
28+
additional_dependencies: [tomli]
29+
args: [--in-place, --config, ./pyproject.toml]
30+
stages: [manual]
31+
- repo: https://github.com/psf/black
32+
rev: 25.1.0
33+
hooks:
34+
- id: black
35+
name: black (check)
36+
args: [--check]
37+
stages: [pre-commit]
38+
- id: black
39+
name: black (fix)
40+
stages: [manual]
41+
- repo: https://github.com/astral-sh/ruff-pre-commit
42+
rev: v0.12.1
43+
hooks:
44+
- id: ruff-check
45+
name: ruff linter (check)
46+
stages: [pre-commit]
47+
- id: ruff-check
48+
name: ruff linter (fix)
49+
args: [--fix]
50+
stages: [manual]

README.md

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
# `logilica-cli`
22

33
`logilica-cli` is a command-line tool which provides CLI access to the Logilica
4-
UI. The tool currently provides two subcommands. The first exports charts and
4+
UI. The tool currently provides two subcommands. The first exports charts and
55
text from Logilica reports and makes them available in a variety of formats,
6-
including HTML, Markdown, and as a Google Docs document. The second is used to
6+
including HTML, Markdown, and as a Google Docs document. The second is used to
77
configure Logilica integrations, supporting a "configuration as code" approach.
88

99
The tool is configured via a YAML file which contains tool configuration
10-
options as well as options for exporting data or configuring Logilica. By
10+
options as well as options for exporting data or configuring Logilica. By
1111
default, the file `logica-cli.yaml` in the current directory is used, but an
1212
alternate path can be specified on the command line.
1313

14-
For export, the configuration includes a list of teams. For each team, it
15-
specifies a list of Logilica dashboards and the team's Jira project. For each
14+
For export, the configuration includes a list of teams. For each team, it
15+
specifies a list of Logilica dashboards and the team's Jira project. For each
1616
dashboard, it specifies the name of an output file (which must not conflict
1717
with any other team's dashboards' output files) and possibly other attributes.
1818

@@ -29,32 +29,31 @@ the configuration file.
2929

3030
Credentials for accessing Logilica are provided by command line options or by
3131
the environment variables, `LOGILICA_DOMAIN`, `LOGILICA_EMAIL`, and
32-
`LOGILICA_PASSWORD`. (Note to the Developer Practices Team: the appropriate
32+
`LOGILICA_PASSWORD`. (Note to the Developer Practices Team: the appropriate
3333
values for the bot accounts can be obtained from the Bitwarden vault; users
3434
with admin privileges can also create their own username/password credentials
35-
using the Logilica UI.) For interactive use, OAuth or SSO credentials can be
35+
using the Logilica UI.) For interactive use, OAuth or SSO credentials can be
3636
used. The tool normally runs in "headless" mode; however, in order to enable
3737
the user to perform an SSO login, the tool opens a browser window during the
38-
run. (You should not interact with this window unless it prompts for your SSO
38+
run. (You should not interact with this window unless it prompts for your SSO
3939
credentials; otherwise, you are likely to disrupt the functioning of the tool.)
4040

41-
To run the tool, check out the Git repo and run:
42-
```pip install -r requirements.txt .```
41+
To install the tool, check out the Git repo and run:
42+
43+
```
44+
pip install -r requirements.txt .
45+
playwright install chromium
46+
```
47+
4348
We recommend doing this inside a [virtual environment](https://docs.python.org/3/library/venv.html),
44-
which uses Python 3.12+. (If you are doing development on the tool, you may want
45-
to specify `-e` in the `pip install` command.) After installing the tool, you also
46-
need to install the browser which it uses to interact with the Logilica web UI:
47-
```playwright install chromium``` (For details on debugging the web interactions,
48-
see the `--pwdebug` option in the command help, below, and the
49-
[Playwright documentation](https://playwright.dev/python/docs/running-tests).)
49+
which uses Python 3.12+.
5050

5151
The PDF files containing the downloaded Logilica reports are stored in a
5252
temporary directory which is created if it does not exist; if it was created by
53-
the tool, the directory is deleted after execution is complete. By default,
54-
the directory is named `lwr_downloaded_pdfs`, and it is created in the current
55-
directory, but an alternate path can be specified on the command line.
53+
the tool, the directory is deleted after execution is complete.
5654

5755
Help is available on the command line:
56+
5857
```text
5958
Usage: logilica-cli [OPTIONS] COMMAND [ARGS]...
6059
@@ -80,6 +79,7 @@ Commands:
8079
```
8180

8281
```text
82+
logilica-cli weekly-report --help
8383
Usage: logilica-cli weekly-report [OPTIONS]
8484
8585
Downloads and processes weekly report for teams specified in the
@@ -90,9 +90,11 @@ Options:
9090
Name [env var: LOGILICA_DOMAIN; required]
9191
-t, --downloads-temp-dir DIRECTORY
9292
Path to a directory to receive downloaded
93-
files (will be created if it doesn't exist;
94-
will be deleted if created) [default:
95-
./lwr_downloaded_pdfs]
93+
files (if unspecified, a temporary directory
94+
will be used; otherwise, the specified
95+
directory will be created if it doesn't
96+
exist; if the directory is created by the
97+
tool, it will be deleted after the run)
9698
-I, --input [logilica|local] Input source -- download from Logilica or
9799
use pre-downloaded files [default:
98100
logilica]
@@ -161,7 +163,35 @@ Options:
161163
var: LOGILICA_EMAIL]
162164
--help Show this message and exit.
163165
```
166+
164167
Some dashboards can be quite slow to load into the UI, so, if you are running
165168
the tool interactively and wish to track its progress, add a `-v` to the command
166-
line to see informational messages. (If you are debugging or just nosy, adding
169+
line to see informational messages. (If you are debugging or just nosy, adding
167170
a _second_ `-v` will add debugging messages to the output.)
171+
172+
## Development
173+
174+
If you are doing development on the tool, you may want to specify `-e` in the `pip install` command to install it in editable mode.
175+
This means that you can make changes to the package's source code and those changes will be reflected in your project without having to reinstall the package.
176+
177+
For details on debugging the web interactions, see the `--pwdebug` option in the command help and the [Playwright documentation](https://playwright.dev/python/docs/running-tests).
178+
179+
### Linting and formatting rules
180+
181+
This project uses `pre-commit` to handle linting and formatting. The `pre-commit` tool reads its configuration from [`.pre-commit-config.yaml`](./.pre-commit-config.yaml) and the configuration options for the individual linters and formatters can be found in the [`pyproject.toml`](./pyproject.toml) file.
182+
The same configuration is used in CI.
183+
184+
To install and execute it locally, follow these steps:
185+
186+
```
187+
pip install pre-commit
188+
pre-commit install
189+
pre-commit run --all-files --hook-stage [pre-commit|manual]
190+
```
191+
192+
If you run `pre-commit` stage, you can check your files, if you run `manual` stage, it will modify your files to correct problems it finds.
193+
194+
### Enabling Red Hat InfoSec plugin
195+
196+
If you are developing locally within Red Hat, you should enable Red Hat InfoSec plugin. You can do that by uncommenting appropriate lines in `.pre-commit-config.yaml` file.
197+
Make sure that you don't commit that change back upstream, as it would break the CI.

logilica_cli/data_sources.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@
1010
@common_options
1111
@click.pass_context
1212
def data_sources(
13-
context: click.Context,
14-
username: str,
15-
password: str,
16-
domain: str,
17-
oauth: bool,
13+
context: click.Context, username: str, password: str, domain: str, oauth: bool
1814
) -> None:
1915
"""Synchronizes configuration of integrations with the configuration file.
2016

logilica_cli/page_dashboard.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ class DashboardPage:
99
PDF_EXPORT_TIMEOUT = 120000
1010

1111
def __init__(self, page: Page):
12-
# PDF generation might take longer than default 30000 ms timeout, so modify for this page in global
13-
# It can be export or download button that takes time to become visible
12+
# PDF generation might take longer than default 30000 ms timeout,
13+
# so modify for this page in global.
14+
# It can be export or download button that takes time to become visible.
1415
page.set_default_timeout(self.PDF_EXPORT_TIMEOUT)
1516
self.page = page
1617
self.export_pdf_button = page.get_by_role("button", name="Export PDF")

logilica_cli/page_navigation.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ def navigate(self, *, menu_dropdown: Optional[str], link_name: str) -> None:
2626

2727
link_locator = self.page.get_by_role("link", name=link_name)
2828

29-
# if dropdown argument was provided, check if dropdown is open as it hides the link
29+
# If dropdown argument was provided, check if dropdown is open as
30+
# it hides the link
3031
if menu_dropdown:
3132
for first_try in (True, False):
3233
try:

logilica_cli/page_settings.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ class SettingsPage:
2626
AVAILABLE_LIST_TIMEOUT = 54000
2727

2828
def __init__(self, page: Page):
29-
3029
self.page = page
3130
# UI elements for public access
3231
self.add_public_repository_dialog_button = page.get_by_role(
@@ -62,7 +61,9 @@ def open_integration_configuration(
6261
"""
6362

6463
logging.debug(
65-
"Opening integration '%s', connector type:'%s'", integration, connector
64+
"Opening integration '%s', connector type:'%s'",
65+
integration,
66+
connector,
6667
)
6768
self.page.locator("div.items-center").filter(has_text=connector).filter(
6869
has_text=integration
@@ -78,7 +79,8 @@ def sync_integrations(self, integrations: dict[str, Any]) -> None:
7879
in integrations sections of the local configuration file.
7980
8081
Raises:
81-
RuntimeError: If any repositories could not have been added to the configuration.
82+
RuntimeError:
83+
If any repositories could not have been added to the configuration.
8284
"""
8385

8486
sync_failures: IntegrationSyncFailures = defaultdict(list)
@@ -278,7 +280,8 @@ def has_entity_imported(
278280
) -> bool:
279281
search_field.fill(entity_id)
280282

281-
# here we need to find the innermost div element that exactly matches repository slug
283+
# Here we need to find the innermost div element
284+
# that exactly matches repository slug.
282285
found = self.page.get_by_text(text=entity_id, exact=True).nth(0).is_visible()
283286
if found:
284287
logging.debug("✅%s '%s' is imported", entity_type, entity_id)
@@ -322,8 +325,8 @@ def add_public_repository(
322325
self.add_public_repository_dialog_button.click()
323326
self.add_public_repository_input.fill(f"{host}/{entity_id}.git")
324327
self.add_public_repository_confirm_button.click()
325-
# as UI refresh is triggered independently of the click and there is no guarantee the repository will be added
326-
# at the top of the page, we don't validate the action success here but later
328+
# UI refresh is triggered independently of the click and there is no guarantee
329+
# the repository will be added at the top of the page, we'll validate it later
327330
return True
328331

329332
def add_membership_entity(
@@ -373,8 +376,8 @@ def control_button(self, entity_id: str, *, order=0) -> Optional[Locator]:
373376
.get_by_role("button")
374377
)
375378

376-
# there might be the same slug in both imported repositories and available repositories
377-
# in that case, we want to be able to select one specifically
379+
# There might be the same slug in both imported repositories and available
380+
# repositories, in that case, we want to be able to select one specifically.
378381
count = locator.count()
379382
if count == 1:
380383
return locator

logilica_cli/pdf_convert.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ def to_format_multiple(
9292
teams: dict[str, dict[str, Any]],
9393
embed_images: bool = True,
9494
) -> int:
95-
9695
total = 0
9796
for team, dashboards in teams.items():
9897
for dashboard, options in dashboards["team_dashboards"].items():

0 commit comments

Comments
 (0)