]> SALOME platform Git repositories - tools/configuration.git/blobdiff - copyright/insert_copyright
Salome HOME
Updated copyright comment
[tools/configuration.git] / copyright / insert_copyright
index c6117fe3e7ea4239e70e758055166ba27428ca54..6c0850e2d499e444853fa125bf7582c531620806 100755 (executable)
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#  -*- coding: iso-8859-1 -*-
-
-# Copyright 2016 EDF R&D
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# Copyright (C) 2017-2024  OPEN CASCADE
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License Version 3 as
@@ -21,28 +20,27 @@ Command line tool to insert copyright notice to a file.
 Usage: type "insert_copyright --help" to learn how to use tool.
 """
 
-import optparse
-import os
+import argparse
+import os.path as osp
 import re
 import sys
 import time
 
-# pragma pylint: disable=redefined-builtin
-
 # -----------------------------------------------------------------------------
 _COMMENTS = {
-    'cpp' : '//',
-    'shell' : '#',
-    'python' : '#',
-    'auto' : None,
+    'cpp': '//',
+    'shell': '#',
+    'python': '#',
+    'auto': None,
     }
 
 _OWNERS = {
-    'cea' : 'CEA/DEN',
-    'edf' : 'EDF R&D',
-    'occ' : 'OPEN CASCADE'
+    'cea': 'CEA/DEN',
+    'edf': 'EDF R&D',
+    'occ': 'OPEN CASCADE'
     }
 
+
 # -----------------------------------------------------------------------------
 def error_exit(msg):
     """
@@ -54,6 +52,7 @@ def error_exit(msg):
     sys.stderr.write("ERROR: {}\n".format(msg))
     sys.exit(-1)
 
+
 # -----------------------------------------------------------------------------
 def warning(msg):
     """
@@ -64,6 +63,7 @@ def warning(msg):
     """
     sys.stderr.write("WARNING: {}\n".format(msg))
 
+
 # -----------------------------------------------------------------------------
 def formats():
     """
@@ -72,7 +72,8 @@ def formats():
     Returns:
         list[str]: List of formats.
     """
-    return _COMMENTS.keys()
+    return list(_COMMENTS)
+
 
 # -----------------------------------------------------------------------------
 def search_line(lines, rex, depth=1):
@@ -93,6 +94,7 @@ def search_line(lines, rex, depth=1):
                 return i
     return -1
 
+
 # -----------------------------------------------------------------------------
 def get_owner(owner):
     """
@@ -116,8 +118,9 @@ def get_owner(owner):
             result.append(i)
     return ', '.join(result)
 
+
 # -----------------------------------------------------------------------------
-def get_comment(format):
+def get_comment(file_format):
     """
     Get comment for given format.
 
@@ -128,7 +131,8 @@ def get_comment(format):
         str: Comment signature for given format; *None* for unsupported
         format.
     """
-    return _COMMENTS.get(format) if format else None
+    return _COMMENTS.get(file_format) if file_format else None
+
 
 # -----------------------------------------------------------------------------
 def get_copyright(comment, owner, year):
@@ -143,17 +147,17 @@ def get_copyright(comment, owner, year):
     Returns:
         list[str]: List of strings with copyright data.
     """
-    template = os.path.join(os.path.dirname(sys.argv[0]), 'copyright.template')
-    copyright = []
+    template = osp.join(osp.dirname(sys.argv[0]), 'copyright.template')
     try:
         with open(template) as fid:
-            copyright = fid.readlines()
+            cp_notice = [i.strip() for i in fid.readlines()]
+            cp_notice = [i % {'year' : year, 'owner' : owner} for i in cp_notice]
+            cp_notice = [comment + ' ' + i if i else comment for i in cp_notice]
+            return [i + '\n' for i in cp_notice] + ['\n']
     except IOError:
         error_exit("cannot find copyright template")
-    copyright = [i.replace('@year@', year) for i in copyright]
-    copyright = [i.replace('@owner@', owner) for i in copyright]
-    copyright = [comment + ' ' + i for i in copyright]
-    return copyright
+    return []
+
 
 # -----------------------------------------------------------------------------
 def get_module_owner(module):
