Merge lp:~marcoceppi/charm-tools/vcs into lp:~charmers/charm-tools/trunk

Proposed by Marco Ceppi
Status: Merged
Approved by: Clint Byrum
Approved revision: 166
Merged at revision: 157
Proposed branch: lp:~marcoceppi/charm-tools/vcs
Merge into: lp:~charmers/charm-tools/trunk
Diff against target: 485 lines (+412/-7)
6 files modified
Makefile (+4/-1)
helpers/bash/vcs.bash (+243/-0)
helpers/sh/net.sh (+4/-5)
tests/helpers/helpers.bash (+18/-0)
tests/helpers/lib.sh (+3/-1)
tests/helpers/test_vcs.bash (+140/-0)
To merge this branch: bzr merge lp:~marcoceppi/charm-tools/vcs
Reviewer Review Type Date Requested Status
Clint Byrum (community) Approve
charmers Pending
Review via email: mp+121129@code.launchpad.net

Description of the change

I noticed so far two charms[1][3][2] take wild user input, supposedly a remote repository url, and takes action against that. This merge is designed to streamline the action of identifying what type of scm/vcs the remote source is and pull it down, or update a local repo from the remote source.

Demonstration of potential use cases: http://shelr.tv/records/50372c849660807bfb000098

[1]: http://jujucharms.com/charms/precise/wordpress
[2]: http://jujucharms.com/~mark-mims/oneiric/rails
[3]: http://jujucharms.com/charms/precise/node-app

To post a comment you must log in.
Revision history for this message
Clint Byrum (clint-fewbar) wrote :

I can has tests?! kthxbai!

review: Needs Fixing
lp:~marcoceppi/charm-tools/vcs updated
163. By Marco Ceppi

Start of tests for vcs helper

164. By Marco Ceppi

* Now with 20% more bash
* Start of test_vcs

165. By Marco Ceppi

Deferring update_repo and fetch_repo to a later data as there is no sane way to accurately mock those setups.

Revision history for this message
Marco Ceppi (marcoceppi) wrote :

omg u can haz. http://i.imgur.com/9xnK8.gif

* Moved vcs.sh to vcs.bash, as it's a bash script
* Created helpers.bash and update lib.sh
* Test(s) for vcs as best as can be covered

I have no idea what would need to be done to update the charm-helpers packaging to add charm-helpers-bash, so some guidance on that if it's needed would be cool

lp:~marcoceppi/charm-tools/vcs updated
166. By Marco Ceppi

Bad logic for CH_VCS_INSTALL_DEPS

Revision history for this message
Mark Mims (mark-mims) wrote :

also have the summit charms... I'll link them here when I push the most current versions up to lp (they're still on oneiric).

Summit's just like rails in that it's django and pulls in the app itself from a config branch.
It _also_ pulls in theme branches too as separate config items.

Revision history for this message
Clint Byrum (clint-fewbar) wrote :

Thanks for adding the tests Marco, this is awesome.

Approved, with 2 minors to fix:

1) needs to be run from Makefile's "make check" rule so the packaging will be tested.

2) Just comment out the unimplemented tests with a # TODO: add tests. Printing "DEFERRED" there is really confusing.

review: Approve
lp:~marcoceppi/charm-tools/vcs updated
167. By Marco Ceppi

Updated makefile to test for bash

168. By Marco Ceppi

