Skip to content

Conversation

@scastlara
Copy link
Collaborator

There are several problems (imo) with the ConfigHandler as it is:

  • It keeps a lot of state internally, which makes it harder to reason about
  • It reads files and does stuff on init which makes it harder to use in tests, it's a strange side effect to read files on init.
  • It treats tomlkit as a dict, but tomlkit uses a TOMLDocument class (which acts somehow as a dict, but is not entirely a dict).
  • The handler was the config.
  • The resolution of the config (deciding between cli/file/defaults) was done outside of the config handler.

In this PR:

  • The handler is initialized and nothing happens yet.
  • You can choose to resolve_config(...) and you get back a frozen dataclass with defaults and everything you need to run Twyn. Pass in any cli arguments you have, and resolve_config will know what to do. Defaults are handled here.
  • Both remove_package_from_allowlist and add_package_to_allowlist use a new dataclass (ReadTwynConfiguration) that represents the configuration as parsed from the toml. Then they use tomlkit (not dictionaries) to write the toml document; handling whether the twyn section is there or not.

@scastlara scastlara requested a review from sdn4z as a code owner November 15, 2024 12:39
@scastlara scastlara force-pushed the config-rewrite branch 3 times, most recently from 65ea856 to d544ffb Compare November 15, 2024 12:42
@scastlara scastlara changed the title refactor: rewrite configuration handle refactor: rewrite configuration handler Nov 15, 2024
@scastlara scastlara self-assigned this Nov 15, 2024
raise TOMLError(f"Error writing toml to {self._file_path}") from None


def _get_logging_level(
Copy link
Collaborator

Choose a reason for hiding this comment

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

should this be inside the class?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Since it does not use self at all, I just put it here.

self.selector_method: Optional[str] = self._twyn_data.get("selector_method")
self.logging_level: Optional[str] = self._twyn_data.get("logging_level")
self.allowlist: set[str] = set(self._twyn_data.get("allowlist", []))
def resolve_config(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I've been thinking for a while, could it be that this class' responsibilities are too broad?

For instance, right now this class both creates mechanisms to create config objects and interacting with the config file, would it make sense to split it?

Say, we have something that acts as a factory, just creating config objects, and then we have the config objects themselves, who are the ones that read and write to the file.

Maybe this is not the PR to make these changes, as some methods are mandatory both when creating the object and when interacting with the file (like _read_toml) but this could be adapted whenever we move this class' implementation to use the FileHandler.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Overall agree that it would not hurt to separate the reading and the writing. Though I imagine they will need mechanisms to share stuff.

Having said that, this class has 3 public methods, and 150 lines or so. It's not too bad. I am not a fan of the config objects writing themselves though.

I do not really know how useful the filehandler will be for this, but I guess I'll see in the next PRs.

@scastlara scastlara merged commit 1176134 into main Nov 15, 2024
8 checks passed
@scastlara scastlara deleted the config-rewrite branch November 15, 2024 15:01
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.

3 participants