diff mbox

[U-Boot,6/7] tools/genboardscfg.py: check if the boards.cfg is up to date

Message ID 1408535269-24066-7-git-send-email-yamada.m@jp.panasonic.com
State Superseded
Delegated to: Tom Rini
Headers show

Commit Message

Masahiro Yamada Aug. 20, 2014, 11:47 a.m. UTC
It looks silly to regenerate the boards.cfg even when it is
already up to date.

The tool should exit with doing nothing if the boards.cfg is newer
than any of defconfig, Kconfig and MAINTAINERS files.

Specify -f (--force) option to get the boards.cfg regenerated
regardless its time stamp.

Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
---

 tools/genboardscfg.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 55 insertions(+), 2 deletions(-)

Comments

Simon Glass Aug. 20, 2014, 7:13 p.m. UTC | #1
On 20 August 2014 05:47, Masahiro Yamada <yamada.m@jp.panasonic.com> wrote:
> It looks silly to regenerate the boards.cfg even when it is
> already up to date.
>
> The tool should exit with doing nothing if the boards.cfg is newer
> than any of defconfig, Kconfig and MAINTAINERS files.
>
> Specify -f (--force) option to get the boards.cfg regenerated
> regardless its time stamp.
>
> Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>

Acked-by: Simon Glass <sjg@chromium.org>

Great idea.

> ---
>
>  tools/genboardscfg.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/tools/genboardscfg.py b/tools/genboardscfg.py
> index 13bb424..899db69 100755
> --- a/tools/genboardscfg.py
> +++ b/tools/genboardscfg.py
> @@ -87,6 +87,51 @@ def get_make_cmd():
>          sys.exit('GNU Make not found')
>      return ret[0].rstrip()
>
> +def output_is_new():
> +    """Check if the boards.cfg file is up to date.
> +
> +    Returns:
> +      True if the boards.cfg file exists and is newer than any of
> +      *_defconfig, MAINTAINERS and Kconfig*.  False otherwise.
> +    """
> +    try:
> +        ctime = os.path.getctime(BOARD_FILE)
> +    except OSError, exception:
> +        if exception.errno == errno.ENOENT:
> +            # return False on 'No such file or directory' error
> +            return False
> +        else:
> +            raise

if not os.path.exists(BOARD_FILE)
   return False

would probably be enough.

> +
> +    for (dirpath, dirnames, filenames) in os.walk(CONFIG_DIR):
> +        for filename in fnmatch.filter(filenames, '*_defconfig'):
> +            if fnmatch.fnmatch(filename, '.*'):
> +                continue
> +            filepath = os.path.join(dirpath, filename)
> +            if ctime < os.path.getctime(filepath):
> +                return False
> +
> +    for (dirpath, dirnames, filenames) in os.walk('.'):
> +        for filename in filenames:
> +            if (fnmatch.fnmatch(filename, '*~') or
> +                not fnmatch.fnmatch(filename, 'Kconfig*') and
> +                not filename == 'MAINTAINERS'):
> +                continue
> +            filepath = os.path.join(dirpath, filename)
> +            if ctime < os.path.getctime(filepath):
> +                return False
> +
> +    # Detect a board that has been removed since the current boards.cfg
> +    # was generated
> +    for line in open(BOARD_FILE):
> +        if line[0] == '#' or line == '\n':
> +            continue
> +        defconfig = line.split()[6] + '_defconfig'
> +        if not os.path.exists(os.path.join(CONFIG_DIR, defconfig)):
> +            return False
> +
> +    return True
> +
>  ### classes ###
>  class MaintainersDatabase:
>
> @@ -507,7 +552,7 @@ class BoardsFileGenerator:
>
>          self.in_progress = False
>
> -def gen_boards_cfg(jobs):
> +def gen_boards_cfg(jobs=1, force=False):
>      """Generate boards.cfg file.
>
>      The incomplete boards.cfg is deleted if an error (including
> @@ -517,6 +562,10 @@ def gen_boards_cfg(jobs):
>        jobs: The number of jobs to run simultaneously
>      """
>      check_top_directory()
> +    if not force and output_is_new():
> +        print "%s is up to date. Nothing to do." % BOARD_FILE
> +        sys.exit(0)
> +
>      generator = BoardsFileGenerator()
>      generator.generate(jobs)
>
> @@ -525,7 +574,10 @@ def main():
>      # Add options here
>      parser.add_option('-j', '--jobs',
>                        help='the number of jobs to run simultaneously')
> +    parser.add_option('-f', '--force', action="store_true", default=False,
> +                      help='regenerate the output even if it is new')
>      (options, args) = parser.parse_args()
> +
>      if options.jobs:
>          try:
>              jobs = int(options.jobs)
> @@ -538,7 +590,8 @@ def main():
>          except (OSError, ValueError):
>              print 'info: failed to get the number of CPUs. Set jobs to 1'
>              jobs = 1
> -    gen_boards_cfg(jobs)
> +
> +    gen_boards_cfg(jobs, force=options.force)
>
>  if __name__ == '__main__':
>      main()
> --
> 1.9.1
>

