cengal.build_tools.ensure_copyright.versions.v_0.ensure_copyright

  1#!/usr/bin/env python
  2# coding=utf-8
  3
  4# Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>
  5# 
  6# Licensed under the Apache License, Version 2.0 (the "License");
  7# you may not use this file except in compliance with the License.
  8# You may obtain a copy of the License at
  9# 
 10#     http://www.apache.org/licenses/LICENSE-2.0
 11# 
 12# Unless required by applicable law or agreed to in writing, software
 13# distributed under the License is distributed on an "AS IS" BASIS,
 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15# See the License for the specific language governing permissions and
 16# limitations under the License.
 17
 18
 19__all__ = ['ensure_copyright', 'get_version', 'set_version', 'default_version_bracket_pair']
 20
 21
 22"""
 23Module Docstring
 24Docstrings: http://www.python.org/dev/peps/pep-0257/
 25"""
 26
 27__author__ = "ButenkoMS <gtalk@butenkoms.space>"
 28__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>"
 29__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ]
 30__license__ = "Apache License, Version 2.0"
 31__version__ = "4.4.1"
 32__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>"
 33__email__ = "gtalk@butenkoms.space"
 34# __status__ = "Prototype"
 35__status__ = "Development"
 36# __status__ = "Production"
 37
 38
 39from cengal.file_system.file_manager import current_src_file_dir, path_relative_to_current_src
 40from cengal.file_system.directory_manager import filtered_file_list_traversal, FilteringType
 41from cengal.file_system.path_manager import path_relative_to_src, RelativePath
 42from cengal.text_processing.encoding_detection import detect_and_decode
 43from cengal.text_processing.text_processing import find_text, replace_slice
 44from cengal.text_processing.brackets_processing import BracketPair, Bracket, replace_text_with_brackets, find_text_with_brackets, find_text_in_brackets, replace_text_in_brackets
 45from os.path import splitext, join
 46from typing import Set, Optional
 47
 48
 49_PYTHON_FILES_EXTENSIONS: Set[str] = {'.pyx', '.py', '.pyw', 'pyi'}
 50
 51
 52def ensure_copyright(src_root_dir: str, 
 53                     head_string: str, 
 54                     license_string: str, 
 55                     license_bracket_pair: BracketPair, 
 56                     module_docstring_string: str, 
 57                     credits_string: str,
 58                     credits_bracket_pair: BracketPair,
 59                     python_files_extensions: Set[str] = None,
 60                     silent: bool = False):
 61    python_files_extensions = python_files_extensions or _PYTHON_FILES_EXTENSIONS
 62    travers_result = filtered_file_list_traversal(src_root_dir, FilteringType.including, _PYTHON_FILES_EXTENSIONS, remove_empty_items=True, use_spinner=False)
 63    files_processed: int = 0
 64    try:
 65        for dir_path, dirs, files in travers_result:
 66            for file in files:
 67                file_path = join(dir_path, file)
 68                if not silent:
 69                    print()
 70                    print(f'... Processing: {file_path}')
 71
 72                try:
 73                    with open(file_path, 'r+b') as file:
 74                        text, text_encoding, bom_bytes = detect_and_decode(file.read())
 75                        if not bom_bytes:
 76                            text_encoding = 'utf-8'
 77                        
 78                        head_string_pos = find_text(text, head_string, 0, len(head_string) * 2)
 79                        license_string_pos = find_text_with_brackets(text, license_bracket_pair)
 80                        module_docstring_string_pos = find_text(text, module_docstring_string)
 81                        credits_string_pos = find_text_with_brackets(text, credits_bracket_pair)
 82                        
 83                        replace_only: bool = bool(head_string_pos is not None) and bool(license_string_pos is not None) and bool(credits_string_pos is not None)
 84                        if replace_only:
 85                            text, _ = replace_text_with_brackets(text, license_bracket_pair, license_string, 1)
 86                            text, _ = replace_text_with_brackets(text, credits_bracket_pair, credits_string, 1)
 87                        else:
 88                            head_string_pos = find_text(text, head_string, 0, len(head_string) * 2)
 89                            if head_string_pos is not None:
 90                                text, _ = replace_slice(text, head_string_pos, str())
 91                            
 92                            license_string_pos = find_text_with_brackets(text, license_bracket_pair)
 93                            if license_string_pos is not None:
 94                                text, _ = replace_slice(text, license_string_pos, str())
 95                            
 96                            module_docstring_string_pos = find_text(text, module_docstring_string)
 97                            if module_docstring_string_pos is not None:
 98                                text, _ = replace_slice(text, module_docstring_string_pos, str())
 99                            
