A bug in RPM ? ( for rubygem-sprockets and rubygem-tilt )
I packaged Rails 3.1.0 and its dependencies few days back for Fedora 16. The repository configuration file is as below:
[rails3] name=rails3 baseurl=http://tuxdna.fedorapeople.org/packaging/rubygems/f16/ enabled=1 gpgcheck=0
Now when I installed Rails 3.1.0, I got into a in issue:
$ sudo yum install rubygem-rails-3.1.0
...OUTPUT SKIPPED...
--> Running transaction check
---> Package rubygem-polyglot.noarch 0:0.3.3-1.fc16 will be installed
---> Package rubygem-sprockets.noarch 0:2.0.3-1.fc16 will be installed
--> Processing Dependency: rubygem(tilt) < 1.3.0 for package: rubygem-sprockets-2.0.3-1.fc16.noarch
--> Finished Dependency Resolution
Error: Package: rubygem-sprockets-2.0.3-1.fc16.noarch (psb)
Requires: rubygem(tilt) < 1.3.0
Installed: rubygem-tilt-1.3.3-1.fc16.noarch (@psb)
rubygem(tilt) = 1.3.3
Available: rubygem-tilt-1.3.2-1.fc16.noarch (fedora)
rubygem(tilt) = 1.3.2
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest
On the surface it seems that rubygem-sprockets wants rubygem-tilt with a version less than 1.3.0 ( we have only 1.3.3 and 1.3.2 available here). However rubygem-sprockets also accepts rubygem-tilt with a version greater than 1.3.0, which is evident from the dependency list:
$ sudo yum deplist rubygem-sprockets-2.0.3-1.fc16.noarch Loaded plugins: auto-update-debuginfo, langpacks, presto, refresh-packagekit Finding dependencies: package: rubygem-sprockets.noarch 2.0.3-1.fc16 ...OUTPUT SKIPPED... dependency: rubygem(tilt) >= 1.1 provider: rubygem-tilt.noarch 1.3.3-1.fc16 dependency: rubygem(tilt) > 1.3.0 provider: rubygem-tilt.noarch 1.3.3-1.fc16 dependency: rubygem(tilt) < 1.3.0 Unsatisfied dependency dependency: rubygem(tilt) < 2 provider: rubygem-tilt.noarch 1.3.3-1.fc16
To verify that it is actually a problem specific to RPM, I downloaded the RPMs and tried installing with rpm command rather than yum:
$ yumdownloader rubygem-tilt-1.3.3-1.fc16.noarch $ yumdownloader rubygem-sprockets-2.0.3-1.fc16.noarch $ ls rubygem-sprockets-2.0.3-1.fc16.noarch.rpm rubygem-tilt-1.3.3-1.fc16.noarch.rpm $ sudo rpm -i rubygem-sprockets-2.0.3-1.fc16.noarch.rpm error: Failed dependencies: rubygem(hike) >= 1.2 is needed by rubygem-sprockets-2.0.3-1.fc16.noarch rubygem(hike) < 2 is needed by rubygem-sprockets-2.0.3-1.fc16.noarch rubygem(tilt) < 1.3.0 is needed by rubygem-sprockets-2.0.3-1.fc16.noarch
Cleary RPM doesn’t handle package version intervals well even though the information is available inside the package – rubygem-sprockets requires
rubygem-tilt: >= 1.1, < 1.3.0, > 1.3.0, < 2.0.0
I have RPM version 4.9.1.2 running on Linux 3.2.7-1.fc16.x86_64.
Steven 7:11 pm on March 5, 2012 Permalink |
I’ve never created an RPM before but it appears obvoius to me that you’ve given RPM an unwinnable condition.
How is it reasonably supposed to find rubygem-tilt 1.3.0. That logically doesn’t make any sense.
Steven 7:13 pm on March 5, 2012 Permalink |
You’re commenting system broke my last comment. Text magically disappeared from it. I think its the HTML. Why HTML, why?
How is it reasonably supposed to find rubygem-tilt greater than 1.3.0 and less than 1.3.0 at the same time?
tuxdna 7:32 pm on March 5, 2012 Permalink |
@Steven:
The Ruby Gem sprockets doesn’t work with tilt version 1.3.0, which is specified as “tilt”, ["~> 1.1", "!= 1.3.0"] in the gem specification https://github.com/sstephenson/sprockets/blob/master/sprockets.gemspec#L16
There is no equivalent of != of gem specification file in RPM specification file. Hence the less than and greater than. It simply says that, any version of tilt [ from 1.1 to less than 1.3.0 ] or [ greater than 1.3.0 and less than 2.0] is accepted.
RPM doesn’t treat it well.
Steven 7:58 pm on March 5, 2012 Permalink |
The real issue then is there should be != . You can’t enter in a condition like that and expect a reasonable result from any package manager.
tuxdna 8:18 pm on March 5, 2012 Permalink
I agree that there should be a != for RPM specfile. However != in a sequence would mean less than and greater than. That is a valid way to specify !=.
What do you think is a solution to this problem?
Steven 9:05 pm on March 5, 2012 Permalink
Let me re-state I’ve written an RPM spec before.
I would start with this:
rubygem-tilt: >= 1.1, < 2.0.0
And then, looking at the documentation, I would simply add version 1.3.0 as a conflict:
http://www.rpm.org/max-rpm/s1-rpm-depend-manual-dependencies.html#S2-RPM-DEPEND-CONFLICTS-TAG
Steven 9:06 pm on March 5, 2012 Permalink
Sorry, NEVER written an RPM spec file before.
tuxdna 7:19 pm on March 7, 2012 Permalink |
@Steven:
I checked that adding following line in RPM spec file fixes the issue:
Conflicts: rubygem(tilt) = 1.3.0
Thanks for the pointer.
However, I still feel that RPM should be able to handle the case when version specified are non continuous. Maybe there is some reason its not there, which I would like to know.
For example there is a proposal for similar problem in Maven:
http://docs.codehaus.org/display/MAVEN/Dependency+Mediation+and+Conflict+Resolution
Matt Rose 12:53 pm on March 6, 2012 Permalink |
That’s not a bug in RPM, that’s a bug in gem2rpm. Gem2rpm should be parsing the versions as Steven described. As it is gem2rpm is building an uninstallable rpm
tuxdna 7:21 pm on March 7, 2012 Permalink |
@Matt:
I disagree, as my viewpoint is different for this problem. Please check my comment above.
( or the link below )
http://tuxdna.wordpress.com/2012/03/05/a-bug-in-rpm-for-rubygem-sprockets-and-rubygem-tilt/#comment-1101
Steven Oliver 8:22 pm on March 7, 2012 Permalink
I think Matt’s right here. This root of this is mathematics more than computer science. Your original line in the RPM spec said that:
1.3 1.3
You only have to have an elementary understanding of math to see why that’s not possible. It’s also no coincident that’s why “” is used as the “not equal” symbol in some programming languages.
If I maintained RPM I would argue that the given tools are sufficient enough to not warrant any changes. Especially in a package like this. Changing the dependency syntax here would possibly require thousands of files to be updated.
The proposed system you pointed out for Maven looks nice, but it also looks overly complicated.