Hide deferred tests for now, TODO

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2012-08-28 18:59:42 +0000
3+++ Makefile 2012-09-05 18:33:18 +0000
4@@ -26,8 +26,11 @@
5
6 check:
7 tests/helpers/helpers.sh || sh -x tests/helpers/helpers.sh timeout
8+ @echo Test shell helpers with dash
9+ bash tests/helpers/helpers.sh || bash -x tests/helpers/helpers.sh timeout
10+ tests/helpers/helpers.bash || sh -x tests/helpers/helpers.bash timeout
11 @echo Test shell helpers with bash
12- bash tests/helpers/helpers.sh || bash -x tests/helpers/helpers.sh timeout
13+ bash tests/helpers/helpers.bash || bash -x tests/helpers/helpers.bash timeout
14 @echo Test charm proof
15 tests/proof/test.sh
16 tests/create/test.sh
17
18=== added directory 'helpers/bash'
19=== added file 'helpers/bash/vcs.bash'
20--- helpers/bash/vcs.bash 1970-01-01 00:00:00 +0000
21+++ helpers/bash/vcs.bash 2012-09-05 18:33:18 +0000
22@@ -0,0 +1,243 @@
23+#!/bin/bash
24+
25+##
26+# Copyright 2012 Marco Ceppi <marco@ceppi.net>
27+#
28+# This file is part of Charm Helpers.
29+#
30+# Charm Helpers is free software: you can redistribute it and/or modify
31+# it under the terms of the GNU General Public License as published by
32+# the Free Software Foundation, either version 3 of the License, or
33+# (at your option) any later version.
34+#
35+# Charm Helpers is distributed in the hope that it will be useful,
36+# but WITHOUT ANY WARRANTY; without even the implied warranty of
37+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38+# GNU General Public License for more details.
39+#
40+# You should have received a copy of the GNU General Public License
41+# along with Charm Helpers. If not, see <http://www.gnu.org/licenses/>.
42+##
43+
44+CH_VCS_INSTALL_DEPS=${CH_VCS_INSTALL_DEPS:-"true"}
45+
46+##
47+# URL Match patterns
48+CH_VCS_BZR_URL_PATTERN="^(lp:~?|bzr:|bzr\+ssh:)"
49+CH_VCS_GIT_URL_PATTERN="(^git@|^git:|.git$)"
50+CH_VCS_SVN_URL_PATTERN="^(svn:|svn\+ssh:)"
51+CH_VCS_HG_URL_PATTERN="" #UGH, they only have ssh:// and https?:// SO DIFFICULT.
52+# This is a VERY generous pattern and should weed out the majority of malformed URLS
53+# Not sure why this didn't work. It works with `egrep -E`, but whatever.
54+#CH_VCS_VALID_URL_PATTERN="(lp:|(https?|svn|bzr|git|ssh)(+ssh)?://)[-a-z0-9+&/?=_:.]*[-a-z0-9+&/=_]"
55+CH_VCS_VALID_URL_PATTERN="^(lp:~?|https?://|svn://|svn\+ssh://|bzr://|bzr\+ssh://|git://|ssh://)[-a-z0-9\+&/?=_:.@]+*[-a-z0-9\+&/=_]"
56+
57+##
58+# "clone", "branch", "fetch" commands
59+CH_VCS_BZR_FETCH_CMD="branch"
60+CH_VCS_GIT_FETCH_CMD="clone"
61+CH_VCS_SVN_FETCH_CMD="co"
62+CH_VCS_HG_FETCH_CMD="clone"
63+
64+##
65+# "pull", "up", updated commands
66+CH_VCS_BZR_UPDATE_CMD="pull"
67+CH_VCS_GIT_UPDATE_CMD="pull"
68+CH_VCS_SVN_UPDATE_CMD="up"
69+CH_VCS_HG_UPDATE_CMD="pull"
70+
71+##
72+# File Match patterns
73+CH_VCS_BZR_FILE=".bzr"
74+CH_VCS_GIT_FILE=".git"
75+CH_VCS_SVN_FILE=".svn"
76+CH_VCS_HG_FILE=".hg"
77+
78+##
79+# Supported VCS
80+CH_VCS_SUPPORTED_TYPES=( bzr git svn hg )
81+
82+##
83+# Make sure all requirements are fullfiled
84+if [ "$CH_VCS_INSTALL_DEPS" = "true" ]; then
85+ apt-get install -y subversion git-core bzr mercurial
86+fi
87+
88+##
89+# Detect VCS
90+# Try to determine the Source Control tool used
91+#
92+# param URL - URL of remote source
93+#
94+# echo type|null
95+#
96+# return 0 OK
97+# return 1 No REPO_URL
98+# return 2 Not a valid VCS
99+##
100+ch_detect_vcs()
101+{
102+ local REPO_URL=${1:-""}
103+
104+ if [ -z "$REPO_URL" ]; then
105+ return 1
106+ fi
107+
108+ if [ -d "$REPO_URL" ]; then
109+ # This is no URL! It's a path!
110+ # Go through each repo type and find out which one we have
111+ for type in "${CH_VCS_SUPPORTED_TYPES[@]}"; do
112+ local REPO_FILE="CH_VCS_${type^^}_FILE"
113+ local REPO_FILE="${!REPO_FILE}"
114+
115+ if [ -d $REPO_URL/$REPO_FILE ]; then
116+ echo $type
117+ return 0
118+ fi
119+ done
120+
121+ # It's a directory, but we couldn't match a VCS tool. We should bail
122+ # because I _doubt_ it'll be a URL.
123+ return 2
124+ fi
125+ # So, it's not a local path? Okay, maybe it's a URL?
126+
127+ # This should be a loop
128+ if [[ $REPO_URL =~ $CH_VCS_BZR_URL_PATTERN ]]; then
129+ # It's a BZR repo!
130+ echo "bzr"
131+ return 0
132+ elif [[ $REPO_URL =~ $CH_VCS_GIT_URL_PATTERN ]]; then
133+ # It's a Git repo!
134+ echo "git"
135+ return 0
136+ elif [[ $REPO_URL =~ $CH_VCS_SVN_URL_PATTERN ]]; then
137+ # It's subversion!
138+ echo "svn"
139+ return 0
140+ elif [[ "$REPO_URL" =~ $CH_VCS_VALID_URL_PATTERN ]]; then
141+ for type in "${CH_VCS_SUPPORTED_TYPES[@]}"; do
142+ local TMP_REPO=`ch_fetch_repo "$REPO_URL" "$type"`
143+ local TMP_RESULT=$?
144+ if [ $TMP_RESULT -eq 0 ]; then
145+ # It's $type! Clean up and bail
146+ rm -rf $TMP_REPO
147+ echo "$type"
148+ return 0
149+ elif [ $TMP_RESULT -le 2 ]; then
150+ # Something went wrong, and it shouldn't have.
151+ return 128
152+ fi
153+
154+ rm -rf "$TMP_REPO"
155+ done
156+ fi
157+
158+ return 2 # Not a valid VCS system
159+}
160+
161+##
162+# Fetch Repo
163+# Pull down the repository and return it's temporary path
164+# param REPO_URL - URL of the remote source
165+# param REPO_TYPE optional - The type of VCS to use
166+#
167+# echo path|null
168+#
169+# return 0 OK
170+# return 1 No REPO_URL
171+# return 2 Not a valid URL
172+# return 3 Unable to fetch
173+##
174+ch_fetch_repo()
175+{
176+ local REPO_URL=${1:-""}
177+ local REPO_TYPE=${2:-""}
178+
179+ # Check for crap
180+ if [ -z "$REPO_URL" ]; then
181+ # Don't give me crap!
182+ return 1
183+ fi
184+
185+ # If we're guessing, then lets guess!
186+ if [ -z "$REPO_TYPE" ]; then
187+ # FUUUU, got to go figure it out now
188+ # Assume nothing, this could be garbage.
189+ if [[ $REPO_URL =~ $CH_VCS_VALID_URL_PATTERN ]]; then
190+ local REPO_TYPE=`ch_detect_vcs $REPO_URL`
191+
192+ if [ $? -gt 0 ] || [ -z "$REPO_TYPE" ]; then
193+ return 2
194+ fi
195+ else
196+ return 2
197+ fi
198+ fi
199+
200+ local REPO_FETCH_CMD="CH_VCS_${REPO_TYPE^^}_FETCH_CMD"
201+ local REPO_FETCH_CMD="${!REPO_FETCH_CMD}"
202+
203+ local REPO_PATH=`mktemp -d /tmp/charm-helper-vcs-$REPO_TYPE.XXXXXX`
204+ local REPO_OPTS=""
205+
206+ # CURE YOU BZR!!!!!
207+ if [ $REPO_TYPE == "bzr" ]; then
208+ REPO_OPTS="--use-existing-dir"
209+ fi
210+
211+
212+ $REPO_TYPE $REPO_FETCH_CMD $REPO_OPTS $REPO_URL $REPO_PATH > /dev/null 2>&1
213+
214+ if [ $? -ne 0 ]; then
215+ rm -rf $REPO_PATH
216+ return 3
217+ fi
218+
219+ echo $REPO_PATH
220+}
221+
222+##
223+# Update Repository
224+# This will "update" the repository to the latest rev
225+#
226+# param REPO_PATH - The local path to the repository
227+#
228+# echo null
229+#
230+# return 0 OK
231+# return 1 No REPO_PATH
232+# return 2 Not a valid repo path
233+# return 3 Failed to update repo
234+##
235+ch_update_repo()
236+{
237+ local REPO_PATH=${1:-""}
238+
239+ if [ ! -d "$REPO_PATH" ]; then
240+ return 1
241+ fi
242+
243+ REPO_TYPE=`ch_detect_vcs "$REPO_PATH"`
244+
245+ if [ $? -ne 0 ]; then
246+ return 3
247+ fi
248+
249+ local REPO_UPDATE="CH_VCS_${REPO_TYPE^^}_UPDATE_CMD"
250+ local REPO_UPDATE="${!REPO_UPDATE}"
251+ local CWD=`pwd`
252+
253+ cd $REPO_PATH
254+ $REPO_TYPE $REPO_UPDATE > /dev/null 2>&1
255+ local SUCC=$?
256+ cd $CWD
257+
258+ if [ $SUCC -eq 0 ]; then
259+ return 0
260+ else
261+ return 3
262+ fi
263+
264+ return 2
265+}
266
267=== modified file 'helpers/sh/net.sh'
268--- helpers/sh/net.sh 2012-03-12 13:06:08 +0000
269+++ helpers/sh/net.sh 2012-09-05 18:33:18 +0000
270@@ -19,8 +19,8 @@
271 # along with Charm Helpers. If not, see <http://www.gnu.org/licenses/>.
272 ##
273
274-##
275-# Globally overridable settings. Make sure to set them before sourcing
276+##
277+# Globally overridable settings. Make sure to set them before sourcing
278 # this file.
279 CH_WGET_ARGS=${CH_WGET_ARGS:-"-q --content-disposition"}
280
281@@ -37,7 +37,7 @@
282 {
283 local FILE=${1:-""}
284 local HASH=${2:-""}
285- local CH_DOWNLOAD_DIR=${CH_DOWNLOAD_DIR:-"`mktemp -d /tmp/ch-downloads.XXXXXX`"}
286+ local CH_DOWNLOAD_DIR=${CH_DOWNLOAD_DIR:-"`mktemp -d /tmp/ch-downloads.XXXXXX`"}
287
288 if [ `ch_is_url "$FILE"` ]; then
289 wget $CH_WGET_ARGS --directory-prefix="$CH_DOWNLOAD_DIR/" "$FILE"
290@@ -48,7 +48,7 @@
291 return 2
292 fi
293
294- if [ -z "$HASH" ];then
295+ if [ -z "$HASH" ];then
296 #echo "Warning, no has specified. The file will be downloaded but not cryptographically checked!" > 2
297 echo "$FILE"
298 return 0
299@@ -181,4 +181,3 @@
300 echo $CHECK_IP
301 return 0
302 }
303-
304
305=== added file 'tests/helpers/helpers.bash'
306--- tests/helpers/helpers.bash 1970-01-01 00:00:00 +0000
307+++ tests/helpers/helpers.bash 2012-09-05 18:33:18 +0000
308@@ -0,0 +1,18 @@
309+#!/bin/bash
310+
311+set -ue
312+
313+test_home=`dirname $0`
314+test_home=`readlink -f $test_home`
315+
316+# Should set 60 second timeout
317+if [ -z ${1:-""} ] ; then
318+ exec $test_home/run_with_timeout.py $0 timeout
319+fi
320+
321+[ "${LIB_SOURCED:-''}" = "1" ] || . $test_home/lib.sh
322+
323+for i in $test_home/test_*.bash ; do
324+ . $i
325+done
326+
327
328=== modified file 'tests/helpers/lib.sh'
329--- tests/helpers/lib.sh 2012-03-12 13:06:08 +0000
330+++ tests/helpers/lib.sh 2012-09-05 18:33:18 +0000
331@@ -10,6 +10,8 @@
332 echo -n `date`: Testing $*
333 }
334
335-HELPERS_HOME=${HELPERS_HOME:-"$test_home/../../helpers/sh"}
336+shell_type=`echo $0 | awk -F. '{print $NF}'`
337+
338+HELPERS_HOME=${HELPERS_HOME:-"$test_home/../../helpers/$shell_type"}
339
340 LIB_SOURCED=1
341
342=== added file 'tests/helpers/test_vcs.bash'
343--- tests/helpers/test_vcs.bash 1970-01-01 00:00:00 +0000
344+++ tests/helpers/test_vcs.bash 2012-09-05 18:33:18 +0000
345@@ -0,0 +1,140 @@
346+#!/bin/bash
347+
348+if [ -z "$test_home" ] ; then
349+ test_home=`dirname $0`
350+ test_home=`readlink -f $test_home`
351+fi
352+
353+[ "$LIB_SOURCED" = "1" ] || . $test_home/lib.sh
354+
355+set -ue
356+
357+MOCK_NET=${MOCK_NET:-"true"}
358+MOCK_VCS=${MOCK_VCS:-"true"}
359+
360+mock_host()
361+{
362+ if echo $* | grep -q "[_#]" ; then return 1 ; fi
363+ echo nothost.local has address 127.0.0.1
364+ echo nothost.local has address 127.0.1.1
365+}
366+
367+mock_dig()
368+{
369+ if echo $* | grep -q "[_#]" ; then return 1 ; fi
370+ echo 127.0.0.1
371+ echo 127.0.1.1
372+}
373+
374+mock_git()
375+{
376+ if [ "$1" = "clone" ] && [ $# -eq 3 ]; then
377+ return 0
378+ fi
379+
380+ if [ "$1" = "pull" ] && [ $# -eq 1 ]; then
381+ return 0
382+ fi
383+
384+ return 1
385+}
386+
387+mock_bzr()
388+{
389+ if [ "$1" = "branch" ] && [ $# -eq 3 ]; then
390+ return 0
391+ fi
392+
393+ if [ "$1" = "pull" ] && [ $# -eq 1 ]; then
394+ return 0
395+ fi
396+
397+ return 1
398+}
399+
400+mock_svn()
401+{
402+ if [ "$1" = "co" ] && [ $# -eq 4 ]; then
403+ return 0
404+ fi
405+
406+ if [ "$1" = "up" ] && [ $# -eq 1 ]; then
407+ return 0
408+ fi
409+
410+ return 1
411+}
412+
413+mock_apt()
414+{
415+ return 0
416+}
417+
418+if [ "$MOCK_NET" = "true" ]; then
419+ alias host=mock_host
420+ alias dig=mock_dig
421+fi
422+
423+## At this time, this doesn't work, but one day it will - or at least should
424+## Assuming that ch_detect_vcs works, ch_fetch_repo and ch_update_repo
425+## should run without issue.
426+if [ "$MOCK_VCS" = "true" ]; then
427+ alias git=mock_git
428+ alias bzr=mock_bzr
429+ alias svn=mock_svn
430+ alias hg=mock_git
431+ alias apt-get=mock_apt
432+fi
433+
434+CH_VCS_INSTALL_DEPS="false"
435+
436+. $HELPERS_HOME/vcs.bash
437+
438+cleanup_repos()
439+{
440+ output Cleaning up fake repos...
441+ rm -rf /tmp/charm-helper-vcs-*
442+}
443+
444+trap cleanup_repos EXIT
445+
446+output Creating fake local repos...
447+temp_no_vcs=`mktemp -d /tmp/charm-helper-vcs-lol.XXXXXX`
448+temp_git_dir=`mktemp -d /tmp/charm-helper-vcs-git.XXXXXX`
449+temp_bzr_dir=`mktemp -d /tmp/charm-helper-vcs-bzr.XXXXXX`
450+temp_svn_dir=`mktemp -d /tmp/charm-helper-vcs-svn.XXXXXX`
451+temp_hg_dir=`mktemp -d /tmp/charm-helper-vcs-hg.XXXXXX`
452+
453+mkdir -p $temp_git_dir/.git
454+mkdir -p $temp_bzr_dir/.bzr
455+mkdir -p $temp_svn_dir/.svn
456+mkdir -p $temp_hg_dir/.hg
457+
458+start_test ch_detect_vcs...
459+ch_detect_vcs "notvalid" && return 1 || :
460+[ "`ch_detect_vcs 'lp:charm-tools'`" = "bzr" ]
461+[ "`ch_detect_vcs 'lp:~charmers/charm-tools/trunk'`" = "bzr" ]
462+[ "`ch_detect_vcs 'bzr+ssh://example.com/~charmers/charm-tools/trunk'`" = "bzr" ]
463+[ "`ch_detect_vcs 'bzr+ssh://example.com/~charmers/charm-tools/trunk'`" = "bzr" ]
464+[ "`ch_detect_vcs $temp_bzr_dir`" = "bzr" ]
465+[ "`ch_detect_vcs 'https://example.com/charm-tools.git'`" = "git" ]
466+[ "`ch_detect_vcs 'http://example.com/charm-tools.git'`" = "git" ]
467+[ "`ch_detect_vcs 'git://example.com/charm-tools.git'`" = "git" ]
468+[ "`ch_detect_vcs 'git@example.com/charm-tools.git'`" = "git" ]
469+[ "`ch_detect_vcs $temp_git_dir`" = "git" ]
470+[ "`ch_detect_vcs 'svn+ssh://example.com/charm-tools/trunk'`" = "svn" ]
471+[ "`ch_detect_vcs 'svn://example.com/charm-tools/trunk'`" = "svn" ]
472+[ "`ch_detect_vcs $temp_svn_dir`" = "svn" ]
473+[ "`ch_detect_vcs $temp_hg_dir`" = "hg" ]
474+echo PASS
475+
476+# TODO
477+#start_test ch_fetch_repo...
478+#echo DEFERRED
479+
480+# TODO
481+#start_test ch_update_repo...
482+#echo DEFERRED
483+
484+trap - EXIT
485+cleanup_repos

Subscribers

People subscribed via source and target branches