forked from amoschov/TideSDK
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathutils.py
207 lines (176 loc) · 7.21 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# This file has been modified from its orginal sources.
#
# Copyright (c) 2012 Software in the Public Interest Inc (SPI)
# Copyright (c) 2012 David Pratt
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Copyright (c) 2008-2012 Appcelerator Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import shutil
import types
import effess
import os.path as path
from SCons.Script import *
TYPICAL_EXCLUDES = ['.pdb', '.exp', '.ilk', '.db', '.swp', '.swo',
'.gitignore', '.psd', '.cpp', '.obj', '.pyc', 'SConscript']
class BuildUtils(object):
def __init__(self, build):
self.build = build
self.env = build.env
# Add our custom builders
self.env['BUILDERS']['KCopySymlink'] = self.env.Builder(
action=KCopySymlink,
source_factory=SCons.Node.FS.default_fs.Entry,
target_factory=SCons.Node.FS.default_fs.Entry,
multi=0)
self.env['BUILDERS']['LightWeightCopyTree'] = self.env.Builder(action=LightWeightCopyTree)
def CopyTree(self, *args, **kwargs):
return SCopyTree(self.env, *args, **kwargs)
def CopyToDir(self, *args, **kwargs):
return SCopyToDir(self.env, *args, **kwargs)
def Copy(self, src, dest):
return self.env.Command(dest, src, Copy('$TARGET', '$SOURCE'))
def Touch(self, file):
return self.env.Command(file, [], Touch('$TARGET'))
def Delete(self, file):
return self.env.Command(file, [], Delete('$TARGET'))
def Mkdir(self, file):
return self.env.Command(file, [], Mkdir('$TARGET'))
def LightWeightCopy(self, indir, outdir):
name = '#' + (indir + '=' + outdir).replace('/', '-').replace('\\', '-')
t = self.env.LightWeightCopyTree(name, [],
OUTDIR=outdir, IN=indir, EXCLUDE=TYPICAL_EXCLUDES)
self.build.mark_stage_target(t)
AlwaysBuild(t)
def filter_file(file, include=[], exclude=[], filter=None):
for suffix in include:
if file.endswith(suffix):
return True
if len(include) > 0:
return False
for suffix in exclude:
if file.endswith(suffix):
return False
if filter:
return filter(file)
return True
# Adapted from: http://www.scons.org/wiki/AccumulateBuilder
def SCopyTree(*args, **kwargs):
targets = []
if (type(args[1]) == types.ListType):
for src in args[1]:
t = SCopyTreeImpl(args[0], src, args[2], **kwargs)
targets.append(t)
return targets
else:
return SCopyTreeImpl(args[0], args[1], args[2], **kwargs)
def SCopyTreeImpl(e, src, dest, **kwargs):
"""Copy a directory recursivley in a sconsy way. If the first
argument is a directory, copy the contents of that directory
into the target directory. If the first argument is a file,
copy that file into the target directory. Will preserve symlinks.
Includes is a list of file suffixes to include. If len(include) > 1
all other files will be skipped. Excludes is a list of file suffixes
to exclude. Filter is a function which given the full path to a file,
will exclude is returns False or include if returns True.
"""
dest = path.abspath(str(dest))
src = path.abspath(str(src))
targets = []
if path.isdir(src):
for item in os.listdir(src):
src_item = path.abspath(path.join(src, item))
#print "copy tree u %s %s" % (src_item, dest)
t = SCopyToDir(e, src_item, dest, **kwargs)
targets.append(t)
return targets
else:
return SCopyToDir(e, src, dest, **kwargs)
def SCopyToDir(*args, **kwargs):
targets = []
if (type(args[1]) == types.ListType):
for src in args[1]:
t = SCopyToDirImpl(args[0], src, args[2], **kwargs)
targets.append(t)
return targets
else:
return SCopyToDirImpl(args[0], args[1], args[2], **kwargs)
def SCopyToDirImpl(e, src, dest, include=[], exclude=[], filter=None, recurse=True):
"""Copy a path into a destination directory in a sconsy way.
the original path will be a child of the destination directory.
Includes is a list of file suffixes to include. If len(include) > 1
all other files will be skipped. Excludes is a list of file suffixes
to exclude. Filter is a function which given the full path to a file,
will exclude is returns False or include if returns True.
"""
def copy_item(src, dest):
dest_dir = path.dirname(dest)
if not path.exists(dest_dir):
os.makedirs(dest_dir)
#print "copy u %s %s" % (src, dest)
# Test for a symlink first, because a symlink can
# also return turn for isdir
if path.islink(src) and filter_file(src, include, exclude, filter):
return e.KCopySymlink(dest, src)
# It doesn't really make sense for includes to
# apply to folders, so we don't use them here
elif path.isdir(src) and filter_file(src, [], exclude, filter):
return copy_items(src, dest)
elif filter_file(src, include, exclude, filter):
return e.Command(dest, src, Copy('$TARGET', '$SOURCE'))
def copy_items(src, dest):
targets = [] # result targets
if not os.path.exists(dest):
os.makedirs(dest)
for item in os.listdir(src):
src_item = path.abspath(path.join(src, item))
dest_item = path.join(dest, item)
t = copy_item(src_item, dest_item)
targets.append(t)
return targets
src = path.abspath(str(src))
bname = path.basename(src)
dest = path.abspath(str(dest))
dest = path.join(dest, bname)
#print "copy %s %s" % (src, dest)
return copy_item(src, dest)
def KCopySymlink(target, source, env):
link_file = str(source[0])
dest_file = str(target[0])
linkto = os.readlink(link_file)
# Remove link before recreating it
# use os.stat so we can sense broken links
try:
os.remove(dest_file)
except:
pass
os.symlink(linkto, dest_file)
def LightWeightCopyTree(target, source, env):
if not 'EXCLUDE' in env:
exclude = []
else:
exclude = env['EXCLUDE']
if type(env['OUTDIR']) == types.ListType:
env['OUTDIR'] = env['OUTDIR'][0]
effess.lightweight_copy_tree(env['IN'], env['OUTDIR'], exclude)