2 # SPDX-License-Identifier: LGPL-2.1-or-later
4 OUTFILE_HEADER
= """#!/usr/bin/env python3
5 # SPDX-License-Identifier: LGPL-2.1-or-later
9 # © 2017 Canonical Ltd.
10 # Author: Dan Streetman <dan.streetman@canonical.com>
13 # Use this only to (re-)create the test/sys-script.py script,
14 # after adding or modifying anything in the test/sys/ directory
35 def f(path, mode, contents):
36 with open(path, "wb") as f:
43 exit("Usage: {} <target dir>".format(sys.argv[0]))
45 if not os.path.isdir(sys.argv[1]):
46 exit("Target dir {} not found".format(sys.argv[1]))
50 if os.path.exists('sys'):
55 def handle_dir(outfile
, path
):
56 m
= os
.lstat(path
).st_mode
& 0o777
57 outfile
.write(f
"d('{path}', {m:#o})\n")
60 def handle_link(outfile
, path
):
61 src
= os
.readlink(path
)
62 outfile
.write(f
"l('{path}', '{src}')\n")
65 def escape_single_quotes(b
):
66 # remove the b'' wrapping each line repr
68 # python escapes all ' only if there are ' and " in the string
70 r
= r
.replace("'", r
"\'")
71 # return line with all ' escaped
75 def handle_file(outfile
, path
):
76 m
= os
.lstat(path
).st_mode
& 0o777
77 with
open(path
, "rb") as f
:
79 if b
.count(b
"\n") > 1:
80 r
= "\n".join( escape_single_quotes(l
) for l
in b
.split(b
"\n") )
84 outfile
.write(f
"f('{path}', {m:#o}, {r})\n")
87 def process_sysdir(outfile
):
88 for (dirpath
, dirnames
, filenames
) in os
.walk('sys'):
89 handle_dir(outfile
, dirpath
)
91 path
= os
.path
.join(dirpath
, d
)
92 if stat
.S_ISLNK(os
.lstat(path
).st_mode
):
93 handle_link(outfile
, path
)
95 path
= os
.path
.join(dirpath
, f
)
96 mode
= os
.lstat(path
).st_mode
97 if stat
.S_ISLNK(mode
):
98 handle_link(outfile
, path
)
99 elif stat
.S_ISREG(mode
):
100 handle_file(outfile
, path
)
103 def verify_dir(tmpd
, path_a
):
104 path_b
= os
.path
.join(tmpd
, path_a
)
105 mode_a
= os
.lstat(path_a
).st_mode
106 mode_b
= os
.lstat(path_b
).st_mode
107 if not stat
.S_ISDIR(mode_b
):
108 raise Exception("Not directory")
109 if (mode_a
& 0o777) != (mode_b
& 0o777):
110 raise Exception("Permissions mismatch")
113 def verify_link(tmpd
, path_a
):
114 path_b
= os
.path
.join(tmpd
, path_a
)
115 if not stat
.S_ISLNK(os
.lstat(path_b
).st_mode
):
116 raise Exception("Not symlink")
117 if os
.readlink(path_a
) != os
.readlink(path_b
):
118 raise Exception("Symlink dest mismatch")
121 def verify_file(tmpd
, path_a
):
122 path_b
= os
.path
.join(tmpd
, path_a
)
123 mode_a
= os
.lstat(path_a
).st_mode
124 mode_b
= os
.lstat(path_b
).st_mode
125 if not stat
.S_ISREG(mode_b
):
126 raise Exception("Not file")
127 if (mode_a
& 0o777) != (mode_b
& 0o777):
128 raise Exception("Permissions mismatch")
129 if not filecmp
.cmp(path_a
, path_b
, shallow
=False):
130 raise Exception("File contents mismatch")
133 def verify_script(tmpd
):
135 for (dirpath
, dirnames
, filenames
) in os
.walk("sys"):
139 verify_dir(tmpd
, path
)
141 path
= os
.path
.join(dirpath
, d
)
142 if stat
.S_ISLNK(os
.lstat(path
).st_mode
):
143 verify_link(tmpd
, path
)
145 path
= os
.path
.join(dirpath
, f
)
146 mode
= os
.lstat(path
).st_mode
147 if stat
.S_ISLNK(mode
):
148 verify_link(tmpd
, path
)
149 elif stat
.S_ISREG(mode
):
150 verify_file(tmpd
, path
)
152 print(f
'FAIL on "{path}"', file=sys
.stderr
)
155 exit('Nothing found!')
157 if __name__
== "__main__":
158 if len(sys
.argv
) < 2:
159 exit('Usage: create-sys-script.py /path/to/test/')
161 outfile
= os
.path
.abspath(os
.path
.dirname(sys
.argv
[0]) + '/sys-script.py')
162 print(f
'Creating {outfile} using contents of {sys.argv[1]}/sys')
164 os
.chdir(sys
.argv
[1])
166 with
open(outfile
, "w") as f
:
167 os
.chmod(outfile
, OUTFILE_MODE
)
168 f
.write(OUTFILE_HEADER
.replace(os
.path
.basename(sys
.argv
[0]),
169 os
.path
.basename(outfile
)))
170 f
.write(OUTFILE_FUNCS
)
171 f
.write(OUTFILE_MAIN
)
174 with tempfile
.TemporaryDirectory() as tmpd
:
175 print(f
'Recreating sys/ using {outfile} at {tmpd}')
176 subprocess
.check_call([outfile
, tmpd
])
179 print(f
'Verification successful, {outfile} is correct')