source: rtems-source-builder/source-builder/sb/path.py @ 869b8a6

4.104.114.95
Last change on this file since 869b8a6 was 869b8a6, checked in by Chris Johns <chrisj@…>, on 08/15/13 at 02:20:29

sb: Fix the copy tree.

Python's distutil's copy tree code maintains a cache of directories
created so deleting a tree a different way then coping the same
tree results in an error because the destination folders in the
tree are not present because distutils thinks they exist. The
solution is to implement a copy tree function.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2012 Chris Johns (chrisj@rtems.org)
4# All rights reserved.
5#
6# This file is part of the RTEMS Tools package in 'rtems-tools'.
7#
8# Permission to use, copy, modify, and/or distribute this software for any
9# purpose with or without fee is hereby granted, provided that the above
10# copyright notice and this permission notice appear in all copies.
11#
12# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20#
21# Manage paths locally. The internally the path is in Unix or shell format and
22# we convert to the native format when performing operations at the Python
23# level. This allows macro expansion to work.
24#
25
26import os
27import shutil
28import string
29
30import error
31
32windows = os.name == 'nt'
33
34def host(path):
35    if path is not None:
36        while '//' in path:
37            path = path.replace('//', '/')
38        if windows and len(path) > 2:
39            if path[0] == '/' and path[2] == '/' and \
40                    (path[1] in string.ascii_lowercase or \
41                         path[1] in string.ascii_uppercase):
42                path = ('%s:%s' % (path[1], path[2:])).replace('/', '\\')
43    return path
44
45def shell(path):
46    if path is not None:
47        if windows and len(path) > 1 and path[1] == ':':
48            path = ('/%s%s' % (path[0], path[2:])).replace('\\', '/')
49        while '//' in path:
50            path = path.replace('//', '/')
51    return path
52
53def basename(path):
54    return shell(os.path.basename(path))
55
56def dirname(path):
57    return shell(os.path.dirname(path))
58
59def join(path, *args):
60    path = shell(path)
61    for arg in args:
62        if len(path):
63            path += '/' + shell(arg)
64        else:
65            path = shell(arg)
66    return shell(path)
67
68def abspath(path):
69    return shell(os.path.abspath(host(path)))
70
71def splitext(path):
72    root, ext = os.path.splitext(host(path))
73    return shell(root), ext
74
75def exists(paths):
76    if type(paths) == list:
77        results = []
78        for p in paths:
79            results += [os.path.exists(host(p))]
80        return results
81    return os.path.exists(host(paths))
82
83def isdir(path):
84    return os.path.isdir(host(path))
85
86def isfile(path):
87    return os.path.isfile(host(path))
88
89def isabspath(path):
90    return path[0] == '/'
91
92def iswritable(path):
93    return os.access(host(path), os.W_OK)
94
95def ispathwritable(path):
96    path = host(path)
97    while len(path) != 0:
98        if os.path.exists(path):
99            return iswritable(path)
100        path = os.path.dirname(path)
101    return False
102
103def mkdir(path):
104    path = host(path)
105    if exists(path):
106        if not isdir(path):
107            raise error.general('path exists and is not a directory: %s' % (path))
108    else:
109        if windows:
110            try:
111                os.makedirs(host(path))
112            except IOError, err:
113                raise error.general('cannot make directory: %s' % (path))
114            except OSError, err:
115                raise error.general('cannot make directory: %s' % (path))
116            except WindowsError, err:
117                raise error.general('cannot make directory: %s' % (path))
118        else:
119            try:
120                os.makedirs(host(path))
121            except IOError, err:
122                raise error.general('cannot make directory: %s' % (path))
123            except OSError, err:
124                raise error.general('cannot make directory: %s' % (path))
125
126def removeall(path):
127
128    def _onerror(function, path, excinfo):
129        print 'removeall error: (%s) %s' % (excinfo, path)
130
131    path = host(path)
132    shutil.rmtree(path, onerror = _onerror)
133    return
134
135def expand(name, paths):
136    l = []
137    for p in paths:
138        l += [join(p, name)]
139    return l
140
141def copy_tree(src, dst):
142    hsrc = host(src)
143    hdst = host(dst)
144
145    names = os.listdir(src)
146
147    if not os.path.isdir(dst):
148        os.makedirs(dst)
149
150    for name in names:
151        srcname = os.path.join(src, name)
152        dstname = os.path.join(dst, name)
153        try:
154            if os.path.islink(srcname):
155                linkto = os.readlink(srcname)
156                os.symlink(linkto, dstname)
157            elif os.path.isdir(srcname):
158                copy_tree(srcname, dstname)
159            else:
160                shutil.copy2(srcname, dstname)
161        except shutil.Error, err:
162            raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(err)))
163        except EnvironmentError, why:
164            raise error.general('copying tree: %s -> %s: %s' % (srcname, dstname, str(why)))
165    try:
166        shutil.copystat(src, dst)
167    except OSError, why:
168        if WindowsError is not None and isinstance(why, WindowsError):
169            pass
170        else:
171            raise error.general('copying tree: %s -> %s: %s' % (src, dst, str(why)))
172
173if __name__ == '__main__':
174    print host('/a/b/c/d-e-f')
175    print host('//a/b//c/d-e-f')
176    print shell('/w/x/y/z')
177    print basename('/as/sd/df/fg/me.txt')
178    print dirname('/as/sd/df/fg/me.txt')
179    print join('/d', 'g', '/tyty/fgfg')
180    windows = True
181    print host('/a/b/c/d-e-f')
182    print host('//a/b//c/d-e-f')
183    print shell('/w/x/y/z')
184    print shell('w:/x/y/z')
185    print basename('x:/sd/df/fg/me.txt')
186    print dirname('x:/sd/df/fg/me.txt')
187    print join('s:/d/', '/g', '/tyty/fgfg')
Note: See TracBrowser for help on using the repository browser.