For Beginners: How does Open Source work?

In the past few years I have been doing some open source contribution, and lately also initiated projects together with fellow programmers. Here I write about what I noticed.

First Stage: Contributing

You find something useful and start to play with it. Then you find a show-stopping bug, or you’d like to have a feature. You get in contact with the team, then submit issues to a bug tracker, if you find one. They might like your Ideas and ask for a patch. If it is important – and in many cases easier to fix then to rewrite on your own – you start fiddling with the code, do changes, write tests, submit patches.

If the team/individual applies the patches you are happy. Usually you have to maintain your own codebase until the feature is released – or you just compile from trunk 🙂

You might also just contribute documentation or tests.

Some personal experiences in this stage

Over the last couple of years I contributed to following projects:

For these I also submitted contributions, but they are still “in-progress”, as they have never been accepted 😦

Since these patch acceptance processes take time, but I needed the fixes, I run personal forks at github for maven-versions-plugin. A custom built artifact is even in use by one of my former customers, because I couldn’t get the patch accepted in time.

Second Stage: Initiating

You create something and publish your code as a zip, on github, codeplex, or somewhere else. Then People start liking it and begin submit patches or report issues. Some people create forks and start maintaining their own code based on yours. Or they (or you) ask for joining the project.

Some projects I founded or work on at this stage:

Third Stage: Team OSS

At this point things change a lot. Who is now in charge of the code base? Who builds+releases it? Who answers submitted issues? Well you have to find out, try to find a process that fits. This usually works quite well with people you personally know, co-workers or even friends. When interacting with others in the community, you’ll find out that everybody has a slightly different agenda: which is good for the project! But it makes it hard to make decisions.

With these projects we currently are in this stage (as of mid 2011)

Fourth Stage: Joining an umbrella organization

Now the need for a good process and for some infrastructure arises. You need hosting, build servers, issue tracker: This is what umbrella organizations like Eclipse Foundation, Apache Software Foundation, Outercurve Foundation or Codehaus help you with.

Apache, for example, is very vote-driven. If you want somebody to become a committer, you ask for a vote on the project’s private mailing list. If you want to release a version, you create it and deploy it to a staging are – then you ask for votes. We once released an Apache NPanday version without waiting the full 72 hours the vote needs to be open; we then had to remove (physically!!) the release from the download servers and maven repositories – as if it never happened.

Apache also offers some infrastructure: a CMS for documentation, Jira for issue-tracking, Hudson and Teamcity for Continuous Builds, SVN+GIT for Version Control, Mailing Lists (users, dev, private), committer directory, and so on.

Every team has to report to the Apache Board of Directors.

Read more on ASF here: http://www.apache.org/foundation/how-it-works.html

Eclipse works quite similarly, but has an even tighter organization. In the bigger projects you have fix release dates and  milestones. And there is something like a Project Lead, which is elected – but then authorized to make decisions alone – as I understand it.

In bigger projects usually a couple of companies donate code and/or full-time developers.

Around August 2010, after having submitted a couple of patches, I was voted to become a committer on Apache NPanday Incubator (Maven for .NET, Declarative Build and Release Management), which moved from Codeplex to ASF around October last year:

Under ASF it is still in incubation, but we hope to graduate to a top level project soon. This means will have our own PMC board and a apache top level domain (npanday.apache.org).

Supplementary: Commercial Support for OSS-Projects

Some companies are afraid of relying on a community for support. Therefore, companies that are very committed to a certain project, often offer Commercial Support options for open source projects.

For example, my employer, itemis AG, offers commercial support for Eclipse Modeling Xtext: Professional Services – Xtext

Happy coding! Happy committing!

Advertisement

New Minimod: FluentGenerics–Interacting with Generic Types and Type-Definitions

Sometimes, from a concrete type, you need to find out if it implements a specific generic type or interface, and even more interesting, which concrete type arguments it uses in it’s implementation.

