Merge lp:~tvansteenburgh/charm-tools/no-symlinks into lp:charm-tools/1.3

Proposed by Tim Van Steenburgh
Status: Needs review
Proposed branch: lp:~tvansteenburgh/charm-tools/no-symlinks
Merge into: lp:charm-tools/1.3
Diff against target: 207 lines (+18/-106)
7 files modified
charmtools/charms.py (+1/-1)
charmtools/generators/template.py (+8/-0)
charmtools/templates/python/config.yaml (+0/-5)
charmtools/templates/python/files/hooks_symlinked/hooks.py (+0/-54)
charmtools/templates/python/template.py (+0/-16)
tests/test_charm_proof.py (+4/-1)
tests_functional/create/test_python_create.py (+5/-29)
To merge this branch: bzr merge lp:~tvansteenburgh/charm-tools/no-symlinks
Reviewer Review Type Date Requested Status
Marco Ceppi (community) Approve
Review via email: mp+233395@code.launchpad.net

Description of the change

Removes option to created symlinked hooks when creating a new charm, since symlinks don't work on Windows.

Run all tests with `make check`. Test manually with:

. bin/activate
charm create foo /tmp

To post a comment you must log in.
Revision history for this message
Marco Ceppi (marcoceppi) :
review: Needs Fixing
Revision history for this message
Marco Ceppi (marcoceppi) :
review: Abstain
Revision history for this message
Marco Ceppi (marcoceppi) wrote :

LGTM

review: Approve

Unmerged revisions

339. By Tim Van Steenburgh

Remove option to symlink hooks when creating charm

338. By Tim Van Steenburgh

Fix charm-proof email validation

formataddr() will put quotes around a name component that
contains special chars. We need to remove those to accurately
compare against the original maintainer string.

