Cool Git stuff from CollabNet Potsdam team

During my git trainings I often say that Git is land of freedom, and this is really true. Not many version control system would allow you to change something in history or permanently delete branch or tag. Git some times will prevent you from doing bad stuff, but you can easily say “shut up, I know what I’m doing” just by passing “force” flag (-f). Here I’m thinking about “force push” (aka “history rewrite”) when you can change something in repository history.

Local history rewrite is really useful when you are crafting yours commits. You can easily rearrange them, edit theirs content and commit message by using “rebase interactive”. I’m using this functionality on daily basis and cannot image working without freedom which it gives!

When we are talking about ability to rewrite remote history some people get really scared, especially in large organizations or those that needs to fallow some strict rules like banks and government orgs. From one hand Git and its “SHA-1 checksumming” ensures them that repository wasn’t changed … but from other hand Git allows changing something in past, of curse such change would be quickly spotted and can be fixed. Simple thought about occurrence of such event scares many enterprise companies, especially when they somehow find out about incident in Eclipse Foundation where almost all branches was accidentally deleted.

One of my first tasks in CollabNet was to provides a safety net against force pushes and branch deletion in Git. Our idea was to provide mechanism that could be easily activated and deactivated, will be accessible for regular users and administrators (regular user can resurrect rewritten history and deleted branch, administrators also can do that but also can permanently remove those entries) and protect whole (even deleted and rewritten history) against Git garbage collection. Base on those assumptions we come up with History Protection mechanism.  If you want know more about it you can watch our short movie or read my other blog post. There is lots more cool Git Enterprise features coming from my CollabNet’s team in Potsdam 😉

Gerrit User Summit and Hackathon, Eclipse DemoCamp Poznan

Last two weeks (8-23 November 2012) was really exhausting, first Gerrit User Summit and Hackathon in Google HQ, then on Thursday (22nd November) Eclipse DemoCamp in Poznan.

First things first: Gerrit User Summit.

This was two-day event in one of Google’s training center. I was really impressed how vibrant Gerrit community is; to be honest I didn’t expect so may people attending to this event and be so active during presentations. There was people not only from Android-oriented companies but also organizations like WikiMedia and hardware companies like Qualcomm or Garmin. First User Summit day includes presentations about server side plugins and improvements in Gerrit 2.5. Second day was mostly occupied by Prolog presentations, I’m really impressed how powerful Prolog rules are and now they can customize Gerrit workflow (eg. you can force at least two +1 votes before change can be submitted, or prevent author from submitting his own change or choose another submit type base on branch name). This day also includes my presentation about Web UI plugins. I’ve presented how simple it is to generate stub GWT and JavaScript based plugin projects, then how easily they can be build and deployed in Gerrit. Currently UI plugis are pretty limited, they can be loaded into UI and say ‘hello’, nothing more but IMO this is good starting point to further development. My slides can be found here.

Then Gerrit Hackathon begins.

Up to 15 persons was hacking Gerrit starting from 12th November. Most of them was focused on improving existing UI and extending its functionality. Useful features were added like:

  • editing topic branch name and commit message in place,
  • configurable dashboards,
  • customizable top level menus,
  • file level comments

were added. Gerrit get also new white look and feel and most of GWT RPC services was rewritten to be REST. My personal focus was on auth-plugins and together with Colby Ranger (Google) and Luca Milanesio (GerritForge) was working on this topic. During first two days we manage to come with draft API and first prototype implementation for handling authentication during git clone commands (using HTTP and SSH protocols). Then move to porting LDAP based authentication and switching Web UI interface to new implementation, unfortunate this appear to be not so easy. Couple hours before hackathon ends we presented hackish implementation that works (in our simple use case) now we need to polish it and make workable for all different kind of use cases 😉

I want to thank here Shawn Pearce for organizing those two awesome events and Google for hosting us in theirs headquarters. Also many thanks to all great developers that I had opportunity talk and code with during User Summit and Haskaton. Hope to see you all at next Gerrit Hackatahon and User Summit.

Eclipse DemoCamp Poznań

Next on my road map was Eclipse DemoCamp in Poznan, this is almost like a tradition that I’m participating in this event, some times as a attendee, some times as speaker. This time I was presenting short introduction to Gerrit. It went well, I got some questions during presentation and afterwards. It appears that Gerrit is already used in some companies in Poznań also some persons from audience was interested in adopting it in theirs organization.

As usually, DemoCamp in Poznań was a great opportunity to meet and chat with my old Eclipse friends: Krzysztof Daniel, Jacek Laskowski, Łukasz Stachowiak, Jacek Pospychała, Natalia Klimasz and others.

Many thanks for organizers (Łukasz Stachowiak and Natalia Klimasz) for organizing yet another great DemoCamp in Poznań. See you all next time! ;D

I’m joining CollabNet

