]> git.sur5r.net Git - u-boot/blobdiff - tools/moveconfig.py
tools: moveconfig: New color used for changed defconfig
[u-boot] / tools / moveconfig.py
index 4881ec539b8bc37ffd83de6825a29aaf02d10925..12a145c0a615722dce3e0db5acbd9783c616bc38 100755 (executable)
@@ -131,6 +131,11 @@ Available options
    Exit immediately if Make exits with a non-zero status while processing
    a defconfig file.
 
+ -s, --force-sync
+   Do "make savedefconfig" forcibly for all the defconfig files.
+   If not specified, "make savedefconfig" only occurs for cases
+   where at least one CONFIG was moved.
+
  -H, --headers-only
    Only cleanup the headers; skip the defconfig processing
 
@@ -147,6 +152,7 @@ To see the complete list of supported options, run
 
 """
 
+import filecmp
 import fnmatch
 import multiprocessing
 import optparse
@@ -602,7 +608,7 @@ class Slot:
 
         This function makes sure the temporary directory is cleaned away
         even if Python suddenly dies due to error.  It should be done in here
-        because it is guranteed the destructor is always invoked when the
+        because it is guaranteed the destructor is always invoked when the
         instance of the class gets unreferenced.
 
         If the subprocess is still running, wait until it finishes.
@@ -627,13 +633,10 @@ class Slot:
         """
         if self.state != STATE_IDLE:
             return False
-        cmd = list(self.make_cmd)
-        cmd.append(defconfig)
-        self.ps = subprocess.Popen(cmd, stdout=self.devnull,
-                                   stderr=subprocess.PIPE)
+
         self.defconfig = defconfig
-        self.state = STATE_DEFCONFIG
         self.log = ''
+        self.do_defconfig()
         return True
 
     def poll(self):
@@ -659,44 +662,46 @@ class Slot:
             return False
 
         if self.ps.poll() != 0:
-            self.log += color_text(self.options.color, COLOR_LIGHT_RED,
-                                   "Failed to process.\n")
-            if self.options.verbose:
-                self.log += color_text(self.options.color, COLOR_LIGHT_CYAN,
-                                       self.ps.stderr.read())
-            self.finish(False)
-            return True
+            self.handle_error()
+        elif self.state == STATE_DEFCONFIG:
+            self.do_autoconf()
+        elif self.state == STATE_AUTOCONF:
+            self.do_savedefconfig()
+        elif self.state == STATE_SAVEDEFCONFIG:
+            self.update_defconfig()
+        else:
+            sys.exit("Internal Error. This should not happen.")
 
-        if self.state == STATE_AUTOCONF:
-            (updated, log) = self.parser.update_dotconfig()
-            self.log += log
+        return True if self.state == STATE_IDLE else False
 
-            if not updated:
-                self.finish(True)
-                return True
-            self.log += color_text(self.options.color, COLOR_LIGHT_GREEN,
-                                   "Syncing by savedefconfig...\n")
-            cmd = list(self.make_cmd)
-            cmd.append('savedefconfig')
-            self.ps = subprocess.Popen(cmd, stdout=self.devnull,
-                                       stderr=subprocess.PIPE)
-            self.state = STATE_SAVEDEFCONFIG
-            return False
+    def handle_error(self):
+        """Handle error cases."""
 
-        if self.state == STATE_SAVEDEFCONFIG:
-            self.log += self.parser.check_defconfig()
-            if not self.options.dry_run:
-                shutil.move(os.path.join(self.build_dir, 'defconfig'),
-                            os.path.join('configs', self.defconfig))
-            self.finish(True)
-            return True
+        self.log += color_text(self.options.color, COLOR_LIGHT_RED,
+                               "Failed to process.\n")
+        if self.options.verbose:
+            self.log += color_text(self.options.color, COLOR_LIGHT_CYAN,
+                                   self.ps.stderr.read())
+        self.finish(False)
+
+    def do_defconfig(self):
+        """Run 'make <board>_defconfig' to create the .config file."""
+
+        cmd = list(self.make_cmd)
+        cmd.append(self.defconfig)
+        self.ps = subprocess.Popen(cmd, stdout=self.devnull,
+                                   stderr=subprocess.PIPE)
+        self.state = STATE_DEFCONFIG
+
+    def do_autoconf(self):
+        """Run 'make include/config/auto.conf'."""
 
         self.cross_compile = self.parser.get_cross_compile()
         if self.cross_compile is None:
             self.log += color_text(self.options.color, COLOR_YELLOW,
                                    "Compiler is missing.  Do nothing.\n")
             self.finish(False)
