3 # Copyright (C) 2010-2012 CEA/DEN
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 '''In this file are implemented the classes and methods
19 relative to the product notion of salomeTools
26 AVAILABLE_VCS = ['git', 'svn', 'cvs']
28 def get_product_config(config, product_name):
29 '''Get the specific configuration of a product from the global configuration
31 :param config Config: The global configuration
32 :param product_name str: The name of the product
33 :return: the specific configuration of the product
37 # Get the version of the product from the application definition
38 version = config.APPLICATION.products[product_name]
39 # if no version, then take the default one defined in the application
40 if isinstance(version, bool):
41 version = config.APPLICATION.tag
43 # Define debug and dev modes
44 # Get the tag if a dictionary is given in APPLICATION.products for the
49 if isinstance(version, src.pyconf.Mapping):
52 if not 'tag' in dic_version:
53 version = config.APPLICATION.tag
55 version = dic_version.tag
57 # Get the debug if any
58 if 'debug' in dic_version:
59 debug = dic_version.debug
62 if 'dev' in dic_version:
66 if 'base' in dic_version:
67 base = dic_version.base
70 # substitute some character with _ in order to get the correct definition
71 # in config.PRODUCTS. This is done because the pyconf tool does not handle
72 # the . and - characters
73 for c in ".-": vv = vv.replace(c, "_")
76 if product_name in config.PRODUCTS:
77 # If it exists, get the information of the product_version
78 if "version_" + vv in config.PRODUCTS[product_name]:
79 # returns specific information for the given version
80 prod_info = config.PRODUCTS[product_name]["version_" + vv]
81 # Get the standard informations
82 elif "default" in config.PRODUCTS[product_name]:
83 # returns the generic information (given version not found)
84 prod_info = config.PRODUCTS[product_name].default
86 # merge opt_depend in depend
87 if prod_info is not None and 'opt_depend' in prod_info:
88 for depend in prod_info.opt_depend:
89 if depend in config.PRODUCTS:
90 prod_info.depend.append(depend,'')
92 # In case of a product get with a vcs,
93 # put the tag (equal to the version)
94 if prod_info is not None and prod_info.get_source in AVAILABLE_VCS:
96 if prod_info.get_source == 'git':
97 prod_info.git_info.tag = version
99 if prod_info.get_source == 'svn':
100 prod_info.svn_info.tag = version
102 if prod_info.get_source == 'cvs':
103 prod_info.cvs_info.tag = version
105 # In case of a fixed product,
106 # define the install_dir (equal to the version)
107 if prod_info is not None and prod_info.get_source=="fixed":
108 prod_info.install_dir = version
110 # Check if the product is defined as native in the application
111 if prod_info is not None:
112 if version == "native":
113 prod_info.get_source = "native"
114 elif prod_info.get_source == "native":
115 msg = _("The product %(prod)s has version %(ver)s but is "
116 "declared as native in its definition" %
117 { 'prod': prod_info.name, 'ver': version})
118 raise src.SatException(msg)
120 # If there is no definition but the product is declared as native,
121 # construct a new definition containing only the get_source key
122 if prod_info is None and version == "native":
123 prod_info = src.pyconf.Config()
124 prod_info.name = product_name
125 prod_info.get_source = "native"
127 # If prod_info is still None, it means that there is no product definition
128 # in the config. The user has to provide it.
129 if prod_info is None:
130 msg = _("No definition found for the product %s\n"
131 "Please create a %s.pyconf file." % (product_name, product_name))
132 raise src.SatException(msg)
134 # Set the debug, dev and version keys
135 prod_info.debug = debug
137 prod_info.version = version
139 # Set the archive_info if the product is get in archive mode
140 if prod_info.get_source == "archive":
141 if not "archive_info" in prod_info:
142 prod_info.addMapping("archive_info",
143 src.pyconf.Mapping(prod_info),
145 if "archive_name" not in prod_info.archive_info:
146 arch_name = product_name + "-" + version + ".tar.gz"
147 arch_path = src.find_file_in_lpath(arch_name,
148 config.PATHS.ARCHIVEPATH)
150 msg = _("Archive %(arch_name)s for %(prod_name)s not found:"
151 "\n" % {"arch_name" : arch_name,
152 "prod_name" : prod_info.name})
153 raise src.SatException(msg)
154 prod_info.archive_info.archive_name = arch_path
156 if (os.path.basename(prod_info.archive_info.archive_name) ==
157 prod_info.archive_info.archive_name):
159 arch_path = src.find_file_in_lpath(
160 prod_info.archive_info.archive_name,
161 config.PATHS.ARCHIVEPATH)
163 msg = _("Archive %(arch_name)s for %(prod_name)s not found:"
164 "\n" % {"arch_name" : arch_name,
165 "prod_name" : prod_info.name})
166 raise src.SatException(msg)
167 prod_info.archive_info.archive_name = arch_path
169 # Set the install_dir key
170 if "no_base" in config.APPLICATION and config.APPLICATION.no_base == "yes":
171 # Set it to the default value (in application directory)
172 prod_info.install_dir = os.path.join(config.APPLICATION.workdir,
177 prod_info.install_dir = "base"
178 if "install_dir" not in prod_info:
179 # Set it to the default value (in application directory)
180 prod_info.install_dir = os.path.join(config.APPLICATION.workdir,
184 if prod_info.install_dir == "base":
185 # Get the product base of the application
186 base_path = src.get_base_path(config)
187 prod_info.install_dir = os.path.join(base_path,
188 prod_info.name + "-" + version)
190 # If the product compiles with a script, check the script existence
191 # and if it is executable
192 if product_has_script(prod_info):
193 # Check the compil_script key existence
194 if "compil_script" not in prod_info:
195 msg = _("No compilation script found for the product %s\n"
196 "Please provide a \"compil_script\" key in its definition."
198 raise src.SatException(msg)
200 # Get the path of the script
201 script = prod_info.compil_script
202 script_name = os.path.basename(script)
203 if script == script_name:
204 # Only a name is given. Search in the default directory
205 script_path = src.find_file_in_lpath(script_name,
206 config.PATHS.PRODUCTPATH,
208 prod_info.compil_script = script_path
210 # Check script existence
211 if not os.path.exists(prod_info.compil_script):
212 raise src.SatException(_("Compilation script not found: %s") %
213 prod_info.compil_script)
215 # Check that the script is executable
216 if not os.access(prod_info.compil_script, os.X_OK):
217 raise src.SatException(
218 _("Compilation script cannot be executed: %s") %
219 prod_info.compil_script)
221 # Get the full paths of all the patches
222 if "patches" in prod_info:
224 for patch in prod_info.patches:
226 # If only a filename, then search for the patch in the PRODUCTPATH
227 if os.path.basename(patch_path) == patch_path:
228 # Search in the PRODUCTPATH/patches
229 patch_path = src.find_file_in_lpath(patch,
230 config.PATHS.PRODUCTPATH,
233 msg = _("Patch %(patch_name)s for %(prod_name)s not found:"
234 "\n" % {"patch_name" : patch,
235 "prod_name" : prod_info.name})
236 raise src.SatException(msg)
237 patches.append(patch_path)
238 prod_info.patches = patches
240 # Get the full paths of the environment scripts
241 if "environ" in prod_info and "env_script" in prod_info.environ:
242 env_script_path = prod_info.environ.env_script
243 # If only a filename, then search for the environment script
244 # in the PRODUCTPATH/env_scripts
245 if os.path.basename(env_script_path) == env_script_path:
246 # Search in the PRODUCTPATH/env_scripts
247 env_script_path = src.find_file_in_lpath(
248 prod_info.environ.env_script,
249 config.PATHS.PRODUCTPATH,
251 if not env_script_path:
252 msg = _("Environment script %(env_name)s for %(prod_name)s not "
253 "found.\n" % {"env_name" : env_script_path,
254 "prod_name" : prod_info.name})
255 raise src.SatException(msg)
257 prod_info.environ.env_script = env_script_path
261 def get_products_infos(lproducts, config):
262 '''Get the specific configuration of a list of products
264 :param lproducts List: The list of product names
265 :param config Config: The global configuration
266 :return: the list of tuples
267 (product name, specific configuration of the product)
268 :rtype: [(str, Config)]
271 # Loop on product names
272 for prod in lproducts:
273 # Get the specific configuration of the product
274 prod_info = get_product_config(config, prod)
275 if prod_info is not None:
276 products_infos.append((prod, prod_info))
278 msg = _("The %s product has no definition "
279 "in the configuration.") % prod
280 raise src.SatException(msg)
281 return products_infos
283 def get_product_dependencies(config, product_info):
284 '''Get recursively the list of products that are
285 in the product_info dependencies
287 :param config Config: The global configuration
288 :param product_info Config: The configuration specific to
290 :return: the list of products in dependence
293 if "depend" not in product_info or product_info.depend == []:
296 for prod in product_info.depend:
299 prod_info = get_product_config(config, prod)
300 dep_prod = get_product_dependencies(config, prod_info)
301 for prod_in_dep in dep_prod:
302 if prod_in_dep not in res:
303 res.append(prod_in_dep)
306 def check_installation(product_info):
307 '''Verify if a product is well installed. Checks install directory presence
308 and some additional files if it is defined in the config
310 :param product_info Config: The configuration specific to
312 :return: True if it is well installed
315 install_dir = product_info.install_dir
316 if not os.path.exists(install_dir):
318 if ("present_files" in product_info and
319 "install" in product_info.present_files):
320 for file_relative_path in product_info.present_files.install:
321 file_path = os.path.join(install_dir, file_relative_path)
322 if not os.path.exists(file_path):
326 def product_is_sample(product_info):
327 '''Know if a product has the sample type
329 :param product_info Config: The configuration specific to
331 :return: True if the product has the sample type, else False
334 if 'type' in product_info:
335 ptype = product_info.type
336 return ptype.lower() == 'sample'
340 def product_is_salome(product_info):
341 '''Know if a product is of type salome
343 :param product_info Config: The configuration specific to
345 :return: True if the product is salome, else False
348 if 'type' in product_info:
349 ptype = product_info.type
350 return ptype.lower() == 'salome'
354 def product_is_fixed(product_info):
355 '''Know if a product is fixed
357 :param product_info Config: The configuration specific to
359 :return: True if the product is fixed, else False
362 get_src = product_info.get_source
363 return get_src.lower() == 'fixed'
365 def product_is_native(product_info):
366 '''Know if a product is native
368 :param product_info Config: The configuration specific to
370 :return: True if the product is native, else False
373 get_src = product_info.get_source
374 return get_src.lower() == 'native'
376 def product_is_dev(product_info):
377 '''Know if a product is in dev mode
379 :param product_info Config: The configuration specific to
381 :return: True if the product is in dev mode, else False
384 dev = product_info.dev
385 return dev.lower() == 'yes'
387 def product_is_debug(product_info):
388 '''Know if a product is in debug mode
390 :param product_info Config: The configuration specific to
392 :return: True if the product is in debug mode, else False
395 debug = product_info.debug
396 return debug.lower() == 'yes'
398 def product_is_autotools(product_info):
399 '''Know if a product is compiled using the autotools
401 :param product_info Config: The configuration specific to
403 :return: True if the product is autotools, else False
406 build_src = product_info.build_source
407 return build_src.lower() == 'autotools'
409 def product_is_cmake(product_info):
410 '''Know if a product is compiled using the cmake
412 :param product_info Config: The configuration specific to
414 :return: True if the product is cmake, else False
417 build_src = product_info.build_source
418 return build_src.lower() == 'cmake'
420 def product_has_script(product_info):
421 '''Know if a product has a compilation script
423 :param product_info Config: The configuration specific to
425 :return: True if the product it has a compilation script, else False
428 if "build_source" not in product_info:
431 build_src = product_info.build_source
432 return build_src.lower() == 'script'