After more then five years working at NCDC in Szczecin I decided to move on and start something new.

During that five years I learn a lot and worked with extraordinary people! Thanks to NCDC I meet great people at conferences (like GeeCon, 33rd Degree, Confitura) and Java User Group’s meetings. I know this for sure that I won’t be in this place with this knowledge and skills if I didn’t join NCDC back then. Thank you all!

But it’s time to move forward, meet new people and learn new things … since first of September 2012 I’m employed in CollabNet and will be working on Gerrit and TeamForge integration. Also part of my duties in CollabNet would be improving Gerrit, JGit and EGit projects so stay tuned for ours contributions 😉

Oh, and one last thing I’m moving to Berlin …

CodingDojo and gentle introduction into Fantom

Last Saturday I was participating in  CodingDojo organized by Szczecin JUG. Our task was to write simple parser that will take a text representation of minefield like “.*..*” (asterisk are mines, dots are empty fields) and transform it into string like this “1*11*”. In other words we was creating heart of the Saper game). It was unusual task because there was only one laptop and one projector, each of participants has 5 minutes to write some code (tests or implementation, of course we use TDD). After few hours of coding and discussions about approaches, data structures and algorithm that would be used we manage to write fully functional parser.

This was really strange experience for me, and to be honest I was little bit scared of … from one point of view this is strange, because I shared lots of code in EGit and other open source project and for sure I’m not scared by showing my code to other developers … but writing it in front of other people, and this filling that they are watching while I’m typing was really strange! But honestly I really like this and can recommend such experiment to everyone!

On my way back I’ve started thinking how same quasi-aplication could be implemented in Fantom. I’m almost sure that you are wondering “what the heck is Fantom”. Fantom is (yet another) JVM language … but it is quite different from others (at least from that I’ve herd about). What is different ? First of all it uses each own byte code; yes, this has some performance penalty, but with such approach its binaries can run on JVM, CLR, browser (yes its compile to JavaScript) and LLVM. Secondly it has build in test framework, build framework, modularity support, actors, truly immutable objects, object-to-string serialization etc. Last but not least, it distinguish nullable and not-nullable objects therefore you have null-contract build in in language syntax, compiler and documentation.  And of course it has support for functional programming and is statically typed … more information you  can find on fantom.org

Now when you know what is Fantom, we can dive into some code samples. My example application would be mentioned above minefield-parser. I would start from tests, and then move to implementation.

As I mentioned before Fantom has build in test framework, just create a file with fan extension, you can call it how you want but by convention file name is same as class name that would be inside (but this isn’t a hard rule). Yours test class need to extend Test (to be more specific sys::Test, sys is name of pod (pods are more or less equivalent with jars)).

class SaperTest : Test {

  Void testEmptyInput() {
    // given
    input := ""

    // when
    result := Parser().parse(input)

    // then
    verifyEq(result, "")
  }

Test methods must return Void type (notice uppercased notation) and name must start from ‘test’ (same as in JUnit3). To assert use verifyXY methods, simple as that. Below you will see full test suite for my Parser.parse method, you don’t need to scan/read all of them just look on first two.

