Source code for ElementsKernel.ProjectCommonRoutines

#
# Copyright (C) 2012-2020 Euclid Science Ground Segment
#
# This library is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 3.0 of the License, or (at your option)
# any later version.
#
# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#

""" This module offers some common routines used by the Elements scripts for creating (C++, python)
projects, modules, classes etc..

:file: ElementsKernel/ProjectCommonRoutines.py
:author: Nicolas Morisset

:date: 01/07/15

"""

import os
import re
import shutil
import ElementsKernel.ParseCmakeLists as pcl
import ElementsKernel.ParseCmakeListsMacros as pclm
import ElementsKernel.NameCheck as nc
import ElementsKernel.Logging as log
import ElementsKernel.Auxiliary as aux

try:
    from builtins import input
except ImportError:
    from __builtin__ import input

# Define a global list containing files created or modified
# by the python scripts for the creation of a Elements project
_filelist = []

# Define regex for name & version checking
NAME_REGEX = r"^[A-Za-z0-9][A-Za-z0-9_-]*$"
VERSION_REGEX = r"^(\d+\.\d+(\.\d+)?|HEAD)$"

LOGGER = log.getLogger(__name__)

CMAKE_LISTS_FILE = 'CMakeLists.txt'


################################################################################
[docs]def addItemToCreationList(element): """ Add an element to the global list. """ _filelist.append(element)
################################################################################
[docs]def printCreationList(): """ Print the contents of the file list """ LOGGER.info("#") LOGGER.info("# File(s) created/modified:") LOGGER.info("#") for elt in _filelist: LOGGER.info("# file --> %s", elt) LOGGER.info("#")
################################################################################
[docs]def checkNameInEuclidNamingDatabase(entity_name, entity_type="", answer_yes=False): """ Check if the entity_name (e.g. project name, module name, class name etc...) already exists in the Euclid Naming Database. This function displays warning messages if the element_name exists already or the database is not available. """ script_goes_on = True LOGGER.info("Querying the Element Naming Database...") db_url = os.environ.get("ELEMENTS_NAMING_DB_URL", "") if not nc.checkDataBaseUrl(db_url): LOGGER.info("#") LOGGER.warning("!!! The Elements Naming Database URL is not valid : <%s> !!!", db_url) LOGGER.warning("!!! Please set the ELEMENTS_NAMING_DB_URL environment variable to the Database URL !!!") else: info = nc.getInfo(entity_name, db_url, entity_type) if info["error"]: LOGGER.error("There was an error querying the DB: %s", info["message"]) else: if info["exists"]: LOGGER.info("#") LOGGER.warning("!!! The \"%s\" name for the \"%s\" type already exists in the Element Naming Database !!!", entity_name, entity_type) LOGGER.warning("See the result for the global query of the \"%s\" name in the DB: %s", entity_name, info["url"]) LOGGER.warning("For more information also connect to: %s", info["private_url"]) script_goes_on = False else: LOGGER.warning("") LOGGER.warning("The \"%s\" name of \"%s\" type doesn't exist in the Element Naming Database!!!", entity_name, entity_type) LOGGER.warning("Please think to add the \"%s\" name in the Element Naming Database below:", entity_name) LOGGER.warning("< %s/NameCheck/project1/ >", db_url) LOGGER.info("") if not answer_yes and not script_goes_on: response_key = input('Do you want to continue?(y/n, default: n)') if not response_key.lower() == "yes" and not response_key.lower() == "y": raise Exception()
################################################################################
[docs]def removeFilesOnDisk(file_list): """ Remove all files on hard drive from the <file_list> list. """ LOGGER.info('') for elt in file_list: LOGGER.info('File deleted : %s', elt) deleteFile(elt) LOGGER.info('')
################################################################################
[docs]def makeDirectory(directory_path): """ Create a directory on disk if any """ if not os.path.exists(directory_path): os.makedirs(directory_path)
################################################################################
[docs]def deleteFile(path_filename): """ Delete the <path_filename> file if it does exist. <path_filename> includes the path and filename. """ if os.path.exists(path_filename): os.remove(path_filename)
################################################################################
[docs]def makeACopy(cmakefile): """ Make a copy(backup) of the <CMakeFileLists.txt> file. The copy is named <CMakeFileLists.txt~>, <cmakefile> includes the path of the file. """ copy_file = cmakefile + '~' if os.path.exists(cmakefile): shutil.copy(cmakefile, copy_file) else: LOGGER.warning('File not found: <%s> Can not make a copy of this file!', cmakefile)
################################################################################
[docs]def checkNameAndVersionValid(name, version): """ Check that the <name> and <version> respect a regex """ if not re.match(NAME_REGEX, name): raise Exception("Name not valid : < %s >. It must follow this regex : < %s >" % (name, NAME_REGEX)) if not re.match(VERSION_REGEX, version): raise Exception("Version number not valid : < %s >. It must follow this regex : < %s >" % (version, VERSION_REGEX))
################################################################################
[docs]def eraseDirectory(directory): """ Erase a directory and its contents from disk """ if os.path.isdir(directory): shutil.rmtree(directory) LOGGER.info('< %s > directory erased!', directory)
################################################################################
[docs]def copyAuxFile(destination, aux_file_name): """ Copy the <aux_file_name> file to the <destination> directory. <aux_file_name> is just the name without path """ aux_path_file = aux.getAuxiliaryPath(os.path.join('ElementsKernel', 'templates', aux_file_name)) shutil.copy(aux_path_file, os.path.join(destination, aux_file_name))
################################################################################
[docs]def checkAuxFileExist(aux_file_name): """ Make sure the <aux_file> auxiliary file exists. Return an exception in case of an error. <aux_file_name> is just the name without the path. """ auxpath = os.path.join('ElementsKernel', 'templates', aux_file_name) aux.getAuxiliaryPath(auxpath)
################################################################################
[docs]def getAuthor(): """ Get the contents of the <USER> environment variables """ try: author_str = os.environ['USER'] except KeyError: author_str = '' return author_str
################################################################################
[docs]def getElementsModuleName(module_directory): """ Get the module name from the <CMAKE_LISTS_FILE> file """ module_name = '' cmake_file = os.path.join(module_directory, CMAKE_LISTS_FILE) if not os.path.isfile(cmake_file): raise Exception("< %s > cmake module file is missing! Are you inside a module directory?" % cmake_file) # Check the make file is an Elements cmake file # it should contain the string : "elements_project" f = open(cmake_file) for line in f.readlines(): if 'elements_subdir' in line: pos_start = line.find('(') pos_end = line.find(')') module_name = line[pos_start + 1:pos_end] f.close() if not module_name: raise Exception("Module name not found in the <%s> file! Perhaps you are not in a " \ "module directory!" % cmake_file) return module_name
################################################################################
[docs]def checkFileNotExist(path_filename, name): """ Check if the <path_filename> file does not already exist <path_filename> : path + filename """ if os.path.exists(path_filename): raise Exception("File already exists there : < %s > with name : < %s >" % (path_filename, name))
################################################################################ ################################################################################
[docs]def createPythonInitFile(init_path_filename): """ Create on disk the __init__.py python file """ if not os.path.exists(init_path_filename): f = open(init_path_filename, 'w') doc_str = "\"\"\"\n" f.write(doc_str) f.write("Module Overview <----------------- TO BE WRITTEN ------------------------>\n\n") f.write(doc_str) f.write("from pkgutil import extend_path\n") f.write("__path__ = extend_path(__path__, __name__)\n") f.close()
################################################################################ ################################################################################
[docs]def updateCmakeCommonPart(cmake_filename, library_dep_list): """ Update Library list in CmakeList file. Common code between scripts It returns a cmake_object object and the module name """ # Backup the file makeACopy(cmake_filename) f = open(cmake_filename) data = f.read() f.close() cmake_object = pcl.CMakeLists(data) # Update find_package macro if library_dep_list: for lib in library_dep_list: package_object = pclm.FindPackage(lib, []) cmake_object.find_package_list.append(package_object) module_name = cmake_object.elements_subdir_list[0].name return cmake_object, module_name