Saturday, September 27, 2014

fswatch 1.4.5 - Release Notes

fswatch 1.4.5 has been released.

New features and bug fixes added since v. 1.4.0 are:

  • Add custom record formats.
  • Localize fswatch and libfswatch using GNU gettext.
  • Add Italian (it) localization.
  • Add Spanish (es) localization.
  • Fix Makefile.am because of broken link when DESTDIR installs are performed.
  • Fix bug in fswatch-run wrapper script for ZSH which caused last argument not to be split when passed to xargs.
  • Add batch marker feature to delimit the boundaries of a batch of events.
  • Add Texinfo documentation.
  • libfswatch API is now versioned.
  • Improved Autoconf checks.
  • The inotify monitor now waits for events and honours the latency settings.
  • Automaticaly generate the ChangeLog using Git.
  • Update autogen.sh to honour some commonly used environment variables.
  • The inotify monitor now provides the same functionality provided by all the other monitors.
  • Recursive directory monitoring is now implemented.
  • Version and revision is now determined dynamically from Git by ancillary scripts invoked by the GNU Build System.
  • fswatch does not compile on OS X < 10.9 because some required C++11 classes are not supported by the C++ runtime.
  • fswatch does not compile on OS X < 10.9 because some required C++11 classes are not supported by the C++ runtime.
  • The libfswatch library has been added with bindings for C and C++.
  • fswatch let users specify the monitor to use by name.

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.

Friday, June 20, 2014

Installing Logstash v 1.4 (and Greater) on FreeBSD

In a previous post I described how to install Logstash (v. 1.3 and previous) on FreeBSD and in this post I will describe how to install Logstash v. 1.4 and greater.

Until version 1.3 included, Logstash was distributed as a single JAR file, and when version 1.4 was released a new packaging style was introduced. As a consequence, new instructions are required to properly setup Logstash in FreeBSD and registering it as a service. Further information about the new    distribution layout can be found in the Logstash release notes.

As seen in the previous post, a Logstash FreeBSD port exists, but it is currently outdated since it bundles Logstash v. 1.2. But while this could be used as a starting point for JAR-based Logstash installations (as we have seen, the update process only required updating the Logstash JAR), this is not possible with the new Logstash distribution because the included rc script will fail to work.

Skimming through the original post is recommended because it provides general information about Logstash and FreeBSD which is required to properly plan and execute a Logstash setup.

Prerequisites

The essential prerequisites required to execute Logstash are:
The former is required because LogStash is a JRuby application while the latter, although not technically a requirement, is the recommended output for Logstash.

Installing Java

To install OpenJDK on FreeBSD you can use pkg to install a ready-to-use binary package:

# pkg install openjdk

Currently, this command will install an instance of OpenJDK v. 7 in both FreeBSD 9 and 10. If you'd rather install a different version, you can search the available packages and pick the one you prefer (command output has been filtered for brevity):

# pkg search openjdk
openjdk-7.60.19,1
openjdk6-b31_3,1
openjdk8-8.5.13_7
# pkg install openjdk8-8.5.13_7

Installing ElasticSearch

Logstash includes an embedded ElasticSearch instance you can use for standalone installations (see my previous post for an introductory view on Logstash operation modes). The required configuration to bootstrap the embedded ElasticSearch instance and to have Logstash use it as its outputs is described in the following sections.

Although simpler from the standpoint of the configuration, Logstash installations using separate ElasticSearch instances are out of the scope of this post.

Installing Logstash

Logstash installation procedure is fairly simple since it is distributed as a tarball:
  • Download Logstash from the official website.
  • Extract the tarball in the designated installation directory (my personal suggestion is to avoid /usr/local because it is used by ports and to use /opt instead).

Creating an rc.d Script

An rc.d script is required in a BSD system to register a service, define its configuration and have the rc framework manage its lifetime. The following script can be used as is or as a starting point to customise your own. If used as is, be aware that the script uses the following default values:
  • Installation directory: ${logstash14_home="/opt/logstash-1.4.1"}
  • Configuration file path: ${logstash14_config="/usr/local/etc/${name}/${name}.conf"}
  • ElasticSearch data directory: ${logstash14_elastic_datadir="/var/db/logstash14"}
  • Java home: ${logstash14_java_home="/usr/local/openjdk6"}
You can override any of the supported configuration values in the /etc/rc.conf file. If, for example, you want to use an alternate Java home path, just add the following line to /etc/rc.conf setting the desired value:

logstash14_java_home="/usr/local/openjdk7"

Testing the Service

To test the Logstash service, the following command can be used:

# service logstash14 onestart

To stop it, use:

# service logstash14 onestop

To help troubleshooting any problem you might find you can enable the Logstash log, setting the logstash14_log variable to YES in the /etc/rc.conf file:

logstash14_log="YES"

The log file location is specified by the logstash14_log_file variable, whose default value is set by the service rc file (only the relevant lines are shown):

name=logstash14
logdir="/var/log"
: ${logstash14_log_file="${logdir}/${name}.log"}

The log file location can be overridden setting the logstash14_log_file variable in the /etc/rc.conf file.

Enabling the Service

Note that the rc script described above does not enable the Logstash service:

: ${logstash14_enable="NO"}

If everything works, you can enable the Logstash service just adding the following line to /etc/rc.conf:

logstash14_enable="YES"