Skip to content

Conversation

@vickgoodman
Copy link
Contributor

Implement DIRECTORY.INTERFACE_HEADERS check - #43

  • Added check
  • Added tests

Darius Neațu and others added 30 commits June 16, 2025 16:11
Add beman-tidy: The Codebase Bemanification Tool
- We no longer need Makefiles
- No need for requirements.txt files, better lockfiles instead

Signed-off-by: rishyak <[email protected]>
Signed-off-by: rishyak <[email protected]>
…alAction

- `type` param of `argparse.BooleanOptionalAction` are deprecated and will be removed in Python 3.14
- https://docs.python.org/3.14/deprecations/pending-removal-in-3.14.html

Signed-off-by: rishyak <[email protected]>
- Move code under beman_tidy/ (including lib/) - This aligns with PyPA's recommended flat layout, and ensures your lib/ subpackage is bundled in the wheel.
- See: https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/
beman-tidy: migrate to pyproject.toml-based build with Astral's uv
# Example path: "exemplar/include/beman/exemplar"
include_path = self.path / "include" / "beman" / self.repo_info["name"]
if (
not os.path.exists(include_path)
Copy link
Member

@neatudarius neatudarius Jul 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still not applied - we should not require using os if we are using Path


# TODO DIRECTORY.INTERFACE_HEADERS
@register_beman_standard_check("DIRECTORY.INTERFACE_HEADERS")
class DirectoryInterfaceHeadersCheck(DirectoryBaseCheck):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not have include_path = self.path / "include" / "beman" / self.repo_info["name"] in your code!
This is why BemanTreeDirectoryCheck class exists. We should have class DirectoryInterfaceHeadersCheck(BemanTreeDirectoryCheck), which will give you self.path -> include/beman/short_name. And then you can create other paths, if you want starting from self.repo_path.

include_path = self.path / "include" / "beman" / self.repo_info["name"]
if (
not os.path.exists(include_path)
or os.path.isfile(include_path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
or os.path.isfile(include_path)
or os.path.isfile(include_path)

can we use pathlib instead os everywhere?

or len(os.listdir(include_path)) == 0
):
self.log(
f"The path '{self.path}' does not exist, is a file or is empty."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
f"The path '{self.path}' does not exist, is a file or is empty."
f"The path '{self.path}' does not exist, is a file or is empty. "

):
self.log(
f"The path '{self.path}' does not exist, is a file or is empty."
" All public header files must reside within include/beman/<short_name>/."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
" All public header files must reside within include/beman/<short_name>/."
"All public header files must reside within include/beman/<short_name>/."

if self.repo_info["name"] == "exemplar":
exclude_dirs.add("cookiecutter")

hpp_files = []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hpp_files = []
header_files = []

Please don't resolve comments , just push fixes and reply. I will marke comments as resolved e.g. https://github.com/bemanproject/infra/pull/134/files#r2207970309.

for hpp_file in hpp_files:
if not hpp_file.startswith(str(include_path)):
self.log(
f"Header file '{hpp_file}' is not under include/beman/{self.repo_info['name']}/ directory."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
f"Header file '{hpp_file}' is not under include/beman/{self.repo_info['name']}/ directory."
f"Header file '{hpp_file}' is not under include/beman/{self.repo_name}/ directory."

we have that shortcut - pleas read tools/beman-tidy/beman_tidy/lib/checks/base/base_check.py

Copy link
Member

@neatudarius neatudarius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temporary blocking this PR until we figured out what's desired plan and expectations for tidy and headers checks


def check(self):
"""
Check that all public header files reside within the include/beman/<short_name>/ directory.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, let's not discussed implementation from this PR, as the pattern is similar to the one for PAPERS (https://github.com/bemanproject/infra/pull/159#discussion_r2223086644).

I propose a plan for DIRECTORY.INTERFACE_HEADERS and DIRECTORY.IMPLEMENTATION_HEADERS
image

@Valid header locations
First of all, we can have headers in

  1. include/beman/<short_name> - valid location
  2. include/ but not in include/beman/<short_name> - invalid location
  3. src/beman/short_name - valid location
  4. src but not in src/beman/short_name - invalid location
  5. examples/ - valid location
  6. tests/beman/short_name - valid location
  7. tests/ but not in tests/beman/short_name - invalid location
  8. cookiecutter - valid location
  9. infra - valid location
    TLDR:
valid_header_locations = [
# Library specific
"include/beman/short_name",
"src/beman/short_name",
"tests/beman/short_name",
'examples",
# Infra
"infra",
"cookiecutter",
]

We can assume, IMO, for now, that this is a complete set of locations which can be used in v1 implementation. If we go with this approach, we can actually run locally run the tool on all libraries and see if we are missing something before first commit!

@CML can provide us necessary info?

  1. I briefly investigated if we can use CML. As per my understanding, CML does not export this info in compile_commands.json, so I think we should actually parse the CML and find the target_sources call and see what we set for PUBLIC and PRIVATE. @nickelpro ?
  2. I don't want to complicate things - let's assume it works with CML. What if a library requires custom build flags to actually build with a (sub)directory? etc
    I think it's better to do best-effort search by accessing the filesystem, IMO.

=================================================================
My proposal

I. Steps for DIRECTORY.INTERFACE_HEADERS:

  1. We assert to exists include/beman/<short_name> (we cannot have a library without at least one public header!). If invalid, we stop -> Missing include/beman/<short_name>. Expected public interface to be present. Please check ....
  2. We do search for all headers in the repo which are not in valid_header_locations , and if we find one we fail the check.
  3. If 1 + 2 passed, DIRECTORY.INTERFACE_HEADERS check also passes.
    (We actually just checked headers are at right location. We didn't use the "public" thing here. It's not needed IMO.)
    TLDR: It's same proposal from this PR.

II. Steps for DIRECTORY.IMPLEMENTATION_HEADERS.
We cannot actually easier distinguish which is public and which is private headers. We can say it's SKIPPED and log a message (we assume my PR #148 is already merged).

=================================================================

Again, please ignore the current pushed implementation, let's decide what should be the desired approach.
CC: @vickgoodman (PR owner) @JeffGarland (Style Czar) @nickelpro (Build Czar)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to Victor's availability (PTO), we discussed and I may take this PR (we want DIRECTORY.*) to be completed for release 1.0 ASAP. @vickgoodman , can you confirm?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to update the PR and close the issue. Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will update this PR next weeks.

@neatudarius
Copy link
Member

Reminder to update this PR with latest main after https://github.com/bemanproject/infra/pull/170.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants