Merge lp:~tvansteenburgh/charm-tools/fix-charm-add into lp:charm-tools/1.3

Proposed by Tim Van Steenburgh
Status: Merged
Merged at revision: 333
Proposed branch: lp:~tvansteenburgh/charm-tools/fix-charm-add
Merge into: lp:charm-tools/1.3
Diff against target: 495 lines (+398/-5)
8 files modified
Makefile (+1/-0)
charmtools/templates/bash/template.py (+1/-1)
charmtools/templates/charm/README.ex (+44/-0)
charmtools/templates/charm/icon.svg (+279/-0)
charmtools/templates/python/template.py (+13/-2)
setup.py (+2/-1)
tests_functional/add/test.sh (+57/-0)
tests_functional/create/test_python_create.py (+1/-1)
To merge this branch: bzr merge lp:~tvansteenburgh/charm-tools/fix-charm-add
Reviewer Review Type Date Requested Status
Marco Ceppi (community) Approve
Review via email: mp+223980@code.launchpad.net

Description of the change

Fix 'charm add' and add tests.

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

LGTM, +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2014-06-12 01:17:13 +0000
3+++ Makefile 2014-06-20 19:48:50 +0000
4@@ -92,6 +92,7 @@
5 @echo Test charm proof
6 tests_functional/proof/test.sh
7 tests_functional/create/test.sh
8+ tests_functional/add/test.sh
9 # PYTHONPATH=helpers/python python helpers/python/charmhelpers/tests/test_charmhelpers.py
10
11 coverage: build bin/test
12
13=== modified file 'charmtools/templates/bash/template.py'
14--- charmtools/templates/bash/template.py 2014-05-23 20:26:16 +0000
15+++ charmtools/templates/bash/template.py 2014-06-20 19:48:50 +0000
16@@ -49,7 +49,7 @@
17 template_dir = path.join(here, 'files')
18 if os.path.exists(output_dir):
19 shutil.rmtree(output_dir)
20- shutil.copytree(template_dir, output_dir, symlinks=True)
21+ shutil.copytree(template_dir, output_dir)
22
23 def _template_file(self, config, outfile):
24 if path.islink(outfile):
25
26=== added directory 'charmtools/templates/charm'
27=== added file 'charmtools/templates/charm/README.ex'
28--- charmtools/templates/charm/README.ex 1970-01-01 00:00:00 +0000
29+++ charmtools/templates/charm/README.ex 2014-06-20 19:48:50 +0000
30@@ -0,0 +1,44 @@
31+# Overview
32+
33+Describe the intended usage of this charm and anything unique about how this charm relates to others here.
34+
35+This README will be displayed in the Charm Store, it should be either Markdown or RST. Ideal READMEs include instructions on how to use the charm, expected usage, and charm features that your audience might be interested in. For an example of a well written README check out Hadoop: http://jujucharms.com/charms/precise/hadoop
36+
37+Use this as a Markdown reference if you need help with the formatting of this README: http://askubuntu.com/editing-help
38+
39+This charm provides [service](http://example.com). Add a description here of what the service itself actually does.
40+
41+Also remember to check the [icon guidelines](https://juju.ubuntu.com/docs/authors-charm-icon.html) so that your charm looks good in the Juju GUI.
42+
43+# Usage
44+
45+Step by step instructions on using the charm:
46+
47+ juju deploy servicename
48+
49+and so on. If you're providing a web service or something that the end user needs to go to, tell them here, especially if you're deploying a service that might listen to a non-default port.
50+
51+You can then browse to http://ip-address to configure the service.
52+
53+## Scale out Usage
54+
55+If the charm has any recommendations for running at scale, outline them in examples here. For example if you have a memcached relation that improves performance, mention it here.
56+
57+## Known Limitations and Issues
58+
59+This not only helps users but gives people a place to start if they want to help you add features to your charm.
60+
61+# Configuration
62+
63+The configuration options will be listed on the charm store, however If you're making assumptions or opinionated decisions in the charm (like setting a default administrator password), you should detail that here so the user knows how to change it immediately, etc.
64+
65+# Contact Information
66+
67+Though this will be listed in the charm store itself don't assume a user will know that, so include that information here:
68+
69+## Upstream Project Name
70+
71+- Upstream website
72+- Upstream bug tracker
73+- Upstream mailing list or contact information
74+- Feel free to add things if it's useful for users
75
76=== added file 'charmtools/templates/charm/icon.svg'
77--- charmtools/templates/charm/icon.svg 1970-01-01 00:00:00 +0000
78+++ charmtools/templates/charm/icon.svg 2014-06-20 19:48:50 +0000
79@@ -0,0 +1,279 @@
80+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
81+<!-- Created with Inkscape (http://www.inkscape.org/) -->
82+
83+<svg
84+ xmlns:dc="http://purl.org/dc/elements/1.1/"
85+ xmlns:cc="http://creativecommons.org/ns#"
86+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
87+ xmlns:svg="http://www.w3.org/2000/svg"
88+ xmlns="http://www.w3.org/2000/svg"
89+ xmlns:xlink="http://www.w3.org/1999/xlink"
90+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
91+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
92+ width="96"
93+ height="96"
94+ id="svg6517"
95+ version="1.1"
96+ inkscape:version="0.48+devel r12274"
97+ sodipodi:docname="Juju_charm_icon_template.svg">
98+ <defs
99+ id="defs6519">
100+ <linearGradient
101+ inkscape:collect="always"
102+ xlink:href="#Background"
103+ id="linearGradient6461"
104+ gradientUnits="userSpaceOnUse"
105+ x1="0"
106+ y1="970.29498"
107+ x2="144"
108+ y2="970.29498"
109+ gradientTransform="matrix(0,-0.66666669,0.6660448,0,-866.25992,731.29077)" />
110+ <linearGradient
111+ id="Background">
112+ <stop
113+ id="stop4178"
114+ offset="0"
115+ style="stop-color:#b8b8b8;stop-opacity:1" />
116+ <stop
117+ id="stop4180"
118+ offset="1"
119+ style="stop-color:#c9c9c9;stop-opacity:1" />
120+ </linearGradient>
121+ <filter
122+ style="color-interpolation-filters:sRGB;"
123+ inkscape:label="Inner Shadow"
124+ id="filter1121">
125+ <feFlood
126+ flood-opacity="0.59999999999999998"
127+ flood-color="rgb(0,0,0)"
128+ result="flood"
129+ id="feFlood1123" />
130+ <feComposite
131+ in="flood"
132+ in2="SourceGraphic"
133+ operator="out"
134+ result="composite1"
135+ id="feComposite1125" />
136+ <feGaussianBlur
137+ in="composite1"
138+ stdDeviation="1"
139+ result="blur"
140+ id="feGaussianBlur1127" />
141+ <feOffset
142+ dx="0"
143+ dy="2"
144+ result="offset"
145+ id="feOffset1129" />
146+ <feComposite
147+ in="offset"
148+ in2="SourceGraphic"
149+ operator="atop"
150+ result="composite2"
151+ id="feComposite1131" />
152+ </filter>
153+ <filter
154+ style="color-interpolation-filters:sRGB;"
155+ inkscape:label="Drop Shadow"
156+ id="filter950">
157+ <feFlood
158+ flood-opacity="0.25"
159+ flood-color="rgb(0,0,0)"
160+ result="flood"
161+ id="feFlood952" />
162+ <feComposite
163+ in="flood"
164+ in2="SourceGraphic"
165+ operator="in"
166+ result="composite1"
167+ id="feComposite954" />
168+ <feGaussianBlur
169+ in="composite1"
170+ stdDeviation="1"
171+ result="blur"
172+ id="feGaussianBlur956" />
173+ <feOffset
174+ dx="0"
175+ dy="1"
176+ result="offset"
177+ id="feOffset958" />
178+ <feComposite
179+ in="SourceGraphic"
180+ in2="offset"
181+ operator="over"
182+ result="composite2"
183+ id="feComposite960" />
184+ </filter>
185+ <clipPath
186+ clipPathUnits="userSpaceOnUse"
187+ id="clipPath873">
188+ <g
189+ transform="matrix(0,-0.66666667,0.66604479,0,-258.25992,677.00001)"
190+ id="g875"
191+ inkscape:label="Layer 1"
192+ style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline">
193+ <path
194+ style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline"
195+ d="m 46.702703,898.22775 50.594594,0 C 138.16216,898.22775 144,904.06497 144,944.92583 l 0,50.73846 c 0,40.86071 -5.83784,46.69791 -46.702703,46.69791 l -50.594594,0 C 5.8378378,1042.3622 0,1036.525 0,995.66429 L 0,944.92583 C 0,904.06497 5.8378378,898.22775 46.702703,898.22775 Z"
196+ id="path877"
197+ inkscape:connector-curvature="0"
198+ sodipodi:nodetypes="sssssssss" />
199+ </g>
200+ </clipPath>
201+ <filter
202+ inkscape:collect="always"
203+ id="filter891"
204+ inkscape:label="Badge Shadow">
205+ <feGaussianBlur
206+ inkscape:collect="always"
207+ stdDeviation="0.71999962"
208+ id="feGaussianBlur893" />
209+ </filter>
210+ </defs>
211+ <sodipodi:namedview
212+ id="base"
213+ pagecolor="#ffffff"
214+ bordercolor="#666666"
215+ borderopacity="1.0"
216+ inkscape:pageopacity="0.0"
217+ inkscape:pageshadow="2"
218+ inkscape:zoom="4.0745362"
219+ inkscape:cx="18.514671"
220+ inkscape:cy="49.018169"
221+ inkscape:document-units="px"
222+ inkscape:current-layer="layer1"
223+ showgrid="true"
224+ fit-margin-top="0"
225+ fit-margin-left="0"
226+ fit-margin-right="0"
227+ fit-margin-bottom="0"
228+ inkscape:window-width="1920"
229+ inkscape:window-height="1029"
230+ inkscape:window-x="0"
231+ inkscape:window-y="24"
232+ inkscape:window-maximized="1"
233+ showborder="true"
234+ showguides="true"
235+ inkscape:guide-bbox="true"
236+ inkscape:showpageshadow="false">
237+ <inkscape:grid
238+ type="xygrid"
239+ id="grid821" />
240+ <sodipodi:guide
241+ orientation="1,0"
242+ position="16,48"
243+ id="guide823" />
244+ <sodipodi:guide
245+ orientation="0,1"
246+ position="64,80"
247+ id="guide825" />
248+ <sodipodi:guide
249+ orientation="1,0"
250+ position="80,40"
251+ id="guide827" />
252+ <sodipodi:guide
253+ orientation="0,1"
254+ position="64,16"
255+ id="guide829" />
256+ </sodipodi:namedview>
257+ <metadata
258+ id="metadata6522">
259+ <rdf:RDF>
260+ <cc:Work
261+ rdf:about="">
262+ <dc:format>image/svg+xml</dc:format>
263+ <dc:type
264+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
265+ <dc:title></dc:title>
266+ </cc:Work>
267+ </rdf:RDF>
268+ </metadata>
269+ <g
270+ inkscape:label="BACKGROUND"
271+ inkscape:groupmode="layer"
272+ id="layer1"
273+ transform="translate(268,-635.29076)"
274+ style="display:inline">
275+ <path
276+ style="fill:url(#linearGradient6461);fill-opacity:1;stroke:none;display:inline;filter:url(#filter1121)"
277+ d="m -268,700.15563 0,-33.72973 c 0,-27.24324 3.88785,-31.13513 31.10302,-31.13513 l 33.79408,0 c 27.21507,0 31.1029,3.89189 31.1029,31.13513 l 0,33.72973 c 0,27.24325 -3.88783,31.13514 -31.1029,31.13514 l -33.79408,0 C -264.11215,731.29077 -268,727.39888 -268,700.15563 Z"
278+ id="path6455"
279+ inkscape:connector-curvature="0"
280+ sodipodi:nodetypes="sssssssss" />
281+ </g>
282+ <g
283+ inkscape:groupmode="layer"
284+ id="layer3"
285+ inkscape:label="PLACE YOUR PICTOGRAM HERE"
286+ style="display:inline" />
287+ <g
288+ inkscape:groupmode="layer"
289+ id="layer2"
290+ inkscape:label="BADGE"
291+ style="display:none"
292+ sodipodi:insensitive="true">
293+ <g
294+ style="display:inline"
295+ transform="translate(-340.00001,-581)"
296+ id="g4394"
297+ clip-path="none">
298+ <g
299+ id="g855">
300+ <g
301+ inkscape:groupmode="maskhelper"
302+ id="g870"
303+ clip-path="url(#clipPath873)"
304+ style="opacity:0.6;filter:url(#filter891)">
305+ <path
306+ transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-237.54282)"
307+ d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"
308+ sodipodi:ry="12"
309+ sodipodi:rx="12"
310+ sodipodi:cy="552.36218"
311+ sodipodi:cx="252"
312+ id="path844"
313+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
314+ sodipodi:type="arc" />
315+ </g>
316+ <g
317+ id="g862">
318+ <path
319+ sodipodi:type="arc"
320+ style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
321+ id="path4398"
322+ sodipodi:cx="252"
323+ sodipodi:cy="552.36218"
324+ sodipodi:rx="12"
325+ sodipodi:ry="12"
326+ d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"
327+ transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-238.54282)" />
328+ <path
329+ transform="matrix(1.25,0,0,1.25,33,-100.45273)"
330+ d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"
331+ sodipodi:ry="12"
332+ sodipodi:rx="12"
333+ sodipodi:cy="552.36218"
334+ sodipodi:cx="252"
335+ id="path4400"
336+ style="color:#000000;fill:#dd4814;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
337+ sodipodi:type="arc" />
338+ <path
339+ sodipodi:type="star"
340+ style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
341+ id="path4459"
342+ sodipodi:sides="5"
343+ sodipodi:cx="666.19574"
344+ sodipodi:cy="589.50385"
345+ sodipodi:r1="7.2431178"
346+ sodipodi:r2="4.3458705"
347+ sodipodi:arg1="1.0471976"
348+ sodipodi:arg2="1.6755161"
349+ inkscape:flatsided="false"
350+ inkscape:rounded="0.1"
351+ inkscape:randomized="0"
352+ d="m 669.8173,595.77657 c -0.39132,0.22593 -3.62645,-1.90343 -4.07583,-1.95066 -0.44938,-0.0472 -4.05653,1.36297 -4.39232,1.06062 -0.3358,-0.30235 0.68963,-4.03715 0.59569,-4.47913 -0.0939,-0.44198 -2.5498,-3.43681 -2.36602,-3.8496 0.18379,-0.41279 4.05267,-0.59166 4.44398,-0.81759 0.39132,-0.22593 2.48067,-3.48704 2.93005,-3.4398 0.44938,0.0472 1.81505,3.67147 2.15084,3.97382 0.3358,0.30236 4.08294,1.2817 4.17689,1.72369 0.0939,0.44198 -2.9309,2.86076 -3.11469,3.27355 C 669.9821,591.68426 670.20862,595.55064 669.8173,595.77657 Z"
353+ transform="matrix(1.511423,-0.16366377,0.16366377,1.511423,-755.37346,-191.93651)" />
354+ </g>
355+ </g>
356+ </g>
357+ </g>
358+</svg>
359
360=== removed symlink 'charmtools/templates/python/files/hooks_symlinked/config-changed'
361=== target was u'hooks.py'
362=== removed symlink 'charmtools/templates/python/files/hooks_symlinked/install'
363=== target was u'hooks.py'
364=== removed symlink 'charmtools/templates/python/files/hooks_symlinked/start'
365=== target was u'hooks.py'
366=== removed symlink 'charmtools/templates/python/files/hooks_symlinked/stop'
367=== target was u'hooks.py'
368=== removed symlink 'charmtools/templates/python/files/hooks_symlinked/upgrade-charm'
369=== target was u'hooks.py'
370=== modified file 'charmtools/templates/python/template.py'
371--- charmtools/templates/python/template.py 2014-05-27 21:23:41 +0000
372+++ charmtools/templates/python/template.py 2014-06-20 19:48:50 +0000
373@@ -54,7 +54,7 @@
374 template_dir = path.join(here, 'files')
375 if os.path.exists(output_dir):
376 shutil.rmtree(output_dir)
377- shutil.copytree(template_dir, output_dir, symlinks=True)
378+ shutil.copytree(template_dir, output_dir)
379
380 def _template_file(self, config, outfile):
381 if path.islink(outfile):
382@@ -75,12 +75,23 @@
383 def _cleanup_hooks(self, config, output_dir):
384 rmdir = 'hooks' if config['symlink'] else 'hooks_symlinked'
385 shutil.rmtree(os.path.join(output_dir, rmdir))
386- if rmdir == 'hooks':
387+
388+ if config['symlink']:
389 os.rename(
390 os.path.join(output_dir, 'hooks_symlinked'),
391 os.path.join(output_dir, 'hooks')
392 )
393+ for link in ['config-changed', 'install', 'start', 'stop',
394+ 'upgrade-charm']:
395+ os.symlink(
396+ os.path.join(output_dir, 'hooks', 'hooks.py'),
397+ os.path.join(output_dir, 'hooks', link)
398+ )
399
400 def _install_charmhelpers(self, output_dir):
401+ helpers_dest = os.path.join(output_dir, 'lib', 'charmhelpers')
402+ if not os.path.exists(helpers_dest):
403+ os.makedirs(helpers_dest)
404+
405 cmd = './scripts/charm_helpers_sync.py -c charm-helpers.yaml'
406 subprocess.check_call(cmd.split(), cwd=output_dir)
407
408=== modified file 'setup.py'
409--- setup.py 2014-06-20 18:35:44 +0000
410+++ setup.py 2014-06-20 19:48:50 +0000
411@@ -14,7 +14,8 @@
412 setup(
413 name='charm-tools',
414 version="1.3.1",
415- packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
416+ packages=find_packages(
417+ exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
418 install_requires=['launchpadlib', 'argparse', 'cheetah', 'pyyaml',
419 'pycrypto', 'paramiko', 'bzr', 'requests',
420 'charmworldlib'],
421
422=== added directory 'tests_functional/add'
423=== added file 'tests_functional/add/test.sh'
424--- tests_functional/add/test.sh 1970-01-01 00:00:00 +0000
425+++ tests_functional/add/test.sh 2014-06-20 19:48:50 +0000
426@@ -0,0 +1,57 @@
427+#!/bin/sh
428+
429+TESTDIR=`dirname $0`
430+
431+# activate virtualenv
432+. $TESTDIR/../../bin/activate
433+
434+cleanup() {
435+ if [ -n "$workdir" ] && [ -d "$workdir" ] ; then
436+ rm -rf $workdir
437+ fi
438+}
439+trap cleanup EXIT
440+
441+workdir=`mktemp -d /tmp/tests.XXXXXX`
442+
443+# These will influence create's maintainer generation and should also
444+# be set when updating the test charms
445+export UBUMAIL=test@testhost
446+export EMAIL=$UBUMAIL
447+export DEBFULLNAME=tester
448+export NAME=$DEBFULLNAME
449+
450+echo ===== Creating test charm for 'charm add' tests =====
451+charm create -t bash testcharm $workdir
452+set -e
453+
454+cd $workdir/testcharm
455+rm -rf icon.svg README.ex
456+
457+echo ===== Testing 'charm add tests' =====
458+charm add tests
459+if [ ! -d tests ] ; then
460+ echo FAIL - tests directory not created
461+ exit 1
462+fi
463+
464+echo ===== Testing 'charm add readme' =====
465+charm add readme
466+if [ ! -f README.ex ] ; then
467+ echo FAIL - README.ex file not created
468+ exit 1
469+fi
470+
471+echo ===== Testing 'charm add icon' =====
472+charm add icon
473+if [ ! -f icon.svg ] ; then
474+ echo FAIL - icon.svg file not created
475+ exit 1
476+fi
477+
478+echo ===== All tests passed! =====
479+echo PASS
480+set +e
481+trap - EXIT
482+cleanup
483+exit 0
484
485=== modified file 'tests_functional/create/test_python_create.py'
486--- tests_functional/create/test_python_create.py 2014-06-11 14:43:37 +0000
487+++ tests_functional/create/test_python_create.py 2014-06-20 19:48:50 +0000
488@@ -38,7 +38,7 @@
489 yield join(root[len(path):], f).lstrip('/')
490
491
492-class BashCreateTest(TestCase):
493+class PythonCreateTest(TestCase):
494 def setUp(self):
495 self.tempdir = tempfile.mkdtemp()
496

Subscribers

People subscribed via source and target branches