##// END OF EJS Templates
hgweb: recurse down collections only if ** in [paths]...
Benoit Allard -
r7523:e60aaae8 default
parent child Browse files
Show More
@@ -32,6 +32,7 import mercurial.hgweb.wsgicgi as wsgicg
32 # virtual/path2 = /real/path2
32 # virtual/path2 = /real/path2
33 # virtual/root = /real/root/*
33 # virtual/root = /real/root/*
34 # / = /real/root2/*
34 # / = /real/root2/*
35 # virtual/root2 = /real/root2/**
35 #
36 #
36 # [collections]
37 # [collections]
37 # /prefix/to/strip/off = /root/of/tree/full/of/repos
38 # /prefix/to/strip/off = /root/of/tree/full/of/repos
@@ -41,15 +42,18 import mercurial.hgweb.wsgicgi as wsgicg
41 # * First two lines mount one repository into one virtual path, like
42 # * First two lines mount one repository into one virtual path, like
42 # '/real/path1' into 'virtual/path1'.
43 # '/real/path1' into 'virtual/path1'.
43 #
44 #
44 # * The third entry tells every mercurial repository found in
45 # * The third entry mounts every mercurial repository found in '/real/root'
45 # '/real/root', recursively, should be mounted in 'virtual/root'. This
46 # in 'virtual/root'. This format is preferred over the [collections] one,
46 # format is preferred over the [collections] one, using absolute paths
47 # since using absolute paths as configuration keys is not support on every
47 # as configuration keys is not supported on every platform (including
48 # platform (especially on Windows).
48 # Windows).
49 #
49 #
50 # * The last entry is a special case mounting all repositories in
50 # * The fourth entry is a special case mounting all repositories in
51 # /'real/root2' in the root of the virtual directory.
51 # /'real/root2' in the root of the virtual directory.
52 #
52 #
53 # * The fifth entry recursively finds all repositories under the real root,
54 # and mounts them using their relative path (to given real root) under the
55 # virtual root.
56 #
53 # collections example: say directory tree /foo contains repos /foo/bar,
57 # collections example: say directory tree /foo contains repos /foo/bar,
54 # /foo/quux/baz. Give this config section:
58 # /foo/quux/baz. Give this config section:
55 # [collections]
59 # [collections]
@@ -54,13 +54,18 class hgwebdir(object):
54 paths = cleannames(cp.items('paths'))
54 paths = cleannames(cp.items('paths'))
55 for prefix, root in paths:
55 for prefix, root in paths:
56 roothead, roottail = os.path.split(root)
56 roothead, roottail = os.path.split(root)
57 if roottail != '*':
57 # "foo = /bar/*" makes every subrepo of /bar/ to be
58 # mounted as foo/subrepo
59 # and "foo = /bar/**" does even recurse inside the
60 # subdirectories, remember to use it without working dir.
61 try:
62 recurse = {'*': False, '**': True}[roottail]
63 except KeyError:
58 self.repos.append((prefix, root))
64 self.repos.append((prefix, root))
59 continue
65 continue
60 # "foo = /bar/*" makes every subrepo of /bar/ to be
61 # mounted as foo/subrepo
62 roothead = os.path.normpath(roothead)
66 roothead = os.path.normpath(roothead)
63 for path in util.walkrepos(roothead, followsym=True):
67 for path in util.walkrepos(roothead, followsym=True,
68 recurse=recurse):
64 path = os.path.normpath(path)
69 path = os.path.normpath(path)
65 name = util.pconvert(path[len(roothead):]).strip('/')
70 name = util.pconvert(path[len(roothead):]).strip('/')
66 if prefix:
71 if prefix:
@@ -1876,7 +1876,7 def ellipsis(text, maxlength=400):
1876 else:
1876 else:
1877 return "%s..." % (text[:maxlength-3])
1877 return "%s..." % (text[:maxlength-3])
1878
1878
1879 def walkrepos(path, followsym=False, seen_dirs=None):
1879 def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
1880 '''yield every hg repository under path, recursively.'''
1880 '''yield every hg repository under path, recursively.'''
1881 def errhandler(err):
1881 def errhandler(err):
1882 if err.filename == path:
1882 if err.filename == path:
@@ -1901,11 +1901,16 def walkrepos(path, followsym=False, see
1901 _add_dir_if_not_there(seen_dirs, path)
1901 _add_dir_if_not_there(seen_dirs, path)
1902 for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
1902 for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
1903 if '.hg' in dirs:
1903 if '.hg' in dirs:
1904 dirs[:] = [] # don't descend further
1905 yield root # found a repository
1904 yield root # found a repository
1905 if recurse:
1906 # avoid recursing inside the .hg directory
1907 # the mq repository is added in any case
1908 dirs.remove('.hg')
1906 qroot = os.path.join(root, '.hg', 'patches')
1909 qroot = os.path.join(root, '.hg', 'patches')
1907 if os.path.isdir(os.path.join(qroot, '.hg')):
1910 if os.path.isdir(os.path.join(qroot, '.hg')):
1908 yield qroot # we have a patch queue repo here
1911 yield qroot # we have a patch queue repo here
1912 else:
1913 dirs[:] = [] # don't descend further
1909 elif followsym:
1914 elif followsym:
1910 newdirs = []
1915 newdirs = []
1911 for d in dirs:
1916 for d in dirs:
@@ -8,16 +8,25 cd webdir
8 hg init a
8 hg init a
9 echo a > a/a
9 echo a > a/a
10 hg --cwd a ci -Ama -d'1 0'
10 hg --cwd a ci -Ama -d'1 0'
11 # create a mercurial queue repository
12 hg --cwd a qinit --config extensions.hgext.mq= -c
11
13
12 hg init b
14 hg init b
13 echo b > b/b
15 echo b > b/b
14 hg --cwd b ci -Amb -d'2 0'
16 hg --cwd b ci -Amb -d'2 0'
15
17
18 # create a nested repository
19 cd b
20 hg init d
21 echo d > d/d
22 hg --cwd d ci -Amd -d'3 0'
23 cd ..
24
16 hg init c
25 hg init c
17 echo c > c/c
26 echo c > c/c
18 hg --cwd c ci -Amc -d'3 0'
27 hg --cwd c ci -Amc -d'3 0'
28
19 root=`pwd`
29 root=`pwd`
20
21 cd ..
30 cd ..
22
31
23 cat > paths.conf <<EOF
32 cat > paths.conf <<EOF
@@ -46,6 +55,7 cat > paths.conf <<EOF
46 t/a/=$root/a
55 t/a/=$root/a
47 b=$root/b
56 b=$root/b
48 coll=$root/*
57 coll=$root/*
58 rcoll=$root/**
49 EOF
59 EOF
50
60
51 hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
61 hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
@@ -64,6 +74,10 echo % should succeed, slashy names
64 # Test [paths] '*' extension
74 # Test [paths] '*' extension
65 "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/coll/?style=raw'
75 "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/coll/?style=raw'
66 "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/coll/a/file/tip/a?style=raw'
76 "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/coll/a/file/tip/a?style=raw'
77 #test [paths] '**' extension
78 "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/?style=raw'
79 "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/b/d/file/tip/d?style=raw'
80
67
81
68 cat > collections.conf <<EOF
82 cat > collections.conf <<EOF
69 [collections]
83 [collections]
@@ -74,7 +88,7 hg serve -p $HGPORT2 -d --pid-file=hg.pi
74 -A access-collections.log -E error-collections.log
88 -A access-collections.log -E error-collections.log
75 cat hg.pid >> $DAEMON_PIDS
89 cat hg.pid >> $DAEMON_PIDS
76
90
77 echo % should succeed
91 echo % collections: should succeed
78 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/?style=raw'
92 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/?style=raw'
79 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/a/file/tip/a?style=raw'
93 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/a/file/tip/a?style=raw'
80 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/b/file/tip/b?style=raw'
94 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/b/file/tip/b?style=raw'
@@ -1,5 +1,6
1 adding a
1 adding a
2 adding b
2 adding b
3 adding d
3 adding c
4 adding c
4 % should give a 404 - file does not exist
5 % should give a 404 - file does not exist
5 404 Not Found
6 404 Not Found
@@ -32,6 +33,11 200 Script output follows
32 /coll/a/
33 /coll/a/
33 /coll/b/
34 /coll/b/
34 /coll/c/
35 /coll/c/
36 /rcoll/a/
37 /rcoll/a/.hg/patches/
38 /rcoll/b/
39 /rcoll/b/d/
40 /rcoll/c/
35 /t/a/
41 /t/a/
36
42
37 200 Script output follows
43 200 Script output follows
@@ -115,7 +121,19 200 Script output follows
115 200 Script output follows
121 200 Script output follows
116
122
117 a
123 a
118 % should succeed
124 200 Script output follows
125
126
127 /rcoll/a/
128 /rcoll/a/.hg/patches/
129 /rcoll/b/
130 /rcoll/b/d/
131 /rcoll/c/
132
133 200 Script output follows
134
135 d
136 % collections: should succeed
119 200 Script output follows
137 200 Script output follows
120
138
121
139
General Comments 0
You need to be logged in to leave comments. Login now