Also fixes tests that were broken due to new files in
charmhelpers.core

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmtools/charms.py'
2--- charmtools/charms.py 2014-06-17 15:44:04 +0000
3+++ charmtools/charms.py 2014-09-04 17:14:02 +0000
4@@ -453,7 +453,7 @@
5 for maintainer in maintainers:
6 (name, address) = email.utils.parseaddr(maintainer)
7 formatted = email.utils.formataddr((name, address))
8- if formatted != maintainer:
9+ if formatted.replace('"', '') != maintainer:
10 linter.warn(
11 'Maintainer format should be "Name <Email>", '
12 'not "%s"' % formatted)
13
14=== modified file 'charmtools/generators/template.py'
15--- charmtools/generators/template.py 2014-07-29 18:15:41 +0000
16+++ charmtools/generators/template.py 2014-09-04 17:14:02 +0000
17@@ -46,6 +46,14 @@
18 """Return default configuration for this template, loaded from a
19 config.yaml file.
20
21+ This is a sample config.yaml that configures one user prompt::
22+
23+ prompts:
24+ symlink:
25+ prompt: Symlink all hooks to one python source file? [yN]
26+ default: n
27+ type: boolean
28+
29 """
30 path = self.config_path()
31 if os.path.exists(path):
32
33=== removed file 'charmtools/templates/python/config.yaml'
34--- charmtools/templates/python/config.yaml 2014-05-27 21:23:41 +0000
35+++ charmtools/templates/python/config.yaml 1970-01-01 00:00:00 +0000
36@@ -1,5 +0,0 @@
37-prompts:
38- symlink:
39- prompt: Symlink all hooks to one python source file? [yN]
40- default: n
41- type: boolean
42
43=== removed directory 'charmtools/templates/python/files/hooks_symlinked'
44=== removed file 'charmtools/templates/python/files/hooks_symlinked/hooks.py'
45--- charmtools/templates/python/files/hooks_symlinked/hooks.py 2014-05-27 21:23:41 +0000
46+++ charmtools/templates/python/files/hooks_symlinked/hooks.py 1970-01-01 00:00:00 +0000
47@@ -1,54 +0,0 @@
48-#!/usr/bin/python
49-
50-import os
51-import sys
52-
53-sys.path.insert(0, os.path.join(os.environ['CHARM_DIR'], 'lib'))
54-
55-from charmhelpers.core import (
56- hookenv,
57- host,
58-)
59-
60-hooks = hookenv.Hooks()
61-log = hookenv.log
62-
63-SERVICE = '$metadata.package'
64-
65-
66-@hooks.hook('install')
67-def install():
68- log('Installing $metadata.package')
69-
70-
71-@hooks.hook('config-changed')
72-def config_changed():
73- config = hookenv.config()
74-
75- for key in config:
76- if config.changed(key):
77- log("config['{}'] changed from {} to {}".format(
78- key, config.previous(key), config[key]))
79-
80- config.save()
81- start()
82-
83-
84-@hooks.hook('upgrade-charm')
85-def upgrade_charm():
86- log('Upgrading $metadata.package')
87-
88-
89-@hooks.hook('start')
90-def start():
91- host.service_restart(SERVICE) or host.service_start(SERVICE)
92-
93-
94-@hooks.hook('stop')
95-def stop():
96- host.service_stop(SERVICE)
97-
98-
99-if __name__ == "__main__":
100- # execute a hook based on the name the program is called by
101- hooks.execute(sys.argv)
102
103=== modified file 'charmtools/templates/python/template.py'
104--- charmtools/templates/python/template.py 2014-07-29 18:15:41 +0000
105+++ charmtools/templates/python/template.py 2014-09-04 17:14:02 +0000
106@@ -46,7 +46,6 @@
107
108 self._template_file(config, path.join(root, outfile))
109
110- self._cleanup_hooks(config, output_dir)
111 self._install_charmhelpers(output_dir)
112
113 def _copy_files(self, output_dir):
114@@ -72,21 +71,6 @@
115 os.rename(o.name, outfile)
116 os.unlink(backupname)
117
118- def _cleanup_hooks(self, config, output_dir):
119- rmdir = 'hooks' if config['symlink'] else 'hooks_symlinked'
120- shutil.rmtree(os.path.join(output_dir, rmdir))
121-
122- if config['symlink']:
123- os.rename(
124- os.path.join(output_dir, 'hooks_symlinked'),
125- os.path.join(output_dir, 'hooks')
126- )
127- # Symlinks must be relative so that they are copied properly
128- # when output_dir is moved to it's final location.
129- for link in ['config-changed', 'install', 'start', 'stop',
130- 'upgrade-charm']:
131- os.symlink('hooks.py', os.path.join(output_dir, 'hooks', link))
132-
133 def _install_charmhelpers(self, output_dir):
134 helpers_dest = os.path.join(output_dir, 'lib', 'charmhelpers')
135 if not os.path.exists(helpers_dest):
136
137=== modified file 'tests/test_charm_proof.py'
138--- tests/test_charm_proof.py 2014-06-17 15:44:04 +0000
139+++ tests/test_charm_proof.py 2014-09-04 17:14:02 +0000
140@@ -420,7 +420,10 @@
141 """Maintainers field happy path."""
142 linter = Mock()
143 charm = {
144- 'maintainers': ['Tester <tester@example.com>'],
145+ 'maintainers': [
146+ 'Tester <tester@example.com>',
147+ 'Tester Joe H. <tester@example.com>',
148+ ]
149 }
150 validate_maintainer(charm, linter)
151 self.assertFalse(linter.err.called)
152
153=== modified file 'tests_functional/create/test_python_create.py'
154--- tests_functional/create/test_python_create.py 2014-06-20 19:46:59 +0000
155+++ tests_functional/create/test_python_create.py 2014-09-04 17:14:02 +0000
156@@ -45,46 +45,22 @@
157 def tearDown(self):
158 shutil.rmtree(self.tempdir)
159
160- def _expected_files(self, symlinked=False):
161+ def _expected_files(self):
162 static_files = list(flatten(pkg_resources.resource_filename(
163 'charmtools', 'templates/python/files')))
164- static_files = [f for f in static_files
165- if not f.startswith('hooks_symlinked/')]
166- if symlinked:
167- static_files.append('hooks/hooks.py')
168 dynamic_files = [
169 'lib/charmhelpers/__init__.py',
170 'lib/charmhelpers/core/__init__.py',
171 'lib/charmhelpers/core/fstab.py',
172 'lib/charmhelpers/core/hookenv.py',
173 'lib/charmhelpers/core/host.py',
174+ 'lib/charmhelpers/core/services/__init__.py',
175+ 'lib/charmhelpers/core/services/base.py',
176+ 'lib/charmhelpers/core/services/helpers.py',
177+ 'lib/charmhelpers/core/templating.py',
178 ]
179 return sorted(static_files + dynamic_files)
180
181- @patch('__builtin__.raw_input')
182- @patch('charmtools.create.setup_parser')
183- def test_interactive(self, setup_parser, raw_input_):
184- """Functional test of a full 'charm create' run."""
185- class args(object):
186- charmname = 'testcharm'
187- charmhome = self.tempdir
188- template = 'python'
189- accept_defaults = False
190- verbose = False
191-
192- setup_parser.return_value.parse_args.return_value = args
193- raw_input_.side_effect = ['Y']
194-
195- main()
196-
197- outputdir = join(self.tempdir, args.charmname)
198- actual_files = sorted(flatten(outputdir))
199- expected_files = self._expected_files(symlinked=True)
200- metadata = yaml.load(open(join(outputdir, 'metadata.yaml'), 'r'))
201-
202- self.assertEqual(expected_files, actual_files)
203- self.assertEqual(metadata['name'], args.charmname)
204-
205 @patch('charmtools.create.setup_parser')
206 def test_defaults(self, setup_parser):
207 """Functional test of a full 'charm create' run."""

Subscribers

People subscribed via source and target branches