Thursday, August 21, 2014

fswatch 1.4.0 - Release Notes

fswatch 1.4.0 has been released bringing few but important updates:
  • Monitor implementations are found at runtime so no more hardcoded options to choose a specific monitor (the plugging mechanism still needs improvements).
  • The fswatch engine has been moved to a separate library called libfswatch with bindings for C and C++. If you need to use the functionality of fswatch from your program, now it's very easy to do. The library and its headers are distributed in the same fswatch bundle.
  • On OS X fswatch can now be installed from either MacPorts and Homebrew (see README for more information).

I hope you enjoy using fswatch as much as I enjoy writing it.

Tuesday, August 19, 2014

Writing a MacPorts Portfile (and Testing It on a Local Repository)

As a MacPorts user, it is maybe funny that fswatch is available on Homebrew and not on MacPorts. Today I put an end to this idiosyncrasy of mine and submitted my first MacPorts port file.

I was pleasantly surprised to discover that, although a deceiving initial impression, setting up my first port file was way easier than I first believed. Furthermore, the MacPorts guys have been very supportive and provided many insights that helped me improve the port file and my understanding of the MacPorts port system (beyond what is described in the nice MacPorts Guide).

The Basic Portfile

The basic Portfile for a source tarball generated by the GNU Build System, that is a package which is built and installed with the now classic:

$ ./configure
$ make
$ make install

is typically very simple, since these two operations are performed out of the box by the Configure, Build and Destroot phases of a port installation life cycle.

In this case, the basic Portfile includes:
  • The modeline (optional).
  • The Subversion ID tag: placeholder string automatically expanded by the MacPorts infrastructure.
  • The PortSystem line: required by all ports.
  • The port name and version: many other port variables (including the source tarball name) depend on these values.
  • The category line: one or more port categories.
  • The platform: darwin most of the times.
  • The maintainers.
  • The short and long description.
  • The homepage.
  • The download URLs.
  • The checksums (used to verify the integrity of the downloaded files).
  • The dependencies (optional).
  • The configure arguments (optional).
A fully working, basic port is the following:

In this example you can see how the download URL is split in two pieces: the master_sites and the distfiles (or distnames). The rationale behind this choice is the fact that a package may typically be hosted by multiple master sites (such as mirrors).

In this example, distfiles is specified. This variable contains the full distribution file name, including the suffix (the file extension). By default this value is set to ${distname}${extract.suffix}. You may as well define the distname (which defaults to ${name}-${version}) and the extract.suffix separately. These parameters, in the example above, are redundant, since they simply set the corresponding default value (and use_zip is used as a shortcut to set extract.suffix and other variables related to processing zip files).

A Portfile for a GitHub-Hosted Project

fswatch, such as many other projects nowadays, is hosted at GitHub.  Although not yet documented on the MacPorts Guide, a recently added PortGroup called github greatly simplifies  the Portfile for such projects. The only existing documentation, at the moment, is this port group source code.

Many of the aforementioned configuration variables are inferred by a much simpler GitHub configuration such as:

github.setup        emcrisostomo fswatch 1.3.9
github.tarball_from releases

This expands to:
  • name is set as the GitHub project name (fswatch in this case).
  • version is set as the GitHub version tag (1.3.9 in this case).
  • The download URL and the distribution file name is inferred from the repository configuration and the corresponding release URL. If the distribution file name is different than the default (${name}-${version}) then you still have to configure it as described in the previous section.
The resulting Portfile is the following:


Checking Your Portfile

The port utility can check whether a Portfile conforms to the MacPorts guidelines using the lint command:

$ port lint --nitpick fswatch
--->  Verifying Portfile for fswatch
--->  0 errors and 0 warnings found.

In the example above the fswatch Portfile passes verification with no errors nor warnings. Be sure to check your Portfile before submitting it to the MacPorts repository.

Testing Your Portfile With a Local Repository

You can test and store your Portfiles in a local repository before submitting them to a public repository in a private repository. Furthermore, you can take advantage of the MacPorts package management features to maintain your own local packages.

Adding a Portfile to a local repository is very simple:
  • Create the local repository directory somewhere (if it does not exist).
  • Create a subdirectory (if it does not exist) named after the primary category of the port you are adding.
  • Create a subdirectory named after the port.
  • Move the Portfile into this directory.
  • Make sure the user macports has sufficient privileges to read the repository (I usually give him ownership of the port directory).
  • Update the port repository indexes running portindex from the repository root.

If you have not done it yet, you have to configure MacPorts to use your local repository, adding a line in $MACPORTS_HOME/etc/macports/sources.conf:

file:///ports

right above any other repository so that ports in the local one take precedence over ports in the public repository.

If everything is setup correctly, you will be able to query and install ports from your local repository.

Further Readings

A basic Portfile such as what I described in this blog post is just the beginning: we only scratched the surface of what MacPorts can offer you. If you want to get further information about MacPorts and the facilities it provides (either from an user or a developer standpoint), start from the MacPorts Guide.

Public Domain Flags Archive (in Vector Image Format)

Some time ago, when I was implementing the EMCCountryPickerController component I described in some earlier posts (such as this one), I soon realised I needed high quality images of the flags of all the countries listed in the ISO 3166-1 standard. And since the EMCCountryPickerController library is GPL-licensed, I needed images whose license was compatible with it in order to distribute them together with the component.

I found decent collections of flags in the internet but at the end I decided to build my own, especially in order to overcome problems that arose from the limited resolution of many image collections.

I picked the flags from Wikimedia Commons since they're available in SVG format (a widely used vector image format). This way, if I need to, I can render a flag at any resolution.

I then assembled a GitHub repository where you can find:
  • All the flags in SVG format.
  • All the flags in PNG format scaled to a width of 256 pixels.
  • All the flags in PNG format, scaled to a width of 512 pixels.

The following is a shell script that can be used to render the flags archive at the desired widths.

The script requires librsvg to be installed.