100                            credits_string_pos = find_text_with_brackets(text, credits_bracket_pair)
101                            if credits_string_pos is not None:
102                                text, _ = replace_slice(text, credits_string_pos, str())
103
104                            new_head: str = head_string + '\n\n' + license_string + '\n\n\n' + module_docstring_string + '\n\n\n' + credits_string + '\n\n\n'
105                            text = new_head + text
106                        
107                        file.seek(0, 0)
108                        file.truncate(0)
109                        data = bom_bytes + text.encode(text_encoding)
110                        file.write(data)
111                        files_processed += 1
112                finally:
113                    if not silent:
114                        print(f'Done: {file_path}')
115    finally:
116        if not silent:
117            print()
118            print(f'Files procesed: {files_processed}')
119
120
121default_credits_bracket_pair: BracketPair = BracketPair([Bracket('credits_string =')], [Bracket('credits_bracket_pair: BracketPair =')])
122default_version_bracket_pair: BracketPair = BracketPair([Bracket('__version__ = "')], [Bracket('"')])
123
124
125def get_version(script_file_full_path: str,
126                credits_string_bracket_pair: Optional[BracketPair] = None, 
127                version_bracket_pair: Optional[BracketPair] = None, 
128                ) -> Optional[str]:
129    credits_string_bracket_pair = default_credits_bracket_pair if credits_string_bracket_pair is None else credits_string_bracket_pair
130    version_bracket_pair = default_version_bracket_pair if version_bracket_pair is None else version_bracket_pair
131    with open(script_file_full_path, 'rb') as file:
132        text, _, _ = detect_and_decode(file.read())
133        credits_string_pos: slice = find_text_in_brackets(text, credits_string_bracket_pair)
134        if credits_string_pos is not None:
135            credits_string: str = text[credits_string_pos]
136            version_pos: slice = find_text_in_brackets(credits_string, version_bracket_pair)
137            if version_pos is not None:
138                return credits_string[version_pos]
139    
140    return None
141
142
143def set_version(script_file_full_path: str,
144                new_version: str, 
145                credits_string_bracket_pair: Optional[BracketPair] = None, 
146                version_bracket_pair: Optional[BracketPair] = None, 
147                ) -> bool:
148    credits_string_bracket_pair = default_credits_bracket_pair if credits_string_bracket_pair is None else credits_string_bracket_pair
149    version_bracket_pair = default_version_bracket_pair if version_bracket_pair is None else version_bracket_pair
150    with open(script_file_full_path, 'r+b') as file:
151        text, text_encoding, bom_bytes = detect_and_decode(file.read())
152        credits_string_pos: slice = find_text_in_brackets(text, credits_string_bracket_pair)
153        if credits_string_pos is not None:
154            credits_string: str = text[credits_string_pos]
155            version_pos: slice = find_text_in_brackets(credits_string, version_bracket_pair)
156            if version_pos is not None:
157                credits_string, _ = replace_text_in_brackets(credits_string, version_bracket_pair, new_version)
158                text, _ = replace_slice(text, credits_string_pos, credits_string)
159                file.seek(0, 0)
160                file.truncate(0)
161                data = bom_bytes + text.encode(text_encoding)
162                file.write(data)
163                return True
164    
165    return False
def get_version( script_file_full_path: str, credits_string_bracket_pair: Union[cengal.text_processing.brackets_processing.versions.v_0.brackets.BracketPair, NoneType] = None, version_bracket_pair: Union[cengal.text_processing.brackets_processing.versions.v_0.brackets.BracketPair, NoneType] = None) -> Union[str, NoneType]:
126def get_version(script_file_full_path: str,
127                credits_string_bracket_pair: Optional[BracketPair] = None, 
128                version_bracket_pair: Optional[BracketPair] = None, 
129                ) -> Optional[str]:
130    credits_string_bracket_pair = default_credits_bracket_pair if credits_string_bracket_pair is None else credits_string_bracket_pair
131    version_bracket_pair = default_version_bracket_pair if version_bracket_pair is None else version_bracket_pair
132    with open(script_file_full_path, 'rb') as file:
133        text, _, _ = detect_and_decode(file.read())
134        credits_string_pos: slice = find_text_in_brackets(text, credits_string_bracket_pair)
135        if credits_string_pos is not None:
136            credits_string: str = text[credits_string_pos]
137            version_pos: slice = find_text_in_brackets(credits_string, version_bracket_pair)
138            if version_pos is not None:
139                return credits_string[version_pos]
140    
141    return None
def set_version( script_file_full_path: str, new_version: str, credits_string_bracket_pair: Union[cengal.text_processing.brackets_processing.versions.v_0.brackets.BracketPair, NoneType] = None, version_bracket_pair: Union[cengal.text_processing.brackets_processing.versions.v_0.brackets.BracketPair, NoneType] = None) -> bool:
144def set_version(script_file_full_path: str,
145                new_version: str, 
146                credits_string_bracket_pair: Optional[BracketPair] = None, 
147                version_bracket_pair: Optional[BracketPair] = None, 
148                ) -> bool:
149    credits_string_bracket_pair = default_credits_bracket_pair if credits_string_bracket_pair is None else credits_string_bracket_pair
150    version_bracket_pair = default_version_bracket_pair if version_bracket_pair is None else version_bracket_pair
151    with open(script_file_full_path, 'r+b') as file:
152        text, text_encoding, bom_bytes = detect_and_decode(file.read())
153        credits_string_pos: slice = find_text_in_brackets(text, credits_string_bracket_pair)
154        if credits_string_pos is not None:
155            credits_string: str = text[credits_string_pos]
156            version_pos: slice = find_text_in_brackets(credits_string, version_bracket_pair)
157            if version_pos is not None:
158                credits_string, _ = replace_text_in_brackets(credits_string, version_bracket_pair, new_version)
159                text, _ = replace_slice(text, credits_string_pos, credits_string)
160                file.seek(0, 0)
161                file.truncate(0)
162                data = bom_bytes + text.encode(text_encoding)
163                file.write(data)
164                return True
165    
166    return False
default_version_bracket_pair: cengal.text_processing.brackets_processing.versions.v_0.brackets.BracketPair = <cengal.text_processing.brackets_processing.versions.v_0.brackets.BracketPair object>