Congratulations!

[Valid Atom 1.0] This is a valid Atom 1.0 feed.

Recommendations

This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.

Source: http://feeds.feedburner.com/RkjTechBlog

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <feed xmlns="http://www.w3.org/2005/Atom">
  3.  
  4. <title>rkj tech blog</title>
  5. <link href="http://rkj.github.com//atom.xml" rel="self"/>
  6. <updated>2017-03-22T23:18:18+00:00</updated>
  7. <id>http://rkj.github.com/</id>
  8. <author>
  9.   <name>Roman Kamyk</name>
  10.   <email>roman.kamyk@gmail.com</email>
  11. </author>
  12.  
  13. <entry>
  14.   <title>Parsing huge OpenStreetMap's JOSM file using Nokogiri</title>
  15.   <link href="http://rkj.github.com//devcamp/josm/openstreetmap/ruby/parser/tutorial/2011/07/05/Parsing-OpenStreetMap-JOSM-data.html"/>
  16.   <updated>2011-07-05T00:00:00+00:00</updated>
  17.   <id>http://rkj.github.com//devcamp/josm/openstreetmap/ruby/parser/tutorial/2011/07/05/Parsing-OpenStreetMap-JOSM-data</id>
  18.   <content type="html">&lt;h1 id=&quot;background&quot;&gt;Background&lt;/h1&gt;
  19.  
  20. &lt;p&gt;While attending &lt;a href=&quot;/event/ssjs/devmeetigs/2011/07/04/DevCamp.html&quot;&gt;SSJS Devcamp&lt;/a&gt;
  21. I was having fun with &lt;a href=&quot;http://www.mongodb.org&quot;&gt;MongoDB&lt;/a&gt; and
  22. &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt;. To make some useful tests we had first to gather some data.  The plan was to import data into MySQL, next migrate it
  23. to NoSQL dbs and then make some tests/comparisons.  After a quick brainstorm we
  24. decided to create database with places/POIs. The greatest free geo repository I
  25. know is &lt;a href=&quot;http://openstreetmap.org&quot;&gt;OpenStreetMap&lt;/a&gt; and they are providing all
  26. theirs data for &lt;a href=&quot;http://wiki.openstreetmap.org/wiki/Downloading_data&quot;&gt;download&lt;/a&gt;.
  27. Whole repository is really huge (almost 17GiB of compressed data), so we
  28. settled for using only Poland data from a &lt;a href=&quot;http://download.geofabrik.de/osm/europe/&quot;&gt;nice
  29. mirror&lt;/a&gt;.&lt;/p&gt;
  30.  
  31. &lt;h1 id=&quot;data&quot;&gt;Data&lt;/h1&gt;
  32.  
  33. &lt;p&gt;Format specification is described on &lt;a href=&quot;http://wiki.openstreetmap.org/wiki/JOSM_file_format&quot;&gt;OSM
  34. wiki&lt;/a&gt;. It is pretty
  35. straightforward XML and contains mostly roads, but also cities, buildings,
  36. shops and ton of other things. This makes even Poland data pretty big (~150MiB
  37. compressed, ~2.5GiB uncompressed XML file). For us just the POI stuff was
  38. important so we had to go through whole file and cherry pick interesting
  39. entries.&lt;/p&gt;
  40.  
  41. &lt;h1 id=&quot;parser&quot;&gt;Parser&lt;/h1&gt;
  42.  
  43. &lt;p&gt;Because of the size of the XML, using a &lt;a href=&quot;http://en.wikipedia.org/wiki/XML#Document_Object_Model_.28DOM.29&quot;&gt;DOM
  44. parser&lt;/a&gt; on a
  45. laptop would not work because of memory usage. Obvious solution would be to use
  46. SAX parser, but I consider it to be totally backwards&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. I prefer &lt;a href=&quot;http://www.xmlpull.org/&quot;&gt;Pull
  47. Parsing&lt;/a&gt; so I searched for some nice parser,
  48. preferably in Ruby. As it turns out, the excellent
  49. &lt;a href=&quot;http://nokogiri.org&quot;&gt;Nokogiri&lt;/a&gt; have one as
  50. &lt;a href=&quot;http://nokogiri.org/Nokogiri/XML/Reader.html&quot;&gt;XML::Reader&lt;/a&gt;.&lt;/p&gt;
  51.  
  52. &lt;h1 id=&quot;code&quot;&gt;Code&lt;/h1&gt;
  53.  
  54. &lt;p&gt;The import was broken into two phases. In phase one the interesting data was
  55. taken from the XML and saved as JSON (it could be any other format of course).
  56. In the second phase it was read and inserted into MySQL. It allowed writing
  57. phase two code while phase one was running and was generally more error
  58. resistant (errors in phase two didn’t cause whole import to be rerun).&lt;/p&gt;
  59.  
  60. &lt;p&gt;Phase one code from &lt;a href=&quot;https://github.com/rkj/devcamp-ssjs-db/blob/master/osm/parse-osm.rb&quot;&gt;GitHub/parse-osm.rb&lt;/a&gt;:&lt;/p&gt;
  61.  
  62. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
  63. 2
  64. 3
  65. 4
  66. 5
  67. 6
  68. 7
  69. 8
  70. 9
  71. 10
  72. 11
  73. 12
  74. 13
  75. 14
  76. 15
  77. 16
  78. 17
  79. 18
  80. 19
  81. 20
  82. 21
  83. 22
  84. 23
  85. 24
  86. 25
  87. 26
  88. 27
  89. 28
  90. 29
  91. 30
  92. 31
  93. 32
  94. 33
  95. 34
  96. 35
  97. 36
  98. 37
  99. 38
  100. 39
  101. 40
  102. 41
  103. 42
  104. 43
  105. 44
  106. 45
  107. 46
  108. 47
  109. 48
  110. 49
  111. 50
  112. 51
  113. 52
  114. 53
  115. 54
  116. 55
  117. 56
  118. 57
  119. 58
  120. 59
  121. 60
  122. 61
  123. 62
  124. 63
  125. 64
  126. 65
  127. 66
  128. 67
  129. 68
  130. 69
  131. 70
  132. 71
  133. 72
  134. 73
  135. 74
  136. 75
  137. 76
  138. 77
  139. 78
  140. 79
  141. 80
  142. 81
  143. 82
  144. 83
  145. 84
  146. 85
  147. 86
  148. 87
  149. 88
  150. 89
  151. 90
  152. 91
  153. 92
  154. 93&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env ruby&lt;/span&gt;
  155. &lt;span class=&quot;c1&quot;&gt;# Small script for scraping POIs from JOSM (http://wiki.openstreetmap.org/wiki/JOSM_file_format).&lt;/span&gt;
  156. &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'rubygems'&lt;/span&gt;
  157. &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'bundler/setup'&lt;/span&gt;
  158. &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'nokogiri'&lt;/span&gt;
  159. &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'json'&lt;/span&gt;
  160. &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'ap'&lt;/span&gt;
  161.  
  162. &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Parser&lt;/span&gt;
  163.  &lt;span class=&quot;c1&quot;&gt;# Tags in data that we ignore.&lt;/span&gt;
  164.  &lt;span class=&quot;no&quot;&gt;IGNORED_TAGS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;created_by&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  165.  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;
  166.    &lt;span class=&quot;c1&quot;&gt;# Map storing attribute name mapped on count of nodes containing it.&lt;/span&gt;
  167.    &lt;span class=&quot;c1&quot;&gt;# It is helpful to see what tags should be taken into account in the first place&lt;/span&gt;
  168.    &lt;span class=&quot;c1&quot;&gt;# during importing.&lt;/span&gt;
  169.    &lt;span class=&quot;vi&quot;&gt;@popular_attributes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  170.    &lt;span class=&quot;c1&quot;&gt;# number of nodes parsed&lt;/span&gt;
  171.    &lt;span class=&quot;vi&quot;&gt;@count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  172.    &lt;span class=&quot;c1&quot;&gt;# number of total xml nodes went through&lt;/span&gt;
  173.    &lt;span class=&quot;vi&quot;&gt;@total_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  174.    &lt;span class=&quot;c1&quot;&gt;# number of entries considered useful as POI&lt;/span&gt;
  175.    &lt;span class=&quot;vi&quot;&gt;@included&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  176.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  177.  
  178.  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  179.    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  180.    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  181.      &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;[&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  182.      &lt;span class=&quot;c1&quot;&gt;# Nokogiri reader created.&lt;/span&gt;
  183.      &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Nokogiri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;XML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  184.      &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  185.      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  186.    &lt;span class=&quot;k&quot;&gt;ensure&lt;/span&gt;
  187.      &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;{}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  188.      &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close&lt;/span&gt;
  189.      &lt;span class=&quot;n&quot;&gt;ap&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@popular_attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sort_by&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;reverse&lt;/span&gt;
  190.      &lt;span class=&quot;no&quot;&gt;STDERR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;
  191.      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@included&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; / &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@count&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; / &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@total_count&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  192.    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  193.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  194.  
  195.  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  196.    &lt;span class=&quot;c1&quot;&gt;# Search for 'node' tags because they contain data (points). Other tags&lt;/span&gt;
  197.    &lt;span class=&quot;c1&quot;&gt;# are discarder.&lt;/span&gt;
  198.    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;progress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'node'&lt;/span&gt;
  199.    &lt;span class=&quot;c1&quot;&gt;# Stop processing if end of file&lt;/span&gt;
  200.    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;
  201.    &lt;span class=&quot;c1&quot;&gt;# Create entry to be enriched with 'tag' data&lt;/span&gt;
  202.    &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;attribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;lat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lon&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;attribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;lon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  203.    &lt;span class=&quot;c1&quot;&gt;# Required fields to create usable POI.&lt;/span&gt;
  204.    &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  205.    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;progress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  206.      &lt;span class=&quot;c1&quot;&gt;# Next node found, so no more tags.&lt;/span&gt;
  207.      &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'node'&lt;/span&gt;
  208.      &lt;span class=&quot;c1&quot;&gt;# Only 'tag' are interesting.&lt;/span&gt;
  209.      &lt;span class=&quot;k&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'tag'&lt;/span&gt;
  210.      &lt;span class=&quot;c1&quot;&gt;# Each tag has form of &amp;lt;tag k=&quot;key&quot; v=&quot;value&quot; /&amp;gt;&lt;/span&gt;
  211.      &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;attribute&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;k&quot;&lt;/span&gt;
  212.      &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IGNORED_TAGS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;
  213.        &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;
  214.        &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;attribute&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;v&quot;&lt;/span&gt;
  215.        &lt;span class=&quot;vi&quot;&gt;@popular_attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  216.        &lt;span class=&quot;vi&quot;&gt;@popular_attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  217.      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  218.    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  219.    &lt;span class=&quot;c1&quot;&gt;# If all required tags were found.&lt;/span&gt;
  220.    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  221.      &lt;span class=&quot;vi&quot;&gt;@included&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  222.      &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  223.      &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  224.    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  225.    &lt;span class=&quot;n&quot;&gt;progress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  226.    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;
  227.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  228.  
  229.  &lt;span class=&quot;c1&quot;&gt;# Progress info&lt;/span&gt;
  230.  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;progress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry_found&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  231.    &lt;span class=&quot;vi&quot;&gt;@total_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  232.    &lt;span class=&quot;vi&quot;&gt;@count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entry_found&lt;/span&gt;
  233.    &lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;
  234.    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@total_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  235.      &lt;span class=&quot;no&quot;&gt;STDERR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.&quot;&lt;/span&gt;
  236.      &lt;span class=&quot;no&quot;&gt;STDERR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@included&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; / &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@count&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; / &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@total_count&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@total_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  237.      &lt;span class=&quot;no&quot;&gt;STDERR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;flush&lt;/span&gt;
  238.    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  239.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  240. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  241.  
  242. &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
  243.  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Usage: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$PROGRAM_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; osm_file output_json&quot;&lt;/span&gt;
  244.  &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  245. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  246. &lt;span class=&quot;no&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  247. &lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  248.  
  249. &lt;p&gt;Parsing whole file ran for a little over 250 seconds:&lt;/p&gt;
  250.  
  251. &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ruby parse-osm.rb poland.osm poi.json  247.94s user 3.07s system 99% cpu 4:13.08 total
  252. &lt;/code&gt;&lt;/pre&gt;
  253. &lt;/div&gt;
  254.  
  255. &lt;p&gt;Just copying the file take more than half of that:&lt;/p&gt;
  256.  
  257. &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cp -i poland.osm del.me  0.03s user 3.80s system 2% cpu 2:32.33 total
  258. &lt;/code&gt;&lt;/pre&gt;
  259. &lt;/div&gt;
  260.  
  261. &lt;p&gt;So the overhead is not too big. While running, the script used less than 4MiB
  262. of RAM, so also very acceptable. The result is 101 793 POI candidates[^2] that
  263. will be imported into the DB in the phase two. It will be described in more
  264. details in a following post, so stay tuned!&lt;/p&gt;
  265.  
  266. &lt;p&gt;react appropriately. Is is just wrong. I guess this API was easy to implement,
  267. but the result is a strange to use, and code using it ends up pretty mangled.
  268. [^2]: Extracted from 14 122 097 JOSM ‘node’s and 89 522 705 XML nodes;that gives processing of
  269. more than 362 440 XML tags per second.&lt;/p&gt;
  270.  
  271. &lt;div class=&quot;footnotes&quot;&gt;
  272.  &lt;ol&gt;
  273.    &lt;li id=&quot;fn:1&quot;&gt;
  274.      &lt;p&gt;I mean literally backwards. You, as a client, has to maintain state and&amp;nbsp;&lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
  275.    &lt;/li&gt;
  276.  &lt;/ol&gt;
  277. &lt;/div&gt;
  278. </content>
  279. </entry>
  280. <entry>
  281.   <title>SSJS Devcamp organized by DevMeetings.pl</title>
  282.   <link href="http://rkj.github.com//event/ssjs/devmeetigs/2011/07/04/DevCamp.html"/>
  283.   <updated>2011-07-04T00:00:00+00:00</updated>
  284.   <id>http://rkj.github.com//event/ssjs/devmeetigs/2011/07/04/DevCamp</id>
  285.   <content type="html">&lt;p&gt;I have always liked lightweight events, like BarCamp, and have tried to attend
  286. most of locally organized ones.  At the beginning of this year I have taken
  287. part in &lt;a href=&quot;http://www.jug.poznan.pl/materialy-ze-spotkan/materialy/1-poznanski-code-retreat/&quot;&gt;Poznań Code
  288. Retreat&lt;/a&gt;
  289. that was really great and intense coding experience, and I would love to take
  290. part in another one.&lt;/p&gt;
  291.  
  292. &lt;p&gt;In June I have received an invitation to a Server Side Javascript R&amp;amp;D Camp
  293. organized by &lt;a href=&quot;http://devmeetings.pl&quot;&gt;DevMeetings.pl&lt;/a&gt;. It was advertised as a
  294. three days long, advanced and practical developers meeting in a nice hotel in
  295. countryside. It didn’t take me long to accept the invitation and I was eagerly
  296. waiting for it.
  297. &lt;!--more--&gt;&lt;/p&gt;
  298.  
  299. &lt;p&gt;About twenty developers arrived on Thursday evening. For the first two days we
  300. worked in 4-5 people teams researching different topics: security, performance,
  301. NoSQL databases, integration, tools and practices. I worked on db team and will
  302. describe the results in some following post. On each day’s evening each team
  303. presented theirs results. This introduced a little pressure and made people
  304. work hard, as no one would like to present nothing…&lt;/p&gt;
  305.  
  306. &lt;p&gt;On Sunday, our final day, each team was given the same task: implement simple
  307. twitter clone using some of the technologies we have worked with. We started at
  308. 10am and the deadline was dinner at 2pm. I, together with
  309. &lt;a href=&quot;http://twitter.com/#!/bartaz&quot;&gt;Bartek&lt;/a&gt; and
  310. &lt;a href=&quot;http://twitter.com/#!/gustaff_weldon&quot;&gt;Bernard&lt;/a&gt; used RingoJS deployed on
  311. AppEngine, and the results are visible
  312. &lt;a href=&quot;http://devcamp.ringojs-twitter.appspot.com/&quot;&gt;here&lt;/a&gt;. I think it is quite
  313. impressive that now we have technologies and tools that allows us to build such
  314. things in a rather short time span. But to be honest we could use Python
  315. instead of RingoJS and there would be even less work to do
  316. (&lt;a href=&quot;http://www.appenginejs.org/&quot;&gt;appenginejs&lt;/a&gt; is rather incomplete and needed
  317. some patches).&lt;/p&gt;
  318.  
  319. &lt;p&gt;And again, after dinner each team showed theirs app, each was crowd beta-tested
  320. and the results of the camp was discussed. Sadly I had to leave before
  321. the conclusion but I have a feeling that SSJS was not voted as production-ready
  322. Java replacement… But more on that later.&lt;/p&gt;
  323.  
  324. &lt;p&gt;I would like to thank the organizers and all the great attenders, I had a great
  325. time and learned a lot about today’s hot technologies. See you next time!&lt;/p&gt;
  326.  
  327. </content>
  328. </entry>
  329. <entry>
  330.   <title>Email notification for multiple Mercurial repositories</title>
  331.   <link href="http://rkj.github.com//mercurial/notifications/2010/06/10/MercurialMultipleReposEmail.html"/>
  332.   <updated>2010-06-10T00:00:00+00:00</updated>
  333.   <id>http://rkj.github.com//mercurial/notifications/2010/06/10/MercurialMultipleReposEmail</id>
  334.   <content type="html">&lt;h1 id=&quot;mercurial-server&quot;&gt;Mercurial-server&lt;/h1&gt;
  335.  
  336. &lt;p&gt;Recently I have discovered the awesome &lt;a href=&quot;http://www.lshift.net/mercurial-server.html&quot;&gt;mercurial-server&lt;/a&gt;. It gives flexible access control, takes care of file permission (which was problematic in our previous setup) and allows to hide physical path of the repo from its URL. It also offers global configuration file, which can include hooks for all of the repositories.&lt;/p&gt;
  337.  
  338. &lt;p&gt;This offers an advantage in setting mail notifications using &lt;a href=&quot;http://mercurial.selenic.com/wiki/NotifyExtension&quot;&gt;NotifyExtension&lt;/a&gt;. In our previous setup we had included all the options and the template in each’s repository hgrc file. It required us to use some setup script for creating repositories and was somewhat clumsy - there were no feel of some global administration.&lt;/p&gt;
  339.  
  340. &lt;p&gt;Using global configuration allow us to easily put the configuration in the global rc file (in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/mercurial-server/remote-hgrc.d/&lt;/code&gt; dir) pointing to the template inside &lt;code class=&quot;highlighter-rouge&quot;&gt;hgadmin&lt;/code&gt; repo. There would still be need to put &lt;code class=&quot;highlighter-rouge&quot;&gt;usersubs&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;reposubs&lt;/code&gt; sections in each repository’ hgrc to specify who gets notification from which repo but it is now much cleaner and only info about specific repo goes to the hgrc.&lt;/p&gt;
  341.  
  342. &lt;h1 id=&quot;global-subscribers-configuration&quot;&gt;Global subscribers configuration&lt;/h1&gt;
  343.  
  344. &lt;p&gt;We wanted to get one step further and have some global configuration of subscribers in one place (and preferably in &lt;code class=&quot;highlighter-rouge&quot;&gt;hgadmin&lt;/code&gt; repo), but this required some extra effort. Since I have not found a way to use any variables in &lt;code class=&quot;highlighter-rouge&quot;&gt;reposubs&lt;/code&gt; section (which specifies who gets notified) we decided that all emails will go to local account (&lt;code class=&quot;highlighter-rouge&quot;&gt;hg@localhost&lt;/code&gt; at the server), and will include custom header (X-Repo) with the repository name (it was easily added in the style file).
  345. Then we use &lt;a href=&quot;http://www.procmail.org/&quot;&gt;procmail&lt;/a&gt; to handle routing:&lt;/p&gt;
  346.  
  347. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;:0c
  348. &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; ^X-Repo: &lt;span class=&quot;se&quot;&gt;\/&lt;/span&gt;.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
  349. &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  350.  &lt;span class=&quot;nv&quot;&gt;RPATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/repos/hgadmin/subscriptions/&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MATCH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
  351.  &lt;span class=&quot;nv&quot;&gt;DEFAULT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;cat /repos/hgadmin/subscriptions/default&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
  352.  &lt;span class=&quot;nv&quot;&gt;EMAIL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; -f &lt;span class=&quot;nv&quot;&gt;$RPATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then &lt;/span&gt;cat &lt;span class=&quot;nv&quot;&gt;$RPATH&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;else &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please create file /hgadmin/subscriptions/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MATCH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;!&quot;&lt;/span&gt; | mail -s &lt;span class=&quot;s2&quot;&gt;&quot;No subscriptions for repository &amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MATCH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;&amp;lt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$DEFAULT&lt;/span&gt;; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$DEFAULT&lt;/span&gt; ; &lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
  353.  :0
  354.  ! &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;EMAIL&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
  355. &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  356.  
  357. &lt;p&gt;If email have the &lt;code class=&quot;highlighter-rouge&quot;&gt;X-Repo&lt;/code&gt; header we search for subscribers in the  repository’s file (addresses can be separated by spaces or newlines). If there is no relevant file, a warning email is sent to the default address, so we do not forget about any created repo.&lt;/p&gt;
  358.  
  359. &lt;p&gt;Then procmail forwards the notification email to the subscribers and we are happy. Of course one could have even more advanced setup involving reading groups or privileges from LDAP, etc.&lt;/p&gt;
  360.  
  361. &lt;p&gt;But maybe you know a simpler way (without procmail) to achieve this?&lt;/p&gt;
  362.  
  363. &lt;p&gt;Below you see our configuration files:&lt;/p&gt;
  364.  
  365. &lt;h1 id=&quot;etcmercurial-serverremote-hgrcdnotifyrc&quot;&gt;/etc/mercurial-server/remote-hgrc.d/notify.rc&lt;/h1&gt;
  366.  
  367. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;nn&quot;&gt;[extensions]&lt;/span&gt;
  368. &lt;span class=&quot;py&quot;&gt;hgext.notify&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
  369.  
  370. &lt;span class=&quot;nn&quot;&gt;[hooks]&lt;/span&gt;
  371. &lt;span class=&quot;py&quot;&gt;changegroup.notify&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;python:hgext.notify.hook&lt;/span&gt;
  372.  
  373. &lt;span class=&quot;nn&quot;&gt;[email]&lt;/span&gt;
  374. &lt;span class=&quot;py&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;vcs-hg@itiner.pl&lt;/span&gt;
  375.  
  376. &lt;span class=&quot;nn&quot;&gt;[smtp]&lt;/span&gt;
  377. &lt;span class=&quot;py&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;localhost&lt;/span&gt;
  378.  
  379. &lt;span class=&quot;nn&quot;&gt;[notify]&lt;/span&gt;
  380. &lt;span class=&quot;py&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;false&lt;/span&gt;
  381. &lt;span class=&quot;py&quot;&gt;strip&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;0&lt;/span&gt;
  382. &lt;span class=&quot;py&quot;&gt;style&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/repos/hgadmin/styles/notify.style&lt;/span&gt;
  383.  
  384. &lt;span class=&quot;nn&quot;&gt;[reposubs]&lt;/span&gt;
  385. &lt;span class=&quot;c&quot;&gt;# key is glob pattern, value is comma-separated list of subscriber emails
  386. &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;hg@localhost&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  387.  
  388. &lt;h1 id=&quot;reposhgadminstylesnotifystyle&quot;&gt;/repos/hgadmin/styles/notify.style&lt;/h1&gt;
  389.  
  390. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;py&quot;&gt;start_files&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'files:      '&lt;/span&gt;
  391. &lt;span class=&quot;py&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' {file}'&lt;/span&gt;
  392. &lt;span class=&quot;py&quot;&gt;end_files&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\n'&lt;/span&gt;
  393. &lt;span class=&quot;py&quot;&gt;start_file_mods&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'files:      '&lt;/span&gt;
  394. &lt;span class=&quot;py&quot;&gt;file_mod&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' {file_mod}'&lt;/span&gt;
  395. &lt;span class=&quot;py&quot;&gt;end_file_mods&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\n'&lt;/span&gt;
  396. &lt;span class=&quot;py&quot;&gt;start_file_adds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'files+:     '&lt;/span&gt;
  397. &lt;span class=&quot;py&quot;&gt;file_add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' {file_add}'&lt;/span&gt;
  398. &lt;span class=&quot;py&quot;&gt;end_file_adds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\n'&lt;/span&gt;
  399. &lt;span class=&quot;py&quot;&gt;start_file_dels&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'files-:     '&lt;/span&gt;
  400. &lt;span class=&quot;py&quot;&gt;file_del&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' {file_del}'&lt;/span&gt;
  401. &lt;span class=&quot;py&quot;&gt;end_file_dels&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\n'&lt;/span&gt;
  402. &lt;span class=&quot;py&quot;&gt;start_file_copies&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'copies:     '&lt;/span&gt;
  403. &lt;span class=&quot;py&quot;&gt;file_copy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' {name} ({source})'&lt;/span&gt;
  404. &lt;span class=&quot;py&quot;&gt;end_file_copies&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\n'&lt;/span&gt;
  405. &lt;span class=&quot;py&quot;&gt;extra&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'extra:       {key}={value|stringescape}\n'&lt;/span&gt;
  406.  
  407. &lt;span class=&quot;py&quot;&gt;changeset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;X-Repo: {webroot|basename}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Subject: [{webroot|basename}] Mercurial changeset {rev} by {author}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;repository: https://vcs.itiner.pl/projects/{webroot|basename}/repository&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;changeset: {rev}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;user:      {author}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;date:      {date|date}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{file_mods}{file_adds}{file_dels}{file_copies_switch}{extras}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;description:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{desc}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  408.  
  409. </content>
  410. </entry>
  411. <entry>
  412.   <title>Automatically adding specific files before commit to Mercurial repo</title>
  413.   <link href="http://rkj.github.com//mercurial/2010/05/26/Mercurial-PreCommitAddFiles.html"/>
  414.   <updated>2010-05-26T00:00:00+00:00</updated>
  415.   <id>http://rkj.github.com//mercurial/2010/05/26/Mercurial-PreCommitAddFiles</id>
  416.   <content type="html">&lt;p&gt;When you create new files, you have to add them manually to the repository using either &lt;code class=&quot;highlighter-rouge&quot;&gt;hg add&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;hg addremove&lt;/code&gt; before issuing commit.&lt;/p&gt;
  417.  
  418. &lt;p&gt;If you often create some files you may want not to be bothered by this additional commands. Then you may use &lt;code class=&quot;highlighter-rouge&quot;&gt;hg commit -A&lt;/code&gt; which will add all new files automatically. You can even make an alias in your &lt;code class=&quot;highlighter-rouge&quot;&gt;.hgrc&lt;/code&gt; so every commit will have the option turned on.&lt;/p&gt;
  419.  
  420. &lt;p&gt;But there might be a problem if you have some unnecessary files (like logs) that are not specified in &lt;code class=&quot;highlighter-rouge&quot;&gt;.hgignore&lt;/code&gt;.
  421. If for some reason you cannot/do not want to create ignore rules for them, but you still want to add some files automatically with commit you may try a simple hook in your &lt;code class=&quot;highlighter-rouge&quot;&gt;.hgrc&lt;/code&gt;:&lt;/p&gt;
  422.  
  423. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;nn&quot;&gt;[hooks]&lt;/span&gt;
  424. &lt;span class=&quot;py&quot;&gt;pre-commit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;hg add . -I 'glob:**.c' -q || true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  425.  
  426. &lt;p&gt;Where you should of course change &lt;code class=&quot;highlighter-rouge&quot;&gt;'glob:**.c'&lt;/code&gt; to a pattern that will match your files.
  427. And do not confuse &lt;code class=&quot;highlighter-rouge&quot;&gt;pre-commit&lt;/code&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;precommit&lt;/code&gt; as they are totally different.&lt;/p&gt;
  428.  
  429. &lt;p&gt;Personally I do not use this, because always before issuing a commit I do:&lt;/p&gt;
  430.  
  431. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg status
  432. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg diff | mate &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  433.  
  434. &lt;p&gt;to see all the changes made and make sure that there are no leftover changes (like some random debugging printfs). But your situation may be different and you can give the hook a try.&lt;/p&gt;
  435. </content>
  436. </entry>
  437. <entry>
  438.   <title>Mercurial rollback can cause unexpected data loss</title>
  439.   <link href="http://rkj.github.com//mercurial/2010/02/18/Mercurial-rollback-dataloss.html"/>
  440.   <updated>2010-02-18T00:00:00+00:00</updated>
  441.   <id>http://rkj.github.com//mercurial/2010/02/18/Mercurial-rollback-dataloss</id>
  442.   <content type="html">&lt;p&gt;One of import differences between Mercurial and git is that in the former it is very hard to change the history of a repository. It is by design (although it can be ,,bypassed’’ with usage of plugins like MQ) and there are good reasons for it. This gives this warm, fuzzy feeling of security and makes harder to screw up really hard. So I consider it to be a real user-friendly aspect of Mercurial.&lt;/p&gt;
  443.  
  444. &lt;p&gt;But recently I was bitten by rollback command which undo last transaction (&lt;code class=&quot;highlighter-rouge&quot;&gt;commit&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;pull&lt;/code&gt;, and some other commands). I use it more often than I would like - mostly for undoing commit. It helps when I have forgot to add a file, or added some garbage, etc. It is suitable only before pushing changes somewhere, because otherwise they will back. But in my case, many simple mistakes are spotted right away, just after &lt;code class=&quot;highlighter-rouge&quot;&gt;commit&lt;/code&gt;, and maybe &lt;code class=&quot;highlighter-rouge&quot;&gt;status&lt;/code&gt;. They may be fixed without rollback - with a second commit, but it would unnecessary clobber history and make look silly. So if I make an erroneous commit I rollback, fix it and commit again. This procedure has worked fine many, many times. Until recently.&lt;/p&gt;
  445.  
  446. &lt;p&gt;Let see some contrived example. First we create a repo:&lt;/p&gt;
  447.  
  448. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;mkdir example
  449. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;example
  450. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg init
  451. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;a &amp;gt; a
  452. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg ci -Am &lt;span class=&quot;s1&quot;&gt;'a'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  453.  
  454. &lt;p&gt;Next we start some development in a branch:&lt;/p&gt;
  455.  
  456. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg branch b
  457. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;b &amp;gt; b
  458. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg ci -Am &lt;span class=&quot;s1&quot;&gt;'b'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  459.  
  460. &lt;p&gt;And next we make mistaken commit&lt;/p&gt;
  461.  
  462. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;d &amp;gt; c
  463. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg ci -Am &lt;span class=&quot;s1&quot;&gt;'c'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  464.  
  465. &lt;p&gt;Normally if we spot error right away we can issue:&lt;/p&gt;
  466.  
  467. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg rollback
  468. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;cat c
  469. d &lt;span class=&quot;c&quot;&gt;# ok, the file is there, we can fix it&lt;/span&gt;
  470. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg ci -Am &lt;span class=&quot;s1&quot;&gt;'c'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  471.  
  472. &lt;p&gt;But if we change a branch and then make a rollback we are screwed:&lt;/p&gt;
  473.  
  474. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg up default
  475. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg rollback
  476. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;cat c
  477. cat: c: No such file or directory &lt;span class=&quot;c&quot;&gt;# hmmm&lt;/span&gt;
  478. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;hg up b &lt;span class=&quot;c&quot;&gt;# let's go to our original branch&lt;/span&gt;
  479. &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;cat c
  480. cat: c: No such file or directory &lt;span class=&quot;c&quot;&gt;# still nothing :/&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  481.  
  482. &lt;p&gt;Since the commit is undone there is no &lt;code class=&quot;highlighter-rouge&quot;&gt;c&lt;/code&gt; in branch &lt;code class=&quot;highlighter-rouge&quot;&gt;b&lt;/code&gt;, so &lt;code class=&quot;highlighter-rouge&quot;&gt;update&lt;/code&gt; does not help. Fortunately for me, I had editor windows still opened, where I could use undo - to redo my changes. This time I have not lost anything. But there were some scary moments ;-).&lt;/p&gt;
  483.  
  484. &lt;p&gt;So I think the lesson is that if you are to make a rollback then be sure that you have not made any updates to the repository, because rollback will not even warn you.&lt;/p&gt;
  485. </content>
  486. </entry>
  487. <entry>
  488.   <title>Updated Rakefile for dealing with mercurial subrepos</title>
  489.   <link href="http://rkj.github.com//mercurial/rake/subrepositories/2010/02/13/Mercurial-subrepos-update.html"/>
  490.   <updated>2010-02-13T00:00:00+00:00</updated>
  491.   <id>http://rkj.github.com//mercurial/rake/subrepositories/2010/02/13/Mercurial-subrepos-update</id>
  492.   <content type="html">&lt;p&gt;Previously I have described my solution for subrepos in Mercurial. It was working nicely but, a little painfully, because you had to add every single Mercurial command you like to use as Rake task. After little googleing and scratching head I have come with a much nicer and general solution:&lt;/p&gt;
  493.  
  494. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Invokes any hg command on every repo.&quot;&lt;/span&gt;
  495. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hg:command&quot;&lt;/span&gt;
  496. &lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/^hg:/&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# rule selecting task starting with hg:&lt;/span&gt;
  497.  &lt;span class=&quot;n&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hg &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^hg:/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 'hg:' is in task name so we have to erase it&lt;/span&gt;
  498. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# and that's all folks :D&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  499.  
  500. &lt;p&gt;It is shorter and any command may be used, with any parameters, like:&lt;/p&gt;
  501.  
  502. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hg&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:status&lt;/span&gt;
  503. &lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hg&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:&quot;revert -a&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  504.  
  505. &lt;p&gt;and so on. Enjoy!&lt;/p&gt;
  506. </content>
  507. </entry>
  508. <entry>
  509.   <title>Shifting bytes left in different languages</title>
  510.   <link href="http://rkj.github.com//java/ruby/python/c/programming/2010/01/19/Shift-left.html"/>
  511.   <updated>2010-01-19T00:00:00+00:00</updated>
  512.   <id>http://rkj.github.com//java/ruby/python/c/programming/2010/01/19/Shift-left</id>
  513.   <content type="html">&lt;p&gt;Recently I must have had a really bad day, because I wrote a very stupid line of code in java:&lt;/p&gt;
  514.  
  515. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  516.  
  517. &lt;p&gt;when I wanted something a little simpler:&lt;/p&gt;
  518.  
  519. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  520.  
  521. &lt;p&gt;It gave unexpected (for me) behavior for shifting negative number of bits. I was having hope that shifting -1 place left would be equal to shifting 1 place right. But I was wrong, and the result was always zero, no matter what number I would try to shift.
  522. After a little search I have found: &lt;a href=&quot;http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html&quot; title=&quot;Bitwise and Bit Shift Operators&quot;&gt;Bitwise and Bit Shift Operators&lt;/a&gt; but is says nothing about this case.&lt;/p&gt;
  523.  
  524. &lt;p&gt;So I tried the same code in different languages to check how they behave. I started with my favorite – Ruby:&lt;/p&gt;
  525.  
  526. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  527.  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  528. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  529. &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [256, 256]&lt;/span&gt;
  530. &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [2, 2]&lt;/span&gt;
  531. &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [1, 1]&lt;/span&gt;
  532. &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [8, 8]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  533.  
  534. &lt;p&gt;Here the results were as I would like them to be.&lt;/p&gt;
  535.  
  536. &lt;p&gt;So what does our good, old friend C has to say?&lt;/p&gt;
  537.  
  538. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
  539. &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  540.  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;one&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  541.  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;two&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  542.  &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Shift(%d, %d): %d, %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;two&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  543. &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  544. &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  545.  &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 256, 256
  546. &lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 2, 2
  547. &lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 0, 1
  548. &lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 0, 0
  549. &lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  550. &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  551.  
  552. &lt;p&gt;It gives the same results as Java code. So I have to assume that it is described in some specification, or maybe is processor specific as shifting is simple assembler instruction.&lt;/p&gt;
  553.  
  554. &lt;p&gt;Last language I have tried is Ruby companion, Python, which behave more elegantly than C or Java:&lt;/p&gt;
  555.  
  556. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  557.  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;no&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  558. &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# (256, 256)&lt;/span&gt;
  559. &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# (2, 2)&lt;/span&gt;
  560. &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# ValueError: negative shift count&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  561.  
  562. &lt;p&gt;It actually checked for nonsensical value and raised an exception not giving me silently wrong (from my perspective) value.
  563. Sadly Python does not behave similarly for other basic mistakes, as:&lt;/p&gt;
  564.  
  565. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt;
  566. &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  567.  
  568. </content>
  569. </entry>
  570. <entry>
  571.   <title>Rakefile for dealing with mercurial subrepos</title>
  572.   <link href="http://rkj.github.com//mercurial/rake/subrepositories/2010/01/16/Mercurial-subrepos.html"/>
  573.   <updated>2010-01-16T00:00:00+00:00</updated>
  574.   <id>http://rkj.github.com//mercurial/rake/subrepositories/2010/01/16/Mercurial-subrepos</id>
  575.   <content type="html">&lt;p&gt;Subrepositories are quite an important things if you have any bigger project, where you can extract some libraries, modules, parts or any other such things. We have chosen Mercurial for version control, because it distributed (svn suxx ass), easy to use, and have good cross-platform support. Until version 1.3 it did not have any support for subrepositories, now it has one.
  576. It is far from perfect, but still much better than nothing. And I am sure it will get better, or eventually great.&lt;/p&gt;
  577.  
  578. &lt;p&gt;But for the time I have made quite simple Rakefile to help with subrepos. It works fine also with Mercurial versions less than 1.3. To use it you must have Ruby and gems: rake, term-ansicolor installed. Script assumes that you have subdirectories which are Mercurial repositiories and issues commands on each of them.&lt;/p&gt;
  579.  
  580. &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rake -T&lt;/code&gt; will give you list of available tasks:&lt;/p&gt;
  581. &lt;ul&gt;
  582.  &lt;li&gt;hg - generic task. You can invoke it like: &lt;code class=&quot;highlighter-rouge&quot;&gt;CMD=status rake hg&lt;/code&gt; and it will invoke CMD on every repository. In this case it will display status.&lt;/li&gt;
  583.  &lt;li&gt;pull, push, status - does what the name says.&lt;/li&gt;
  584.  &lt;li&gt;update - does pull -u.&lt;/li&gt;
  585.  &lt;li&gt;rebase - does pull –rebase. You must have &lt;code class=&quot;highlighter-rouge&quot;&gt;hgext.rebase=&lt;/code&gt; enabled for it to work.&lt;/li&gt;
  586.  &lt;li&gt;tag - invoked &lt;code class=&quot;highlighter-rouge&quot;&gt;rake tag name=0.1&lt;/code&gt; will tag each repository with tag 0.1.&lt;/li&gt;
  587.  &lt;li&gt;upto - invoked &lt;code class=&quot;highlighter-rouge&quot;&gt;rake upto rev=0.2&lt;/code&gt; will do &lt;code class=&quot;highlighter-rouge&quot;&gt;hg up -r 0.2&lt;/code&gt;. It makes sense with branches and tags, not so much with revisions, because each subrepo have its own history ;-).&lt;/li&gt;
  588.  &lt;li&gt;commit - if you have main repository, that contains all the others (as when you use Mercurial subrepo support) it will read commit messages from all the subrepos since last commit to the main repo and copy them into clipboard (works on a Mac only, I think).&lt;/li&gt;
  589. &lt;/ul&gt;
  590.  
  591. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
  592. 2
  593. 3
  594. 4
  595. 5
  596. 6
  597. 7
  598. 8
  599. 9
  600. 10
  601. 11
  602. 12
  603. 13
  604. 14
  605. 15
  606. 16
  607. 17
  608. 18
  609. 19
  610. 20
  611. 21
  612. 22
  613. 23
  614. 24
  615. 25
  616. 26
  617. 27
  618. 28
  619. 29
  620. 30
  621. 31
  622. 32
  623. 33
  624. 34
  625. 35
  626. 36
  627. 37
  628. 38
  629. 39
  630. 40
  631. 41
  632. 42
  633. 43
  634. 44
  635. 45
  636. 46
  637. 47
  638. 48
  639. 49
  640. 50
  641. 51
  642. 52
  643. 53
  644. 54
  645. 55
  646. 56
  647. 57
  648. 58
  649. 59
  650. 60
  651. 61
  652. 62
  653. 63
  654. 64
  655. 65
  656. 66
  657. 67
  658. 68
  659. 69
  660. 70
  661. 71
  662. 72
  663. 73
  664. 74
  665. 75
  666. 76
  667. 77
  668. 78
  669. 79
  670. 80
  671. 81
  672. 82
  673. 83
  674. 84
  675. 85
  676. 86
  677. 87
  678. 88
  679. 89
  680. 90&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  681.  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'term/ansicolor'&lt;/span&gt;
  682.  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;
  683.    &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ANSIColor&lt;/span&gt;
  684.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  685. &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;LoadError&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
  686.  &lt;span class=&quot;no&quot;&gt;STDERR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please install gem term-ansicolor to use this rakefile.&quot;&lt;/span&gt;
  687.  &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  688. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  689.  
  690. &lt;span class=&quot;vi&quot;&gt;@repos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;**/.hg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/.hg$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  691. &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  692.  &lt;span class=&quot;vi&quot;&gt;@repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  693.    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  694.      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;= &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;yellow&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&quot;&lt;/span&gt;
  695.      &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;cd &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  696.    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
  697.      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Failed because: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;red&lt;/span&gt;
  698.    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  699.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  700. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  701.  
  702. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Invokes any hg command on every repo. Provide CMD=command env variable.&quot;&lt;/span&gt;
  703. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:hg&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  704.  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'CMD'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;nil?&lt;/span&gt;
  705.    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Missing rev parameter&quot;&lt;/span&gt;
  706.  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
  707.    &lt;span class=&quot;n&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hg &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'CMD'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  708.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  709. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  710.  
  711. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Rebase&quot;&lt;/span&gt;
  712. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:rebase&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  713.  &lt;span class=&quot;n&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hg pull --rebase&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  714. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  715.  
  716. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Pull&quot;&lt;/span&gt;
  717. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:pull&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  718.  &lt;span class=&quot;n&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hg pull&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  719. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  720.  
  721. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Pull -u&quot;&lt;/span&gt;
  722. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:update&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  723.  &lt;span class=&quot;n&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hg pull -u&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  724. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  725.  
  726. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Status&quot;&lt;/span&gt;
  727. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:status&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  728.  &lt;span class=&quot;n&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hg status&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  729. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  730.  
  731. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Push&quot;&lt;/span&gt;
  732. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:push&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  733.  &lt;span class=&quot;n&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hg push&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  734. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  735.  
  736. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Tag repos. Provide name=tag_name param&quot;&lt;/span&gt;
  737. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:tag&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  738.  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;nil?&lt;/span&gt;
  739.    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Missing name parameter&quot;&lt;/span&gt;
  740.  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
  741.    &lt;span class=&quot;n&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hg tag &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  742.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  743. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  744.  
  745. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Update all repos to some revision. Provide rev=revision parameter.&quot;&lt;/span&gt;
  746. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:upto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  747.  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;nil?&lt;/span&gt;
  748.    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Missing rev parameter&quot;&lt;/span&gt;
  749.  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
  750.    &lt;span class=&quot;n&quot;&gt;on_repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hg update -C &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  751.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  752. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  753.  
  754. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Commits main repository and adds commits messages from every subrepo.&quot;&lt;/span&gt;
  755. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:commit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  756.  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'time'&lt;/span&gt;
  757.  &lt;span class=&quot;n&quot;&gt;last_date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;%x{hg tip --template '{date|isodate}'}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;
  758.  &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;strftime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%Y-%m-%d %H:%M&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  759.  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;reject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;basename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;itiner&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  760.    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%x{cd &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;amp;&amp;amp; hg log -d '&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;' --template=&quot;== {desc}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;&quot;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;strip&lt;/span&gt;
  761.    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;empty?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;= &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  762.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  763.  &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;strip&lt;/span&gt;
  764.  &lt;span class=&quot;c1&quot;&gt;# mac only?&lt;/span&gt;
  765.  &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;popen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'pbcopy'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'w'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  766.    &lt;span class=&quot;n&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  767.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  768.  &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hg commit &amp;amp;&amp;amp; hg push&quot;&lt;/span&gt;
  769. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  770. &lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  771.  
  772. </content>
  773. </entry>
  774. <entry>
  775.   <title>WYSIWYG in LaTeX with Rakefile</title>
  776.   <link href="http://rkj.github.com//latex/rake/2010/01/15/LaTeX-with-Rakefile.html"/>
  777.   <updated>2010-01-15T00:00:00+00:00</updated>
  778.   <id>http://rkj.github.com//latex/rake/2010/01/15/LaTeX-with-Rakefile</id>
  779.   <content type="html">&lt;p&gt;First tools to work with text I have learned where WYSIWYG and everywhere I looked they were praised. I really did not know the alternative and could not think a reason for it to exist in time of fast computers.
  780. But when I was exposed to LaTex I have instantly fell in love. Compared to Word it produces astonishingly beautiful output, takes whole of issues away  (numbering, chapters, pages with one sentence on it, positioning pictures and many, many more) and lets you focus on content (and structure) not on the final look (just like WriteBoard, I am using right now). But it has some issues. Actually my relationship with LaTeX is more like love-hate one. Sooner or later you will want to do some non-trivial thing to do. And you will either have to dig really deeply or find someone who did it before - and neither one may be easy, even on the shoulders of google.
  781. But knowing many its faults I still do know imagine writing a thesis in some word processor instead of LaTeX - that would be just plain stupid…&lt;/p&gt;
  782.  
  783. &lt;p&gt;I would like to share with you a simple script that makes life with LaTeX a little nicer. It is a Rakefile, so you need to have Ruby and Rake gem installed. It contains some simple tasks:&lt;/p&gt;
  784. &lt;ul&gt;
  785.  &lt;li&gt;compile - creates PDF document from the source files. It makes a couple of runs too much, but just to be sure that everything is on the right place, with bibliography, table of content, etc.&lt;/li&gt;
  786.  &lt;li&gt;clean - deletes all the messy and unneeded files if you would like to zip folder and send it somewhere.&lt;/li&gt;
  787.  &lt;li&gt;view - tries to display PDF in some reader available on your system.&lt;/li&gt;
  788.  &lt;li&gt;run - the most interesting part. I have stolen a concept from autotest. It checks the source files every second and if there are any changes it runs compile. If you have a sane PDF reader (like Sumatra on Windows, or Skim on Mac - not Adobe Reader) then it will refresh pdf as soon as it is ready. So you can have this rake task running in the background, and every time you hit save you will see changes in the pdf.&lt;/li&gt;
  789. &lt;/ul&gt;
  790.  
  791. &lt;p&gt;I consider this to be the best of both worlds. You can write freely for most time, but when you are finishing and want to take care of the final look you can almost instantly see changes in PDF and tweek quirks until you are satisfied.&lt;/p&gt;
  792.  
  793. &lt;p&gt;There are other tools to acomplish similar results. One of them is LyX, but there is a problem with retrieving source tex files from it. And you will need them at some point, to do some tweeking, or something that is not available in LyX, but can be done in LaTeX and it will be painful. So do not even start - its lame. There are also some editors with similar capabilities, but I have my favorite editor, you may have yours - and the scripts works with them all.&lt;/p&gt;
  794.  
  795. &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
  796. 2
  797. 3
  798. 4
  799. 5
  800. 6
  801. 7
  802. 8
  803. 9
  804. 10
  805. 11
  806. 12
  807. 13
  808. 14
  809. 15
  810. 16
  811. 17
  812. 18
  813. 19
  814. 20
  815. 21
  816. 22
  817. 23
  818. 24
  819. 25
  820. 26
  821. 27
  822. 28
  823. 29
  824. 30
  825. 31
  826. 32
  827. 33
  828. 34
  829. 35
  830. 36
  831. 37
  832. 38
  833. 39
  834. 40
  835. 41
  836. 42
  837. 43
  838. 44
  839. 45
  840. 46
  841. 47
  842. 48
  843. 49
  844. 50
  845. 51
  846. 52
  847. 53
  848. 54
  849. 55
  850. 56&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;no&quot;&gt;TEX_FILES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FileList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*.tex&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;figures/*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.bib&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.cls&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  851. &lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;thesis&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# name of main file without .tex suffix&lt;/span&gt;
  852. &lt;span class=&quot;no&quot;&gt;MAIN_TEX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.tex&quot;&lt;/span&gt;
  853. &lt;span class=&quot;no&quot;&gt;OUT_PDF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.pdf&quot;&lt;/span&gt;
  854.  
  855. &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;OUT_PDF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;TEX_FILES&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  856.  &lt;span class=&quot;sx&quot;&gt;%x{pdflatex -interaction=batchmode &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN_TEX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  857.  &lt;span class=&quot;sx&quot;&gt;%x{makeindex &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  858.  &lt;span class=&quot;sx&quot;&gt;%x{bibtex &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  859.  &lt;span class=&quot;sx&quot;&gt;%x{pdflatex -interaction=batchmode &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN_TEX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  860.  &lt;span class=&quot;sx&quot;&gt;%x{bibtex &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;.gls &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  861.  &lt;span class=&quot;sx&quot;&gt;%x{makeindex &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  862.  &lt;span class=&quot;sx&quot;&gt;%x{pdflatex -interaction=batchmode &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN_TEX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  863.  &lt;span class=&quot;sx&quot;&gt;%x{makeindex &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  864.  &lt;span class=&quot;sx&quot;&gt;%x{bibtex &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  865.  &lt;span class=&quot;sx&quot;&gt;%x{bibtex &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;.gls &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  866.  &lt;span class=&quot;sx&quot;&gt;%x{pdflatex -interaction=batchmode &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN_TEX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1}&lt;/span&gt;
  867.  &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;pdflatex -interaction=batchmode &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN_TEX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;gt;/dev/null&quot;&lt;/span&gt;
  868.  &lt;span class=&quot;n&quot;&gt;cp&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAIN&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.pdf&quot;&lt;/span&gt;
  869. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  870.  
  871. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Removes unnecessery files&quot;&lt;/span&gt;
  872. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:clean&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  873.  &lt;span class=&quot;n&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FileList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*.aux&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*.bak&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*.log&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*.blg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.bbl&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.toc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.out&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.idx&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.ilg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.ind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;THESIS&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.pdf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.dep&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.glo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.gls&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  874. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  875.  
  876. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  877.  
  878. &lt;span class=&quot;s2&quot;&gt;&quot;Open text editor to edit files&quot;&lt;/span&gt;
  879. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:edit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  880.  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;$EDITOR&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;mate&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;vim&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;emacs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  881.    &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; *tex *bib Rakefile&quot;&lt;/span&gt;
  882.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Unable to find text editor.&quot;&lt;/span&gt;
  883. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  884.  
  885. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:run&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  886.  &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rake&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;OUT_PDF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  887.  &lt;span class=&quot;kp&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  888.    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  889.      &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;reenable&lt;/span&gt;
  890.      &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;invoke&lt;/span&gt;
  891.    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
  892.      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Error: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, sleeping for 15 seconds.&quot;&lt;/span&gt;
  893.      &lt;span class=&quot;no&quot;&gt;Kernel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;
  894.    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  895.    &lt;span class=&quot;no&quot;&gt;Kernel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;      
  896.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  897. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  898.  
  899. &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Shows Thesis&quot;&lt;/span&gt;
  900. &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;OUT_PDF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  901.  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;open&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;okular&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;kpdf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;acroread&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;viewer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  902.    &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;viewer&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;OUT_PDF&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  903.  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;or&lt;/span&gt;
  904.  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Unable to find any pdf viewer.&quot;&lt;/span&gt;
  905. &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  906. &lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  907.  
  908. </content>
  909. </entry>
  910. </feed>
  911.  

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid Atom 1.0" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

http://www.feedvalidator.org/check.cgi?url=http%3A//feeds.feedburner.com/RkjTechBlog

Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda