<?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/"
	>

<channel>
	<title>experimentalworks</title>
	<atom:link href="http://blog.experimentalworks.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.experimentalworks.net</link>
	<description></description>
	<lastBuildDate>Thu, 04 Mar 2010 14:04:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Dealing with Sessions in Compojure</title>
		<link>http://blog.experimentalworks.net/2010/02/dealing-with-sessions-in-compojure/</link>
		<comments>http://blog.experimentalworks.net/2010/02/dealing-with-sessions-in-compojure/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 10:46:31 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=407</guid>
		<description><![CDATA[The blog post gives you a short introduction into the session management of Compojure.]]></description>
			<content:encoded><![CDATA[<p>I recently started working with <a href="http://compojure.org">Compojure</a>, a <a href="http://en.wikipedia.org/wiki/Web_Application_Framework">web framework</a> for programming language <a href="http://clojure.org">Clojure</a>. After playing around with basic GET and POST requests I tried to store and load data from a session. As Compojure is quiet new, there is not much documentation how to deal with sessions, particularly as Compojure and it&#8217;s API still changes fast.</p>
<p>In the following post I&#8217;ll show a brief example on how to create a login page with Compojure 0.3.2 running on Clojure 1.1.0.</p>
<p><span id="more-407"></span></p>
<h4>What is Clojure?</h4>
<p>Clojure is a <a href="http://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp</a> dialect. So it&#8217;s a programming language based on the principles of Lisp. The interesting part about Clojure is that it runs on the <a href="http://en.wikipedia.org/wiki/Java_Virtual_Machine">Java Virtual Machine</a>. As a developer you can therefore use the bright variety of Java written libraries in your code without touching one line of <a href="http://en.wikipedia.org/wiki/Java_(programming_language)">Java</a>. Use the power of Java libraries together with the power of Lisp.</p>
<h4>What is Compojure?</h4>
<p>Compojure is a web framework for Clojure. It handles <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol">incoming request</a>, offers an easy way to create <a href="http://java.sun.com/products/servlet/">servlets</a> and provides basic functionality for <a href="http://en.wikipedia.org/wiki/HTML">HTML</a> templates. The current stable version 0.3.2. Compojure is a young project and things change fast there, so be aware that a 0.3.2 application might not run on 0.4.</p>
<h4>What is a session?</h4>
<p>Basically it&#8217;s a per-user store managed by the server. For example a server backend can store the credentials of a user that it received in a request in this store making it possible to identify the user again when he or she does a second request. Usually this functionality is achieved by a library or by the interpreter itself (for example in <a href="http://php.net">PHP</a>) and is implemented by storing the session data either in memory or on disk together with a unique identifier that is then stored in a cookie at the users computer. So when the user comes back, the cookie is read and the identifier is used to find the data for the user.</p>
<h3>The application</h3>
<h4>A basic example</h4>
<p>Before we work with a session, let&#8217;s create a simple webpage that displays hello world for us.<br />
<script src="http://gist.github.com/316604.js"></script></p>
<p>The example is straight forward. We define a set of <em>routes</em>. In our example the route is &#8220;/*&#8221;, so it matches everything. The route then takes a function as a second argument. In our case we use the templating mechanism of Compojure and create a simple HTML response with the <font face="monospace">(html)</font> macro.</p>
<p>We then start the server using the <font face="monospace">(run-server)</font> macro and binding our routes to a specified mountpoint. I won&#8217;t go into details about servlets but usually it is sufficient if you have a servlet running on the mountpoint &#8220;/*&#8221; and then a set of routes.</p>
<p>To run the server you can use a small script like this one:<br />
<code><br />
#!/bin/sh<br />
CLASSPATH=.:~/dev/clojure/compojure.jar:~/dev/clojure/clojure.jar<br />
java -cp $CLASSPATH clojure.lang.Script net/experimentalworks/clojure/serve.clj<br />
</code></p>
<h4>Adding sessions</h4>
<p>Before we can start adding sessions we have to be aware that Compojure has a mechanism called <em>decorating</em>. So you can decorate a set or routes with what Compojure calls a middleware. We will think of it as a way to enable advanced mechanism. To add the session mechanism to a set of routes use the <font face="monospace">(decorate)</font> macro as shown in the following code:</p>
<p><script src="http://gist.github.com/316609.js"></script></p>
<p>Note the that we define a session decoration. At the moment sessions only support in-memory storage (which by the way should be usually the way you want to manage sessions). The <font face="monospace">:memory</font> keyword here is to tell Compojure to store it&#8217;s sessions in memory. Although you can omit the keyword, I prefer writing it down so people can easily figure out how our session is stored.</p>
<h4>Creating a login</h4>
<p>Let&#8217;s create a login. We will first add a new route called <font face="monospace">/login/:user</font>. This will tell Compojure that the last part of the query string is a parameter and it should extract it. We can then access the value using <font face="monospace">(:user params)</font>. We use the <font face="monospace">(session-assoc)</font> function to associate our username with the session-key <font face="monospace">:loggedin</font>. Here is what the code looks like:<br />
<script src="http://gist.github.com/316614.js"></script></p>
<p>You can then &#8220;login&#8221; to your site using <font face="monospace">http://localhost:8080/login/test</font> and you Compojure will recognize you again if you go back to <font face="monospace">http://localhost:8080/</font></p>
<h4>Logout</h4>
<p>To logout, we clear the key itself. Let&#8217;s a have a look directly into the code. We use the <font face="monospace">(session-dissoc)</font> function to drop the key (it seems that clear-session is broken in my <a href="http://github.com/weavejester/compojure">Compojure checkout</a> for whatever reasons..need to debug *debug*).<br />
<script src="http://gist.github.com/316623.js"></script><br />
Use <font face="monospace">http://localhost:8080/logout</font> to get rid of your session.</p>
<h4>Conclusion</h4>
<p>The basic idea behind Compojure sessions is simple and I hope you were able to grasp the idea a little bit. What can be annoying and what I didn&#8217;t show you is that you might run into problems within the actual implementation, although the basic stuff should work fine. Once you figured out the basics you can read and write sessions withing seconds and the code becomes clean and beautiful. Feel free to comment on this article if you like the post, it&#8217;s the only measurement for me that I can use to make sure I&#8217;m not writing stupid stuff.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2010/02/dealing-with-sessions-in-compojure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Talks</title>
		<link>http://blog.experimentalworks.net/2010/02/talks/</link>
		<comments>http://blog.experimentalworks.net/2010/02/talks/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 21:53:29 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=401</guid>
		<description><![CDATA[I really enjoy giving talks. This is particularly because I like to teach people something and because I&#8217;m really enthusiastic about the technical things I talk about. Once of these things are obviously decentralized version control system, in particular Git and Mercurial. Finally after two years of submitting talks to various conferences, people and conferences [...]]]></description>
			<content:encoded><![CDATA[<p>I really enjoy giving talks. This is particularly because I like to teach people something and because I&#8217;m really enthusiastic about the technical things I talk about. Once of these things are obviously decentralized version control system, in particular <a href="http://git-scm.org">Git</a> and <a href="http://mercurial.selenic.com">Mercurial</a>. Finally after two years of submitting talks to various conferences, people and conferences in the <a href="http://php.net">PHP</a> community start to pick up this topic. Seems that 2010 is the year of <a href="http://en.wikipedia.org/wiki/Distributed_revision_control">DVCS</a>, and I&#8217;m really looking forward to give a talk about the<a href="http://phpconference.nl/schedule/talks#advancedgit"> advanced features of Git</a> at</p>
<ul>
<li><a href="http://phpconference.nl">Dutch PHP Conference 2010</a></li>
<li><a href="http://phpconference.de">Interntational PHP Conference</a></li>
</ul>
<p>The talk will give a very brief overview how Git works, and will then give a more detailed insight in how Git handles commits, files, etc so that people get a very good understanding about the concepts that are needed to fully understand tools like git <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html">rebase</a>, git <a href="http://ftp.sunet.se/pub/Linux/kernel.org/software/scm/git/docs/git-reflog.html">reflog</a> and git <a href="http://ftp.sunet.se/pub/Linux/kernel.org/software/scm/git/docs/git-svn.html">svn</a>. The aim is to provide them will all necessary information and a few examples to get lost commits back, rebase their branches and design more complex git workflows in the future without needing to search the web or ask a guru.</p>
<p>A second talk will be more focused on beginners and developers coming from <a href="http://subversion.tigris.org/">subversion</a>. This talk will be part of a series of talks the german <a href="http://telekom.de">telekom</a> is organizing. I&#8217;ll also give an extended version of this as an in-house workshop at a Munich based company.</p>
<p>So for me it seems that after five years, DVCS is mature enough to get into companies and that we can expect a bright variety of companies to adopt new tools and workflows. Let&#8217;s see what&#8217;s coming&#8230;</p>
<p><strong>For sure I still offer Git and Mercurial trainings, so feel free to contact me (dsp ~at~ php ~dot~ net)</strong></p>
<p><em>probably shameless self promotion</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2010/02/talks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clojure, and it&#8217;s not a typo.</title>
		<link>http://blog.experimentalworks.net/2010/02/clojure-and-its-not-a-typo/</link>
		<comments>http://blog.experimentalworks.net/2010/02/clojure-and-its-not-a-typo/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 11:17:24 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[sonar]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=393</guid>
		<description><![CDATA[Why lisp can be sooooo sweet. A clojure class extending java.

compile it

(set! *compile-path* "build")
(compile 'net.experimentalworks.clojure.outdegree)

Ah yeah and hsv2rgb transformation:

]]></description>
			<content:encoded><![CDATA[<p>Why lisp can be sooooo sweet. A clojure class extending java.<br />
<script src="http://gist.github.com/294201.js"></script></p>
<p>compile it</p>
<pre>
(set! *compile-path* "build")
(compile 'net.experimentalworks.clojure.outdegree)
</pre>
<p>Ah yeah and hsv2rgb transformation:<br />
<script src="http://gist.github.com/294152.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2010/02/clojure-and-its-not-a-typo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a simple PHP sourcecode buildscript in Scala</title>
		<link>http://blog.experimentalworks.net/2010/01/writing-a-simple-php-source-buildscript-in-scala/</link>
		<comments>http://blog.experimentalworks.net/2010/01/writing-a-simple-php-source-buildscript-in-scala/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 22:48:22 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=356</guid>
		<description><![CDATA[Scala is a fascinating language. Running on the Java VM, Scala offers a powerful mixture from both the imperative Java world and functional programming including modern techniques like Actors. Personally I prefer to not just learn programming languages, but also try them out while reading through the book.
As I wanted to have nice a build [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.scala-lang.org">Scala</a> is a fascinating language. Running on the <a href="http://java.com">Java VM</a>, Scala offers a powerful mixture from both the imperative Java world and functional programming including modern techniques like <a href="http://www.scala-lang.org/node/242">Actors</a>. Personally I prefer to not just learn programming languages, but also try them out while reading through the book.</p>
<p>As I wanted to have nice a build system for my <a href="http://php.net">PHP</a> <a href="http://svn.php.net">subversion</a> checkout, I used this need as a project to start coding Scala. So what do I exactly need? I want to build multiple versions of PHP from the same branch without checking out the code twice. I also want to configure these builds somewhere without always typing in the parameter list or so. For further versions I want to be able to configure these in a file that can easily be distributed to other machines.</p>
<p>I set down and wrote a parser for a configuration file that can configured build targets which is then build by<br />
the program. The configuration file I used is specialized for this purpose, which is why I didn&#8217;t used something like ant or so. The result is called <strong><a href='http://blog.experimentalworks.net/wp-content/uploads/2010/01/bauaffe-3.0.0a1.jar'>bauaffe-3.0.0a1.jar</a></strong>.</p>
<p>I&#8217;ll just show a few things done in the project, but mainly focus on what the nice script can do. Further blog posts will be about the actual implementation.</p>
<p>The configuration looks like this</p>
<pre>
$ cat ~/.buildmaker
begin default configuration
    define source "/Users/dsp/dev/c/php-src"
    define build "/Users/dsp/dev/c/php-src/build"
    define defaults as
        with "iconv=/opt/local"
    build trunk as
        "php60" using defaults
        "php60-debug" using defaults
            enable "debug"
    build branch "PHP_5_3" as
        "php53" using defaults
            environment PHP_AUTOCONF="autoconf213"
        "php53-debug" using defaults
            enable "debug"
            environment PHP_AUTOCONF="autoconf213"
</pre>
<p>.<br />
Proper indention is not necessary (as e.g in python).</p>
<hr />
You might want to think that parsing the configuration file can be difficult. Well, if you use C you would use YACC, if you use PHP, I don&#8217;t know what you would have done, but Scala is made to create this kind of Domain Specific Languages (for my the config is a DSL). You can easily transform a EBNF directly to scala code using the JavaTokenParsers provided by the Scala Library. As an example this it the statement that parses the first line:<br />
<code><br />
    def begin : Parser[Configuration] =<br />
        "begin" ~ ("default" | stringLiteral) ~ "configuration" ~ rep(define | build) ^^ {<br />
        case "begin"~name~"configuration"~confs => new Configuration(name, confs)<br />
    }<br />
</code><br />
which is directly taken from the BNF:<br />
<code><br />
      config ::= "begin" ( "default" | string ) "configuration" ( define | build )*<br />
</code></p>
<p>Did I mention that the actual parser is 170 lines of code with usual indention and formatting?</p>
<hr />
<p><strong>Configuration</strong><br />
The configuration file is searched in <i>~/.buildmaker</i>, or if <i>~/.builmaker</i> doesn&#8217;t exists, <i>buildmaker.conf</i> in the current directory. How do you configure the tool? First of all you can specify a configuration. It is usually called &#8220;default&#8221;. It is not yet supported to name it differently, although the parser is able to parse it. In further versions multiple configurations per file are allowed.</p>
<p><strong>Variables</strong><br />
Variables are set using the <i>define</i> syntax. At the moment you can set the <i>build</i> and <i>source</i> variable as well the <em>defaults</em> variable, which is usually a block of statements that can be used in the branch configurations. </p>
<p><strong>Branches</strong><br />
A branch is configured using the <em>build</em> syntax. You first have to specify which branch to build. Every branch can then configured to have build target with a given set of options. Branch options are:</p>
<ul>
<li>with <em>string</em>: Builds the target with the given extension</li>
<li>enable <em>string</em>: Builds the target with the given extension</li>
<li>environment <em>string=string</em>: Builds the target with environment variable</li>
</ul>
<p>. You can specify <i>using defaults</i> which will cause the runner to use the options specified in the <i>defaults</i> define.</p>
<p><em>At the moment the parser will not do a good job in notifying you what you are allowed to do and what not, although pure parse error will be emitted. You can also not set any other variable than the described once.</em></p>
<p><strong>Building</strong><br />
Calling</p>
<pre>
$ java -jar bauaffe-3.0.0a1.jar list
TARGET                         LAST BUILD
php60                          None
php60-debug                    None
php53                          Sat Jan 09 16:55:12 CET 2010
php53-debug                    Sat Jan 09 16:59:37 CET 2010
</pre>
<p>gives you a list of parsed targets and their last build date. You can build a target using</p>
<pre>
$ java -jar bauaffe-3.0.0a1.jar <targetname>
</targetname></pre>
<p>or build all using</p>
<pre>
$ java -jar bauaffe-3.0.0a1.jar all
</pre>
<p>Please notice that the current version requires that you now what you are doing. You might miss some error messages or find them not useful. I&#8217;ll change this before the first release, if I&#8217;ll do a final version of it. I hope you like the little tool.</p>
<p><a href='http://blog.experimentalworks.net/wp-content/uploads/2010/01/bauaffe-3.0.0a1.jar'>Download It!</a></p>
<p><em>Scala (pronounced /ˈskɑːlə, ˈskeɪlə/) is a multi-paradigm programming language designed to integrate features of object-oriented programming and functional programming.[1] The name Scala stands for &#8220;scalable language&#8221;, signifying that it is designed to grow with the demands of its users.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2010/01/writing-a-simple-php-source-buildscript-in-scala/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Show exit status of the last executed command in ZSH prompt</title>
		<link>http://blog.experimentalworks.net/2009/12/show-exit-status-of-the-last-executed-command-in-zsh-prompt/</link>
		<comments>http://blog.experimentalworks.net/2009/12/show-exit-status-of-the-last-executed-command-in-zsh-prompt/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 10:34:17 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Private]]></category>
		<category><![CDATA[zsh]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/2009/12/show-exit-status-of-the-last-executed-command-in-zsh-prompt/</guid>
		<description><![CDATA[We recently stumbled over the problem that we want to know the exit status of the last command that was executed in our ZSH. Well the obvious thing is echoing $?, but as we need this quite often we want to have it in our right prompt. Googling around a little bit, we found the [...]]]></description>
			<content:encoded><![CDATA[<p>We recently stumbled over the problem that we want to know the exit status of the last command that was executed in our ZSH. Well the obvious thing is echoing $?, but as we need this quite often we want to have it in our right prompt. Googling around a little bit, we found the solution:</p>
<p>In your .zshrc add the following line<br />
<code><br />
RPROMPT='[%?]'<br />
</code><br />
This will give you the last exit status on the right site of your shell.</p>
<p>My zsh now looks like this (with the additional stuff)<br />
<code><br />
buenosaires:~/dev/c/git.git/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (next)[1]<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2009/12/show-exit-status-of-the-last-executed-command-in-zsh-prompt/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Writing a hg to subversion gate</title>
		<link>http://blog.experimentalworks.net/2009/12/writing-a-hg-to-subversion-gate/</link>
		<comments>http://blog.experimentalworks.net/2009/12/writing-a-hg-to-subversion-gate/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 23:59:04 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Version Control]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=318</guid>
		<description><![CDATA[Using a decentralized version control system (DVCS) like Mercurial (hg) or Git as a client for Subversion is very common. With the unique features of a DVCS a developer can have both the features of offline development and local branching while still being able to push to a subversion server. This approach is often used [...]]]></description>
			<content:encoded><![CDATA[<p>Using a decentralized version control system (DVCS) like Mercurial (hg) or Git as a client for Subversion is very common. With the unique features of a DVCS a developer can have both the features of offline development and local branching while still being able to push to a subversion server. This approach is often used in environments in which subversion is the given version control system. While the approach of using this bi-directional push and pull mechanism, provided by git-svn or hgsubversion, works perfectly for one developer, it has limitations working in a team using the usual DVCS push and pull concepts.</p>
<p>The following article will outline the current limitations of bi-directional dvcs to subversion bridges and shows a simple approach to implement a solution for a certain instance of the problem.</p>
<p><span id="more-318"></span><br />
<strong>The bi-directional bridge</strong><br />
The idea of finding a way to interchange commits back and forth between a DVCS and subversion was born early in the development of tools like Git and Mercurial. The basic idea is easy to grasp. To initialize a repository the DVCS requests all changes between revision 0 and the current HEAD from the subversion server and imports every change as a regular changeset into the local repository of the DVCS. In addition it maintains a mapping between the local, DVCS specific, changeset IDs and the revision numbers in the subversion repository. If a developer wants to push his newly created changesets from it&#8217;s local repository back to subversion, the bridge determines the latest pushed changeset and then iterates over the unpushed changes, committing them bit by bit to the subversion server. </p>
<p>Depending on the DVCS you use it will then delete the local changeset and reimport the comitted changesets from the subversion server to ensure that the changeset contains the right date and comitter information as well as the right mapping to the subversion revisionnumber.</p>
<p><em>Example</em><br />
To clarify what we just discussed. Assume that we are using git-svn. We are importing a subversion repository with just one commit using the command (I won&#8217;t get into detail how to use the command):<br />
<code><br />
 $ git svn clone svn://example.com/repo<br />
</code><br />
This command results in a repository which in our example contains the following commit.<br />
<code><br />
commit 7a730e9187becbe1979059cd9752fdea38e3cd9e<br />
Author: david &gt;david @cffdd316-8dd2-4046-8f43-d0df91842a18&lt;<br />
Date:   Thu Jul 12 19:39:51 2007 +0000</p>
<p>    Crescas in mille millia<br />
</code><br />
Let&#8217;s asusme that we create a new commit on top:<br />
<code><br />
commit 129e0e4239ac4d375f2a2132dee042a27f2fd70c<br />
Author: David S. P. &gt;dsp at php.ent&lt;<br />
Date:   Fri Jul 13 12:23:42 2007 +0000</p>
<p>	First Draft<br />
</code><br />
If we push it using <em>git svn dcommit</em>, it&#8217;ll be committed into subversion and<br />
reimported as:<br />
<code><br />
commit 8200f32f61432004b488d063564ac9dae7bf6827<br />
Author: david &gt;david @cffdd316-8dd2-4046-8f43-d0df91842a18&lt;<br />
Date:   Fri Jul 13 12:23:42 2007 +0000</p>
<p>	First Draft<br />
</code></p>
<p><strong>Limitations</strong><br />
Tools like <em>git-svn</em> or <em>hgsubversion</em> are working perfectly fine as long as you use them just as a subversion client. There is a serious limitation in what you can push and pull from and to a subversion server. Particularly, problems arise if you are using the usual DVCS push and pull method to exchange changesets. Why so? If you push and pull from other DVCS repositories you might have to create a merge. Modern DVCS like Git, Mercurial or Bazaar represent history as a directed acyclic graph (DAG). Therefore a merge is a commit which has two (or more) parents, which means that a merge is the resulting connection of two parallel strands of history. Now this is a very comfortable and powerful way to describe history in parallel development. Sadly subversion doesn&#8217;t handles history and hence merges the same way (at least not priort svn 1.5). As a result, it is not possible to represent the Merge from a DVCS in subversion.</p>
<p>Different bi-directional bridges have different approaches to this problems. Git-svn will commit the Merge but not the commits which are part of the seconds strand of history, while hgsubversion will abort if it has to push a merge. The fact that hgsubversion aborts in case of a merge is our actual problem. We want to use Mercurial and therefore need to find a way to push a merge to subversion.</p>
<p><strong>A usecase</strong><br />
You shouldn&#8217;t care much about these limitations. Usually, people are using the bi-directional bridge locally to be able to do offline commits or bisect a bug. In that case, everything will work fine.</p>
<p>But why do I write a complete blog post about a hg to svn bridge if the problem is already solved? The answer is pretty simple.</p>
<ol>
<li>Imagine you are working in a small team. Everybody in the team knows Mercurial and everybody likes to use it. Moreover you are working offline from time to time, and the members of the team sometimes have to exchange unfinished features with other members. In that case you will probably use Mercurial as your version control system. The problem here is the customer. He dictates the VCS and it has to be Subversion. Now subversion at all is not that bad, but in your particular case, it&#8217;s a huge drawback. You have to find a way to mirror your Mercurial repository to the Subversion server.
</li>
<li>A second use case is that you are working on an OpenSource project which uses github or bitbucket to host it&#8217;s repositories. As you are using the OpenSource framework also at work. You have to use Subversion and you want to use svn:externals to integrate your fancy framework into the existing Subversion repository</li>
</ol>
<p>As you see, there is a use case for DVSC to Subversion mirror. As no such tool exists at the moment, we&#8217;ll try to implement a (frankly, very stupid) mirroring mechanism.</p>
<p><strong>The idea and it&#8217;s limitations</strong><br />
We see that we need to mirror a existing Mercurial repository to Subversion.<br />
We also know that we cannot use the existing tools. Our requirements are the following.</p>
<ol>
<li>Mirror a Mercurial repository into a Subversion repository</li>
<li>Track latest synchronized changeset</li>
<li>Handle merges</li>
</ol>
<p>Note that we would have been able to do this with git-svn, while it&#8217;s not possible to do it with hgsubversion.</p>
<p>A few assumptions about the environment where we want to use our mirroring mechanism helps us to simplify the requirements.</p>
<ol>
<li>We do not need to preserve the author information</li>
<li>We have a central Mercurial repository called Gate</li>
<li>No commit will be done into the repository other than our mirroring (and believe me, things get ulgy for you if you try to&#8230;)</li>
<li>We do not need to preserve all commits</li>
</ol>
<p>So what is the end result? We just need to find a way to push all changesets and just ignore all merged changes, but commit the merge itself. This should be sufficient.</p>
<p>In our particular environment everyone has his own repository, but one person integrates all changes into one repository called the Gate. Commits reaching the gate are committed to Subversion.</p>
<p><strong>The implementation</strong><br />
To make a long story short (it&#8217;s getting late). We are using Mercurials log command and it&#8217;s option to obtain a linear history that can be pushed. To get the the history, we use<br />
<code><br />
	hg log --follow-first<br />
</code><br />
This will return the history omitting all merged changesets but including the merges itself. We silently drop the changesets that were merged, but retain the result. As we need to get just the SHA-1, we use the &#8211;template option to get the node. We then iterate over the history, updating our working copy to each changeset in the history, adding all newly created files and deleting all removed files and then comitting the current state of the working directory. So here is our final script<br />
<code></p>
<pre>
#!/bin/sh

lc=0
cont=0
if test -f "LAST_COMMIT"
then
	lc=`cat LAST_COMMIT`
	cont=1
fi

for hash in `hg log --follow-first --template "{node}\n" -r $lc:tip`
	do
		if test $cont -eq 1
		then
			cont=0
			continue
		fi

		echo "update to $hash"
		if ! hg log --template "{desc}\n"  -r $hash > COMMIT_MSG
		then
			echo "Canno get log" >&#038;2
			exit 127;
		fi
		cat COMMIT_MSG

		hg up -C -r $hash
		for file in `hg log --template "{file_adds}\n" -r $hash`
			do
				echo "add $file"
				svn add --parents $file
			done
		for file in `hg log --template "{file_dels}\n" -r $hash`
			do
				echo "del $file"
				svn rm $file
			done
		svn commit -F COMMIT_MSG
		echo $hash > LAST_COMMIT
	done
</pre>
<p></code><br />
It looks scary, and yes it <em>is</em> scary. But for the moment it works. Our simple hg to subversion bridge is finished.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2009/12/writing-a-hg-to-subversion-gate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving to a new server</title>
		<link>http://blog.experimentalworks.net/2009/11/moving-to-a-new-server/</link>
		<comments>http://blog.experimentalworks.net/2009/11/moving-to-a-new-server/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 00:34:28 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/2009/11/moving-to-a-new-server/</guid>
		<description><![CDATA[I&#8217;m currently moving my blog and everything on experimentalworks to a new server. The new server is running latest OpenSolaris with all the fancy stuff in it. Enjoy.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently moving my blog and everything on experimentalworks to a new server. The new server is running latest OpenSolaris with all the fancy stuff in it. Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2009/11/moving-to-a-new-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ask a Droid</title>
		<link>http://blog.experimentalworks.net/2009/09/ask-a-droid/</link>
		<comments>http://blog.experimentalworks.net/2009/09/ask-a-droid/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 18:04:09 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=308</guid>
		<description><![CDATA[I bought a G1 dev phone six month ago. Not because I seriously wanted to write applications for the android platform, but because it was the only way to get an Android based phone in Europe. Nevertheless, the complete Android platform is really appealing to me, mainly because it&#8217;s more open than an iPhone, there [...]]]></description>
			<content:encoded><![CDATA[<p>I bought a G1 dev phone six month ago. Not because I seriously wanted to write applications for the android platform, but because it was the only way to get an Android based phone in Europe. Nevertheless, the complete Android platform is really appealing to me, mainly because it&#8217;s more open than an iPhone, there are much more nerdy apps for it and &#8211; yeah I know what you think &#8211; it&#8217;s based on Java.</p>
<p><em>Warning this is a potential boring blog entry. Apprx writting time was about 5min</em></p>
<p>I once tried writing applications for the iPhone and started to like the concept of Obj-C while still I hate the syntax and I don&#8217;t like the API that much. Android makes things simple for me, and I guess for most people knowing a little bit java. It implements big parts of the Java standard (although it doesn&#8217;t claim to be standard compatible) which makes it easy to start writing apps if you know the libraries a little bit. Android also includes the powerful HTTP libraries of the Apache project as well as Json and XML parsers.</p>
<p>Having said this, the most important factor why I started to love my phone and the Android system: I can easily deploy apps on my phone, I debug it on my phone, I have nearly the complete power of the java framework and I totaly enjoy seeing my first app starting on the actual phone after 1 hour of coding. The app itself is fairly simple. It&#8217;s a basic search interface phpMyFAQs upcoming Rest API.<br />
So you can search an existing phpMyFAQ installation for a search term and display the result. Although the app needs phpMyFAQ 2.6.0-alpha it&#8217;s already available in the Android Market. So feel free to check it out. You can test it with the URL: <em>http://faq.phpmyfaq.de/</em>. The source can be found at <a href="http://github.com/thorsten/pmfMobileKit">http://github.com/thorsten/pmfMobileKit</a>. Expect more updates to the app soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2009/09/ask-a-droid/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Birthday</title>
		<link>http://blog.experimentalworks.net/2009/08/birthday/</link>
		<comments>http://blog.experimentalworks.net/2009/08/birthday/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 23:10:50 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[nonsense]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=298</guid>
		<description><![CDATA[Ups, I nearly missed the third birthday of my blog. Happy birthday experimentalworks blog.
]]></description>
			<content:encoded><![CDATA[<p>Ups, I nearly missed the <a href="http://blog.experimentalworks.net/2006/07/about-open-source-and-business/">third</a> birthday of my blog. Happy birthday experimentalworks blog.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2009/08/birthday/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CRE</title>
		<link>http://blog.experimentalworks.net/2009/08/cre/</link>
		<comments>http://blog.experimentalworks.net/2009/08/cre/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 22:45:29 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[chaosradio]]></category>
		<category><![CDATA[radio]]></category>

		<guid isPermaLink="false">http://blog.experimentalworks.net/?p=283</guid>
		<description><![CDATA[Ich bin mir gar nicht mehr sicher, wann ich das Chaosradio entdeckt habe. Es wird so ca. vor zwei Jahren gewesen sein, als der Begriff Podcast geschaffen wurde und die ersten deutsprachigen Podcasts das Licht der Welt erblickt haben. Als technologieverliebter Nerd stößt man so unweigerlich früher oder später auf das Chaosradio. Während ich anfangs [...]]]></description>
			<content:encoded><![CDATA[<p>Ich bin mir gar nicht mehr sicher, wann ich das <a href="http://chaosradio.ccc.de">Chaosradio</a> entdeckt habe. Es wird so ca. vor zwei Jahren gewesen sein, als der Begriff <a href="http://de.wikipedia.org/wiki/Podcasting">Podcast</a> geschaffen wurde und die ersten deutsprachigen Podcasts das Licht der Welt erblickt haben. Als technologieverliebter Nerd stößt man so unweigerlich früher oder später auf das Chaosradio. Während ich anfangs eher das dreistündige Chaosradio, das auch auf Fritz ausgestrahlt wird, anhörte, bin ich doch relativ schnell dazu übergegangen <a href="http://tim.geekheim.de/2009/08/09/cre-kettenblogging-fr-den-weltfrieden/">Pritloves</a> Express-Variante zu abonnieren. Denn sind wir mal ehrlich, zwar sind die Anrufer bei Chaosradio manchmal ganz amüsant, doch zum Großteil eher nervend. Die kompakten und meistens inhaltlich guten Folgende des CREs machen da deutlich mehr Spaß.</p>
<p>Inhaltlich ist das CRE eher technisch aufgestellt und befasst sich mit allem was den Nerd erfreut, sozusagen die Cub-Mate des audiophilen Tekki. CRE ist also gut für die Geek-Gesundheit, liefert einen Blick über den Tellerrand und, hepp, befasst sich sogar mit <a href="http://chaosradio.ccc.de/cre131.html">Soziologie</a> und <a href="http://chaosradio.ccc.de/cre118.html">Politik</a>. Und manchmal werden sogar <a href="http://chaosradio.ccc.de/cre130.html">langjährige Wünsche</a> erfüllt.</p>
<p>Absolute Highlights sind natürlich Folgen wie die Bayrische Hackerpost, Internet Memes und der Mifare-Hack. So ist es kaum verwunderlich, dass man nach späterstens zwei Wochen CRE freie Zeit anfängt unruhig den CRE Blog anzusurfen und den Podcast Feed zu abonnieren. Leider fehlt immer noch was zum Thema PHP, aber das ist ja per se uncool, deswegen wird das wohl auch nichts mehr. Schade eigentlich, vielleicht gibts ja nochmal was dediziertes zum Thema Flamewars, da kann man PHP dann immer gerne einstreuen. Überhaupt gibt CRE immer Anlass zur Diskussion, meistens weil ein Detail in irgendeinem Nebensatz nicht stimmte oder allgemein der Gast inkompetent war, aber eh klar: man selbst ist immer der bessere Experte (vorallem wenn es um DVCS geht, wo&#8217;s vielleicht sogar stimmen würde *rant*). Aber auch &#8220;ranten&#8221; gehört zur Informatikerausbildung. Also immer brav CRE hören.</p>
<p><a href="http://presently.de/374/chaosradio-express/">Was man am CRE verbessern kann?</a>:<br />
Ich finde die Idee mit einem Photo pro Podcast eigentlich ganz gut. Mehr fällt mir auch nicht ein.</p>
<p>Und jetzt weiter in der von <a href="http://tim.geekheim.de/2009/08/09/cre-kettenblogging-fr-den-weltfrieden/">Tim initiierten</a> Blogkette:<br />
<a href="http://meet-unix.org/blog/wordpress/?p=131">Zurück zu Nummer 12 in der Blogkette</a>.<br />
<a href="http://www.hardturm.ch/luz/2009/08/uber-cre-chaosradio-express/">Weiter zu Nummer 14 in der Blogkette</a>.</p>
<p>und jetzt weitermachen!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2009/08/cre/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
