cfengine 0.12.2__tar.gz → 0.14.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.
Files changed (151) hide show
  1. cfengine-0.14.0/.github/workflows/make-check.yml +51 -0
  2. cfengine-0.14.0/.github/workflows/update-syntax-description.yml +69 -0
  3. {cfengine-0.12.2 → cfengine-0.14.0}/.gitignore +1 -0
  4. cfengine-0.14.0/.python-version +1 -0
  5. cfengine-0.14.0/CLAUDE.md +51 -0
  6. {cfengine-0.12.2 → cfengine-0.14.0}/HACKING.md +47 -51
  7. cfengine-0.14.0/Makefile +26 -0
  8. {cfengine-0.12.2 → cfengine-0.14.0}/PKG-INFO +4 -4
  9. {cfengine-0.12.2 → cfengine-0.14.0}/README.md +2 -2
  10. {cfengine-0.12.2 → cfengine-0.14.0}/pyproject.toml +4 -1
  11. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine.egg-info/PKG-INFO +4 -4
  12. cfengine-0.14.0/src/cfengine.egg-info/SOURCES.txt +140 -0
  13. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine.egg-info/requires.txt +1 -1
  14. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/commands.py +47 -31
  15. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/deptool.py +2 -2
  16. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/dev.py +18 -26
  17. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/docs.py +77 -47
  18. cfengine-0.14.0/src/cfengine_cli/format.py +901 -0
  19. cfengine-0.14.0/src/cfengine_cli/lint.py +1408 -0
  20. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/main.py +8 -5
  21. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/masterfiles/analyze.py +11 -17
  22. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/masterfiles/download.py +1 -1
  23. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/masterfiles/generate_release_information.py +53 -22
  24. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/profile.py +1 -1
  25. cfengine-0.14.0/src/cfengine_cli/syntax-description.json +10343 -0
  26. cfengine-0.14.0/src/cfengine_cli/syntax_tree.py +42 -0
  27. cfengine-0.14.0/tests/README.md +58 -0
  28. {cfengine-0.12.2 → cfengine-0.14.0}/tests/format/002_basics.expected.cf +13 -5
  29. {cfengine-0.12.2 → cfengine-0.14.0}/tests/format/002_basics.input.cf +10 -2
  30. {cfengine-0.12.2 → cfengine-0.14.0}/tests/format/003_wrapping.expected.cf +33 -7
  31. {cfengine-0.12.2 → cfengine-0.14.0}/tests/format/003_wrapping.input.cf +29 -3
  32. {cfengine-0.12.2 → cfengine-0.14.0}/tests/format/004_comments.expected.cf +20 -0
  33. {cfengine-0.12.2 → cfengine-0.14.0}/tests/format/004_comments.input.cf +18 -0
  34. cfengine-0.14.0/tests/format/005_bundle_comments.expected.cf +54 -0
  35. cfengine-0.14.0/tests/format/005_bundle_comments.input.cf +52 -0
  36. cfengine-0.14.0/tests/format/006_remove_empty_comments.expected.cf +24 -0
  37. cfengine-0.14.0/tests/format/006_remove_empty_comments.input.cf +30 -0
  38. cfengine-0.14.0/tests/format/007_class_guarded_empty_lines.expected.cf +9 -0
  39. cfengine-0.14.0/tests/format/007_class_guarded_empty_lines.input.cf +10 -0
  40. cfengine-0.14.0/tests/format/008_long_string.expected.cf +6 -0
  41. cfengine-0.14.0/tests/format/008_long_string.input.cf +5 -0
  42. cfengine-0.14.0/tests/format/009_single_line.expected.cf +58 -0
  43. cfengine-0.14.0/tests/format/009_single_line.input.cf +76 -0
  44. cfengine-0.14.0/tests/format/010_stakeholder.expected.cf +119 -0
  45. cfengine-0.14.0/tests/format/010_stakeholder.input.cf +99 -0
  46. cfengine-0.14.0/tests/format/011_macros.expected.cf +192 -0
  47. cfengine-0.14.0/tests/format/011_macros.input.cf +182 -0
  48. cfengine-0.14.0/tests/format/011_promises.expected.cf +516 -0
  49. cfengine-0.14.0/tests/format/011_promises.input.cf +409 -0
  50. cfengine-0.14.0/tests/lint/001_hello_world.cf +5 -0
  51. cfengine-0.14.0/tests/lint/002_ifvarclass.expected.txt +7 -0
  52. cfengine-0.14.0/tests/lint/002_ifvarclass.x.cf +6 -0
  53. cfengine-0.14.0/tests/lint/003_deprecated_promise_type.cf +5 -0
  54. cfengine-0.14.0/tests/lint/003_deprecated_promise_type.expected.txt +7 -0
  55. cfengine-0.14.0/tests/lint/003_deprecated_promise_type.x.cf +5 -0
  56. cfengine-0.14.0/tests/lint/004_bundle_name_lowercase.cf +5 -0
  57. cfengine-0.14.0/tests/lint/004_bundle_name_lowercase.expected.txt +6 -0
  58. cfengine-0.14.0/tests/lint/004_bundle_name_lowercase.x.cf +5 -0
  59. cfengine-0.14.0/tests/lint/005_bundle_type.cf +5 -0
  60. cfengine-0.14.0/tests/lint/005_bundle_type.expected.txt +6 -0
  61. cfengine-0.14.0/tests/lint/005_bundle_type.x.cf +5 -0
  62. cfengine-0.14.0/tests/lint/006_syntax_error.cf +5 -0
  63. cfengine-0.14.0/tests/lint/006_syntax_error.expected.txt +7 -0
  64. cfengine-0.14.0/tests/lint/006_syntax_error.x.cf +5 -0
  65. cfengine-0.14.0/tests/lint/007_empty_file.expected.txt +3 -0
  66. cfengine-0.14.0/tests/lint/008_namespace.cf +16 -0
  67. cfengine-0.14.0/tests/lint/008_namespace.expected.txt +7 -0
  68. cfengine-0.14.0/tests/lint/008_namespace.x.cf +16 -0
  69. cfengine-0.14.0/tests/lint/009_bundle_shadows_function.cf +5 -0
  70. cfengine-0.14.0/tests/lint/009_bundle_shadows_function.expected.txt +6 -0
  71. cfengine-0.14.0/tests/lint/009_bundle_shadows_function.x.cf +5 -0
  72. cfengine-0.14.0/tests/lint/010_unknown_function_inside_vars.cf +24 -0
  73. cfengine-0.14.0/tests/lint/010_unknown_function_inside_vars.expected.txt +12 -0
  74. cfengine-0.14.0/tests/lint/010_unknown_function_inside_vars.x.cf +22 -0
  75. cfengine-0.14.0/tests/lint/011_mutually_exclusive_types_vars.cf +14 -0
  76. cfengine-0.14.0/tests/lint/011_mutually_exclusive_types_vars.expected.txt +12 -0
  77. cfengine-0.14.0/tests/lint/011_mutually_exclusive_types_vars.x.cf +17 -0
  78. cfengine-0.14.0/tests/lint/012_invalid_attributes.expected.txt +12 -0
  79. cfengine-0.14.0/tests/lint/012_invalid_attributes.x.cf +13 -0
  80. cfengine-0.14.0/tests/lint/013_function_call_arg_count.cf +8 -0
  81. cfengine-0.14.0/tests/lint/013_function_call_arg_count.expected.txt +12 -0
  82. cfengine-0.14.0/tests/lint/013_function_call_arg_count.x.cf +14 -0
  83. cfengine-0.14.0/tests/lint/014_num_args_body.expected.txt +20 -0
  84. cfengine-0.14.0/tests/lint/014_num_args_body.x.cf +24 -0
  85. cfengine-0.14.0/tests/lint/014_num_args_bundle.expected.txt +20 -0
  86. cfengine-0.14.0/tests/lint/014_num_args_bundle.x.cf +17 -0
  87. cfengine-0.14.0/tests/lint/014_num_args_bundle_body.cf +11 -0
  88. cfengine-0.14.0/tests/lint/015_variadic_func_arg_count.cf +16 -0
  89. cfengine-0.14.0/tests/lint/015_variadic_func_arg_count.expected.txt +12 -0
  90. cfengine-0.14.0/tests/lint/015_variadic_func_arg_count.x.cf +18 -0
  91. cfengine-0.14.0/tests/lint/016_macro_multi_def_bundle.cf +25 -0
  92. cfengine-0.14.0/tests/lint/016_macro_multi_def_bundle.expected.txt +14 -0
  93. cfengine-0.14.0/tests/lint/016_macro_multi_def_bundle.x.cf +25 -0
  94. cfengine-0.14.0/tests/lint/017_half_promises.cf +12 -0
  95. cfengine-0.14.0/tests/lint/017_half_promises.expected.txt +17 -0
  96. cfengine-0.14.0/tests/lint/017_half_promises.x.cf +29 -0
  97. cfengine-0.14.0/tests/lint/018_implies_body.cf +12 -0
  98. cfengine-0.14.0/tests/lint/018_implies_body.expected.txt +38 -0
  99. cfengine-0.14.0/tests/lint/018_implies_body.x.cf +31 -0
  100. cfengine-0.14.0/tests/lint/019_nested_calls.cf +22 -0
  101. cfengine-0.14.0/tests/lint/019_nested_calls.expected.txt +22 -0
  102. cfengine-0.14.0/tests/lint/019_nested_calls.x.cf +24 -0
  103. cfengine-0.14.0/tests/lint/020_bundle_name_expansion.cf +15 -0
  104. {cfengine-0.12.2 → cfengine-0.14.0}/tests/run-format-tests.sh +3 -4
  105. cfengine-0.14.0/tests/run-lint-tests.sh +46 -0
  106. {cfengine-0.12.2 → cfengine-0.14.0}/tests/run-shell-tests.sh +2 -1
  107. cfengine-0.14.0/tests/shell/004-format-check.sh +67 -0
  108. cfengine-0.14.0/tests/unit/__init__.py +0 -0
  109. cfengine-0.14.0/tests/unit/test_format.py +514 -0
  110. cfengine-0.14.0/uv.lock +474 -0
  111. cfengine-0.12.2/.github/workflows/format.yml +0 -61
  112. cfengine-0.12.2/.github/workflows/lint.yml +0 -44
  113. cfengine-0.12.2/.github/workflows/test.yml +0 -49
  114. cfengine-0.12.2/.python-version +0 -1
  115. cfengine-0.12.2/src/cfengine.egg-info/SOURCES.txt +0 -63
  116. cfengine-0.12.2/src/cfengine_cli/format.py +0 -242
  117. cfengine-0.12.2/src/cfengine_cli/lint.py +0 -399
  118. cfengine-0.12.2/src/cfengine_cli/policy_language.py +0 -239
  119. cfengine-0.12.2/uv.lock +0 -474
  120. {cfengine-0.12.2 → cfengine-0.14.0}/.github/dependabot.yml +0 -0
  121. {cfengine-0.12.2 → cfengine-0.14.0}/.github/workflows/pypi-publish.yml +0 -0
  122. {cfengine-0.12.2 → cfengine-0.14.0}/LICENSE +0 -0
  123. {cfengine-0.12.2 → cfengine-0.14.0}/ci/01-install.sh +0 -0
  124. {cfengine-0.12.2 → cfengine-0.14.0}/ci/02-safe-tests.sh +0 -0
  125. {cfengine-0.12.2 → cfengine-0.14.0}/ci/03-unsafe-tests.sh +0 -0
  126. {cfengine-0.12.2 → cfengine-0.14.0}/setup.cfg +0 -0
  127. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine.egg-info/dependency_links.txt +0 -0
  128. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine.egg-info/entry_points.txt +0 -0
  129. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine.egg-info/top_level.txt +0 -0
  130. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/__init__.py +0 -0
  131. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/__main__.py +0 -0
  132. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/deptool-README.md +0 -0
  133. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/masterfiles/__init__.py +0 -0
  134. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/masterfiles/check_download_matches_git.py +0 -0
  135. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/masterfiles/generate_git_tags.py +0 -0
  136. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/masterfiles/generate_vcf_download.py +0 -0
  137. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/masterfiles/generate_vcf_git_checkout.py +0 -0
  138. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/paths.py +0 -0
  139. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/shell.py +0 -0
  140. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/utils.py +0 -0
  141. {cfengine-0.12.2 → cfengine-0.14.0}/src/cfengine_cli/version.py +0 -0
  142. {cfengine-0.12.2 → cfengine-0.14.0}/tests/format/001_hello_world.expected.cf +0 -0
  143. {cfengine-0.12.2 → cfengine-0.14.0}/tests/format/001_hello_world.input.cf +0 -0
  144. /cfengine-0.12.2/tests/__init__.py → /cfengine-0.14.0/tests/lint/007_empty_file.x.cf +0 -0
  145. {cfengine-0.12.2 → cfengine-0.14.0}/tests/shell/001-help.sh +0 -0
  146. {cfengine-0.12.2 → cfengine-0.14.0}/tests/shell/002-version.sh +0 -0
  147. {cfengine-0.12.2 → cfengine-0.14.0}/tests/shell/003-format.sh +0 -0
  148. {cfengine-0.12.2/tests → cfengine-0.14.0/tests/unit}/test_deps.py +0 -0
  149. {cfengine-0.12.2/tests → cfengine-0.14.0/tests/unit}/test_paths.py +0 -0
  150. {cfengine-0.12.2/tests → cfengine-0.14.0/tests/unit}/test_utils.py +0 -0
  151. {cfengine-0.12.2/tests → cfengine-0.14.0/tests/unit}/test_version.py +0 -0
