From c1e6e70870c83f0794103bd639edea0446eb1afa Mon Sep 17 00:00:00 2001
From: Fabien Meghazi <fme@openerp.com>
Date: Wed, 11 Jun 2014 09:55:17 +0200
Subject: [PATCH] Added --force to odoo deploy

Will force --init mode even if module is already installed
---
 addons/base_import_module/controllers/main.py        |  5 +++--
 .../base_import_module/models/base_import_module.py  |  6 ++++--
 addons/base_import_module/models/ir_module.py        |  8 ++++----
 .../base_import_module/views/base_import_module.xml  |  2 ++
 openerp/cli/deploy.py                                | 12 +++++++-----
 5 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/addons/base_import_module/controllers/main.py b/addons/base_import_module/controllers/main.py
index d97e75ba8b69..d1c25544566f 100644
--- a/addons/base_import_module/controllers/main.py
+++ b/addons/base_import_module/controllers/main.py
@@ -34,6 +34,7 @@ class ImportModule(Controller):
 
     @route('/base_import_module/upload', type='http', auth='user', methods=['POST'])
     @webservice
-    def upload(self, mod_file=None, **kw):
+    def upload(self, mod_file=None, force='', **kw):
         self.check_user()
-        return request.registry['ir.module.module'].import_zipfile(request.cr, request.uid, mod_file, context=request.context)[0]
+        force = True if force == '1' else False
+        return request.registry['ir.module.module'].import_zipfile(request.cr, request.uid, mod_file, force=force, context=request.context)[0]
diff --git a/addons/base_import_module/models/base_import_module.py b/addons/base_import_module/models/base_import_module.py
index 36edb5a56f35..df13a2096a13 100644
--- a/addons/base_import_module/models/base_import_module.py
+++ b/addons/base_import_module/models/base_import_module.py
@@ -12,10 +12,12 @@ class base_import_module(osv.TransientModel):
         'module_file': fields.binary('Module .ZIP file', required=True),
         'state':fields.selection([('init','init'),('done','done')], 'Status', readonly=True),
         'import_message': fields.char('Import message'),
+        'force': fields.boolean('Force init', help="Force init mode even if installed. (will update `noupdate='1'` records)"),
     }
 
-    _defaults = {  
+    _defaults = {
         'state': 'init',
+        'force': False,
     }
 
     def import_module(self, cr, uid, ids, context=None):
@@ -24,7 +26,7 @@ class base_import_module(osv.TransientModel):
         zip_data = base64.decodestring(data.module_file)
         fp = BytesIO()
         fp.write(zip_data)
-        res = module_obj.import_zipfile(cr, uid, fp, context=context)
+        res = module_obj.import_zipfile(cr, uid, fp, force=data.force, context=context)
         self.write(cr, uid, ids, {'state': 'done', 'import_message': res[0]}, context=context)
         context = dict(context, module_name=res[1])
         # Return wizard otherwise it will close wizard and will not show result message to user. 
diff --git a/addons/base_import_module/models/ir_module.py b/addons/base_import_module/models/ir_module.py
index 2a0a9ea7fed6..759a51180782 100644
--- a/addons/base_import_module/models/ir_module.py
+++ b/addons/base_import_module/models/ir_module.py
@@ -16,7 +16,7 @@ MAX_FILE_SIZE = 100 * 1024 * 1024 # in megabytes
 class view(osv.osv):
     _inherit = "ir.module.module"
 
-    def import_module(self, cr, uid, module, path, context=None):
+    def import_module(self, cr, uid, module, path, force=False, context=None):
         known_mods = self.browse(cr, uid, self.search(cr, uid, []))
         known_mods_names = dict([(m.name, m) for m in known_mods])
 
@@ -30,7 +30,7 @@ class view(osv.osv):
 
         if mod:
             self.write(cr, uid, mod.id, values)
-            mode = 'update'
+            mode = 'update' if not force else 'init'
         else:
             assert terp.get('installable', True), "Module not installable"
             self.create(cr, uid, dict(name=module, state='uninstalled', **values))
@@ -73,7 +73,7 @@ class view(osv.osv):
 
         return True
 
-    def import_zipfile(self, cr, uid, module_file, context=None):
+    def import_zipfile(self, cr, uid, module_file, force=False, context=None):
         if not module_file:
             raise Exception("No file sent.")
         if not zipfile.is_zipfile(module_file):
@@ -95,7 +95,7 @@ class view(osv.osv):
                     try:
                         # assert mod_name.startswith('theme_')
                         path = opj(module_dir, mod_name)
-                        self.import_module(cr, uid, mod_name, path, context=context)
+                        self.import_module(cr, uid, mod_name, path, force=force, context=context)
                         success.append(mod_name)
                     except Exception, e:
                         errors[mod_name] = str(e)
diff --git a/addons/base_import_module/views/base_import_module.xml b/addons/base_import_module/views/base_import_module.xml
index daaa7779c27e..494069d7ddf4 100644
--- a/addons/base_import_module/views/base_import_module.xml
+++ b/addons/base_import_module/views/base_import_module.xml
@@ -12,6 +12,8 @@
                     <group states="init" col="4">
                         <label string="Select module package to import (.zip file):" colspan="4"/>
                         <field name="module_file" colspan="4"/>
+
+                        <field name="force"/>
                     </group>
                     <group states="done" col="4">
                         <field name="import_message" colspan="4" nolabel="1" readonly="1"/>
diff --git a/openerp/cli/deploy.py b/openerp/cli/deploy.py
index 36ff0717377d..7c5e9536c0cc 100644
--- a/openerp/cli/deploy.py
+++ b/openerp/cli/deploy.py
@@ -15,20 +15,21 @@ class Deploy(Command):
         super(Deploy, self).__init__()
         self.session = requests.session()
 
-    def deploy_module(self, module_path, url, login, password, db=''):
+    def deploy_module(self, module_path, url, login, password, db='', force=False):
         url = url.rstrip('/')
         self.authenticate(url, login, password, db)
         module_file = self.zip_module(module_path)
         try:
-            return self.upload_module(url, module_file)
+            return self.upload_module(url, module_file, force=force)
         finally:
             os.remove(module_file)
 
-    def upload_module(self, server, module_file):
+    def upload_module(self, server, module_file, force=False):
         print("Uploading module file...")
         url = server + '/base_import_module/upload'
         files = dict(mod_file=open(module_file, 'rb'))
-        res = self.session.post(url, files=files)
+        force = '1' if force else ''
+        res = self.session.post(url, files=files, data=dict(force=force))
         if res.status_code != 200:
             raise Exception("Could not authenticate on server '%s'" % server)
         return res.text
@@ -75,6 +76,7 @@ class Deploy(Command):
         parser.add_argument('--login', dest='login', default="admin", help='Login (default=admin)')
         parser.add_argument('--password', dest='password', default="admin", help='Password (default=admin)')
         parser.add_argument('--verify-ssl', action='store_true', help='Verify SSL certificate')
+        parser.add_argument('--force', action='store_true', help='Force init even if module is already installed. (will update `noupdate="1"` records)')
         if not cmdargs:
             sys.exit(parser.print_help())
 
@@ -86,7 +88,7 @@ class Deploy(Command):
         try:
             if not args.url.startswith(('http://', 'https://')):
                 args.url = 'https://%s' % args.url
-            result = self.deploy_module(args.path, args.url, args.login, args.password, args.db)
+            result = self.deploy_module(args.path, args.url, args.login, args.password, args.db, force=args.force)
             print(result)
         except Exception, e:
             sys.exit("ERROR: %s" % e)
-- 
GitLab