Since this information can be “hidden” somewhere in the type hierarchy, I created some helper extension methods that help finding this information and released them as a Minimod. What is a Minimod?

It can answer these simple questions:

Is List<Int32> an IEnumerable<T>? yes
If it is, what are the type parameters? Int32

Is Dictionary<Int32,String> an IDictionary<TKey,TValue>? yes
If it is, what are the type parameters? Int32,String

This is the test/example code generating them:

[Test]
public void PrintExamples()
{
    printExample(typeof(List<int>), typeof(IEnumerable<>));
    printExample(typeof(Dictionary<int, string>), typeof(IDictionary<,>));
}

private static void printExample(Type type, Type genTypeDef)
{
    bool isOfGenericType = type.IsOfGenericType(genTypeDef);

    Console.WriteLine("Is {0} an {1}? {2}",
                      type.GetPrettyName(),
                      genTypeDef.GetPrettyName(),
                      isOfGenericType ? "yes." : "no.");

    if (isOfGenericType)
    {
        Console.WriteLine("If it is, what are the type parameters? "
                          + type.GetGenericArgumentsFor(genTypeDef)
                                .Select(_ => _.GetPrettyName())
                                .JoinStringsWith(", "));
    }
}

Summary

The Minimod adds to System.Type the following extension methods:

  • bool IsOfGenericType(this Type type, Type genericTypeDefinition)
  • Type[] GetGenericTypesFor(this Type type, Type genericTypeDefinition)
  • Type GetGenericTypeFor(this Type type, Type genericTypeDefinition)
  • Type[] GetGenericArgumentsFor(this Type type, Type genericTypeDefinition)

Get it!

It is published to Nuget as a Minimod: NuGet gallery

Other minimods are also available there: Packages – NuGet gallery

Original source code is found at: minimod/minimods – GitHub

Eclipse Labs Xtext Utils: Unit Testing helpers released

On Jul 28th we released a first version of our Xtext Unit Testing utilities. It supports makes unit-testing of Xtext-based grammars a no-brainer!!

Integration-style testing of files

image

A integration-style test covers many of the aspects you want to test, when writing new (test-first), or changing grammars (regression).

A simple test like this one:

@Test
public void person_no_attributes(){
    testFile("person_no_attributes.dmodel");
}

; will cover following functionality:

  • Model file parsed into EMF-model with no errors
  • All cross-references resolved
  • Validation passed; no warnings, no errors.
  • Serializer runs without errors
  • Formatter runs without errors
  • Serialize+Format exactly matches the input-files’ content

Further capabilities (need documentation!)

  • Fluent-API for validation assertion. Example:
// error line 1: person.name-feature is missing display name
assertConstraints(
  issues.errorsOnly()
             .inLine(1)
             .under(Modul.class, "person")
             .named("name")
             .oneOfThemContains("missing display name")
);
  • Switches for turning on/off serialization and formatter

Unit-testing of Parser- or Lexer-Rules

I’ll just show an example here:

@Test
public void id(){
    testTerminal("bar", /* token stream: */ "ID");
    testTerminal("bar3", /* token stream: */ "ID");
    
    testNotTerminal("3bar", /* unexpected */ "ID");
    
    // token streams with multiple token
    testTerminal("foo.bar", "ID", "'.'", "ID");
}

@Test
public void qualifiedNameWithWildcard(){
    testParserRule("foo.*", "QualifiedNameWithWildCard");
}

Download / Install

The Eclipse plugin is available on this P2 update site: http://xtext-utils.eclipselabs.org.codespot.com/git.distribution/releases/unittesting-0.9.x

The project is hosted on Google Code:

Source: http://code.google.com/a/eclipselabs.org/p/xtext-utils/source/checkout?repo=unittesting

Unit-Testing Documentation: Unit_Testing – xtext-utils – Unit testing – A collection of useful utilities and samples for Xtext based projects – Google Project Hosting