diff --git a/pgxnclient/cli.py b/pgxnclient/cli.py index a884380..84f4066 100644 --- a/pgxnclient/cli.py +++ b/pgxnclient/cli.py @@ -114,7 +114,27 @@ def command_dispatch(argv=None): # through the current executable. argv.insert(0, sys.executable) - os.execv(argv[0], argv) + import platform + if platform.system() == 'Windows': + # + # On Windows, the [Popen] class uses the Windows CreateProcess() function. + # + # If env is not None, it must be a mapping that defines the environment variables + # for the new process; these are used instead of the default behavior of + # inheriting the current process environment. + # + # https://docs.python.org/3.3/library/subprocess.html#replacing-the-os-spawn-family + # + # os.exec on all Windows versions + # http://stackoverflow.com/questions/7004687/os-exec-on-windows + # + # sys.executable: get current /path/to/python.exe that is being used + # + import subprocess + all_argv = [sys.executable] + argv + subprocess.call(all_argv) + else: + os.execv(argv[0], argv) def _get_exec(cmd): fn = find_script('pgxn-' + cmd) diff --git a/pgxnclient/commands/__init__.py b/pgxnclient/commands/__init__.py index 9b0fedb..ae136d5 100644 --- a/pgxnclient/commands/__init__.py +++ b/pgxnclient/commands/__init__.py @@ -217,7 +217,20 @@ def popen(self, cmd, *args, **kwargs): """ logger.debug("running command: %s", cmd) try: + import platform + if platform.system() == 'Windows': + import re + if isinstance(cmd, (list, tuple)): + if re.search('configure$', cmd[0]): + cmd[0] = 'sh ./configure' + if isinstance(cmd, str): + if re.search('configure$', cmd): + cmd = 'sh ./configure' + else: + cmd = cmd + return Popen(cmd, *args, **kwargs) + except OSError, e: if not isinstance(cmd, basestring): cmd = ' '.join(cmd) @@ -458,9 +471,15 @@ def customize_parser(self, parser, subparsers, **kwargs): subp = super(WithPgConfig, self).customize_parser( parser, subparsers, **kwargs) - subp.add_argument('--pg_config', metavar="PROG", default='pg_config', - help = _("the pg_config executable to find the database" - " [default: %(default)s]")) + import platform + if platform.system() == 'Windows': + subp.add_argument('--pg_config', metavar="PROG", default='pg_config.exe', + help = _("the pg_config executable to find the database" + " [default: %(default)s]")) + else: + subp.add_argument('--pg_config', metavar="PROG", default='pg_config', + help = _("the pg_config executable to find the database" + " [default: %(default)s]")) return subp @@ -540,7 +559,17 @@ def run_make(self, cmd, dir, env=None, sudo=None): if sudo: cmdline.extend(shlex.split(sudo)) - cmdline.extend([self.get_make(), 'PG_CONFIG=%s' % self.get_pg_config()]) + import platform + if platform.system() == 'Windows': + # remove colons ':' + # if a character exists at the beginning and if it is upper case, then make it lowercase + # append a backslash '/' to the beginning of the line + # replace many occurances of '\\' with '/' + import re + new_pg_config = ('/' + re.sub("^[A-Z]", lambda m: m.group(0).lower(),self.get_pg_config().replace(":",""))).replace("\\","/") + cmdline.extend([self.get_make(), 'PG_CONFIG=%s' % new_pg_config]) + else: + cmdline.extend([self.get_make(), 'PG_CONFIG=%s' % self.get_pg_config()]) if isinstance(cmd, basestring): cmdline.append(cmd) @@ -587,13 +616,20 @@ def get_make(self, _cache=[]): @classmethod def _find_default_make(self): - for make in ('gmake', 'make'): - path = find_executable(make) - if path: - return make + import platform + if platform.system() == 'Windows': + for make in ('gmake.exe', 'make.exe'): + path = find_executable(make) + if path: + return make + else: + for make in ('gmake', 'make'): + path = find_executable(make) + if path: + return make # if nothing was found, fall back on 'gmake'. If it was missing we - # will give an error when attempting to use it + # will give an error when attempting to use it. return 'gmake' @@ -668,4 +704,3 @@ def get_psql_env(self): if self.opts.port: rv['PGPORT'] = str(self.opts.port) if self.opts.username: rv['PGUSER'] = self.opts.username return rv -