#
# 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 script will create a new Elements project
:file: ElementsKernel/Project.py
:author: Nicolas Morisset
:date: 01/07/15
"""
import os
import re
import ELEMENTS_VERSION # @UnresolvedImport pylint: disable=import-error
from ElementsKernel import Logging
from ElementsKernel import Auxiliary
from ElementsKernel import ProjectCommonRoutines
try:
from builtins import input
except ImportError:
from __builtin__ import input
LOGGER = Logging.getLogger(__name__)
AUX_CMAKE_LIST_IN = "CMakeLists.txt.in"
AUX_MAKE_FILE_IN = "Makefile.in"
AUX_PROJ_RST_IN = "doc_project.rst.in"
AUX_PROJ_MAINPAGE_IN = "mainpage.dox.in"
AUX_GITIGNORE_IN = "gitignore_template.in"
AUX_GITATTRIBUTES_IN = "gitattributes_template.in"
AUX_EDITOR_CONFIG = "editorconfig"
AUX_CLANG_FORMAT = "clang-format"
target_locations = { AUX_CMAKE_LIST_IN: "CMakeLists.txt",
AUX_MAKE_FILE_IN: "Makefile",
AUX_PROJ_RST_IN: "doc/doc_project.rst",
AUX_PROJ_MAINPAGE_IN: "doc/mainpage.dox",
AUX_GITIGNORE_IN: ".gitignore",
AUX_GITATTRIBUTES_IN: ".gitattributes",
AUX_EDITOR_CONFIG: ".editorconfig",
AUX_CLANG_FORMAT: ".clang-format"
}
################################################################################
[docs]def setPath():
"""
Set the installation path either the current directory or
the directory set by the <User_area> environment variable
"""
# Check if User_area environment variable exists
user_area = os.environ.get('User_area')
if not user_area is None:
LOGGER.debug('# <$User_area> environment variable defined to : <%s>', user_area)
destination_path = user_area
else:
destination_path = os.getcwd()
return destination_path
################################################################################
[docs]def checkDependencyProjectValid(str_list):
"""
Check if the dependency project name and version list is valid
"""
for i in range(len(str_list)):
ProjectCommonRoutines.checkNameAndVersionValid(str_list[i][0], str_list[i][1])
################################################################################
[docs]def duplicate_elements(duplicate_list):
"""
Look for duplicate element in a list
"""
name_list = []
for elt in duplicate_list:
if not elt[0] in name_list:
name_list.append(elt[0])
else:
raise Exception("Found twice the following dependency : < %s >" % elt[0])
################################################################################
[docs]def getElementsVersion():
"""
Get the Elements version number
"""
elt_version = ELEMENTS_VERSION.ELEMENTS_ORIGINAL_VERSION
LOGGER.info('# Elements version found : <%s>', elt_version)
return str(elt_version)
################################################################################
[docs]def getSubstituteConfiguration(proj_name, proj_version, dep_projects, standalone=False, visibility=False):
"""
Format all dependent projects
We put by default Elements dependency if no one is given
"""
if standalone:
str_dep_projects = ""
else:
str_dep_projects = 'Elements ' + getElementsVersion()
if dep_projects:
for dep in dep_projects:
if not dep[0] in str_dep_projects:
str_dep_projects += ' ' + dep[0] + ' ' + dep[1]
else:
LOGGER.warning('<%s> dependency already exists. It is skipped!', dep[0])
if str_dep_projects:
str_dep_projects = "USE " + str_dep_projects
str_visibility = ""
if visibility:
str_visibility = """set(ELEMENTS_HIDE_SYMBOLS ON
CACHE STRING "Enable explicit symbol visibility on gcc-4"
FORCE)"""
configuration = {"PROJECT_NAME":proj_name,
"PROJECT_VERSION":proj_version,
"DEPENDANCE_LIST":str_dep_projects,
"ELEMENTS_HIDE_SYMBOLS":str_visibility}
return configuration
################################################################################
[docs]def createProject(project_dir, proj_name, proj_version, dep_projects, standalone=False, visibility=False):
"""
Create the project structure
"""
LOGGER.info('# Creating the project')
configuration = getSubstituteConfiguration(proj_name, proj_version, dep_projects, standalone, visibility)
for src in target_locations:
file_name = os.path.join("ElementsKernel", "templates", src)
tgt = target_locations[src]
Auxiliary.configure(file_name, project_dir, tgt,
configuration=configuration,
create_missing_dir=True)
ProjectCommonRoutines.addItemToCreationList(os.path.join(project_dir, tgt))
[docs]def makeChecks(proj_name, proj_version, dependency, dependant_projects):
"""
Make some checks
"""
# Check project name and version
ProjectCommonRoutines.checkNameAndVersionValid(proj_name, proj_version)
if not dependency is None:
checkDependencyProjectValid(dependant_projects)
# Check for duplicate dependencies
if not dependency is None:
duplicate_elements(dependant_projects)
# Check AUX files exist
ProjectCommonRoutines.checkAuxFileExist(AUX_CMAKE_LIST_IN)
ProjectCommonRoutines.checkAuxFileExist(AUX_MAKE_FILE_IN)
################################################################################
[docs]def getProjectDirectory(no_version_directory, destination_path, proj_name, proj_version):
"""
Build project directory path
"""
if no_version_directory:
project_dir = os.path.join(destination_path, proj_name)
else:
project_dir = os.path.join(destination_path, proj_name, proj_version)
return project_dir
################################################################################
[docs]def lookForDirectories(project_dir):
"""
Look for any version directory in the project directory e.g HEAD, 1.2.3, 1.0 etc...
"""
match_list = []
dirlist = [elt for elt in os.listdir(project_dir) if os.path.isdir(os.path.join(project_dir, elt)) ]
for elt in dirlist:
match = re.match(ProjectCommonRoutines.VERSION_REGEX, elt)
if match:
match_list.append(match.group(0))
return match_list
################################################################################
[docs]def checkProjectExist(project_dir, no_version_directory, force_erase, answer_yes=False):
"""
Look for any version directory in the project directory e.g 1.0,1.2 etc...
"""
if os.path.exists(project_dir) and not force_erase:
LOGGER.warning('<%s> Project ALREADY exists!!!', project_dir)
version_dir_list = lookForDirectories(project_dir)
# Warn user about directory under the project
if no_version_directory and version_dir_list:
LOGGER.warning('Found the following version(s) directory(ies) : %s', version_dir_list)
if not answer_yes:
response_key = input('Do you want to overwrite the existing project (y/n, default: n)?')
if answer_yes or response_key.lower() == "yes" or response_key == "y":
LOGGER.info('# Overwriting the existing project: <%s>', project_dir)
else:
raise Exception()
elif force_erase:
ProjectCommonRoutines.eraseDirectory(project_dir)