=== added file 'Makefile.win32'
--- Makefile.win32	1970-01-01 00:00:00 +0000
+++ Makefile.win32	2007-12-12 05:52:11 +0000
@@ -0,0 +1,64 @@
+PACKAGE = jhbuild
+VERSION = 0.1
+
+CC = gcc
+CFLAGS = -Wall -O2
+
+bindir=$(HOME)/bin
+desktopdir=$(HOME)/.local/share/applications
+
+all: install-check
+	@echo 'Run "make install" to install.'
+
+install-check: install-check.c
+	@cp install-check.sh install-check	
+	@chmod +x install-check 
+
+update:
+	svn update --quiet
+
+install: install-check
+	@echo "Creating $(bindir)/jhbuild"
+	@mkdir -p $(bindir)
+	@sed "s,@jhbuilddir@,`pwd`,g" < jhbuild.in > $(bindir)/jhbuild
+	@chmod a+x $(bindir)/jhbuild
+
+	@echo "Creating $(desktopdir)/jhbuild.desktop"
+	@mkdir -p $(desktopdir)
+	@cp jhbuild.desktop $(desktopdir)
+	@echo "Exec=$(bindir)/jhbuild gui" >> $(desktopdir)/jhbuild.desktop
+
+	/usr/bin/install -m755 install-check $(bindir)/install-check
+
+distdir = $(PACKAGE)-$(VERSION)
+dist:
+	-rm -rf $(distdir)
+	mkdir $(distdir)
+	cp -p README COPYING ChangeLog Makefile jhbuild.in jhbuild.desktop $(distdir)/
+	cp -p *.c *.jhbuildrc $(distdir)/
+	mkdir $(distdir)/modulesets
+	cp -p modulesets/*.modules $(distdir)/modulesets/
+	cp -p modulesets/moduleset.dtd modulesets/moduleset.xsl $(distdir)/modulesets/
+	mkdir $(distdir)/patches
+	cp -p patches/*.patch $(distdir)/patches/
+	mkdir $(distdir)/jhbuild
+	cp -p jhbuild/*.py jhbuild/defaults.jhbuildrc $(distdir)/jhbuild/
+	mkdir $(distdir)/jhbuild/commands
+	cp -p jhbuild/commands/*.py $(distdir)/jhbuild/commands/
+	mkdir $(distdir)/jhbuild/frontends
+	cp -p jhbuild/frontends/*.py $(distdir)/jhbuild/frontends/
+	cp -p jhbuild/frontends/jhbuild.glade $(distdir)/jhbuild/frontends/
+	mkdir $(distdir)/jhbuild/modtypes
+	cp -p jhbuild/modtypes/*.py $(distdir)/jhbuild/modtypes/
+	mkdir $(distdir)/jhbuild/utils
+	cp -p jhbuild/utils/*.py $(distdir)/jhbuild/utils/
+	mkdir $(distdir)/scripts
+	cp -p scripts/*.py scripts/*.xsl scripts/*.deps scripts/*.exceptions $(distdir)/scripts/
+	mkdir $(distdir)/scripts/branch-violations
+	cp -p scripts/branch-violations/README scripts/branch-violations/find-branch-* \
+		$(distdir)/scripts/branch-violations/
+	chmod -R a+r $(distdir)
+	tar czf $(distdir).tar.gz $(distdir)
+	rm -rf $(distdir)
+
+.PHONY: all update install

=== added file 'install-check.sh'
--- install-check.sh	1970-01-01 00:00:00 +0000
+++ install-check.sh	2007-12-12 05:51:42 +0000
@@ -0,0 +1,2 @@
+#!/bin/sh
+/usr/bin/install $*

=== added file 'jhbuild/utils/download.py'
--- jhbuild/utils/download.py	1970-01-01 00:00:00 +0000
+++ jhbuild/utils/download.py	2007-12-12 07:09:00 +0000
@@ -0,0 +1,45 @@
+# Copyright (C) 2007  John 
+#
+#   download.py: helper functions for downloading urls
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+import urllib, urllib2
+from jhbuild.utils import httpcache
+from jhbuild.utils.cmds import has_command
+
+def _download_status_hook(count, blockSize, totalSize):
+    if totalSize:
+        progress = 100.0*float(count*blockSize)/float(totalSize)
+    else:
+        progress = 100.0
+    print 'Downloading: %2.1f%%' % progress
+
+def download_file(buildscript, url, localfile, nonetwork=False, cache=False):
+    try:
+        if cache == True:
+            localfile = httpcache.load(url, nonetwork=nonetwork)
+        else:
+            if has_command('wget'):
+                res = buildscript.execute(['wget', url, '-O', localfile])
+            elif has_command('curl'):
+                res = buildscript.execute(['curl', '-L', url, '-o', localfile])
+            else:
+                urllib.urlretrieve(url, localfile, _download_status_hook)
+    except urllib2.URLError, e:
+        raise Exception('could not download patch: %s (%s)' % (url,e))
+    except urllib2.HTTPError, e:
+        raise Exception('could not download patch: %s (%s)' % (url,e))
+    return localfile
+

=== added file 'jhbuild/utils/unpack.py'
--- jhbuild/utils/unpack.py	1970-01-01 00:00:00 +0000
+++ jhbuild/utils/unpack.py	2007-12-12 07:30:21 +0000
@@ -0,0 +1,95 @@
+# Copyright (C) 2007  Alberto Ruiz <aruiz@gnome.org>
+#
+#   unpack.py: helper functions for unpacking compressed packages
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+import tarfile
+import zipfile
+import os.path
+
+from jhbuild.utils.cmds import has_command
+
+def unpack_tar_file(localfile, target):
+    pkg = tarfile.open(localfile, 'r|*')
+    pkg.extractall(target)
+    pkg.close()
+
+def unpack_zip_file(localfile, target):
+    def attr_check_symlink(attr):
+        return attr == 0xA1ED0000
+
+    def attr_to_file_perm(attr):
+        perm = attr
+        perm &= 0x08FF0000
+        perm >>= 16
+        perm |= 0x00000100
+        return perm
+
+    def attr_to_dir_perm(attr):
+        perm = attr
+        perm &= 0xFFFF0000
+        perm >>= 16
+        perm |= 0x00000100
+        return perm
+
+    def makedirs(dir):
+        if not os.path.isdir(dir):
+            os.makedirs(dir)
+
+    pkg = zipfile.ZipFile(localfile, 'r')
+    for pkg_fileinfo in pkg.filelist:
+	pkg_file = pkg_fileinfo.filename
+        attr = pkg_fileinfo.external_attr
+
+        # Symlink
+        if attr_check_symlink(attr):
+            # This is not supported yet
+            continue
+
+        # Dir
+        if pkg_file.endswith('/'):
+            dir = os.path.join(target, pkg_file)
+            makedirs(dir)
+            os.chmod(dir, attr_to_dir_perm(attr))
+            continue
+
+        # File
+        if '/' in pkg_file:
+            dir = os.path.dirname(pkg_file)
+            dir = os.path.join(target, dir)
+            makedirs(dir)
+            
+        data = pkg.read(pkg_file)
+        file = open(os.path.join(target, pkg_file), 'wb')
+        file.write(data)
+        file.close()
+
+        os.chmod(os.path.join(target, pkg_file), attr_to_file_perm(attr))
+        
+def unpack_archive(buildscript, localfile, target):
+    if localfile.endswith('.bz2') and has_command('tar'):
+        buildscript.execute(['tar','-xjf','%s' % localfile],cwd=target)
+    elif (localfile.endswith('.gz') or localfile.endswith('.tgz')) and has_command('tar'):
+        buildscript.execute(['tar','-xzf','%s' % localfile],cwd=target)
+    elif localfile.endswith('.zip') and has_command('unzip'):
+        buildscript.execute(['unzip','%s' % localfile],cwd=target)
+    else:
+        if tarfile.is_tarfile(localfile):
+            unpack_tar_file(localfile, target)
+        elif zipfile.is_zipfile(localfile):
+            unpack_zip_file(localfile, target)    
+        else:
+            raise Exception("python doesnt know about this archive")
+

=== added file 'modulesets/test.modules'
--- modulesets/test.modules	1970-01-01 00:00:00 +0000
+++ modulesets/test.modules	2007-12-12 11:19:21 +0000
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<moduleset>
+	<repository type="svn" name="svn.greenbird" default="yes" href="https://svn.greenbirdsystems.com/"/>
+
+	<tarball id="foo" version="1.10">
+		<source href="http://www.johnstowers.co.nz/files/foo-1.10.tar.gz"/>
+	</tarball>
+
+	<tarball id="bar" version="0.1.3">
+		<source href="http://www.johnstowers.co.nz/files/bar-0.1.3.zip"/>
+	</tarball>
+
+        <tarball id="baz" version="1.2.3">
+        	<source href="http://www.johnstowers.co.nz/files/baz-1.2.3.tar.gz" md5sum="a9903bedb91bd71f34706687f14a0420"/>
+        	<patches>
+        		<patch file="http://www.johnstowers.co.nz/files/check-patch.patch"/>
+        	</patches>
+        </tarball>
+
+        <autotools id="bob">
+            <branch repo="svn.greenbird" />
+        </autotools>
+
+	<metamodule id="test">
+    		<dependencies>
+                    <dep package="foo"/>
+                    <dep package="bar"/>
+                    <dep package="baz"/>
+		</dependencies>
+	</metamodule>
+
+</moduleset>

=== added file 'test.jhbuildrc'
--- test.jhbuildrc	1970-01-01 00:00:00 +0000
+++ test.jhbuildrc	2007-12-12 11:19:42 +0000
@@ -0,0 +1,19 @@
+# -*- mode: python -*-
+moduleset = 'test'
+modules = ['test']
+
+# what directory should the source be checked out to?
+basepath = os.path.expanduser('~/ABC')
+checkoutroot = os.path.join(basepath,'checkout')
+prefix = os.path.join(basepath,'build123')
+
+# extra arguments to pass to all autogen.sh scripts
+# to speed up builds of gnome2, try '--disable-static --disable-gtk-doc'
+autogenargs = '--disable-gtk-doc'
+
+# set some environment variables
+os.environ['BAZ'] = 'yes'
+
+# Module specific args
+module_autogenargs['foo'] = autogenargs + ' --extra-arg=123'
+

=== modified file 'README'
--- README	2007-08-12 13:11:14 +0000
+++ README	2007-12-12 05:54:24 +0000
@@ -108,6 +108,12 @@
 Bootstrapping should only need to be done once (unless the
 requirements of some package change).
 
+Jhbuild on Windows
+------------------
+
+At this stage Jhbuild on windows is supported when run from the msys
+shell using the mingw32 compiler. To install Jhbuild from within msys 
+run "make -f Makefile.32 install"
 
 Using jhbuild
 -------------

=== modified file 'jhbuild.in'
--- jhbuild.in	2004-02-05 01:45:17 +0000
+++ jhbuild.in	2007-12-12 05:56:04 +0000
@@ -1,6 +1,9 @@
 #!/usr/bin/env python
 import sys
-sys.path.insert(0, '@jhbuilddir@')
+if sys.platform.startswith('win'):
+    sys.path.insert(0, 'C:/msys@jhbuilddir@')
+else:
+    sys.path.insert(0, '@jhbuilddir@')
 
 import jhbuild.main
 jhbuild.main.main(sys.argv[1:])

=== modified file 'jhbuild/config.py'
--- jhbuild/config.py	2007-11-18 20:02:27 +0000
+++ jhbuild/config.py	2007-12-12 06:15:48 +0000
@@ -36,7 +36,7 @@
                 'alwaysautogen', 'nobuild', 'makeclean', 'makecheck',
                 'use_lib64', 'tinderbox_outputdir', 'sticky_date',
                 'tarballdir', 'pretty_print', 'svn_program', 'makedist',
-                'makedistcheck', 'nonotify', 'cvs_program',
+                'makedistcheck', 'nonotify', 'cvs_program', 'notrayicon',
                 'checkout_mode', 'copy_dir', 'module_checkout_mode']
 
 env_prepends = {}

=== modified file 'jhbuild/defaults.jhbuildrc'
--- jhbuild/defaults.jhbuildrc	2007-10-11 09:26:00 +0000
+++ jhbuild/defaults.jhbuildrc	2007-12-12 06:24:15 +0000
@@ -2,6 +2,7 @@
 # This file holds the default values for the ~/.jhbuildrc file.
 # Do not copy this to ~/.jhbuildrc
 
+import sys
 import os
 
 # what modules to build?
@@ -60,11 +61,15 @@
 # whether to install to lib64 directories?  Currently this will default to
 # True on Linux AMD64, PPC64 or S390x systems, and False everywhere else.
 # Patches accepted to fix the default for other architectures.
-uname = os.uname()
-use_lib64 = (uname[0], uname[4]) in [ ('Linux', 'x86_64'),
+if sys.platform.startswith('win'):
+    #uname() not supported on windows
+    use_lib64 = False
+else:
+    uname = os.uname()
+    use_lib64 = (uname[0], uname[4]) in [ ('Linux', 'x86_64'),
                                       ('Linux', 'ppc64'),
                                       ('Linux', 's390x') ]
-del uname
+    del uname
 
 # default buildscript.  You should probably leave this as the default.
 # In particular, don't set it to 'gtk'.
@@ -85,8 +90,14 @@
 # program to use for cvs
 cvs_program = 'cvs'
 
-# whether not to emit notifications through the notification daemon
-nonotify = False
+if sys.platform.startswith('win'):
+    notrayicon = True
+    nonotify = True
+else:
+    # Show a tray icon using zenity
+    notrayicon = False
+    # whether not to emit notifications through the notification daemon
+    nonotify = False
 
 # whether to run tests in real X and not in Xvfb
 noxvfb = False

=== modified file 'jhbuild/frontends/autobuild.py'
--- jhbuild/frontends/autobuild.py	2007-05-28 19:07:27 +0000
+++ jhbuild/frontends/autobuild.py	2007-12-12 06:15:48 +0000
@@ -98,7 +98,7 @@
                 os.environ[k] = 'C'
 
         if self.verbose:
-            self.trayicon = trayicon.TrayIcon()
+            self.trayicon = trayicon.TrayIcon(config)
 
     def message(self, msg, module_num=-1, skipfp = False):
         '''Display a message to the user'''

=== modified file 'jhbuild/frontends/terminal.py'
--- jhbuild/frontends/terminal.py	2007-09-27 13:36:42 +0000
+++ jhbuild/frontends/terminal.py	2007-12-12 11:19:22 +0000
@@ -64,12 +64,11 @@
 class TerminalBuildScript(buildscript.BuildScript):
     def __init__(self, config, module_list):
         buildscript.BuildScript.__init__(self, config, module_list)
-        self.trayicon = trayicon.TrayIcon()
+        self.trayicon = trayicon.TrayIcon(config)
         self.notify = notify.Notify(config)
 
     def message(self, msg, module_num=-1):
         '''Display a message to the user'''
-        
         if module_num == -1:
             module_num = self.module_num
         if module_num > 0:
@@ -88,31 +87,34 @@
             action_target = module.name
         self.message('%s %s' % (action, action_target), module_num)
 
-    def execute(self, command, hint=None, cwd=None, extra_env=None):
+    def _execute(self, command, cwd=None, extra_env=None, capture_output=False):
         if not command:
             raise CommandError('No command given')
+        if not isinstance(command, list):
+            import traceback
+            traceback.print_exc()
+            raise CommandError('Command must be a list not a %s\n%s' % (type(command),command))
 
         kws = {
-            'close_fds': True
+            #close fds is not implemented on windows
+            'close_fds' :   sys.platform.startswith('win')==False,
+            #Shell breaks things on windows (launches explorer) so 
+            #Use Popen with a list instead of a string and make shell False
+            'shell'     :   False
             }
-        if isinstance(command, (str, unicode)):
-            kws['shell'] = True
-            pretty_command = command
-        else:
-            pretty_command = ' '.join(command)
+
+        pretty_command = ' '.join(command)
         print pretty_command
 
-        # get rid of hint if pretty printing is disabled.
-        if not self.config.pretty_print:
-            hint = None
-
+        #print output to console
         kws['stdin'] = subprocess.PIPE
-        if hint in ('cvs', 'svn', 'hg-update.py'):
+        kws['stdout'] = None
+        kws['stderr'] = None
+
+        #need to capture the output to check for conflicts in vcs commands
+        if capture_output == True:
             kws['stdout'] = subprocess.PIPE
             kws['stderr'] = subprocess.STDOUT
-        else:
-            kws['stdout'] = None
-            kws['stderr'] = None
 
         if cwd is not None:
             kws['cwd'] = cwd
@@ -127,8 +129,41 @@
             sys.stderr.write('Error: %s\n' % str(e))
             raise CommandError(str(e))
 
-        if hint in ('cvs', 'svn', 'hg-update.py'):
-            conflicts = []
+        return p
+
+    def execute(self, command, cwd=None, extra_env=None):
+        p = self._execute(
+                    command=command,
+                    cwd=cwd,
+                    extra_env=extra_env,
+                    capture_output=False
+                    )
+        
+
+        try:
+            p.communicate()
+        except KeyboardInterrupt:
+            try:
+                os.kill(p.pid, signal.SIGINT)
+            except OSError:
+                # process might already be dead.
+                pass
+        if p.wait() != 0:
+            pretty_command = ' '.join(command)
+            raise CommandError('########## Error running %s' % pretty_command, p.returncode)
+
+    def execute_vcs(self, command, hint=None, cwd=None, extra_env=None):
+        '''Executes a vcs command and checks for conflicts'''
+        p = self._execute(
+                    command=command, 
+                    cwd=cwd, 
+                    extra_env=extra_env,
+                    capture_output=True
+                    )
+
+        #Check for conflicts
+        conflicts = []
+        if hint in ('cvs', 'svn', 'hg'):
             def format_line(line, error_output, conflicts=conflicts):
                 if line[-1] == '\n': line = line[:-1]
                 if line.startswith('C '):
@@ -140,25 +175,42 @@
                     print '%s%s%s' % (t_colour[8], line, t_reset)
                 else:
                     print line
-            cmds.pprint_output(p, format_line)
-            if conflicts:
-                sys.stdout.write('\nConflicts during checkout:\n')
-                for line in conflicts:
-                    sys.stdout.write('%s  %s%s\n'
-                                     % (t_colour[12], line, t_reset))
-                # make sure conflicts fail
-                if p.returncode == 0 and hint == 'cvs': p.returncode = 1
-        else:
-            try:
-                p.communicate()
-            except KeyboardInterrupt:
-                try:
-                    os.kill(p.pid, signal.SIGINT)
-                except OSError:
-                    # process might already be dead.
-                    pass
-        if p.wait() != 0:
-            raise CommandError('########## Error running %s' % pretty_command, p.returncode)
+            retcode = cmds.pprint_output(p, format_line)
+        if conflicts != []:
+            sys.stdout.write('\nConflicts during checkout:\n')
+            for line in conflicts:
+                sys.stdout.write('%s  %s%s\n'
+                                 % (t_colour[12], line, t_reset))
+        if retcode != 0:
+            raise CommandError('########## Error running %s' % hint)
+
+    def execute_script(self, command, args_str='', cwd=None, extra_env=None):
+        '''Exectues a script that is not in PREFIX. Likely configure or autogen'''
+
+        # ----------------------------------------
+        # THIS IS THE MAIN WIN32 HACK
+        # ----------------------------------------
+        if sys.platform.startswith('win') and command[0].startswith('./'):
+            command = ['sh', command[0].replace('./','')] + command[1:]
+        
+        #Convert string arg to list
+        command += cmds.cmdstr2list(args_str)
+        self.execute(
+                command,
+                cwd=cwd,
+                extra_env=extra_env
+                )
+
+    def execute_make(self, make_command=[], args_str='', cwd=None, extra_env=None):
+        '''Executes make (cmd). Prepends any makeargs before the make_cmd'''
+        command = ['%s' % os.environ.get('MAKE', 'make')]
+        command += cmds.cmdstr2list(args_str)
+        command += make_command
+        self.execute(
+                command,
+                cwd=cwd,
+                extra_env=extra_env
+                )
 
     def start_phase(self, module, state):
         self.trayicon.set_icon(os.path.join(icondir,

=== modified file 'jhbuild/modtypes/autotools.py'
--- jhbuild/modtypes/autotools.py	2007-10-11 09:26:00 +0000
+++ jhbuild/modtypes/autotools.py	2007-12-12 07:33:42 +0000
@@ -134,38 +134,48 @@
         buildscript.set_action('Configuring', self)
 
         if buildscript.config.buildroot and self.supports_non_srcdir_builds:
-            cmd = self.get_srcdir(buildscript) + '/' + self.autogen_sh
+            cmd = ['%s/%s' % (self.get_srcdir(buildscript),self.autogen_sh)]
         else:
-            cmd = './' + self.autogen_sh
-        cmd += ' --prefix %s' % buildscript.config.prefix
+            cmd = ['./%s' % self.autogen_sh]
+        cmd.append('--prefix=%s' % buildscript.config.prefix)
         if buildscript.config.use_lib64:
-            cmd += " --libdir '${exec_prefix}/lib64'"
-        cmd += ' %s' % self.autogenargs
-
-        if self.autogen_sh == 'autoreconf':
-            buildscript.execute(['autoreconf', '-i'], cwd=builddir)
-            cmd = cmd.replace('autoreconf', 'configure')
-            cmd = cmd.replace('--enable-maintainer-mode', '')
-
-        # Fix up the arguments for special cases:
-        #   tarballs: remove --enable-maintainer-mode to avoid breaking build
-        #   tarballs: remove '-- ' to avoid breaking build (GStreamer weirdness)
-        #   non-tarballs: place --prefix and --libdir after '-- ', if present
-        if self.autogen_sh == 'configure':
-            cmd = cmd.replace('--enable-maintainer-mode', '')
-            
-            # Also, don't pass '--', which gstreamer attempts to do, since
-            # it is royally broken.
-            cmd = cmd.replace('-- ', '')
-        else:
-            # place --prefix and --libdir arguments after '-- '
-            # (GStreamer weirdness)
-            if self.autogenargs.find('-- ') != -1:
-                p = re.compile('(.*)(--prefix %s )((?:--libdir %s )?)(.*)-- ' %
-                       (buildscript.config.prefix, "'\${exec_prefix}/lib64'"))
-                cmd = p.sub(r'\1\4-- \2\3', cmd)
-
-        buildscript.execute(cmd, cwd=builddir)
+            cmd.append("--libdir='${exec_prefix}/lib64'")
+
+        #FIXME: need to support other autogens......
+        if self.autogen_sh != 'autogen.sh':
+            raise BuildStateError('Only autogen.sh is supported (not %s)' % self.autogen_sh)
+        
+#        cmd += ' %s' % self.autogenargs
+#
+#        if self.autogen_sh == 'autoreconf':
+#            buildscript.execute(['autoreconf', '-i'], cwd=builddir)
+#            cmd = cmd.replace('autoreconf', 'configure')
+#            cmd = cmd.replace('--enable-maintainer-mode', '')
+#
+#        # Fix up the arguments for special cases:
+#        #   tarballs: remove --enable-maintainer-mode to avoid breaking build
+#        #   tarballs: remove '-- ' to avoid breaking build (GStreamer weirdness)
+#        #   non-tarballs: place --prefix and --libdir after '-- ', if present
+#        if self.autogen_sh == 'configure':
+#            cmd = cmd.replace('--enable-maintainer-mode', '')
+#            
+#            # Also, don't pass '--', which gstreamer attempts to do, since
+#            # it is royally broken.
+#            cmd = cmd.replace('-- ', '')
+#        else:
+#            # place --prefix and --libdir arguments after '-- '
+#            # (GStreamer weirdness)
+#            if self.autogenargs.find('-- ') != -1:
+#                p = re.compile('(.*)(--prefix %s )((?:--libdir %s )?)(.*)-- ' %
+#                       (buildscript.config.prefix, "'\${exec_prefix}/lib64'"))
+#                cmd = p.sub(r'\1\4-- \2\3', cmd)
+
+        buildscript.execute_script(
+            cmd, 
+            args_str=self.autogenargs, 
+            cwd=builddir
+            )
+
     do_configure.next_state = STATE_CLEAN
     do_configure.error_states = [STATE_FORCE_CHECKOUT]
 
@@ -175,8 +185,11 @@
 
     def do_clean(self, buildscript):
         buildscript.set_action('Cleaning', self)
-        cmd = '%s %s clean' % (os.environ.get('MAKE', 'make'), self.makeargs)
-        buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+        buildscript.execute_make(
+            make_command=['clean'],
+            args_str=self.makeargs,
+            cwd=self.get_builddir(buildscript)
+            )
     do_clean.next_state = STATE_BUILD
     do_clean.error_states = [STATE_FORCE_CHECKOUT, STATE_CONFIGURE]
 
@@ -185,8 +198,10 @@
 
     def do_build(self, buildscript):
         buildscript.set_action('Building', self)
-        cmd = '%s %s' % (os.environ.get('MAKE', 'make'), self.makeargs)
-        buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+        buildscript.execute_make(
+            args_str=self.makeargs,
+            cwd=self.get_builddir(buildscript)
+            )
     do_build.next_state = STATE_CHECK
     do_build.error_states = [STATE_FORCE_CHECKOUT, STATE_CONFIGURE]
 
@@ -196,8 +211,11 @@
 
     def do_check(self, buildscript):
         buildscript.set_action('Checking', self)
-        cmd = '%s %s check' % (os.environ.get('MAKE', 'make'), self.makeargs)
-        buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+        buildscript.execute_make(
+            make_command=['check'],
+            args_str=self.makeargs,
+            cwd=self.get_builddir(buildscript)
+            )
     do_check.next_state = STATE_DIST
     do_check.error_states = [STATE_FORCE_CHECKOUT, STATE_CONFIGURE]
 
@@ -207,10 +225,14 @@
     def do_dist(self, buildscript):
         buildscript.set_action('Creating tarball for', self)
         if buildscript.config.makedistcheck:
-            cmd = '%s %s distcheck' % (os.environ.get('MAKE', 'make'), self.makeargs)
+            cmd = 'distcheck'
         else:
-            cmd = '%s %s dist' % (os.environ.get('MAKE', 'make'), self.makeargs)
-        buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+            cmd = 'dist'
+        buildscript.execute_make(
+            make_command=[cmd],
+            args_str=self.makeargs,
+            cwd=self.get_builddir(buildscript)
+            )
     do_dist.next_state = STATE_INSTALL
     do_dist.error_states = [STATE_FORCE_CHECKOUT, STATE_CONFIGURE]
 
@@ -220,11 +242,16 @@
     def do_install(self, buildscript):
         buildscript.set_action('Installing', self)
         if self.makeinstallargs:
-            cmd = '%s %s' % (os.environ.get('MAKE', 'make'), self.makeinstallargs)
+            args = self.makeinstallargs
+            cmd = ''
         else:
-            cmd = '%s %s install' % (os.environ.get('MAKE', 'make'), self.makeargs)
-
-        buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+            args = self.makeargs
+            cmd = 'install'
+        buildscript.execute_make(
+            make_command=[cmd],
+            args_str=args,
+            cwd=self.get_builddir(buildscript)
+            )
         buildscript.packagedb.add(self.name, self.get_revision() or '')
     do_install.next_state = Package.STATE_DONE
     do_install.error_states = []

=== modified file 'jhbuild/modtypes/tarball.py'
--- jhbuild/modtypes/tarball.py	2007-10-15 13:11:58 +0000
+++ jhbuild/modtypes/tarball.py	2007-12-12 07:33:42 +0000
@@ -25,8 +25,9 @@
 
 from jhbuild.errors import FatalError, CommandError, BuildStateError
 from jhbuild.modtypes import Package, register_module_type, get_dependencies
-from jhbuild.utils import httpcache
 from jhbuild.utils.cmds import has_command
+from jhbuild.utils.download import download_file
+from jhbuild.utils.unpack import unpack_archive
 
 jhbuild_directory = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                                  '..', '..'))
@@ -127,7 +128,9 @@
         else:
             checkout_mode = buildscript.config.checkout_mode
         if checkout_mode == 'clobber':
-            buildscript.execute(['rm', '-rf', self.get_srcdir(buildscript)])
+            buildscript.execute(
+                ['rm', '-rf', self.get_srcdir(buildscript)]
+                )
             buildscript.packagedb.remove(self.name)
 
         if buildscript.packagedb.check(self.name, self.version):
@@ -143,14 +146,10 @@
             if self.check_localfile(buildscript) is not None:
                 # don't have a local copy
                 buildscript.set_action('Downloading', self, action_target=self.source_url)
-                if has_command('wget'):
-                    res = buildscript.execute(
-                            ['wget', self.source_url, '-O', localfile])
-                elif has_command('curl'):
-                    res = buildscript.execute(
-                            ['curl', '-L', self.source_url, '-o', localfile])
-                else:
-                    raise FatalError("unable to find wget or curl")
+                try:
+                    download_file(buildscript,self.source_url,localfile,nonetwork=False,cache=False)
+                except:
+                    raise FatalError("unable to download archive")
 
         status = self.check_localfile(buildscript)
         if status is not None:
@@ -163,18 +162,11 @@
         srcdir = self.get_srcdir(buildscript)
 
         buildscript.set_action('Unpacking', self)
-        if localfile.endswith('.bz2'):
-            buildscript.execute('bunzip2 -dc "%s" | tar xf -' % localfile,
-                                cwd=buildscript.config.checkoutroot)
-        elif localfile.endswith('.gz') or localfile.endswith('.tgz'):
-            buildscript.execute('gunzip -dc "%s" | tar xf -' % localfile,
-                                cwd=buildscript.config.checkoutroot)
-        elif localfile.endswith('.zip'):
-            buildscript.execute('unzip "%s"' % localfile,
-                                cwd=buildscript.config.checkoutroot)
-        else:
+        try:
+            unpack_archive(buildscript, localfile, buildscript.config.checkoutroot)
+        except:
             raise FatalError("don't know how to handle: %s" % localfile)
-        
+
         if not os.path.exists(srcdir):
             raise BuildStateError('could not unpack tarball')
     do_unpack.next_state = STATE_PATCH
@@ -185,17 +177,15 @@
             patchfile = ''
             if urlparse.urlparse(patch)[0]: # patch name has scheme
                 try:
-                    patchfile = httpcache.load(patch, nonetwork=buildscript.config.nonetwork)
-                except urllib2.URLError, e:
+                    patchfile = download_file(buildscript,patch,'',nonetwork=buildscript.config.nonetwork,cache=True)
+                except:
                     return (self.STATE_CONFIGURE, 'could not download patch', [])
-                except urllib2.HTTPError, e:
-                    return (self.STATE_CONFIGURE,
-                            'could not download patch (error: %s)' % e.code, [])
+
             elif self.uri:
                 for patch_prefix in ('.', 'patches'):
                     uri = urlparse.urljoin(self.uri, os.path.join(patch_prefix, patch))
                     try:
-                        patchfile = httpcache.load(uri, nonetwork=buildscript.config.nonetwork)
+                        patchfile = download_file(buildscript,uri,'',nonetwork=buildscript.config.nonetwork,cache=True)
                     except Exception, e:
                         continue
                     if not os.path.isfile(patchfile):
@@ -207,9 +197,11 @@
                 patchfile = os.path.join(jhbuild_directory, 'patches', patch)
             buildscript.set_action('Applying Patch', self, action_target=patch)
             try:
-                buildscript.execute('patch -p%d < "%s"' % (patchstrip,
-                                                           patchfile),
-                                    cwd=self.get_srcdir(buildscript))
+                cmd = ['patch','-p%d' % patchstrip,'--input=%s' % patchfile]
+                buildscript.execute(
+                    cmd,
+                    cwd=self.get_srcdir(buildscript)
+                    )
             except CommandError:
                 return (self.STATE_CONFIGURE, 'could not apply patch', [])
             
@@ -223,35 +215,38 @@
         if buildscript.config.buildroot and not os.path.exists(builddir):
             os.makedirs(builddir)
         buildscript.set_action('Configuring', self)
+
         if buildscript.config.buildroot and self.supports_non_srcdir_builds:
-            cmd = self.get_srcdir(buildscript) + '/configure'
+            cmd = [self.get_srcdir(buildscript) + '/configure']
         else:
-            cmd = './configure'
-        cmd += ' --prefix %s' % buildscript.config.prefix
+            cmd = ['./configure']
+        cmd.append('--prefix=%s' % buildscript.config.prefix)
         if buildscript.config.use_lib64:
-            cmd += " --libdir '${exec_prefix}/lib64'"
-        cmd += ' %s' % self.autogenargs
-
-        # Fix up the arguments for special cases:
-        #   remove '-- ' to avoid breaking build (GStreamer weirdness)
-        cmd = cmd.replace('-- ', '')
-
-        buildscript.execute(cmd, cwd=builddir)
+            cmd.append("--libdir='${exec_prefix}/lib64'")
+        buildscript.execute_script(
+            cmd, 
+            args_str=self.autogenargs, 
+            cwd=builddir
+            )
     do_configure.next_state = STATE_BUILD
     do_configure.error_states = []
 
     def do_build(self, buildscript):
         buildscript.set_action('Building', self)
-        cmd = '%s %s' % (os.environ.get('MAKE', 'make'), self.makeargs)
-        buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+        buildscript.execute_make(
+            args_str=self.makeargs,
+            cwd=self.get_builddir(buildscript)
+            )
     do_build.next_state = STATE_INSTALL
     do_build.error_states = []
 
     def do_install(self, buildscript):
         buildscript.set_action('Installing', self)
-        cmd = '%s %s install' % (os.environ.get('MAKE', 'make'), self.makeargs)
-        error = None
-        buildscript.execute(cmd, cwd=self.get_builddir(buildscript))
+        buildscript.execute_make(
+            make_command=['install'],
+            args_str=self.makeargs,
+            cwd=self.get_builddir(buildscript)
+            )
         buildscript.packagedb.add(self.name, self.version or '')
     do_install.next_state = Package.STATE_DONE
     do_install.error_states = []

=== modified file 'jhbuild/moduleset.py'
--- jhbuild/moduleset.py	2007-10-12 10:22:45 +0000
+++ jhbuild/moduleset.py	2007-12-12 07:03:32 +0000
@@ -32,7 +32,7 @@
 
 from jhbuild import modtypes
 from jhbuild.versioncontrol import get_repo_type
-from jhbuild.utils import httpcache
+from jhbuild.utils.download import download_file
 
 __all__ = ['load', 'load_tests']
 
@@ -202,11 +202,12 @@
             yield node
 
 def _parse_module_set(config, uri):
-    try:
-        filename = httpcache.load(uri, nonetwork=config.nonetwork)
-    except Exception, e:
-        raise FatalError('could not download %s: %s' % (uri, str(e)))
-    filename = os.path.normpath(filename)
+    if uri.startswith('http'):
+        try:
+            filename = download_file(None,uri,'',nonetwork=config.nonetwork,cache=True)
+        except Exception, e:
+            raise FatalError('could not download %s: %s' % (uri, str(e)))
+    filename = os.path.normpath(uri)
     try:
         document = xml.dom.minidom.parse(filename)
     except xml.parsers.expat.ExpatError, e:

=== modified file 'jhbuild/utils/cmds.py'
--- jhbuild/utils/cmds.py	2007-05-06 10:00:37 +0000
+++ jhbuild/utils/cmds.py	2007-12-12 07:33:53 +0000
@@ -206,3 +206,15 @@
             return True
     return False
 
+def cmdstr2list(string):
+    '''The opposite of windows list2cmds. Splits a string into
+    a list according to how *nix shell splits it'''
+    if string.count("|") != 0 or string.count(">") != 0 or string.count("<") != 0:
+        raise CommandError('Pipe command is non portable on windows: %s' % string)        
+    cmd = []
+    for a in string.split(' '):
+        if a != '':
+            cmd.append(a)
+    return cmd
+
+

=== modified file 'jhbuild/utils/trayicon.py'
--- jhbuild/utils/trayicon.py	2007-10-23 16:29:35 +0000
+++ jhbuild/utils/trayicon.py	2007-12-12 06:23:15 +0000
@@ -24,7 +24,10 @@
 class TrayIcon:
     proc = None
 
-    def __init__(self):
+    def __init__(self, config):
+        self.proc = None
+        if config and config.notrayicon:
+            return
         if not os.environ.get('DISPLAY'):
             return
         self._run_zenity()

=== modified file 'jhbuild/versioncontrol/svn.py'
--- jhbuild/versioncontrol/svn.py	2007-10-11 09:26:00 +0000
+++ jhbuild/versioncontrol/svn.py	2007-12-12 07:33:42 +0000
@@ -183,7 +183,11 @@
         if self.config.sticky_date:
             cmd.extend(['-r', '{%s}' % self.config.sticky_date])
 
-        buildscript.execute(cmd, 'svn', cwd=self.checkoutroot)
+        buildscript.execute_vcs(
+            cmd,
+            hint='svn',
+            cwd=self.checkoutroot
+            )
     
     def _checkout(self, buildscript, copydir=None):
         cmd = ['svn', 'checkout', self.module]
@@ -195,9 +199,17 @@
             cmd.extend(['-r', '{%s}' % self.config.sticky_date])
 
         if copydir:
-            buildscript.execute(cmd, 'svn', cwd=copydir)
+            buildscript.execute_vcs(
+                cmd,
+                hint='svn',
+                cwd=copydir
+                )
         else:
-            buildscript.execute(cmd, 'svn', cwd=self.config.checkoutroot)
+            buildscript.execute_vcs(
+                cmd,
+                hint='svn',
+                cwd=self.config.checkoutroot
+                )
 
     def _update(self, buildscript, copydir=None):
         opt = []
@@ -216,13 +228,21 @@
         else:
             cmd = ['svn', 'update'] + opt + ['.']
 
-        buildscript.execute(cmd, 'svn', cwd=outputdir)
+        buildscript.execute_vcs(
+            cmd,
+            hint='svn',
+            cwd=outputdir
+            )
 
         try:
             self._check_for_conflicts()
         except CommandError:
             # execute svn status so conflicts are displayed
-            buildscript.execute(['svn', 'status'], 'svn', cwd=self.srcdir)
+            buildscript.execute_vcs(
+                command=['svn', 'status'],
+                hint='svn',
+                cwd=self.srcdir
+                )
             raise
 
     def _check_for_conflicts(self):

=== modified file 'jhbuild/versioncontrol/tarball.py'
--- jhbuild/versioncontrol/tarball.py	2007-10-12 15:00:56 +0000
+++ jhbuild/versioncontrol/tarball.py	2007-12-12 07:30:21 +0000
@@ -27,6 +27,8 @@
 from jhbuild.versioncontrol import Repository, Branch, register_repo_type
 from jhbuild.utils.cmds import has_command
 from jhbuild.modtypes import get_branch
+from jhbuild.utils.download import download_file
+from jhbuild.utils.unpack import unpack_archive
 
 jhbuild_directory = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                                  '..', '..'))
@@ -160,27 +162,17 @@
             self._check_tarball()
         except BuildStateError:
             # don't have the tarball, try downloading it and check again
-            if has_command('wget'):
-                res = buildscript.execute(
-                        ['wget', self.module, '-O', localfile])
-            elif has_command('curl'):
-                res = buildscript.execute(
-                        ['curl', '-L', self.module, '-o', localfile])
-            else:
-                raise FatalError("unable to find wget or curl")
-
+            try:
+                download_file(buildscript,self.module,localfile)
+            except:
+                raise FatalError("unable to find download archive")
             self._check_tarball()
 
         # now to unpack it
-        if localfile.endswith('.bz2'):
-            buildscript.execute('bunzip2 -dc "%s" | tar xf -' % localfile,
-                                cwd=self.checkoutroot)
-        elif localfile.endswith('.gz') or localfile.endswith('.tgz'):
-            buildscript.execute('gunzip -dc "%s" | tar xf -' % localfile,
-                                cwd=self.checkoutroot)
-        elif localfile.endswith('.zip'):
-            buildscript.execute('unzip "%s"' % localfile,
-                                cwd=self.checkoutroot)
+        try:
+            unpack_archive(buildscript, localfile, self.checkoutroot)
+        except:
+            raise FatalError("don't know how to handle: %s" % localfile)
 
         if not os.path.exists(self.srcdir):
             raise BuildStateError('could not unpack tarball')

