-
Notifications
You must be signed in to change notification settings - Fork 183
cmd-diff: a few misc enhancements #4253
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
base: main
Are you sure you want to change the base?
Conversation
It had some common elements so let's use a loop.
Since we could be operating on directories or files change file_from -> path_from and file_to -> path_to. Also change the temporary output filenames to more properly indicate they are outputs.
This strategy simply changes directory into the given path before running the provided command rather than replacing a templated `{}` with the path. Useful for commands that operate more cleanly when operated on in the directory where you want the operation to occur.
Having vimdiff is a lot more powerful to me because you can manually do a few things in the terminal to massage the files on each side of the diff to give you more information (i.e. narrow in on exactly what diff you are interested in). Let's add a --difftool boolean flag to trigger `git difftool`, which will allow diffs to be displayed using vimdiff. Additionally include vim-enhanced so we have `vimdiff` installed and at our disposal.
This way we can have more commands that can leverae this code for different "diffs" on the resulting mounted filesystems. Prep for a future commit.
A few more views of differences between two metal disk image mounted filesystems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces several enhancements to cmd-diff
, including new --metal-ls
and --metal-du
differs and a --difftool
option to use an external diff tool like vimdiff
. The refactoring to support the new differs is well-executed, with shared logic extracted into a reusable generator.
My review focuses on a couple of areas for improvement. The implementation of --difftool
relies on a global variable, which can affect maintainability. I've suggested alternatives to make this dependency explicit. I also found a minor issue with a superfluous attribute access in the diff_cmd_outputs
function. Overall, these are good additions to the tool.
# Modify the USE_DIFFTOOL global based on the --difftool argument | ||
global USE_DIFFTOOL | ||
USE_DIFFTOOL = args.difftool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a global variable like USE_DIFFTOOL
makes the code harder to reason about and test due to hidden dependencies. It's better to make dependencies explicit.
A preferred approach would be to pass the difftool
setting down through function arguments. While this might require a larger refactoring, it would improve code quality. A less disruptive alternative could be to encapsulate settings into a configuration object that is created in main()
and passed to the functions that need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A preferred approach would be to pass the difftool setting down through function arguments. While this might require a larger refactoring, it would improve code quality. A less disruptive alternative could be to encapsulate settings into a configuration object that is created in main() and passed to the functions that need it.
indeed. I started this way, but passing that around to all the functions proved a bit more "unclean" than I wanted. It was part me being lazy and part just not wanting to pass it all around because it's ugly.
Though, this is ugly too.
Let's see what other people think.
I tried to build cosa with the patch on aarch64 and failed, not sure if I missed something.
|
Potentially running out of memory? Or maybe the machine you are on doesn't support virtualization (i.e. does |
Make sure to also:
|
The .stdout at the end of this line is unnecessary and has no effect. When stdout is redirected to a file object, the stdout attribute of the returned CompletedProcess object is None. Assisted-By <gemini-code-assist> coreos#4253 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I like new differs.
src/cmd-diff
Outdated
c = list(cmd) | ||
if '{}' not in c: | ||
c += ['{}'] | ||
idx = c.index('{}') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't need to be in the loop. Probably cleaner to still clone the list for each iteration though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right. it doesn't need to be in the loop but keeping the code grouped together with the strategy was nice rather than having multiple if strategy=
branches.
@@ -401,16 +401,21 @@ def diff_metal(diff_from, diff_to): | |||
shutdown_process(p_to) | |||
|
|||
|
|||
def diff_cmd_outputs(cmd, path_from, path_to): | |||
def diff_cmd_outputs(cmd, path_from, path_to, strategy='template'): | |||
workingdir = os.getcwd() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor/optional: in situations like this, I prefer to use the signature default so that it's equivalent to not passing an argument at all in the default case. Often (like here), that's None
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i.e.
workingdir = os.getcwd() | |
workingdir = None |
? I can make that change if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, exactly.
@@ -401,16 +401,21 @@ def diff_metal(diff_from, diff_to): | |||
shutdown_process(p_to) | |||
|
|||
|
|||
def diff_cmd_outputs(cmd, path_from, path_to): | |||
def diff_cmd_outputs(cmd, path_from, path_to, strategy='template'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels a bit weird to use a string for this. Couldn't it just be a boolean?
That avoids the assert
also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kind of liked leaving this open to different strategies in the future and also being more explicit in the naming.
i.e. what would the boolean argument's name be? use_cd_not_template=False
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe just chdir
?
Or we could make it into a proper enum too like OSTreeImport
if we want to keep this structure.
@@ -110,3 +110,6 @@ python3-libguestfs | |||
|
|||
# For generating kubernetes YAML files (e.g Konflux resources) | |||
kustomize | |||
|
|||
# For vimdiff | |||
vim-enhanced |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, how can we structure this so that this functionality is not dependent on the $preferred_tool
shipping in cosa? One option is that cosa diff --difftool
in that case just outputs the command and you run it.
Or... it could also do something like systemd-run --user -t --same-dir --wait --collect git difftool ...
maybe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. I like git-delta so being able to plug my own tool would be nice. How about we juste write the git diff output to a file and then we can invoke the tool we want?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cosa diff --difftool
in that case just outputs the command and you run it.
Only thing about this is it implies not cleaning up after itself.
Or... it could also do something like systemd-run --user -t --same-dir --wait --collect git difftool ... maybe.
This implies functionality we don't necessarily have today. i.e. in the run via bash function case where we run inside the COSA container, we don't have things mounted into the container that would allow it to run a systemd unit on the host.
It definitely sucks installing this into the COSA container too, but it was the easiest thing to do. We don't have to do that, i'd just continue to do what I've been doing, which is cosa shell
and then sudo dnf install vim
before running cosa diff --difftool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only thing about this is it implies not cleaning up after itself.
Indeed. I think it's OK in that case to tell the user they're responsible for cleanup.
This implies functionality we don't necessarily have today. i.e. in the run via bash function case where we run inside the COSA container, we don't have things mounted into the container that would allow it to run a systemd unit on the host.
Right yeah, the idea would be to add another option to the alias.
It definitely sucks installing this into the COSA container too, but it was the easiest thing to do. We don't have to do that, i'd just continue to do what I've been doing, which is cosa shell and then sudo dnf install vim before running cosa diff --difftool
Not strongly against to be clear, but I think it'd be a larger win to try to make this work for everyone.
# Now that the mounts are live, we can diff them | ||
git_diff(mount_dir_from, mount_dir_to) | ||
# Allow the caller to operate on these values | ||
yield mount_dir_from, mount_dir_to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't a more appropriate model for the single yield
case be to just take a function as argument?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess. Like a callback?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looked into this a little, but time boxed myself on it and ran out of time. Can we leave it and improve later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically I mean something like
def diff_metal_ls(diff_from, diff_to):
cmd = ['find', '.']
def differ(mount_dir_from, mount_dir_to):
diff_cmd_outputs(cmd, mount_dir_from, mount_dir_to, strategy='cd')
diff_metal_helper(diff_from, diff_to, differ)
or did that not work?
Sorry for the late reply, test on x86_64, and it works.
|
The answer to this is nuanced. We could potentially add a pipe here to sort the output, but with When I was doing this I'd do just that. I'd pipe the left and right panes through I'd also do things like remove the unique hashes from the output so that the diffs were normalized (i.e. removing unique things that aren't important to the diff). So I view this as something that can be solved by using a powerful difftool rather than having to bake all that functionality directly into |
See individual commit messages.
We now have a
--metal-ls
and--metal-du
and also a--difftool
to tellcosa diff
to output usinggit difftool
versusgit diff
so we can usevimdiff
.