@@ -166,7 +170,7 @@ def get_module_owner(module):
     Returns:
         str: Module's owner.
     """
-    modules_info = os.path.join(os.path.dirname(sys.argv[0]), 'modules.info')
+    modules_info = osp.join(osp.dirname(sys.argv[0]), 'modules.info')
     owner = None
     try:
         with open(modules_info) as fid:
@@ -178,6 +182,7 @@ def get_module_owner(module):
         warning("cannot find modules info file")
     return owner
 
+
 # -----------------------------------------------------------------------------
 def autodetect_owner(filename):
     """
@@ -189,28 +194,35 @@ def autodetect_owner(filename):
     Returns:
         str: Owner; *None* if owner isn't detected.
     """
-    filename = os.path.realpath(filename)
-    if os.path.exists(filename):
-        directory = os.path.dirname(filename)
+    filename = osp.realpath(filename)
+    if osp.exists(filename):
+        directory = osp.dirname(filename)
         while directory != '/':
-            config_file = os.path.join(directory, '.git', 'config')
-            if os.path.exists(config_file):
-                from ConfigParser import ConfigParser
-                from StringIO import StringIO
+            config_file = osp.join(directory, '.git', 'config')
+            if osp.exists(config_file):
+                try:
+                    from ConfigParser import ConfigParser
+                except ImportError:
+                    from configparser import ConfigParser
+                try:
+                    from StringIO import StringIO
+                except ImportError:
+                    from io import StringIO
                 with open(config_file) as fid:
                     gitcfg = fid.readlines()
                     cfg = ConfigParser()
                     data = StringIO(''.join([l.lstrip() for l in gitcfg]))
-                    cfg.readfp(data)
+                    cfg.readfp(data) # pragma pylint: disable=deprecated-method
                     url = cfg.get('remote "origin"', 'url')
-                    module = os.path.split(url)[-1]
+                    module = osp.split(url)[-1]
                     if module.endswith('.git'):
                         module = module[:-4]
                     return get_module_owner(module)
                 break
-            directory = os.path.dirname(directory)
+            directory = osp.dirname(directory)
     return None
 
+
 # -----------------------------------------------------------------------------
 def autodetect_format(filename):
     """
@@ -223,24 +235,42 @@ def autodetect_format(filename):
         str: Format of comments; *None* if format isn't detected.
     """
     extensions = {
-        'cpp' : ('c', 'cpp', 'cxx', 'cc', 'c++',
-                 'h', 'hxx', 'hpp', 'hh', 'h++',
-                 'idl', 'i'),
-        'shell' : ('sh', 'bash', 'csh', 'cmake', 'txt', 'cfg', 'ini', 'm4'),
-        'python' : ('py',),
+        'cpp': ('c', 'cpp', 'cxx', 'cc', 'c++',
+                'h', 'hxx', 'hpp', 'hh', 'h++',
+                'idl', 'i'),
+        'shell': ('sh', 'bash', 'csh', 'cmake', 'txt', 'cfg', 'ini', 'm4'),
+        'python': ('py',),
         }
-    if filename and os.path.isfile(filename):
-        extension = os.path.splitext(filename)[1][1:].lower()
+    rev_extensions = {e: k for k, exts in extensions.items() for e in exts}
+    if filename and osp.isfile(filename):
+        extension = osp.splitext(filename)[1][1:].lower()
         if extension in ('in',):
-            name = os.path.splitext(filename)[0]
-            extension = os.path.splitext(name)[1][1:].lower()
-        for format in extensions:
-            if extension in extensions[format]:
-                return format
+            name = osp.splitext(filename)[0]
+            extension = osp.splitext(name)[1][1:].lower()
+        if extension in rev_extensions:
+            return rev_extensions[extension]
+
+    try:
+        import magic
+        mtool = magic.open(magic.MAGIC_MIME_TYPE)
+        mtool.load()
+        file_formats = {
+            'cpp': ('text/x-c', 'text/x-c++'),
+            'shell': ('text/x-shellscript',),
+            'python': ('text/x-python',),
+            }
+        rev_file_formats = {f: k for k, ff in file_formats.items() for f in ff}
+        file_format = mtool.file(filename)
+        if file_format in rev_file_formats:
+            return rev_file_formats[file_format]
+    except ImportError:
+        pass
+
     return None
 
+
 # -----------------------------------------------------------------------------
-def insert_copyright(filename, owner, year, format):
+def insert_copyright(filename, owner, year, file_format):
     """
     Insert copyright note to a file.
 
@@ -248,7 +278,7 @@ def insert_copyright(filename, owner, year, format):
         filename (str): File path.
         owner (str): Copyright owner.
         year (str): Copyright year(s).
