From f478ab775d9d5bf68065bdfa3ed7225e5c83ca99 Mon Sep 17 00:00:00 2001 From: Konstantin Leontev Date: Thu, 1 Dec 2022 15:07:14 +0300 Subject: [PATCH] [bos #32522][EDF] SALOME on Demand. Now we can create salomex from provided module dir, salomexb and salomexd files. --- bin/SalomeOnDemandTK/ExtensionBuilder.py | 199 ++++++++++++++++++----- 1 file changed, 157 insertions(+), 42 deletions(-) diff --git a/bin/SalomeOnDemandTK/ExtensionBuilder.py b/bin/SalomeOnDemandTK/ExtensionBuilder.py index edd99c372..c75ca4861 100644 --- a/bin/SalomeOnDemandTK/ExtensionBuilder.py +++ b/bin/SalomeOnDemandTK/ExtensionBuilder.py @@ -29,86 +29,201 @@ import tarfile -import os.path +import os import sys import logging import io -import pathlib +import json +import fnmatch # Setup logger's output FORMAT = '%(funcName)s():%(lineno)s: %(message)s' logging.basicConfig(format=FORMAT, level=logging.DEBUG) logger = logging.getLogger() -"""Salome Extension Directory inside any extension's archive""" +'''Salome Extension Directory inside any extension's archive''' salomeExtDir = '__SALOME_EXT__' -salomexcName = 'salomexc' +arcFileNameExt = 'salomex' +bFileNameExt = 'salomexb' +cFileNameExt = 'salomexc' +dFileNameExt = 'salomexd' + +extNameKey = 'name' +extDescrKey = 'descr' +extDependsOnKey = 'dependsOn' +extAuthorKey = 'author' +extComponentsKey = 'components' + + +def createSalomexdFile(name, descr = '', dependsOn = [], author = '', components = []): + ''' + Create a basic salomexd file from provided args. + ''' + + logger.debug('Create salomexd file...') + + jsonString = json.dumps( + { + extNameKey: name, + extDescrKey: descr, + extDependsOnKey: dependsOn, + extAuthorKey: author, + extComponentsKey: components + }, + indent = 4 + ) -def listFilesAbs(dirPath): - """ - Returns the recursive list of absolut paths to files (as pathlib.Path objects) - in the dirPath root directory and all subdirectories. - """ + try: + with open(name + '.' + dFileNameExt, "w") as file: + file.write(jsonString) + + except Exception: + import traceback + logger.error(traceback.format_exc()) + + +def createSalomexbFile(name, included): + ''' + Create a salomexb file from a list of included file names. + For example: + */*.py + doc/*.html + doc/*.jp + ''' + + logger.debug('Create salomexb file...') + + try: + with open(name + '.' + bFileNameExt, "w") as file: + file.write('\n'.join(included[0:])) - files = [] + except Exception: + import traceback + logger.error(traceback.format_exc()) + + +def readSalomexbFile(filePath): + ''' + Returns a content af a salomexb file as a list of strings + ''' + + logger.debug('Read salomexb file %s', filePath) + + try: + with open(filePath, 'r', encoding='UTF-8') as file: + return [line.rstrip() for line in file] + + except Exception: + import traceback + logger.error(traceback.format_exc()) + return [] - for path in pathlib.Path(dirPath).iterdir(): - if path.is_file(): - files.append(path) - else: - files += listFilesAbs(path) - return files +def readJsonFile(filePath): + ''' + Returns a content af a json file as a dictionary + ''' + + logger.debug('Read json file %s', filePath) + + try: + with open(filePath) as jsonFile: + return json.load(jsonFile) + + except Exception: + import traceback + logger.error(traceback.format_exc()) + return {} + def listFilesRel(dirPath): - """ - Returns the recursive list of relative paths to files (as pathlib.Path objects) + ''' + Returns the recursive list of relative paths to files as strings in the dirPath root directory and all subdirectories. - """ + ''' - filesAbs = listFilesAbs(dirPath) - return [file.relative_to(dirPath) for file in filesAbs] + filesList = [] + for root, dirs, files in os.walk(dirPath): + for file in files: + filesList += os.path.relpath(os.path.join(root, file), dirPath) -def listFiles(dirPath, isRel = True): - """ - Returns the recursive list of paths to files (as a list of strings) - in the dirPath root directory and all subdirectories. - """ + return filesList - pathList = listFilesRel(dirPath) if isRel else listFilesAbs(dirPath) - return [str(path) for path in pathList] def fileListToNewLineStr(fileList): - """ + ''' Returns the list of paths as a newline separated string - """ + ''' return '\n'.join(file for file in fileList) -def salomeExtFromInstallDir(sourceDirPath, extName = ''): - """ + +def createSalomexFile(sourceDirPath, salomexbPath, salomexdPath): + ''' Makes salome extension archive from a classic module install directory - """ + ''' + + logger.debug('Starting create an salome extension file') + + if sourceDirPath == '': + logger.error('sourceDirPath argument cannot be empty!') + return - logger.debug('salomeExtFromInstallDir() call') + extName = '' + + # Try to get info from salomexd file + salomexdContent = readJsonFile(salomexdPath) + if extNameKey in salomexdContent and salomexdContent[extNameKey]: + extName = salomexdContent[extNameKey] - sourceDirName = os.path.basename(sourceDirPath) if extName == '': - extName = sourceDirName + extName = os.path.basename(sourceDirPath) try: - with tarfile.open(extName, "w:gz") as ext: - ext.add(sourceDirPath, salomeExtDir) + with tarfile.open(extName + '.' + arcFileNameExt, "w:gz") as ext: + # Write all included files to the extension's dir + + # Get the file's matching pattern in the first place + includedFilesPattern = readSalomexbFile(salomexbPath) + if not includedFilesPattern: + # We don't have any pattern, so include all the files + includedFilesPattern = ['*'] + + logger.debug('Included files pattern: %s', includedFilesPattern) + + # List of the files those actually written to the archive. + # It goes to the salomexc file then. + files = [] + + def fileFilter(tarinfo): + logger.debug('File name: %s', tarinfo.name) - # Write control file - list of files inside extension's dir - files = listFiles(sourceDirPath) + # Skip dir itself, otherwise it excludes all the files inside + if tarinfo.isdir(): + return tarinfo + + for f in includedFilesPattern: + if fnmatch.fnmatch(tarinfo.name, f): + logger.debug('File name %s matches pattern %s', tarinfo.name, f) + files.append(tarinfo.name) + return tarinfo + + return None + + ext.add(sourceDirPath, salomeExtDir, recursive = True, filter = fileFilter) + + # Write the control file - list of the files inside extension's dir extDirListData = fileListToNewLineStr(files).encode('utf8') - info = tarfile.TarInfo(salomexcName) + info = tarfile.TarInfo(extName + '.' + cFileNameExt) info.size=len(extDirListData) ext.addfile(info, io.BytesIO(extDirListData)) + # Write the description file as is + ext.add(salomexdPath) + except Exception: import traceback logger.error(traceback.format_exc()) + if __name__ == '__main__': - salomeExtFromInstallDir(sys.argv[1]) + createSalomexFile(sys.argv[1:]) -- 2.39.2