-
-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
util: Break VDF actions into util functions #407
base: main
Are you sure you want to change the base?
Conversation
I should've given an example in the OP, but to illustrate more benefits to using this approach, here's how we might use this function in future. Update
|
Marking as a draft as it needs a little bit of further testing, and needs #336 as some code in that PR will be migrated over to using this new approach.
Note: The functionality in this PR is specific to text-based VDF files (such as
config.vdf
orlibraryfolders.vdf
). It does not cover the binary VDF files (such asshortcuts.vdf
).Overview
This PR implements the VDF splitting logic discussed in #336. This makes interacting with text-based VDF files a lot easier, as we only need to give the path to this file, and a function that will perform some action on this. We accomplish this by defining a function that expects some VDF file dict, and it will manipulate the information in that dict.
This function is then passed to our new util function which loads the VDF file, runs this function to modify the VDF file dict, and then handles writing that updated data out for us.
Doing things this way means:
vdf
library is used so that we don't have to remember this each time we want to write to the VDF file.config_vdf_dict
and I will handle updating the data I care about in this dict".Background
The goal of this PR was to avoid duplicated and convoluted calls to
vdf.dump
, primarily when writing toconfig.vdf
. The problem is that each time we want to do this, we need to know a lot of implementation details and we need to do a bit of boilerplate.config.vdf
file handle, check that it exists, and then parse it withvdf.load
.CompatToolMapping
section inside of it.vdf.dump
.Implementation
This PR resolves those issues by creating one util function called
update_vdf_text_data
that handles all of the details on loading and writing with a text-based VDF file, and accepts a function that takes that loaded VDF file and manipulates it. This util function then handles writing this data out again. This meansupdate_vdf_text_data
doesn't have to know how to load the VDF file, only how it wants to modify the data.update_vdf_text_data
function doesn't have to know how the caller wants to modify the VDF file, it only has to know how to load and write the VDF file.There is a small convenience wrapper around
update_vdf_text_data
specific to writing toconfig.vdf
as this is quite common.For the two examples in this PR, I updated
steam_update_ctools
(used to update the compatibility tools in bulk from the Games List) andsteam_update_ctool
(used to update games' ctools with Batch Update). These two util functions now have nested functions inside of them that manipulate theconfig_vdf_dict
. These nested functions can even use the passed data to the parent function! For example,steam_update_ctools
gets passed a games list. But in order to properly updateconfig_vdf_dict
we need data about this game list. A nested function inside ofsteam_update_ctools
can use the games list parameter as well as its own parameter that will get passed to this nested function when it is called byupdate_vdf_text_data
.This is really cool, because it means the nested function can still act the same way as the old code and still have access to the games list parameter, but doesn't have to be handle the VDF dict itself, it can just get that from whoever calls it! How this works is an absolute mystery to me, it is quite magic.
This is the solution I came up with. Right now it seems like a pretty clean way to break out this functionality , there's a (hopefully) clear illustration on how the data interacts. We have the util function that writes to the VDF files, and can take some Callable that can manipulate the data. That callable and the caller of the util function doesn't have to care about how the VDF files are loaded, it just has to expect the data and care how it wants to manipulate it for its own implementation detail.
As always, all feedback is welcome. Once I have tested some more and once #336 is merged, I will pull this out of draft. But I wanted to work on it while the idea was fresh in my head, and get a PR writeup done now while the rationale and implementation was also fresh 😄
Thanks!