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
48 if isinstance(version, src.pyconf.Mapping):
51 if not 'tag' in dic_version:
52 version = config.APPLICATION.tag
54 version = dic_version.tag
56 # Get the debug if any
57 if 'debug' in dic_version:
58 debug = dic_version.debug
61 if 'dev' in dic_version:
65 # substitute some character with _ in order to get the correct definition
66 # in config.PRODUCTS. This is done because the pyconf tool does not handle
67 # the . and - characters
68 for c in ".-": vv = vv.replace(c, "_")
71 if product_name in config.PRODUCTS:
72 # If it exists, get the information of the product_version
73 if "version_" + vv in config.PRODUCTS[product_name]:
74 # returns specific information for the given version
75 prod_info = config.PRODUCTS[product_name]["version_" + vv]
76 # Get the standard informations
77 elif "default" in config.PRODUCTS[product_name]:
78 # returns the generic information (given version not found)
79 prod_info = config.PRODUCTS[product_name].default
81 # merge opt_depend in depend
82 if prod_info is not None and 'opt_depend' in prod_info:
83 for depend in prod_info.opt_depend:
84 if depend in config.PRODUCTS:
85 prod_info.depend.append(depend,'')
87 # In case of a product get with a vcs,
88 # put the tag (equal to the version)
89 if prod_info is not None and prod_info.get_source in AVAILABLE_VCS:
91 if prod_info.get_source == 'git':
92 prod_info.git_info.tag = version
94 if prod_info.get_source == 'svn':
95 prod_info.svn_info.tag = version
97 if prod_info.get_source == 'cvs':
98 prod_info.cvs_info.tag = version
100 # In case of a fixed product,
101 # define the install_dir (equal to the version)
102 if prod_info is not None and prod_info.get_source=="fixed":
103 prod_info.install_dir = version
105 # Check if the product is defined as native in the application
106 if prod_info is not None:
107 if version == "native":
108 prod_info.get_source = "native"
109 elif prod_info.get_source == "native":
110 msg = _("The product %(prod)s has version %(ver)s but is "
111 "declared as native in its definition" %
112 { 'prod': prod_info.name, 'ver': version})
113 raise src.SatException(msg)
115 # If there is no definition but the product is declared as native,
116 # construct a new definition containing only the get_source key
117 if prod_info is None and version == "native":
118 prod_info = src.pyconf.Config()
119 prod_info.name = product_name
120 prod_info.get_source = "native"
122 # If prod_info is still None, it means that there is no product definition
123 # in the config. The user has to provide it.
124 if prod_info is None:
125 msg = _("No definition found for the product %s\n"
126 "Please create a %s.pyconf file." % (product_name, product_name))
127 raise src.SatException(msg)
129 # Set the debug, dev and version keys
130 prod_info.debug = debug
132 prod_info.version = version
134 # Set the archive_info if the product is get in archive mode
135 if prod_info.get_source == "archive":
136 if not "archive_info" in prod_info:
137 prod_info.addMapping("archive_info",
138 src.pyconf.Mapping(prod_info),
140 if "archive_name" not in prod_info.archive_info:
141 arch_name = product_name + "-" + version + ".tar.gz"
142 arch_path = src.find_file_in_lpath(arch_name,
143 config.PATHS.ARCHIVEPATH)
145 msg = _("Archive %(arch_name)s for %(prod_name)s not found:"
146 "\n" % {"arch_name" : arch_name,
147 "prod_name" : prod_info.name})
148 raise src.SatException(msg)
149 prod_info.archive_info.archive_name = arch_path
151 if (os.path.basename(prod_info.archive_info.archive_name) ==
152 prod_info.archive_info.archive_name):
154 arch_path = src.find_file_in_lpath(
155 prod_info.archive_info.archive_name,
156 config.PATHS.ARCHIVEPATH)
158 msg = _("Archive %(arch_name)s for %(prod_name)s not found:"
159 "\n" % {"arch_name" : arch_name,
160 "prod_name" : prod_info.name})
161 raise src.SatException(msg)
162 prod_info.archive_info.archive_name = arch_path
164 # Set the install_dir key
165 if "install_dir" not in prod_info:
166 # Set it to the default value (in application directory)
167 prod_info.install_dir = os.path.join(config.APPLICATION.workdir,
171 if prod_info.install_dir == "base":
172 # Get the product base of the application
173 base_path = src.get_base_path(config)
174 prod_info.install_dir = os.path.join(base_path,
175 prod_info.name + "-" + version)
177 # If the product compiles with a script, check the script existence
178 # and if it is executable
179 if product_has_script(prod_info):
180 # Check the compil_script key existence
181 if "compil_script" not in prod_info:
182 msg = _("No compilation script found for the product %s\n"
183 "Please provide a \"compil_script\" key in its definition."
185 raise src.SatException(msg)
187 # Get the path of the script
188 script = prod_info.compil_script
189 script_name = os.path.basename(script)
190 if script == script_name:
191 # Only a name is given. Search in the default directory
192 script_path = src.find_file_in_lpath(script_name,
193 config.PATHS.PRODUCTPATH,
195 prod_info.compil_script = script_path
197 # Check script existence
198 if not os.path.exists(prod_info.compil_script):
199 raise src.SatException(_("Compilation script not found: %s") %
200 prod_info.compil_script)
202 # Check that the script is executable
203 if not os.access(prod_info.compil_script, os.X_OK):
204 raise src.SatException(
205 _("Compilation script cannot be executed: %s") %
206 prod_info.compil_script)
208 # Get the full paths of all the patches
209 if "patches" in prod_info:
211 for patch in prod_info.patches:
213 # If only a filename, then search for the patch in the PRODUCTPATH
214 if os.path.basename(patch_path) == patch_path:
215 # Search in the PRODUCTPATH/patches
216 patch_path = src.find_file_in_lpath(patch,
217 config.PATHS.PRODUCTPATH,
220 msg = _("Patch %(patch_name)s for %(prod_name)s not found:"
221 "\n" % {"patch_name" : patch,
222 "prod_name" : prod_info.name})
223 raise src.SatException(msg)
224 patches.append(patch_path)
225 prod_info.patches = patches
227 # Get the full paths of the environment scripts
228 if "environ" in prod_info and "env_script" in prod_info.environ:
229 env_script_path = prod_info.environ.env_script
230 # If only a filename, then search for the environment script
231 # in the PRODUCTPATH/env_scripts
232 if os.path.basename(env_script_path) == env_script_path:
233 # Search in the PRODUCTPATH/env_scripts
234 env_script_path = src.find_file_in_lpath(
235 prod_info.environ.env_script,
236 config.PATHS.PRODUCTPATH,
238 if not env_script_path:
239 msg = _("Environment script %(env_name)s for %(prod_name)s not "
240 "found.\n" % {"env_name" : env_script_path,
241 "prod_name" : prod_info.name})
242 raise src.SatException(msg)
244 prod_info.environ.env_script = env_script_path
248 def get_products_infos(lproducts, config):
249 '''Get the specific configuration of a list of products
251 :param lproducts List: The list of product names
252 :param config Config: The global configuration
253 :return: the list of tuples
254 (product name, specific configuration of the product)
255 :rtype: [(str, Config)]
258 # Loop on product names
259 for prod in lproducts:
260 # Get the specific configuration of the product
261 prod_info = get_product_config(config, prod)
262 if prod_info is not None:
263 products_infos.append((prod, prod_info))
265 msg = _("The %s product has no definition "
266 "in the configuration.") % prod
267 raise src.SatException(msg)
268 return products_infos
270 def get_product_dependencies(config, product_info):
271 '''Get recursively the list of products that are
272 in the product_info dependencies
274 :param config Config: The global configuration
275 :param product_info Config: The configuration specific to
277 :return: the list of products in dependence
280 if "depend" not in product_info or product_info.depend == []:
283 for prod in product_info.depend:
286 prod_info = get_product_config(config, prod)
287 dep_prod = get_product_dependencies(config, prod_info)
288 for prod_in_dep in dep_prod:
289 if prod_in_dep not in res:
290 res.append(prod_in_dep)
293 def check_installation(product_info):
294 '''Verify if a product is well installed. Checks install directory presence
295 and some additional files if it is defined in the config
297 :param product_info Config: The configuration specific to
299 :return: True if it is well installed
302 install_dir = product_info.install_dir
303 if not os.path.exists(install_dir):
305 if ("present_files" in product_info and
306 "install" in product_info.present_files):
307 for file_relative_path in product_info.present_files.install:
308 file_path = os.path.join(install_dir, file_relative_path)
309 if not os.path.exists(file_path):
313 def product_is_sample(product_info):
314 '''Know if a product has the sample type
316 :param product_info Config: The configuration specific to
318 :return: True if the product has the sample type, else False
321 if 'type' in product_info:
322 ptype = product_info.type
323 return ptype.lower() == 'sample'
327 def product_is_salome(product_info):
328 '''Know if a product is of type salome
330 :param product_info Config: The configuration specific to
332 :return: True if the product is salome, else False
335 if 'type' in product_info:
336 ptype = product_info.type
337 return ptype.lower() == 'salome'
341 def product_is_fixed(product_info):
342 '''Know if a product is fixed
344 :param product_info Config: The configuration specific to
346 :return: True if the product is fixed, else False
349 get_src = product_info.get_source
350 return get_src.lower() == 'fixed'
352 def product_is_native(product_info):
353 '''Know if a product is native
355 :param product_info Config: The configuration specific to
357 :return: True if the product is native, else False
360 get_src = product_info.get_source
361 return get_src.lower() == 'native'
363 def product_is_dev(product_info):
364 '''Know if a product is in dev mode
366 :param product_info Config: The configuration specific to
368 :return: True if the product is in dev mode, else False
371 dev = product_info.dev
372 return dev.lower() == 'yes'
374 def product_is_debug(product_info):
375 '''Know if a product is in debug mode
377 :param product_info Config: The configuration specific to
379 :return: True if the product is in debug mode, else False
382 debug = product_info.debug
383 return debug.lower() == 'yes'
385 def product_is_autotools(product_info):
386 '''Know if a product is compiled using the autotools
388 :param product_info Config: The configuration specific to
390 :return: True if the product is autotools, else False
393 build_src = product_info.build_source
394 return build_src.lower() == 'autotools'
396 def product_is_cmake(product_info):
397 '''Know if a product is compiled using the cmake
399 :param product_info Config: The configuration specific to
401 :return: True if the product is cmake, else False
404 build_src = product_info.build_source
405 return build_src.lower() == 'cmake'
407 def product_has_script(product_info):
408 '''Know if a product has a compilation script
410 :param product_info Config: The configuration specific to
412 :return: True if the product it has a compilation script, else False
415 if "build_source" not in product_info:
418 build_src = product_info.build_source
419 return build_src.lower() == 'script'