Regards,
Simon
Masahiro Yamada Aug. 21, 2014, 4:02 a.m. UTC | #2
Hi Simon,



On Wed, 20 Aug 2014 13:13:13 -0600
Simon Glass <sjg@chromium.org> wrote:
> > +def output_is_new():
> > +    """Check if the boards.cfg file is up to date.
> > +
> > +    Returns:
> > +      True if the boards.cfg file exists and is newer than any of
> > +      *_defconfig, MAINTAINERS and Kconfig*.  False otherwise.
> > +    """
> > +    try:
> > +        ctime = os.path.getctime(BOARD_FILE)
> > +    except OSError, exception:
> > +        if exception.errno == errno.ENOENT:
> > +            # return False on 'No such file or directory' error
> > +            return False
> > +        else:
> > +            raise
> 
> if not os.path.exists(BOARD_FILE)
>    return False
> 
> would probably be enough.
> 


Actually my first code was as follows:

------------>8------------------------
if not os.path.exists(BOARD_FILE)
    return False

ctime = os.path.getctime(BOARD_FILE)
-------------8<----------------------



But what if someone deletes BOARD_FILE
between os.path.exists(BOARD_FILE) and os.path.getctime(BOARD_FILE)?

I know it is ridiculous to consider such a rare case.


But I believe it is Python style to follow
"try something and then handle an exception" thing.

I am trying to be a bit strict to this rule
when invoking OS system calls where there is possibility of failure.



Best Regards
Masahiro Yamada
Simon Glass Aug. 23, 2014, 1:54 a.m. UTC | #3
Hi Masahiro,

On 20 August 2014 22:02, Masahiro Yamada <yamada.m@jp.panasonic.com> wrote:
> Hi Simon,
>
>
>
> On Wed, 20 Aug 2014 13:13:13 -0600
> Simon Glass <sjg@chromium.org> wrote:
>> > +def output_is_new():
>> > +    """Check if the boards.cfg file is up to date.
>> > +
>> > +    Returns:
>> > +      True if the boards.cfg file exists and is newer than any of
>> > +      *_defconfig, MAINTAINERS and Kconfig*.  False otherwise.
>> > +    """
>> > +    try:
>> > +        ctime = os.path.getctime(BOARD_FILE)
>> > +    except OSError, exception:
>> > +        if exception.errno == errno.ENOENT:
>> > +            # return False on 'No such file or directory' error
>> > +            return False
>> > +        else:
>> > +            raise
>>
>> if not os.path.exists(BOARD_FILE)
>>    return False
>>
>> would probably be enough.
>>
>
>
> Actually my first code was as follows:
>
> ------------>8------------------------
> if not os.path.exists(BOARD_FILE)
>     return False
>
> ctime = os.path.getctime(BOARD_FILE)
> -------------8<----------------------
>
>
>
> But what if someone deletes BOARD_FILE
> between os.path.exists(BOARD_FILE) and os.path.getctime(BOARD_FILE)?
>
> I know it is ridiculous to consider such a rare case.
>
>
> But I believe it is Python style to follow
> "try something and then handle an exception" thing.
>
> I am trying to be a bit strict to this rule
> when invoking OS system calls where there is possibility of failure.

