-
Notifications
You must be signed in to change notification settings - Fork 367
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
Add "local_generator" #2734
Add "local_generator" #2734
Conversation
I have to say, there's beauty to the simplicity of this. Would be even simpler if the new generator was added as the last thing to the array I think. Subject to name-bikeshedding of course. "local_generator" is not a bad for what it is, but my head keeps coming up with spec_somethings instead (and then rejecting) 😅 |
That is an option. Will look at it tomorrow
This is the hardest think, right :( |
And that is why I have also considered the |
The name should imply this is a per-spec thing, so I don't think "find" is good. "local" is much better, but in rpm context I tend to associate that with "this host" rather than per package. "spec" seems accurate, because it is a per-spec thing. But then that makes me think of dependencies of the spec itself. Which may even be a thing one day (technically, they do have parse-requirements which often is different from build-requirements). How about just "package"? (%__package_requires, %__package_provides etc). That seems very much to the point too: these are specific to this package. |
Hmm, but just "package" kinda gives the idea that these are the only dependencies this package will have, which is not the case. "package_local" maybe? |
8a532b2
to
61bd40a
Compare
Done. On top of that, I have also added a test case. The other generator abuses I have still left the |
build/rpmfc.c
Outdated
char *bn = basename(files[i]); | ||
bn[strlen(bn)-strlen(".attr")] = '\0'; | ||
fc->atypes[i] = rpmfcAttrNew(bn); | ||
} | ||
fc->atypes[nattrs - 1] = rpmfcAttrNew("local_generator"); |
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.
The nfiles
could be used here instead, but I am not sure it would make the code more readable.
If |
This is good point. Not sure if this is real problem though.
I have proposed this earlier in #782 (comment) and put this idea into practice for Fedora. I have no preference. I just wanted to move this forward a bit ;) now I stand by waiting for guidance (i.e. the right implementation and the acceptable name). |
OK, just hard coding one file attribute doesn't seem like a good idea. I added a macro that allows you to register an arbitrary number of local file attributes and generators. I am still wondering if we need a mechanism to avoid executing generators twice when the package is already installed while a new version is building. May be we should use the original name and over write the locally installed configuration. This would be pretty simple to do I guess by just checking the list of previously loaded file attributes. |
tests/rpmbuild.at
Outdated
@@ -866,6 +866,7 @@ RPMTEST_CHECK([ | |||
RPMDB_INIT | |||
|
|||
runroot rpmbuild -bb --quiet \ | |||
--define '__local_file_attrs local_generator' \ |
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.
While this is "just test case", maybe the local_generator
could use different name, just to avoid the impression that the local
is somehow mandatory in the latter
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.
Maybe something like totally_random_generator_name
Nice, now we can argue if the Nevertheless, thx for contributing. I see your point. OTOH, if I read your commit correctly, my original proposal had the advantage, where one could count with convention over configuration. IOW with your changes one additional line is needed to make this work. |
On the second thought, maybe it really is the right way. I am coming from place where no "local" generator us was possible, so one was already great improvement. But maybe there are use cases for multiple generators? OTOH, one could call them via some helper script or by chaining them (in the worst case by executing |
Hmm, I guess we are taking about two different use cases. You are thinking about a dependency generator that is in the package only and not installed ever. For that you want a unique name that won't ever clash with installed file attributes. I am thinking about actually shipping the dependency generator but also using it in the package itself. For that you need to make sure that it is only run once during the build - even if the package is actually installed in the system building the package. The you'd want the names to be the same and RPM should overwrite the installed one with the one in the package. I guess we do want both use cases to work. |
This ^^ actually is my use case and here is how it looks in practice: https://src.fedoraproject.org/rpms/ruby/blob/308b2c0ab2c6268847ed3bf2008e74bce334e810/f/ruby.spec#_187-190 Saying all these, it makes me realize that in theory, if the Not sure. In reality, having Ruby installed during build of Ruby is problematic for different reasons, so I don't have to be worried in this case.
Do I? I don't think there is currently anything, which would prevent one generator running twice. E.g. if there are multiple Actually, from this POV, my original PR (making the Nevertheless, let me be clear that I am not really arguing for or against of any of those variant. Both versions are acceptable. But it is good to understand all the corner cases 👍 |
I think the issues is reproducibility and correctness. If you fix the dependency generator in your package you don't want to old - possibly broken - deps still in your package, just because the old package is still on your build system. |
That is actually good point. So in the Ruby case, it would actually make sense to override the
Actually, this leads me to another silly idea. Maybe the |
OK, just to write down how the current system works: The RPM goes through the list of file attrs (currently from globbing the The has the disadvantage that when e.g. a |
OK, I replaced the word "local" as its meaning is just too vague here. "Packaged" discourages using file attributes that are just on the machine without being shipped or being installed from another package. While this is technically possible this is something we clearly don't want to encourage. These patches still need to be squashed and a combined commit message be added. I'll leave them separate for now to make it easier to review the last few changes on their own. |
Normally file attributes and their dependency generators are shipped in separate packages that need to be installed before the package making use of them can be build. | ||
|
||
Since rpm 4.20 the names of file attribute shipped with the package can be put into the *__packaged_file_attrs* macro separated by colons (:). The macros that normally go into the *\*.attr* files still need to be defined (the dependency generators typically pointing to some Source files or some files in the install root). | ||
|
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 think that example would be useful here. Also the following paragraph is not very tangible without example.
|
I find
Back to bike-shedding. |
|
I think the issue here that they can be both overriding existing ones or being an add-on. This makes it difficult to find a good name that covers both cases. OK, technically the macro doesn't override existing file attrs. Overriding/defining the macros does. So here we are registering file attr names... This all makes |
|
Indeed. It's sufficiently vague to cover both cases we care about, and totally accurate in the sense that its local to the build.
I can live with either local or add. There are bigger crisis in the world 😆 |
57334a2
to
5ff3074
Compare
Ok, renamed back to |
build/rpmfc.c
Outdated
// skip file attrs found in __local_file_attrs for now | ||
for (j=0; (j < nlocals) && strcmp(bn, local_attrs[j]); j++); | ||
if (j < nlocals) { | ||
free(bn); |
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 is not right, basename() doesn't allocate, so this would free some random pointer inside an allocation.
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.
Might be more readable to just toss all basenames into a new argv with argvAddUniq() , which frees us from having to care about these details here and allows doing rpmfcAttrNew()'s from a single loop.
build/rpmfc.c
Outdated
for (int i = 0; i < nfiles; i++) { | ||
char *bn = basename(files[i]); | ||
bn[strlen(bn)-strlen(".attr")] = '\0'; | ||
// skip file attrs found in __local_file_attrs for now |
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.
/* */ comments, thanks.
runroot rpmbuild -bb --quiet \ | ||
--define '__local_file_attrs my_test_attr' \ | ||
--define '__my_test_attr_provides() foo(%{basename:%{1}})' \ | ||
--define '__my_test_attr_path .*' \ |
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 covers on of the use-cases, but the excess free() in the code kinda proves that we need a test for the other scenario too where there's a pre-existing attr by the same name.
One more thing wrt the macro name: I wonder if this is a case where it should not have those leading underscores. The generator itself is full of double underscore names, but the newly added macro here is something directly intended for packager use in a spec. I dunno, it may even be more confusing to have one of the macros without them 😅 |
tests/rpmbuild.at
Outdated
RPMDB_INIT | ||
|
||
runroot rpmbuild -bb --quiet \ | ||
--define '__local_file_attrs my_test_attr' \ |
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.
If this covered multiple generators to demonstrate that something like this is supported, that would be even better
May be someone(tm) should write down the policy regarding underscores. May be in a RPM Design Philosophy document... But I agree that there should probably be less underscores. |
ab3a293
to
7c64e73
Compare
OK, removed one underscore from the macro name, rewrite the init code and added two test cases that deal with already installed file attributes. |
build/rpmfc.c
Outdated
for (int i = 0; i < nfiles; i++) { | ||
char *bn = basename(files[i]); | ||
bn[strlen(bn)-strlen(".attr")] = '\0'; | ||
argvAddUniq(&all_attrs, bn); |
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.
The files coming out of rpmGlob() are unique already, you don't need argvAddUniq() here. What I meant is that you could simply use the argv coming from rpmGlob() (the .attr is already getting stripped out) and argvAddUniq() the local stuff to that.
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.
Yes, but they are file names and not just attribute names. An while they are unique because we hard coded the glob, making the location configurable may turn up the same names from different locations. That's why I made the code a bit more defensive than it needs to be. Also I don't even want to think what rpmGlob returns if it doesn't find anything. Overall I don't think this is going to get that much simpler in the end.
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.
Doh, I was somehow thinking rpmGlob() returned basenames there but, but (of course) it doesn't. So scratch that part, sorry.
The location is configurable but it's still always just a single directory, it cannot possibly have multiple files by the same name. It's not that argvAddUniq() is wrong, it just gives the reader the wrong impression basically. Similarly moving this .attr splitting loop out of the rpmGlob() if-block seems strange, because there's only ever anything to do on rpmGlob() success. So that's kinda backwards to what you say about not wanting to think about the case where it doesn't find anything because that's already handled, and just obfuscates the diff for no good reason. It's always better to let the actual change stand out in the diff when reasonably possible.
This is the actual change to the first part here. nattr gets recalculated later on, but most of the time it's already correct from here:
/* Discover known attributes from pathnames + initialize them */
if (rpmGlob(attrPath, NULL, &files) == 0) {
nattrs = argvCount(files);
- fc->atypes = xcalloc(nattrs + 1, sizeof(*fc->atypes));
for (int i = 0; i < nattrs; i++) {
char *bn = basename(files[i]);
bn[strlen(bn)-strlen(".attr")] = '\0';
- fc->atypes[i] = rpmfcAttrNew(bn);
+ argvAdd(&all_attrs, bn);
}
- fc->atypes[nattrs] = NULL;
argvFree(files);
}
+
+ /* Get file attributes from _local_file_attrs macro */
+ /* ... /
(actually one could just pass &nattrs to rpmGlob() and avoid the argvCount(), but that too would kinda obfuscate the diff)
Patch cleanliness aside, this all needs to be just one commit. It's a single new feature with its tests, we are not interested in PR review in the commit history.
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.
Sure. There also is a "squash and merge" button somewhere down there...
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 realised the really right way to do this is to refactor the discovery/init split to a separate commit, and then the local_attr thing doesn't need to change anything at all, only add itself.
Having asked this to be one commit already I couldn't very well ask you to do this, so here goes: #2911
e1dea8e
to
95b89b6
Compare
This can declare file attributes which details can be defined in the spec file. This allows enabling file attributes and their dependency generators even if they are only shipped in the package itself and are not yet installed. The names need to be separated by colons (:). Co-authored-by: Florian Festi <[email protected]> Resolves: rpm-software-management#782
95b89b6
to
805d831
Compare
Merged as #2911 |
This generator can be used by .spec file, which ships their own generators:
Resolves #782