Please consider merging branch builddepfix
of repo https://git.spwhitton.name/propellor
Patches Apt.buildDep
to check whether the build deps are installable, so that it no longer registers a change every spin.
Apt.buildDep now checks if the dpkg status file has changed, so done --Joey
Looks like Build-Depends-Index is not handled, nor are 'a | b' build deps, or arch-specific build deps. Since versions are skipped, if a build dep needed a newer version, the property also wouldn't try to upgrade to it after this change.
I feel that parsing build deps is too complex for propellor.
It might work to somehow detect if apt has made any changes.
How about simply checking if /var/lib/dpkg/status is changed?
I added a
changesFile
property combinator which should be helpful for that.I was hoping your deep knowledge of Apt would be able to help with this!
Before I proceed, how would you feel about catching the output of apt and only printing it if apt did make changes? Although that would make the output weirdly appear all at once when the build deps are actually installed, on the other hand it would mean no output if they're not, when we detect no changes to /var/lib/dpkg/status.
I think it would probably depend on the user when that makes sense to do. If I'm installing build deps over a slow network connection, I'd like to see the output.
It would be awesome if this transformation could be applied to any arbitrary Property. I don't immediately know how to do that, although it seems useful that all process spawning already goes through concurrent-output, which can buffer the output and display it only when the command finishes.
Perhaps an extension to concurrent-ouput could let it buffer the output of all commands run by a property and then discard the buffer if the property finished with NoChange. But I don't see a way to make this work when multiple properties are being run concurrently.
I've made a property combinator
noChangeIfUnchanged
and applied it to Apt.buildDep in mybuilddepfix
branch. Please take a look.In my testing of this, Propellor hides the output if the build deps are already installed i.e. if the property returns NoChange. So it looks like you've already implemented your awesome at some point
changesFile
combinator when I sat down to write mine. Taking a look now, my approach is much more direct for cases likeApt.buildDep
when the problem is registering a change when there should be NoChange, whereas I think the intention of your changesFile is the opposite case. Though it might be nice to combine them. Let me know what you think.The two combinators are indeed very similar. The reason I wrote changesFile the way I did is that that allows it to be applied repeatedly when a property can change any of several files.
That seems fairly likely to come up, while it would be unusual for a property to have to change multiple files at once to be considered to make a change at all, which is what multiple applications of
noChangeIfUnchanged
leads to.But neither combinator causes apt's output to not be displayed, which is what I thought we were talking about.
My original goal was to have
Apt.buildDep
return NoChange if the build deps are already installed. As a welcome but unexplained side-effect, on my systemnoChangeIfUnchanged
does cause apt's output not to be displayed.I'll think about ways to combine our two combinators.
I can get what I want if I use
trivial
andchangesFile
in the way you described. So please consider adding your method as a combinator:which is okay because
trivial
is idempotent sochangeIfChanges
may be applied more than once (I've got this in my branch with a decent docstring and I've applied it toApt.buildDep
).I think that this ought to be its own combinator, rather than just a recommendation to use
trivial
andchangesFile
in such cases, because this doesn't follow the semantics oftrivial
: it's not necessarily the case that it is the same amount of work to check if the property needs to be ensured as it is to ensure it.(In this language, my
noChangeIfUnchanged
could be calledchangeOnlyIfChanges
. I agree that it's very unlikely to useful.)(Again, on my machine, applying
changeIfChanges
toApt.buildDep
magically hides apt's output if the build-deps are already installed.)The parenthesized property here is all marked trivial, so a change to f won't result in MadeChange, though a change to f' will.
The only way propellor might intercept the output of a program is if you're using the new Concurrent module. In that case it should buffer program output and display it all at once. There could potentially be a bug there that hid program output. I certianly can't reproduce changesFile hiding the output of a program:
changeIfChanges
to avoid that problem withtrivial
, and I'll try to pin down the hiding of apt's output.I had a thought about this; trivial is a code smell and adding UncheckedProperty type avoids needing to use trivial.
So, now cmdProperty, runApt, and other things that make a Property but can't really detect when it MadeChange can instead make an UncheckedProperty, and changesFile is one of the ways to convert that into a Property.
My implementation also allows applying changesFile multiple times, to detect a change to multiple files.