Skip to content

Commit d50e1c7

Browse files
authored
Merge pull request #48 from derek10cloud/add-lint
Add ruff linter to improve code quality and maintainability
2 parents 49e93ac + b3d9e4a commit d50e1c7

File tree

13 files changed

+649
-175
lines changed

13 files changed

+649
-175
lines changed

.github/workflows/lint-check.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Lint Check
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
check_lint:
11+
defaults:
12+
run:
13+
working-directory: "stackql_deploy"
14+
runs-on: ubuntu-latest
15+
if: github.event_name == 'pull_request'
16+
strategy:
17+
max-parallel: 1
18+
matrix:
19+
python-version: ["3.11"]
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v2
23+
24+
- name: Set up Python ${{ matrix.python-version }}
25+
uses: actions/setup-python@v4
26+
with:
27+
python-version: ${{ matrix.python-version }}
28+
29+
- name: Install dependencies
30+
run: pip install ruff
31+
32+
- name: Lint check with ruff
33+
run: ruff check .

README.md

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
11
<!-- web assets -->
2+
23
[logo]: https://stackql.io/img/stackql-logo-bold.png "stackql logo"
34
[deploylogo]: https://stackql.io/img/stackql-deploy-logo.png "stackql-deploy logo"
45
[stackqlrepo]: https://github.com/stackql/stackql
56
[homepage]: https://stackql.io/
67
[docs]: https://stackql.io/docs
78
[blog]: https://stackql.io/blog
89
[registry]: https://github.com/stackql/stackql-provider-registry
10+
911
<!-- [readthedocs]: -->
12+
1013
[pypi]: https://pypi.org/project/stackql-deploy/
14+
1115
<!-- badges -->
16+
1217
[badge1]: https://img.shields.io/badge/platform-windows%20macos%20linux-brightgreen "Platforms"
1318
[badge2]: https://img.shields.io/pypi/v/stackql-deploy "PyPi Version"
1419
[badge3]: https://img.shields.io/pypi/dm/stackql-deploy "PyPi Downloads"
1520
[badge4]: https://img.shields.io/github/license/stackql/stackql "License"
21+
1622
<!-- github links -->
23+
1724
[discussions]: https://github.com/orgs/stackql/discussions
1825
[issues]: https://github.com/stackql/stackql-deploy/issues/new/choose
26+
1927
<!-- misc links -->
28+
2029
[twitter]: https://twitter.com/stackql
2130

2231
<!-- language: lang-none -->
@@ -36,23 +45,25 @@
3645
<p align="center">
3746

3847
<!-- [__Read the docs »__][readthedocs] -->
39-
[__PyPi__][pypi]
40-
[__Raise an Issue__][issues]
48+
49+
[**PyPi**][pypi]
50+
[**Raise an Issue**][issues]
4151

4252
</p>
4353
</div>
4454

4555
## About The Project
4656

47-
[__`stackql-deploy`__][pypi] is an open-source command line utility which implements a declarative, model driven framework to deploy and manage multi cloud stacks using [__`stackql`__][stackqlrepo]. [__`stackql-deploy`__][pypi] is distributed as a Python script to be used as a CLI tool, do the following to get started:
57+
[**`stackql-deploy`**][pypi] is an open-source command line utility which implements a declarative, model driven framework to deploy and manage multi cloud stacks using [**`stackql`**][stackqlrepo]. [**`stackql-deploy`**][pypi] is distributed as a Python script to be used as a CLI tool, do the following to get started:
4858
<br />
4959

5060
```bash
5161
pip install stackql-deploy
5262
```
5363

