Merge lp:~teknico/charm-helpers/lint-fixes into lp:charm-helpers
- lint-fixes
- Merge into devel
Proposed by
Nicola Larosa
Status: | Merged |
---|---|
Merge reported by: | James Page |
Merged at revision: | not available |
Proposed branch: | lp:~teknico/charm-helpers/lint-fixes |
Merge into: | lp:charm-helpers |
Diff against target: |
1224 lines (+172/-156) 22 files modified
README.test (+3/-0) bin/contrib/saltstack/salt-call (+3/-2) charmhelpers/cli/commands.py (+2/-2) charmhelpers/cli/host.py (+2/-1) charmhelpers/core/hookenv.py (+33/-32) charmhelpers/core/host.py (+19/-19) charmhelpers/fetch/__init__.py (+18/-16) charmhelpers/fetch/archiveurl.py (+5/-4) charmhelpers/fetch/bzrurl.py (+9/-7) charmhelpers/payload/__init__.py (+3/-1) charmhelpers/payload/archive.py (+3/-2) charmhelpers/payload/execd.py (+2/-1) tests/contrib/hahelpers/test_ceph_utils.py (+3/-3) tests/core/test_hookenv.py (+4/-4) tests/core/test_host.py (+7/-6) tests/fetch/test_archiveurl.py (+4/-2) tests/fetch/test_bzrurl.py (+3/-5) tests/fetch/test_fetch.py (+12/-14) tests/payload/test_archive.py (+6/-4) tests/payload/test_execd.py (+6/-4) tests/tools/test_charm_helper_sync.py (+19/-19) tools/charm_helpers_sync/charm_helpers_sync.py (+6/-8) |
To merge this branch: | bzr merge lp:~teknico/charm-helpers/lint-fixes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Page | Abstain | ||
Matthew Wedgwood | Pending | ||
Review via email: mp+181859@code.launchpad.net |
Commit message
Description of the change
Lint and styling fixes. Sorry for the diff size.
To post a comment you must log in.
- 74. By Nicola Larosa
-
Merge from trunk, one conflict resolved.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'README.test' |
2 | --- README.test 2013-05-22 21:11:01 +0000 |
3 | +++ README.test 2013-09-02 08:01:21 +0000 |
4 | @@ -1,7 +1,10 @@ |
5 | Required Packages for Running Tests |
6 | ----------------------------------- |
7 | + |
8 | python-shelltoolbox |
9 | python-tempita |
10 | python-nose |
11 | python-mock |
12 | python-testtools |
13 | + |
14 | +Also, install flake8 from PyPI. |
15 | |
16 | === modified file 'bin/contrib/saltstack/salt-call' |
17 | --- bin/contrib/saltstack/salt-call 2013-06-19 09:54:19 +0000 |
18 | +++ bin/contrib/saltstack/salt-call 2013-09-02 08:01:21 +0000 |
19 | @@ -1,8 +1,9 @@ |
20 | #!/usr/bin/env python |
21 | -''' |
22 | + |
23 | +""" |
24 | Directly call a salt command in the modules, does not require a running salt |
25 | minion to run. |
26 | -''' |
27 | +""" |
28 | |
29 | from salt.scripts import salt_call |
30 | |
31 | |
32 | === modified file 'charmhelpers/cli/commands.py' |
33 | --- charmhelpers/cli/commands.py 2013-06-19 23:00:23 +0000 |
34 | +++ charmhelpers/cli/commands.py 2013-09-02 08:01:21 +0000 |
35 | @@ -1,2 +1,2 @@ |
36 | -from . import CommandLine |
37 | -import host |
38 | +# from . import CommandLine |
39 | +# import host |
40 | |
41 | === modified file 'charmhelpers/cli/host.py' |
42 | --- charmhelpers/cli/host.py 2013-06-20 15:03:24 +0000 |
43 | +++ charmhelpers/cli/host.py 2013-09-02 08:01:21 +0000 |
44 | @@ -4,9 +4,10 @@ |
45 | |
46 | @cmdline.subcommand() |
47 | def mounts(): |
48 | - "List mounts" |
49 | + """List mounts.""" |
50 | return host.mounts() |
51 | |
52 | + |
53 | @cmdline.subcommand_builder('service', description="Control system services") |
54 | def service(subparser): |
55 | subparser.add_argument("action", help="The action to perform (start, stop, etc...)") |
56 | |
57 | === modified file 'charmhelpers/core/hookenv.py' |
58 | --- charmhelpers/core/hookenv.py 2013-07-18 16:13:49 +0000 |
59 | +++ charmhelpers/core/hookenv.py 2013-09-02 08:01:21 +0000 |
60 | @@ -1,14 +1,15 @@ |
61 | -"Interactions with the Juju environment" |
62 | # Copyright 2013 Canonical Ltd. |
63 | # |
64 | # Authors: |
65 | # Charm Helpers Developers <juju@lists.ubuntu.com> |
66 | |
67 | +"""Interactions with the Juju environment.""" |
68 | + |
69 | +import json |
70 | import os |
71 | -import json |
72 | -import yaml |
73 | import subprocess |
74 | import UserDict |
75 | +import yaml |
76 | |
77 | CRITICAL = "CRITICAL" |
78 | ERROR = "ERROR" |
79 | @@ -21,7 +22,8 @@ |
80 | |
81 | |
82 | def cached(func): |
83 | - ''' Cache return values for multiple executions of func + args |
84 | + """ |
85 | + Decorator that caches return values for multiple executions of func + args. |
86 | |
87 | For example: |
88 | |
89 | @@ -32,7 +34,7 @@ |
90 | unit_get('test') |
91 | |
92 | will cache the result of unit_get + 'test' for future calls. |
93 | - ''' |
94 | + """ |
95 | def wrapper(*args, **kwargs): |
96 | global cache |
97 | key = str((func, args, kwargs)) |
98 | @@ -46,8 +48,8 @@ |
99 | |
100 | |
101 | def flush(key): |
102 | - ''' Flushes any entries from function cache where the |
103 | - key is found in the function+args ''' |
104 | + """Flush any entries from function cache where the |
105 | + key is found in the function+args.""" |
106 | flush_list = [] |
107 | for item in cache: |
108 | if key in item: |
109 | @@ -57,7 +59,7 @@ |
110 | |
111 | |
112 | def log(message, level=None): |
113 | - "Write a message to the juju log" |
114 | + """Write a message to the juju log.""" |
115 | command = ['juju-log'] |
116 | if level: |
117 | command += ['-l', level] |
118 | @@ -66,7 +68,7 @@ |
119 | |
120 | |
121 | class Serializable(UserDict.IterableUserDict): |
122 | - "Wrapper, an object that can be serialized to yaml or json" |
123 | + """Wrapper, an object that can be serialized to yaml or json.""" |
124 | |
125 | def __init__(self, obj): |
126 | # wrap the object |
127 | @@ -96,16 +98,16 @@ |
128 | self.data = state |
129 | |
130 | def json(self): |
131 | - "Serialize the object to json" |
132 | + """Serialize the object to json.""" |
133 | return json.dumps(self.data) |
134 | |
135 | def yaml(self): |
136 | - "Serialize the object to yaml" |
137 | + """Serialize the object to yaml.""" |
138 | return yaml.dump(self.data) |
139 | |
140 | |
141 | def execution_environment(): |
142 | - """A convenient bundling of the current execution context""" |
143 | + """A convenient bundling of the current execution context.""" |
144 | context = {} |
145 | context['conf'] = config() |
146 | if relation_id(): |
147 | @@ -119,38 +121,38 @@ |
148 | |
149 | |
150 | def in_relation_hook(): |
151 | - "Determine whether we're running in a relation hook" |
152 | + """Determine whether we're running in a relation hook.""" |
153 | return 'JUJU_RELATION' in os.environ |
154 | |
155 | |
156 | def relation_type(): |
157 | - "The scope for the current relation hook" |
158 | + """The scope for the current relation hook.""" |
159 | return os.environ.get('JUJU_RELATION', None) |
160 | |
161 | |
162 | def relation_id(): |
163 | - "The relation ID for the current relation hook" |
164 | + """The relation ID for the current relation hook.""" |
165 | return os.environ.get('JUJU_RELATION_ID', None) |
166 | |
167 | |
168 | def local_unit(): |
169 | - "Local unit ID" |
170 | + """Local unit ID.""" |
171 | return os.environ['JUJU_UNIT_NAME'] |
172 | |
173 | |
174 | def remote_unit(): |
175 | - "The remote unit for the current relation hook" |
176 | + """The remote unit for the current relation hook.""" |
177 | return os.environ['JUJU_REMOTE_UNIT'] |
178 | |
179 | |
180 | def service_name(): |
181 | - "The name service group this unit belongs to" |
182 | + """The name service group this unit belongs to.""" |
183 | return local_unit().split('/')[0] |
184 | |
185 | |
186 | @cached |
187 | def config(scope=None): |
188 | - "Juju charm configuration" |
189 | + """Juju charm configuration.""" |
190 | config_cmd_line = ['config-get'] |
191 | if scope is not None: |
192 | config_cmd_line.append(scope) |
193 | @@ -192,7 +194,7 @@ |
194 | |
195 | @cached |
196 | def relation_ids(reltype=None): |
197 | - "A list of relation_ids" |
198 | + """A list of relation_ids.""" |
199 | reltype = reltype or relation_type() |
200 | relid_cmd_line = ['relation-ids', '--format=json'] |
201 | if reltype is not None: |
202 | @@ -203,7 +205,7 @@ |
203 | |
204 | @cached |
205 | def related_units(relid=None): |
206 | - "A list of related units" |
207 | + """A list of related units.""" |
208 | relid = relid or relation_id() |
209 | units_cmd_line = ['relation-list', '--format=json'] |
210 | if relid is not None: |
211 | @@ -213,7 +215,7 @@ |
212 | |
213 | @cached |
214 | def relation_for_unit(unit=None, rid=None): |
215 | - "Get the json represenation of a unit's relation" |
216 | + """Get the json represenation of a unit's relation.""" |
217 | unit = unit or remote_unit() |
218 | relation = relation_get(unit=unit, rid=rid) |
219 | for key in relation: |
220 | @@ -225,7 +227,7 @@ |
221 | |
222 | @cached |
223 | def relations_for_id(relid=None): |
224 | - "Get relations of a specific relation ID" |
225 | + """Get relations of a specific relation ID.""" |
226 | relation_data = [] |
227 | relid = relid or relation_ids() |
228 | for unit in related_units(relid): |
229 | @@ -237,7 +239,7 @@ |
230 | |
231 | @cached |
232 | def relations_of_type(reltype=None): |
233 | - "Get relations of a specific type" |
234 | + """Get relations of a specific type.""" |
235 | relation_data = [] |
236 | reltype = reltype or relation_type() |
237 | for relid in relation_ids(reltype): |
238 | @@ -249,7 +251,7 @@ |
239 | |
240 | @cached |
241 | def relation_types(): |
242 | - "Get a list of relation types supported by this charm" |
243 | + """Get a list of relation types supported by this charm.""" |
244 | charmdir = os.environ.get('CHARM_DIR', '') |
245 | mdf = open(os.path.join(charmdir, 'metadata.yaml')) |
246 | md = yaml.safe_load(mdf) |
247 | @@ -278,14 +280,14 @@ |
248 | |
249 | |
250 | def open_port(port, protocol="TCP"): |
251 | - "Open a service network port" |
252 | + """Open a service network port.""" |
253 | _args = ['open-port'] |
254 | _args.append('{}/{}'.format(port, protocol)) |
255 | subprocess.check_call(_args) |
256 | |
257 | |
258 | def close_port(port, protocol="TCP"): |
259 | - "Close a service network port" |
260 | + """Close a service network port.""" |
261 | _args = ['close-port'] |
262 | _args.append('{}/{}'.format(port, protocol)) |
263 | subprocess.check_call(_args) |
264 | @@ -327,11 +329,10 @@ |
265 | def wrapper(decorated): |
266 | for hook_name in hook_names: |
267 | self.register(hook_name, decorated) |
268 | - else: |
269 | - self.register(decorated.__name__, decorated) |
270 | - if '_' in decorated.__name__: |
271 | - self.register( |
272 | - decorated.__name__.replace('_', '-'), decorated) |
273 | + self.register(decorated.__name__, decorated) |
274 | + if '_' in decorated.__name__: |
275 | + self.register( |
276 | + decorated.__name__.replace('_', '-'), decorated) |
277 | return decorated |
278 | return wrapper |
279 | |
280 | |
281 | === modified file 'charmhelpers/core/host.py' |
282 | --- charmhelpers/core/host.py 2013-08-23 16:42:43 +0000 |
283 | +++ charmhelpers/core/host.py 2013-09-02 08:01:21 +0000 |
284 | @@ -1,19 +1,19 @@ |
285 | -"""Tools for working with the host system""" |
286 | # Copyright 2012 Canonical Ltd. |
287 | # |
288 | # Authors: |
289 | # Nick Moffitt <nick.moffitt@canonical.com> |
290 | # Matthew Wedgwood <matthew.wedgwood@canonical.com> |
291 | |
292 | +"""Tools for working with the host system.""" |
293 | + |
294 | +from collections import OrderedDict |
295 | +import grp |
296 | +import hashlib |
297 | import os |
298 | import pwd |
299 | -import grp |
300 | import random |
301 | import string |
302 | import subprocess |
303 | -import hashlib |
304 | - |
305 | -from collections import OrderedDict |
306 | |
307 | from hookenv import log |
308 | |
309 | @@ -55,7 +55,7 @@ |
310 | |
311 | |
312 | def adduser(username, password=None, shell='/bin/bash', system_user=False): |
313 | - """Add a user""" |
314 | + """Add a user.""" |
315 | try: |
316 | user_info = pwd.getpwnam(username) |
317 | log('user {0} already exists!'.format(username)) |
318 | @@ -77,7 +77,7 @@ |
319 | |
320 | |
321 | def add_user_to_group(username, group): |
322 | - """Add a user to a group""" |
323 | + """Add a user to a group.""" |
324 | cmd = [ |
325 | 'gpasswd', '-a', |
326 | username, |
327 | @@ -88,7 +88,7 @@ |
328 | |
329 | |
330 | def rsync(from_path, to_path, flags='-r', options=None): |
331 | - """Replicate the contents of a path""" |
332 | + """Replicate the contents of a path.""" |
333 | options = options or ['--delete', '--executability'] |
334 | cmd = ['/usr/bin/rsync', flags] |
335 | cmd.extend(options) |
336 | @@ -99,7 +99,7 @@ |
337 | |
338 | |
339 | def symlink(source, destination): |
340 | - """Create a symbolic link""" |
341 | + """Create a symbolic link.""" |
342 | log("Symlinking {} as {}".format(source, destination)) |
343 | cmd = [ |
344 | 'ln', |
345 | @@ -111,7 +111,7 @@ |
346 | |
347 | |
348 | def mkdir(path, owner='root', group='root', perms=0555, force=False): |
349 | - """Create a directory""" |
350 | + """Create a directory.""" |
351 | log("Making dir {} {}:{} {:o}".format(path, owner, group, |
352 | perms)) |
353 | uid = pwd.getpwnam(owner).pw_uid |
354 | @@ -127,7 +127,7 @@ |
355 | |
356 | |
357 | def write_file(path, content, owner='root', group='root', perms=0444): |
358 | - """Create or overwrite a file with the contents of a string""" |
359 | + """Create or overwrite a file with the contents of a string.""" |
360 | log("Writing file {} {}:{} {:o}".format(path, owner, group, perms)) |
361 | uid = pwd.getpwnam(owner).pw_uid |
362 | gid = grp.getgrnam(group).gr_gid |
363 | @@ -138,7 +138,7 @@ |
364 | |
365 | |
366 | def mount(device, mountpoint, options=None, persist=False): |
367 | - '''Mount a filesystem''' |
368 | + """Mount a filesystem.""" |
369 | cmd_args = ['mount'] |
370 | if options is not None: |
371 | cmd_args.extend(['-o', options]) |
372 | @@ -155,7 +155,7 @@ |
373 | |
374 | |
375 | def umount(mountpoint, persist=False): |
376 | - '''Unmount a filesystem''' |
377 | + """Unmount a filesystem.""" |
378 | cmd_args = ['umount', mountpoint] |
379 | try: |
380 | subprocess.check_output(cmd_args) |
381 | @@ -169,7 +169,7 @@ |
382 | |
383 | |
384 | def mounts(): |
385 | - '''List of all mounted volumes as [[mountpoint,device],[...]]''' |
386 | + """List of all mounted volumes as [[mountpoint,device],[...]].""" |
387 | with open('/proc/mounts') as f: |
388 | # [['/mount/point','/dev/path'],[...]] |
389 | system_mounts = [m[1::-1] for m in [l.strip().split() |
390 | @@ -178,7 +178,7 @@ |
391 | |
392 | |
393 | def file_hash(path): |
394 | - ''' Generate a md5 hash of the contents of 'path' or None if not found ''' |
395 | + """Generate a md5 hash of the contents of 'path' or None if not found.""" |
396 | if os.path.exists(path): |
397 | h = hashlib.md5() |
398 | with open(path, 'r') as source: |
399 | @@ -189,7 +189,7 @@ |
400 | |
401 | |
402 | def restart_on_change(restart_map): |
403 | - ''' Restart services based on configuration files changing |
404 | + """Restart services based on configuration files changing. |
405 | |
406 | This function is used a decorator, for example |
407 | |
408 | @@ -202,7 +202,7 @@ |
409 | In this example, the cinder-api and cinder-volume services |
410 | would be restarted if /etc/ceph/ceph.conf is changed by the |
411 | ceph_client_changed function. |
412 | - ''' |
413 | + """ |
414 | def wrap(f): |
415 | def wrapped_f(*args): |
416 | checksums = {} |
417 | @@ -220,7 +220,7 @@ |
418 | |
419 | |
420 | def lsb_release(): |
421 | - '''Return /etc/lsb-release in a dict''' |
422 | + """Return /etc/lsb-release in a dict.""" |
423 | d = {} |
424 | with open('/etc/lsb-release', 'r') as lsb: |
425 | for l in lsb: |
426 | @@ -230,7 +230,7 @@ |
427 | |
428 | |
429 | def pwgen(length=None): |
430 | - '''Generate a random pasword.''' |
431 | + """Generate a random password.""" |
432 | if length is None: |
433 | length = random.choice(range(35, 45)) |
434 | alphanumeric_chars = [ |
435 | |
436 | === modified file 'charmhelpers/fetch/__init__.py' |
437 | --- charmhelpers/fetch/__init__.py 2013-08-21 11:45:37 +0000 |
438 | +++ charmhelpers/fetch/__init__.py 2013-09-02 08:01:21 +0000 |
439 | @@ -1,18 +1,19 @@ |
440 | import importlib |
441 | -from yaml import safe_load |
442 | -from charmhelpers.core.host import ( |
443 | - lsb_release |
444 | -) |
445 | +import subprocess |
446 | from urlparse import ( |
447 | urlparse, |
448 | urlunparse, |
449 | ) |
450 | -import subprocess |
451 | + |
452 | +import apt_pkg |
453 | +from yaml import safe_load |
454 | + |
455 | from charmhelpers.core.hookenv import ( |
456 | config, |
457 | log, |
458 | ) |
459 | -import apt_pkg |
460 | +from charmhelpers.core.host import lsb_release |
461 | + |
462 | |
463 | CLOUD_ARCHIVE = """# Ubuntu Cloud Archive |
464 | deb http://ubuntu-cloud.archive.canonical.com/ubuntu {} main |
465 | @@ -23,7 +24,7 @@ |
466 | |
467 | |
468 | def filter_installed_packages(packages): |
469 | - """Returns a list of packages that require installation""" |
470 | + """Return a list of packages that require installation.""" |
471 | apt_pkg.init() |
472 | cache = apt_pkg.Cache() |
473 | _pkgs = [] |
474 | @@ -39,7 +40,7 @@ |
475 | |
476 | |
477 | def apt_install(packages, options=None, fatal=False): |
478 | - """Install one or more packages""" |
479 | + """Install one or more packages.""" |
480 | options = options or [] |
481 | cmd = ['apt-get', '-y'] |
482 | cmd.extend(options) |
483 | @@ -57,7 +58,7 @@ |
484 | |
485 | |
486 | def apt_update(fatal=False): |
487 | - """Update local apt cache""" |
488 | + """Update local apt cache.""" |
489 | cmd = ['apt-get', 'update'] |
490 | if fatal: |
491 | subprocess.check_call(cmd) |
492 | @@ -66,7 +67,7 @@ |
493 | |
494 | |
495 | def apt_purge(packages, fatal=False): |
496 | - """Purge one or more packages""" |
497 | + """Purge one or more packages.""" |
498 | cmd = ['apt-get', '-y', 'purge'] |
499 | if isinstance(packages, basestring): |
500 | cmd.append(packages) |
501 | @@ -105,7 +106,7 @@ |
502 | sources_var='install_sources', |
503 | keys_var='install_keys'): |
504 | """ |
505 | - Configure multiple sources from charm configuration |
506 | + Configure multiple sources from charm configuration. |
507 | |
508 | Example config: |
509 | install_sources: |
510 | @@ -144,13 +145,14 @@ |
511 | |
512 | def install_remote(source): |
513 | """ |
514 | - Install a file tree from a remote source |
515 | + Install a file tree from a remote source. |
516 | |
517 | The specified source should be a url of the form: |
518 | scheme://[host]/path[#[option=value][&...]] |
519 | |
520 | - Schemes supported are based on this modules submodules |
521 | - Options supported are submodule-specific""" |
522 | + Schemes supported are based on this modules submodules. |
523 | + Options supported are submodule-specific. |
524 | + """ |
525 | # We ONLY check for True here because can_handle may return a string |
526 | # explaining why it can't handle a given source. |
527 | handlers = [h for h in plugins() if h.can_handle(source) is True] |
528 | @@ -172,7 +174,7 @@ |
529 | |
530 | |
531 | class BaseFetchHandler(object): |
532 | - """Base class for FetchHandler implementations in fetch plugins""" |
533 | + """Base class for FetchHandler implementations in fetch plugins.""" |
534 | def can_handle(self, source): |
535 | """Returns True if the source can be handled. Otherwise returns |
536 | a string explaining why it cannot""" |
537 | @@ -187,7 +189,7 @@ |
538 | return urlparse(url) |
539 | |
540 | def base_url(self, url): |
541 | - """Return url without querystring or fragment""" |
542 | + """Return url without querystring or fragment.""" |
543 | parts = list(self.parse_url(url)) |
544 | parts[4:] = ['' for i in parts[4:]] |
545 | return urlunparse(parts) |
546 | |
547 | === modified file 'charmhelpers/fetch/archiveurl.py' |
548 | --- charmhelpers/fetch/archiveurl.py 2013-07-10 18:57:39 +0000 |
549 | +++ charmhelpers/fetch/archiveurl.py 2013-09-02 08:01:21 +0000 |
550 | @@ -1,5 +1,7 @@ |
551 | import os |
552 | import urllib2 |
553 | + |
554 | +from charmhelpers.core.host import mkdir |
555 | from charmhelpers.fetch import ( |
556 | BaseFetchHandler, |
557 | UnhandledSource |
558 | @@ -8,11 +10,11 @@ |
559 | get_archive_handler, |
560 | extract, |
561 | ) |
562 | -from charmhelpers.core.host import mkdir |
563 | |
564 | |
565 | class ArchiveUrlFetchHandler(BaseFetchHandler): |
566 | - """Handler for archives via generic URLs""" |
567 | + """Handler for archives via generic URLs.""" |
568 | + |
569 | def can_handle(self, source): |
570 | url_parts = self.parse_url(source) |
571 | if url_parts.scheme not in ('http', 'https', 'ftp', 'file'): |
572 | @@ -22,8 +24,7 @@ |
573 | return False |
574 | |
575 | def download(self, source, dest): |
576 | - # propogate all exceptions |
577 | - # URLError, OSError, etc |
578 | + # Propagate all exceptions: URLError, OSError, etc. |
579 | response = urllib2.urlopen(source) |
580 | try: |
581 | with open(dest, 'w') as dest_file: |
582 | |
583 | === modified file 'charmhelpers/fetch/bzrurl.py' |
584 | --- charmhelpers/fetch/bzrurl.py 2013-08-22 10:19:51 +0000 |
585 | +++ charmhelpers/fetch/bzrurl.py 2013-09-02 08:01:21 +0000 |
586 | @@ -1,10 +1,10 @@ |
587 | import os |
588 | + |
589 | +from charmhelpers.core.host import mkdir |
590 | from charmhelpers.fetch import ( |
591 | BaseFetchHandler, |
592 | UnhandledSource |
593 | ) |
594 | -from charmhelpers.core.host import mkdir |
595 | - |
596 | try: |
597 | from bzrlib.branch import Branch |
598 | except ImportError: |
599 | @@ -12,8 +12,10 @@ |
600 | apt_install("python-bzrlib") |
601 | from bzrlib.branch import Branch |
602 | |
603 | + |
604 | class BzrUrlFetchHandler(BaseFetchHandler): |
605 | - """Handler for bazaar branches via generic and lp URLs""" |
606 | + """Handler for bazaar branches via generic and lp URLs.""" |
607 | + |
608 | def can_handle(self, source): |
609 | url_parts = self.parse_url(source) |
610 | if url_parts.scheme not in ('bzr+ssh', 'lp'): |
611 | @@ -23,7 +25,7 @@ |
612 | |
613 | def branch(self, source, dest): |
614 | url_parts = self.parse_url(source) |
615 | - # If we use lp:branchname scheme we need to load plugins |
616 | + # If we use lp:branchname scheme we need to load plugins. |
617 | if not self.can_handle(source): |
618 | raise UnhandledSource("Cannot handle {}".format(source)) |
619 | if url_parts.scheme == "lp": |
620 | @@ -37,8 +39,9 @@ |
621 | |
622 | def install(self, source): |
623 | url_parts = self.parse_url(source) |
624 | - branch_name = url_parts.path.strip("/").split("/")[-1] |
625 | - dest_dir = os.path.join(os.environ.get('CHARM_DIR'), "fetched", branch_name) |
626 | + branch_name = url_parts.path.strip('/').split('/')[-1] |
627 | + dest_dir = os.path.join( |
628 | + os.environ.get('CHARM_DIR'), 'fetched', branch_name) |
629 | if not os.path.exists(dest_dir): |
630 | mkdir(dest_dir, perms=0755) |
631 | try: |
632 | @@ -46,4 +49,3 @@ |
633 | except OSError as e: |
634 | raise UnhandledSource(e.strerror) |
635 | return dest_dir |
636 | - |
637 | |
638 | === modified file 'charmhelpers/payload/__init__.py' |
639 | --- charmhelpers/payload/__init__.py 2013-05-18 23:25:48 +0000 |
640 | +++ charmhelpers/payload/__init__.py 2013-09-02 08:01:21 +0000 |
641 | @@ -1,1 +1,3 @@ |
642 | -"Tools for working with files injected into a charm just before deployment." |
643 | +""" |
644 | +Tools for working with files injected into a charm just before deployment. |
645 | +""" |
646 | |
647 | === modified file 'charmhelpers/payload/archive.py' |
648 | --- charmhelpers/payload/archive.py 2013-07-03 23:04:00 +0000 |
649 | +++ charmhelpers/payload/archive.py 2013-09-02 08:01:21 +0000 |
650 | @@ -1,6 +1,7 @@ |
651 | import os |
652 | import tarfile |
653 | import zipfile |
654 | + |
655 | from charmhelpers.core import ( |
656 | host, |
657 | hookenv, |
658 | @@ -46,12 +47,12 @@ |
659 | |
660 | |
661 | def extract_tarfile(archive_name, destpath): |
662 | - "Unpack a tar archive, optionally compressed" |
663 | + """Unpack a tar archive, optionally compressed.""" |
664 | archive = tarfile.open(archive_name) |
665 | archive.extractall(destpath) |
666 | |
667 | |
668 | def extract_zipfile(archive_name, destpath): |
669 | - "Unpack a zip file" |
670 | + """Unpack a zip file.""" |
671 | archive = zipfile.ZipFile(archive_name) |
672 | archive.extractall(destpath) |
673 | |
674 | === modified file 'charmhelpers/payload/execd.py' |
675 | --- charmhelpers/payload/execd.py 2013-06-07 12:34:25 +0000 |
676 | +++ charmhelpers/payload/execd.py 2013-09-02 08:01:21 +0000 |
677 | @@ -1,8 +1,9 @@ |
678 | #!/usr/bin/env python |
679 | |
680 | import os |
681 | +import subprocess |
682 | import sys |
683 | -import subprocess |
684 | + |
685 | from charmhelpers.core import hookenv |
686 | |
687 | |
688 | |
689 | === modified file 'tests/contrib/hahelpers/test_ceph_utils.py' |
690 | --- tests/contrib/hahelpers/test_ceph_utils.py 2013-08-13 01:12:03 +0000 |
691 | +++ tests/contrib/hahelpers/test_ceph_utils.py 2013-09-02 08:01:21 +0000 |
692 | @@ -126,6 +126,6 @@ |
693 | fstype = 'xfs' |
694 | ceph_utils.make_filesystem(device, fstype) |
695 | self.check_call.assert_called_with(['mkfs', '-t', fstype, device]) |
696 | - self.log.assert_called_with('ceph: Formatting block device %s as ' |
697 | - 'filesystem %s.' % (device, fstype), level='INFO') |
698 | - |
699 | + self.log.assert_called_with( |
700 | + 'ceph: Formatting block device %s as filesystem %s.' % ( |
701 | + device, fstype), level='INFO') |
702 | |
703 | === modified file 'tests/core/test_hookenv.py' |
704 | --- tests/core/test_hookenv.py 2013-08-07 17:05:39 +0000 |
705 | +++ tests/core/test_hookenv.py 2013-09-02 08:01:21 +0000 |
706 | @@ -1,9 +1,7 @@ |
707 | +import cPickle as pickle |
708 | import json |
709 | - |
710 | -import cPickle as pickle |
711 | -from mock import patch, call, mock_open |
712 | +from mock import call, MagicMock, mock_open, patch |
713 | from StringIO import StringIO |
714 | -from mock import MagicMock |
715 | from testtools import TestCase |
716 | import yaml |
717 | |
718 | @@ -25,6 +23,7 @@ |
719 | |
720 | |
721 | class SerializableTest(TestCase): |
722 | + |
723 | def test_serializes_object_to_json(self): |
724 | foo = { |
725 | 'bar': 'baz', |
726 | @@ -115,6 +114,7 @@ |
727 | |
728 | |
729 | class HelpersTest(TestCase): |
730 | + |
731 | def setUp(self): |
732 | super(HelpersTest, self).setUp() |
733 | # Reset hookenv cache for each test |
734 | |
735 | === modified file 'tests/core/test_host.py' |
736 | --- tests/core/test_host.py 2013-08-23 16:42:43 +0000 |
737 | +++ tests/core/test_host.py 2013-09-02 08:01:21 +0000 |
738 | @@ -1,7 +1,7 @@ |
739 | from collections import OrderedDict |
740 | from contextlib import contextmanager |
741 | +import io |
742 | import subprocess |
743 | -import io |
744 | |
745 | from mock import patch, call, MagicMock |
746 | from testtools import TestCase |
747 | @@ -18,19 +18,20 @@ |
748 | """rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 |
749 | """).strip().split('\n') |
750 | |
751 | -LSB_RELEASE = u'''DISTRIB_ID=Ubuntu |
752 | +LSB_RELEASE = u"""DISTRIB_ID=Ubuntu |
753 | DISTRIB_RELEASE=13.10 |
754 | DISTRIB_CODENAME=saucy |
755 | DISTRIB_DESCRIPTION="Ubuntu Saucy Salamander (development branch)" |
756 | -''' |
757 | +""" |
758 | |
759 | |
760 | @contextmanager |
761 | def patch_open(): |
762 | - '''Patch open() to allow mocking both open() itself and the file that is |
763 | + """Patch open() to allow mocking both open() itself and the file that is |
764 | yielded. |
765 | |
766 | - Yields the mock for "open" and "file", respectively.''' |
767 | + Yields the mock for "open" and "file", respectively. |
768 | + """ |
769 | mock_open = MagicMock(spec=open) |
770 | mock_file = MagicMock(spec=file) |
771 | |
772 | @@ -45,7 +46,7 @@ |
773 | |
774 | @contextmanager |
775 | def mock_open(filename, contents=None): |
776 | - ''' Slightly simpler mock of open to return contents for filename ''' |
777 | + """Slightly simpler mock of open to return contents for filename """ |
778 | def mock_file(*args): |
779 | if args[0] == filename: |
780 | return io.StringIO(contents) |
781 | |
782 | === modified file 'tests/fetch/test_archiveurl.py' |
783 | --- tests/fetch/test_archiveurl.py 2013-07-10 18:57:39 +0000 |
784 | +++ tests/fetch/test_archiveurl.py 2013-09-02 08:01:21 +0000 |
785 | @@ -1,16 +1,18 @@ |
786 | import os |
787 | -from testtools import TestCase |
788 | +import urllib2 |
789 | from urlparse import urlparse |
790 | + |
791 | from mock import ( |
792 | MagicMock, |
793 | patch, |
794 | mock_open, |
795 | ) |
796 | +from testtools import TestCase |
797 | + |
798 | from charmhelpers.fetch import ( |
799 | archiveurl, |
800 | UnhandledSource, |
801 | ) |
802 | -import urllib2 |
803 | |
804 | |
805 | class ArchiveUrlFetchHandlerTest(TestCase): |
806 | |
807 | === modified file 'tests/fetch/test_bzrurl.py' |
808 | --- tests/fetch/test_bzrurl.py 2013-08-21 11:45:37 +0000 |
809 | +++ tests/fetch/test_bzrurl.py 2013-09-02 08:01:21 +0000 |
810 | @@ -1,10 +1,12 @@ |
811 | import os |
812 | -from testtools import TestCase |
813 | from urlparse import urlparse |
814 | + |
815 | from mock import ( |
816 | MagicMock, |
817 | patch, |
818 | ) |
819 | +from testtools import TestCase |
820 | + |
821 | from charmhelpers.fetch import ( |
822 | bzrurl, |
823 | UnhandledSource, |
824 | @@ -41,7 +43,6 @@ |
825 | ) |
826 | self.fh = bzrurl.BzrUrlFetchHandler() |
827 | |
828 | - |
829 | def test_handles_bzr_urls(self): |
830 | for url in self.valid_urls: |
831 | result = self.fh.can_handle(url) |
832 | @@ -50,7 +51,6 @@ |
833 | result = self.fh.can_handle(url) |
834 | self.assertNotEqual(result, True, url) |
835 | |
836 | - |
837 | @patch('bzrlib.branch.Branch.open') |
838 | def test_branch(self, _open): |
839 | dest_path = "/destination/path" |
840 | @@ -65,7 +65,6 @@ |
841 | with patch.dict('os.environ', {'CHARM_DIR': 'foo'}): |
842 | self.assertRaises(UnhandledSource, self.fh.branch, url, dest_path) |
843 | |
844 | - |
845 | @patch('charmhelpers.fetch.bzrurl.mkdir') |
846 | def test_installs(self, _mkdir): |
847 | self.fh.branch = MagicMock() |
848 | @@ -77,4 +76,3 @@ |
849 | where = self.fh.install(url) |
850 | self.assertEqual(where, dest) |
851 | _mkdir.assert_called_with(where, perms=0755) |
852 | - |
853 | |
854 | === modified file 'tests/fetch/test_fetch.py' |
855 | --- tests/fetch/test_fetch.py 2013-08-21 15:45:53 +0000 |
856 | +++ tests/fetch/test_fetch.py 2013-09-02 08:01:21 +0000 |
857 | @@ -1,13 +1,16 @@ |
858 | from contextlib import contextmanager |
859 | -from testtools import TestCase |
860 | +from urlparse import urlparse |
861 | + |
862 | from mock import ( |
863 | patch, |
864 | MagicMock, |
865 | call, |
866 | ) |
867 | -from urlparse import urlparse |
868 | +from testtools import TestCase |
869 | +import yaml |
870 | + |
871 | from charmhelpers import fetch |
872 | -import yaml |
873 | + |
874 | |
875 | FAKE_APT_CACHE = { |
876 | # an installed package |
877 | @@ -38,10 +41,10 @@ |
878 | |
879 | @contextmanager |
880 | def patch_open(): |
881 | - '''Patch open() to allow mocking both open() itself and the file that is |
882 | + """Patch open() to allow mocking both open() itself and the file that is |
883 | yielded. |
884 | |
885 | - Yields the mock for "open" and "file", respectively.''' |
886 | + Yields the mock for "open" and "file", respectively.""" |
887 | mock_open = MagicMock(spec=open) |
888 | mock_file = MagicMock(spec=file) |
889 | |
890 | @@ -96,9 +99,9 @@ |
891 | @patch.object(fetch, 'apt_install') |
892 | def test_add_source_cloud(self, apt_install, filter_pkg): |
893 | source = "cloud:havana-updates" |
894 | - result = '''# Ubuntu Cloud Archive |
895 | + result = """# Ubuntu Cloud Archive |
896 | deb http://ubuntu-cloud.archive.canonical.com/ubuntu havana-updates main |
897 | -''' |
898 | +""" |
899 | with patch_open() as (mock_open, mock_file): |
900 | fetch.add_source(source=source) |
901 | mock_file.write.assert_called_with(result) |
902 | @@ -352,27 +355,24 @@ |
903 | check_call.assert_called_with(['apt-get', '-y', '--foo', '--bar', |
904 | 'install', 'foo', 'bar']) |
905 | |
906 | - |
907 | @patch('subprocess.check_call') |
908 | @patch.object(fetch, 'log') |
909 | def test_purges_apt_packages_as_string_fatal(self, log, mock_call): |
910 | packages = 'irrelevant names' |
911 | mock_call.side_effect = OSError('fail') |
912 | |
913 | - mock_call.assertRaises(OSError, fetch.apt_purge, packages, fatal=True ) |
914 | + mock_call.assertRaises(OSError, fetch.apt_purge, packages, fatal=True) |
915 | log.assert_called() |
916 | |
917 | - |
918 | @patch('subprocess.check_call') |
919 | @patch.object(fetch, 'log') |
920 | def test_purges_apt_packages_fatal(self, log, mock_call): |
921 | packages = ['irrelevant', 'names'] |
922 | mock_call.side_effect = OSError('fail') |
923 | |
924 | - mock_call.assertRaises(OSError, fetch.apt_purge, packages, fatal=True ) |
925 | + mock_call.assertRaises(OSError, fetch.apt_purge, packages, fatal=True) |
926 | log.assert_called() |
927 | |
928 | - |
929 | @patch('subprocess.call') |
930 | @patch.object(fetch, 'log') |
931 | def test_purges_apt_packages_as_string_nofatal(self, log, mock_call): |
932 | @@ -383,7 +383,6 @@ |
933 | log.assert_called() |
934 | mock_call.assert_called_with(['apt-get', '-y', 'purge', 'foo bar']) |
935 | |
936 | - |
937 | @patch('subprocess.call') |
938 | @patch.object(fetch, 'log') |
939 | def test_purges_apt_packages_nofatal(self, log, mock_call): |
940 | @@ -395,7 +394,6 @@ |
941 | mock_call.assert_called_with(['apt-get', '-y', 'purge', 'foo', |
942 | 'bar']) |
943 | |
944 | - |
945 | @patch('subprocess.check_call') |
946 | def test_apt_update_fatal(self, check_call): |
947 | fetch.apt_update(fatal=True) |
948 | |
949 | === modified file 'tests/payload/test_archive.py' |
950 | --- tests/payload/test_archive.py 2013-07-03 23:04:00 +0000 |
951 | +++ tests/payload/test_archive.py 2013-09-02 08:01:21 +0000 |
952 | @@ -1,13 +1,15 @@ |
953 | import os |
954 | -from testtools import TestCase |
955 | +from shutil import rmtree |
956 | +import subprocess |
957 | +from tempfile import mkdtemp |
958 | + |
959 | from mock import ( |
960 | patch, |
961 | MagicMock, |
962 | ) |
963 | +from testtools import TestCase |
964 | + |
965 | from charmhelpers.payload import archive |
966 | -from tempfile import mkdtemp |
967 | -from shutil import rmtree |
968 | -import subprocess |
969 | |
970 | |
971 | class ArchiveTestCase(TestCase): |
972 | |
973 | === modified file 'tests/payload/test_execd.py' |
974 | --- tests/payload/test_execd.py 2013-07-11 08:31:49 +0000 |
975 | +++ tests/payload/test_execd.py 2013-09-02 08:01:21 +0000 |
976 | @@ -1,11 +1,11 @@ |
977 | -from testtools import TestCase |
978 | -from mock import patch |
979 | import os |
980 | import shutil |
981 | import stat |
982 | - |
983 | from tempfile import mkdtemp |
984 | |
985 | +from mock import patch |
986 | +from testtools import TestCase |
987 | + |
988 | from charmhelpers.payload import execd |
989 | |
990 | |
991 | @@ -58,7 +58,9 @@ |
992 | expected_file = os.path.join(self.test_charm_dir, execd_dir, |
993 | module_dir, 'charm-pre-install-success') |
994 | files = os.listdir(os.path.dirname(expected_file)) |
995 | - self.assertTrue(os.path.exists(expected_file), "files were: %s. charmdir is: %s" % (files, self.test_charm_dir)) |
996 | + self.assertTrue( |
997 | + os.path.exists(expected_file), |
998 | + 'files were: %s. charmdir is: %s' % (files, self.test_charm_dir)) |
999 | |
1000 | def test_execd_preinstall(self): |
1001 | """All charm-pre-install hooks are executed.""" |
1002 | |
1003 | === modified file 'tests/tools/test_charm_helper_sync.py' |
1004 | --- tests/tools/test_charm_helper_sync.py 2013-07-12 01:28:42 +0000 |
1005 | +++ tests/tools/test_charm_helper_sync.py 2013-09-02 08:01:21 +0000 |
1006 | @@ -19,7 +19,7 @@ |
1007 | |
1008 | class HelperSyncTests(unittest.TestCase): |
1009 | def test_clone_helpers(self): |
1010 | - '''It properly branches the correct helpers branch''' |
1011 | + """It properly branches the correct helpers branch.""" |
1012 | with patch('subprocess.check_call') as check_call: |
1013 | sync.clone_helpers(work_dir='/tmp/foo', branch='lp:charm-helpers') |
1014 | check_call.assert_called_with(['bzr', 'branch', |
1015 | @@ -27,19 +27,19 @@ |
1016 | '/tmp/foo/charm-helpers']) |
1017 | |
1018 | def test_module_path(self): |
1019 | - '''It converts a python module path to a filesystem path''' |
1020 | + """It converts a python module path to a filesystem path.""" |
1021 | self.assertEquals(sync._module_path('some.test.module'), |
1022 | 'some/test/module') |
1023 | |
1024 | def test_src_path(self): |
1025 | - '''It renders the correct path to module within charm-helpers tree''' |
1026 | + """It renders the correct path to module within charm-helpers tree.""" |
1027 | path = sync._src_path(src='/tmp/charm-helpers', |
1028 | module='contrib.openstack') |
1029 | self.assertEquals('/tmp/charm-helpers/charmhelpers/contrib/openstack', |
1030 | path) |
1031 | |
1032 | def test_dest_path(self): |
1033 | - '''It correctly finds the correct install path within a charm''' |
1034 | + """It correctly finds the correct install path within a charm.""" |
1035 | path = sync._dest_path(dest='/tmp/mycharm/hooks/charmhelpers', |
1036 | module='contrib.openstack') |
1037 | self.assertEquals('/tmp/mycharm/hooks/charmhelpers/contrib/openstack', |
1038 | @@ -49,7 +49,7 @@ |
1039 | @patch('os.path.exists') |
1040 | @patch('os.walk') |
1041 | def test_ensure_init(self, walk, exists, _open): |
1042 | - '''It ensures all subdirectories of a parent are python importable''' |
1043 | + """It ensures all subdirectories of a parent are python importable.""" |
1044 | # os walk |
1045 | # os.path.join |
1046 | # os.path.exists |
1047 | @@ -73,7 +73,7 @@ |
1048 | @patch('os.makedirs') |
1049 | @patch('os.path.exists') |
1050 | def test_sync_pyfile(self, exists, mkdirs, copy, isfile, ensure_init): |
1051 | - '''It correctly syncs a py src file from src to dest''' |
1052 | + """It correctly syncs a py src file from src to dest.""" |
1053 | exists.return_value = False |
1054 | isfile.return_value = True |
1055 | sync.sync_pyfile('/tmp/charm-helpers/core/host', |
1056 | @@ -88,7 +88,7 @@ |
1057 | ensure_init.assert_called_with('hooks/charmhelpers/core') |
1058 | |
1059 | def _test_filter_dir(self, opts, isfile, isdir): |
1060 | - '''It filters non-python files and non-module dirs from source''' |
1061 | + """It filters non-python files and non-module dirs from source.""" |
1062 | files = { |
1063 | 'bad_file.bin': 'f', |
1064 | 'some_dir': 'd', |
1065 | @@ -119,7 +119,7 @@ |
1066 | @patch('os.path.isdir') |
1067 | @patch('os.path.isfile') |
1068 | def test_filter_dir_no_opts(self, isfile, isdir): |
1069 | - '''It filters out all non-py files by default''' |
1070 | + """It filters out all non-py files by default.""" |
1071 | result = self._test_filter_dir(opts=None, isfile=isfile, isdir=isdir) |
1072 | ex = ['bad_file.bin', 'bad_file.img', 'some_dir'] |
1073 | self.assertEquals(ex, result) |
1074 | @@ -127,7 +127,7 @@ |
1075 | @patch('os.path.isdir') |
1076 | @patch('os.path.isfile') |
1077 | def test_filter_dir_with_include(self, isfile, isdir): |
1078 | - '''It includes non-py files if specified as an include opt''' |
1079 | + """It includes non-py files if specified as an include opt.""" |
1080 | result = self._test_filter_dir(opts=['inc=*.img'], |
1081 | isfile=isfile, isdir=isdir) |
1082 | ex = ['bad_file.bin', 'some_dir'] |
1083 | @@ -136,7 +136,7 @@ |
1084 | @patch('os.path.isdir') |
1085 | @patch('os.path.isfile') |
1086 | def test_filter_dir_include_all(self, isfile, isdir): |
1087 | - '''It does not filter anything if option specified to include all''' |
1088 | + """It does not filter anything if option specified to include all.""" |
1089 | self.assertEquals(sync.get_filter(opts=['inc=*']), None) |
1090 | |
1091 | @patch('tools.charm_helpers_sync.charm_helpers_sync.get_filter') |
1092 | @@ -146,7 +146,7 @@ |
1093 | @patch('os.path.exists') |
1094 | def test_sync_directory(self, exists, rmtree, copytree, ensure_init, |
1095 | _filter): |
1096 | - '''It correctly syncs src directory to dest directory''' |
1097 | + """It correctly syncs src directory to dest directory.""" |
1098 | _filter.return_value = None |
1099 | sync.sync_directory('/tmp/charm-helpers/charmhelpers/core', |
1100 | 'hooks/charmhelpers/core') |
1101 | @@ -158,7 +158,7 @@ |
1102 | |
1103 | @patch('os.path.isfile') |
1104 | def test_is_pyfile(self, isfile): |
1105 | - '''It correctly identifies incomplete path to a py src file as such''' |
1106 | + """It correctly identifies incomplete path to a py src file as such.""" |
1107 | sync._is_pyfile('/tmp/charm-helpers/charmhelpers/core/host') |
1108 | isfile.assert_called_with( |
1109 | '/tmp/charm-helpers/charmhelpers/core/host.py' |
1110 | @@ -167,7 +167,7 @@ |
1111 | @patch('tools.charm_helpers_sync.charm_helpers_sync.sync_directory') |
1112 | @patch('os.path.isdir') |
1113 | def test_syncs_directory(self, is_dir, sync_dir): |
1114 | - '''It correctly syncs a module directory''' |
1115 | + """It correctly syncs a module directory.""" |
1116 | is_dir.return_value = True |
1117 | sync.sync(src='/tmp/charm-helpers', |
1118 | dest='hooks/charmhelpers', |
1119 | @@ -181,7 +181,7 @@ |
1120 | @patch('tools.charm_helpers_sync.charm_helpers_sync._is_pyfile') |
1121 | @patch('os.path.isdir') |
1122 | def test_syncs_file(self, is_dir, is_pyfile, sync_pyfile): |
1123 | - '''It correctly syncs a module file''' |
1124 | + """It correctly syncs a module file.""" |
1125 | is_dir.return_value = False |
1126 | is_pyfile.return_value = True |
1127 | sync.sync(src='/tmp/charm-helpers', |
1128 | @@ -195,7 +195,7 @@ |
1129 | @patch('tools.charm_helpers_sync.charm_helpers_sync.sync') |
1130 | @patch('os.path.isdir') |
1131 | def test_sync_helpers_from_config(self, isdir, _sync): |
1132 | - '''It correctly syncs a list of included helpers''' |
1133 | + """It correctly syncs a list of included helpers.""" |
1134 | include = yaml.load(INCLUDE)['include'] |
1135 | isdir.return_value = True |
1136 | sync.sync_helpers(include=include, |
1137 | @@ -219,14 +219,14 @@ |
1138 | self.assertEquals(ex_calls, _sync.call_args_list) |
1139 | |
1140 | def test_extract_option_no_globals(self): |
1141 | - '''It extracts option from an included item with no global options''' |
1142 | + """It extracts option from an included item with no global options.""" |
1143 | inc = 'contrib.openstack.templates|inc=*.template' |
1144 | result = sync.extract_options(inc) |
1145 | ex = ('contrib.openstack.templates', ['inc=*.template']) |
1146 | self.assertEquals(ex, result) |
1147 | |
1148 | def test_extract_option_with_global_as_string(self): |
1149 | - '''It extracts option for include with global options as str''' |
1150 | + """It extracts option for include with global options as str.""" |
1151 | inc = 'contrib.openstack.templates|inc=*.template' |
1152 | result = sync.extract_options(inc, global_options='inc=foo.*') |
1153 | ex = ('contrib.openstack.templates', |
1154 | @@ -234,14 +234,14 @@ |
1155 | self.assertEquals(ex, result) |
1156 | |
1157 | def test_extract_option_with_globals(self): |
1158 | - '''It extracts option from an included item with global options''' |
1159 | + """It extracts option from an included item with global options.""" |
1160 | inc = 'contrib.openstack.templates|inc=*.template' |
1161 | result = sync.extract_options(inc, global_options=['inc=*.cfg']) |
1162 | ex = ('contrib.openstack.templates', ['inc=*.template', 'inc=*.cfg']) |
1163 | self.assertEquals(ex, result) |
1164 | |
1165 | def test_extract_multiple_options_with_globals(self): |
1166 | - '''It extracts multiple options from an included item''' |
1167 | + """It extracts multiple options from an included item.""" |
1168 | inc = 'contrib.openstack.templates|inc=*.template,inc=foo.*' |
1169 | result = sync.extract_options(inc, global_options=['inc=*.cfg']) |
1170 | ex = ('contrib.openstack.templates', |
1171 | |
1172 | === modified file 'tools/charm_helpers_sync/charm_helpers_sync.py' |
1173 | --- tools/charm_helpers_sync/charm_helpers_sync.py 2013-07-12 01:28:42 +0000 |
1174 | +++ tools/charm_helpers_sync/charm_helpers_sync.py 2013-09-02 08:01:21 +0000 |
1175 | @@ -1,22 +1,19 @@ |
1176 | #!/usr/bin/python |
1177 | # |
1178 | # Copyright 2013 Canonical Ltd. |
1179 | - |
1180 | # Authors: |
1181 | # Adam Gandelman <adamg@ubuntu.com> |
1182 | -# |
1183 | |
1184 | +from fnmatch import fnmatch |
1185 | import logging |
1186 | import optparse |
1187 | import os |
1188 | +import shutil |
1189 | import subprocess |
1190 | -import shutil |
1191 | import sys |
1192 | import tempfile |
1193 | import yaml |
1194 | |
1195 | -from fnmatch import fnmatch |
1196 | - |
1197 | CHARM_HELPERS_BRANCH = 'lp:charm-helpers' |
1198 | |
1199 | |
1200 | @@ -52,13 +49,13 @@ |
1201 | |
1202 | |
1203 | def ensure_init(path): |
1204 | - ''' |
1205 | - ensure directories leading up to path are importable, omitting |
1206 | + """ |
1207 | + Ensure directories leading up to path are importable, omitting |
1208 | parent directory, eg path='/hooks/helpers/foo'/: |
1209 | hooks/ |
1210 | hooks/helpers/__init__.py |
1211 | hooks/helpers/foo/__init__.py |
1212 | - ''' |
1213 | + """ |
1214 | for d, dirs, files in os.walk(os.path.join(*path.split('/')[:2])): |
1215 | _i = os.path.join(d, '__init__.py') |
1216 | if not os.path.exists(_i): |
1217 | @@ -165,6 +162,7 @@ |
1218 | inc, opts = extract_options(m, global_options) |
1219 | sync(src, dest, '%s.%s' % (k, inc), opts) |
1220 | |
1221 | + |
1222 | if __name__ == '__main__': |
1223 | parser = optparse.OptionParser() |
1224 | parser.add_option('-c', '--config', action='store', dest='config', |
Hi Nicola
Looking at the current master branch, this is all now fixed up.
Thanks for the MP