<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>HyperThunk</title>
	<atom:link href="http://hyperthunk.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://hyperthunk.wordpress.com</link>
	<description></description>
	<lastBuildDate>Fri, 30 Dec 2011 02:14:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='hyperthunk.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>HyperThunk</title>
		<link>http://hyperthunk.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://hyperthunk.wordpress.com/osd.xml" title="HyperThunk" />
	<atom:link rel='hub' href='http://hyperthunk.wordpress.com/?pushpress=hub'/>
		<item>
		<title>rebar plugins tutorial is moving</title>
		<link>http://hyperthunk.wordpress.com/2011/12/30/rebar-plugins-tutorial-is-moving/</link>
		<comments>http://hyperthunk.wordpress.com/2011/12/30/rebar-plugins-tutorial-is-moving/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 01:23:03 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=321</guid>
		<description><![CDATA[I&#8217;ve been wanting to spend some time checking out Octopress, and the series on rebar plugins provides me with a good opportunity to do this. Instead of spending my free time writing up a second post this week, I&#8217;ve opted to move the series to a custom location and use Octopress as a publishing engine. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=321&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been wanting to spend some time checking out Octopress, and the series on rebar plugins provides me with a good opportunity to do this. Instead of spending my free time writing up a second post this week, I&#8217;ve opted to move the series to a custom location and use Octopress as a publishing engine.</p>
<p>My reasons for doing this are several. Firstly, as I mentioned, I wanted a chance to check out the Octopress wrap around Jekyll, and I must admit that so far I&#8217;m finding it nice and high level. Secondly, I wanted better handling of code highlighting than the free wordpress account gives me, and the pygments integration in Jekyll does the job very nicely. I also wanted to be able to provide sample code for each of the posts, and by publishing the series using github pages, I can use a single git repository to manage both the sample code and the gh-pages publication branch. All in all, it seems like a pretty neat solution.</p>
<p>From now on, rebar plugin tutorials will be published to http://hyperthunk.github.com/rebar-plugin-tutorial/.  </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/321/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=321&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2011/12/30/rebar-plugins-tutorial-is-moving/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
		<item>
		<title>rebar plugins &#8211; customising your build</title>
		<link>http://hyperthunk.wordpress.com/2011/12/26/rebar-plugins-customising-your-build/</link>
		<comments>http://hyperthunk.wordpress.com/2011/12/26/rebar-plugins-customising-your-build/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 22:55:24 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[builds]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[rebar]]></category>
		<category><![CDATA[extensibility]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=276</guid>
		<description><![CDATA[This is the first post in a series on customising rebar using plugins. Initially, I want to focus on how plugins work, then move on to see what kind of extensibility they can provide to developers. Caveats There are so many caveats to this, I hardly know where to start. Here&#8217;s a short-list to begin [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=276&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is the first post in a series on customising <a href="http://github.com/basho/rebar">rebar</a> using plugins. Initially, I want to focus on <em>how </em>plugins work, then move on to see what kind of extensibility they can provide to developers.</p>
<h2>Caveats</h2>
<p>There are so many caveats to this, I hardly know where to start. Here&#8217;s a short-list to begin with:</p>
<ol>
<li>What&#8217;s written here is based on my experience and could be lacking important detail, or even plain wrong!</li>
<li>Rebar&#8217;s support for plugins may disappear at any time in the future, as they&#8217;re not a fully documented or official feature AFAIK &#8211; though this probably isn&#8217;t likely in practise, it is possible</li>
<li>Rebar has no official API for plugins, so their use is at best undocumented, and in all cases probably completely unsupported &#8211; you will find friends on the mailing list though, I&#8217;m sure</li>
</ol>
<p>I&#8217;ve written quite a few plugins by now, and have even submitted a few patches relating to them. It&#8217;s fair to say that I&#8217;m quite opinionated about how plugins work and how they should work, but it&#8217;s also worth remembering that I&#8217;m only a very minor contributor and my opinions are just that &#8211; my private opinions.</p>
<h2>First things first</h2>
<p>Currently <a href="http://github.com/basho/rebar">rebar</a> supports two kinds of extensibility mechanism: Plugin Extensions and Hooks. Hooks are a <em>lightly</em> documented feature, with the only real explanation being the <a href="https://github.com/basho/rebar/blob/master/rebar.config.sample#L142">sample rebar config file</a>. We&#8217;re not going to cover hooks in much detail, as they are simple enough to understand and are only really applicable to simple scripting tasks that don&#8217;t require, for example, cross platform support or complex logic. Plugin extensions on the other hand, are <a href="https://github.com/basho/rebar/wiki/Extending-rebar">documented</a> (to some extend anyway), and provide a much greater degree of extensibility to developers.</p>
<p>Before we can talk sensibly about plugins, we need to take a look at some of the fundamentals behind rebar, especially its handling of build configuration files and processing of commands. For any given command, say <em>foo</em>, rebar <em>understands </em>the command if (and only if) <em>one of the modules it</em> <em>knows about</em> exports a function with a signature that matches:</p>
<ol>
<li>the name of the command and arity 2</li>
<li>the name of the command prefixed with <em>pre_,</em> and arity 2</li>
<li>the name of the command prefixed with <em>post_, and arity 2</em></li>
</ol>
<p>We&#8217;ll be covering how rebar <em>knows about</em> modules later on, but for now we&#8217;ll just assume it&#8217;s magic. For the command <em>foo</em> to have any meaning then, we&#8217;d need at least one module with at least one of the following signatures exported:</p>
<div class="highlight" style="background:#f8f8f8;">
<pre style="line-height:125%;">-<span style="color:#999999;font-weight:bold;">module</span>(foo).
-<span style="color:#999999;font-weight:bold;">compile</span>(export_all).

<span style="color:#0000ff;">pre_foo</span>(_, _) <span style="color:#666666;">-&gt;</span>
	<span style="color:#0000ff;font-weight:bold;">io</span>:format(<span style="color:#ba2121;">"we're running just before foo!</span><span style="color:#bb6688;font-weight:bold;">~n</span><span style="color:#ba2121;">"</span>).

<span style="color:#0000ff;">foo</span>(_, _) <span style="color:#666666;">-&gt;</span>
	<span style="color:#0000ff;font-weight:bold;">io</span>:format(<span style="color:#ba2121;">"we're in foo!</span><span style="color:#bb6688;font-weight:bold;">~n</span><span style="color:#ba2121;">"</span>).

<span style="color:#0000ff;">post_foo</span>(_, _) <span style="color:#666666;">-&gt;</span>
	<span style="color:#0000ff;font-weight:bold;">io</span>:format(<span style="color:#ba2121;">"we're running just after foo!</span><span style="color:#bb6688;font-weight:bold;">~n</span><span style="color:#ba2121;">"</span>).</pre>
</div>
<p>&nbsp;&nbsp;<br />
Another essential is how rebar handles build configuration. There are four ways that rebar handles configuration settings. Firstly, rebar loads the <em>global config file</em> from <em>$HOME/.rebar/config </em>if it actually exists, otherwise it creates an empty config set. Secondly, rebar loads configurations for any directory by either (a) examining the terms in the local file <em>rebar.config</em> if it exists, or (b) creating an empty config set. Thirdly, when first executing in the current directory (known as <em>base_dir</em>), rebar will check for a special global variable (passed as <em>config= </em>or alternatively <em>-C &lt;config-name&gt; instead) </em> which overrides the name of the config file it should search in. This latter technique is only applied to the configuration in the <em>base_dir.</em></p>
<p>The fourth approach to configuration handling is not just for initialising new configurations. As rebar executes user commands (e.g., <em>clean, compile, eunit</em>) in a given directory, it uses two special commands to obtain a list of directories that need to be processed <em>before</em> the current one, and providing the current directory is processed without error, <em>afterwards</em> as well. These commands, <em>preprocess</em> and <em>postprocess</em>, can be exported by any module.</p>
<p>When rebar executes, it builds up a list of modules that <em>understand </em>the current command. For each of these modules it tries to call <em>pre</em> and <em>postprocess</em>, then it traverses any <em>pre-</em> directories before handling the current command in the current directory. Once all the pre-processing is done, each module that exports one of the three function signatures compatible with the current command is called (for one or more of the <em>pre_&lt;command&gt;/2, &lt;command&gt;/2 and post_&lt;command&gt;/2 exports)</em> to handle the actual command. The directories returned by any <em>postprocess </em>calls are handled last of all.</p>
<p>What is <em>vital</em> to understand about all of this, is that as rebar traverses the file system, recursively handling any pre- directories, in each new dir it executes with a <strong>brand new</strong> rebar config set. This config set <em>inherits</em> the parent configuration (i.e., the config set for the parent dir) but can override certain configuration variables by providing it&#8217;s own <em>rebar.config</em> file. This is how dependencies and applications stored in sub-directories are handled. The salient points about this mechanism are that</p>
<ol>
<li>the only configuration file rebar notices in sub-directories is the one named <em>rebar.config</em></li>
<li>any configuration override (passed with -C for example) is ignored in sub-directories</li>
<li>just because a local <em>rebar.config</em> overrides a variable/setting, this might not be applied</li>
</ol>
<p>Point #3 is a bit scary if you&#8217;re new to rebar, but essentially it is the result of rebar&#8217;s config handling module exporting multiple config handling functions, some of which get the local (i.e., the most locally scoped) value, some a list of possible values and others the combined list of all values. Depending on which of these functions a particular command/module uses when <em>reading </em>the configuration, you can potentially see a number of things happen:</p>
<div>
<ol>
<li>you might see the local value (from <em>rebar.config</em>) get applied</li>
<li>you might see the value from the <em>parent</em> config get applied (e.g., if there is no local config)</li>
<li>you might see the local value get ignored</li>
</ol>
<p>I strongly recommend spending some time looking at <a href="https://github.com/basho/rebar/blob/master/src/rebar_config.erl">rebar&#8217;s config module</a> if you&#8217;re planning on writing plugins (or using complex plugins written by others), as it&#8217;ll save you a lot of head scratching time if you understand this up front.</p>
</div>
<h2>What are plugins?</h2>
<p>As far as rebar is concerned, plugins are simply <a href="http://erlang.org/doc/reference_manual/modules.html">Erlang modules</a> that it knows something about. There are essentially two ways that rebar <em>knows about </em>modules:</p>
<ol>
<li>From the rebar.app configuration file</li>
<li>Via the plugins section of the build configuration</li>
</ol>
<p>Modules which are <em>registered </em>in the rebar.app configuration file are basically part of rebar itself. Plugins on the other hand, are modules which the build configuration (somewhere in the tree) knows about via the <em>plugins</em> configuration element. This configuration is built up to include every branch, including the global config, so just because you&#8217;ve got no local plugins configuration, doesn&#8217;t mean plugins won&#8217;t get run in your subdirectories. In practise, this means that plugins registered <em>up top (e.g., globally or in the base_dir configuration)</em> will get run in <em>all</em> your sub-directories, including of course dependencies. Bare this in mind when using plugins, and take advantage of <em>skip_deps, apps= and skip_apps= </em>where necessary to avoid unexpected things happening in your sub-dirs and deps folders.</p>
<p>To (hopefully) make the differences between plugin extensions and built-in modules a bit clearer, we&#8217;re going to classify plugin extensions into three groups, and will hereafter refer to them simply as <em>plugins:</em></p>
<ol>
<li>Internal/Built-in</li>
<li>External/Pre-packaged</li>
<li>Local</li>
</ol>
<p>Let&#8217;s look at what these classifications mean in practise, and hopefully get an understanding of the terminology I&#8217;ve chosen. Internal (or built-in) modules come bundled as part of rebar itself, and as per the <a href="https://github.com/basho/rebar/wiki/Extending-rebar">documentation</a>, these are <em>registered</em> in the rebar application config file. The functionality exposed by these modules is available to every rebar user, so they work Out Of The Box. These plugins are the least likely to be used for extending rebar however, because in practise they require you to either (a) maintain a custom fork of rebar or (b) submit a pull request in order for your extension(s) to be accepted as part of the main source tree. It is the other two types of plugin we will be looking at in this post.</p>
<h3>External Plugins</h3>
<p>Pre-packaged plugins are bundled as separate Erlang/OTP libraries to be installed globally, or included in a project using rebar&#8217;s dependency handling mechanism. The latter technique is more useful, as it ensures that someone who fetches your source code to build/install it, will be able to obtain the right plugins without going outside of the project source tree.</p>
<p>The key thing to understand here is that the plugin <em>must</em> be installed somehow in order for rebar to pick it up. We&#8217;ve mentioned that rebar <em>knows about</em> plugins because they&#8217;re in the {<em>plugins, ListOfPlugins}</em> configuration element, but in practise things aren&#8217;t quite that simple. In order for a plugin to actually get executed (in response to a specific command, it&#8217;s pre/post hooks or indeed the special <em>preprocess</em> and <em>postprocess</em> commands), it needs to be on the code path! This is fine if the plugin is installed globally into the user&#8217;s erl environment (for example by putting it&#8217;s application root directory somewhere on the <em>ERL_LIBS</em> environment variable), but not so fine if you&#8217;re fetching it into the project&#8217;s dependencies. If the dependency is a direct one, then <a href="https://github.com/basho/rebar/blob/master/src/rebar_deps.erl#L66">the <em>preprocess </em>handler in <em>rebar_deps</em></a> will nicely update the code path for all commands, so as long as you&#8217;re not trying to make the plugin run before rebar&#8217;s built-in modules (which is, in fact, impossible) then it&#8217;ll be on the path. This once again doesn&#8217;t always work in practise however, because the function that builds up the code path makes no attempt to deal with transitive dependencies. I keep meaning to do a pull request for this, but I&#8217;m waiting for others to get through the queue first.</p>
<h3>Local Plugins</h3>
<p>You probably recall that I mentioned plugins need to be on the code path in order to be executed by rebar? Well thanks to a nifty pull request from yours truly, there is in fact another way. If rebar cannot find a module on the code path matching the name given to the <em>plugins</em> configuration element, it will attempt to locate a source file for the module in either the <em>base_dir</em> or the directory indicated by the <em>plugin_dir</em> config element. If it finds a source file with a matching name, it attempts to compile it on the fly and load the beam code into the running emulator, thereby making the plugin available dynamically.</p>
<p>The aim of <em>local plugins</em> is to provide a mechanism for scripting complex tasks/hooks that apply only to your specific project. This is in contrast with the idea of external/pre-packaged plugins, which provide add-on re-usable features to rebar that can be used across projects.</p>
<h3>Next time&#8230;</h3>
<p>Next time we&#8217;ll be looking at the structure of the plugin callback functions and how to use them in practise. We&#8217;ll also be taking a whirlwind tour of some of the commonly (re)used rebar modules such as <em>rebar_config, rebar_utils</em> and <em>rebar_log</em>, as well as discussing some of the pros and cons of using plugins and what the current workarounds look like. We&#8217;ll finish with a working example of an external plugin that adds new functionality to rebar with all the source code available on github.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/276/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=276&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2011/12/26/rebar-plugins-customising-your-build/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
		<item>
		<title>Packaging OTP applications with the rebar-dist-plugin</title>
		<link>http://hyperthunk.wordpress.com/2011/05/26/packaging-otp-applications-with-the-rebar-dist-plugin/</link>
		<comments>http://hyperthunk.wordpress.com/2011/05/26/packaging-otp-applications-with-the-rebar-dist-plugin/#comments</comments>
		<pubDate>Thu, 26 May 2011 13:23:29 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=268</guid>
		<description><![CDATA[A good example of how rebar-plugins can add useful features to your build, the rebar-dist-plugin allows you to produce an archive for your project which can be distributed rather than forcing people to use git/mercurial/etc to obtain and build your sources. The plugin comes with some pre-defined assemblies (which are the plugin&#8217;s unit of configuration) for packaging [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=268&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A good example of how rebar-plugins can add useful features to your build, the <a href="https://github.com/hyperthunk/rebar_dist_plugin">rebar-dist-plugin</a> allows you to produce an archive for your project which can be distributed rather than forcing people to use git/mercurial/etc to obtain and build your sources.</p>
<p>The plugin comes with some pre-defined <em>assemblies</em> (which are the plugin&#8217;s unit of configuration) for packaging up a rebar generated release, or project (i.e., the ebin, include and priv directories). Future releases will add other pre-packaged options such as sources, docs and so on.</p>
<p>Using the plugin is pretty simple, and there is some documentation on the <a href="https://github.com/hyperthunk/rebar_dist_plugin/wiki">project wiki</a> which is mostly up to date.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/268/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/268/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/268/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=268&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2011/05/26/packaging-otp-applications-with-the-rebar-dist-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
		<item>
		<title>Customise your build, with rebar plugins</title>
		<link>http://hyperthunk.wordpress.com/2011/04/28/customise-your-build-with-rebar-plugins/</link>
		<comments>http://hyperthunk.wordpress.com/2011/04/28/customise-your-build-with-rebar-plugins/#comments</comments>
		<pubDate>Thu, 28 Apr 2011 12:14:43 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[rebar]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=253</guid>
		<description><![CDATA[Customise your build, with rebar plugins!<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=253&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I started playing with this today, and have come up with a sample application <a href="https://github.com/hyperthunk/rebar-frobble" target="_blank">here</a>. The basic concept behind rebar plugins is fairly simple: you refer to them in your <code>rebar.config</code> and they get <em>hooked</em> into the build at execution time. Naturally rebar (which is executed via escript) needs to be able to find the beam code for these (plugin) modules on the code path, so if you&#8217;re putting one together specifically for a project, you&#8217;ll need to take advantage of rebar&#8217;s <code>sub_dirs</code> support in order to pre-compile them before the rest of your code. The sample project does just that, by compiling the <em>build</em> project prior to the rest of the sources. Including it in your <code>lib_dirs</code> also ensures it is on the code path.</p>
<p>So what can you do with your plugins? <del datetime="2011-12-30T02:12:52+00:00">Plugins do not participate in rebar&#8217;s <em>preprocess</em> stage, so they cannot run in isolation from the core (internal) rebar modules</del> &#8211; edit: as of a while back, plugins do in fact participate in the pre and post processing via the same callbacks as built in modules. Check out some of my later posts, or better still head over to http://hyperthunk.github.com/rebar-plugin-tutorial/ for more details. </p>
<p>In practise, this means that your plugin can do one of two things:</p>
<ol>
<li>Hook into an existing command (such as &#8216;compile&#8217;), or</li>
<li>Expose a new command (such as &#8216;frobble&#8217; in the example code on github)</li>
</ol>
<p>The second approach comes with (yet more) caveats though: new, custom commands cannot run in isolation. I suspect this is because plugins do not participate in the <em>preprocess</em> stage, or that they&#8217;re excluded from the code that identified modules willing to handle a given command, or both. This means that the <code>rebar_frobble</code> plugin from the example project, runs in two contexts:</p>
<div>
<ol>
<li>During execution of the &#8216;compile&#8217; command, after the other (internal) modules have handled it</li>
<li>After execution of the &#8216;compile&#8217; command, during execution of the &#8216;frobble&#8217; command</li>
</ol>
</div>
<p>In practice, this means you can run [<code>rebar compile frobble]</code>, but not [<code>rebar frobble]</code>. [UPDATE] If you referenced the plugin in the top level rebar.config, it would remedy this situation, but you don't always want to do that. This isn't very intuitive and I suspect the developers may decide to clarify (or change) this behaviour in future. Despite the slightly confusing execution profile, rebar plugins are a very neat way of customising your rebar build. With <strong>full </strong>access to all the rebar internal modules, as well as the current (local and global) configuration, the plugin author has a lot of flexibility and power at their fingertips. Naturally with great power comes great responsibility, and plugin authors should consider carefully the use of exports besides published command names and their command/2 function interfaces.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/253/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=253&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2011/04/28/customise-your-build-with-rebar-plugins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
		<item>
		<title>Managing multiple Erlang/OTP installations</title>
		<link>http://hyperthunk.wordpress.com/2011/02/23/managing-multiple-erlangotp-installations/</link>
		<comments>http://hyperthunk.wordpress.com/2011/02/23/managing-multiple-erlangotp-installations/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 18:52:19 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=233</guid>
		<description><![CDATA[A recent post on the erlang-questions mailing list got me thinking about the way that I manage multiple (concurrent) versions of Erlang/OTP at the moment. This only works on unix-like operating systems, but it has been useful until now. Basically, I choose a common folder, which on OSX tends to be ~/Library/Erlang and somewhere similar [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=233&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://www.erlang.org/cgi-bin/ezmlm-cgi?4:mss:56630:201102:fbfdmiaoecpohghfhamc">recent post</a> on the erlang-questions mailing list got me thinking about the way that I manage multiple (concurrent) versions of Erlang/OTP at the moment. This only works on unix-like operating systems, but it has been useful until now.</p>
<p>Basically, I choose a common folder, which on OSX tends to be <em>~/Library/Erlang</em> and somewhere similar on other *nixes. Under this directory I keep a subdirectory into which multiple ERTS versions can be installed and another <em>site</em> directory into which common/shared libraries and applications can be installed.</p>
<p><code> ~/Library/Erlang/Current -&gt; /Users/t4/Library/Erlang/Versions/R13B04<br />
~/Library/Erlang/Versions<br />
~/Library/Erlang/Versions/R12B02<br />
~/Library/Erlang/Versions/R12B05<br />
~/Library/Erlang/Versions/R13B04<br />
~/Library/Erlang/Site<br />
~/Library/Erlang/Site/erlsom-1.2.1<br />
~/Library/Erlang/Site/gen_server2-1.0.0<br />
~/Library/Erlang/Site/mochiweb-1.7.1<br />
~/Library/Erlang/Site/protobuffs-0.5.0<br />
~/Library/Erlang/Site/webmachine-1.8.0</code></p>
<p>I then set my <code>$ERL_LIBS</code> environment variable to the <em>site</em> directory and symlink the <em>current</em> folder as I wish. I also configure tools like epm and/or sutro to use the <em>site</em> directory as their target install folder, giving me a consistent way to install things. </p>
<p>The main thing lacking from this approach is that I have control over which libs/apps in the <em>site</em> directory are compatible with which installed versions of ERTS. A good solution to this that doesn&#8217;t force me to use an entire tool-chain in order to take advantage of it, sounds very promising.   </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/233/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=233&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2011/02/23/managing-multiple-erlangotp-installations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
		<item>
		<title>Compiling Erlang Linked-in driver code on Snow Leopard</title>
		<link>http://hyperthunk.wordpress.com/2010/12/15/compiling-erlang-linked-in-driver-code-on-snow-leopard/</link>
		<comments>http://hyperthunk.wordpress.com/2010/12/15/compiling-erlang-linked-in-driver-code-on-snow-leopard/#comments</comments>
		<pubDate>Wed, 15 Dec 2010 10:01:00 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=224</guid>
		<description><![CDATA[Compile Joe Armstrong's example linked-in driver code on Snow Leopard.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=224&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Someone emailed me to ask how to get Joe&#8217;s example driver code to compile on snow leopard. The solution is to pass the right flags to gcc:</p>
<p><code> t4$ gcc -o exampledrv \<br />
-arch x86_64   \<br />
-fPIC -bundle   \<br />
-flat_namespace \<br />
-undefined suppress \<br />
$CFLAGS complex.c port_driver.c</code></p>
<p>This will generally still fail at runtime unless you rename (or symlink to) the .dylib you&#8217;ve created so that your shared library has the .so extension, for which the erts code is explicitly looking. Caveat: this last point may have been fixed in recent Erlang/OTP releases, but I&#8217;m a little out of touch! Using <a href="http://github.com/basho/rebar">rebar</a> to build your port driver sources circumvents this naming issue either way.</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/224/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=224&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2010/12/15/compiling-erlang-linked-in-driver-code-on-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
		<item>
		<title>jquery.xslt</title>
		<link>http://hyperthunk.wordpress.com/2010/09/21/jquery-xslt/</link>
		<comments>http://hyperthunk.wordpress.com/2010/09/21/jquery-xslt/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 20:12:16 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=220</guid>
		<description><![CDATA[I&#8217;ve created yet another jQuery xslt transformation plugin. This one is based on the sarissa javascript library, which abstracts many of the cross browser implementation details for you. I tried the jquery.transform plugin, which didn&#8217;t work for me in all browsers, but I wanted the same kind of control over caching and ajax calls. This [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=220&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve created yet another <a href="http://jquery.org">jQuery</a> xslt transformation plugin. This one is based on the <a href="http://sarissa.sourceforge.net">sarissa</a> javascript library, which abstracts many of the cross browser implementation details for you. I tried the jquery.transform plugin, which didn&#8217;t work for me in all browsers, but I wanted the same kind of control over caching and ajax calls. This one is already in use at work, and you can get a look at it <a href="http://hyperthunk.github.com/jquery.xslt">here</a>.   </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/220/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/220/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/220/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=220&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2010/09/21/jquery-xslt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
		<item>
		<title>Concurrency testing in Erlang with libtest</title>
		<link>http://hyperthunk.wordpress.com/2010/08/10/concurrency-testing-in-erlang-with-libtest/</link>
		<comments>http://hyperthunk.wordpress.com/2010/08/10/concurrency-testing-in-erlang-with-libtest/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 12:56:49 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[erlang]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=211</guid>
		<description><![CDATA[I&#8217;ve just started a new project, with the aim of making it easier to test the concurrent programs I write in Erlang. My stated aims are quite simple: Provide services for capturing inter-process messages and context Provide support for stubbing out processes and OTP behaviours Provide hamcrest matchers that make it simple to define assertions [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=211&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just started a new project, with the aim of making it easier to test the concurrent programs I write in <a href="http://erlang.org">Erlang</a>. My stated aims are quite simple:</p>
<ul>
<li>Provide services for capturing inter-process messages and context</li>
<li>Provide support for stubbing out processes and OTP behaviours</li>
<li>Provide hamcrest matchers that make it simple to define assertions about your application&#8217;s behaviour</li>
</ul>
<p>It&#8217;s all in a very early stage (apart from my <a href="http://github.com/hyperthunk/hamcrest-erlang">Erlang implementation of hamcrest</a>, which is coming along nicely now) and the source code is available on github <a href="http://github.com/hyperthunk/libtest">here</a>. Here are a couple of samples to whet the appetite:<br />
<code><br />
?assertThat(registered_name(Mod), observed_message_from(self(), Msg)),<br />
?assertThat(registered_name(Slave, ProcessName), observed_message(Msg)),<br />
?assertThat(Pid, observed_message({message, "hello"})),<br />
?assertThat(?COLLECTOR,<br />
    categorises(observed_message({message, "woo hoo"}),<br />
      as(category1))).<br />
</code></p>
<p>Stubbing of OTP behaviours will almost certainly be based on <a href="http://github.com/noss/emock">emock</a>, and I&#8217;m planning on integrating nicely with <a href="http://github.com/manopapad/proper">PropEr</a> as I&#8217;ve started using this library quite a lot myself. The mechanics of replacing registered <em>gen_server</em>s and the like (using runtime code generation and/or re-registration/config), I&#8217;ll probably leave alone as there are plenty of good libraries out there that do this already. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/211/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=211&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2010/08/10/concurrency-testing-in-erlang-with-libtest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
		<item>
		<title>Property based testing against mocks?</title>
		<link>http://hyperthunk.wordpress.com/2010/07/13/property-based-testing-against-mocks/</link>
		<comments>http://hyperthunk.wordpress.com/2010/07/13/property-based-testing-against-mocks/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 00:43:13 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=203</guid>
		<description><![CDATA[More of a quick splurge than anything &#8211; I was looking over some old code and noticed a unit test that creates a lazy list of tests, each of which asserts some properties about a bisection based search over a set of stub objects which are all based on an existing superclass and have a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=203&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>More of a quick splurge than anything &#8211; I was looking over some old code and noticed a unit test that creates a lazy list of tests, each of which  asserts some properties about a bisection based search over a set of stub objects which are all based on an existing superclass and have a property defined which returns a randomised value each time you interact with it. Unusual but kind of cool. Here&#8217;s the code&#8230;<br />
<code><br />
@forall_lazy(searchbase=<br />
&nbsp;&nbsp;&nbsp;&nbsp;sets(items=stubs(cls=Identifiable,<br />
&nbsp;&nbsp;&nbsp;&nbsp;salsaId=strings(low=1)),<br />
&nbsp;&nbsp;&nbsp;&nbsp;size=(1,3011)),<br />
&nbsp;&nbsp;&nbsp;&nbsp;subject=integers(low=0, high=1010))<br />
def check_detect_using_bisect(searchbase, subject):<br />
&nbsp;&nbsp;searchbase = list(searchbase)<br />
&nbsp;&nbsp;item = searchbase[max(0, min(subject, len(searchbase) -1))]<br />
&nbsp;&nbsp;universe = sorted(searchbase, key=salsa_key)<br />
&nbsp;&nbsp;search_result = detect(cmp, item, universe, key=salsa_key)<br />
&nbsp;&nbsp;reason = "item (%i) mapped_to (%i)" % (universe.index(item), universe.index(search_result))<br />
&nbsp;&nbsp;assert_that(search_result, is_(not_none()), reason)<br />
&nbsp;&nbsp;assert_that(search_result.salsaId, is_(equal_to(item.salsaId)), reason)</p>
<p>def test_detect_using_bisect():<br />
&nbsp;&nbsp;[ (yield testcase) for testcase in check_detect_using_bisect() ]<br />
  </code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/203/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/203/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=203&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2010/07/13/property-based-testing-against-mocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
		<item>
		<title>Post compile hooks with rebar</title>
		<link>http://hyperthunk.wordpress.com/2010/07/13/post-compile-hooks-with-rebar/</link>
		<comments>http://hyperthunk.wordpress.com/2010/07/13/post-compile-hooks-with-rebar/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 00:01:32 +0000</pubDate>
		<dc:creator>Hyperthunk</dc:creator>
				<category><![CDATA[builds]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://hyperthunk.wordpress.com/?p=193</guid>
		<description><![CDATA[Sometimes you want your build to do some additional work after compiling. For example, in my Erlang implementation of hamcrest, I dynamically generate the main header file after compiling to ensure that all the functions exported from the hamcrest_matchers module are imported when the header gets included and to ensure that wrapper macros for eunit [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=193&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Sometimes you want your build to do some additional work after compiling. For example, in my <a href="http://erlang.org" target="_blank">Erlang</a> implementation of <a href="http://github.com/hyperthunk/hamcrest-erlang">hamcrest</a>, I dynamically generate the main header file after compiling to ensure that all the functions exported from the hamcrest_matchers module are imported when the header gets included and to ensure that wrapper macros for eunit are also generated for each of them.</p>
<p>Typically you&#8217;d just have a makefile deal with this, maybe like so:</p>
<p><code> compile:<br />
./rebar compile; escript header_gen<br />
</code></p>
<p>But that kind of breaks other people&#8217;s builds if they want to use rebar themselves. The problem is that rebar doesn&#8217;t yet provide a mechanism for overriding the build/compile command for dependencies (at all, let alone individually) and thus if your build requires a makefile to be run then your consumers build has to incur the same kind of complexity. Fortunately there is a work-around. Rebar provides a <em>compile_post_script</em> hook which you can specify in your <code>rebar.config</code> file. You specify a shell command and rebar will run this hook immediately after compilation. Unfortunately it also runs it when the compile command is applied to all your dependencies (again this is something which isn&#8217;t controllable yet) which typically will break because your shell command is not relevant to these apps. I spent a little time trying to do something clever with <code>erl --eval '...'</code> but in the end that didn&#8217;t play nicely at all. I then tried to encode the whole thing in a compound shell command like <code>if [ -f hrlgen ]; then escript hrl; fi</code> but then discovered that <code>rebar_utils:sh/1</code> (which runs the shell command) wraps the supplied command text in an <code>exec</code> system call (which obviously isn&#8217;t going to work for a complex if..then expression). In the end, it was a comedic reptile that came to the rescue:</p>
<p><code> {compile_post_script,<br />
"env ERL_LIBS=deps python -c \"import os; os.path.isfile('hrlgen') and os.system('escript hrlgen') or None\""}.<br />
</code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hyperthunk.wordpress.com/193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hyperthunk.wordpress.com/193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hyperthunk.wordpress.com/193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hyperthunk.wordpress.com/193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/hyperthunk.wordpress.com/193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/hyperthunk.wordpress.com/193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/hyperthunk.wordpress.com/193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/hyperthunk.wordpress.com/193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hyperthunk.wordpress.com/193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hyperthunk.wordpress.com/193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hyperthunk.wordpress.com/193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hyperthunk.wordpress.com/193/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hyperthunk.wordpress.com/193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hyperthunk.wordpress.com/193/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hyperthunk.wordpress.com&amp;blog=3976050&amp;post=193&amp;subd=hyperthunk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://hyperthunk.wordpress.com/2010/07/13/post-compile-hooks-with-rebar/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/696de188d5a6a3dc31b31d1b79f61fc8?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">loggerheadz</media:title>
		</media:content>
	</item>
	</channel>
</rss>
