1 |
commit: 42238f4ff13ae6c75bc1925f366429a35c26317d |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon May 27 06:11:28 2019 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon May 27 07:39:39 2019 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/mirrorselect.git/commit/?id=42238f4f |
7 |
|
8 |
write_make_conf: support multi-line GENTOO_MIRRORS (bug 543814) |
9 |
|
10 |
Use shlex to support multi-line GENTOO_MIRRORS assignments. |
11 |
|
12 |
Bug: https://bugs.gentoo.org/543814 |
13 |
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> |
14 |
|
15 |
.gitignore | 1 - |
16 |
mirrorselect/configs.py | 33 +++++++++++++++++++++++++++------ |
17 |
setup.py | 37 ++++++++++++++++++------------------- |
18 |
tests/__init__.py | 0 |
19 |
tests/test_write_make_conf.py | 41 +++++++++++++++++++++++++++++++++++++++++ |
20 |
5 files changed, 86 insertions(+), 26 deletions(-) |
21 |
|
22 |
diff --git a/.gitignore b/.gitignore |
23 |
index f7a7e7e..8e480b9 100644 |
24 |
--- a/.gitignore |
25 |
+++ b/.gitignore |
26 |
@@ -1,6 +1,5 @@ |
27 |
*.py[co] |
28 |
testing* |
29 |
-test* |
30 |
*.geany |
31 |
build* |
32 |
.gitignore |
33 |
|
34 |
diff --git a/mirrorselect/configs.py b/mirrorselect/configs.py |
35 |
index 9fa4f2c..8c4b4df 100644 |
36 |
--- a/mirrorselect/configs.py |
37 |
+++ b/mirrorselect/configs.py |
38 |
@@ -4,7 +4,7 @@ |
39 |
"""Mirrorselect 2.x |
40 |
Tool for selecting Gentoo source and rsync mirrors. |
41 |
|
42 |
-Copyright 2005-2012 Gentoo Foundation |
43 |
+Copyright 2005-2019 Gentoo Authors |
44 |
|
45 |
Copyright (C) 2005 Colin Kingsley <tercel@g.o> |
46 |
Copyright (C) 2008 Zac Medico <zmedico@g.o> |
47 |
@@ -75,10 +75,32 @@ def write_make_conf(output, config_path, var, mirror_string): |
48 |
except IOError: |
49 |
lines = [] |
50 |
|
51 |
- regex = re.compile('^%s=.*' % var) |
52 |
- for line in lines: |
53 |
- if regex.match(line): |
54 |
- lines.remove(line) |
55 |
+ with open(config_path + '.backup', 'r') as f: |
56 |
+ lex = shlex.shlex(f, posix=True) |
57 |
+ lex.wordchars = string.digits + letters + r"~!@#$%*_\:;?,./-+{}" |
58 |
+ lex.quotes = "\"'" |
59 |
+ while True: |
60 |
+ key = lex.get_token() |
61 |
+ |
62 |
+ if key == var: |
63 |
+ begin_line = lex.lineno |
64 |
+ equ = lex.get_token() |
65 |
+ if equ is None: |
66 |
+ break |
67 |
+ if equ != '=': |
68 |
+ continue |
69 |
+ |
70 |
+ val = lex.get_token() |
71 |
+ if val is None: |
72 |
+ break |
73 |
+ end_line = lex.lineno |
74 |
+ |
75 |
+ new_lines = [] |
76 |
+ for index, line in enumerate(lines): |
77 |
+ if index < begin_line - 1 or index >= end_line - 1: |
78 |
+ new_lines.append(line) |
79 |
+ lines = new_lines |
80 |
+ break |
81 |
|
82 |
lines.append(mirror_string) |
83 |
|
84 |
@@ -92,7 +114,6 @@ def write_make_conf(output, config_path, var, mirror_string): |
85 |
config.close() |
86 |
|
87 |
output.print_info('Done.\n') |
88 |
- sys.exit(0) |
89 |
|
90 |
|
91 |
def write_repos_conf(output, config_path, var, value): |
92 |
|
93 |
diff --git a/setup.py b/setup.py |
94 |
index 919dcce..5571711 100755 |
95 |
--- a/setup.py |
96 |
+++ b/setup.py |
97 |
@@ -8,9 +8,11 @@ import re |
98 |
import sys |
99 |
from distutils import core, log |
100 |
from distutils.command.sdist import sdist |
101 |
+from distutils.core import Command |
102 |
|
103 |
import os |
104 |
import io |
105 |
+import unittest |
106 |
|
107 |
|
108 |
__version__ = os.getenv('VERSION', default=os.getenv('PVR', default='9999')) |
109 |
@@ -80,26 +82,23 @@ class x_sdist(sdist): |
110 |
sdist.finalize_options(self) |
111 |
|
112 |
|
113 |
-def load_test(): |
114 |
- """Only return the real test class if it's actually being run so that we |
115 |
- don't depend on snakeoil just to install.""" |
116 |
+class TestCommand(Command): |
117 |
+ user_options = [] |
118 |
|
119 |
- desc = "run the test suite" |
120 |
- if 'test' in sys.argv[1:]: |
121 |
- try: |
122 |
- from snakeoil import distutils_extensions |
123 |
- except ImportError: |
124 |
- sys.stderr.write("Error: We depend on dev-python/snakeoil ") |
125 |
- sys.stderr.write("to run tests.\n") |
126 |
- sys.exit(1) |
127 |
- class test(distutils_extensions.test): |
128 |
- description = desc |
129 |
- default_test_namespace = 'mirrorselect.test' |
130 |
- else: |
131 |
- class test(core.Command): |
132 |
- description = desc |
133 |
+ def initialize_options(self): |
134 |
+ pass |
135 |
+ |
136 |
+ def finalize_options(self): |
137 |
+ pass |
138 |
+ |
139 |
+ def run(self): |
140 |
+ suite = unittest.TestSuite() |
141 |
+ tests = unittest.defaultTestLoader.discover('tests') |
142 |
+ suite.addTests(tests) |
143 |
+ result = unittest.TextTestRunner(verbosity=2).run(suite) |
144 |
+ if result.errors or result.failures: |
145 |
+ raise SystemExit(1) |
146 |
|
147 |
- return test |
148 |
|
149 |
test_data = { |
150 |
'mirrorselect': [ |
151 |
@@ -125,7 +124,7 @@ core.setup( |
152 |
['mirrorselect.8']), |
153 |
), |
154 |
cmdclass={ |
155 |
- 'test': load_test(), |
156 |
+ 'test': TestCommand, |
157 |
'sdist': x_sdist, |
158 |
'set_version': set_version, |
159 |
}, |
160 |
|
161 |
diff --git a/tests/__init__.py b/tests/__init__.py |
162 |
new file mode 100644 |
163 |
index 0000000..e69de29 |
164 |
|
165 |
diff --git a/tests/test_write_make_conf.py b/tests/test_write_make_conf.py |
166 |
new file mode 100644 |
167 |
index 0000000..3dedd93 |
168 |
--- /dev/null |
169 |
+++ b/tests/test_write_make_conf.py |
170 |
@@ -0,0 +1,41 @@ |
171 |
+# Copyright 2019 Gentoo Authors |
172 |
+ |
173 |
+import os |
174 |
+import shutil |
175 |
+import tempfile |
176 |
+import unittest |
177 |
+ |
178 |
+from mirrorselect.configs import write_make_conf |
179 |
+from mirrorselect.output import Output |
180 |
+ |
181 |
+ |
182 |
+class WriteMakeConfTestCase(unittest.TestCase): |
183 |
+ def test_write_make_conf(self): |
184 |
+ |
185 |
+ var = 'GENTOO_MIRRORS' |
186 |
+ mirror_string = '{}="a b"'.format(var) |
187 |
+ |
188 |
+ cases = ( |
189 |
+ ('{}="foo\nbar"\n'.format(var), '{}\n'.format(mirror_string)), |
190 |
+ ('\n{}="foo\nbar"\n'.format(var), '\n{}\n'.format(mirror_string)), |
191 |
+ ('\n{}="foo bar"\n'.format(var), '\n{}\n'.format(mirror_string)), |
192 |
+ ('\n{}="foo bar"\n\n'.format(var), '\n\n{}\n'.format(mirror_string)), |
193 |
+ ('\n{}="foo \\\nbar"\n'.format(var), '\n{}\n'.format(mirror_string)), |
194 |
+ ('\n\n{}="foo \\\nbar"\n'.format(var), '\n\n{}\n'.format(mirror_string)), |
195 |
+ ('\n\n{}="foo \\\nbar"\na="b"\n'.format(var), '\n\na="b"\n{}\n'.format(mirror_string)), |
196 |
+ ) |
197 |
+ |
198 |
+ for make_conf, expected_result in cases: |
199 |
+ tempdir = tempfile.mkdtemp() |
200 |
+ status_output = open(os.devnull, 'w') |
201 |
+ try: |
202 |
+ config_path = os.path.join(tempdir, 'make.conf') |
203 |
+ with open(config_path, 'wt') as f: |
204 |
+ f.write(make_conf) |
205 |
+ write_make_conf(Output(out=status_output), config_path, var, mirror_string) |
206 |
+ with open(config_path, 'rt') as f: |
207 |
+ result = f.read() |
208 |
+ self.assertEqual(result, expected_result) |
209 |
+ finally: |
210 |
+ shutil.rmtree(tempdir) |
211 |
+ status_output.close() |