Skip to content

Validate config/manifest documents using Pydantic#74

Merged
bschwedler merged 7 commits intomainfrom
toml-schema-validation
Jan 16, 2025
Merged

Validate config/manifest documents using Pydantic#74
bschwedler merged 7 commits intomainfrom
toml-schema-validation

Conversation

@bschwedler
Copy link
Contributor

@bschwedler bschwedler commented Jan 10, 2025

  • Use pydantic BaseModel for all Config objects
  • Create ManifestDocument BaseModel and add validation

First step in #51

This change moves to using BaseModel instead of a dataclass which has
several advantages for validation

- Built-in validation
- Default values can be set on the class attr
- We can add custom validators

We also add a new ConfigDocument class that represents the TOML document
itself.

Additionally, we also change the entities stored as a Set to a List.
De-duplication is handled by a field validator.
@bschwedler bschwedler added the docker Related to container images we produce label Jan 10, 2025
@github-actions
Copy link

github-actions bot commented Jan 10, 2025

Test Results

135 tests   133 ✅  5s ⏱️
  1 suites    2 💤
  1 files      0 ❌

Results for commit f8a1582.

♻️ This comment has been updated with latest results.

@bschwedler
Copy link
Contributor Author

@ianpittwood I fully expect that further validations and test will be required when I start to convert the document objects into the targetbuild/project structure.

Copy link
Contributor

@ianpittwood ianpittwood left a comment

Choose a reason for hiding this comment

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

We should probably consider updating the version in pyproject.toml at least to a new dev version.

Everything looks good so far direction-wise to me! I mostly had questions and some nits on typos and such.


@field_validator("os", mode="after")
@classmethod
def validate_os(cls, _os: List[str]) -> List[str]:
Copy link
Contributor

Choose a reason for hiding this comment

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

For my own understanding, would we be receiving the substring of the Containerfile extension in here? For example (and I know these have been altered) from our existing files ubuntu2204 or centos7

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I haven't gotten to that point yet. I was intending to look at this when I re-worked how the manifests relate to the build plan.


# Only allow lowercase letters, number, hyphens, underscores, and periods
# Do not use raw strings here to avoid escaping (e.g. r"{{.+?}}")
TAG_STR: str = "[a-z0-9-_.]"
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I prefer globals/constants to always be just after imports or for them to be members of their relevant class. I can also understand why grouping them may be more visible for you though. Perhaps we should consider further breaking down these definitions into additional files and/or modules and utilizing __init__.py to export them for ease of use?

Copy link
Contributor Author

@bschwedler bschwedler Jan 13, 2025

Choose a reason for hiding this comment

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

I originally had these up at the top of the file. I'll move them back up there.

I like your idea of adding more files. I'll think about how to do this, but now I'm thinking separate modules for the config/manifest and making each file much smaller.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking maybe something like this:

.
└── models/
    ├── __init__.py
    ├── config/
    │   ├── __init__.py
    │   ├── components.py
    │   │   ├── <ConfigRegistry>
    │   │   └── <ConfigRepository>
    │   ├── document.py
    │   │   └── <ConfigDocument>
    │   └── model.py
    │       └── <Config>
    └── manifest/
        ├── __init__.py
        ├── components.py
        │   ├── <BuildOS>
        │   └── <GossConfig>
        ├── document.py
        │   ├── <ManifestGoss>
        │   ├── <ManifestBuild>
        │   ├── <ManifestTarget>
        │   └── <ManifestDocument>
        └── model.py
            ├── <TargetBuild>
            └── <Manifest>

But that's just an idea for splitting stuff up in a pattern between the two primary definition types.

I do think this draws attention to a possible issue, however. We may need to make the delineation clearer between classes used for ingesting the Document versus those used for modeling the related Object. I don't think classes like ConfigRegistry or ConfigRepository should necessarily be reused and instead should have ConfigDocumentX classes. I think we want to still clearly separate Document=Validation and Model=Transformation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This has been refactored in the latest commits.

I completely agree with keeping the config and manifest document information separate from the usage. In the next PR, I'll be refactoring the Project class and related thingz and we'll see where everything lands.

We will be further refactoring models into smaller files.

To keep that change isolated, incorporate the rest of the PR feedback
into a separate commit.
@bschwedler bschwedler force-pushed the toml-schema-validation branch from 445faed to 2d10e9a Compare January 15, 2025 21:43
@bschwedler
Copy link
Contributor Author

@ianpittwood Can you please give this another once-over? Thanks!

Copy link
Contributor

@ianpittwood ianpittwood left a comment

Choose a reason for hiding this comment

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

Just a few issues in os.py mainly and some other suggestions. I think it'll be good once the missed variable renames get fixed :D.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same as os.py, perhaps this should be target_goss.py?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm going to leave this one as goss.py since the TargetGoss will come in the next PR.

@bschwedler bschwedler force-pushed the toml-schema-validation branch from e8d63de to f8a1582 Compare January 16, 2025 16:06
@bschwedler bschwedler merged commit 852cd6c into main Jan 16, 2025
2 checks passed
@bschwedler bschwedler deleted the toml-schema-validation branch January 16, 2025 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docker Related to container images we produce

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants