diff setup.py @ 1100:2be46f391cfa

setup: SAT_INSTALL environment variable handles "clean" and "purge" options
author souliane <souliane@mailoo.org>
date Tue, 15 Jul 2014 13:37:50 +0200
parents a32ef03d4af0
children 8e15eeb3cfc3
line wrap: on
line diff
--- a/setup.py	Sun Jul 06 21:54:07 2014 +0200
+++ b/setup.py	Tue Jul 15 13:37:50 2014 +0200
@@ -2,7 +2,8 @@
 # -*- coding: utf-8 -*-
 
 # SAT: a jabber client
-# Copyright (C) 2009, 2010, 2011  Jérôme Poisson (goffi@goffi.org)
+# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014  Jérôme Poisson (goffi@goffi.org)
+# Copyright (C) 2013, 2014 Adrien Cossa (souliane@mailoo.org)
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -26,14 +27,19 @@
 import sys
 import subprocess
 from stat import ST_MODE
+import shutil
+
 
 NAME = 'sat'
 LAUNCH_DAEMON_COMMAND = 'sat'
 
-ENV_SAT_INSTALL = "SAT_INSTALL" # environment variable to customise installation
-NO_PREINSTALL_OPT = 'nopreinstall' # skip all preinstallation checks
-AUTO_DEB_OPT = 'autodeb' # automaticaly install debs
-NO_X_OPT = 'nox' # don't install X dependant packages
+ENV_SAT_INSTALL = "SAT_INSTALL"  # environment variable to customise installation
+NO_PREINSTALL_OPT = 'nopreinstall'  # skip all preinstallation checks
+AUTO_DEB_OPT = 'autodeb'  # automaticaly install debs
+NO_X_OPT = 'nox'  # don't install X dependant packages
+CLEAN_OPT = 'clean'  # remove previous installation directories
+PURGE_OPT = 'purge'  # remove building and previous installation directories
+
 
 class MercurialException(Exception):
     pass
@@ -75,23 +81,83 @@
     def custom_create_links(self):
         """Create symbolic links to executables"""
         # the script which launch the daemon
-        links = [(self.sh_script_path, LAUNCH_DAEMON_COMMAND)]
-        for source, dest in links:
-            dest_name, copied = copy_file(source, os.path.join(self.install_scripts, dest), link='sym')
+        for source, dest in self.sh_script_links:
+            if os.path.islink(dest) and os.readlink(dest) != source:
+                os.remove(dest)  # copy_file doesn't force the link update
+            dest_name, copied = copy_file(source, dest, link='sym')
             assert (copied)
             # we change the perm in the same way as in the original install_scripts
             mode = ((os.stat(dest_name)[ST_MODE]) | 0555) & 07777
             os.chmod(dest_name, mode)
 
     def run(self):
+        self.sh_script_path = os.path.join(self.install_lib, NAME, 'sat.sh')
+        self.sh_script_links = [(self.sh_script_path, os.path.join(self.install_scripts, LAUNCH_DAEMON_COMMAND))]
+        sys.stdout.write('running pre installation stuff\n')
+        sys.stdout.flush()
+        if PURGE_OPT in install_opt:
+            self.purge()
+        elif CLEAN_OPT in install_opt:
+            self.clean()
         install.run(self)
         sys.stdout.write('running post installation stuff\n')
         sys.stdout.flush()
-        self.sh_script_path = os.path.join(self.install_lib, 'sat', 'sat.sh')
-        self.primitivus_path = os.path.join(self.install_lib, 'sat_frontends', 'primitivus')
         self.custom_auto_options()
         self.custom_create_links()
 
+    def confirm(self, message):
+        """Ask the user for a confirmation"""
+        message += 'Proceed'
+        while True:
+            res = raw_input("%s (y/n)? " % message)
+            if res not in ['y', 'Y', 'n', 'N']:
+                print "Your response ('%s') was not one of the expected responses: y, n" % res
+                message = 'Proceed'
+                continue
+            if res in ('y', 'Y'):
+                return True
+            return False
+
+    def clean(self, message=None, to_remove=None):
+        """Clean previous installation directories
+
+        @param message (str): to use a non-default confirmation message
+        @param to_remove (str): extra files/directories to remove
+        """
+        if message is None:
+            message = "Cleaning previous installation directories"
+        if to_remove is None:
+            to_remove = []
+        to_remove.extend([os.path.join(self.install_lib, NAME),
+                          os.path.join(self.install_data, 'share', 'doc', NAME),
+                          os.path.join(self.install_lib, "%s-py%s.egg-info" % (self.config_vars['dist_fullname'], self.config_vars['py_version_short'])),
+                          ])
+        for source, dest in self.sh_script_links:
+            if os.path.islink(dest):
+                to_remove.append(dest)
+
+        for script in ('jp', 'wix', 'primitivus'):
+            dest = os.path.join(self.install_scripts, script)
+            if os.path.exists(dest):
+                to_remove.append(dest)
+
+        message = "%s:\n%s\n" % (message, "\n".join(["    %s" % path for path in to_remove]))
+        if not self.confirm(message):
+            return
+        sys.stdout.write('cleaning previous installation directories...\n')
+        sys.stdout.flush()
+        for path in to_remove:
+            if os.path.isdir(path):
+                shutil.rmtree(path, ignore_errors=True)
+            else:
+                os.remove(path)
+
+    def purge(self):
+        """Clean building and previous installation directories"""
+        message = "Cleaning building and previous installation directories"
+        to_remove = [os.path.join(os.getcwd(), 'build')]
+        self.clean(message, to_remove)
+
 
 def preinstall_check(install_opt):
     """Check presence of problematic dependencies, and try to install them with package manager
@@ -121,7 +187,7 @@
         modules_toinstall.append('mercurial')"""  # hg can be installed from pypi
 
     if modules_toinstall:
-        if AUTO_DEB_OPT in install_opt: # auto debian installation is requested
+        if AUTO_DEB_OPT in install_opt:  # auto debian installation is requested
             # are we on a distribution using apt ?
             apt_path = subprocess.Popen('which apt-get', stdout=subprocess.PIPE, shell=True).communicate()[0][:-1]
         else:
@@ -146,6 +212,7 @@
                 sys.stdout.write("- %s (Debian name: %s)\n" % (module_name, package[module_name]))
             sys.exit(2)
 
+
 if sys.argv[1].lower() in ['egg_info', 'install']:
     # we only check dependencies if egg_info or install is used
     install_opt = os.environ.get(ENV_SAT_INSTALL, "").split()