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 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 prod_info.section = "version_" + vv
82 # Get the standard informations
83 elif "default" in config.PRODUCTS[product_name]:
84 # returns the generic information (given version not found)
85 prod_info = config.PRODUCTS[product_name].default
86 prod_info.section = "default"
88 # merge opt_depend in depend
89 if prod_info is not None and 'opt_depend' in prod_info:
90 for depend in prod_info.opt_depend:
91 if depend in config.PRODUCTS:
92 prod_info.depend.append(depend,'')
94 # In case of a product get with a vcs,
95 # put the tag (equal to the version)
96 if prod_info is not None and prod_info.get_source in AVAILABLE_VCS:
98 if prod_info.get_source == 'git':
99 prod_info.git_info.tag = version
101 if prod_info.get_source == 'svn':
102 prod_info.svn_info.tag = version
104 if prod_info.get_source == 'cvs':
105 prod_info.cvs_info.tag = version
107 # In case of a fixed product,
108 # define the install_dir (equal to the version)
109 if prod_info is not None and prod_info.get_source=="fixed":
110 prod_info.install_dir = version
112 # Check if the product is defined as native in the application
113 if prod_info is not None:
114 if version == "native":
115 prod_info.get_source = "native"
116 elif prod_info.get_source == "native":
117 msg = _("The product %(prod)s has version %(ver)s but is "
118 "declared as native in its definition" %
119 { 'prod': prod_info.name, 'ver': version})
120 raise src.SatException(msg)
122 # If there is no definition but the product is declared as native,
123 # construct a new definition containing only the get_source key
124 if prod_info is None and version == "native":
125 prod_info = src.pyconf.Config()
126 prod_info.name = product_name
127 prod_info.get_source = "native"
129 # If prod_info is still None, it means that there is no product definition
130 # in the config. The user has to provide it.
131 if prod_info is None:
132 msg = _("No definition found for the product %s\n"
133 "Please create a %s.pyconf file." % (product_name, product_name))
134 raise src.SatException(msg)
136 # Set the debug, dev and version keys
137 prod_info.debug = debug
139 prod_info.version = version
141 # Set the archive_info if the product is get in archive mode
142 if prod_info.get_source == "archive":
143 if not "archive_info" in prod_info:
144 prod_info.addMapping("archive_info",
145 src.pyconf.Mapping(prod_info),
147 if "archive_name" not in prod_info.archive_info:
148 arch_name = product_name + "-" + version + ".tar.gz"
149 arch_path = src.find_file_in_lpath(arch_name,
150 config.PATHS.ARCHIVEPATH)
152 msg = _("Archive %(arch_name)s for %(prod_name)s not found:"
153 "\n" % {"arch_name" : arch_name,
154 "prod_name" : prod_info.name})
155 raise src.SatException(msg)
156 prod_info.archive_info.archive_name = arch_path
158 if (os.path.basename(prod_info.archive_info.archive_name) ==
159 prod_info.archive_info.archive_name):
160 arch_name = prod_info.archive_info.archive_name
161 arch_path = src.find_file_in_lpath(
163 config.PATHS.ARCHIVEPATH)
165 msg = _("Archive %(arch_name)s for %(prod_name)s not found:"
166 "\n" % {"arch_name" : arch_name,
167 "prod_name" : prod_info.name})
168 raise src.SatException(msg)
169 prod_info.archive_info.archive_name = arch_path
171 # Set the install_dir key
172 if "no_base" in config.APPLICATION and config.APPLICATION.no_base == "yes":
173 # Set it to the default value (in application directory)
174 prod_info.install_dir = os.path.join(config.APPLICATION.workdir,
179 prod_info.install_dir = "base"
180 if "install_dir" not in prod_info:
181 # Set it to the default value (in application directory)
182 prod_info.install_dir = os.path.join(config.APPLICATION.workdir,
186 if prod_info.install_dir == "base":
187 # Get the product base of the application
188 base_path = src.get_base_path(config)
189 prod_info.install_dir = os.path.join(base_path,
190 prod_info.name + "-" + version)
192 # If the product compiles with a script, check the script existence
193 # and if it is executable
194 if product_has_script(prod_info):
195 # Check the compil_script key existence
196 if "compil_script" not in prod_info:
197 msg = _("No compilation script found for the product %s\n"
198 "Please provide a \"compil_script\" key in its definition."
200 raise src.SatException(msg)
202 # Get the path of the script
203 script = prod_info.compil_script
204 script_name = os.path.basename(script)
205 if script == script_name:
206 # Only a name is given. Search in the default directory
207 script_path = src.find_file_in_lpath(script_name,
208 config.PATHS.PRODUCTPATH,
211 raise src.SatException(_("Compilation script not found: %s") %
213 prod_info.compil_script = script_path
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 product_has_patches(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 product_has_env_script(prod_info):
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'
434 def product_has_env_script(product_info):
435 '''Know if a product has an environment script
437 :param product_info Config: The configuration specific to
439 :return: True if the product it has an environment script, else False
442 return "environ" in product_info and "env_script" in product_info.environ
444 def product_has_patches(product_info):
445 '''Know if a product has one or more patches
447 :param product_info Config: The configuration specific to
449 :return: True if the product has one or more patches
452 return "patches" in product_info and len(product_info.patches) > 0