1"""distutils.cmd
2
3Provides the Command class, the base class for the command classes
4in the distutils.command package.
5"""
6
7import sys, os, re
8from distutils.errors import DistutilsOptionError
9from distutils import util, dir_util, file_util, archive_util, dep_util
10from distutils import log
11
12class Command:
13    """Abstract base class for defining command classes, the "worker bees"
14    of the Distutils.  A useful analogy for command classes is to think of
15    them as subroutines with local variables called "options".  The options
16    are "declared" in 'initialize_options()' and "defined" (given their
17    final values, aka "finalized") in 'finalize_options()', both of which
18    must be defined by every command class.  The distinction between the
19    two is necessary because option values might come from the outside
20    world (command line, config file, ...), and any options dependent on
21    other options must be computed *after* these outside influences have
22    been processed -- hence 'finalize_options()'.  The "body" of the
23    subroutine, where it does all its work based on the values of its
24    options, is the 'run()' method, which must also be implemented by every
25    command class.
26    """
27
28    # 'sub_commands' formalizes the notion of a "family" of commands,
29    # eg. "install" as the parent with sub-commands "install_lib",
30    # "install_headers", etc.  The parent of a family of commands
31    # defines 'sub_commands' as a class attribute; it's a list of
32    #    (command_name : string, predicate : unbound_method | string | None)
33    # tuples, where 'predicate' is a method of the parent command that
34    # determines whether the corresponding command is applicable in the
35    # current situation.  (Eg. we "install_headers" is only applicable if
36    # we have any C header files to install.)  If 'predicate' is None,
37    # that command is always applicable.
38    #
39    # 'sub_commands' is usually defined at the *end* of a class, because
40    # predicates can be unbound methods, so they must already have been
41    # defined.  The canonical example is the "install" command.
42    sub_commands = []
43
44
45    # -- Creation/initialization methods -------------------------------
46
47    def __init__(self, dist):
48        """Create and initialize a new Command object.  Most importantly,
49        invokes the 'initialize_options()' method, which is the real
50        initializer and depends on the actual command being
51        instantiated.
52        """
53        # late import because of mutual dependence between these classes
54        from distutils.dist import Distribution
55
56        if not isinstance(dist, Distribution):
57            raise TypeError("dist must be a Distribution instance")
58        if self.__class__ is Command:
59            raise RuntimeError("Command is an abstract class")
60
61        self.distribution = dist
62        self.initialize_options()
63
64        # Per-command versions of the global flags, so that the user can
65        # customize Distutils' behaviour command-by-command and let some
66        # commands fall back on the Distribution's behaviour.  None means
67        # "not defined, check self.distribution's copy", while 0 or 1 mean
68        # false and true (duh).  Note that this means figuring out the real
69        # value of each flag is a touch complicated -- hence "self._dry_run"
70        # will be handled by __getattr__, below.
71        # XXX This needs to be fixed.
72        self._dry_run = None
73
74        # verbose is largely ignored, but needs to be set for
75        # backwards compatibility (I think)?
76        self.verbose = dist.verbose
77
78        # Some commands define a 'self.force' option to ignore file
79        # timestamps, but methods defined *here* assume that
80        # 'self.force' exists for all commands.  So define it here
81        # just to be safe.
82        self.force = None
83
84        # The 'help' flag is just used for command-line parsing, so
85        # none of that complicated bureaucracy is needed.
86        self.help = 0
87
88        # 'finalized' records whether or not 'finalize_options()' has been
89        # called.  'finalize_options()' itself should not pay attention to
90        # this flag: it is the business of 'ensure_finalized()', which
91        # always calls 'finalize_options()', to respect/update it.
92        self.finalized = 0
93
94    # XXX A more explicit way to customize dry_run would be better.
95    def __getattr__(self, attr):
96        if attr == 'dry_run':
97            myval = getattr(self, "_" + attr)
98            if myval is None:
99                return getattr(self.distribution, attr)
100            else:
101                return myval
102        else:
103            raise AttributeError(attr)
104
105    def ensure_finalized(self):
106        if not self.finalized:
107            self.finalize_options()
108        self.finalized = 1
109
110    # Subclasses must define:
111    #   initialize_options()
112    #     provide default values for all options; may be customized by
113    #     setup script, by options from config file(s), or by command-line
114    #     options
115    #   finalize_options()
116    #     decide on the final values for all options; this is called
117    #     after all possible intervention from the outside world
118    #     (command-line, option file, etc.) has been processed
119    #   run()
120    #     run the command: do whatever it is we're here to do,
121    #     controlled by the command's various option values
122
123    def initialize_options(self):
124        """Set default values for all the options that this command
125        supports.  Note that these defaults may be overridden by other
126        commands, by the setup script, by config files, or by the
127        command-line.  Thus, this is not the place to code dependencies
128        between options; generally, 'initialize_options()' implementations
129        are just a bunch of "self.foo = None" assignments.
130
131        This method must be implemented by all command classes.
132        """
133        raise RuntimeError("abstract method -- subclass %s must override"
134                           % self.__class__)
135
136    def finalize_options(self):
137        """Set final values for all the options that this command supports.
138        This is always called as late as possible, ie.  after any option
139        assignments from the command-line or from other commands have been
140        done.  Thus, this is the place to code option dependencies: if
141        'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as
142        long as 'foo' still has the same value it was assigned in
143        'initialize_options()'.
144
145        This method must be implemented by all command classes.
146        """
147        raise RuntimeError("abstract method -- subclass %s must override"
148                           % self.__class__)
149
150
151    def dump_options(self, header=None, indent=""):
152        from distutils.fancy_getopt import longopt_xlate
153        if header is None:
154            header = "command options for '%s':" % self.get_command_name()
155        self.announce(indent + header, level=log.INFO)
156        indent = indent + "  "
157        for (option, _, _) in self.user_options:
158            option = option.translate(longopt_xlate)
159            if option[-1] == "=":
160                option = option[:-1]
161            value = getattr(self, option)
162            self.announce(indent + "%s = %s" % (option, value),
163                          level=log.INFO)
164
165    def run(self):
166        """A command's raison d'etre: carry out the action it exists to
167        perform, controlled by the options initialized in
168        'initialize_options()', customized by other commands, the setup
169        script, the command-line, and config files, and finalized in
170        'finalize_options()'.  All terminal output and filesystem
171        interaction should be done by 'run()'.
172
173        This method must be implemented by all command classes.
174        """
175        raise RuntimeError("abstract method -- subclass %s must override"
176                           % self.__class__)
177
178    def announce(self, msg, level=1):
179        """If the current verbosity level is of greater than or equal to
180        'level' print 'msg' to stdout.
181        """
182        log.log(level, msg)
183
184    def debug_print(self, msg):
185        """Print 'msg' to stdout if the global DEBUG (taken from the
186        DISTUTILS_DEBUG environment variable) flag is true.
187        """
188        from distutils.debug import DEBUG
189        if DEBUG:
190            print(msg)
191            sys.stdout.flush()
192
193
194    # -- Option validation methods -------------------------------------
195    # (these are very handy in writing the 'finalize_options()' method)
196    #
197    # NB. the general philosophy here is to ensure that a particular option
198    # value meets certain type and value constraints.  If not, we try to
199    # force it into conformance (eg. if we expect a list but have a string,
200    # split the string on comma and/or whitespace).  If we can't force the
201    # option into conformance, raise DistutilsOptionError.  Thus, command
202    # classes need do nothing more than (eg.)
203    #   self.ensure_string_list('foo')
204    # and they can be guaranteed that thereafter, self.foo will be
205    # a list of strings.
206
207    def _ensure_stringlike(self, option, what, default=None):
208        val = getattr(self, option)
209        if val is None:
210            setattr(self, option, default)
211            return default
212        elif not isinstance(val, str):
213            raise DistutilsOptionError("'%s' must be a %s (got `%s`)"
214                                       % (option, what, val))
215        return val
216
217    def ensure_string(self, option, default=None):
218        """Ensure that 'option' is a string; if not defined, set it to
219        'default'.
220        """
221        self._ensure_stringlike(option, "string", default)
222
223    def ensure_string_list(self, option):
224        r"""Ensure that 'option' is a list of strings.  If 'option' is
225        currently a string, we split it either on /,\s*/ or /\s+/, so
226        "foo bar baz", "foo,bar,baz", and "foo,   bar baz" all become
227        ["foo", "bar", "baz"].
228        """
229        val = getattr(self, option)
230        if val is None:
231            return
232        elif isinstance(val, str):
233            setattr(self, option, re.split(r',\s*|\s+', val))
234        else:
235            if isinstance(val, list):
236                ok = all(isinstance(v, str) for v in val)
237            else:
238                ok = False
239            if not ok:
240                raise DistutilsOptionError(
241                      "'%s' must be a list of strings (got %r)"
242                      % (option, val))
243
244    def _ensure_tested_string(self, option, tester, what, error_fmt,
245                              default=None):
246        val = self._ensure_stringlike(option, what, default)
247        if val is not None and not tester(val):
248            raise DistutilsOptionError(("error in '%s' option: " + error_fmt)
249                                       % (option, val))
250
251    def ensure_filename(self, option):
252        """Ensure that 'option' is the name of an existing file."""
253        self._ensure_tested_string(option, os.path.isfile,
254                                   "filename",
255                                   "'%s' does not exist or is not a file")
256
257    def ensure_dirname(self, option):
258        self._ensure_tested_string(option, os.path.isdir,
259                                   "directory name",
260                                   "'%s' does not exist or is not a directory")
261
262
263    # -- Convenience methods for commands ------------------------------
264
265    def get_command_name(self):
266        if hasattr(self, 'command_name'):
267            return self.command_name
268        else:
269            return self.__class__.__name__
270
271    def set_undefined_options(self, src_cmd, *option_pairs):
272        """Set the values of any "undefined" options from corresponding
273        option values in some other command object.  "Undefined" here means
274        "is None", which is the convention used to indicate that an option
275        has not been changed between 'initialize_options()' and
276        'finalize_options()'.  Usually called from 'finalize_options()' for
277        options that depend on some other command rather than another
278        option of the same command.  'src_cmd' is the other command from
279        which option values will be taken (a command object will be created
280        for it if necessary); the remaining arguments are
281        '(src_option,dst_option)' tuples which mean "take the value of
282        'src_option' in the 'src_cmd' command object, and copy it to
283        'dst_option' in the current command object".
284        """
285        # Option_pairs: list of (src_option, dst_option) tuples
286        src_cmd_obj = self.distribution.get_command_obj(src_cmd)
287        src_cmd_obj.ensure_finalized()
288        for (src_option, dst_option) in option_pairs:
289            if getattr(self, dst_option) is None:
290                setattr(self, dst_option, getattr(src_cmd_obj, src_option))
291
292    def get_finalized_command(self, command, create=1):
293        """Wrapper around Distribution's 'get_command_obj()' method: find
294        (create if necessary and 'create' is true) the command object for
295        'command', call its 'ensure_finalized()' method, and return the
296        finalized command object.
297        """
298        cmd_obj = self.distribution.get_command_obj(command, create)
299        cmd_obj.ensure_finalized()
300        return cmd_obj
301
302    # XXX rename to 'get_reinitialized_command()'? (should do the
303    # same in dist.py, if so)
304    def reinitialize_command(self, command, reinit_subcommands=0):
305        return self.distribution.reinitialize_command(command,
306                                                      reinit_subcommands)
307
308    def run_command(self, command):
309        """Run some other command: uses the 'run_command()' method of
310        Distribution, which creates and finalizes the command object if
311        necessary and then invokes its 'run()' method.
312        """
313        self.distribution.run_command(command)
314
315    def get_sub_commands(self):
316        """Determine the sub-commands that are relevant in the current
317        distribution (ie., that need to be run).  This is based on the
318        'sub_commands' class attribute: each tuple in that list may include
319        a method that we call to determine if the subcommand needs to be
320        run for the current distribution.  Return a list of command names.
321        """
322        commands = []
323        for (cmd_name, method) in self.sub_commands:
324            if method is None or method(self):
325                commands.append(cmd_name)
326        return commands
327
328
329    # -- External world manipulation -----------------------------------
330
331    def warn(self, msg):
332        log.warn("warning: %s: %s\n", self.get_command_name(), msg)
333
334    def execute(self, func, args, msg=None, level=1):
335        util.execute(func, args, msg, dry_run=self.dry_run)
336
337    def mkpath(self, name, mode=0o777):
338        dir_util.mkpath(name, mode, dry_run=self.dry_run)
339
340    def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1,
341                  link=None, level=1):
342        """Copy a file respecting verbose, dry-run and force flags.  (The
343        former two default to whatever is in the Distribution object, and
344        the latter defaults to false for commands that don't define it.)"""
345        return file_util.copy_file(infile, outfile, preserve_mode,
346                                   preserve_times, not self.force, link,
347                                   dry_run=self.dry_run)
348
349    def copy_tree(self, infile, outfile, preserve_mode=1, preserve_times=1,
350                   preserve_symlinks=0, level=1):
351        """Copy an entire directory tree respecting verbose, dry-run,
352        and force flags.
353        """
354        return dir_util.copy_tree(infile, outfile, preserve_mode,
355                                  preserve_times, preserve_symlinks,
356                                  not self.force, dry_run=self.dry_run)
357
358    def move_file (self, src, dst, level=1):
359        """Move a file respecting dry-run flag."""
360        return file_util.move_file(src, dst, dry_run=self.dry_run)
361
362    def spawn(self, cmd, search_path=1, level=1):
363        """Spawn an external command respecting dry-run flag."""
364        from distutils.spawn import spawn
365        spawn(cmd, search_path, dry_run=self.dry_run)
366
367    def make_archive(self, base_name, format, root_dir=None, base_dir=None,
368                     owner=None, group=None):
369        return archive_util.make_archive(base_name, format, root_dir, base_dir,
370                                         dry_run=self.dry_run,
371                                         owner=owner, group=group)
372
373    def make_file(self, infiles, outfile, func, args,
374                  exec_msg=None, skip_msg=None, level=1):
375        """Special case of 'execute()' for operations that process one or
376        more input files and generate one output file.  Works just like
377        'execute()', except the operation is skipped and a different
378        message printed if 'outfile' already exists and is newer than all
379        files listed in 'infiles'.  If the command defined 'self.force',
380        and it is true, then the command is unconditionally run -- does no
381        timestamp checks.
382        """
383        if skip_msg is None:
384            skip_msg = "skipping %s (inputs unchanged)" % outfile
385
386        # Allow 'infiles' to be a single string
387        if isinstance(infiles, str):
388            infiles = (infiles,)
389        elif not isinstance(infiles, (list, tuple)):
390            raise TypeError(
391                  "'infiles' must be a string, or a list or tuple of strings")
392
393        if exec_msg is None:
394            exec_msg = "generating %s from %s" % (outfile, ', '.join(infiles))
395
396        # If 'outfile' must be regenerated (either because it doesn't
397        # exist, is out-of-date, or the 'force' flag is true) then
398        # perform the action that presumably regenerates it
399        if self.force or dep_util.newer_group(infiles, outfile):
400            self.execute(func, args, exec_msg, level)
401        # Otherwise, print the "skip" message
402        else:
403            log.debug(skip_msg)
404