-        format (str): Format of comments.
+        file_format (str): Format of comments.
     """
     try:
         with open(filename) as fid:
@@ -257,29 +287,28 @@ def insert_copyright(filename, owner, year, format):
         warning("cannot read file: {}".format(filename))
         return
 
-    if format in ('auto',):
-        format = autodetect_format(filename)
+    if file_format in ('auto',):
+        file_format = autodetect_format(filename)
 
     if owner.lower() in ('auto',):
         owner = autodetect_owner(filename) or get_owner('all')
     else:
         owner = get_owner(owner)
 
-    comment = get_comment(format)
+    comment = get_comment(file_format)
     if comment is None:
         warning("cannot detect format")
         return
 
     shell_row = search_line(lines, r'^#!') \
-        if format in ('sh', 'bash', 'csh', 'py', 'python') else -1
-    coding_row = search_line(lines, r'-\*- coding:', 3) \
-        if format in ('py', 'python') else -1
-    insert_point = max(0, shell_row+1, coding_row+1)
-
-    copyright = get_copyright(comment, owner, year)
-    if copyright:
-        lines = lines[:insert_point] + copyright + ['\n'] \
-            + lines[insert_point:]
+        if file_format in ('sh', 'bash', 'csh', 'py', 'python') else -1
+    coding_row = search_line(lines, r'coding:', 3) \
+        if file_format in ('py', 'python') else -1
+    insert_point = max(0, shell_row + 1, coding_row + 1)
+
+    cp_notice = get_copyright(comment, owner, year)
+    if cp_notice:
+        lines[insert_point:insert_point] = cp_notice
         try:
             with open(filename, 'w') as fid:
                 for line in lines:
@@ -288,46 +317,45 @@ def insert_copyright(filename, owner, year, format):
             warning("cannot write file: {}".format(filename))
             return
 
+
 # -----------------------------------------------------------------------------
 def main():
     """Main function."""
 
     # Parse command line.
-    usage = "%prog [options] [FILE] ..."
-    description = "Command line tool to insert copyright notice to a file."
-    parser = optparse.OptionParser(usage=usage, description=description)
+    description = "Command line tool to insert copyright notice to file(s)."
+    parser = argparse.ArgumentParser(description=description)
 
     help_string = "copyright owner; if not specified, tool tries to " \
         "autodetect an owner from the file path; if auto-detection fails, " \
         "an owner is set to '{owner}'"
     owner = 'auto'
-    parser.add_option("-o", "--owner", action="store",
-                      dest="owner", default=owner,
-                      help=help_string.format(owner=get_owner('all')))
+    parser.add_argument("-o", "--owner", action="store",
+                        dest="owner", default=owner,
+                        help=help_string.format(owner=get_owner('all')))
     help_string = "copyright year(s); default: current year ({year})"
     year = str(time.localtime().tm_year)
-    parser.add_option("-y", "--year", action="store",
-                      dest="year", default=year,
-                      help=help_string.format(year=year))
-    help_string = "format of comments ({choices}); default: {format}"
-    format = 'auto'
-    parser.add_option("-f", "--format", action="store",
-                      type='choice', choices=formats(),
-                      dest="format", default=format,
-                      help=help_string.format(format=format,
-                                              choices="|".join(formats())))
-
-    options, files = parser.parse_args(sys.argv[1:])
-
-    owner = options.owner
-    year = options.year
-    format = options.format
-
-    if not files:
-        error_exit('file is not specified')
+    parser.add_argument("-y", "--year", action="store",
+                        dest="year", default=year,
+                        help=help_string.format(year=year))
+    help_string = "format of comments ({choices}); default: {file_format}"
+    file_format = 'auto'
+    parser.add_argument("-f", "--format", action="store", choices=formats(),
+                        dest="format", default=file_format,
+                        help=help_string.format(file_format=file_format,
+                                                choices="|".join(formats())))
+    help_string = "file where to insert copyright notice"
+    parser.add_argument('files', nargs='+', metavar='FILE', help=help_string)
+
+    args = parser.parse_args(sys.argv[1:])
+
+    owner = args.owner
+    year = args.year
+    file_format = args.format
+    files = args.files
 
     for filename in files:
-        insert_copyright(filename, owner, year, format)
+        insert_copyright(filename, owner, year, file_format)
 
     return 0