SCM Extensions

Source Control Management (SCM) plugins

This is a guide for people who want to write a new SCM plugin for DamageControl.

Writing the SCM class

DamageControl relies on the RubySCM API for interaction with underlying SCMs.
(RubySCM is an API that has been factored out of DamageControl's core).
The first step in adding support for a new SCM is to write a RubySCM class.

To prove compliance with the RubySCM API we have written a test suite that you can use. If your class passes that test suite,
you can be pretty sure your SCM class is good enough for DamageControl, and we'll happily add it to the codebase.

Write a test class that uses RubySCMs test suite

TODO

and a skeleton of your SCM class

TODO

Try to run the test:

ruby -Iserver server/rubyscm/MookyTest

This will probably fail, and it is time to fix the first error - implement the create method.

def initialize(mooky_dir)
  @mooky_dir = mooky_dir
end

def create(&line_proc)
  cmd(@mooky_dir, "mooky create", &line_proc)
end

Run the test again. Assuming your code is correct, you should now get a different error, which should lead you to
implement the next method. Just continue like this until all tests are passing

If your SCM's command line interface writes output that needs to be parsed, we recommend you implement the parsing
logic in a spearate class. That will allow you to test the parser without running the command.

RubySCM API

Here is a more detailed description of the required methods in the RubySCM API.

create(&line_proc)

(Local method)
This method should call the mooky command line that will create a new repository. Details about where it should be created
should be passed to the constructor.

Parameters

  • &line_proc - A block that should receive lines from the command(s)'s standard output.

import(import_dir, &line_proc)

(Local method)
This method should call the mooky command line that will recursively import files into the repository.

Parameters

  • import_dir - The directory to import.
  • &line_proc - A block that should receive lines from the command(s)'s standard output.

checkout(checkout_dir, scm_from_time, scm_to_time, &line_proc)

(Regular method)
This method should call the mooky command line that will check out previously imported sources to a working folder.

Parameters

  • checkout_dir - The directory where files should be checked out.
  • scm_from_time - The from-time (inclusive) for which we want files checked out. If nil, it means from the start of time.
  • scm_to_time - The to-time (inclusive) for which we want files checked out. If nil, it means up to the end of time.
  • &line_proc - A block that should receive lines from the command(s)'s standard output.

Return values

  • If nothing was checked out (i.e. uptodate), return nil.
  • If this is the first checkout, return the UTC timestamp of the last checkin, according to the SCM's clock.
  • If this was an update, (i.e. previously checked out, but not uptodate), return a ChangeSets object representing all
    the changes within the period.

commit(checkout_dir, commit_message, &line_proc)

(Local method)
Commits (checks in) all files that have been locally modified.

Parameters

  • checkout_dir - The directory where files should be checked out.
  • commit_message - The message that should go along with the commit.
  • &line_proc - A block that should receive lines from the command(s)'s standard output.

RubySCM optional API

If the SCM supports triggers, you can implement the following methods to allow installation (and uninstallation) of
triggers in the SCM. A trigger is a command that gets executed as the result of a commit (checkin).

install_trigger(trigger_command, trigger_files_checkout_dir, &line_proc)

This method should install the trigger command in such a way that it is executed when a commit to the SCM occurs.

Parameters

  • trigger_command - The command to run when the trigger is fired.
  • trigger_files_checkout_dir - A working folder that can optionally be used if the trigger installation
    requires it. (The parameter was added because CVS needs it).
  • &line_proc - A block that should receive lines from the command(s)'s standard output.

trigger_installed?(trigger_command, trigger_files_checkout_dir, &line_proc)

This method should return true if the trigger_command is installed, otherwise false.

uninstall_trigger(trigger_command, trigger_files_checkout_dir, &line_proc)

This method should install the trigger command in such a way that it no longer executed when a commit to the SCM occurs.

Web interface

If you write your own SCM plugin you would probably also want the DamageControl web admin to display it as a supported SCM in the project configuration pages. Every SCM has its own set of values that needs to be specified in order to check out code.

To enable your SCM to be configured from the web you need to implement something we call an SCMWebConfigurator.

See CVSWebConfigurator for an example on how to implement one.

Basically you need to create an erb file for the part of the form that is the SCM configuration. This will be included into configure.erb. You can also define JavaScript code that will be included in the top of the same page and you can execute JavaScript code on the onLoad event. The details of all this should become quite apparent by reading the code for the above mentioned CVSWebConfigurator.

To inform the DamageControl server about your new SCM you edit DamageControlServer.scm_configurator_classes in DamageControlServer.rb. You can also override this method in your own server configuration if you like.

Credit

If you contribute all of this with unit tests (see the SVNTest.rb and SVNLogParserTest.rb for inspiration) you will earn lots of DamageControl points. If you know how to write working code, but not how to write unit tests, we'd of course be happy to accept your contribution regardless.

If you don't know Ruby

If all of this is too big a task for you you can still contribute. The DaamageControl development team doesn't have acces to or knowledge of every single SCM out there. But we'd be able to implement this for you if you help us out with some extra information such as:

  • What are the command line commands for executing checkouts, updates and getting (history) logs.
  • What does the output of the log command typically look like.

Please contact us on dev@damagecontrol.codehaus.org for further information.

Labels

 
(None)