54-
> __Note for macOS users__
55-
> to install `stackql-deploy` in a virtual environment (which may be necessary on __macOS__), use the following:
64+
> **Note for macOS users**
65+
> to install `stackql-deploy` in a virtual environment (which may be necessary on **macOS**), use the following:
66+
>
5667
> ```bash
5768
> python3 -m venv myenv
5869
> source myenv/bin/activate
@@ -61,15 +72,15 @@ pip install stackql-deploy
6172
6273
## About StackQL
6374
64-
StackQL is a utility which allows you to query and interact with cloud and SaaS resources in real time using SQL grammar. StackQL supports a full set of SQL query/DML grammar, including `JOIN`, `UNION` adn subquery functionality and supports mutation operations on cloud and SaaS resources such as `create`, `update` and `delete`, implemented as `INSERT`, `UPDATE` and `DELETE` respectively. StackQL also supports grammar for performing lifecycle operations such as starting or stopping a VM using the `EXEC` statement.
75+
StackQL is a utility which allows you to query and interact with cloud and SaaS resources in real time using SQL grammar. StackQL supports a full set of SQL query/DML grammar, including `JOIN`, `UNION` adn subquery functionality and supports mutation operations on cloud and SaaS resources such as `create`, `update` and `delete`, implemented as `INSERT`, `UPDATE` and `DELETE` respectively. StackQL also supports grammar for performing lifecycle operations such as starting or stopping a VM using the `EXEC` statement.
6576
66-
StackQL provider definitions are defined in plaintext OpenAPI extensions to the providers specification. These definitions are then used to generate the SQL schema and the API client. The source for the provider definitions are stored in the [__StackQL Registry__][registry].
77+
StackQL provider definitions are defined in plaintext OpenAPI extensions to the providers specification. These definitions are then used to generate the SQL schema and the API client. The source for the provider definitions are stored in the [**StackQL Registry**][registry].
6778
6879
## How it works
6980
7081
<!-- > see [__readthedocs__]() for more detailed documentation -->
7182
72-
A __`stackql-deploy`__ project is a directory containing StackQL scripts with a manifest file at the root of the directory, for example:
83+
A **`stackql-deploy`** project is a directory containing StackQL scripts with a manifest file at the root of the directory, for example:
7384
7485
```
7586
├── example_stack
@@ -115,9 +126,9 @@ resources:
115126
116127
Deployment orchestration using `stackql-deploy` includes:
117128
118-
- __*pre-flight*__ checks, which are StackQL queries that check for the existence or current configuration state of a resource
119-
- __*deployment*__ scripts, which are StackQL queries to create or update resoruces (or delete in the case of de-provisioning)
120-
- __*post-deployment*__ tests, which are StackQL queries to confirm that resources were deployed and have the desired state
129+
- **_pre-flight_** checks, which are StackQL queries that check for the existence or current configuration state of a resource
130+
- **_deployment_** scripts, which are StackQL queries to create or update resoruces (or delete in the case of de-provisioning)
131+
- **_post-deployment_** tests, which are StackQL queries to confirm that resources were deployed and have the desired state
121132
122133
This process is described here:
123134
@@ -278,16 +289,26 @@ Navigate to your `docs` directory and build the Sphinx documentation:
278289
```
279290
cd docs
280291
make html
281-
```
292+
```
293+
294+
## Code Linting
295+
296+
To maintain code quality and consistency, we use `ruff` as the linter for this project. `ruff` offers fast performance and a comprehensive set of linting rules suitable for `stackql-deploy`. You can run the lint check as follows:
297+
298+
```bash
299+
ruff check .
300+
```
301+
302+
Note: If you need to install ruff, you can do so with `pip install ruff`.
282303
283304
## Contributing
284305
285-
Contributions are welcome and encouraged.
306+
Contributions are welcome and encouraged.
286307
287308
## License
288309
289310
Distributed under the MIT License. See [`LICENSE`](https://github.com/stackql/stackql-deploy/blob/main/LICENSE) for more information.
290311
291312
## Contact
292313
293-
Get in touch with us via Twitter at [__@stackql__][twitter], email us at [__info@stackql.io__](info@stackql.io) or start a conversation using [__discussions__][discussions].
314+
Get in touch with us via Twitter at [**@stackql**][twitter], email us at [**info@stackql.io**](info@stackql.io) or start a conversation using [**discussions**][discussions].

pyproject.toml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
[tool.poetry.group.dev.dependencies]
2+
ruff = "^0.6.9"
3+
4+
# Tool-specific configurations
5+
6+
# Ruff configuration (linter)
7+
[tool.ruff]
8+
line-length = 120 # Maximum allowed line length
9+
exclude = [
10+
"docs",
11+
"examples",
12+
"images",
13+
"website",
14+
]
15+
16+
[tool.ruff.format]
17+
quote-style = "preserve" # Preserve existing quote style (single or double)
18+
19+
[tool.ruff.lint]
20+
select = ["E", "F", "W"] # Select specific linting rules (E: Errors, F: Pyflakes, W: Warnings)
21+
ignore = [
22+
"F405", # Ignore 'import *' warnings
23+
]
24+
25+
[tool.ruff.lint.isort]
26+
force-single-line = true # Force single-line imports for better readability
27+
28+
# Black configuration (code formatter)
29+
[tool.black]
30+
line-length = 120 # Same line length limit as Ruff for consistency
31+
target-version = ['py38'] # Target Python version for formatting
32+
33+
# Flake8 configuration (for additional linting, if needed)
34+
[tool.flake8]
35+
max-line-length = 120 # Align with Ruff's line length setting
36+
ignore = [
37+
"E501", # Ignore long line warnings
38+
]

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
'stackql_deploy': [
2424
'templates/**/*.template', # Include template files recursively
2525
],
26-
},
26+
},
2727
include_package_data=True,
2828
install_requires=[
29-
'click',
29+
'click',
3030
'python-dotenv',
3131
'jinja2',
3232
'pystackql>=3.6.1',

stackql_deploy/cli.py

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
def print_unicode_box(message):
1919
border_color = '\033[93m' # Yellow color
2020
reset_color = '\033[0m'
21-
21+
2222
lines = message.split('\n')
2323
max_length = max(len(line) for line in lines)
2424
top_border = border_color + '┌' + '─' * (max_length + 2) + '┐' + reset_color
2525
bottom_border = border_color + '└' + '─' * (max_length + 2) + '┘' + reset_color
26-
26+
2727
click.echo(top_border)
2828
for line in lines:
2929
click.echo(border_color + '│ ' + line.ljust(max_length) + ' │' + reset_color)
@@ -88,10 +88,21 @@ def add_common_options(command):
8888
common_options = [
8989
click.option('--log-level', default='INFO', help='set the logging level.'),
9090
click.option('--env-file', default='.env', help='environment variables file.'),
91-
click.option('-e', '--env', multiple=True, callback=parse_env_var, help='set additional environment variables.'),
91+
click.option(
92+
'-e',
93+
'--env',
94+
multiple=True,
95+
callback=parse_env_var,
96+
help='set additional environment variables.'
97+
),
9298
click.option('--dry-run', is_flag=True, help='perform a dry run of the operation.'),
9399
click.option('--show-queries', is_flag=True, help='show queries run in the output logs.'),
94-
click.option('--on-failure', type=click.Choice(['rollback', 'ignore', 'error']), default='error', help='action on failure.')
100+
click.option(
101+
"--on-failure",
102+
type=click.Choice(["rollback", "ignore", "error"]),
103+
default="error",
104+
help="action on failure.",
105+
)
95106
]
96107
for option in common_options:
97108
command = option(command)
@@ -240,7 +251,7 @@ def info(ctx):
240251
)
241252

242253
click.echo(click.style("stackql-deploy CLI", fg="green", bold=True))
243-
click.echo(f" Version: {deploy_version}\n")
254+
click.echo(f" Version: {deploy_version}\n")
244255

245256
click.echo(click.style("StackQL Library", fg="green", bold=True))
246257
click.echo(f" Version: {stackql.version}")
@@ -270,7 +281,7 @@ def shell(ctx):
270281
custom_registry=ctx.obj.get('custom_registry'),
271282
download_dir=ctx.obj.get('download_dir')
272283
)
273-
284+
274285
# Find the stackql binary path
275286
stackql_binary_path = find_stackql_binary(stackql.bin_path, ctx.obj.get('download_dir'))
276287

@@ -280,7 +291,7 @@ def shell(ctx):
280291
sys.exit(1)
281292

282293
click.echo(f"Launching stackql shell from: {stackql_binary_path}")
283-
294+
284295
# Launch the stackql shell as a subprocess
285296
try:
286297
subprocess.run([stackql_binary_path, "shell", "--colorscheme", "null"], check=True)
@@ -297,7 +308,7 @@ def shell(ctx):
297308
@click.pass_context
298309
def upgrade(ctx):
299310
"""Upgrade the pystackql package and stackql binary to the latest version."""
300-
311+
301312
stackql = get_stackql_instance()
302313
orig_pkg_version = stackql.package_version
303314
orig_stackql_version = stackql.version
@@ -306,7 +317,7 @@ def upgrade(ctx):
306317
click.echo("upgrading pystackql package...")
307318
try:
308319
# Run the pip install command to upgrade pystackql
309-
result = subprocess.run(
320+
subprocess.run(
310321
[sys.executable, "-m", "pip", "install", "--upgrade", "--quiet", "pystackql"],
311322
check=True,
312323
stdout=subprocess.PIPE,
@@ -341,18 +352,22 @@ def create_project_structure(stack_name, provider=None):
341352
base_path = os.path.join(os.getcwd(), stack_name)
342353
if os.path.exists(base_path):
343354
raise click.ClickException(f"directory '{stack_name}' already exists.")
344-
355+
345356
directories = ['resources']
346357
for directory in directories:
347358
os.makedirs(os.path.join(base_path, directory), exist_ok=True)
348-
359+
349360
# Check if provider is supported
350361
if provider is None:
351362
logger.debug(f"provider not supplied, defaulting to `{DEFAULT_PROVIDER}`")
352363
provider = DEFAULT_PROVIDER
353364
elif provider not in SUPPORTED_PROVIDERS:
354365
provider = DEFAULT_PROVIDER
355-
message = f"provider '{provider}' is not supported for `init`, supported providers are: {', '.join(SUPPORTED_PROVIDERS)}, defaulting to `{DEFAULT_PROVIDER}`"
366+
message = (
367+
f"provider '{provider}' is not supported for `init`, "
368+
f"supported providers are: {', '.join(SUPPORTED_PROVIDERS)}, "
369+
f"defaulting to `{DEFAULT_PROVIDER}`"
370+
)
356371
click.secho(message, fg='yellow', err=False)
357372

358373
# set template files
@@ -373,7 +388,7 @@ def create_project_structure(stack_name, provider=None):
373388
'README.md.template': os.path.join(base_path, 'README.md'),
374389
f'resources/{sample_res_name}.iql.template': os.path.join(base_path,'resources', f'{sample_res_name}.iql'),
375390
}
376-
391+
377392
for template_name, output_name in template_files.items():
378393
logger.debug(f"template name: {template_name}")
379394
logger.debug(f"template output name: {output_name}")
@@ -384,7 +399,11 @@ def create_project_structure(stack_name, provider=None):
384399

385400
@cli.command()
386401
@click.argument('stack_name')
387-
@click.option('--provider', default=None, help='[OPTIONAL] specify a provider to start your project, supported values: aws, azure, google')
402+
@click.option(
403+
"--provider",
404+
default=None,
405+
help="[OPTIONAL] specify a provider to start your project, supported values: aws, azure, google",
406+
)
388407
def init(stack_name, provider):
389408
"""Initialize a new stackql-deploy project structure."""
390409
setup_logger("init", locals())

0 commit comments

Comments
 (0)