-            return True
+            return
 
         cmd = list(self.make_cmd)
         if self.cross_compile:
@@ -706,7 +711,43 @@ class Slot:
         self.ps = subprocess.Popen(cmd, stdout=self.devnull,
                                    stderr=subprocess.PIPE)
         self.state = STATE_AUTOCONF
-        return False
+
+    def do_savedefconfig(self):
+        """Update the .config and run 'make savedefconfig'."""
+
+        (updated, log) = self.parser.update_dotconfig()
+        self.log += log
+
+        if not self.options.force_sync and not updated:
+            self.finish(True)
+            return
+        if updated:
+            self.log += color_text(self.options.color, COLOR_LIGHT_GREEN,
+                                   "Syncing by savedefconfig...\n")
+        else:
+            self.log += "Syncing by savedefconfig (forced by option)...\n"
+
+        cmd = list(self.make_cmd)
+        cmd.append('savedefconfig')
+        self.ps = subprocess.Popen(cmd, stdout=self.devnull,
+                                   stderr=subprocess.PIPE)
+        self.state = STATE_SAVEDEFCONFIG
+
+    def update_defconfig(self):
+        """Update the input defconfig and go back to the idle state."""
+
+        self.log += self.parser.check_defconfig()
+        orig_defconfig = os.path.join('configs', self.defconfig)
+        new_defconfig = os.path.join(self.build_dir, 'defconfig')
+        updated = not filecmp.cmp(orig_defconfig, new_defconfig)
+
+        if updated:
+            self.log += color_text(self.options.color, COLOR_LIGHT_BLUE,
+                                   "defconfig was updated.\n")
+
+        if not self.options.dry_run and updated:
+            shutil.move(new_defconfig, orig_defconfig)
+        self.finish(True)
 
     def finish(self, success):
         """Display log along with progress and go to the idle state.
@@ -822,10 +863,13 @@ def move_config(configs, options):
       options: option flags
     """
     if len(configs) == 0:
-        print 'Nothing to do. exit.'
-        sys.exit(0)
-
-    print 'Move %s (jobs: %d)' % (', '.join(configs), options.jobs)
+        if options.force_sync:
+            print 'No CONFIG is specified. You are probably syncing defconfigs.',
+        else:
+            print 'Neither CONFIG nor --force-sync is specified. Nothing will happen.',
+    else:
+        print 'Move ' + ', '.join(configs),
+    print '(jobs: %d)\n' % options.jobs
 
     if options.defconfigs:
         defconfigs = [line.strip() for line in open(options.defconfigs)]
@@ -879,6 +923,8 @@ def main():
     parser.add_option('-e', '--exit-on-error', action='store_true',
                       default=False,
                       help='exit immediately on any error')
+    parser.add_option('-s', '--force-sync', action='store_true', default=False,
+                      help='force sync by savedefconfig')
     parser.add_option('-H', '--headers-only', dest='cleanup_headers_only',
                       action='store_true', default=False,
                       help='only cleanup the headers')
@@ -890,7 +936,7 @@ def main():
 
     (options, configs) = parser.parse_args()
 
-    if len(configs) == 0:
+    if len(configs) == 0 and not options.force_sync:
         parser.print_usage()
         sys.exit(1)
 
@@ -907,7 +953,8 @@ def main():
     if not options.cleanup_headers_only:
         move_config(configs, options)
 
-    cleanup_headers(configs, options.dry_run)
+    if configs:
+        cleanup_headers(configs, options.dry_run)
 
 if __name__ == '__main__':
     main()