@@ -0,0 +1,51 @@
1
+ # This workflow installs the necessary dependencies, runs make check, and
2
+ # checks if there are any edits. It should be very similar to what developers
3
+ # are expected to do locally. We want to ensure that all tests pass (make
4
+ # check succeeds) and that there is no additional formatting / untracked
5
+ # files generated.
6
+ #
7
+ # Note that make check is a bit special in this repo, it has some things you
8
+ # might not expect:
9
+ # 1. It doesn't only run tests, it also runs formatters and linters
10
+ # 2. It installs the CFEngine CLI, so that shell tests will work
11
+
12
+ name: Run make check
13
+ on:
14
+ push:
15
+ branches: [main]
16
+ pull_request:
17
+ branches: [main]
18
+ permissions:
19
+ contents: read
20
+ jobs:
21
+ check:
22
+ runs-on: ubuntu-24.04
23
+ strategy:
24
+ fail-fast: true
25
+ matrix:
26
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - name: Set up Python ${{ matrix.python-version }}
30
+ uses: actions/setup-python@v5
31
+ with:
32
+ python-version: ${{ matrix.python-version }}
33
+ - name: Install dependencies
34
+ run: |
35
+ python -m pip install --upgrade pip
36
+ python -m pip install uv
37
+ sudo apt-get install npm
38
+ npm install --global prettier
39
+ - name: Set python version file for uv
40
+ run: |
41
+ echo "${{ matrix.python-version }}" > .python-version
42
+ - name: Run make check
43
+ run: |
44
+ make check
45
+ - name: Reset python version file
46
+ run: |
47
+ git restore .python-version
48
+ - name: See if there are changes
49
+ run: |
50
+ git diff --exit-code
51
+ git ls-files --other --directory --exclude-standard | sed q1
@@ -0,0 +1,69 @@
1
+ name: Update syntax-description
2
+
3
+ on:
4
+ schedule:
5
+ - cron: "0 7 * * 1" # Run every Monday at 7am UTC
6
+ # | | | | |
7
+ # | | | | day of the week (0-6) (Sunday to Saturday)
8
+ # | | | month (1-12)
9
+ # | | day of the month (1-31)
10
+ # | hour (0-23)
11
+ # minute (0-59)
12
+ workflow_dispatch: # Enables manual trigger
13
+
14
+ jobs:
15
+ update_syntax_desc:
16
+ if: contains(fromJSON('["cfengine","mendersoftware","NorthernTechHQ"]'), github.repository_owner)
17
+ name: Update syntax-description
18
+ runs-on: ubuntu-24.04
19
+ permissions:
20
+ contents: write
21
+ pull-requests: write
22
+ steps:
23
+ - name: Checks-out repository
24
+ uses: actions/checkout@v4
25
+ with:
26
+ ref: "main"
27
+ - name: Set up Python 3.12
28
+ uses: actions/setup-python@v5
29
+ with:
30
+ python-version: "3.12"
31
+ - name: Install dependencies
32
+ run: |
33
+ python -m pip install --upgrade pip
34
+ python -m pip install cf-remote cfengine
35
+ - name: Install cfengine
36
+ run: |
37
+ cf-remote --version master download --edition community ubuntu24 amd64 hub
38
+ sudo dpkg -i ~/.cfengine/cf-remote/packages/cfengine-community*.deb
39
+ - name: Extract new syntax-description
40
+ run: |
41
+ (
42
+ sudo cf-promises --syntax-description json
43
+ ) > new.json
44
+ cfengine format new.json
45
+ - name: Set Git user
46
+ run: |
47
+ git config user.name 'github-actions[bot]'
48
+ git config user.email 'github-actions[bot]@users.noreply.github.com'
49
+ - name: Update contents of syntax-description
50
+ run: |
51
+ if ! cmp -s new.json ./src/cfengine_cli/syntax-description.json; then
52
+ cat new.json > ./src/cfengine_cli/syntax-description.json
53
+ echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
54
+ rm new.json
55
+ fi
56
+ - name: Create Pull Request
57
+ if: env.CHANGES_DETECTED == 'true'
58
+ uses: cfengine/create-pull-request@v6
59
+ with:
60
+ title: Updated syntax-description.json
61
+ body: Automated update to syntax-description.json [the `update-syntax-description` workflow](https://github.com/cfengine/cfengine-cli/tree/main/.github/workflows/update-syntax-description.yml).
62
+ reviewers: |
63
+ simonthalvorsen
64
+ olehermanse
65
+ larsewi
66
+ nickanderson
67
+ craigcomstock
68
+ branch: update-syntax-description
69
+ branch-suffix: timestamp
@@ -11,6 +11,7 @@ __pycache__
11
11
  /tmp/
12
12
  *.log
13
13
  *.output.cf
14
+ *.output.txt
14
15
  git_diff_exists
15
16
  commit_message.txt
16
17
  black_output.txt
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,51 @@
1
+ # CFEngine CLI information for LLMs
2
+
3
+ ## Fix the implementation
4
+
5
+ In general, when the prompter asks you to fix the implementation, this means that they have adjusted the tests already and they want you to fix the implementation.
6
+ Typically you should not touch the tests in this case, unless there is something obviously wrong in them, like a typo.
7
+ The first step to identify what is necessary should be to run the tests and see which ones are failing.
8
+
9
+ ## Running tests
10
+
11
+ In general, the main command to run for testing is:
12
+
13
+ ```bash
14
+ make check
15
+ ```
16
+
17
+ This will run all the test suites.
18
+
19
+ ## Running python tools
20
+
21
+ This project uses `uv`.
22
+ That means that you should not run `python`, `python3`, `pip`, `pip3` directly.
23
+ Instead, run the appropriate uv command to ensure we're using the right python and the right dependencies.
24
+
25
+ ## Pointers for the source code
26
+
27
+ When fixing issues, these are usually the files to look at:
28
+
29
+ - The implementation of `cfengine format` is in `src/cfengine_cli/format.py`.
30
+ - The implementation of `cfengine lint` is in `src/cfengine_cli/lint.py`.
31
+
32
+ ## Syntax trees
33
+
34
+ When working on the formatter or the linter, it is often useful to look at the syntax tree of the policy file.
35
+ There is a `dev` subcommand for this:
36
+
37
+ ```bash
38
+ uv run cfengine dev syntax-tree tests/lint/001_hello_world.cf
39
+ ```
40
+
41
+ The command above prints the syntax tree for `tests/lint/001_hello_world.cf` to the terminal (standard output).
42
+
43
+ ## Test suites
44
+
45
+ As mentioned above, the `make check` command runs all the tests.
46
+ We have different suites:
47
+
48
+ - Unit tests in `tests/unit` test individual python functions.
49
+ - Formatting tests in `tests/format` test the formatter (`cfengine format`).
50
+ - Linting tests in `tests/lint` test the linter.
51
+ - Shell tests in `tests/shell` tests various subcommands and the tool as a whole in an end-to-end fashion.
@@ -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, you can install it globally using pipx:
22
+
23
+ ```bash
24
+ make install
25
+ ```
26
+
27
+ This is optional — `make check` and `uv run` work without a global install.
28
+
29
+ ## Running commands without installing
30
+
31
+ You can run commands without installing globally, 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
+ uv run bash tests/run-lint-tests.sh
50
+ uv run bash tests/run-format-tests.sh
51
+ uv run 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`).
@@ -0,0 +1,26 @@
1
+ .PHONY: default format lint install check venv
2
+
3
+ default: check
4
+
5
+ venv:
6
+ uv venv --clear
7
+ uv sync
8
+
9
+ format: venv
10
+ uv tool run black . --target-version py310
11
+ prettier . --write
12
+
13
+ lint: venv
14
+ uv tool run black --check . --fast
15
+ uv tool run flake8 src/ --ignore=E203,W503,E722,E731 --max-complexity=100 --max-line-length=160
16
+ uv tool run pyflakes src/
17
+ uv tool run pyright src/
18
+
19
+ install:
20
+ pipx install --force --editable .
21
+
22
+ check: venv format lint
23
+ uv run pytest
24
+ uv run bash tests/run-lint-tests.sh
25
+ uv run bash tests/run-format-tests.sh
26
+ uv run bash tests/run-shell-tests.sh
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cfengine
3
- Version: 0.12.2
3
+ Version: 0.14.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
@@ -696,7 +696,7 @@ Requires-Python: >=3.10
696
696
  Description-Content-Type: text/markdown
697
697
  Requires-Dist: cf-remote>=0.7.3
698
698
  Requires-Dist: cfbs>=5.5.0
699
- Requires-Dist: tree-sitter-cfengine>=1.1.8
699
+ Requires-Dist: tree-sitter-cfengine>=1.1.12
700
700
  Requires-Dist: tree-sitter>=0.25
701
701
  Requires-Dist: markdown-it-py>=3.0.0
702
702
 
@@ -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 errors)
766
- Failure, 1 errors in total.
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 errors)
64
- Failure, 1 errors in total.
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.
@@ -12,7 +12,7 @@ requires-python = ">=3.10"
12
12
  dependencies = [
13
13
  "cf-remote>=0.7.3",
14
14
  "cfbs>=5.5.0",
15
- "tree-sitter-cfengine>=1.1.8",
15
+ "tree-sitter-cfengine>=1.1.12",
16
16
  "tree-sitter>=0.25",
17
17
  "markdown-it-py>=3.0.0",
18
18
  ]
@@ -40,6 +40,9 @@ cfengine = "cfengine_cli.main:main"
40
40
  [tool.setuptools]
41
41
  license-files = [] # Workaround bug in setuptools https://github.com/astral-sh/uv/issues/9513
42
42
 
43
+ [tool.setuptools.package-data]
44
+ cfengine_cli = ["*.json"] # syntax-description.json
45
+
43
46
  [tool.pyright]
44
47
  include = ["src"]
45
48
  venvPath = "."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cfengine
3
- Version: 0.12.2
3
+ Version: 0.14.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
@@ -696,7 +696,7 @@ Requires-Python: >=3.10
696
696
  Description-Content-Type: text/markdown
697
697
  Requires-Dist: cf-remote>=0.7.3
698
698
  Requires-Dist: cfbs>=5.5.0
699
- Requires-Dist: tree-sitter-cfengine>=1.1.8
699
+ Requires-Dist: tree-sitter-cfengine>=1.1.12
700
700
  Requires-Dist: tree-sitter>=0.25
701
701
  Requires-Dist: markdown-it-py>=3.0.0
702
702
 
@@ -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 errors)
766
- Failure, 1 errors in total.
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.
@@ -0,0 +1,140 @@
1
+ .gitignore
2
+ .python-version
3
+ CLAUDE.md
4
+ HACKING.md
5
+ LICENSE
6
+ Makefile
7
+ README.md
8
+ pyproject.toml
9
+ uv.lock
10
+ .github/dependabot.yml
11
+ .github/workflows/make-check.yml
12
+ .github/workflows/pypi-publish.yml
13
+ .github/workflows/update-syntax-description.yml
14
+ ci/01-install.sh
15
+ ci/02-safe-tests.sh
16
+ ci/03-unsafe-tests.sh
17
+ src/cfengine.egg-info/PKG-INFO
18
+ src/cfengine.egg-info/SOURCES.txt
19
+ src/cfengine.egg-info/dependency_links.txt
20
+ src/cfengine.egg-info/entry_points.txt
21
+ src/cfengine.egg-info/requires.txt
22
+ src/cfengine.egg-info/top_level.txt
23
+ src/cfengine_cli/__init__.py
24
+ src/cfengine_cli/__main__.py
25
+ src/cfengine_cli/commands.py
26
+ src/cfengine_cli/deptool-README.md
27
+ src/cfengine_cli/deptool.py
28
+ src/cfengine_cli/dev.py
29
+ src/cfengine_cli/docs.py
30
+ src/cfengine_cli/format.py
31
+ src/cfengine_cli/lint.py
32
+ src/cfengine_cli/main.py
33
+ src/cfengine_cli/paths.py
34
+ src/cfengine_cli/profile.py
35
+ src/cfengine_cli/shell.py
36
+ src/cfengine_cli/syntax-description.json
37
+ src/cfengine_cli/syntax_tree.py
38
+ src/cfengine_cli/utils.py
39
+ src/cfengine_cli/version.py
40
+ src/cfengine_cli/masterfiles/__init__.py
41
+ src/cfengine_cli/masterfiles/analyze.py
42
+ src/cfengine_cli/masterfiles/check_download_matches_git.py
43
+ src/cfengine_cli/masterfiles/download.py
44
+ src/cfengine_cli/masterfiles/generate_git_tags.py
45
+ src/cfengine_cli/masterfiles/generate_release_information.py
46
+ src/cfengine_cli/masterfiles/generate_vcf_download.py
47
+ src/cfengine_cli/masterfiles/generate_vcf_git_checkout.py
48
+ tests/README.md
49
+ tests/run-format-tests.sh
50
+ tests/run-lint-tests.sh
51
+ tests/run-shell-tests.sh
52
+ tests/format/001_hello_world.expected.cf
53
+ tests/format/001_hello_world.input.cf
54
+ tests/format/002_basics.expected.cf
55
+ tests/format/002_basics.input.cf
56
+ tests/format/003_wrapping.expected.cf
57
+ tests/format/003_wrapping.input.cf
58
+ tests/format/004_comments.expected.cf
59
+ tests/format/004_comments.input.cf
60
+ tests/format/005_bundle_comments.expected.cf
61
+ tests/format/005_bundle_comments.input.cf
62
+ tests/format/006_remove_empty_comments.expected.cf
63
+ tests/format/006_remove_empty_comments.input.cf
64
+ tests/format/007_class_guarded_empty_lines.expected.cf
65
+ tests/format/007_class_guarded_empty_lines.input.cf
66
+ tests/format/008_long_string.expected.cf
67
+ tests/format/008_long_string.input.cf
68
+ tests/format/009_single_line.expected.cf
69
+ tests/format/009_single_line.input.cf
70
+ tests/format/010_stakeholder.expected.cf
71
+ tests/format/010_stakeholder.input.cf
72
+ tests/format/011_macros.expected.cf
73
+ tests/format/011_macros.input.cf
74
+ tests/format/011_promises.expected.cf
75
+ tests/format/011_promises.input.cf
76
+ tests/lint/001_hello_world.cf
77
+ tests/lint/002_ifvarclass.expected.txt
78
+ tests/lint/002_ifvarclass.x.cf
79
+ tests/lint/003_deprecated_promise_type.cf
80
+ tests/lint/003_deprecated_promise_type.expected.txt
81
+ tests/lint/003_deprecated_promise_type.x.cf
82
+ tests/lint/004_bundle_name_lowercase.cf
83
+ tests/lint/004_bundle_name_lowercase.expected.txt
84
+ tests/lint/004_bundle_name_lowercase.x.cf
85
+ tests/lint/005_bundle_type.cf
86
+ tests/lint/005_bundle_type.expected.txt
87
+ tests/lint/005_bundle_type.x.cf
88
+ tests/lint/006_syntax_error.cf
89
+ tests/lint/006_syntax_error.expected.txt
90
+ tests/lint/006_syntax_error.x.cf
91
+ tests/lint/007_empty_file.expected.txt
92
+ tests/lint/007_empty_file.x.cf
93
+ tests/lint/008_namespace.cf
94
+ tests/lint/008_namespace.expected.txt
95
+ tests/lint/008_namespace.x.cf
96
+ tests/lint/009_bundle_shadows_function.cf
97
+ tests/lint/009_bundle_shadows_function.expected.txt
98
+ tests/lint/009_bundle_shadows_function.x.cf
99
+ tests/lint/010_unknown_function_inside_vars.cf
100
+ tests/lint/010_unknown_function_inside_vars.expected.txt
101
+ tests/lint/010_unknown_function_inside_vars.x.cf
102
+ tests/lint/011_mutually_exclusive_types_vars.cf
103
+ tests/lint/011_mutually_exclusive_types_vars.expected.txt
104
+ tests/lint/011_mutually_exclusive_types_vars.x.cf
105
+ tests/lint/012_invalid_attributes.expected.txt
106
+ tests/lint/012_invalid_attributes.x.cf
107
+ tests/lint/013_function_call_arg_count.cf
108
+ tests/lint/013_function_call_arg_count.expected.txt
109
+ tests/lint/013_function_call_arg_count.x.cf
110
+ tests/lint/014_num_args_body.expected.txt
111
+ tests/lint/014_num_args_body.x.cf
112
+ tests/lint/014_num_args_bundle.expected.txt
113
+ tests/lint/014_num_args_bundle.x.cf
114
+ tests/lint/014_num_args_bundle_body.cf
115
+ tests/lint/015_variadic_func_arg_count.cf
116
+ tests/lint/015_variadic_func_arg_count.expected.txt
117
+ tests/lint/015_variadic_func_arg_count.x.cf
118
+ tests/lint/016_macro_multi_def_bundle.cf
119
+ tests/lint/016_macro_multi_def_bundle.expected.txt
120
+ tests/lint/016_macro_multi_def_bundle.x.cf
121
+ tests/lint/017_half_promises.cf
122
+ tests/lint/017_half_promises.expected.txt
123
+ tests/lint/017_half_promises.x.cf
124
+ tests/lint/018_implies_body.cf
125
+ tests/lint/018_implies_body.expected.txt
126
+ tests/lint/018_implies_body.x.cf
127
+ tests/lint/019_nested_calls.cf
128
+ tests/lint/019_nested_calls.expected.txt
129
+ tests/lint/019_nested_calls.x.cf
130
+ tests/lint/020_bundle_name_expansion.cf
131
+ tests/shell/001-help.sh
132
+ tests/shell/002-version.sh
133
+ tests/shell/003-format.sh
134
+ tests/shell/004-format-check.sh
135
+ tests/unit/__init__.py
136
+ tests/unit/test_deps.py
137
+ tests/unit/test_format.py
138
+ tests/unit/test_paths.py
139
+ tests/unit/test_utils.py
140
+ tests/unit/test_version.py
@@ -1,5 +1,5 @@
1
1
  cf-remote>=0.7.3
2
2
  cfbs>=5.5.0
3
- tree-sitter-cfengine>=1.1.8
3
+ tree-sitter-cfengine>=1.1.12
4
4
  tree-sitter>=0.25
5
5
  markdown-it-py>=3.0.0