From e37e139f0a61efa26c95cf4cbc0d96337cc4693f Mon Sep 17 00:00:00 2001
From: Karl-Hermann Wieners <karl-hermann.wieners@mpimet.mpg.de>
Date: Mon, 1 Aug 2022 16:58:24 +0200
Subject: [PATCH] update: avoid code duplication (echo/exec)

---
 CHANGES.txt |  1 +
 mkexp       | 23 +++++------------------
 update.py   | 29 +++++++++++++++++++++++++++--
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index cb60529..a344f63 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -19,6 +19,7 @@ Tools
 -----
 
 * importexp: added support for running outside of native environment
+* update: avoid code duplication in generated script
 
 Release 1.1.5
 =============
diff --git a/mkexp b/mkexp
index 04d666f..cc7ec23 100755
--- a/mkexp
+++ b/mkexp
@@ -25,6 +25,7 @@ from expconfig import ConfigObj, ExpConfig, ExpConfigError
 import feedback
 import files
 import package_info
+import update
 
 #
 # Basic settings
@@ -623,21 +624,7 @@ readme_file.close()
 
 # Create update script from experiment description
 
-move_file_to_backup(os.path.join(script_dir, 'update'),
-                    os.path.join(backup_dir, 'update'))
-update_file = io.open(os.path.join(script_dir, 'update'), 'w')
-update_file.write(u'#! /bin/sh\n')
-update_file.write(u'#\n')
-update_file.write(u'# Regenerate all files with identical configuration\n')
-update_file.write(u'#\n')
-update_file.write(u'# ' + extra_dict['mkexp_input'].replace('$$', '$') + '\n')
-update_file.write(u'#\n')
-update_file.write(u'cd ' + quote(os.environ.get('PWD', os.getcwd())) + '\n')
-update_file.write(u'PATH=' + quote(os.environ.get('PATH', '')) + '\n')
-update_file.write(u'PYTHONPATH=' + quote(os.environ.get('PYTHONPATH', '')) + '\n')
-update_file.write(u'MKEXP_PATH=' + quote(os.environ.get('MKEXP_PATH', '')) + '\n')
-update_file.write(u'export PATH PYTHONPATH MKEXP_PATH\n')
-update_file.write(u'echo ' + ' '.join(map(quote, sys.argv)) + ' "$@" >&2\n')
-update_file.write(u'exec ' + ' '.join(map(quote, sys.argv)) + ' "$@"\n')
-update_file.close()
-chmod_plus_x(os.path.join(script_dir, 'update'))
+update_name = os.path.join(script_dir, 'update')
+move_file_to_backup(update_name, os.path.join(backup_dir, 'update'))
+update.write_update(update_name, extra_dict, sys.argv)
+chmod_plus_x(update_name)
diff --git a/update.py b/update.py
index 2ecffac..4bd282f 100644
--- a/update.py
+++ b/update.py
@@ -4,11 +4,33 @@ Module for 'update' information generated by mkexp tool.
 $Id$
 '''
 
+import io
 import os
 import re
 
 import expargparse
 
+def write_update(update_name, extra_dict, argv):
+    def quote(value):
+        return repr(value).lstrip('u')
+    update_file = io.open(update_name, 'w')
+    update_file.write(u'#! /bin/sh\n')
+    update_file.write(u'#\n')
+    update_file.write(u'# Regenerate all files with identical configuration\n')
+    update_file.write(u'#\n')
+    update_file.write(u'# ' + extra_dict['mkexp_input'].replace('$$', '$') + '\n')
+    update_file.write(u'#\n')
+    update_file.write(u'cd ' + quote(os.environ.get('PWD', os.getcwd())) + '\n')
+    update_file.write(u'PATH=' + quote(os.environ.get('PATH', '')) + '\n')
+    update_file.write(u'PYTHONPATH=' + quote(os.environ.get('PYTHONPATH', '')) + '\n')
+    update_file.write(u'MKEXP_PATH=' + quote(os.environ.get('MKEXP_PATH', '')) + '\n')
+    update_file.write(u'export PATH PYTHONPATH MKEXP_PATH\n')
+    update_file.write(u'set - ' + ' '.join(map(quote, argv)) + ' "$@"\n')
+    update_file.write(u'echo "$@" >&2\n')
+    update_file.write(u'exec "$@"\n')
+    update_file.close()
+
+
 class Update:
     '''Object containing 'update' information generated by mkexp tool
     '''
@@ -24,16 +46,19 @@ class Update:
         update_file = open(update_name)
 
         for line in update_file:
-            match = re.match(r"^cd '(.*)'$", line)
+            match = re.match(r"cd '(.*)'$", line)
             if match:
                 self.config_dir = match.group(1)
             else:
-                match = re.match(r"^exec '.*?' '(.*)'", line)
+                # Support older update file formats
+                match =(re.match(r"set - '.*?' '(.*)'", line) or
+                        re.match(r"exec '.*?' '(.*)'", line))
                 if match:
                     # Check mkexp command line
                     mkexp_line = expargparse.MkexpArgumentParser() 
                     self.mkexp_args = \
                         mkexp_line.parse_args(match.group(1).split("' '"))
+                    break
 
         update_file.close()
 
-- 
GitLab