annotate bitten/build/api.py @ 279:5e7b6337d77c

* Fix snapshot deletion after build on Windows. * Don't extract files in archives that have an absolute path, or contain up-references (`..`) * Fixes to the sequencing of output from processes launched through the `CommandLine` class.
author cmlenz
date Fri, 14 Oct 2005 14:19:19 +0000
parents 62b668fc713d
children fe966b950424
rev   line source
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
1 # -*- coding: iso8859-1 -*-
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
2 #
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
3 # Copyright (C) 2005 Christopher Lenz <cmlenz@gmx.de>
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
4 # All rights reserved.
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
5 #
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
8 # are also available at http://bitten.cmlenz.net/wiki/License.
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
9
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
10 import logging
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
11 import fnmatch
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
12 import os
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
13 import shlex
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
14 import time
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
15
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
16 log = logging.getLogger('bitten.build.api')
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
17
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
18
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
19 class BuildError(Exception):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
20 """Exception raised when a build fails."""
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
21
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
22
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
23 class TimeoutError(Exception):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
24 """Exception raised when the execution of a command times out."""
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
25
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
26
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
27 class CommandLine(object):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
28 """Simple helper for executing subprocesses."""
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
29 # TODO: Use 'subprocess' module if available (Python >= 2.4)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
30
210
c550e31c06d2 Implement providing input data to processes executed via the `CommandLine` class. The `<sh:pipe>` recipe command should now be functional. Closes #34.
cmlenz
parents: 183
diff changeset
31 def __init__(self, executable, args, input=None, cwd=None):
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
32 """Initialize the CommandLine object.
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
33
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
34 @param executable The name of the program to execute
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
35 @param args A list of arguments to pass to the executable
210
c550e31c06d2 Implement providing input data to processes executed via the `CommandLine` class. The `<sh:pipe>` recipe command should now be functional. Closes #34.
cmlenz
parents: 183
diff changeset
36 @param input String or file-like object containing any input data for
c550e31c06d2 Implement providing input data to processes executed via the `CommandLine` class. The `<sh:pipe>` recipe command should now be functional. Closes #34.
cmlenz
parents: 183
diff changeset
37 the program
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
38 @param cwd The working directory to change to before executing the
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
39 command
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
40 """
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
41 self.executable = executable
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
42 self.arguments = [str(arg) for arg in args]
210
c550e31c06d2 Implement providing input data to processes executed via the `CommandLine` class. The `<sh:pipe>` recipe command should now be functional. Closes #34.
cmlenz
parents: 183
diff changeset
43 self.input = input
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
44 self.cwd = cwd
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
45 if self.cwd:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
46 assert os.path.isdir(self.cwd)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
47 self.returncode = None
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
48
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
49 if os.name == 'nt': # windows
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
50
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
51 def execute(self, timeout=None):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
52 args = [self.executable] + self.arguments
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
53 for idx, arg in enumerate(args):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
54 if arg.find(' ') >= 0:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
55 args[idx] = '"%s"' % arg
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
56 log.debug('Executing %s', args)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
57
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
58 if self.cwd:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
59 old_cwd = os.getcwd()
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
60 os.chdir(self.cwd)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
61
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
62 import tempfile
211
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
63 in_name = None
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
64 if self.input:
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
65 if isinstance(self.input, basestring):
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
66 in_file, in_name = tempfile.mkstemp(prefix='bitten_',
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
67 suffix='.pipe')
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
68 os.write(in_file, self.input)
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
69 os.close(in_file)
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
70 in_redirect = '< "%s" ' % in_name
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
71 else:
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
72 in_redirect = '< "%s" ' % self.input.name
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
73 else:
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
74 in_redirect = ''
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
75
211
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
76 out_file, out_name = tempfile.mkstemp(prefix='bitten_',
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
77 suffix='.pipe')
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
78 os.close(out_file)
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
79 err_file, err_name = tempfile.mkstemp(prefix='bitten_',
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
80 suffix='.pipe')
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
81 os.close(err_file)
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
82
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
83 try:
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
84 cmd = '( %s ) > "%s" %s 2> "%s"' % (' '.join(args), out_name,
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
85 in_redirect, err_name)
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
86 self.returncode = os.system(cmd)
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
87 log.debug('Exited with code %s', self.returncode)
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
88
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
89 out_file = file(out_name, 'r')
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
90 err_file = file(err_name, 'r')
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
91 out_lines = out_file.readlines()
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
92 err_lines = err_file.readlines()
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
93 out_file.close()
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
94 err_file.close()
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
95 finally:
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
96 if in_name:
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
97 os.unlink(in_name)
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
98 if out_name:
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
99 os.unlink(out_name)
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
100 if err_name:
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
101 os.unlink(err_name)
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
102 if self.cwd:
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
103 os.chdir(old_cwd)
211
d1ead1bfcc65 Follow-up to [219]: Input to processes now also implemented for Windows.
cmlenz
parents: 210
diff changeset
104
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
105 for out_line, err_line in self._combine(out_lines, err_lines):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
106 yield out_line and out_line.rstrip(), \
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
107 err_line and err_line.rstrip()
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
108
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
109 else: # posix
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
110
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
111 def execute(self, timeout=None):
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
112 import popen2, select
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
113 if self.cwd:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
114 old_cwd = os.getcwd()
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
115 os.chdir(self.cwd)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
116
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
117 log.debug('Executing %s', [self.executable] + self.arguments)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
118 pipe = popen2.Popen3([self.executable] + self.arguments,
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
119 capturestderr=True)
210
c550e31c06d2 Implement providing input data to processes executed via the `CommandLine` class. The `<sh:pipe>` recipe command should now be functional. Closes #34.
cmlenz
parents: 183
diff changeset
120 if self.input:
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
121 if isinstance(self.input, basestring):
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
122 in_data = self.input
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
123 else:
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
124 in_data = self.input.read()
210
c550e31c06d2 Implement providing input data to processes executed via the `CommandLine` class. The `<sh:pipe>` recipe command should now be functional. Closes #34.
cmlenz
parents: 183
diff changeset
125 else:
c550e31c06d2 Implement providing input data to processes executed via the `CommandLine` class. The `<sh:pipe>` recipe command should now be functional. Closes #34.
cmlenz
parents: 183
diff changeset
126 pipe.tochild.close()
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
127 in_data = ''
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
128
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
129 out_data, err_data = [], []
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
130 in_eof = out_eof = err_eof = False
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
131 if not in_data:
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
132 in_eof = True
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
133 while not out_eof or not err_eof:
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
134 readable = [pipe.fromchild] * (not out_eof) + \
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
135 [pipe.childerr] * (not err_eof)
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
136 writable = [pipe.tochild] * (not in_eof)
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
137 ready = select.select(readable, writable, [], timeout)
210
c550e31c06d2 Implement providing input data to processes executed via the `CommandLine` class. The `<sh:pipe>` recipe command should now be functional. Closes #34.
cmlenz
parents: 183
diff changeset
138 if not (ready[0] or ready[1]):
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
139 raise TimeoutError, 'Command %s timed out' % self.executable
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
140 if pipe.tochild in ready[1]:
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
141 sent = os.write(pipe.tochild.fileno(), in_data)
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
142 in_data = in_data[sent:]
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
143 if not in_data:
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
144 pipe.tochild.close()
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
145 in_eof = True
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
146 if pipe.fromchild in ready[0]:
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
147 data = os.read(pipe.fromchild.fileno(), 1024)
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
148 if data:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
149 out_data.append(data)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
150 else:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
151 out_eof = True
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
152 if pipe.childerr in ready[0]:
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
153 data = os.read(pipe.childerr.fileno(), 1024)
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
154 if data:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
155 err_data.append(data)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
156 else:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
157 err_eof = True
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
158 out_lines = self._extract_lines(out_data)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
159 err_lines = self._extract_lines(err_data)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
160 for out_line, err_line in self._combine(out_lines, err_lines):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
161 yield out_line, err_line
212
62b668fc713d Removed the use of the `fcntl` module to make the file IO non-blocking in the `CommandLine` class. Instead, use the functions `os.read()` and `os.write()`, which should only block when no data is available -- and that cannot happen because of the preceding `select()`.
cmlenz
parents: 211
diff changeset
162 time.sleep(.1)
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
163 self.returncode = pipe.wait()
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
164 log.debug('%s exited with code %s', self.executable,
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
165 self.returncode)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
167 if self.cwd:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
168 os.chdir(old_cwd)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
169
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
170 def _combine(self, *iterables):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
171 iterables = [iter(iterable) for iterable in iterables]
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
172 size = len(iterables)
279
5e7b6337d77c * Fix snapshot deletion after build on Windows.
cmlenz
parents: 212
diff changeset
173 while True:
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
174 to_yield = [None] * size
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
175 for idx, iterable in enumerate(iterables):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
176 if iterable is None:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
177 continue
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
178 try:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
179 to_yield[idx] = iterable.next()
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
180 except StopIteration:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
181 iterables[idx] = None
279
5e7b6337d77c * Fix snapshot deletion after build on Windows.
cmlenz
parents: 212
diff changeset
182 if not [iterable for iterable in iterables if iterable is not None]:
5e7b6337d77c * Fix snapshot deletion after build on Windows.
cmlenz
parents: 212
diff changeset
183 break
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
184 yield tuple(to_yield)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
185
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
186 def _extract_lines(self, data):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
187 extracted = []
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
188 def _endswith_linesep(string):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
189 for linesep in ('\n', '\r\n', '\r'):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
190 if string.endswith(linesep):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
191 return True
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
192 buf = ''.join(data)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
193 lines = buf.splitlines(True)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
194 if len(lines) > 1:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
195 extracted += lines[:-1]
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
196 if _endswith_linesep(lines[-1]):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
197 extracted.append(lines[-1])
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
198 buf = ''
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
199 else:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
200 buf = lines[-1]
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
201 elif _endswith_linesep(buf):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
202 extracted.append(buf)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
203 buf = ''
279
5e7b6337d77c * Fix snapshot deletion after build on Windows.
cmlenz
parents: 212
diff changeset
204 data[:] = [buf] * bool(buf)
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
205
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
206 return [line.rstrip() for line in extracted]
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
207
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
208
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
209 class FileSet(object):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
210 """Utility class for collecting a list of files in a directory that match
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
211 given name/path patterns."""
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
212
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
213 DEFAULT_EXCLUDES = ['CVS/*', '*/CVS/*', '.svn/*', '*/.svn/*',
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
214 '.DS_Store', 'Thumbs.db']
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
215
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
216 def __init__(self, basedir, include=None, exclude=None):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
217 self.files = []
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
218 self.basedir = basedir
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
219
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
220 self.include = []
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
221 if include is not None:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
222 self.include = shlex.split(include)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
223
183
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
224 self.exclude = self.DEFAULT_EXCLUDES[:]
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
225 if exclude is not None:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
226 self.exclude += shlex.split(exclude)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
227
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
228 for dirpath, dirnames, filenames in os.walk(self.basedir):
210
c550e31c06d2 Implement providing input data to processes executed via the `CommandLine` class. The `<sh:pipe>` recipe command should now be functional. Closes #34.
cmlenz
parents: 183
diff changeset
229 dirpath = dirpath[len(self.basedir) + 1:]
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
230
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
231 for filename in filenames:
183
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
232 filepath = nfilepath = os.path.join(dirpath, filename)
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
233 if os.sep != '/':
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
234 nfilepath = nfilepath.replace(os.sep, '/')
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
235
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
236 if self.include:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
237 included = False
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
238 for pattern in self.include:
183
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
239 if fnmatch.fnmatchcase(nfilepath, pattern) or \
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
240 fnmatch.fnmatchcase(filename, pattern):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
241 included = True
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
242 break
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
243 if not included:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
244 continue
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
245
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
246 excluded = False
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
247 for pattern in self.exclude:
183
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
248 if fnmatch.fnmatchcase(nfilepath, pattern) or \
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
249 fnmatch.fnmatchcase(filename, pattern):
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
250 excluded = True
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
251 break
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
252 if not excluded:
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
253 self.files.append(filepath)
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
254
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
255 def __iter__(self):
183
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
256 for filename in self.files:
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
257 yield filename
166
60af98d66f11 * Move the `CommandLine` class from `bitten.util.cmdline` to `bitten.build.api`.
cmlenz
parents:
diff changeset
258
183
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
259 def __contains__(self, filename):
fda952491beb * Normalize separators in file paths to "/" in `FileSet`s, so that pattern matching against `include`/`exclude` patterns also works on Windows.
cmlenz
parents: 166
diff changeset
260 return filename in self.files
Copyright (C) 2012-2017 Edgewall Software