2 # Interactively decide what to distribute
4 # The distribution type is signalled by a letter. The currently
6 # p PPC normal distribution
7 # P PPC development distribution
8 # m 68K normal distribution
9 # M 68K development distribution
11 # The exclude file signals files to always exclude,
12 # The pattern file records are of the form
14 # This excludes all files ending in .c for normal distributions.
16 # The include file signals files and directories to include.
17 # Records are of the form
19 # This includes the Lib dir in all distributions
20 # ('pPmM', 'Tools:bgen:AE:AppleEvents.py', 'Lib:MacToolbox:AppleEvents.py')
21 # This includes the specified file, putting it in the given place.
23 from MkDistr_ui
import *
31 SyntaxError='Include/exclude file syntax error'
34 """Include/exclude database, common code"""
36 def __init__(self
, type, filename
):
38 self
.filename
= filename
45 def parse(self
, dbfile
):
54 if not d
or d
[0] == '#': continue
55 pat
= self
.parseline(d
)
56 self
.rawdata
.append(pat
)
58 def parseline(self
, line
):
62 raise SyntaxError, line
63 if type(data
) <> type(()) or len(data
) not in (2,3):
64 raise SyntaxError, line
70 fp
= open(self
.filename
, 'w')
71 for d
in self
.rawdata
:
78 self
.rawdata
.append(value
)
82 def delete(self
, value
):
84 for i
in range(len(self
.rawdata
)):
85 if self
.rawdata
[i
][1] == key
:
87 self
.unrebuild1(i
, key
)
90 print 'Not found!', key
93 return map(lambda x
: x
[1], self
.rawdata
)
96 for t
, src
, dst
in self
.rawdata
:
99 print 'Not found!', value
101 def is_modified(self
):
104 class IncMatcher(Matcher
):
105 """Include filename database and matching engine"""
110 for v
in self
.rawdata
:
113 def rebuild1(self
, (tp
, src
, dst
)):
117 self
.idict
[src
] = dst
121 def unrebuild1(self
, num
, src
):
122 if self
.idict
.has_key(src
):
127 def match(self
, patharg
):
129 # First check the include directory
132 if self
.idict
.has_key(path
):
133 # We know of this path (or initial piece of path)
134 dstpath
= self
.idict
[path
]
135 # We do want it distributed. Tack on the tail.
137 dstpath
= os
.path
.join(dstpath
, removed
[0])
138 removed
= removed
[1:]
139 # Finally, if the resultant string ends in a separator
140 # tack on our input filename
141 if dstpath
[-1] == os
.sep
:
142 dir, file = os
.path
.split(path
)
143 dstpath
= os
.path
.join(dstpath
, path
)
145 path
, lastcomp
= os
.path
.split(path
)
148 removed
[0:0] = [lastcomp
]
149 # Next check the exclude directory
152 if self
.edict
.has_key(path
):
154 path
, lastcomp
= os
.path
.split(path
)
157 removed
[0:0] = [lastcomp
]
160 def checksourcetree(self
):
162 for name
in self
.idict
.keys():
163 if not os
.path
.exists(name
):
167 class ExcMatcher(Matcher
):
168 """Exclude pattern database and matching engine"""
172 for v
in self
.rawdata
:
175 def rebuild1(self
, (tp
, src
, dst
)):
177 pat
= fnmatch
.translate(src
)
178 self
.relist
.append(regex
.compile(pat
))
180 self
.relist
.append(None)
182 def unrebuild1(self
, num
, src
):
185 def match(self
, path
):
186 comps
= os
.path
.split(path
)
188 for pat
in self
.relist
:
189 if pat
and pat
.match(file) == len(file):
195 """The main program glueing it all together"""
199 fss
, ok
= macfs
.GetDirectory('Source directory:')
202 os
.chdir(fss
.as_pathname())
203 self
.typedist
= GetType()
204 print 'TYPE', self
.typedist
205 self
.inc
= IncMatcher(self
.typedist
, '(MkDistr.include)')
206 self
.exc
= ExcMatcher(self
.typedist
, '(MkDistr.exclude)')
207 self
.ui
= MkDistrUI(self
)
211 return self
.checkdir(':', 1)
213 def checkdir(self
, path
, istop
):
214 files
= os
.listdir(path
)
218 if self
.exc
.match(f
):
220 fullname
= os
.path
.join(path
, f
)
221 if self
.inc
.match(fullname
) == None:
222 if os
.path
.isdir(fullname
):
223 todo
.append(fullname
)
229 rv
.append('... and more ...')
231 rv
= rv
+ self
.checkdir(d
, 0)
234 def run(self
, destprefix
):
235 missing
= self
.inc
.checksourcetree()
237 print '==== Missing source files ===='
240 print '==== Fix and retry ===='
242 if not self
.rundir(':', destprefix
, 0):
244 self
.rundir(':', destprefix
, 1)
246 def rundir(self
, path
, destprefix
, doit
):
247 files
= os
.listdir(path
)
251 if self
.exc
.match(f
):
253 fullname
= os
.path
.join(path
, f
)
254 if os
.path
.isdir(fullname
):
255 todo
.append(fullname
)
257 dest
= self
.inc
.match(fullname
)
259 print 'Not yet resolved:', fullname
263 print 'COPY ', fullname
264 print ' -> ', os
.path
.join(destprefix
, dest
)
265 macostools
.copy(fullname
, os
.path
.join(destprefix
, dest
), 1)
267 if not self
.rundir(d
, destprefix
, doit
):
275 def is_modified(self
):
276 return self
.inc
.is_modified() or self
.exc
.is_modified()
278 if __name__
== '__main__':