cfengine 0.12.2__tar.gz → 0.13.0__tar.gz
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.
- {cfengine-0.12.2 → cfengine-0.13.0}/.github/workflows/test.yml +4 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/.gitignore +1 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/HACKING.md +47 -51
- cfengine-0.13.0/Makefile +22 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/PKG-INFO +3 -3
- {cfengine-0.12.2 → cfengine-0.13.0}/README.md +2 -2
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine.egg-info/PKG-INFO +3 -3
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine.egg-info/SOURCES.txt +36 -6
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/commands.py +5 -9
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/docs.py +59 -25
- cfengine-0.13.0/src/cfengine_cli/format.py +407 -0
- cfengine-0.13.0/src/cfengine_cli/lint.py +885 -0
- cfengine-0.13.0/tests/README.md +58 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/format/002_basics.expected.cf +5 -1
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/format/002_basics.input.cf +3 -0
- cfengine-0.13.0/tests/format/005_bundle_comments.expected.cf +49 -0
- cfengine-0.13.0/tests/format/005_bundle_comments.input.cf +47 -0
- cfengine-0.13.0/tests/format/006_remove_empty_comments.expected.cf +24 -0
- cfengine-0.13.0/tests/format/006_remove_empty_comments.input.cf +30 -0
- cfengine-0.13.0/tests/format/007_class_guarded_empty_lines.expected.cf +11 -0
- cfengine-0.13.0/tests/format/007_class_guarded_empty_lines.input.cf +10 -0
- cfengine-0.13.0/tests/lint/001_hello_world.cf +5 -0
- cfengine-0.13.0/tests/lint/002_ifvarclass.expected.txt +7 -0
- cfengine-0.13.0/tests/lint/002_ifvarclass.x.cf +6 -0
- cfengine-0.13.0/tests/lint/003_deprecated_promise_type.cf +5 -0
- cfengine-0.13.0/tests/lint/003_deprecated_promise_type.expected.txt +7 -0
- cfengine-0.13.0/tests/lint/003_deprecated_promise_type.x.cf +5 -0
- cfengine-0.13.0/tests/lint/004_bundle_name_lowercase.cf +5 -0
- cfengine-0.13.0/tests/lint/004_bundle_name_lowercase.expected.txt +6 -0
- cfengine-0.13.0/tests/lint/004_bundle_name_lowercase.x.cf +5 -0
- cfengine-0.13.0/tests/lint/005_bundle_type.cf +5 -0
- cfengine-0.13.0/tests/lint/005_bundle_type.expected.txt +6 -0
- cfengine-0.13.0/tests/lint/005_bundle_type.x.cf +5 -0
- cfengine-0.13.0/tests/lint/006_syntax_error.cf +5 -0
- cfengine-0.13.0/tests/lint/006_syntax_error.expected.txt +7 -0
- cfengine-0.13.0/tests/lint/006_syntax_error.x.cf +5 -0
- cfengine-0.13.0/tests/lint/007_empty_file.expected.txt +3 -0
- cfengine-0.13.0/tests/lint/008_namespace.cf +16 -0
- cfengine-0.13.0/tests/lint/008_namespace.expected.txt +7 -0
- cfengine-0.13.0/tests/lint/008_namespace.x.cf +16 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/run-format-tests.sh +3 -4
- cfengine-0.13.0/tests/run-lint-tests.sh +46 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/run-shell-tests.sh +2 -1
- cfengine-0.13.0/tests/unit/__init__.py +0 -0
- cfengine-0.13.0/tests/unit/test_format.py +70 -0
- cfengine-0.12.2/src/cfengine_cli/format.py +0 -242
- cfengine-0.12.2/src/cfengine_cli/lint.py +0 -399
- {cfengine-0.12.2 → cfengine-0.13.0}/.github/dependabot.yml +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/.github/workflows/format.yml +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/.github/workflows/lint.yml +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/.github/workflows/pypi-publish.yml +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/.python-version +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/LICENSE +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/ci/01-install.sh +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/ci/02-safe-tests.sh +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/ci/03-unsafe-tests.sh +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/pyproject.toml +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/setup.cfg +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine.egg-info/dependency_links.txt +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine.egg-info/entry_points.txt +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine.egg-info/requires.txt +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine.egg-info/top_level.txt +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/__init__.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/__main__.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/deptool-README.md +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/deptool.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/dev.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/main.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/masterfiles/__init__.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/masterfiles/analyze.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/masterfiles/check_download_matches_git.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/masterfiles/download.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/masterfiles/generate_git_tags.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/masterfiles/generate_release_information.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/masterfiles/generate_vcf_download.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/masterfiles/generate_vcf_git_checkout.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/paths.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/policy_language.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/profile.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/shell.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/utils.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/src/cfengine_cli/version.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/format/001_hello_world.expected.cf +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/format/001_hello_world.input.cf +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/format/003_wrapping.expected.cf +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/format/003_wrapping.input.cf +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/format/004_comments.expected.cf +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/format/004_comments.input.cf +0 -0
- /cfengine-0.12.2/tests/__init__.py → /cfengine-0.13.0/tests/lint/007_empty_file.x.cf +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/shell/001-help.sh +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/shell/002-version.sh +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/tests/shell/003-format.sh +0 -0
- {cfengine-0.12.2/tests → cfengine-0.13.0/tests/unit}/test_deps.py +0 -0
- {cfengine-0.12.2/tests → cfengine-0.13.0/tests/unit}/test_paths.py +0 -0
- {cfengine-0.12.2/tests → cfengine-0.13.0/tests/unit}/test_utils.py +0 -0
- {cfengine-0.12.2/tests → cfengine-0.13.0/tests/unit}/test_version.py +0 -0
- {cfengine-0.12.2 → cfengine-0.13.0}/uv.lock +0 -0
|
@@ -4,6 +4,53 @@ This document aims to have relevant information for people contributing to and m
|
|
|
4
4
|
It is not necessary for users of the tool to know about these processes.
|
|
5
5
|
For general user information, see the [README](./README.md).
|
|
6
6
|
|
|
7
|
+
## Code formatting
|
|
8
|
+
|
|
9
|
+
We use automated code formatters to ensure consistent code style / indentation.
|
|
10
|
+
Please format Python code with [black](https://pypi.org/project/black/), and YAML and markdown files with [Prettier](https://prettier.io/).
|
|
11
|
+
For simplicity's sake, we don't have a custom configuration, we use the tool's defaults.
|
|
12
|
+
|
|
13
|
+
If your editor does not do this automatically, you can run these tools from the command line:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
make format
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Installing from source:
|
|
20
|
+
|
|
21
|
+
For developers working on CFEngine CLI, it is recommended to install an editable version of the tool:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
make install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Some of the tests require that you have the CLI installed (they run `cfengine` commands).
|
|
28
|
+
|
|
29
|
+
## Running commands without installing
|
|
30
|
+
|
|
31
|
+
You can also run commands without installing, using `uv`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv run cfengine format
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Running tests
|
|
38
|
+
|
|
39
|
+
Use the makefile command to run all linting and tests:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
make check
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Running individual test suites:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uv run pytest
|
|
49
|
+
bash tests/run-lint-tests.sh
|
|
50
|
+
bash tests/run-format-tests.sh
|
|
51
|
+
bash tests/run-shell-tests.sh
|
|
52
|
+
```
|
|
53
|
+
|
|
7
54
|
## Releasing new versions
|
|
8
55
|
|
|
9
56
|
Releases are [automated using a GH Action](https://github.com/cfengine/cfengine-cli/blob/main/.github/workflows/pypi-publish.yml)
|
|
@@ -79,62 +126,11 @@ Copy the token and paste it into the GitHub Secret named `PYPI_PASSWORD`.
|
|
|
79
126
|
`PYPI_USERNAME` should be there already, you don't have to edit it, it is simply `__token__`.
|
|
80
127
|
Don't store the token anywhere else - we generate new tokens if necessary.
|
|
81
128
|
|
|
82
|
-
## Code formatting
|
|
83
|
-
|
|
84
|
-
We use automated code formatters to ensure consistent code style / indentation.
|
|
85
|
-
Please format Python code with [black](https://pypi.org/project/black/), and YAML and markdown files with [Prettier](https://prettier.io/).
|
|
86
|
-
For simplicity's sake, we don't have a custom configuration, we use the tool's defaults.
|
|
87
|
-
|
|
88
|
-
If your editor does not do this automatically, you can run these tools from the command line:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
black . && prettier . --write
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Running commands during development
|
|
95
|
-
|
|
96
|
-
This project uses `uv`.
|
|
97
|
-
This makes it easy to run commands without installing the project, for example:
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
uv run cfengine format
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Installing from source:
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
git fetch --all --tags
|
|
107
|
-
pip3 install .
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Running tests
|
|
111
|
-
|
|
112
|
-
Unit tests:
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
py.test
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Shell tests (requires installing first):
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
cat tests/shell/*.sh | bash
|
|
122
|
-
```
|
|
123
|
-
|
|
124
129
|
## Not implemented yet / TODOs
|
|
125
130
|
|
|
126
131
|
- `cfengine run`
|
|
127
132
|
- The command could automatically detect that you have CFEngine installed on a remote hub, and run it there instead (using `cf-remote`).
|
|
128
133
|
- Handle when `cf-agent` is not installed, help users install.
|
|
129
134
|
- Prompt / help users do what they meant (i.e. build and deploy and run).
|
|
130
|
-
- `cfengine format`
|
|
131
|
-
- Automatically break up and indent method calls, function calls, and nested function calls.
|
|
132
|
-
- Smarter placement of comments based on context.
|
|
133
|
-
- The command should be able to take a filename as an argument, and also operate using stdin and stdout.
|
|
134
|
-
(Receive file content on stdin, file type using command line arg, output formatted file to stdout).
|
|
135
|
-
- We can add a shortcut, `cfengine fmt`, since that matches other tools, like `deno`.
|
|
136
|
-
- `cfengine lint`
|
|
137
|
-
- The command should be able to take a filename as an argument, and also take file content from stdin.
|
|
138
|
-
- It would be nice if we refactored `validate_config()` in `cfbs` so it would take a simple dictionary (JSON) instead of a special CFBSConfig object.
|
|
139
135
|
- Missing commands:
|
|
140
136
|
- `cfengine install` - Install CFEngine packages / binaries (Wrapping `cf-remote install`).
|
cfengine-0.13.0/Makefile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.PHONY: default format lint install check
|
|
2
|
+
|
|
3
|
+
default: check
|
|
4
|
+
|
|
5
|
+
format:
|
|
6
|
+
uv tool run black .
|
|
7
|
+
prettier . --write
|
|
8
|
+
|
|
9
|
+
lint:
|
|
10
|
+
uv tool run black --check .
|
|
11
|
+
uv tool run flake8 src/ --ignore=E203,W503,E722,E731 --max-complexity=100 --max-line-length=160
|
|
12
|
+
uv tool run pyflakes src/
|
|
13
|
+
uv tool run pyright src/
|
|
14
|
+
|
|
15
|
+
install:
|
|
16
|
+
pipx install --force --editable .
|
|
17
|
+
|
|
18
|
+
check: format lint install
|
|
19
|
+
uv run pytest
|
|
20
|
+
bash tests/run-lint-tests.sh
|
|
21
|
+
bash tests/run-format-tests.sh
|
|
22
|
+
bash tests/run-shell-tests.sh
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cfengine
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Summary: Human-oriented CLI for interacting with CFEngine tools
|
|
5
5
|
License: GNU GENERAL PUBLIC LICENSE
|
|
6
6
|
Version 3, 29 June 2007
|
|
@@ -762,8 +762,8 @@ When it finds a mistake, it points out where the problem is like this;
|
|
|
762
762
|
ifvarclass => "cfengine";
|
|
763
763
|
^--------^
|
|
764
764
|
Deprecation: Use 'if' instead of 'ifvarclass' at main.cf:5:7
|
|
765
|
-
FAIL: main.cf (1
|
|
766
|
-
Failure, 1
|
|
765
|
+
FAIL: main.cf (1 error)
|
|
766
|
+
Failure, 1 error in total.
|
|
767
767
|
```
|
|
768
768
|
|
|
769
769
|
Note that since we use a different parser than `cf-agent` / `cf-promises`, they are not 100% in sync.
|
|
@@ -60,8 +60,8 @@ When it finds a mistake, it points out where the problem is like this;
|
|
|
60
60
|
ifvarclass => "cfengine";
|
|
61
61
|
^--------^
|
|
62
62
|
Deprecation: Use 'if' instead of 'ifvarclass' at main.cf:5:7
|
|
63
|
-
FAIL: main.cf (1
|
|
64
|
-
Failure, 1
|
|
63
|
+
FAIL: main.cf (1 error)
|
|
64
|
+
Failure, 1 error in total.
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
Note that since we use a different parser than `cf-agent` / `cf-promises`, they are not 100% in sync.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cfengine
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Summary: Human-oriented CLI for interacting with CFEngine tools
|
|
5
5
|
License: GNU GENERAL PUBLIC LICENSE
|
|
6
6
|
Version 3, 29 June 2007
|
|
@@ -762,8 +762,8 @@ When it finds a mistake, it points out where the problem is like this;
|
|
|
762
762
|
ifvarclass => "cfengine";
|
|
763
763
|
^--------^
|
|
764
764
|
Deprecation: Use 'if' instead of 'ifvarclass' at main.cf:5:7
|
|
765
|
-
FAIL: main.cf (1
|
|
766
|
-
Failure, 1
|
|
765
|
+
FAIL: main.cf (1 error)
|
|
766
|
+
Failure, 1 error in total.
|
|
767
767
|
```
|
|
768
768
|
|
|
769
769
|
Note that since we use a different parser than `cf-agent` / `cf-promises`, they are not 100% in sync.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
.python-version
|
|
3
3
|
HACKING.md
|
|
4
4
|
LICENSE
|
|
5
|
+
Makefile
|
|
5
6
|
README.md
|
|
6
7
|
pyproject.toml
|
|
7
8
|
uv.lock
|
|
@@ -43,13 +44,10 @@ src/cfengine_cli/masterfiles/generate_git_tags.py
|
|
|
43
44
|
src/cfengine_cli/masterfiles/generate_release_information.py
|
|
44
45
|
src/cfengine_cli/masterfiles/generate_vcf_download.py
|
|
45
46
|
src/cfengine_cli/masterfiles/generate_vcf_git_checkout.py
|
|
46
|
-
tests/
|
|
47
|
+
tests/README.md
|
|
47
48
|
tests/run-format-tests.sh
|
|
49
|
+
tests/run-lint-tests.sh
|
|
48
50
|
tests/run-shell-tests.sh
|
|
49
|
-
tests/test_deps.py
|
|
50
|
-
tests/test_paths.py
|
|
51
|
-
tests/test_utils.py
|
|
52
|
-
tests/test_version.py
|
|
53
51
|
tests/format/001_hello_world.expected.cf
|
|
54
52
|
tests/format/001_hello_world.input.cf
|
|
55
53
|
tests/format/002_basics.expected.cf
|
|
@@ -58,6 +56,38 @@ tests/format/003_wrapping.expected.cf
|
|
|
58
56
|
tests/format/003_wrapping.input.cf
|
|
59
57
|
tests/format/004_comments.expected.cf
|
|
60
58
|
tests/format/004_comments.input.cf
|
|
59
|
+
tests/format/005_bundle_comments.expected.cf
|
|
60
|
+
tests/format/005_bundle_comments.input.cf
|
|
61
|
+
tests/format/006_remove_empty_comments.expected.cf
|
|
62
|
+
tests/format/006_remove_empty_comments.input.cf
|
|
63
|
+
tests/format/007_class_guarded_empty_lines.expected.cf
|
|
64
|
+
tests/format/007_class_guarded_empty_lines.input.cf
|
|
65
|
+
tests/lint/001_hello_world.cf
|
|
66
|
+
tests/lint/002_ifvarclass.expected.txt
|
|
67
|
+
tests/lint/002_ifvarclass.x.cf
|
|
68
|
+
tests/lint/003_deprecated_promise_type.cf
|
|
69
|
+
tests/lint/003_deprecated_promise_type.expected.txt
|
|
70
|
+
tests/lint/003_deprecated_promise_type.x.cf
|
|
71
|
+
tests/lint/004_bundle_name_lowercase.cf
|
|
72
|
+
tests/lint/004_bundle_name_lowercase.expected.txt
|
|
73
|
+
tests/lint/004_bundle_name_lowercase.x.cf
|
|
74
|
+
tests/lint/005_bundle_type.cf
|
|
75
|
+
tests/lint/005_bundle_type.expected.txt
|
|
76
|
+
tests/lint/005_bundle_type.x.cf
|
|
77
|
+
tests/lint/006_syntax_error.cf
|
|
78
|
+
tests/lint/006_syntax_error.expected.txt
|
|
79
|
+
tests/lint/006_syntax_error.x.cf
|
|
80
|
+
tests/lint/007_empty_file.expected.txt
|
|
81
|
+
tests/lint/007_empty_file.x.cf
|
|
82
|
+
tests/lint/008_namespace.cf
|
|
83
|
+
tests/lint/008_namespace.expected.txt
|
|
84
|
+
tests/lint/008_namespace.x.cf
|
|
61
85
|
tests/shell/001-help.sh
|
|
62
86
|
tests/shell/002-version.sh
|
|
63
|
-
tests/shell/003-format.sh
|
|
87
|
+
tests/shell/003-format.sh
|
|
88
|
+
tests/unit/__init__.py
|
|
89
|
+
tests/unit/test_deps.py
|
|
90
|
+
tests/unit/test_format.py
|
|
91
|
+
tests/unit/test_paths.py
|
|
92
|
+
tests/unit/test_utils.py
|
|
93
|
+
tests/unit/test_version.py
|
|
@@ -4,7 +4,7 @@ import re
|
|
|
4
4
|
import json
|
|
5
5
|
from cfengine_cli.profile import profile_cfengine, generate_callstack
|
|
6
6
|
from cfengine_cli.dev import dispatch_dev_subcommand
|
|
7
|
-
from cfengine_cli.lint import
|
|
7
|
+
from cfengine_cli.lint import lint_args
|
|
8
8
|
from cfengine_cli.shell import user_command
|
|
9
9
|
from cfengine_cli.paths import bin
|
|
10
10
|
from cfengine_cli.version import cfengine_cli_version_string
|
|
@@ -96,20 +96,16 @@ def format(names, line_length) -> int:
|
|
|
96
96
|
|
|
97
97
|
def _lint(files, strict) -> int:
|
|
98
98
|
if not files:
|
|
99
|
-
return
|
|
100
|
-
|
|
101
|
-
errors = 0
|
|
102
|
-
|
|
103
|
-
for file in files:
|
|
104
|
-
errors += lint_single_arg(file, strict)
|
|
105
|
-
|
|
106
|
-
return errors
|
|
99
|
+
return lint_args(["."], strict)
|
|
100
|
+
return lint_args(files, strict)
|
|
107
101
|
|
|
108
102
|
|
|
109
103
|
def lint(files, strict) -> int:
|
|
110
104
|
errors = _lint(files, strict)
|
|
111
105
|
if errors == 0:
|
|
112
106
|
print("Success, no errors found.")
|
|
107
|
+
elif errors == 1:
|
|
108
|
+
print("Failure, 1 error in total.")
|
|
113
109
|
else:
|
|
114
110
|
print(f"Failure, {errors} errors in total.")
|
|
115
111
|
return errors
|
|
@@ -16,7 +16,8 @@ import markdown_it
|
|
|
16
16
|
from cfbs.pretty import pretty_file
|
|
17
17
|
from cfbs.utils import find
|
|
18
18
|
|
|
19
|
-
from cfengine_cli.
|
|
19
|
+
from cfengine_cli.format import format_policy_file
|
|
20
|
+
from cfengine_cli.lint import lint_args, lint_policy_file_snippet
|
|
20
21
|
from cfengine_cli.utils import UserError
|
|
21
22
|
|
|
22
23
|
IGNORED_DIRS = [".git"]
|
|
@@ -127,7 +128,7 @@ def fn_check_syntax(
|
|
|
127
128
|
first_line,
|
|
128
129
|
_last_line,
|
|
129
130
|
snippet_number,
|
|
130
|
-
prefix
|
|
131
|
+
prefix,
|
|
131
132
|
):
|
|
132
133
|
snippet_abs_path = os.path.abspath(snippet_path)
|
|
133
134
|
|
|
@@ -138,8 +139,13 @@ def fn_check_syntax(
|
|
|
138
139
|
|
|
139
140
|
match language:
|
|
140
141
|
case "cf":
|
|
141
|
-
r =
|
|
142
|
-
snippet_abs_path,
|
|
142
|
+
r = lint_policy_file_snippet(
|
|
143
|
+
snippet_abs_path,
|
|
144
|
+
origin_path,
|
|
145
|
+
first_line + 1,
|
|
146
|
+
snippet_number,
|
|
147
|
+
prefix,
|
|
148
|
+
strict=False,
|
|
143
149
|
)
|
|
144
150
|
if r != 0:
|
|
145
151
|
raise UserError(f"Error when checking '{origin_path}'")
|
|
@@ -189,6 +195,7 @@ def fn_replace(origin_path, snippet_path, _language, first_line, last_line, inde
|
|
|
189
195
|
|
|
190
196
|
|
|
191
197
|
def fn_autoformat(_origin_path, snippet_path, language, _first_line, _last_line):
|
|
198
|
+
assert language in ("cf", "json")
|
|
192
199
|
match language:
|
|
193
200
|
case "json":
|
|
194
201
|
try:
|
|
@@ -203,6 +210,9 @@ def fn_autoformat(_origin_path, snippet_path, language, _first_line, _last_line)
|
|
|
203
210
|
raise UserError(f"Couldn't open '{snippet_path}'")
|
|
204
211
|
except json.decoder.JSONDecodeError:
|
|
205
212
|
raise UserError(f"Invalid json in '{snippet_path}'")
|
|
213
|
+
case "cf":
|
|
214
|
+
# Note: Dead code - Not used for CFEngine policy yet
|
|
215
|
+
format_policy_file(snippet_path, 80)
|
|
206
216
|
|
|
207
217
|
|
|
208
218
|
def _translate_language(x):
|
|
@@ -241,10 +251,23 @@ def _process_markdown_code_blocks(
|
|
|
241
251
|
origin_paths = sorted(parsed_markdowns["files"].keys())
|
|
242
252
|
origin_paths_len = len(origin_paths)
|
|
243
253
|
|
|
254
|
+
if origin_paths_len == 0:
|
|
255
|
+
print("No markdown files found.")
|
|
256
|
+
return
|
|
257
|
+
|
|
258
|
+
if syntax_check:
|
|
259
|
+
# We currently only print the filenames during linting, not formatting
|
|
260
|
+
print(
|
|
261
|
+
f"Processing code blocks (snippets) inside {origin_paths_len} markdown files:"
|
|
262
|
+
)
|
|
244
263
|
for origin_paths_i, origin_path in enumerate(origin_paths):
|
|
245
264
|
percentage = int(100 * (origin_paths_i + 1) / origin_paths_len)
|
|
246
|
-
|
|
265
|
+
spaces = " " * (4 - len(str(percentage)))
|
|
266
|
+
prefix = f"[{origin_paths_i + 1}/{origin_paths_len}{spaces}({percentage}%)] "
|
|
247
267
|
offset = 0
|
|
268
|
+
if syntax_check and not parsed_markdowns["files"][origin_path]["code-blocks"]:
|
|
269
|
+
print(f"{prefix}SKIP: No code blocks in '{origin_path}'")
|
|
270
|
+
continue
|
|
248
271
|
for i, code_block in enumerate(
|
|
249
272
|
parsed_markdowns["files"][origin_path]["code-blocks"]
|
|
250
273
|
):
|
|
@@ -259,33 +282,44 @@ def _process_markdown_code_blocks(
|
|
|
259
282
|
snippet_path = f"{origin_path}.snippet-{snippet_number}.{language}"
|
|
260
283
|
|
|
261
284
|
flags = code_block["flags"]
|
|
285
|
+
first_line = code_block["first_line"]
|
|
286
|
+
last_line = code_block["last_line"]
|
|
262
287
|
if "noextract" in flags or "skip" in flags:
|
|
263
288
|
# code block was marked to be skipped
|
|
289
|
+
if syntax_check:
|
|
290
|
+
print(
|
|
291
|
+
f"{prefix}SKIP: Snippet {snippet_number} at '{origin_path}:{first_line}' ({language} {' '.join(flags)})"
|
|
292
|
+
)
|
|
264
293
|
continue
|
|
265
294
|
if extract:
|
|
266
295
|
fn_extract(
|
|
267
296
|
origin_path,
|
|
268
297
|
snippet_path,
|
|
269
298
|
language,
|
|
270
|
-
|
|
271
|
-
|
|
299
|
+
first_line,
|
|
300
|
+
last_line,
|
|
272
301
|
)
|
|
273
302
|
|
|
274
|
-
if syntax_check
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
origin_path
|
|
278
|
-
snippet_path,
|
|
279
|
-
language,
|
|
280
|
-
code_block["first_line"],
|
|
281
|
-
code_block["last_line"],
|
|
282
|
-
snippet_number,
|
|
283
|
-
prefix,
|
|
303
|
+
if syntax_check:
|
|
304
|
+
if "novalidate" in flags:
|
|
305
|
+
print(
|
|
306
|
+
f"{prefix}SKIP: Snippet {snippet_number} at '{origin_path}:{first_line}' ({language} {' '.join(flags)})"
|
|
284
307
|
)
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
308
|
+
else:
|
|
309
|
+
try:
|
|
310
|
+
fn_check_syntax(
|
|
311
|
+
origin_path,
|
|
312
|
+
snippet_path,
|
|
313
|
+
language,
|
|
314
|
+
first_line,
|
|
315
|
+
last_line,
|
|
316
|
+
snippet_number,
|
|
317
|
+
prefix,
|
|
318
|
+
)
|
|
319
|
+
except Exception as e:
|
|
320
|
+
if cleanup:
|
|
321
|
+
os.remove(snippet_path)
|
|
322
|
+
raise e
|
|
289
323
|
|
|
290
324
|
if output_check and "noexecute" not in flags:
|
|
291
325
|
fn_check_output()
|
|
@@ -295,8 +329,8 @@ def _process_markdown_code_blocks(
|
|
|
295
329
|
origin_path,
|
|
296
330
|
snippet_path,
|
|
297
331
|
language,
|
|
298
|
-
|
|
299
|
-
|
|
332
|
+
first_line,
|
|
333
|
+
last_line,
|
|
300
334
|
)
|
|
301
335
|
|
|
302
336
|
if replace and "noreplace" not in flags:
|
|
@@ -304,7 +338,7 @@ def _process_markdown_code_blocks(
|
|
|
304
338
|
origin_path,
|
|
305
339
|
snippet_path,
|
|
306
340
|
language,
|
|
307
|
-
|
|
341
|
+
first_line,
|
|
308
342
|
code_block["last_line"],
|
|
309
343
|
code_block["indent"],
|
|
310
344
|
)
|
|
@@ -409,7 +443,7 @@ def check_docs() -> int:
|
|
|
409
443
|
|
|
410
444
|
Run by the command:
|
|
411
445
|
cfengine dev lint-docs"""
|
|
412
|
-
r =
|
|
446
|
+
r = lint_args(["."], strict=False)
|
|
413
447
|
if r != 0:
|
|
414
448
|
return r
|
|
415
449
|
_process_markdown_code_blocks(
|