Thursday, May 28, 2009

How to Install Mercurial on Windows 2008 with IIS 7

Because of IIS' non compliance with the CGI standard, the Windows Mercurial installer will install a version that produces a messed up Mercurial web interface; when publishing repositories over HTTP CGI.

In order to fix this the user must apply a small source level patch and rebuild the Mercurial source tree.

I know nothing of Python development.   So after weeks of brute force enthusiasm, I have cobbled together the following how-to from various how-tos and tutorials omitting things that are not essential.  If you're an Uber-Python programmer and have suggestions to streamline the instructions, please feel free to supply your comments below.


Get The Files

  1. Python 2.5.4 - http://www.python.org/download/releases/2.5.4/
    You will need this to compile, you can use a higher version I guess, but I haven't tried

  2. ActiveState Python 2.5.4 - http://www.activestate.com/activepython/
    Why another Python interpreter? Because the official Python above does not work with IIS 7.  Make sure to get the ActiveState Python version that is in line with the Python version you used to compile, in my case its version 2.5.4.

  3. MinGW - http://sourceforge.net/project/showfiles.php?group_id=2435&package_id=240780

  4. Mercurial 1.2.1 Source - http://www.selenic.com/hg/

  5. TortoiseHg - http://bitbucket.org/tortoisehg/stable/downloads/
    It just makes things easier, feel free to use command line hg after you compiled the source.

Installation

  1. Install Python 2.5.4 - The default folder is C:\Python25\ and this will be the directory I'll use for this instructions.

  2. Install MinGW - Pick Current and Minimal make sure to install to C:\MinGW

  3. Patch Mercurial
    • Unzip the Mercurial Source to C:\hg-release

    • Apply the following diff to hgwebdir_mod.py this file is located under a folder called hgweb:

      --- hgwebdir_mod.py.orig 2008-08-18 15:16:19.906250000 -0400
      +++ hgwebdir_mod.py 2008-08-18 15:16:43.109375000 -0400

      @@ -80,6 +80,10 @@
          try:
              virtual = req.env.get("PATH_INFO", "").strip('/')
      +       if virtual == 'hgwebdir.py':
      +           virtual = ''
      +       elif virtual[:11] == 'hgwebdir.py':
      +           virtual = virtual[12:]

              tmpl = self.templater(req)
              try:
                  ctype = tmpl('mimetype', encoding=util._encoding)
      @@ -278,6 +282,11 @@
          def config(section, name, default=None, untrusted=True):
              return self.parentui.config(section, name, default, untrusted)
      +   if (req.env['SERVER_SOFTWARE'].split('/')[0] == 'Microsoft-IIS'):
      +       if req.env['PATH_INFO'] == '/hgwebdir.py':
      +           req.env['PATH_INFO'] = '/'
      +       elif req.env['PATH_INFO'][:12] == '/hgwebdir.py':
      +           req.env['PATH_INFO'] = req.env['PATH_INFO'][13:]
           if self._baseurl is not None:
              req.env['SCRIPT_NAME'] = self._baseurl

  4. Build and Install Mercurial
    • Modify the Path environment variable as follows:
      C:\Python25\;blah blah blah;C:\MinGW\Bin\;
    • Open a command prompt and navigate to c:\hg-release
    • Enter command python setup.py build --force -c mingw32
    • Enter command python setup.py install --force --skip-build

  5. Create Some Repositories - I used TortoiseHG at this point to create
    C:\hg-repo\repo00 and C:\hg-repo\repo01

  6. Publish the Repositories
    • Navigate to c:\hg-release
    • Rename hgwebdir.cgi to hgwebdir.py
    • Open hgwebdir.py and change line 1 from #!/usr/bin/env python to
      #!c:/python25/python.exe
    • Save and close the file
    • Create a file called hgweb.config
    • Open hgweb.config and enter
      [paths]
      / = c:\hg-repo\**
    • Save and Close the file
    • Copy hgwebdir.py and hgweb.config to c:\inetpub\wwwroot\

  7. Enable Python in IIS
    • Uninstall Python 2.5.4
    • Install ActiveState Python - it will default to the same directory
    • Run "inetmgr"
    • Open your server instance and double click "Handler Mappings"  you can do this on your website or apply it server wide by clicking on your server node instead of the website node
    • Click "Add Script Map..." from the left pane
    • Enter *.py in the "Request path:" textbox
    • Enter c:\python25\python.exe -u "%s" "%s" in the "Executable:" textbox (MAKE SURE TO INCLUDE THE QUOTES)
    • Enter Python in the "Name" textbox
    • Click the "Request Restrictions..." button
    • Click the "Verbs" tab
    • Select the "One of the following verbs:"
    • Enter GET,HEAD,POST in the textbox
    • Click the "OK" Button
    • Click the "OK" Button
    • Click "Yes" on the "Add Script Map" dialog

  8. Test
    • Open browser and navigate to http://localhost/hgwebdir.py

  9. Congrats if you see the repository list and able to click in to view the details, but there's not much to see now.  Remember to use TortoiseHg to configure the "web" settings of the repositories, like access and SSL settings.
I'll play with this and post more articles in the future as I get accustomed to Mercurial.  Looks promising so far.