How the ConvertExtension works

This page documents the implementation of the ConvertExtension (henceforth, “convert”) as of main @ r7040.

If you are a user, you should read the ConvertExtension page instead. If you still intend to read this page, you should read ConvertExtension first, so that you have a full understanding of what the implementation is implementing.

Currently, this document is a very broad draft. It will have more details in time.

Inputs

Every VCS that convert supports as input is represented by a subclass of the abstract class common.converter_source. The repository to convert is represented by an instance of a source. For example, when converting from Subversion, the input repository is represented by an instance of convert.subversion.svn_source, which is a subclass of converter_source.

The converter_source class takes three arguments:

Additionally, it has a property named encoding, which is 'utf-8' by default.

If a converter_source subclass finds no valid repository at the given path, it raises the exception common.NoRepo. The subclass may also raise NoRepo if some library that it depends on isn't available.

The Subversion source (convert.subversion.svn_source) uses “url”, not “path”, as the name of its second argument, because Subversion works with URLs rather than paths. However, it does support local file paths; it uses the geturl function in the same module to silently upgrade a path to a URL. Additionally, the url argument is not optional.

Each converter_source class has a pair of abstract methods named before and after, which subclasses can use to perform any necessary preparation and clean-up.

Outputs

Output classes are called sinks. Every VCS that convert supports as output is represented by a subclass of the abstract class common.converter_sink.

The converter_sink class takes two arguments:

Unlike the converter_source class, the path argument here is not optional.

Additionally, it has a property named created_files, which is a list that holds the paths to files that the sink has created, so that the sink can unlink them if the conversion fails. The abstract class does not handle this clean-up; it leaves it to the subclasses.

Each converter_sink class has a pair of abstract methods named before and after, which subclasses can use to perform any necessary preparation and clean-up.

The convert command

The command is implemented in the convert.convcmd sub-module. Only the most basic requirements for a Mercurial extension command are in convert.__init__; the convert function there tail-calls convert.convcmd.convert (henceforth, convert).

The convert function calls two subroutines in the same module, convertsink and convertsource, to obtain sink and source instances for the destination and source repositories. These functions that iterate the mappings of VCS names to sink/source classes, trying each class in turn on the specified destination and source repositories.

The final step in the function is to create an instance of convcmd.converter, which is the class that actually performs the conversion.


CategoryInternals