  Void testTrowErrWhenIllegalCharactedIsPresent() {
    // given
    input := ".a"

    // when
    verifyErr(ArgErr#) {
      Parser().parse(input)
    }
  }

As you can notice,  first test has a strange notation in ‘then’ section, there is verifyErr(ArgErr#) { Parser().parse(input) }, what it means ? This is an assertion method that check does given line throws and ArgErr (with is an argument exception). ArgErr# is more or less equivalent to ArgErr.class (or IllegalArgumentException.class) in java. Second parameter for verifyErr method (yes, statement in curly brackets is an parameter) is actually code that should throw given exception. This actually example of passing function as a parameter and when it last (or single parameter) it can be passed as a block statement after method non-functional parameters.

Another thing that you can notice is that there is no new keyword or equivalent. Fantom constructors are some how similar to factory methods, you just mark them with ‘new‘ keyword in class definition fallowed with unique name (make is default one) and you have yours constructor.

Same as in other modern JVM languages default access level to method/constructor/class is ‘public’ and you don’t need to type it explicitly, also semicolons are not required at end of the line. Another commonly used feature in new JVM language is type inference, but comparing to Scala’s type inference, one used in Fantom is really simple, it can only infer variable types, you must explicitly declare return type and parameters types.

Rest of test test code is pretty much the same, so lets move to more interesting part … the implementation! Method parse should be understandable for every one since it is only calling private methods.

class Parser {

  Str parse(Str input) {
    lines := input.splitLines
    validateInput(lines)
    result := createMatrix(lines.size, lines[0].size)

    lines.each |line, i| {
      parseLine(line, result, i);
    }

    return convertToStr(result)
  }

Only code in line 8 and 9 could be little bit strange. So lines variable is an List of Str‘s (yes it is shorten notation of String), and we are calling each method on this array (when method takes no arguments or one function argument brackets can be skip); each method takes function with two parameters first is value of element, second is it position. Notation |value, i| { parseLine(…) } is declaration of function that takes two parameters with name value and i , types of those parameters are infer from each method parameter signature. So, this simple two line notation calls parseLine method on each input line, it is that simple! Lets move with rest of the code!

  private Void validateInput(Str[] lines) {
    firstLineSize := lines[0].size
    if (!lines.all |line| {
      line.size == firstLineSize && line.all |c| { c == '.' || c == '*' }
    })
      throw ArgErr("Line size mismatch or illegal character was used")
  }

Another strange notation can be found on line 17 and 18. In both lines we are calling all method that is defined on Str and List classes. In both cases it checks does all elements matches given boolean condition. This “simple” if statement checks does each line have same number of elements and don’t contain other chars then dots and asterisk. Yet another hint, if yours function/closure/method has only one statement you don’t need to use return keyword.

  private Int[][] createMatrix(Int row, Int cols) {
    Int[][] result := [,]
    row.times {
      result.add([,].fill(0, cols))
    }

    return result
  }

Next strange notation you can find in line 24. What the heck is that [,] ? This is sort cut for creating empty List. As you can notice type inference in Fantom works both ways, now it figures out that this empty list should be type of List[][].

In Fantom you don’t need to use for loops to repeat some code X times. There is times method on Int type, it takes function as a argument and it will call this function X times. Example of using this method can be found in line 25.

In line 26 you  can find example usage of fill method defined on List class. An empty list is created and then filled with zeros. So method createMattrix will return matrix with given size filled in with zeros. Simple as that .. and it only has 4 lines of code!

  private Void parseLine(Str input, Int[][] result, Int i) {
    input.each |c, j| {
      if (c == '*') {
        prevCol := j - 1
        nextCol := j + 1
        result[i][j] = -10
        if (j > 0)
          result[i][prevCol]++
        if (j < input.size - 1)
          result[i][nextCol]++
        range := prevCol.max(0)..nextCol.min(result[i].size - 1)
        if (i > 0)
          incrementInRange(result[i - 1], range)
        if (i < result.size -1)
          incrementInRange(result[i + 1], range)
      }
    }
  }

In line 33 we meet once again each method, I hope that you already know what it does 😉

Another interesting thing can be found in line 42; double dot operator. This is a code sugar for creating Range objects (it will be used in line 52), they are simplifying iterating over only range of elements. You just pass bottom boundary double-dots upper boundary and Fantom generates everything in between. There is also ‘..<‘ operator  for exclusive range.

  private Void incrementInRange(Int[] row, Range range) {
    row.eachRange(range) |value, p| {
      row[p]++
    }
  }

eachRange, yet another useful and interesting method in List class! I’m using it in line 52 to increment values in neighbourhood of filed with mine. Here I’m only interested in position of element (the p variable), but because position is second parameter of function I also need declare variable that will hold element value.

This is pretty much it, now rest of code in this gist should be understandable for you, if not (or you have further questions) leave me comment under this post.

Automatic Screen Detection And Configuration Under Awesome WM

Recently I’m mainly interested in automating my day-to-day tasks on Linux laptop. I’ve started with automating back-up process, now come time to automate external screen detection (and configuration).

For couple of months I was struggling with ZSH history to find XRandR commands that enables and disables external screen. During that time I was almost sure that there is another way of handling this task … since eg. Gnome was doing it automatically. First idea was to find part of Gnome that is responsible for this feature and simply just integrate it with Aersome WM. But my from-time-to-time raw searches didn’t snow any interesting resources. Therefore I’ve decided that I must done it by my self … this is how screenful project was born.

What is screenful ?

It is simple extension to Awesome WM that allows you (with little knowledge of Lua and XRandR params) automatically configure connected screen. It integrates udev drm/change event with Awesome and XRandR. First of all there is udev rule that when drm/change event appears inform screenful about output change in particular card. Then screenful will “calculate” which card output was connected/disconnected, computes screen id based on EDID and finally run configured action. When configuration file doesn’t have specified configuration for this id then screenles will append commented configuration for it and run default action.

What is unique in screenful ?

Same as Awesome WM config file, the screenful config file is a Lua script! Therefore you can do anything you can imagine when external monitor is connected/disconnected. For example you can switch mplayer default audio output when you HD TV set is connected using HDMI cable then change it back when you disconnecting HDMI cable. Also you can reorganize yours tags and windows using Awesome Lua API … and more … Honestly I doubt that you can achieve similar behaviour in any different Window Manager 😉

Project is hosted on github if you encounter any issues or have ideas about new functionalities in screenful feel free to fork me, fill a bug or mail me 😉