1 |
# ***** BEGIN LICENSE BLOCK ***** |
2 |
# Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
3 |
# |
4 |
# The contents of this file are subject to the Mozilla Public License Version |
5 |
# 1.1 (the "License"); you may not use this file except in compliance with |
6 |
# the License. You may obtain a copy of the License at |
7 |
# http://www.mozilla.org/MPL/ |
8 |
# |
9 |
# Software distributed under the License is distributed on an "AS IS" basis, |
10 |
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
11 |
# for the specific language governing rights and limitations under the |
12 |
# License. |
13 |
# |
14 |
# The Original Code is Mozilla. |
15 |
# |
16 |
# The Initial Developer of the Original Code is |
17 |
# the Mozilla Foundation. |
18 |
# Portions created by the Initial Developer are Copyright (C) 2007 |
19 |
# the Initial Developer. All Rights Reserved. |
20 |
# |
21 |
# Contributor(s): |
22 |
# Axel Hecht <axel@pike.org> |
23 |
# |
24 |
# Alternatively, the contents of this file may be used under the terms of |
25 |
# either the GNU General Public License Version 2 or later (the "GPL"), or |
26 |
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
27 |
# in which case the provisions of the GPL or the LGPL are applicable instead |
28 |
# of those above. If you wish to allow use of your version of this file only |
29 |
# under the terms of either the GPL or the LGPL, and not to allow others to |
30 |
# use your version of this file under the terms of the MPL, indicate your |
31 |
# decision by deleting the provisions above and replace them with the notice |
32 |
# and other provisions required by the GPL or the LGPL. If you do not delete |
33 |
# the provisions above, a recipient may use your version of this file under |
34 |
# the terms of any one of the MPL, the GPL or the LGPL. |
35 |
# |
36 |
# ***** END LICENSE BLOCK ***** |
37 |
|
38 |
# This is a partial python port of nsinstall. |
39 |
# It's intended to be used when there's no natively compile nsinstall |
40 |
# available, and doesn't intend to be fully equivalent. |
41 |
# Its major use is for l10n repackaging on systems that don't have |
42 |
# a full build environment set up. |
43 |
# The basic limitation is, it doesn't even try to link and ignores |
44 |
# all related options. |
45 |
|
46 |
from optparse import OptionParser |
47 |
import os |
48 |
import os.path |
49 |
import sys |
50 |
import shutil |
51 |
|
52 |
def nsinstall(argv): |
53 |
usage = "usage: %prog [options] arg1 [arg2 ...] target-directory" |
54 |
p = OptionParser(usage=usage) |
55 |
|
56 |
p.add_option('-D', action="store_true", |
57 |
help="Create a single directory only") |
58 |
p.add_option('-t', action="store_true", |
59 |
help="Preserve time stamp") |
60 |
p.add_option('-m', action="store", |
61 |
help="Set mode", metavar="mode") |
62 |
p.add_option('-d', action="store_true", |
63 |
help="Create directories in target") |
64 |
p.add_option('-R', action="store_true", |
65 |
help="Use relative symbolic links (ignored)") |
66 |
p.add_option('-l', action="store_true", |
67 |
help="Create link (ignored)") |
68 |
p.add_option('-L', action="store", metavar="linkprefix", |
69 |
help="Link prefix (ignored)") |
70 |
|
71 |
# The remaining arguments are not used in our tree, thus they're not |
72 |
# implented. |
73 |
def BadArg(option, opt, value, parser): |
74 |
parser.error('option not supported: %s' % opt) |
75 |
|
76 |
p.add_option('-C', action="callback", metavar="CWD", |
77 |
callback=BadArg, |
78 |
help="NOT SUPPORTED") |
79 |
p.add_option('-o', action="callback", callback=BadArg, |
80 |
help="Set owner (NOT SUPPORTED)", metavar="owner") |
81 |
p.add_option('-g', action="callback", callback=BadArg, |
82 |
help="Set group (NOT SUPPORTED)", metavar="group") |
83 |
|
84 |
(options, args) = p.parse_args(argv) |
85 |
|
86 |
if options.m: |
87 |
# mode is specified |
88 |
try: |
89 |
options.m = int(options.m, 8) |
90 |
except: |
91 |
sys.stderr.write('nsinstall: ' + options.m + ' is not a valid mode\n') |
92 |
return 1 |
93 |
|
94 |
# just create one directory? |
95 |
if options.D: |
96 |
if len(args) != 1: |
97 |
return 1 |
98 |
if os.path.exists(args[0]): |
99 |
if not os.path.isdir(args[0]): |
100 |
sys.stderr.write('nsinstall: ' + args[0] + ' is not a directory\n') |
101 |
sys.exit(1) |
102 |
if options.m: |
103 |
os.chmod(args[0], options.m) |
104 |
sys.exit() |
105 |
if options.m: |
106 |
os.makedirs(args[0], options.m) |
107 |
else: |
108 |
os.makedirs(args[0]) |
109 |
return 0 |
110 |
|
111 |
# nsinstall arg1 [...] directory |
112 |
if len(args) < 2: |
113 |
p.error('not enough arguments') |
114 |
|
115 |
def copy_all_entries(entries, target): |
116 |
for e in entries: |
117 |
dest = os.path.join(target, |
118 |
os.path.basename(os.path.normpath(e))) |
119 |
handleTarget(e, dest) |
120 |
if options.m: |
121 |
os.chmod(dest, options.m) |
122 |
|
123 |
# set up handler |
124 |
if options.d: |
125 |
# we're supposed to create directories |
126 |
def handleTarget(srcpath, targetpath): |
127 |
# target directory was already created, just use mkdir |
128 |
os.mkdir(targetpath) |
129 |
else: |
130 |
# we're supposed to copy files |
131 |
def handleTarget(srcpath, targetpath): |
132 |
if os.path.isdir(srcpath): |
133 |
if not os.path.exists(targetpath): |
134 |
os.mkdir(targetpath) |
135 |
entries = [os.path.join(srcpath, e) for e in os.listdir(srcpath)] |
136 |
copy_all_entries(entries, targetpath) |
137 |
# options.t is not relevant for directories |
138 |
if options.m: |
139 |
os.chmod(targetpath, options.m) |
140 |
elif options.t: |
141 |
shutil.copy2(srcpath, targetpath) |
142 |
else: |
143 |
shutil.copy(srcpath, targetpath) |
144 |
|
145 |
# the last argument is the target directory |
146 |
target = args.pop() |
147 |
# ensure target directory |
148 |
if not os.path.isdir(target): |
149 |
os.makedirs(target) |
150 |
|
151 |
copy_all_entries(args, target) |
152 |
return 0 |
153 |
|
154 |
if __name__ == '__main__': |
155 |
sys.exit(nsinstall(sys.argv[1:])) |