Mercurial Forests: A Real World Example (LuaDoc with CMake)

logo-droplets-50_textmedium170px-cmake_logo_textmediumlang-128_textmedium

(Update 2009/09/04: I added a new entry on Mercurial Subrepos which is slated to replace Forests.Link here)

In my last entry, we created a Git Superproject for LuaDoc and its dependencies. For comparison, let's repeat the example using the Mercurial Forest Extension.

Because the Forest is still an unofficial extension, you may need to configure/install things for your Mercurial installation. My example below assumes you have a working Forest extension installed. The following link contains instructions and a tutorial I based this example on.

http://www.selenic.com/mercurial/wiki/index.cgi/ForestExtension


The first step is to create the regular individual Mercurial repositories for each subproject. They can be found here:

Mercurial Repositories

Lua:

http://www.assembla.com/spaces/lua/trac_mercurial_tool

LuaSocket:

http://www.assembla.com/spaces/luasocket/trac_mercurial_tool

LuaSQL:

http://www.assembla.com/spaces/luasql/trac_mercurial_tool

LuaFileSystem:

http://www.assembla.com/spaces/luafilesystem/trac_mercurial_tool

LuaLogging:

http://www.assembla.com/spaces/lualogging/trac_mercurial_tool

LuaDoc:

http://www.assembla.com/spaces/luadoc/trac_mercurial_tool


Next I want to create a new Forest repository which starts out as just a regular Mecurial repository. This is where I add my Unification script and other support files that belong to the Forest as a whole, and not the individual subprojects.

$ mkdir LuaDocForest
											$ cd LuaDocForest
											$ cp /Location_of_Unification_Script/CMakeLists.txt .
											$ cp /Location_of_some_notes/Notes.txt .
											$ cp /Location_of_uninstall_scr/cmake_uninstall.cmake.in .
											$ hg init
											$ hg add .
											$ hg commit -m "Initial Forest repository creation"
											$ hg push https://hg.assembla.com/luadocsuperforest
											


You can find the repository at Assembla I pushed to located here:

LuaDoc Mercurial Forest Repository

http://www.assembla.com/spaces/luadocsuperforest/trac_mercurial_tool


To test the repository, I remove the repository and re-clone it from Assembla.

$ cd ..
											$ rm -rf LuaDocSuperProject/
											$ hg clone https://hg.assembla.com/luadocsuperforest LuaDocForest
											$ cd LuaDocForest
											

  

Next we want to place the subprojects inside the LuaDocForest directory. Unlike git where we had a special 'git submodule add' command, with Mercurial, we use the standard clone command.

$ cd LuaDocForest
											$ hg clone https://hg.assembla.com/lua lua
											$ hg clone https://hg.assembla.com/luasocket luasocket
											$ hg clone https://hg.assembla.com/luasql luasql
											$ hg clone https://hg.assembla.com/luafilesystem luafilesystem
											$ hg clone https://hg.assembla.com/lualogging lualogging
											$ hg clone https://hg.assembla.com/luadoc luadoc
											


At this point, you are able to use the 'hg fclone' extension to clone the LuaDocForest project to another place. But I want to two things that are slightly different. First, I want to share the repository on a public server for everybody to reach. Second, I don't really want the server to have a deep copy of all the files. (In addition, it is worth noting that Assembla and all the other free Mercurial hosting I've found doesn't have the forest extension installed.) So a few more additional steps are required.

First we need to generate a file that contains a list of all the subprojects and their locations. Git implicitly creates this information for you through the 'git submodule add' command. Since Mercurial Forests are still only an extension and we haven't used any special Forest commands yet, this information doesn't exist yet, so we need to create this information ourselves. We can use the Forest command 'hg fsnap' which will create this list. We will save this information to a file and add it to the Forest repository so it can be used later. 

Note: With the snapshot.txt, I found I had to replace all the instances of 'None' with the word 'tip'.
$ hg fsnap -t > snapshot.txt
											# Edit snapshot.txt to replace all 'None' with 'tip'
											$ hg add snapshot.txt
											$ hg commit -m "Adding snapshot list."
											$ hg push
											


Your Turn:

So now you can grab the Forest from the public server. Like Git (and also because the server knows nothing about the Forest extension), it is a two step process. You must clone the Forest repository first. Then to pull the submodules, you run a second command, 'hg fseed snapshot.txt'. 

$ hg clone https://hg.assembla.com/luadocsuperforest MyLuaDocForest
											$ cd MyLuaDocForest
											$ hg fseed snapshot.txt

You can go inside each submodule and work as a normal Mercurial repository. From the top-level Forest directory, you also have the option to use 'hg pull' and 'hg push'. These commands don't seem to be particularly complicated. They seem to just traverse through each of your submodules and run 'hg pull' or 'hg push' respectively.


Building via CMake:

For completeness, I repeat my instructions on how to build LuaDoc with the CMake Unification script. It is identical to what we did with Git. (The build script doesn't care about the SCM system.) As usual with CMake, you are encouraged to do out-of-source builds. So starting at the directory above MyLuaDocForest, do:

$ mkdir BUILD
											$ cd BUILD
											$ ccmake ../MyLuaDocForest
											# Configure with the GUI and Generate.
											$ make
											$ make install  # may need to run with higher access
											


If all works well, everything should build and things will be installed. To uninstall, I have implemented an uninstall target so you can just do:

$ make uninstall  # may need to run with higher access
											
There is also a file generated in your BUILD directory called install_manifest.txt which lists all the files installed in case something is broken.


Running:

Make sure you set up your environment corrently, e.g.:

$ export LUA_CPATH='/usr/local/lib/lua/5.1/?.so;;'
											$ export LUA_PATH='/usr/local/share/lua/5.1/?.lua;;'
											$ export PATH=/usr/local/bin:$PATH

The executable to LuaDoc is called luadoc (luadoc.exe for Windows). Assuming your path is setup correctly, you should just be able to type that in and run it. You will get a prompt of different command switches and arguments you are expected to pass. Find a Lua script and give it a try.


If you are having problems, to test if Lua and the modules were installed correctly, you might try running lua and loading LuaSocket:

$ lua
											Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
											> socket = require("socket")
											> print(socket._VERSION)
											LuaSocket 2.0.2

If lua runs, but the module fails to load, there is probably something wrong with your LUA_*PATH. (Or something was installed to the wrong location.)


Reference Articles:

Copyright © PlayControl Software, LLC / Eric Wing