##// END OF EJS Templates
Move “Using existing profile dir” from info to debug:...
Matthias Bussonnier -
Show More
@@ -1,380 +1,380 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for IPython.
3 An application for IPython.
4
4
5 All top-level applications should use the classes in this module for
5 All top-level applications should use the classes in this module for
6 handling configuration and creating configurables.
6 handling configuration and creating configurables.
7
7
8 The job of an :class:`Application` is to create the master configuration
8 The job of an :class:`Application` is to create the master configuration
9 object and then create the configurable objects, passing the config to them.
9 object and then create the configurable objects, passing the config to them.
10 """
10 """
11
11
12 # Copyright (c) IPython Development Team.
12 # Copyright (c) IPython Development Team.
13 # Distributed under the terms of the Modified BSD License.
13 # Distributed under the terms of the Modified BSD License.
14
14
15 import atexit
15 import atexit
16 import glob
16 import glob
17 import logging
17 import logging
18 import os
18 import os
19 import shutil
19 import shutil
20 import sys
20 import sys
21
21
22 from IPython.config.application import Application, catch_config_error
22 from IPython.config.application import Application, catch_config_error
23 from IPython.config.loader import ConfigFileNotFound
23 from IPython.config.loader import ConfigFileNotFound
24 from IPython.core import release, crashhandler
24 from IPython.core import release, crashhandler
25 from IPython.core.profiledir import ProfileDir, ProfileDirError
25 from IPython.core.profiledir import ProfileDir, ProfileDirError
26 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir, ensure_dir_exists
26 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir, ensure_dir_exists
27 from IPython.utils import py3compat
27 from IPython.utils import py3compat
28 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, Set, Instance
28 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, Set, Instance
29
29
30 if os.name == 'nt':
30 if os.name == 'nt':
31 programdata = os.environ.get('PROGRAMDATA', None)
31 programdata = os.environ.get('PROGRAMDATA', None)
32 if programdata:
32 if programdata:
33 SYSTEM_CONFIG_DIRS = [os.path.join(programdata, 'ipython')]
33 SYSTEM_CONFIG_DIRS = [os.path.join(programdata, 'ipython')]
34 else: # PROGRAMDATA is not defined by default on XP.
34 else: # PROGRAMDATA is not defined by default on XP.
35 SYSTEM_CONFIG_DIRS = []
35 SYSTEM_CONFIG_DIRS = []
36 else:
36 else:
37 SYSTEM_CONFIG_DIRS = [
37 SYSTEM_CONFIG_DIRS = [
38 "/usr/local/etc/ipython",
38 "/usr/local/etc/ipython",
39 "/etc/ipython",
39 "/etc/ipython",
40 ]
40 ]
41
41
42
42
43 # aliases and flags
43 # aliases and flags
44
44
45 base_aliases = {
45 base_aliases = {
46 'profile-dir' : 'ProfileDir.location',
46 'profile-dir' : 'ProfileDir.location',
47 'profile' : 'BaseIPythonApplication.profile',
47 'profile' : 'BaseIPythonApplication.profile',
48 'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
48 'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
49 'log-level' : 'Application.log_level',
49 'log-level' : 'Application.log_level',
50 'config' : 'BaseIPythonApplication.extra_config_file',
50 'config' : 'BaseIPythonApplication.extra_config_file',
51 }
51 }
52
52
53 base_flags = dict(
53 base_flags = dict(
54 debug = ({'Application' : {'log_level' : logging.DEBUG}},
54 debug = ({'Application' : {'log_level' : logging.DEBUG}},
55 "set log level to logging.DEBUG (maximize logging output)"),
55 "set log level to logging.DEBUG (maximize logging output)"),
56 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
56 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
57 "set log level to logging.CRITICAL (minimize logging output)"),
57 "set log level to logging.CRITICAL (minimize logging output)"),
58 init = ({'BaseIPythonApplication' : {
58 init = ({'BaseIPythonApplication' : {
59 'copy_config_files' : True,
59 'copy_config_files' : True,
60 'auto_create' : True}
60 'auto_create' : True}
61 }, """Initialize profile with default config files. This is equivalent
61 }, """Initialize profile with default config files. This is equivalent
62 to running `ipython profile create <profile>` prior to startup.
62 to running `ipython profile create <profile>` prior to startup.
63 """)
63 """)
64 )
64 )
65
65
66
66
67 class BaseIPythonApplication(Application):
67 class BaseIPythonApplication(Application):
68
68
69 name = Unicode(u'ipython')
69 name = Unicode(u'ipython')
70 description = Unicode(u'IPython: an enhanced interactive Python shell.')
70 description = Unicode(u'IPython: an enhanced interactive Python shell.')
71 version = Unicode(release.version)
71 version = Unicode(release.version)
72
72
73 aliases = Dict(base_aliases)
73 aliases = Dict(base_aliases)
74 flags = Dict(base_flags)
74 flags = Dict(base_flags)
75 classes = List([ProfileDir])
75 classes = List([ProfileDir])
76
76
77 # Track whether the config_file has changed,
77 # Track whether the config_file has changed,
78 # because some logic happens only if we aren't using the default.
78 # because some logic happens only if we aren't using the default.
79 config_file_specified = Set()
79 config_file_specified = Set()
80
80
81 config_file_name = Unicode()
81 config_file_name = Unicode()
82 def _config_file_name_default(self):
82 def _config_file_name_default(self):
83 return self.name.replace('-','_') + u'_config.py'
83 return self.name.replace('-','_') + u'_config.py'
84 def _config_file_name_changed(self, name, old, new):
84 def _config_file_name_changed(self, name, old, new):
85 if new != old:
85 if new != old:
86 self.config_file_specified.add(new)
86 self.config_file_specified.add(new)
87
87
88 # The directory that contains IPython's builtin profiles.
88 # The directory that contains IPython's builtin profiles.
89 builtin_profile_dir = Unicode(
89 builtin_profile_dir = Unicode(
90 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
90 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
91 )
91 )
92
92
93 config_file_paths = List(Unicode)
93 config_file_paths = List(Unicode)
94 def _config_file_paths_default(self):
94 def _config_file_paths_default(self):
95 return [py3compat.getcwd()]
95 return [py3compat.getcwd()]
96
96
97 extra_config_file = Unicode(config=True,
97 extra_config_file = Unicode(config=True,
98 help="""Path to an extra config file to load.
98 help="""Path to an extra config file to load.
99
99
100 If specified, load this config file in addition to any other IPython config.
100 If specified, load this config file in addition to any other IPython config.
101 """)
101 """)
102 def _extra_config_file_changed(self, name, old, new):
102 def _extra_config_file_changed(self, name, old, new):
103 try:
103 try:
104 self.config_files.remove(old)
104 self.config_files.remove(old)
105 except ValueError:
105 except ValueError:
106 pass
106 pass
107 self.config_file_specified.add(new)
107 self.config_file_specified.add(new)
108 self.config_files.append(new)
108 self.config_files.append(new)
109
109
110 profile = Unicode(u'default', config=True,
110 profile = Unicode(u'default', config=True,
111 help="""The IPython profile to use."""
111 help="""The IPython profile to use."""
112 )
112 )
113
113
114 def _profile_changed(self, name, old, new):
114 def _profile_changed(self, name, old, new):
115 self.builtin_profile_dir = os.path.join(
115 self.builtin_profile_dir = os.path.join(
116 get_ipython_package_dir(), u'config', u'profile', new
116 get_ipython_package_dir(), u'config', u'profile', new
117 )
117 )
118
118
119 ipython_dir = Unicode(config=True,
119 ipython_dir = Unicode(config=True,
120 help="""
120 help="""
121 The name of the IPython directory. This directory is used for logging
121 The name of the IPython directory. This directory is used for logging
122 configuration (through profiles), history storage, etc. The default
122 configuration (through profiles), history storage, etc. The default
123 is usually $HOME/.ipython. This option can also be specified through
123 is usually $HOME/.ipython. This option can also be specified through
124 the environment variable IPYTHONDIR.
124 the environment variable IPYTHONDIR.
125 """
125 """
126 )
126 )
127 def _ipython_dir_default(self):
127 def _ipython_dir_default(self):
128 d = get_ipython_dir()
128 d = get_ipython_dir()
129 self._ipython_dir_changed('ipython_dir', d, d)
129 self._ipython_dir_changed('ipython_dir', d, d)
130 return d
130 return d
131
131
132 _in_init_profile_dir = False
132 _in_init_profile_dir = False
133 profile_dir = Instance(ProfileDir)
133 profile_dir = Instance(ProfileDir)
134 def _profile_dir_default(self):
134 def _profile_dir_default(self):
135 # avoid recursion
135 # avoid recursion
136 if self._in_init_profile_dir:
136 if self._in_init_profile_dir:
137 return
137 return
138 # profile_dir requested early, force initialization
138 # profile_dir requested early, force initialization
139 self.init_profile_dir()
139 self.init_profile_dir()
140 return self.profile_dir
140 return self.profile_dir
141
141
142 overwrite = Bool(False, config=True,
142 overwrite = Bool(False, config=True,
143 help="""Whether to overwrite existing config files when copying""")
143 help="""Whether to overwrite existing config files when copying""")
144 auto_create = Bool(False, config=True,
144 auto_create = Bool(False, config=True,
145 help="""Whether to create profile dir if it doesn't exist""")
145 help="""Whether to create profile dir if it doesn't exist""")
146
146
147 config_files = List(Unicode)
147 config_files = List(Unicode)
148 def _config_files_default(self):
148 def _config_files_default(self):
149 return [self.config_file_name]
149 return [self.config_file_name]
150
150
151 copy_config_files = Bool(False, config=True,
151 copy_config_files = Bool(False, config=True,
152 help="""Whether to install the default config files into the profile dir.
152 help="""Whether to install the default config files into the profile dir.
153 If a new profile is being created, and IPython contains config files for that
153 If a new profile is being created, and IPython contains config files for that
154 profile, then they will be staged into the new directory. Otherwise,
154 profile, then they will be staged into the new directory. Otherwise,
155 default config files will be automatically generated.
155 default config files will be automatically generated.
156 """)
156 """)
157
157
158 verbose_crash = Bool(False, config=True,
158 verbose_crash = Bool(False, config=True,
159 help="""Create a massive crash report when IPython encounters what may be an
159 help="""Create a massive crash report when IPython encounters what may be an
160 internal error. The default is to append a short message to the
160 internal error. The default is to append a short message to the
161 usual traceback""")
161 usual traceback""")
162
162
163 # The class to use as the crash handler.
163 # The class to use as the crash handler.
164 crash_handler_class = Type(crashhandler.CrashHandler)
164 crash_handler_class = Type(crashhandler.CrashHandler)
165
165
166 @catch_config_error
166 @catch_config_error
167 def __init__(self, **kwargs):
167 def __init__(self, **kwargs):
168 super(BaseIPythonApplication, self).__init__(**kwargs)
168 super(BaseIPythonApplication, self).__init__(**kwargs)
169 # ensure current working directory exists
169 # ensure current working directory exists
170 try:
170 try:
171 directory = py3compat.getcwd()
171 directory = py3compat.getcwd()
172 except:
172 except:
173 # exit if cwd doesn't exist
173 # exit if cwd doesn't exist
174 self.log.error("Current working directory doesn't exist.")
174 self.log.error("Current working directory doesn't exist.")
175 self.exit(1)
175 self.exit(1)
176
176
177 #-------------------------------------------------------------------------
177 #-------------------------------------------------------------------------
178 # Various stages of Application creation
178 # Various stages of Application creation
179 #-------------------------------------------------------------------------
179 #-------------------------------------------------------------------------
180
180
181 def init_crash_handler(self):
181 def init_crash_handler(self):
182 """Create a crash handler, typically setting sys.excepthook to it."""
182 """Create a crash handler, typically setting sys.excepthook to it."""
183 self.crash_handler = self.crash_handler_class(self)
183 self.crash_handler = self.crash_handler_class(self)
184 sys.excepthook = self.excepthook
184 sys.excepthook = self.excepthook
185 def unset_crashhandler():
185 def unset_crashhandler():
186 sys.excepthook = sys.__excepthook__
186 sys.excepthook = sys.__excepthook__
187 atexit.register(unset_crashhandler)
187 atexit.register(unset_crashhandler)
188
188
189 def excepthook(self, etype, evalue, tb):
189 def excepthook(self, etype, evalue, tb):
190 """this is sys.excepthook after init_crashhandler
190 """this is sys.excepthook after init_crashhandler
191
191
192 set self.verbose_crash=True to use our full crashhandler, instead of
192 set self.verbose_crash=True to use our full crashhandler, instead of
193 a regular traceback with a short message (crash_handler_lite)
193 a regular traceback with a short message (crash_handler_lite)
194 """
194 """
195
195
196 if self.verbose_crash:
196 if self.verbose_crash:
197 return self.crash_handler(etype, evalue, tb)
197 return self.crash_handler(etype, evalue, tb)
198 else:
198 else:
199 return crashhandler.crash_handler_lite(etype, evalue, tb)
199 return crashhandler.crash_handler_lite(etype, evalue, tb)
200
200
201 def _ipython_dir_changed(self, name, old, new):
201 def _ipython_dir_changed(self, name, old, new):
202 if old is not None:
202 if old is not None:
203 str_old = py3compat.cast_bytes_py2(os.path.abspath(old),
203 str_old = py3compat.cast_bytes_py2(os.path.abspath(old),
204 sys.getfilesystemencoding()
204 sys.getfilesystemencoding()
205 )
205 )
206 if str_old in sys.path:
206 if str_old in sys.path:
207 sys.path.remove(str_old)
207 sys.path.remove(str_old)
208 str_path = py3compat.cast_bytes_py2(os.path.abspath(new),
208 str_path = py3compat.cast_bytes_py2(os.path.abspath(new),
209 sys.getfilesystemencoding()
209 sys.getfilesystemencoding()
210 )
210 )
211 sys.path.append(str_path)
211 sys.path.append(str_path)
212 ensure_dir_exists(new)
212 ensure_dir_exists(new)
213 readme = os.path.join(new, 'README')
213 readme = os.path.join(new, 'README')
214 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
214 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
215 if not os.path.exists(readme) and os.path.exists(readme_src):
215 if not os.path.exists(readme) and os.path.exists(readme_src):
216 shutil.copy(readme_src, readme)
216 shutil.copy(readme_src, readme)
217 for d in ('extensions', 'nbextensions'):
217 for d in ('extensions', 'nbextensions'):
218 path = os.path.join(new, d)
218 path = os.path.join(new, d)
219 try:
219 try:
220 ensure_dir_exists(path)
220 ensure_dir_exists(path)
221 except OSError:
221 except OSError:
222 # this will not be EEXIST
222 # this will not be EEXIST
223 self.log.error("couldn't create path %s: %s", path, e)
223 self.log.error("couldn't create path %s: %s", path, e)
224 self.log.debug("IPYTHONDIR set to: %s" % new)
224 self.log.debug("IPYTHONDIR set to: %s" % new)
225
225
226 def load_config_file(self, suppress_errors=True):
226 def load_config_file(self, suppress_errors=True):
227 """Load the config file.
227 """Load the config file.
228
228
229 By default, errors in loading config are handled, and a warning
229 By default, errors in loading config are handled, and a warning
230 printed on screen. For testing, the suppress_errors option is set
230 printed on screen. For testing, the suppress_errors option is set
231 to False, so errors will make tests fail.
231 to False, so errors will make tests fail.
232 """
232 """
233 self.log.debug("Searching path %s for config files", self.config_file_paths)
233 self.log.debug("Searching path %s for config files", self.config_file_paths)
234 base_config = 'ipython_config.py'
234 base_config = 'ipython_config.py'
235 self.log.debug("Attempting to load config file: %s" %
235 self.log.debug("Attempting to load config file: %s" %
236 base_config)
236 base_config)
237 try:
237 try:
238 Application.load_config_file(
238 Application.load_config_file(
239 self,
239 self,
240 base_config,
240 base_config,
241 path=self.config_file_paths
241 path=self.config_file_paths
242 )
242 )
243 except ConfigFileNotFound:
243 except ConfigFileNotFound:
244 # ignore errors loading parent
244 # ignore errors loading parent
245 self.log.debug("Config file %s not found", base_config)
245 self.log.debug("Config file %s not found", base_config)
246 pass
246 pass
247
247
248 for config_file_name in self.config_files:
248 for config_file_name in self.config_files:
249 if not config_file_name or config_file_name == base_config:
249 if not config_file_name or config_file_name == base_config:
250 continue
250 continue
251 self.log.debug("Attempting to load config file: %s" %
251 self.log.debug("Attempting to load config file: %s" %
252 self.config_file_name)
252 self.config_file_name)
253 try:
253 try:
254 Application.load_config_file(
254 Application.load_config_file(
255 self,
255 self,
256 config_file_name,
256 config_file_name,
257 path=self.config_file_paths
257 path=self.config_file_paths
258 )
258 )
259 except ConfigFileNotFound:
259 except ConfigFileNotFound:
260 # Only warn if the default config file was NOT being used.
260 # Only warn if the default config file was NOT being used.
261 if config_file_name in self.config_file_specified:
261 if config_file_name in self.config_file_specified:
262 msg = self.log.warn
262 msg = self.log.warn
263 else:
263 else:
264 msg = self.log.debug
264 msg = self.log.debug
265 msg("Config file not found, skipping: %s", config_file_name)
265 msg("Config file not found, skipping: %s", config_file_name)
266 except:
266 except:
267 # For testing purposes.
267 # For testing purposes.
268 if not suppress_errors:
268 if not suppress_errors:
269 raise
269 raise
270 self.log.warn("Error loading config file: %s" %
270 self.log.warn("Error loading config file: %s" %
271 self.config_file_name, exc_info=True)
271 self.config_file_name, exc_info=True)
272
272
273 def init_profile_dir(self):
273 def init_profile_dir(self):
274 """initialize the profile dir"""
274 """initialize the profile dir"""
275 self._in_init_profile_dir = True
275 self._in_init_profile_dir = True
276 if self.profile_dir is not None:
276 if self.profile_dir is not None:
277 # already ran
277 # already ran
278 return
278 return
279 if 'ProfileDir.location' not in self.config:
279 if 'ProfileDir.location' not in self.config:
280 # location not specified, find by profile name
280 # location not specified, find by profile name
281 try:
281 try:
282 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
282 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
283 except ProfileDirError:
283 except ProfileDirError:
284 # not found, maybe create it (always create default profile)
284 # not found, maybe create it (always create default profile)
285 if self.auto_create or self.profile == 'default':
285 if self.auto_create or self.profile == 'default':
286 try:
286 try:
287 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
287 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
288 except ProfileDirError:
288 except ProfileDirError:
289 self.log.fatal("Could not create profile: %r"%self.profile)
289 self.log.fatal("Could not create profile: %r"%self.profile)
290 self.exit(1)
290 self.exit(1)
291 else:
291 else:
292 self.log.info("Created profile dir: %r"%p.location)
292 self.log.info("Created profile dir: %r"%p.location)
293 else:
293 else:
294 self.log.fatal("Profile %r not found."%self.profile)
294 self.log.fatal("Profile %r not found."%self.profile)
295 self.exit(1)
295 self.exit(1)
296 else:
296 else:
297 self.log.info("Using existing profile dir: %r"%p.location)
297 self.log.debug("Using existing profile dir: %r"%p.location)
298 else:
298 else:
299 location = self.config.ProfileDir.location
299 location = self.config.ProfileDir.location
300 # location is fully specified
300 # location is fully specified
301 try:
301 try:
302 p = ProfileDir.find_profile_dir(location, self.config)
302 p = ProfileDir.find_profile_dir(location, self.config)
303 except ProfileDirError:
303 except ProfileDirError:
304 # not found, maybe create it
304 # not found, maybe create it
305 if self.auto_create:
305 if self.auto_create:
306 try:
306 try:
307 p = ProfileDir.create_profile_dir(location, self.config)
307 p = ProfileDir.create_profile_dir(location, self.config)
308 except ProfileDirError:
308 except ProfileDirError:
309 self.log.fatal("Could not create profile directory: %r"%location)
309 self.log.fatal("Could not create profile directory: %r"%location)
310 self.exit(1)
310 self.exit(1)
311 else:
311 else:
312 self.log.info("Creating new profile dir: %r"%location)
312 self.log.debug("Creating new profile dir: %r"%location)
313 else:
313 else:
314 self.log.fatal("Profile directory %r not found."%location)
314 self.log.fatal("Profile directory %r not found."%location)
315 self.exit(1)
315 self.exit(1)
316 else:
316 else:
317 self.log.info("Using existing profile dir: %r"%location)
317 self.log.info("Using existing profile dir: %r"%location)
318 # if profile_dir is specified explicitly, set profile name
318 # if profile_dir is specified explicitly, set profile name
319 dir_name = os.path.basename(p.location)
319 dir_name = os.path.basename(p.location)
320 if dir_name.startswith('profile_'):
320 if dir_name.startswith('profile_'):
321 self.profile = dir_name[8:]
321 self.profile = dir_name[8:]
322
322
323 self.profile_dir = p
323 self.profile_dir = p
324 self.config_file_paths.append(p.location)
324 self.config_file_paths.append(p.location)
325 self._in_init_profile_dir = False
325 self._in_init_profile_dir = False
326
326
327 def init_config_files(self):
327 def init_config_files(self):
328 """[optionally] copy default config files into profile dir."""
328 """[optionally] copy default config files into profile dir."""
329 self.config_file_paths.extend(SYSTEM_CONFIG_DIRS)
329 self.config_file_paths.extend(SYSTEM_CONFIG_DIRS)
330 # copy config files
330 # copy config files
331 path = self.builtin_profile_dir
331 path = self.builtin_profile_dir
332 if self.copy_config_files:
332 if self.copy_config_files:
333 src = self.profile
333 src = self.profile
334
334
335 cfg = self.config_file_name
335 cfg = self.config_file_name
336 if path and os.path.exists(os.path.join(path, cfg)):
336 if path and os.path.exists(os.path.join(path, cfg)):
337 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
337 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
338 cfg, src, self.profile_dir.location, self.overwrite)
338 cfg, src, self.profile_dir.location, self.overwrite)
339 )
339 )
340 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
340 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
341 else:
341 else:
342 self.stage_default_config_file()
342 self.stage_default_config_file()
343 else:
343 else:
344 # Still stage *bundled* config files, but not generated ones
344 # Still stage *bundled* config files, but not generated ones
345 # This is necessary for `ipython profile=sympy` to load the profile
345 # This is necessary for `ipython profile=sympy` to load the profile
346 # on the first go
346 # on the first go
347 files = glob.glob(os.path.join(path, '*.py'))
347 files = glob.glob(os.path.join(path, '*.py'))
348 for fullpath in files:
348 for fullpath in files:
349 cfg = os.path.basename(fullpath)
349 cfg = os.path.basename(fullpath)
350 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
350 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
351 # file was copied
351 # file was copied
352 self.log.warn("Staging bundled %s from %s into %r"%(
352 self.log.warn("Staging bundled %s from %s into %r"%(
353 cfg, self.profile, self.profile_dir.location)
353 cfg, self.profile, self.profile_dir.location)
354 )
354 )
355
355
356
356
357 def stage_default_config_file(self):
357 def stage_default_config_file(self):
358 """auto generate default config file, and stage it into the profile."""
358 """auto generate default config file, and stage it into the profile."""
359 s = self.generate_config_file()
359 s = self.generate_config_file()
360 fname = os.path.join(self.profile_dir.location, self.config_file_name)
360 fname = os.path.join(self.profile_dir.location, self.config_file_name)
361 if self.overwrite or not os.path.exists(fname):
361 if self.overwrite or not os.path.exists(fname):
362 self.log.warn("Generating default config file: %r"%(fname))
362 self.log.warn("Generating default config file: %r"%(fname))
363 with open(fname, 'w') as f:
363 with open(fname, 'w') as f:
364 f.write(s)
364 f.write(s)
365
365
366 @catch_config_error
366 @catch_config_error
367 def initialize(self, argv=None):
367 def initialize(self, argv=None):
368 # don't hook up crash handler before parsing command-line
368 # don't hook up crash handler before parsing command-line
369 self.parse_command_line(argv)
369 self.parse_command_line(argv)
370 self.init_crash_handler()
370 self.init_crash_handler()
371 if self.subapp is not None:
371 if self.subapp is not None:
372 # stop here if subapp is taking over
372 # stop here if subapp is taking over
373 return
373 return
374 cl_config = self.config
374 cl_config = self.config
375 self.init_profile_dir()
375 self.init_profile_dir()
376 self.init_config_files()
376 self.init_config_files()
377 self.load_config_file()
377 self.load_config_file()
378 # enforce cl-opts override configfile opts:
378 # enforce cl-opts override configfile opts:
379 self.update_config(cl_config)
379 self.update_config(cl_config)
380
380
General Comments 0
You need to be logged in to leave comments. Login now