Salome HOME
src.xmlManager escapeSequence
[tools/sat.git] / commands / clean.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2012  CEA/DEN
4 #
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.
9 #
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.
14 #
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
19 import re
20
21 import src
22
23 # Compatibility python 2/3 for input function
24 # input stays input for python 3 and input = raw_input for python 2
25 try: 
26     input = raw_input
27 except NameError: 
28     pass
29
30 PROPERTY_EXPRESSION = "^.+:.+$"
31
32 # Define all possible option for the clean command :  sat clean <options>
33 parser = src.options.Options()
34 parser.add_option('p', 'products', 'list2', 'products',
35     _('Optional: Products to clean. This option can be'
36     ' passed several time to clean several products.'))
37 parser.add_option('', 'properties', 'string', 'properties',
38     _('Optional: Filter the products by their properties.\n\tSyntax: '
39       '--properties <property>:<value>'))
40 parser.add_option('s', 'sources', 'boolean', 'sources', 
41     _("Optional: Clean the product source directories."))
42 parser.add_option('b', 'build', 'boolean', 'build', 
43     _("Optional: Clean the product build directories."))
44 parser.add_option('i', 'install', 'boolean', 'install', 
45     _("Optional: Clean the product install directories."))
46 parser.add_option('a', 'all', 'boolean', 'all', 
47     _("Optional: Clean the product source, build and install directories."))
48 parser.add_option('', 'sources_without_dev', 'boolean', 'sources_without_dev', 
49     _("Optional: do not clean the products in development mode."))
50
51 def get_products_list(options, cfg, logger):
52     """\
53     method that gives the product list with their informations from 
54     configuration regarding the passed options.
55     
56     :param options Options: The Options instance that stores the commands 
57                             arguments
58     :param config Config: The global configuration
59     :param logger Logger: The logger instance to use for the display and logging
60     :return: The list of (product name, product_informations).
61     :rtype: List
62     """
63     # Get the products to be prepared, regarding the options
64     if options.products is None:
65         # No options, get all products sources
66         products = cfg.APPLICATION.products
67     else:
68         # if option --products, check that all products of the command line
69         # are present in the application.
70         products = options.products
71         for p in products:
72             if p not in cfg.APPLICATION.products:
73                 raise src.SatException(_("Product %(product)s "
74                             "not defined in application %(application)s") %
75                         { 'product': p, 'application': cfg.VARS.application} )
76     
77     # Construct the list of tuple containing 
78     # the products name and their definition
79     products_infos = src.product.get_products_infos(products, cfg)
80     
81     # if the property option was passed, filter the list
82     if options.properties:
83         [prop, value] = options.properties.split(":")
84         products_infos = [(p_name, p_info) for 
85                           (p_name, p_info) in products_infos 
86                           if "properties" in p_info and 
87                           prop in p_info.properties and 
88                           p_info.properties[prop] == value]
89         
90     return products_infos
91
92 def get_source_directories(products_infos, without_dev):
93     """\
94     Returns the list of directory source paths corresponding 
95     to the list of product information given as input.
96     If without_dev (bool) the dev products are ignored.
97     
98     :param products_infos list: The list of (name, config) corresponding to one
99                                 product.
100     :param without_dev boolean: If True, then ignore the dev products.
101     :return: the list of source paths.
102     :rtype: list
103     """
104     l_dir_source = []
105     for __, product_info in products_infos:
106         if product_has_dir(product_info, without_dev):
107             l_dir_source.append(src.Path(product_info.source_dir))
108     return l_dir_source
109
110 def get_build_directories(products_infos):
111     """\
112     Returns the list of directory build paths corresponding to the list of 
113     product information given as input.
114     
115     :param products_infos list: The list of (name, config) corresponding to one
116                                 product.
117     :return: the list of build paths.
118     :rtype: list
119     """
120     l_dir_build = []
121     for __, product_info in products_infos:
122         if product_has_dir(product_info):
123             if "build_dir" in product_info:
124                 l_dir_build.append(src.Path(product_info.build_dir))
125     return l_dir_build
126
127 def get_install_directories(products_infos):
128     """\
129     Returns the list of directory install paths corresponding to the list of 
130     product information given as input.
131     
132     :param products_infos list: The list of (name, config) corresponding to one product.
133     :return: the list of install paths.
134     :rtype: list
135     """
136     l_dir_install = []
137     for __, product_info in products_infos:
138         if product_has_dir(product_info):
139             l_dir_install.append(src.Path(product_info.install_dir))
140     return l_dir_install
141
142 def product_has_dir(product_info, without_dev=False):
143     """\
144     Returns a boolean at True if there is a source, build and install
145     directory corresponding to the product described by product_info.
146     
147     :param products_info Config: The config corresponding to the product.
148     :return: True if there is a source, build and install directory corresponding to the product described by product_info.
149     :rtype: boolean
150     """
151     if (src.product.product_is_native(product_info) or 
152                             src.product.product_is_fixed(product_info)):
153         return False
154     if without_dev:
155         if src.product.product_is_dev(product_info):
156             return False
157     return True
158     
159 def suppress_directories(l_paths, logger):
160     """Suppress the paths given in the list in l_paths.
161     
162     :param l_paths list: The list of Path to be suppressed
163     :param logger Logger: The logger instance to use for the display and logging
164     """    
165     for path in l_paths:
166         if not path.isdir():
167             msg = _("Warning: the path %s does not "
168                     "exists (or is not a directory)\n" % path.__str__())
169             logger.write(src.printcolors.printcWarning(msg), 1)
170         else:
171             logger.write(_("Removing %s ...") % path.__str__())
172             path.rm()
173             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 3)
174
175 def description():
176     """method called when salomeTools is called with --help option.
177     
178     :return: The text to display for the clean command description.
179     :rtype: str
180     """
181     return _("""\
182 The clean command suppress the SOURCES, BUILD or INSTALL directories of the application products.
183 Use the options to define what directories you want to suppress and to set the list of products
184
185 example:
186 >> sat clean SALOME-xx --build --install --properties is_salome_module:yes
187 """)
188   
189 def run(args, runner, logger):
190     """\
191     method called when salomeTools is called with clean parameter.
192     """
193     
194     # Parse the options
195     (options, args) = parser.parse_args(args)
196
197     # check that the command has been called with an application
198     src.check_config_has_application( runner.cfg )
199
200     # Verify the --properties option
201     if options.properties:
202         oExpr = re.compile(PROPERTY_EXPRESSION)
203         if not oExpr.search(options.properties):
204             msg = _('WARNING: the "--properties" options must have the '
205                     'following syntax:\n--properties <property>:<value>')
206             logger.write(src.printcolors.printcWarning(msg), 1)
207             logger.write("\n", 1)
208             options.properties = None
209             
210
211     # Get the list of products to threat
212     products_infos = get_products_list(options, runner.cfg, logger)
213
214     # Construct the list of directories to suppress
215     l_dir_to_suppress = []
216     if options.all:
217         l_dir_to_suppress += (get_source_directories(products_infos, 
218                                             options.sources_without_dev) +
219                              get_build_directories(products_infos) + 
220                              get_install_directories(products_infos))
221     else:
222         if options.install:
223             l_dir_to_suppress += get_install_directories(products_infos)
224         
225         if options.build:
226             l_dir_to_suppress += get_build_directories(products_infos)
227             
228         if options.sources or options.sources_without_dev:
229             l_dir_to_suppress += get_source_directories(products_infos, 
230                                                 options.sources_without_dev)
231     
232     if len(l_dir_to_suppress) == 0:
233         logger.write(src.printcolors.printcWarning(_("Nothing to suppress\n")))
234         logger.write(_("""\
235 Please specify what you want to suppress:
236 try 'sat --help clean' and 'sat clean ... --products ... --sources --build --install
237 """))
238         return
239     
240     # Check with the user if he really wants to suppress the directories
241     if not runner.options.batch:
242         logger.write(_("Remove the following directories ?\n"), 1)
243         for directory in l_dir_to_suppress:
244             logger.write("  %s\n" % directory, 1)
245         rep = input(_("Are you sure you want to continue? [Yes/No] "))
246         if rep.upper() != _("YES"):
247             return 0
248     
249     # Suppress the list of paths
250     suppress_directories(l_dir_to_suppress, logger)
251     
252     return 0