blob: 07b3549c6fe8da6a435cbbdebfdfa974085eb286 [file] [log] [blame]
Greg Wardaebf7062000-04-04 02:05:59 +00001"""distutils.dep_util
2
3Utility functions for simple, timestamp-based dependency of files
4and groups of files; also, function based entirely on such
5timestamp dependency analysis."""
6
Greg Wardaebf7062000-04-04 02:05:59 +00007__revision__ = "$Id$"
8
9import os
10from distutils.errors import DistutilsFileError
11
12
Tarek Ziadé36797272010-07-22 12:50:05 +000013def newer (source, target):
14 """Return true if 'source' exists and is more recently modified than
15 'target', or if 'source' exists and 'target' doesn't. Return false if
16 both exist and 'target' is the same age or younger than 'source'.
17 Raise DistutilsFileError if 'source' does not exist.
Greg Wardca4289f2000-09-26 02:13:49 +000018 """
19 if not os.path.exists(source):
Thomas Wouters89d996e2007-09-08 17:39:28 +000020 raise DistutilsFileError("file '%s' does not exist" %
21 os.path.abspath(source))
Greg Wardca4289f2000-09-26 02:13:49 +000022 if not os.path.exists(target):
Tarek Ziadé36797272010-07-22 12:50:05 +000023 return 1
Greg Wardaebf7062000-04-04 02:05:59 +000024
Tarek Ziadé36797272010-07-22 12:50:05 +000025 from stat import ST_MTIME
26 mtime1 = os.stat(source)[ST_MTIME]
27 mtime2 = os.stat(target)[ST_MTIME]
Greg Wardaebf7062000-04-04 02:05:59 +000028
Tarek Ziadé36797272010-07-22 12:50:05 +000029 return mtime1 > mtime2
30
31# newer ()
32
33
34def newer_pairwise (sources, targets):
Greg Wardaebf7062000-04-04 02:05:59 +000035 """Walk two filename lists in parallel, testing if each source is newer
Greg Wardca4289f2000-09-26 02:13:49 +000036 than its corresponding target. Return a pair of lists (sources,
37 targets) where source is newer than target, according to the semantics
38 of 'newer()'.
39 """
40 if len(sources) != len(targets):
Collin Winter5b7e9d72007-08-30 03:52:21 +000041 raise ValueError("'sources' and 'targets' must be same length")
Greg Wardaebf7062000-04-04 02:05:59 +000042
43 # build a pair of lists (sources, targets) where source is newer
44 n_sources = []
45 n_targets = []
Tarek Ziadé36797272010-07-22 12:50:05 +000046 for i in range(len(sources)):
47 if newer(sources[i], targets[i]):
48 n_sources.append(sources[i])
49 n_targets.append(targets[i])
Greg Wardaebf7062000-04-04 02:05:59 +000050
Tarek Ziadé36797272010-07-22 12:50:05 +000051 return (n_sources, n_targets)
Greg Wardaebf7062000-04-04 02:05:59 +000052
Tarek Ziadé36797272010-07-22 12:50:05 +000053# newer_pairwise ()
54
55
56def newer_group (sources, target, missing='error'):
Greg Wardca4289f2000-09-26 02:13:49 +000057 """Return true if 'target' is out-of-date with respect to any file
Tarek Ziadé36797272010-07-22 12:50:05 +000058 listed in 'sources'. In other words, if 'target' exists and is newer
Greg Wardca4289f2000-09-26 02:13:49 +000059 than every file in 'sources', return false; otherwise return true.
60 'missing' controls what we do when a source file is missing; the
61 default ("error") is to blow up with an OSError from inside 'stat()';
62 if it is "ignore", we silently drop any missing source files; if it is
63 "newer", any missing source files make us assume that 'target' is
64 out-of-date (this is handy in "dry-run" mode: it'll make you pretend to
65 carry out commands that wouldn't work because inputs are missing, but
66 that doesn't matter because you're not actually going to run the
67 commands).
68 """
Greg Wardaebf7062000-04-04 02:05:59 +000069 # If the target doesn't even exist, then it's definitely out-of-date.
Greg Wardca4289f2000-09-26 02:13:49 +000070 if not os.path.exists(target):
Tarek Ziadé36797272010-07-22 12:50:05 +000071 return 1
Fred Drakeb94b8492001-12-06 20:51:35 +000072
Greg Wardaebf7062000-04-04 02:05:59 +000073 # Otherwise we have to find out the hard way: if *any* source file
74 # is more recent than 'target', then 'target' is out-of-date and
75 # we can immediately return true. If we fall through to the end
76 # of the loop, then 'target' is up-to-date and we return false.
Tarek Ziadé36797272010-07-22 12:50:05 +000077 from stat import ST_MTIME
78 target_mtime = os.stat(target)[ST_MTIME]
Greg Wardaebf7062000-04-04 02:05:59 +000079 for source in sources:
Greg Wardca4289f2000-09-26 02:13:49 +000080 if not os.path.exists(source):
Greg Wardaebf7062000-04-04 02:05:59 +000081 if missing == 'error': # blow up when we stat() the file
Fred Drakeb94b8492001-12-06 20:51:35 +000082 pass
83 elif missing == 'ignore': # missing source dropped from
Greg Wardaebf7062000-04-04 02:05:59 +000084 continue # target's dependency list
85 elif missing == 'newer': # missing source means target is
Tarek Ziadé36797272010-07-22 12:50:05 +000086 return 1 # out-of-date
Fred Drakeb94b8492001-12-06 20:51:35 +000087
Tarek Ziadé36797272010-07-22 12:50:05 +000088 source_mtime = os.stat(source)[ST_MTIME]
89 if source_mtime > target_mtime:
90 return 1
91 else:
92 return 0
Greg Wardaebf7062000-04-04 02:05:59 +000093
Tarek Ziadé36797272010-07-22 12:50:05 +000094# newer_group ()