Failure in this case seems safe IMO :-) Anyway I will leave this up to
you, it is not important.

Regards,
Simon
diff mbox

Patch

diff --git a/tools/genboardscfg.py b/tools/genboardscfg.py
index 13bb424..899db69 100755
--- a/tools/genboardscfg.py
+++ b/tools/genboardscfg.py
@@ -87,6 +87,51 @@  def get_make_cmd():
         sys.exit('GNU Make not found')
     return ret[0].rstrip()
 
+def output_is_new():
+    """Check if the boards.cfg file is up to date.
+
+    Returns:
+      True if the boards.cfg file exists and is newer than any of
+      *_defconfig, MAINTAINERS and Kconfig*.  False otherwise.
+    """
+    try:
+        ctime = os.path.getctime(BOARD_FILE)
+    except OSError, exception:
+        if exception.errno == errno.ENOENT:
+            # return False on 'No such file or directory' error
+            return False
+        else:
+            raise
+
+    for (dirpath, dirnames, filenames) in os.walk(CONFIG_DIR):
+        for filename in fnmatch.filter(filenames, '*_defconfig'):
+            if fnmatch.fnmatch(filename, '.*'):
+                continue
+            filepath = os.path.join(dirpath, filename)
+            if ctime < os.path.getctime(filepath):
+                return False
+
+    for (dirpath, dirnames, filenames) in os.walk('.'):
+        for filename in filenames:
+            if (fnmatch.fnmatch(filename, '*~') or
+                not fnmatch.fnmatch(filename, 'Kconfig*') and
+                not filename == 'MAINTAINERS'):
+                continue
+            filepath = os.path.join(dirpath, filename)
+            if ctime < os.path.getctime(filepath):
+                return False
+
+    # Detect a board that has been removed since the current boards.cfg
+    # was generated
+    for line in open(BOARD_FILE):
+        if line[0] == '#' or line == '\n':
+            continue
+        defconfig = line.split()[6] + '_defconfig'
+        if not os.path.exists(os.path.join(CONFIG_DIR, defconfig)):
+            return False
+
+    return True
+
 ### classes ###
 class MaintainersDatabase:
 
@@ -507,7 +552,7 @@  class BoardsFileGenerator:
 
         self.in_progress = False
 
-def gen_boards_cfg(jobs):
+def gen_boards_cfg(jobs=1, force=False):
     """Generate boards.cfg file.
 
     The incomplete boards.cfg is deleted if an error (including
@@ -517,6 +562,10 @@  def gen_boards_cfg(jobs):
       jobs: The number of jobs to run simultaneously
     """
     check_top_directory()
+    if not force and output_is_new():
+        print "%s is up to date. Nothing to do." % BOARD_FILE
+        sys.exit(0)
+
     generator = BoardsFileGenerator()
     generator.generate(jobs)
 
@@ -525,7 +574,10 @@  def main():
     # Add options here
     parser.add_option('-j', '--jobs',
                       help='the number of jobs to run simultaneously')
+    parser.add_option('-f', '--force', action="store_true", default=False,
+                      help='regenerate the output even if it is new')
     (options, args) = parser.parse_args()
+
     if options.jobs:
         try:
             jobs = int(options.jobs)
@@ -538,7 +590,8 @@  def main():
         except (OSError, ValueError):
             print 'info: failed to get the number of CPUs. Set jobs to 1'
             jobs = 1
-    gen_boards_cfg(jobs)
+
+    gen_boards_cfg(jobs, force=options.force)
 
 if __name__ == '__main__':
     main()