This page describes Ruby language and Ruby gem ports, package management and infrastructure in FreeBSD.
How to commit for ruby@?
More to come for this, but one of the key things to remember is that when you update a gem, you must at least build all the things that depend on it. Also note that gems can be patched using normal patch files now, which is sometimes useful for updating versions of dependencies.
You can find ruby@ people on EFNet and Libera Chat IRC. There is now a #rubyports on EFNet. Feel free to connect and ask questions or discuss ruby ports on FreeBSD.
Gem packaging FAQ
Why does the FreeBSD community package gems? Can't you just use bundler?
All users, including both end users of classic applications, and system administrators who will install web applications, have different needs. One of the goals of Ports is to build some packages that can be used to either build from ports or simply pkg install. Gem is also essentially a package manager. Some prefer not to use one packaging system for installing their web server and another for installing the web application they run in that web server (and it's dependencies), instead just using one package system for everything. Also, gems are often updated, but some prefer to always stick with known good versions of software before upgrading, so they like to have the same versions of packages all the time, even building themselves and using the same package files across many systems. Gem bundles often install compatible but slightly different versions of the same software (gem version 1.1.1 vs gem version 1.1.2, for example).
Properly and securely building software packages does create some restrictions. For example, when packages are built, the build can only download software during the "fetch" phase of ports building. Fetch during patch, build, install, etc. are not allowed. There are good reasons for that of course, but it adds some complexity. This conflicts in some sense with gem which fetchs, builds and installs all in one step.
Another part of the reason we package gems is that it simplifies things. A user can simply "pkg install redmine" and, baring any bugs and local config, have a working redmine install. This will include the redmine software, it's gem dependencies, the web server, any ImageMagick dependencies that might exist, etc. Contrast this with using the pkg to install just the web server and ImageMagick software, then using bundler to install gems and redmine.
Ports could perhaps be setup to call bundler, but this would complicate the package building, particularly where one package shares dependencies with another. And this would really violate the packaging requirements as well.
Why do you patch gems?
There are many reasons gems get patched. Sometimes it's due to compile time issues, for those gems which contain C extensions. Other times, it's just adding special cases for things related to FreeBSD, such as system related gems. We always strive to work with upstream developers on all local patches.
One of the most common reasons gems are patched in ports is changing version requirements of dependencies. Ports doesn't support installing multiple versions of the same package as easily as gem, yet some ports depend on the same gem but different versions of it. For example:
Port X depends on gem XYZ version ~> 1.0.1
Port Y depends on gem XYZ version ~> 1.1.1
This creates a conflict in ports or creates extra work creating a port for both 1.0.1 and 1.1.1. (This happens because gem and ruby software authors follow the default pessimistic version constraints shown on rubygems.org which suggests depending on the exact patch versions of a gem. We're referring here to the suggested depend line like:
gem "XYZ", "~> 1.0.1"
This overly strict dependency version requirement isn't necessary as long as gems are following semantic versioning. So often in order to avoid extra work, we patch things to use less restrictive versions of dependencies. Simply changing to requirement to 1.1 makes life easier for everyone and almost always works properly.
- Sometimes, due to pessimistic version constraints, a port will depend on a version of a gem that is not the latest. These are typically named "category/rubygem-gemnameXY".
- The port of the same gem called "category/rubygem-gemname" should always reflect the latest version (e.g. on rubygems.org). (An exception to this rule was made for rails 4.x because many things still are not ready for rails 4.x and because it would have been too much work to create all the older version ports.)
When these older version ports are required, make sure they are the least specific possible. For example, if gemname 3.2.1 is the latest, and something depends on gemname 2.2.x ("~> 2.2.1"), then category/rubygem-gemname22 should be created. But if the dependency on the older version is on 2.x ("~> 2.2"), then the port should be category/rubygem-gemname2. This ensure that the latest version possible can be used. Also, be sure to add a PORTSCOUT line in the older port dir.
- Be sure to add a PKGNAMESUFFIX to the older version port so that it doesn't break INDEX. PKGNAME should correspond to the directory name in the portstree. For example, category/rubygem-gemname2 should have PKGNAMESUFFIX=2
- Be sure to delete older verions of gems that are no longer needed.
- If there are multiple ports that could satisfy a dep and you need it, create a port which specifies the version you need. For example, if a port could depend on the rails 3.x or rails 4.x version of a dep, create two ports and suffix the less-used port (e.g. -rails4). This should only be done when needed and be sure to remove them when no longer needed.