cfn-check 0.1.1__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cfn-check might be problematic. Click here for more details.

cfn_check/__init__.py CHANGED
@@ -1,2 +1,2 @@
1
- from .rules.rules import Rules as Rules
1
+ from .collection.collection import Collection as Collection
2
2
  from .rules.rule import Rule as Rule
@@ -1,9 +1,9 @@
1
- from cfn_check.rules.rules import Rules
1
+ from cfn_check.collection.collection import Collection
2
2
  from cfn_check.validation.validator import Validator
3
3
 
4
4
 
5
5
  def bind(
6
- rule_set: Rules,
6
+ rule_set: Collection,
7
7
  validation: Validator
8
8
  ):
9
9
  validation.func = validation.func.__get__(rule_set, rule_set.__class__)
@@ -1,6 +1,7 @@
1
1
 
2
2
  import asyncio
3
3
  import os
4
+ import pathlib
4
5
  import yaml
5
6
  from cfn_check.loader.loader import (
6
7
  Loader,
@@ -9,23 +10,62 @@ from cfn_check.loader.loader import (
9
10
  )
10
11
  from cfn_check.shared.types import YamlObject, Data
11
12
 
12
- def open_template(path: str) -> YamlObject | Exception:
13
+ def open_template(path: str) -> YamlObject | None:
14
+
15
+ if os.path.exists(path) is False:
16
+ return None
17
+
13
18
  try:
14
19
  with open(path, 'r') as f:
15
20
  return yaml.load(f, Loader=Loader)
16
- except (Exception, ) as e:
21
+ except Exception as e:
17
22
  raise e
18
23
 
19
24
  def is_file(path: str) -> bool:
20
25
  return os.path.isdir(path) is False
21
26
 
22
27
 
28
+ async def path_exists(path: str, loop: asyncio.AbstractEventLoop):
29
+ return await loop.run_in_executor(
30
+ None,
31
+ os.path.exists,
32
+ path,
33
+ )
34
+
35
+ async def convert_to_cwd(loop: asyncio.AbstractEventLoop):
36
+ return await loop.run_in_executor(
37
+ None,
38
+ os.getcwd,
39
+ )
40
+
41
+ async def localize_path(path: str, loop: asyncio.AbstractEventLoop):
42
+ localized = path.replace('~/', '')
43
+
44
+ home_directory = await loop.run_in_executor(
45
+ None,
46
+ pathlib.Path.home,
47
+ )
48
+
49
+ return await loop.run_in_executor(
50
+ None,
51
+ os.path.join,
52
+ home_directory,
53
+ localized,
54
+ )
55
+
23
56
  async def load_templates(
24
57
  path: str,
25
58
  tags: list[str],
26
59
  file_pattern: str | None = None,
27
60
  ):
61
+
28
62
  loop = asyncio.get_event_loop()
63
+
64
+ if path == '.':
65
+ path = await convert_to_cwd(loop)
66
+
67
+ elif path.startswith('~/'):
68
+ path = await localize_path(path, loop)
29
69
 
30
70
  if await loop.run_in_executor(
31
71
  None,
@@ -36,6 +76,8 @@ async def load_templates(
36
76
  path,
37
77
  ]
38
78
 
79
+ assert await path_exists(path) is True, f'❌ Template at {path} does not exist'
80
+
39
81
  elif file_pattern:
40
82
 
41
83
  template_filepaths = await loop.run_in_executor(
@@ -65,4 +107,10 @@ async def load_templates(
65
107
  ) for template_path in template_filepaths
66
108
  ])
67
109
 
110
+ found_templates = [
111
+ template for template in templates if template is not None
112
+ ]
113
+
114
+ assert len(found_templates) > 0, "❌ Could not open any templates"
115
+
68
116
  return templates
cfn_check/cli/validate.py CHANGED
@@ -7,7 +7,7 @@ from cfn_check.cli.utils.attributes import bind
7
7
  from cfn_check.cli.utils.files import load_templates
8
8
  from cfn_check.evaluation.validate import run_validations
9
9
  from cfn_check.logging.models import InfoLog
10
- from cfn_check.rules.rules import Rules
10
+ from cfn_check.collection.collection import Collection
11
11
  from cfn_check.validation.validator import Validator
12
12
 
13
13
 
@@ -15,7 +15,7 @@ from cfn_check.validation.validator import Validator
15
15
  async def validate(
16
16
  path: str,
17
17
  file_pattern: str | None = None,
18
- rules: ImportType[Rules] = None,
18
+ rules: ImportType[Collection] = None,
19
19
  tags: list[str] = [
20
20
  'Ref',
21
21
  'Sub',
@@ -38,7 +38,7 @@ async def validate(
38
38
  '''
39
39
  Validate Cloud Foundation
40
40
 
41
- @param rules Path to a file containing Rules
41
+ @param rules Path to a file containing Collections
42
42
  @param file_pattern A string pattern used to find template files
43
43
  @param tags List of CloudFormation intrinsic function tags
44
44
  @param log_level The log level to use
File without changes
@@ -0,0 +1,2 @@
1
+ class Collection:
2
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cfn-check
3
- Version: 0.1.1
3
+ Version: 0.2.1
4
4
  Summary: Validate Cloud Formation
5
5
  Author-email: Ada Lundhe <adalundhe@lundhe.audio>
6
6
  License: MIT License
@@ -39,7 +39,7 @@ Requires-Dist: hyperlight-cocoa
39
39
  Requires-Dist: async-logging
40
40
  Dynamic: license-file
41
41
 
42
- # <b>CFN Check</b>
42
+ # <b>CFN-Check</b>
43
43
  <b>A tool for checking CloudFormation</b>
44
44
 
45
45
  [![PyPI version](https://img.shields.io/pypi/v/cfn-check?color=blue)](https://pypi.org/project/cfn-check/)
@@ -48,16 +48,16 @@ Dynamic: license-file
48
48
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/cfn-check?color=red)](https://pypi.org/project/cfn-check/)
49
49
 
50
50
 
51
- | Package | Cocoa |
51
+ | Package | cfn-check |
52
52
  | ----------- | ----------- |
53
- | Version | 0.1.0 |
53
+ | Version | 0.2.0 |
54
54
  | Download | https://pypi.org/project/cfn-check/ |
55
55
  | Source | https://github.com/adalundhe/cfn-check |
56
56
  | Keywords | cloud-formation, testing, aws, cli |
57
57
 
58
58
 
59
59
  CFN-Check is a small, fast, friendly tool for validating AWS CloudFormation YAML templates. It is code-driven, with
60
- rules written as simple, `Rule` decorator wrapped python class methods for `Rules`-inheriting classes.
60
+ rules written as simple, `Rule` decorator wrapped python class methods for `Collection`-inheriting classes.
61
61
 
62
62
  <br/>
63
63
 
@@ -88,7 +88,7 @@ Cloud Formation easy while offering both CLI and Python API interfaces.
88
88
 
89
89
  - `Python 3.12`
90
90
  - Any number of valid CloudFormation templates or a path to said templates.
91
- - A `.py` file containing at least one `Rules` class with at least one valid `@Rule()` decorated method
91
+ - A `.py` file containing at least one `Collection` class with at least one valid `@Rule()` decorated method
92
92
 
93
93
  To get started (we recommend using `uv`), run:
94
94
 
@@ -106,10 +106,10 @@ Next open the `rules.py` file and create a basic Python class
106
106
  as below.
107
107
 
108
108
  ```python
109
- from cfn_check import Rules, Rule
109
+ from cfn_check import Collection, Rule
110
110
 
111
111
 
112
- class ValidateResourceType(Rules):
112
+ class ValidateResourceType(Collection):
113
113
 
114
114
  @Rule(
115
115
  "Resources::*::Type",
@@ -241,7 +241,7 @@ cfn-lint validate -r rules.py template.yaml
241
241
  which outputs:
242
242
 
243
243
  ```
244
- 2025-09-17T01:46:41.542078+00:00 - INFO - 19783474 - /Users/adalundhe/Documents/Duckbill/cfn-check/cfn_check/cli/validate.py:validate.80 - ✅ 1 validations met for 1 templates
244
+ 2025-09-17T01:46:41.542078+00:00 - INFO - 19783474 - /Users/adalundhe/Documents/adalundhe/cfn-check/cfn_check/cli/validate.py:validate.80 - ✅ 1 validations met for 1 templates
245
245
  ```
246
246
 
247
247
  Congrats! You've just made the cloud a bit better place!
@@ -1,10 +1,12 @@
1
- cfn_check/__init__.py,sha256=k1-xUfaN07znTID-I4uJcP3l1cWG3Fr-hPFoB5NVKHk,76
1
+ cfn_check/__init__.py,sha256=ccUo2YxBmuEmak1M5o-8J0ECLXNkDDUsLJ4mkm31GvU,96
2
2
  cfn_check/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  cfn_check/cli/root.py,sha256=dHq9zzXyj-Wrj-fzirtFjptShzWbBGsO3n9tspm-pec,1688
4
- cfn_check/cli/validate.py,sha256=qUQ-4BFZAfqCh2lc12dkR6EwimXmRJCfw_0cLvOzkK8,1987
4
+ cfn_check/cli/validate.py,sha256=e20Hyfs3GJSrBbMRPt8dy3L0yjVnYo36ol_zOVhZco8,2013
5
5
  cfn_check/cli/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- cfn_check/cli/utils/attributes.py,sha256=zKOZhyWYsU1qcBUqQg8ppbHqrnwPNEcj2FI0eP29gzY,319
7
- cfn_check/cli/utils/files.py,sha256=W2lf42qAlTOJ-YJeBWsK99FjnsxZtmit241cLyURg2A,1448
6
+ cfn_check/cli/utils/attributes.py,sha256=iIUIgl6cT5XEUOW7D54-xxmMpTis84ySQY1b9osB47E,339
7
+ cfn_check/cli/utils/files.py,sha256=pkN-3jqI2cwiCBhnKYmaoEPqFw_qypOhKlLk-SvINFw,2557
8
+ cfn_check/collection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ cfn_check/collection/collection.py,sha256=wNxahoOqQge3C56blz5VtOq6lX5MZ9F2JjQIyZ3_SxU,27
8
10
  cfn_check/evaluation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
11
  cfn_check/evaluation/check.py,sha256=5GgoZY0YfyOeOP92VJVH4Y3AYB7jUGjxwsr0qsbVGeo,414
10
12
  cfn_check/evaluation/errors.py,sha256=yPJdtRYo67le4yMC9sYqcboCnkqKsJ3KPbSPFY2-Pi8,773
@@ -16,15 +18,14 @@ cfn_check/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
16
18
  cfn_check/logging/models.py,sha256=-tBaK6p8mJ0cO8h2keEJ-VmtFX_VW4XzwAw2PtqbkF0,490
17
19
  cfn_check/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
20
  cfn_check/rules/rule.py,sha256=r6-eKCUdPaNIena2NDv3J_QlcWes1KLObI9ukRZZz1o,500
19
- cfn_check/rules/rules.py,sha256=d7VvF6nlXER1puY9lEbQjFQv7RJMmD-wF4RoDCm8mQ0,22
20
21
  cfn_check/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
22
  cfn_check/shared/types.py,sha256=-om3DyZsjK_tJd-I8SITkoE55W0nB2WA3LOc87Cs7xI,414
22
23
  cfn_check/validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
24
  cfn_check/validation/validator.py,sha256=FGPeb8Uc8lvX3Y5rs-fxeJKIOqzUXwXh_gCFcy6d3b0,1182
24
- cfn_check-0.1.1.dist-info/licenses/LICENSE,sha256=EbCpGNzOkyQ53ig7J2Iwgmy4Og0dgHe8COo3WylhIKk,1069
25
- example/rules.py,sha256=gEAX52iK76XBdfiilqfqnxh6j8rACp7v7dwbb_EQ-1o,359
26
- cfn_check-0.1.1.dist-info/METADATA,sha256=26wu7hNXHtzg6hAZer8_lNcNFRM9mJ_R2Ji1JkW-jd4,8447
27
- cfn_check-0.1.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
28
- cfn_check-0.1.1.dist-info/entry_points.txt,sha256=B4lCHoDHmwisABxKgRLShwqqFv7QwwDAFXoAChOnkwg,53
29
- cfn_check-0.1.1.dist-info/top_level.txt,sha256=hUn9Ya50yY1fpgWxEhG5iMgfMDDVX7qWQnM1xrgZnhM,18
30
- cfn_check-0.1.1.dist-info/RECORD,,
25
+ cfn_check-0.2.1.dist-info/licenses/LICENSE,sha256=EbCpGNzOkyQ53ig7J2Iwgmy4Og0dgHe8COo3WylhIKk,1069
26
+ example/rules.py,sha256=XVsOkY5gxEier6oVyMVwuJ3ftwbv987udEkg2qZe_Zs,369
27
+ cfn_check-0.2.1.dist-info/METADATA,sha256=c7EmyUA8rmPum59hiaXuyULhPWlrQVbwxssUl3Obgt0,8472
28
+ cfn_check-0.2.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
29
+ cfn_check-0.2.1.dist-info/entry_points.txt,sha256=B4lCHoDHmwisABxKgRLShwqqFv7QwwDAFXoAChOnkwg,53
30
+ cfn_check-0.2.1.dist-info/top_level.txt,sha256=hUn9Ya50yY1fpgWxEhG5iMgfMDDVX7qWQnM1xrgZnhM,18
31
+ cfn_check-0.2.1.dist-info/RECORD,,
example/rules.py CHANGED
@@ -1,7 +1,7 @@
1
- from cfn_check import Rules, Rule
1
+ from cfn_check import Collection, Rule
2
2
 
3
3
 
4
- class ValidateResourceTypes(Rules):
4
+ class ValidateResourceTypes(Collection):
5
5
 
6
6
  @Rule(
7
7
  "Resources::*::Type",
cfn_check/rules/rules.py DELETED
@@ -1,2 +0,0 @@
1
- class Rules:
2
- pass