##// END OF EJS Templates
core: finished removal of pyro4....
marcink -
r213:28f26574 default
parent child Browse files
Show More
@@ -1,85 +1,79 b''
1 ################################################################################
1 ################################################################################
2 # RhodeCode VCSServer with HTTP Backend - configuration #
2 # RhodeCode VCSServer with HTTP Backend - configuration #
3 # #
3 # #
4 ################################################################################
4 ################################################################################
5
5
6 [app:main]
6 [app:main]
7 use = egg:rhodecode-vcsserver
7 use = egg:rhodecode-vcsserver
8
8
9 pyramid.default_locale_name = en
9 pyramid.default_locale_name = en
10 pyramid.includes =
10 pyramid.includes =
11
11
12 # default locale used by VCS systems
12 # default locale used by VCS systems
13 locale = en_US.UTF-8
13 locale = en_US.UTF-8
14
14
15 # cache regions, please don't change
15 # cache regions, please don't change
16 beaker.cache.regions = repo_object
16 beaker.cache.regions = repo_object
17 beaker.cache.repo_object.type = memorylru
17 beaker.cache.repo_object.type = memorylru
18 beaker.cache.repo_object.max_items = 100
18 beaker.cache.repo_object.max_items = 100
19 # cache auto-expires after N seconds
19 # cache auto-expires after N seconds
20 beaker.cache.repo_object.expire = 300
20 beaker.cache.repo_object.expire = 300
21 beaker.cache.repo_object.enabled = true
21 beaker.cache.repo_object.enabled = true
22
22
23 [server:main]
23 [server:main]
24 ## COMMON ##
24 ## COMMON ##
25 host = 0.0.0.0
25 host = 0.0.0.0
26 port = 9900
26 port = 9900
27
27
28 use = egg:waitress#main
28 use = egg:waitress#main
29
29
30
30
31 ################################
31 ################################
32 ### LOGGING CONFIGURATION ####
32 ### LOGGING CONFIGURATION ####
33 ################################
33 ################################
34 [loggers]
34 [loggers]
35 keys = root, vcsserver, pyro4, beaker
35 keys = root, vcsserver, beaker
36
36
37 [handlers]
37 [handlers]
38 keys = console
38 keys = console
39
39
40 [formatters]
40 [formatters]
41 keys = generic
41 keys = generic
42
42
43 #############
43 #############
44 ## LOGGERS ##
44 ## LOGGERS ##
45 #############
45 #############
46 [logger_root]
46 [logger_root]
47 level = NOTSET
47 level = NOTSET
48 handlers = console
48 handlers = console
49
49
50 [logger_vcsserver]
50 [logger_vcsserver]
51 level = DEBUG
51 level = DEBUG
52 handlers =
52 handlers =
53 qualname = vcsserver
53 qualname = vcsserver
54 propagate = 1
54 propagate = 1
55
55
56 [logger_beaker]
56 [logger_beaker]
57 level = DEBUG
57 level = DEBUG
58 handlers =
58 handlers =
59 qualname = beaker
59 qualname = beaker
60 propagate = 1
60 propagate = 1
61
61
62 [logger_pyro4]
63 level = DEBUG
64 handlers =
65 qualname = Pyro4
66 propagate = 1
67
68
62
69 ##############
63 ##############
70 ## HANDLERS ##
64 ## HANDLERS ##
71 ##############
65 ##############
72
66
73 [handler_console]
67 [handler_console]
74 class = StreamHandler
68 class = StreamHandler
75 args = (sys.stderr,)
69 args = (sys.stderr,)
76 level = DEBUG
70 level = DEBUG
77 formatter = generic
71 formatter = generic
78
72
79 ################
73 ################
80 ## FORMATTERS ##
74 ## FORMATTERS ##
81 ################
75 ################
82
76
83 [formatter_generic]
77 [formatter_generic]
84 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
78 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
85 datefmt = %Y-%m-%d %H:%M:%S
79 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,109 +1,103 b''
1 ################################################################################
1 ################################################################################
2 # RhodeCode VCSServer with HTTP Backend - configuration #
2 # RhodeCode VCSServer with HTTP Backend - configuration #
3 # #
3 # #
4 ################################################################################
4 ################################################################################
5
5
6
6
7 [server:main]
7 [server:main]
8 ## COMMON ##
8 ## COMMON ##
9 host = 127.0.0.1
9 host = 127.0.0.1
10 port = 9900
10 port = 9900
11
11
12
12
13 ##########################
13 ##########################
14 ## GUNICORN WSGI SERVER ##
14 ## GUNICORN WSGI SERVER ##
15 ##########################
15 ##########################
16 ## run with gunicorn --log-config vcsserver.ini --paste vcsserver.ini
16 ## run with gunicorn --log-config vcsserver.ini --paste vcsserver.ini
17 use = egg:gunicorn#main
17 use = egg:gunicorn#main
18 ## Sets the number of process workers. Recommended
18 ## Sets the number of process workers. Recommended
19 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
19 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
20 workers = 2
20 workers = 2
21 ## process name
21 ## process name
22 proc_name = rhodecode_vcsserver
22 proc_name = rhodecode_vcsserver
23 ## type of worker class, one of sync, gevent
23 ## type of worker class, one of sync, gevent
24 ## recommended for bigger setup is using of of other than sync one
24 ## recommended for bigger setup is using of of other than sync one
25 worker_class = sync
25 worker_class = sync
26 ## The maximum number of simultaneous clients. Valid only for Gevent
26 ## The maximum number of simultaneous clients. Valid only for Gevent
27 #worker_connections = 10
27 #worker_connections = 10
28 ## max number of requests that worker will handle before being gracefully
28 ## max number of requests that worker will handle before being gracefully
29 ## restarted, could prevent memory leaks
29 ## restarted, could prevent memory leaks
30 max_requests = 1000
30 max_requests = 1000
31 max_requests_jitter = 30
31 max_requests_jitter = 30
32 ## amount of time a worker can spend with handling a request before it
32 ## amount of time a worker can spend with handling a request before it
33 ## gets killed and restarted. Set to 6hrs
33 ## gets killed and restarted. Set to 6hrs
34 timeout = 21600
34 timeout = 21600
35
35
36
36
37 [app:main]
37 [app:main]
38 use = egg:rhodecode-vcsserver
38 use = egg:rhodecode-vcsserver
39
39
40 pyramid.default_locale_name = en
40 pyramid.default_locale_name = en
41 pyramid.includes =
41 pyramid.includes =
42
42
43 ## default locale used by VCS systems
43 ## default locale used by VCS systems
44 locale = en_US.UTF-8
44 locale = en_US.UTF-8
45
45
46 # cache regions, please don't change
46 # cache regions, please don't change
47 beaker.cache.regions = repo_object
47 beaker.cache.regions = repo_object
48 beaker.cache.repo_object.type = memorylru
48 beaker.cache.repo_object.type = memorylru
49 beaker.cache.repo_object.max_items = 100
49 beaker.cache.repo_object.max_items = 100
50 # cache auto-expires after N seconds
50 # cache auto-expires after N seconds
51 beaker.cache.repo_object.expire = 300
51 beaker.cache.repo_object.expire = 300
52 beaker.cache.repo_object.enabled = true
52 beaker.cache.repo_object.enabled = true
53
53
54
54
55 ################################
55 ################################
56 ### LOGGING CONFIGURATION ####
56 ### LOGGING CONFIGURATION ####
57 ################################
57 ################################
58 [loggers]
58 [loggers]
59 keys = root, vcsserver, pyro4, beaker
59 keys = root, vcsserver, beaker
60
60
61 [handlers]
61 [handlers]
62 keys = console
62 keys = console
63
63
64 [formatters]
64 [formatters]
65 keys = generic
65 keys = generic
66
66
67 #############
67 #############
68 ## LOGGERS ##
68 ## LOGGERS ##
69 #############
69 #############
70 [logger_root]
70 [logger_root]
71 level = NOTSET
71 level = NOTSET
72 handlers = console
72 handlers = console
73
73
74 [logger_vcsserver]
74 [logger_vcsserver]
75 level = DEBUG
75 level = DEBUG
76 handlers =
76 handlers =
77 qualname = vcsserver
77 qualname = vcsserver
78 propagate = 1
78 propagate = 1
79
79
80 [logger_beaker]
80 [logger_beaker]
81 level = DEBUG
81 level = DEBUG
82 handlers =
82 handlers =
83 qualname = beaker
83 qualname = beaker
84 propagate = 1
84 propagate = 1
85
85
86 [logger_pyro4]
87 level = DEBUG
88 handlers =
89 qualname = Pyro4
90 propagate = 1
91
92
86
93 ##############
87 ##############
94 ## HANDLERS ##
88 ## HANDLERS ##
95 ##############
89 ##############
96
90
97 [handler_console]
91 [handler_console]
98 class = StreamHandler
92 class = StreamHandler
99 args = (sys.stderr,)
93 args = (sys.stderr,)
100 level = DEBUG
94 level = DEBUG
101 formatter = generic
95 formatter = generic
102
96
103 ################
97 ################
104 ## FORMATTERS ##
98 ## FORMATTERS ##
105 ################
99 ################
106
100
107 [formatter_generic]
101 [formatter_generic]
108 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
102 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
109 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
103 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,812 +1,786 b''
1 # Generated by pip2nix 0.4.0
1 # Generated by pip2nix 0.4.0
2 # See https://github.com/johbo/pip2nix
2 # See https://github.com/johbo/pip2nix
3
3
4 {
4 {
5 Beaker = super.buildPythonPackage {
5 Beaker = super.buildPythonPackage {
6 name = "Beaker-1.7.0";
6 name = "Beaker-1.7.0";
7 buildInputs = with self; [];
7 buildInputs = with self; [];
8 doCheck = false;
8 doCheck = false;
9 propagatedBuildInputs = with self; [];
9 propagatedBuildInputs = with self; [];
10 src = fetchurl {
10 src = fetchurl {
11 url = "https://pypi.python.org/packages/97/8e/409d2e7c009b8aa803dc9e6f239f1db7c3cdf578249087a404e7c27a505d/Beaker-1.7.0.tar.gz";
11 url = "https://pypi.python.org/packages/97/8e/409d2e7c009b8aa803dc9e6f239f1db7c3cdf578249087a404e7c27a505d/Beaker-1.7.0.tar.gz";
12 md5 = "386be3f7fe427358881eee4622b428b3";
12 md5 = "386be3f7fe427358881eee4622b428b3";
13 };
13 };
14 meta = {
14 meta = {
15 license = [ pkgs.lib.licenses.bsdOriginal ];
15 license = [ pkgs.lib.licenses.bsdOriginal ];
16 };
16 };
17 };
17 };
18 Jinja2 = super.buildPythonPackage {
18 Jinja2 = super.buildPythonPackage {
19 name = "Jinja2-2.8";
19 name = "Jinja2-2.8";
20 buildInputs = with self; [];
20 buildInputs = with self; [];
21 doCheck = false;
21 doCheck = false;
22 propagatedBuildInputs = with self; [MarkupSafe];
22 propagatedBuildInputs = with self; [MarkupSafe];
23 src = fetchurl {
23 src = fetchurl {
24 url = "https://pypi.python.org/packages/f2/2f/0b98b06a345a761bec91a079ccae392d282690c2d8272e708f4d10829e22/Jinja2-2.8.tar.gz";
24 url = "https://pypi.python.org/packages/f2/2f/0b98b06a345a761bec91a079ccae392d282690c2d8272e708f4d10829e22/Jinja2-2.8.tar.gz";
25 md5 = "edb51693fe22c53cee5403775c71a99e";
25 md5 = "edb51693fe22c53cee5403775c71a99e";
26 };
26 };
27 meta = {
27 meta = {
28 license = [ pkgs.lib.licenses.bsdOriginal ];
28 license = [ pkgs.lib.licenses.bsdOriginal ];
29 };
29 };
30 };
30 };
31 Mako = super.buildPythonPackage {
31 Mako = super.buildPythonPackage {
32 name = "Mako-1.0.6";
32 name = "Mako-1.0.6";
33 buildInputs = with self; [];
33 buildInputs = with self; [];
34 doCheck = false;
34 doCheck = false;
35 propagatedBuildInputs = with self; [MarkupSafe];
35 propagatedBuildInputs = with self; [MarkupSafe];
36 src = fetchurl {
36 src = fetchurl {
37 url = "https://pypi.python.org/packages/56/4b/cb75836863a6382199aefb3d3809937e21fa4cb0db15a4f4ba0ecc2e7e8e/Mako-1.0.6.tar.gz";
37 url = "https://pypi.python.org/packages/56/4b/cb75836863a6382199aefb3d3809937e21fa4cb0db15a4f4ba0ecc2e7e8e/Mako-1.0.6.tar.gz";
38 md5 = "a28e22a339080316b2acc352b9ee631c";
38 md5 = "a28e22a339080316b2acc352b9ee631c";
39 };
39 };
40 meta = {
40 meta = {
41 license = [ pkgs.lib.licenses.mit ];
41 license = [ pkgs.lib.licenses.mit ];
42 };
42 };
43 };
43 };
44 MarkupSafe = super.buildPythonPackage {
44 MarkupSafe = super.buildPythonPackage {
45 name = "MarkupSafe-0.23";
45 name = "MarkupSafe-0.23";
46 buildInputs = with self; [];
46 buildInputs = with self; [];
47 doCheck = false;
47 doCheck = false;
48 propagatedBuildInputs = with self; [];
48 propagatedBuildInputs = with self; [];
49 src = fetchurl {
49 src = fetchurl {
50 url = "https://pypi.python.org/packages/c0/41/bae1254e0396c0cc8cf1751cb7d9afc90a602353695af5952530482c963f/MarkupSafe-0.23.tar.gz";
50 url = "https://pypi.python.org/packages/c0/41/bae1254e0396c0cc8cf1751cb7d9afc90a602353695af5952530482c963f/MarkupSafe-0.23.tar.gz";
51 md5 = "f5ab3deee4c37cd6a922fb81e730da6e";
51 md5 = "f5ab3deee4c37cd6a922fb81e730da6e";
52 };
52 };
53 meta = {
53 meta = {
54 license = [ pkgs.lib.licenses.bsdOriginal ];
54 license = [ pkgs.lib.licenses.bsdOriginal ];
55 };
55 };
56 };
56 };
57 PasteDeploy = super.buildPythonPackage {
57 PasteDeploy = super.buildPythonPackage {
58 name = "PasteDeploy-1.5.2";
58 name = "PasteDeploy-1.5.2";
59 buildInputs = with self; [];
59 buildInputs = with self; [];
60 doCheck = false;
60 doCheck = false;
61 propagatedBuildInputs = with self; [];
61 propagatedBuildInputs = with self; [];
62 src = fetchurl {
62 src = fetchurl {
63 url = "https://pypi.python.org/packages/0f/90/8e20cdae206c543ea10793cbf4136eb9a8b3f417e04e40a29d72d9922cbd/PasteDeploy-1.5.2.tar.gz";
63 url = "https://pypi.python.org/packages/0f/90/8e20cdae206c543ea10793cbf4136eb9a8b3f417e04e40a29d72d9922cbd/PasteDeploy-1.5.2.tar.gz";
64 md5 = "352b7205c78c8de4987578d19431af3b";
64 md5 = "352b7205c78c8de4987578d19431af3b";
65 };
65 };
66 meta = {
66 meta = {
67 license = [ pkgs.lib.licenses.mit ];
67 license = [ pkgs.lib.licenses.mit ];
68 };
68 };
69 };
69 };
70 Pyro4 = super.buildPythonPackage {
71 name = "Pyro4-4.41";
72 buildInputs = with self; [];
73 doCheck = false;
74 propagatedBuildInputs = with self; [serpent];
75 src = fetchurl {
76 url = "https://pypi.python.org/packages/56/2b/89b566b4bf3e7f8ba790db2d1223852f8cb454c52cab7693dd41f608ca2a/Pyro4-4.41.tar.gz";
77 md5 = "ed69e9bfafa9c06c049a87cb0c4c2b6c";
78 };
79 meta = {
80 license = [ pkgs.lib.licenses.mit ];
81 };
82 };
83 WebOb = super.buildPythonPackage {
70 WebOb = super.buildPythonPackage {
84 name = "WebOb-1.3.1";
71 name = "WebOb-1.3.1";
85 buildInputs = with self; [];
72 buildInputs = with self; [];
86 doCheck = false;
73 doCheck = false;
87 propagatedBuildInputs = with self; [];
74 propagatedBuildInputs = with self; [];
88 src = fetchurl {
75 src = fetchurl {
89 url = "https://pypi.python.org/packages/16/78/adfc0380b8a0d75b2d543fa7085ba98a573b1ae486d9def88d172b81b9fa/WebOb-1.3.1.tar.gz";
76 url = "https://pypi.python.org/packages/16/78/adfc0380b8a0d75b2d543fa7085ba98a573b1ae486d9def88d172b81b9fa/WebOb-1.3.1.tar.gz";
90 md5 = "20918251c5726956ba8fef22d1556177";
77 md5 = "20918251c5726956ba8fef22d1556177";
91 };
78 };
92 meta = {
79 meta = {
93 license = [ pkgs.lib.licenses.mit ];
80 license = [ pkgs.lib.licenses.mit ];
94 };
81 };
95 };
82 };
96 WebTest = super.buildPythonPackage {
83 WebTest = super.buildPythonPackage {
97 name = "WebTest-1.4.3";
84 name = "WebTest-1.4.3";
98 buildInputs = with self; [];
85 buildInputs = with self; [];
99 doCheck = false;
86 doCheck = false;
100 propagatedBuildInputs = with self; [WebOb];
87 propagatedBuildInputs = with self; [WebOb];
101 src = fetchurl {
88 src = fetchurl {
102 url = "https://pypi.python.org/packages/51/3d/84fd0f628df10b30c7db87895f56d0158e5411206b721ca903cb51bfd948/WebTest-1.4.3.zip";
89 url = "https://pypi.python.org/packages/51/3d/84fd0f628df10b30c7db87895f56d0158e5411206b721ca903cb51bfd948/WebTest-1.4.3.zip";
103 md5 = "631ce728bed92c681a4020a36adbc353";
90 md5 = "631ce728bed92c681a4020a36adbc353";
104 };
91 };
105 meta = {
92 meta = {
106 license = [ pkgs.lib.licenses.mit ];
93 license = [ pkgs.lib.licenses.mit ];
107 };
94 };
108 };
95 };
109 backports.shutil-get-terminal-size = super.buildPythonPackage {
96 backports.shutil-get-terminal-size = super.buildPythonPackage {
110 name = "backports.shutil-get-terminal-size-1.0.0";
97 name = "backports.shutil-get-terminal-size-1.0.0";
111 buildInputs = with self; [];
98 buildInputs = with self; [];
112 doCheck = false;
99 doCheck = false;
113 propagatedBuildInputs = with self; [];
100 propagatedBuildInputs = with self; [];
114 src = fetchurl {
101 src = fetchurl {
115 url = "https://pypi.python.org/packages/ec/9c/368086faa9c016efce5da3e0e13ba392c9db79e3ab740b763fe28620b18b/backports.shutil_get_terminal_size-1.0.0.tar.gz";
102 url = "https://pypi.python.org/packages/ec/9c/368086faa9c016efce5da3e0e13ba392c9db79e3ab740b763fe28620b18b/backports.shutil_get_terminal_size-1.0.0.tar.gz";
116 md5 = "03267762480bd86b50580dc19dff3c66";
103 md5 = "03267762480bd86b50580dc19dff3c66";
117 };
104 };
118 meta = {
105 meta = {
119 license = [ pkgs.lib.licenses.mit ];
106 license = [ pkgs.lib.licenses.mit ];
120 };
107 };
121 };
108 };
122 configobj = super.buildPythonPackage {
109 configobj = super.buildPythonPackage {
123 name = "configobj-5.0.6";
110 name = "configobj-5.0.6";
124 buildInputs = with self; [];
111 buildInputs = with self; [];
125 doCheck = false;
112 doCheck = false;
126 propagatedBuildInputs = with self; [six];
113 propagatedBuildInputs = with self; [six];
127 src = fetchurl {
114 src = fetchurl {
128 url = "https://pypi.python.org/packages/64/61/079eb60459c44929e684fa7d9e2fdca403f67d64dd9dbac27296be2e0fab/configobj-5.0.6.tar.gz";
115 url = "https://pypi.python.org/packages/64/61/079eb60459c44929e684fa7d9e2fdca403f67d64dd9dbac27296be2e0fab/configobj-5.0.6.tar.gz";
129 md5 = "e472a3a1c2a67bb0ec9b5d54c13a47d6";
116 md5 = "e472a3a1c2a67bb0ec9b5d54c13a47d6";
130 };
117 };
131 meta = {
118 meta = {
132 license = [ pkgs.lib.licenses.bsdOriginal ];
119 license = [ pkgs.lib.licenses.bsdOriginal ];
133 };
120 };
134 };
121 };
135 cov-core = super.buildPythonPackage {
122 cov-core = super.buildPythonPackage {
136 name = "cov-core-1.15.0";
123 name = "cov-core-1.15.0";
137 buildInputs = with self; [];
124 buildInputs = with self; [];
138 doCheck = false;
125 doCheck = false;
139 propagatedBuildInputs = with self; [coverage];
126 propagatedBuildInputs = with self; [coverage];
140 src = fetchurl {
127 src = fetchurl {
141 url = "https://pypi.python.org/packages/4b/87/13e75a47b4ba1be06f29f6d807ca99638bedc6b57fa491cd3de891ca2923/cov-core-1.15.0.tar.gz";
128 url = "https://pypi.python.org/packages/4b/87/13e75a47b4ba1be06f29f6d807ca99638bedc6b57fa491cd3de891ca2923/cov-core-1.15.0.tar.gz";
142 md5 = "f519d4cb4c4e52856afb14af52919fe6";
129 md5 = "f519d4cb4c4e52856afb14af52919fe6";
143 };
130 };
144 meta = {
131 meta = {
145 license = [ pkgs.lib.licenses.mit ];
132 license = [ pkgs.lib.licenses.mit ];
146 };
133 };
147 };
134 };
148 coverage = super.buildPythonPackage {
135 coverage = super.buildPythonPackage {
149 name = "coverage-3.7.1";
136 name = "coverage-3.7.1";
150 buildInputs = with self; [];
137 buildInputs = with self; [];
151 doCheck = false;
138 doCheck = false;
152 propagatedBuildInputs = with self; [];
139 propagatedBuildInputs = with self; [];
153 src = fetchurl {
140 src = fetchurl {
154 url = "https://pypi.python.org/packages/09/4f/89b06c7fdc09687bca507dc411c342556ef9c5a3b26756137a4878ff19bf/coverage-3.7.1.tar.gz";
141 url = "https://pypi.python.org/packages/09/4f/89b06c7fdc09687bca507dc411c342556ef9c5a3b26756137a4878ff19bf/coverage-3.7.1.tar.gz";
155 md5 = "c47b36ceb17eaff3ecfab3bcd347d0df";
142 md5 = "c47b36ceb17eaff3ecfab3bcd347d0df";
156 };
143 };
157 meta = {
144 meta = {
158 license = [ pkgs.lib.licenses.bsdOriginal ];
145 license = [ pkgs.lib.licenses.bsdOriginal ];
159 };
146 };
160 };
147 };
161 decorator = super.buildPythonPackage {
148 decorator = super.buildPythonPackage {
162 name = "decorator-4.0.11";
149 name = "decorator-4.0.11";
163 buildInputs = with self; [];
150 buildInputs = with self; [];
164 doCheck = false;
151 doCheck = false;
165 propagatedBuildInputs = with self; [];
152 propagatedBuildInputs = with self; [];
166 src = fetchurl {
153 src = fetchurl {
167 url = "https://pypi.python.org/packages/cc/ac/5a16f1fc0506ff72fcc8fd4e858e3a1c231f224ab79bb7c4c9b2094cc570/decorator-4.0.11.tar.gz";
154 url = "https://pypi.python.org/packages/cc/ac/5a16f1fc0506ff72fcc8fd4e858e3a1c231f224ab79bb7c4c9b2094cc570/decorator-4.0.11.tar.gz";
168 md5 = "73644c8f0bd4983d1b6a34b49adec0ae";
155 md5 = "73644c8f0bd4983d1b6a34b49adec0ae";
169 };
156 };
170 meta = {
157 meta = {
171 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "new BSD License"; } ];
158 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "new BSD License"; } ];
172 };
159 };
173 };
160 };
174 dulwich = super.buildPythonPackage {
161 dulwich = super.buildPythonPackage {
175 name = "dulwich-0.13.0";
162 name = "dulwich-0.13.0";
176 buildInputs = with self; [];
163 buildInputs = with self; [];
177 doCheck = false;
164 doCheck = false;
178 propagatedBuildInputs = with self; [];
165 propagatedBuildInputs = with self; [];
179 src = fetchurl {
166 src = fetchurl {
180 url = "https://pypi.python.org/packages/84/95/732d280eee829dacc954e8109f97b47abcadcca472c2ab013e1635eb4792/dulwich-0.13.0.tar.gz";
167 url = "https://pypi.python.org/packages/84/95/732d280eee829dacc954e8109f97b47abcadcca472c2ab013e1635eb4792/dulwich-0.13.0.tar.gz";
181 md5 = "6dede0626657c2bd08f48ca1221eea91";
168 md5 = "6dede0626657c2bd08f48ca1221eea91";
182 };
169 };
183 meta = {
170 meta = {
184 license = [ pkgs.lib.licenses.gpl2Plus ];
171 license = [ pkgs.lib.licenses.gpl2Plus ];
185 };
172 };
186 };
173 };
187 enum34 = super.buildPythonPackage {
174 enum34 = super.buildPythonPackage {
188 name = "enum34-1.1.6";
175 name = "enum34-1.1.6";
189 buildInputs = with self; [];
176 buildInputs = with self; [];
190 doCheck = false;
177 doCheck = false;
191 propagatedBuildInputs = with self; [];
178 propagatedBuildInputs = with self; [];
192 src = fetchurl {
179 src = fetchurl {
193 url = "https://pypi.python.org/packages/bf/3e/31d502c25302814a7c2f1d3959d2a3b3f78e509002ba91aea64993936876/enum34-1.1.6.tar.gz";
180 url = "https://pypi.python.org/packages/bf/3e/31d502c25302814a7c2f1d3959d2a3b3f78e509002ba91aea64993936876/enum34-1.1.6.tar.gz";
194 md5 = "5f13a0841a61f7fc295c514490d120d0";
181 md5 = "5f13a0841a61f7fc295c514490d120d0";
195 };
182 };
196 meta = {
183 meta = {
197 license = [ pkgs.lib.licenses.bsdOriginal ];
184 license = [ pkgs.lib.licenses.bsdOriginal ];
198 };
185 };
199 };
186 };
200 gevent = super.buildPythonPackage {
187 gevent = super.buildPythonPackage {
201 name = "gevent-1.1.2";
188 name = "gevent-1.1.2";
202 buildInputs = with self; [];
189 buildInputs = with self; [];
203 doCheck = false;
190 doCheck = false;
204 propagatedBuildInputs = with self; [greenlet];
191 propagatedBuildInputs = with self; [greenlet];
205 src = fetchurl {
192 src = fetchurl {
206 url = "https://pypi.python.org/packages/43/8f/cb3224a0e6ab663547f45c10d0651cfd52633fde4283bf68d627084df8cc/gevent-1.1.2.tar.gz";
193 url = "https://pypi.python.org/packages/43/8f/cb3224a0e6ab663547f45c10d0651cfd52633fde4283bf68d627084df8cc/gevent-1.1.2.tar.gz";
207 md5 = "bb32a2f852a4997138014d5007215c6e";
194 md5 = "bb32a2f852a4997138014d5007215c6e";
208 };
195 };
209 meta = {
196 meta = {
210 license = [ pkgs.lib.licenses.mit ];
197 license = [ pkgs.lib.licenses.mit ];
211 };
198 };
212 };
199 };
213 gprof2dot = super.buildPythonPackage {
200 gprof2dot = super.buildPythonPackage {
214 name = "gprof2dot-2016.10.13";
201 name = "gprof2dot-2016.10.13";
215 buildInputs = with self; [];
202 buildInputs = with self; [];
216 doCheck = false;
203 doCheck = false;
217 propagatedBuildInputs = with self; [];
204 propagatedBuildInputs = with self; [];
218 src = fetchurl {
205 src = fetchurl {
219 url = "https://pypi.python.org/packages/a0/e0/73c71baed306f0402a00a94ffc7b2be94ad1296dfcb8b46912655b93154c/gprof2dot-2016.10.13.tar.gz";
206 url = "https://pypi.python.org/packages/a0/e0/73c71baed306f0402a00a94ffc7b2be94ad1296dfcb8b46912655b93154c/gprof2dot-2016.10.13.tar.gz";
220 md5 = "0125401f15fd2afe1df686a76c64a4fd";
207 md5 = "0125401f15fd2afe1df686a76c64a4fd";
221 };
208 };
222 meta = {
209 meta = {
223 license = [ { fullName = "LGPL"; } ];
210 license = [ { fullName = "LGPL"; } ];
224 };
211 };
225 };
212 };
226 greenlet = super.buildPythonPackage {
213 greenlet = super.buildPythonPackage {
227 name = "greenlet-0.4.10";
214 name = "greenlet-0.4.10";
228 buildInputs = with self; [];
215 buildInputs = with self; [];
229 doCheck = false;
216 doCheck = false;
230 propagatedBuildInputs = with self; [];
217 propagatedBuildInputs = with self; [];
231 src = fetchurl {
218 src = fetchurl {
232 url = "https://pypi.python.org/packages/67/62/ca2a95648666eaa2ffeb6a9b3964f21d419ae27f82f2e66b53da5b943fc4/greenlet-0.4.10.zip";
219 url = "https://pypi.python.org/packages/67/62/ca2a95648666eaa2ffeb6a9b3964f21d419ae27f82f2e66b53da5b943fc4/greenlet-0.4.10.zip";
233 md5 = "bed0c4b3b896702131f4d5c72f87c41d";
220 md5 = "bed0c4b3b896702131f4d5c72f87c41d";
234 };
221 };
235 meta = {
222 meta = {
236 license = [ pkgs.lib.licenses.mit ];
223 license = [ pkgs.lib.licenses.mit ];
237 };
224 };
238 };
225 };
239 gunicorn = super.buildPythonPackage {
226 gunicorn = super.buildPythonPackage {
240 name = "gunicorn-19.6.0";
227 name = "gunicorn-19.6.0";
241 buildInputs = with self; [];
228 buildInputs = with self; [];
242 doCheck = false;
229 doCheck = false;
243 propagatedBuildInputs = with self; [];
230 propagatedBuildInputs = with self; [];
244 src = fetchurl {
231 src = fetchurl {
245 url = "https://pypi.python.org/packages/84/ce/7ea5396efad1cef682bbc4068e72a0276341d9d9d0f501da609fab9fcb80/gunicorn-19.6.0.tar.gz";
232 url = "https://pypi.python.org/packages/84/ce/7ea5396efad1cef682bbc4068e72a0276341d9d9d0f501da609fab9fcb80/gunicorn-19.6.0.tar.gz";
246 md5 = "338e5e8a83ea0f0625f768dba4597530";
233 md5 = "338e5e8a83ea0f0625f768dba4597530";
247 };
234 };
248 meta = {
235 meta = {
249 license = [ pkgs.lib.licenses.mit ];
236 license = [ pkgs.lib.licenses.mit ];
250 };
237 };
251 };
238 };
252 hgsubversion = super.buildPythonPackage {
239 hgsubversion = super.buildPythonPackage {
253 name = "hgsubversion-1.8.6";
240 name = "hgsubversion-1.8.6";
254 buildInputs = with self; [];
241 buildInputs = with self; [];
255 doCheck = false;
242 doCheck = false;
256 propagatedBuildInputs = with self; [mercurial subvertpy];
243 propagatedBuildInputs = with self; [mercurial subvertpy];
257 src = fetchurl {
244 src = fetchurl {
258 url = "https://pypi.python.org/packages/ce/97/032e5093ad250e9908cea04395cbddb6902d587f712a79b53b2d778bdfdd/hgsubversion-1.8.6.tar.gz";
245 url = "https://pypi.python.org/packages/ce/97/032e5093ad250e9908cea04395cbddb6902d587f712a79b53b2d778bdfdd/hgsubversion-1.8.6.tar.gz";
259 md5 = "9310cb266031cf8d0779885782a84a5b";
246 md5 = "9310cb266031cf8d0779885782a84a5b";
260 };
247 };
261 meta = {
248 meta = {
262 license = [ pkgs.lib.licenses.gpl1 ];
249 license = [ pkgs.lib.licenses.gpl1 ];
263 };
250 };
264 };
251 };
265 infrae.cache = super.buildPythonPackage {
252 infrae.cache = super.buildPythonPackage {
266 name = "infrae.cache-1.0.1";
253 name = "infrae.cache-1.0.1";
267 buildInputs = with self; [];
254 buildInputs = with self; [];
268 doCheck = false;
255 doCheck = false;
269 propagatedBuildInputs = with self; [Beaker repoze.lru];
256 propagatedBuildInputs = with self; [Beaker repoze.lru];
270 src = fetchurl {
257 src = fetchurl {
271 url = "https://pypi.python.org/packages/bb/f0/e7d5e984cf6592fd2807dc7bc44a93f9d18e04e6a61f87fdfb2622422d74/infrae.cache-1.0.1.tar.gz";
258 url = "https://pypi.python.org/packages/bb/f0/e7d5e984cf6592fd2807dc7bc44a93f9d18e04e6a61f87fdfb2622422d74/infrae.cache-1.0.1.tar.gz";
272 md5 = "b09076a766747e6ed2a755cc62088e32";
259 md5 = "b09076a766747e6ed2a755cc62088e32";
273 };
260 };
274 meta = {
261 meta = {
275 license = [ pkgs.lib.licenses.zpt21 ];
262 license = [ pkgs.lib.licenses.zpt21 ];
276 };
263 };
277 };
264 };
278 ipdb = super.buildPythonPackage {
265 ipdb = super.buildPythonPackage {
279 name = "ipdb-0.10.1";
266 name = "ipdb-0.10.1";
280 buildInputs = with self; [];
267 buildInputs = with self; [];
281 doCheck = false;
268 doCheck = false;
282 propagatedBuildInputs = with self; [ipython setuptools];
269 propagatedBuildInputs = with self; [ipython setuptools];
283 src = fetchurl {
270 src = fetchurl {
284 url = "https://pypi.python.org/packages/eb/0a/0a37dc19572580336ad3813792c0d18c8d7117c2d66fc63c501f13a7a8f8/ipdb-0.10.1.tar.gz";
271 url = "https://pypi.python.org/packages/eb/0a/0a37dc19572580336ad3813792c0d18c8d7117c2d66fc63c501f13a7a8f8/ipdb-0.10.1.tar.gz";
285 md5 = "4aeab65f633ddc98ebdb5eebf08dc713";
272 md5 = "4aeab65f633ddc98ebdb5eebf08dc713";
286 };
273 };
287 meta = {
274 meta = {
288 license = [ pkgs.lib.licenses.bsdOriginal ];
275 license = [ pkgs.lib.licenses.bsdOriginal ];
289 };
276 };
290 };
277 };
291 ipython = super.buildPythonPackage {
278 ipython = super.buildPythonPackage {
292 name = "ipython-5.1.0";
279 name = "ipython-5.1.0";
293 buildInputs = with self; [];
280 buildInputs = with self; [];
294 doCheck = false;
281 doCheck = false;
295 propagatedBuildInputs = with self; [setuptools decorator pickleshare simplegeneric traitlets prompt-toolkit pygments pexpect backports.shutil-get-terminal-size pathlib2 pexpect];
282 propagatedBuildInputs = with self; [setuptools decorator pickleshare simplegeneric traitlets prompt-toolkit pygments pexpect backports.shutil-get-terminal-size pathlib2 pexpect];
296 src = fetchurl {
283 src = fetchurl {
297 url = "https://pypi.python.org/packages/89/63/a9292f7cd9d0090a0f995e1167f3f17d5889dcbc9a175261719c513b9848/ipython-5.1.0.tar.gz";
284 url = "https://pypi.python.org/packages/89/63/a9292f7cd9d0090a0f995e1167f3f17d5889dcbc9a175261719c513b9848/ipython-5.1.0.tar.gz";
298 md5 = "47c8122420f65b58784cb4b9b4af35e3";
285 md5 = "47c8122420f65b58784cb4b9b4af35e3";
299 };
286 };
300 meta = {
287 meta = {
301 license = [ pkgs.lib.licenses.bsdOriginal ];
288 license = [ pkgs.lib.licenses.bsdOriginal ];
302 };
289 };
303 };
290 };
304 ipython-genutils = super.buildPythonPackage {
291 ipython-genutils = super.buildPythonPackage {
305 name = "ipython-genutils-0.2.0";
292 name = "ipython-genutils-0.2.0";
306 buildInputs = with self; [];
293 buildInputs = with self; [];
307 doCheck = false;
294 doCheck = false;
308 propagatedBuildInputs = with self; [];
295 propagatedBuildInputs = with self; [];
309 src = fetchurl {
296 src = fetchurl {
310 url = "https://pypi.python.org/packages/e8/69/fbeffffc05236398ebfcfb512b6d2511c622871dca1746361006da310399/ipython_genutils-0.2.0.tar.gz";
297 url = "https://pypi.python.org/packages/e8/69/fbeffffc05236398ebfcfb512b6d2511c622871dca1746361006da310399/ipython_genutils-0.2.0.tar.gz";
311 md5 = "5a4f9781f78466da0ea1a648f3e1f79f";
298 md5 = "5a4f9781f78466da0ea1a648f3e1f79f";
312 };
299 };
313 meta = {
300 meta = {
314 license = [ pkgs.lib.licenses.bsdOriginal ];
301 license = [ pkgs.lib.licenses.bsdOriginal ];
315 };
302 };
316 };
303 };
317 mercurial = super.buildPythonPackage {
304 mercurial = super.buildPythonPackage {
318 name = "mercurial-4.1.2";
305 name = "mercurial-4.1.2";
319 buildInputs = with self; [];
306 buildInputs = with self; [];
320 doCheck = false;
307 doCheck = false;
321 propagatedBuildInputs = with self; [];
308 propagatedBuildInputs = with self; [];
322 src = fetchurl {
309 src = fetchurl {
323 url = "https://pypi.python.org/packages/88/c1/f0501fd67f5e69346da41ee0bd7b2619ce4bbc9854bb645074c418b9941f/mercurial-4.1.2.tar.gz";
310 url = "https://pypi.python.org/packages/88/c1/f0501fd67f5e69346da41ee0bd7b2619ce4bbc9854bb645074c418b9941f/mercurial-4.1.2.tar.gz";
324 md5 = "934c99808bdc8385e074b902d59b0d93";
311 md5 = "934c99808bdc8385e074b902d59b0d93";
325 };
312 };
326 meta = {
313 meta = {
327 license = [ pkgs.lib.licenses.gpl1 pkgs.lib.licenses.gpl2Plus ];
314 license = [ pkgs.lib.licenses.gpl1 pkgs.lib.licenses.gpl2Plus ];
328 };
315 };
329 };
316 };
330 mock = super.buildPythonPackage {
317 mock = super.buildPythonPackage {
331 name = "mock-1.0.1";
318 name = "mock-1.0.1";
332 buildInputs = with self; [];
319 buildInputs = with self; [];
333 doCheck = false;
320 doCheck = false;
334 propagatedBuildInputs = with self; [];
321 propagatedBuildInputs = with self; [];
335 src = fetchurl {
322 src = fetchurl {
336 url = "https://pypi.python.org/packages/15/45/30273ee91feb60dabb8fbb2da7868520525f02cf910279b3047182feed80/mock-1.0.1.zip";
323 url = "https://pypi.python.org/packages/15/45/30273ee91feb60dabb8fbb2da7868520525f02cf910279b3047182feed80/mock-1.0.1.zip";
337 md5 = "869f08d003c289a97c1a6610faf5e913";
324 md5 = "869f08d003c289a97c1a6610faf5e913";
338 };
325 };
339 meta = {
326 meta = {
340 license = [ pkgs.lib.licenses.bsdOriginal ];
327 license = [ pkgs.lib.licenses.bsdOriginal ];
341 };
328 };
342 };
329 };
343 msgpack-python = super.buildPythonPackage {
330 msgpack-python = super.buildPythonPackage {
344 name = "msgpack-python-0.4.8";
331 name = "msgpack-python-0.4.8";
345 buildInputs = with self; [];
332 buildInputs = with self; [];
346 doCheck = false;
333 doCheck = false;
347 propagatedBuildInputs = with self; [];
334 propagatedBuildInputs = with self; [];
348 src = fetchurl {
335 src = fetchurl {
349 url = "https://pypi.python.org/packages/21/27/8a1d82041c7a2a51fcc73675875a5f9ea06c2663e02fcfeb708be1d081a0/msgpack-python-0.4.8.tar.gz";
336 url = "https://pypi.python.org/packages/21/27/8a1d82041c7a2a51fcc73675875a5f9ea06c2663e02fcfeb708be1d081a0/msgpack-python-0.4.8.tar.gz";
350 md5 = "dcd854fb41ee7584ebbf35e049e6be98";
337 md5 = "dcd854fb41ee7584ebbf35e049e6be98";
351 };
338 };
352 meta = {
339 meta = {
353 license = [ pkgs.lib.licenses.asl20 ];
340 license = [ pkgs.lib.licenses.asl20 ];
354 };
341 };
355 };
342 };
356 pathlib2 = super.buildPythonPackage {
343 pathlib2 = super.buildPythonPackage {
357 name = "pathlib2-2.1.0";
344 name = "pathlib2-2.1.0";
358 buildInputs = with self; [];
345 buildInputs = with self; [];
359 doCheck = false;
346 doCheck = false;
360 propagatedBuildInputs = with self; [six];
347 propagatedBuildInputs = with self; [six];
361 src = fetchurl {
348 src = fetchurl {
362 url = "https://pypi.python.org/packages/c9/27/8448b10d8440c08efeff0794adf7d0ed27adb98372c70c7b38f3947d4749/pathlib2-2.1.0.tar.gz";
349 url = "https://pypi.python.org/packages/c9/27/8448b10d8440c08efeff0794adf7d0ed27adb98372c70c7b38f3947d4749/pathlib2-2.1.0.tar.gz";
363 md5 = "38e4f58b4d69dfcb9edb49a54a8b28d2";
350 md5 = "38e4f58b4d69dfcb9edb49a54a8b28d2";
364 };
351 };
365 meta = {
352 meta = {
366 license = [ pkgs.lib.licenses.mit ];
353 license = [ pkgs.lib.licenses.mit ];
367 };
354 };
368 };
355 };
369 pexpect = super.buildPythonPackage {
356 pexpect = super.buildPythonPackage {
370 name = "pexpect-4.2.1";
357 name = "pexpect-4.2.1";
371 buildInputs = with self; [];
358 buildInputs = with self; [];
372 doCheck = false;
359 doCheck = false;
373 propagatedBuildInputs = with self; [ptyprocess];
360 propagatedBuildInputs = with self; [ptyprocess];
374 src = fetchurl {
361 src = fetchurl {
375 url = "https://pypi.python.org/packages/e8/13/d0b0599099d6cd23663043a2a0bb7c61e58c6ba359b2656e6fb000ef5b98/pexpect-4.2.1.tar.gz";
362 url = "https://pypi.python.org/packages/e8/13/d0b0599099d6cd23663043a2a0bb7c61e58c6ba359b2656e6fb000ef5b98/pexpect-4.2.1.tar.gz";
376 md5 = "3694410001a99dff83f0b500a1ca1c95";
363 md5 = "3694410001a99dff83f0b500a1ca1c95";
377 };
364 };
378 meta = {
365 meta = {
379 license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ];
366 license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ];
380 };
367 };
381 };
368 };
382 pickleshare = super.buildPythonPackage {
369 pickleshare = super.buildPythonPackage {
383 name = "pickleshare-0.7.4";
370 name = "pickleshare-0.7.4";
384 buildInputs = with self; [];
371 buildInputs = with self; [];
385 doCheck = false;
372 doCheck = false;
386 propagatedBuildInputs = with self; [pathlib2];
373 propagatedBuildInputs = with self; [pathlib2];
387 src = fetchurl {
374 src = fetchurl {
388 url = "https://pypi.python.org/packages/69/fe/dd137d84daa0fd13a709e448138e310d9ea93070620c9db5454e234af525/pickleshare-0.7.4.tar.gz";
375 url = "https://pypi.python.org/packages/69/fe/dd137d84daa0fd13a709e448138e310d9ea93070620c9db5454e234af525/pickleshare-0.7.4.tar.gz";
389 md5 = "6a9e5dd8dfc023031f6b7b3f824cab12";
376 md5 = "6a9e5dd8dfc023031f6b7b3f824cab12";
390 };
377 };
391 meta = {
378 meta = {
392 license = [ pkgs.lib.licenses.mit ];
379 license = [ pkgs.lib.licenses.mit ];
393 };
380 };
394 };
381 };
395 prompt-toolkit = super.buildPythonPackage {
382 prompt-toolkit = super.buildPythonPackage {
396 name = "prompt-toolkit-1.0.14";
383 name = "prompt-toolkit-1.0.14";
397 buildInputs = with self; [];
384 buildInputs = with self; [];
398 doCheck = false;
385 doCheck = false;
399 propagatedBuildInputs = with self; [six wcwidth];
386 propagatedBuildInputs = with self; [six wcwidth];
400 src = fetchurl {
387 src = fetchurl {
401 url = "https://pypi.python.org/packages/55/56/8c39509b614bda53e638b7500f12577d663ac1b868aef53426fc6a26c3f5/prompt_toolkit-1.0.14.tar.gz";
388 url = "https://pypi.python.org/packages/55/56/8c39509b614bda53e638b7500f12577d663ac1b868aef53426fc6a26c3f5/prompt_toolkit-1.0.14.tar.gz";
402 md5 = "f24061ae133ed32c6b764e92bd48c496";
389 md5 = "f24061ae133ed32c6b764e92bd48c496";
403 };
390 };
404 meta = {
391 meta = {
405 license = [ pkgs.lib.licenses.bsdOriginal ];
392 license = [ pkgs.lib.licenses.bsdOriginal ];
406 };
393 };
407 };
394 };
408 ptyprocess = super.buildPythonPackage {
395 ptyprocess = super.buildPythonPackage {
409 name = "ptyprocess-0.5.1";
396 name = "ptyprocess-0.5.1";
410 buildInputs = with self; [];
397 buildInputs = with self; [];
411 doCheck = false;
398 doCheck = false;
412 propagatedBuildInputs = with self; [];
399 propagatedBuildInputs = with self; [];
413 src = fetchurl {
400 src = fetchurl {
414 url = "https://pypi.python.org/packages/db/d7/b465161910f3d1cef593c5e002bff67e0384898f597f1a7fdc8db4c02bf6/ptyprocess-0.5.1.tar.gz";
401 url = "https://pypi.python.org/packages/db/d7/b465161910f3d1cef593c5e002bff67e0384898f597f1a7fdc8db4c02bf6/ptyprocess-0.5.1.tar.gz";
415 md5 = "94e537122914cc9ec9c1eadcd36e73a1";
402 md5 = "94e537122914cc9ec9c1eadcd36e73a1";
416 };
403 };
417 meta = {
404 meta = {
418 license = [ ];
405 license = [ ];
419 };
406 };
420 };
407 };
421 py = super.buildPythonPackage {
408 py = super.buildPythonPackage {
422 name = "py-1.4.31";
409 name = "py-1.4.31";
423 buildInputs = with self; [];
410 buildInputs = with self; [];
424 doCheck = false;
411 doCheck = false;
425 propagatedBuildInputs = with self; [];
412 propagatedBuildInputs = with self; [];
426 src = fetchurl {
413 src = fetchurl {
427 url = "https://pypi.python.org/packages/f4/9a/8dfda23f36600dd701c6722316ba8a3ab4b990261f83e7d3ffc6dfedf7ef/py-1.4.31.tar.gz";
414 url = "https://pypi.python.org/packages/f4/9a/8dfda23f36600dd701c6722316ba8a3ab4b990261f83e7d3ffc6dfedf7ef/py-1.4.31.tar.gz";
428 md5 = "5d2c63c56dc3f2115ec35c066ecd582b";
415 md5 = "5d2c63c56dc3f2115ec35c066ecd582b";
429 };
416 };
430 meta = {
417 meta = {
431 license = [ pkgs.lib.licenses.mit ];
418 license = [ pkgs.lib.licenses.mit ];
432 };
419 };
433 };
420 };
434 pygments = super.buildPythonPackage {
421 pygments = super.buildPythonPackage {
435 name = "pygments-2.2.0";
422 name = "pygments-2.2.0";
436 buildInputs = with self; [];
423 buildInputs = with self; [];
437 doCheck = false;
424 doCheck = false;
438 propagatedBuildInputs = with self; [];
425 propagatedBuildInputs = with self; [];
439 src = fetchurl {
426 src = fetchurl {
440 url = "https://pypi.python.org/packages/71/2a/2e4e77803a8bd6408a2903340ac498cb0a2181811af7c9ec92cb70b0308a/Pygments-2.2.0.tar.gz";
427 url = "https://pypi.python.org/packages/71/2a/2e4e77803a8bd6408a2903340ac498cb0a2181811af7c9ec92cb70b0308a/Pygments-2.2.0.tar.gz";
441 md5 = "13037baca42f16917cbd5ad2fab50844";
428 md5 = "13037baca42f16917cbd5ad2fab50844";
442 };
429 };
443 meta = {
430 meta = {
444 license = [ pkgs.lib.licenses.bsdOriginal ];
431 license = [ pkgs.lib.licenses.bsdOriginal ];
445 };
432 };
446 };
433 };
447 pyramid = super.buildPythonPackage {
434 pyramid = super.buildPythonPackage {
448 name = "pyramid-1.7.4";
435 name = "pyramid-1.7.4";
449 buildInputs = with self; [];
436 buildInputs = with self; [];
450 doCheck = false;
437 doCheck = false;
451 propagatedBuildInputs = with self; [setuptools WebOb repoze.lru zope.interface zope.deprecation venusian translationstring PasteDeploy];
438 propagatedBuildInputs = with self; [setuptools WebOb repoze.lru zope.interface zope.deprecation venusian translationstring PasteDeploy];
452 src = fetchurl {
439 src = fetchurl {
453 url = "https://pypi.python.org/packages/33/91/55f5c661f8923902cd1f68d75f2b937c45e7682857356cf18f0be5493899/pyramid-1.7.4.tar.gz";
440 url = "https://pypi.python.org/packages/33/91/55f5c661f8923902cd1f68d75f2b937c45e7682857356cf18f0be5493899/pyramid-1.7.4.tar.gz";
454 md5 = "6ef1dfdcff9136d04490410757c4c446";
441 md5 = "6ef1dfdcff9136d04490410757c4c446";
455 };
442 };
456 meta = {
443 meta = {
457 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
444 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
458 };
445 };
459 };
446 };
460 pyramid-jinja2 = super.buildPythonPackage {
447 pyramid-jinja2 = super.buildPythonPackage {
461 name = "pyramid-jinja2-2.5";
448 name = "pyramid-jinja2-2.5";
462 buildInputs = with self; [];
449 buildInputs = with self; [];
463 doCheck = false;
450 doCheck = false;
464 propagatedBuildInputs = with self; [pyramid zope.deprecation Jinja2 MarkupSafe];
451 propagatedBuildInputs = with self; [pyramid zope.deprecation Jinja2 MarkupSafe];
465 src = fetchurl {
452 src = fetchurl {
466 url = "https://pypi.python.org/packages/a1/80/595e26ffab7deba7208676b6936b7e5a721875710f982e59899013cae1ed/pyramid_jinja2-2.5.tar.gz";
453 url = "https://pypi.python.org/packages/a1/80/595e26ffab7deba7208676b6936b7e5a721875710f982e59899013cae1ed/pyramid_jinja2-2.5.tar.gz";
467 md5 = "07cb6547204ac5e6f0b22a954ccee928";
454 md5 = "07cb6547204ac5e6f0b22a954ccee928";
468 };
455 };
469 meta = {
456 meta = {
470 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
457 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
471 };
458 };
472 };
459 };
473 pyramid-mako = super.buildPythonPackage {
460 pyramid-mako = super.buildPythonPackage {
474 name = "pyramid-mako-1.0.2";
461 name = "pyramid-mako-1.0.2";
475 buildInputs = with self; [];
462 buildInputs = with self; [];
476 doCheck = false;
463 doCheck = false;
477 propagatedBuildInputs = with self; [pyramid Mako];
464 propagatedBuildInputs = with self; [pyramid Mako];
478 src = fetchurl {
465 src = fetchurl {
479 url = "https://pypi.python.org/packages/f1/92/7e69bcf09676d286a71cb3bbb887b16595b96f9ba7adbdc239ffdd4b1eb9/pyramid_mako-1.0.2.tar.gz";
466 url = "https://pypi.python.org/packages/f1/92/7e69bcf09676d286a71cb3bbb887b16595b96f9ba7adbdc239ffdd4b1eb9/pyramid_mako-1.0.2.tar.gz";
480 md5 = "ee25343a97eb76bd90abdc2a774eb48a";
467 md5 = "ee25343a97eb76bd90abdc2a774eb48a";
481 };
468 };
482 meta = {
469 meta = {
483 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
470 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
484 };
471 };
485 };
472 };
486 pytest = super.buildPythonPackage {
473 pytest = super.buildPythonPackage {
487 name = "pytest-3.0.5";
474 name = "pytest-3.0.5";
488 buildInputs = with self; [];
475 buildInputs = with self; [];
489 doCheck = false;
476 doCheck = false;
490 propagatedBuildInputs = with self; [py];
477 propagatedBuildInputs = with self; [py];
491 src = fetchurl {
478 src = fetchurl {
492 url = "https://pypi.python.org/packages/a8/87/b7ca49efe52d2b4169f2bfc49aa5e384173c4619ea8e635f123a0dac5b75/pytest-3.0.5.tar.gz";
479 url = "https://pypi.python.org/packages/a8/87/b7ca49efe52d2b4169f2bfc49aa5e384173c4619ea8e635f123a0dac5b75/pytest-3.0.5.tar.gz";
493 md5 = "cefd527b59332688bf5db4a10aa8a7cb";
480 md5 = "cefd527b59332688bf5db4a10aa8a7cb";
494 };
481 };
495 meta = {
482 meta = {
496 license = [ pkgs.lib.licenses.mit ];
483 license = [ pkgs.lib.licenses.mit ];
497 };
484 };
498 };
485 };
499 pytest-catchlog = super.buildPythonPackage {
486 pytest-catchlog = super.buildPythonPackage {
500 name = "pytest-catchlog-1.2.2";
487 name = "pytest-catchlog-1.2.2";
501 buildInputs = with self; [];
488 buildInputs = with self; [];
502 doCheck = false;
489 doCheck = false;
503 propagatedBuildInputs = with self; [py pytest];
490 propagatedBuildInputs = with self; [py pytest];
504 src = fetchurl {
491 src = fetchurl {
505 url = "https://pypi.python.org/packages/f2/2b/2faccdb1a978fab9dd0bf31cca9f6847fbe9184a0bdcc3011ac41dd44191/pytest-catchlog-1.2.2.zip";
492 url = "https://pypi.python.org/packages/f2/2b/2faccdb1a978fab9dd0bf31cca9f6847fbe9184a0bdcc3011ac41dd44191/pytest-catchlog-1.2.2.zip";
506 md5 = "09d890c54c7456c818102b7ff8c182c8";
493 md5 = "09d890c54c7456c818102b7ff8c182c8";
507 };
494 };
508 meta = {
495 meta = {
509 license = [ pkgs.lib.licenses.mit ];
496 license = [ pkgs.lib.licenses.mit ];
510 };
497 };
511 };
498 };
512 pytest-cov = super.buildPythonPackage {
499 pytest-cov = super.buildPythonPackage {
513 name = "pytest-cov-2.4.0";
500 name = "pytest-cov-2.4.0";
514 buildInputs = with self; [];
501 buildInputs = with self; [];
515 doCheck = false;
502 doCheck = false;
516 propagatedBuildInputs = with self; [pytest coverage];
503 propagatedBuildInputs = with self; [pytest coverage];
517 src = fetchurl {
504 src = fetchurl {
518 url = "https://pypi.python.org/packages/00/c0/2bfd1fcdb9d407b8ac8185b1cb5ff458105c6b207a9a7f0e13032de9828f/pytest-cov-2.4.0.tar.gz";
505 url = "https://pypi.python.org/packages/00/c0/2bfd1fcdb9d407b8ac8185b1cb5ff458105c6b207a9a7f0e13032de9828f/pytest-cov-2.4.0.tar.gz";
519 md5 = "2fda09677d232acc99ec1b3c5831e33f";
506 md5 = "2fda09677d232acc99ec1b3c5831e33f";
520 };
507 };
521 meta = {
508 meta = {
522 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.mit ];
509 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.mit ];
523 };
510 };
524 };
511 };
525 pytest-profiling = super.buildPythonPackage {
512 pytest-profiling = super.buildPythonPackage {
526 name = "pytest-profiling-1.2.2";
513 name = "pytest-profiling-1.2.2";
527 buildInputs = with self; [];
514 buildInputs = with self; [];
528 doCheck = false;
515 doCheck = false;
529 propagatedBuildInputs = with self; [six pytest gprof2dot];
516 propagatedBuildInputs = with self; [six pytest gprof2dot];
530 src = fetchurl {
517 src = fetchurl {
531 url = "https://pypi.python.org/packages/73/e8/804681323bac0bc45c520ec34185ba8469008942266d0074699b204835c1/pytest-profiling-1.2.2.tar.gz";
518 url = "https://pypi.python.org/packages/73/e8/804681323bac0bc45c520ec34185ba8469008942266d0074699b204835c1/pytest-profiling-1.2.2.tar.gz";
532 md5 = "0a16d7dda2d23b91e9730fa4558cf728";
519 md5 = "0a16d7dda2d23b91e9730fa4558cf728";
533 };
520 };
534 meta = {
521 meta = {
535 license = [ pkgs.lib.licenses.mit ];
522 license = [ pkgs.lib.licenses.mit ];
536 };
523 };
537 };
524 };
538 pytest-runner = super.buildPythonPackage {
525 pytest-runner = super.buildPythonPackage {
539 name = "pytest-runner-2.9";
526 name = "pytest-runner-2.9";
540 buildInputs = with self; [];
527 buildInputs = with self; [];
541 doCheck = false;
528 doCheck = false;
542 propagatedBuildInputs = with self; [];
529 propagatedBuildInputs = with self; [];
543 src = fetchurl {
530 src = fetchurl {
544 url = "https://pypi.python.org/packages/11/d4/c335ddf94463e451109e3494e909765c3e5205787b772e3b25ee8601b86a/pytest-runner-2.9.tar.gz";
531 url = "https://pypi.python.org/packages/11/d4/c335ddf94463e451109e3494e909765c3e5205787b772e3b25ee8601b86a/pytest-runner-2.9.tar.gz";
545 md5 = "2212a2e34404b0960b2fdc2c469247b2";
532 md5 = "2212a2e34404b0960b2fdc2c469247b2";
546 };
533 };
547 meta = {
534 meta = {
548 license = [ pkgs.lib.licenses.mit ];
535 license = [ pkgs.lib.licenses.mit ];
549 };
536 };
550 };
537 };
551 pytest-sugar = super.buildPythonPackage {
538 pytest-sugar = super.buildPythonPackage {
552 name = "pytest-sugar-0.7.1";
539 name = "pytest-sugar-0.7.1";
553 buildInputs = with self; [];
540 buildInputs = with self; [];
554 doCheck = false;
541 doCheck = false;
555 propagatedBuildInputs = with self; [pytest termcolor];
542 propagatedBuildInputs = with self; [pytest termcolor];
556 src = fetchurl {
543 src = fetchurl {
557 url = "https://pypi.python.org/packages/03/97/05d988b4fa870e7373e8ee4582408543b9ca2bd35c3c67b569369c6f9c49/pytest-sugar-0.7.1.tar.gz";
544 url = "https://pypi.python.org/packages/03/97/05d988b4fa870e7373e8ee4582408543b9ca2bd35c3c67b569369c6f9c49/pytest-sugar-0.7.1.tar.gz";
558 md5 = "7400f7c11f3d572b2c2a3b60352d35fe";
545 md5 = "7400f7c11f3d572b2c2a3b60352d35fe";
559 };
546 };
560 meta = {
547 meta = {
561 license = [ pkgs.lib.licenses.bsdOriginal ];
548 license = [ pkgs.lib.licenses.bsdOriginal ];
562 };
549 };
563 };
550 };
564 pytest-timeout = super.buildPythonPackage {
551 pytest-timeout = super.buildPythonPackage {
565 name = "pytest-timeout-1.2.0";
552 name = "pytest-timeout-1.2.0";
566 buildInputs = with self; [];
553 buildInputs = with self; [];
567 doCheck = false;
554 doCheck = false;
568 propagatedBuildInputs = with self; [pytest];
555 propagatedBuildInputs = with self; [pytest];
569 src = fetchurl {
556 src = fetchurl {
570 url = "https://pypi.python.org/packages/cc/b7/b2a61365ea6b6d2e8881360ae7ed8dad0327ad2df89f2f0be4a02304deb2/pytest-timeout-1.2.0.tar.gz";
557 url = "https://pypi.python.org/packages/cc/b7/b2a61365ea6b6d2e8881360ae7ed8dad0327ad2df89f2f0be4a02304deb2/pytest-timeout-1.2.0.tar.gz";
571 md5 = "83607d91aa163562c7ee835da57d061d";
558 md5 = "83607d91aa163562c7ee835da57d061d";
572 };
559 };
573 meta = {
560 meta = {
574 license = [ pkgs.lib.licenses.mit { fullName = "DFSG approved"; } ];
561 license = [ pkgs.lib.licenses.mit { fullName = "DFSG approved"; } ];
575 };
562 };
576 };
563 };
577 repoze.lru = super.buildPythonPackage {
564 repoze.lru = super.buildPythonPackage {
578 name = "repoze.lru-0.6";
565 name = "repoze.lru-0.6";
579 buildInputs = with self; [];
566 buildInputs = with self; [];
580 doCheck = false;
567 doCheck = false;
581 propagatedBuildInputs = with self; [];
568 propagatedBuildInputs = with self; [];
582 src = fetchurl {
569 src = fetchurl {
583 url = "https://pypi.python.org/packages/6e/1e/aa15cc90217e086dc8769872c8778b409812ff036bf021b15795638939e4/repoze.lru-0.6.tar.gz";
570 url = "https://pypi.python.org/packages/6e/1e/aa15cc90217e086dc8769872c8778b409812ff036bf021b15795638939e4/repoze.lru-0.6.tar.gz";
584 md5 = "2c3b64b17a8e18b405f55d46173e14dd";
571 md5 = "2c3b64b17a8e18b405f55d46173e14dd";
585 };
572 };
586 meta = {
573 meta = {
587 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
574 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
588 };
575 };
589 };
576 };
590 rhodecode-vcsserver = super.buildPythonPackage {
577 rhodecode-vcsserver = super.buildPythonPackage {
591 name = "rhodecode-vcsserver-4.8.0";
578 name = "rhodecode-vcsserver-4.8.0";
592 buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage configobj];
579 buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage configobj];
593 doCheck = true;
580 doCheck = true;
594 propagatedBuildInputs = with self; [Beaker configobj decorator dulwich hgsubversion infrae.cache mercurial msgpack-python pyramid pyramid-jinja2 pyramid-mako repoze.lru simplejson subprocess32 subvertpy six translationstring WebOb wheel zope.deprecation zope.interface ipdb ipython gevent greenlet gunicorn waitress Pyro4 serpent pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage];
581 propagatedBuildInputs = with self; [Beaker configobj decorator dulwich hgsubversion infrae.cache mercurial msgpack-python pyramid pyramid-jinja2 pyramid-mako repoze.lru simplejson subprocess32 subvertpy six translationstring WebOb wheel zope.deprecation zope.interface ipdb ipython gevent greenlet gunicorn waitress pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage];
595 src = ./.;
582 src = ./.;
596 meta = {
583 meta = {
597 license = [ { fullName = "GPL V3"; } { fullName = "GNU General Public License v3 or later (GPLv3+)"; } ];
584 license = [ { fullName = "GPL V3"; } { fullName = "GNU General Public License v3 or later (GPLv3+)"; } ];
598 };
585 };
599 };
586 };
600 serpent = super.buildPythonPackage {
601 name = "serpent-1.15";
602 buildInputs = with self; [];
603 doCheck = false;
604 propagatedBuildInputs = with self; [];
605 src = fetchurl {
606 url = "https://pypi.python.org/packages/7b/38/b2b27673a882ff2ea5871bb3e3e6b496ebbaafd1612e51990ffb158b9254/serpent-1.15.tar.gz";
607 md5 = "e27b1aad5c218e16442f52abb7c7053a";
608 };
609 meta = {
610 license = [ pkgs.lib.licenses.mit ];
611 };
612 };
613 setuptools = super.buildPythonPackage {
587 setuptools = super.buildPythonPackage {
614 name = "setuptools-30.1.0";
588 name = "setuptools-30.1.0";
615 buildInputs = with self; [];
589 buildInputs = with self; [];
616 doCheck = false;
590 doCheck = false;
617 propagatedBuildInputs = with self; [];
591 propagatedBuildInputs = with self; [];
618 src = fetchurl {
592 src = fetchurl {
619 url = "https://pypi.python.org/packages/1e/43/002c8616db9a3e7be23c2556e39b90a32bb40ba0dc652de1999d5334d372/setuptools-30.1.0.tar.gz";
593 url = "https://pypi.python.org/packages/1e/43/002c8616db9a3e7be23c2556e39b90a32bb40ba0dc652de1999d5334d372/setuptools-30.1.0.tar.gz";
620 md5 = "cac497f42e5096ac8df29e38d3f81c3e";
594 md5 = "cac497f42e5096ac8df29e38d3f81c3e";
621 };
595 };
622 meta = {
596 meta = {
623 license = [ pkgs.lib.licenses.mit ];
597 license = [ pkgs.lib.licenses.mit ];
624 };
598 };
625 };
599 };
626 simplegeneric = super.buildPythonPackage {
600 simplegeneric = super.buildPythonPackage {
627 name = "simplegeneric-0.8.1";
601 name = "simplegeneric-0.8.1";
628 buildInputs = with self; [];
602 buildInputs = with self; [];
629 doCheck = false;
603 doCheck = false;
630 propagatedBuildInputs = with self; [];
604 propagatedBuildInputs = with self; [];
631 src = fetchurl {
605 src = fetchurl {
632 url = "https://pypi.python.org/packages/3d/57/4d9c9e3ae9a255cd4e1106bb57e24056d3d0709fc01b2e3e345898e49d5b/simplegeneric-0.8.1.zip";
606 url = "https://pypi.python.org/packages/3d/57/4d9c9e3ae9a255cd4e1106bb57e24056d3d0709fc01b2e3e345898e49d5b/simplegeneric-0.8.1.zip";
633 md5 = "f9c1fab00fd981be588fc32759f474e3";
607 md5 = "f9c1fab00fd981be588fc32759f474e3";
634 };
608 };
635 meta = {
609 meta = {
636 license = [ pkgs.lib.licenses.zpt21 ];
610 license = [ pkgs.lib.licenses.zpt21 ];
637 };
611 };
638 };
612 };
639 simplejson = super.buildPythonPackage {
613 simplejson = super.buildPythonPackage {
640 name = "simplejson-3.7.2";
614 name = "simplejson-3.7.2";
641 buildInputs = with self; [];
615 buildInputs = with self; [];
642 doCheck = false;
616 doCheck = false;
643 propagatedBuildInputs = with self; [];
617 propagatedBuildInputs = with self; [];
644 src = fetchurl {
618 src = fetchurl {
645 url = "https://pypi.python.org/packages/6d/89/7f13f099344eea9d6722779a1f165087cb559598107844b1ac5dbd831fb1/simplejson-3.7.2.tar.gz";
619 url = "https://pypi.python.org/packages/6d/89/7f13f099344eea9d6722779a1f165087cb559598107844b1ac5dbd831fb1/simplejson-3.7.2.tar.gz";
646 md5 = "a5fc7d05d4cb38492285553def5d4b46";
620 md5 = "a5fc7d05d4cb38492285553def5d4b46";
647 };
621 };
648 meta = {
622 meta = {
649 license = [ { fullName = "Academic Free License (AFL)"; } pkgs.lib.licenses.mit ];
623 license = [ { fullName = "Academic Free License (AFL)"; } pkgs.lib.licenses.mit ];
650 };
624 };
651 };
625 };
652 six = super.buildPythonPackage {
626 six = super.buildPythonPackage {
653 name = "six-1.9.0";
627 name = "six-1.9.0";
654 buildInputs = with self; [];
628 buildInputs = with self; [];
655 doCheck = false;
629 doCheck = false;
656 propagatedBuildInputs = with self; [];
630 propagatedBuildInputs = with self; [];
657 src = fetchurl {
631 src = fetchurl {
658 url = "https://pypi.python.org/packages/16/64/1dc5e5976b17466fd7d712e59cbe9fb1e18bec153109e5ba3ed6c9102f1a/six-1.9.0.tar.gz";
632 url = "https://pypi.python.org/packages/16/64/1dc5e5976b17466fd7d712e59cbe9fb1e18bec153109e5ba3ed6c9102f1a/six-1.9.0.tar.gz";
659 md5 = "476881ef4012262dfc8adc645ee786c4";
633 md5 = "476881ef4012262dfc8adc645ee786c4";
660 };
634 };
661 meta = {
635 meta = {
662 license = [ pkgs.lib.licenses.mit ];
636 license = [ pkgs.lib.licenses.mit ];
663 };
637 };
664 };
638 };
665 subprocess32 = super.buildPythonPackage {
639 subprocess32 = super.buildPythonPackage {
666 name = "subprocess32-3.2.6";
640 name = "subprocess32-3.2.6";
667 buildInputs = with self; [];
641 buildInputs = with self; [];
668 doCheck = false;
642 doCheck = false;
669 propagatedBuildInputs = with self; [];
643 propagatedBuildInputs = with self; [];
670 src = fetchurl {
644 src = fetchurl {
671 url = "https://pypi.python.org/packages/28/8d/33ccbff51053f59ae6c357310cac0e79246bbed1d345ecc6188b176d72c3/subprocess32-3.2.6.tar.gz";
645 url = "https://pypi.python.org/packages/28/8d/33ccbff51053f59ae6c357310cac0e79246bbed1d345ecc6188b176d72c3/subprocess32-3.2.6.tar.gz";
672 md5 = "754c5ab9f533e764f931136974b618f1";
646 md5 = "754c5ab9f533e764f931136974b618f1";
673 };
647 };
674 meta = {
648 meta = {
675 license = [ pkgs.lib.licenses.psfl ];
649 license = [ pkgs.lib.licenses.psfl ];
676 };
650 };
677 };
651 };
678 subvertpy = super.buildPythonPackage {
652 subvertpy = super.buildPythonPackage {
679 name = "subvertpy-0.9.3";
653 name = "subvertpy-0.9.3";
680 buildInputs = with self; [];
654 buildInputs = with self; [];
681 doCheck = false;
655 doCheck = false;
682 propagatedBuildInputs = with self; [];
656 propagatedBuildInputs = with self; [];
683 src = fetchurl {
657 src = fetchurl {
684 url = "https://code.rhodecode.com/upstream/subvertpy/archive/subvertpy-0.9.3.tar.gz?md5=4e49da2fe07608239cc9a80a7bb8f33c";
658 url = "https://code.rhodecode.com/upstream/subvertpy/archive/subvertpy-0.9.3.tar.gz?md5=4e49da2fe07608239cc9a80a7bb8f33c";
685 md5 = "4e49da2fe07608239cc9a80a7bb8f33c";
659 md5 = "4e49da2fe07608239cc9a80a7bb8f33c";
686 };
660 };
687 meta = {
661 meta = {
688 license = [ pkgs.lib.licenses.lgpl21Plus ];
662 license = [ pkgs.lib.licenses.lgpl21Plus ];
689 };
663 };
690 };
664 };
691 termcolor = super.buildPythonPackage {
665 termcolor = super.buildPythonPackage {
692 name = "termcolor-1.1.0";
666 name = "termcolor-1.1.0";
693 buildInputs = with self; [];
667 buildInputs = with self; [];
694 doCheck = false;
668 doCheck = false;
695 propagatedBuildInputs = with self; [];
669 propagatedBuildInputs = with self; [];
696 src = fetchurl {
670 src = fetchurl {
697 url = "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz";
671 url = "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz";
698 md5 = "043e89644f8909d462fbbfa511c768df";
672 md5 = "043e89644f8909d462fbbfa511c768df";
699 };
673 };
700 meta = {
674 meta = {
701 license = [ pkgs.lib.licenses.mit ];
675 license = [ pkgs.lib.licenses.mit ];
702 };
676 };
703 };
677 };
704 traitlets = super.buildPythonPackage {
678 traitlets = super.buildPythonPackage {
705 name = "traitlets-4.3.2";
679 name = "traitlets-4.3.2";
706 buildInputs = with self; [];
680 buildInputs = with self; [];
707 doCheck = false;
681 doCheck = false;
708 propagatedBuildInputs = with self; [ipython-genutils six decorator enum34];
682 propagatedBuildInputs = with self; [ipython-genutils six decorator enum34];
709 src = fetchurl {
683 src = fetchurl {
710 url = "https://pypi.python.org/packages/a5/98/7f5ef2fe9e9e071813aaf9cb91d1a732e0a68b6c44a32b38cb8e14c3f069/traitlets-4.3.2.tar.gz";
684 url = "https://pypi.python.org/packages/a5/98/7f5ef2fe9e9e071813aaf9cb91d1a732e0a68b6c44a32b38cb8e14c3f069/traitlets-4.3.2.tar.gz";
711 md5 = "3068663f2f38fd939a9eb3a500ccc154";
685 md5 = "3068663f2f38fd939a9eb3a500ccc154";
712 };
686 };
713 meta = {
687 meta = {
714 license = [ pkgs.lib.licenses.bsdOriginal ];
688 license = [ pkgs.lib.licenses.bsdOriginal ];
715 };
689 };
716 };
690 };
717 translationstring = super.buildPythonPackage {
691 translationstring = super.buildPythonPackage {
718 name = "translationstring-1.3";
692 name = "translationstring-1.3";
719 buildInputs = with self; [];
693 buildInputs = with self; [];
720 doCheck = false;
694 doCheck = false;
721 propagatedBuildInputs = with self; [];
695 propagatedBuildInputs = with self; [];
722 src = fetchurl {
696 src = fetchurl {
723 url = "https://pypi.python.org/packages/5e/eb/bee578cc150b44c653b63f5ebe258b5d0d812ddac12497e5f80fcad5d0b4/translationstring-1.3.tar.gz";
697 url = "https://pypi.python.org/packages/5e/eb/bee578cc150b44c653b63f5ebe258b5d0d812ddac12497e5f80fcad5d0b4/translationstring-1.3.tar.gz";
724 md5 = "a4b62e0f3c189c783a1685b3027f7c90";
698 md5 = "a4b62e0f3c189c783a1685b3027f7c90";
725 };
699 };
726 meta = {
700 meta = {
727 license = [ { fullName = "BSD-like (http://repoze.org/license.html)"; } ];
701 license = [ { fullName = "BSD-like (http://repoze.org/license.html)"; } ];
728 };
702 };
729 };
703 };
730 venusian = super.buildPythonPackage {
704 venusian = super.buildPythonPackage {
731 name = "venusian-1.0";
705 name = "venusian-1.0";
732 buildInputs = with self; [];
706 buildInputs = with self; [];
733 doCheck = false;
707 doCheck = false;
734 propagatedBuildInputs = with self; [];
708 propagatedBuildInputs = with self; [];
735 src = fetchurl {
709 src = fetchurl {
736 url = "https://pypi.python.org/packages/86/20/1948e0dfc4930ddde3da8c33612f6a5717c0b4bc28f591a5c5cf014dd390/venusian-1.0.tar.gz";
710 url = "https://pypi.python.org/packages/86/20/1948e0dfc4930ddde3da8c33612f6a5717c0b4bc28f591a5c5cf014dd390/venusian-1.0.tar.gz";
737 md5 = "dccf2eafb7113759d60c86faf5538756";
711 md5 = "dccf2eafb7113759d60c86faf5538756";
738 };
712 };
739 meta = {
713 meta = {
740 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
714 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
741 };
715 };
742 };
716 };
743 waitress = super.buildPythonPackage {
717 waitress = super.buildPythonPackage {
744 name = "waitress-1.0.1";
718 name = "waitress-1.0.1";
745 buildInputs = with self; [];
719 buildInputs = with self; [];
746 doCheck = false;
720 doCheck = false;
747 propagatedBuildInputs = with self; [];
721 propagatedBuildInputs = with self; [];
748 src = fetchurl {
722 src = fetchurl {
749 url = "https://pypi.python.org/packages/78/7d/84d11b96c3f60164dec3bef4a859a03aeae0231aa93f57fbe0d05fa4ff36/waitress-1.0.1.tar.gz";
723 url = "https://pypi.python.org/packages/78/7d/84d11b96c3f60164dec3bef4a859a03aeae0231aa93f57fbe0d05fa4ff36/waitress-1.0.1.tar.gz";
750 md5 = "dda92358a7569669086155923a46e57c";
724 md5 = "dda92358a7569669086155923a46e57c";
751 };
725 };
752 meta = {
726 meta = {
753 license = [ pkgs.lib.licenses.zpt21 ];
727 license = [ pkgs.lib.licenses.zpt21 ];
754 };
728 };
755 };
729 };
756 wcwidth = super.buildPythonPackage {
730 wcwidth = super.buildPythonPackage {
757 name = "wcwidth-0.1.7";
731 name = "wcwidth-0.1.7";
758 buildInputs = with self; [];
732 buildInputs = with self; [];
759 doCheck = false;
733 doCheck = false;
760 propagatedBuildInputs = with self; [];
734 propagatedBuildInputs = with self; [];
761 src = fetchurl {
735 src = fetchurl {
762 url = "https://pypi.python.org/packages/55/11/e4a2bb08bb450fdbd42cc709dd40de4ed2c472cf0ccb9e64af22279c5495/wcwidth-0.1.7.tar.gz";
736 url = "https://pypi.python.org/packages/55/11/e4a2bb08bb450fdbd42cc709dd40de4ed2c472cf0ccb9e64af22279c5495/wcwidth-0.1.7.tar.gz";
763 md5 = "b3b6a0a08f0c8a34d1de8cf44150a4ad";
737 md5 = "b3b6a0a08f0c8a34d1de8cf44150a4ad";
764 };
738 };
765 meta = {
739 meta = {
766 license = [ pkgs.lib.licenses.mit ];
740 license = [ pkgs.lib.licenses.mit ];
767 };
741 };
768 };
742 };
769 wheel = super.buildPythonPackage {
743 wheel = super.buildPythonPackage {
770 name = "wheel-0.29.0";
744 name = "wheel-0.29.0";
771 buildInputs = with self; [];
745 buildInputs = with self; [];
772 doCheck = false;
746 doCheck = false;
773 propagatedBuildInputs = with self; [];
747 propagatedBuildInputs = with self; [];
774 src = fetchurl {
748 src = fetchurl {
775 url = "https://pypi.python.org/packages/c9/1d/bd19e691fd4cfe908c76c429fe6e4436c9e83583c4414b54f6c85471954a/wheel-0.29.0.tar.gz";
749 url = "https://pypi.python.org/packages/c9/1d/bd19e691fd4cfe908c76c429fe6e4436c9e83583c4414b54f6c85471954a/wheel-0.29.0.tar.gz";
776 md5 = "555a67e4507cedee23a0deb9651e452f";
750 md5 = "555a67e4507cedee23a0deb9651e452f";
777 };
751 };
778 meta = {
752 meta = {
779 license = [ pkgs.lib.licenses.mit ];
753 license = [ pkgs.lib.licenses.mit ];
780 };
754 };
781 };
755 };
782 zope.deprecation = super.buildPythonPackage {
756 zope.deprecation = super.buildPythonPackage {
783 name = "zope.deprecation-4.1.2";
757 name = "zope.deprecation-4.1.2";
784 buildInputs = with self; [];
758 buildInputs = with self; [];
785 doCheck = false;
759 doCheck = false;
786 propagatedBuildInputs = with self; [setuptools];
760 propagatedBuildInputs = with self; [setuptools];
787 src = fetchurl {
761 src = fetchurl {
788 url = "https://pypi.python.org/packages/c1/d3/3919492d5e57d8dd01b36f30b34fc8404a30577392b1eb817c303499ad20/zope.deprecation-4.1.2.tar.gz";
762 url = "https://pypi.python.org/packages/c1/d3/3919492d5e57d8dd01b36f30b34fc8404a30577392b1eb817c303499ad20/zope.deprecation-4.1.2.tar.gz";
789 md5 = "e9a663ded58f4f9f7881beb56cae2782";
763 md5 = "e9a663ded58f4f9f7881beb56cae2782";
790 };
764 };
791 meta = {
765 meta = {
792 license = [ pkgs.lib.licenses.zpt21 ];
766 license = [ pkgs.lib.licenses.zpt21 ];
793 };
767 };
794 };
768 };
795 zope.interface = super.buildPythonPackage {
769 zope.interface = super.buildPythonPackage {
796 name = "zope.interface-4.1.3";
770 name = "zope.interface-4.1.3";
797 buildInputs = with self; [];
771 buildInputs = with self; [];
798 doCheck = false;
772 doCheck = false;
799 propagatedBuildInputs = with self; [setuptools];
773 propagatedBuildInputs = with self; [setuptools];
800 src = fetchurl {
774 src = fetchurl {
801 url = "https://pypi.python.org/packages/9d/81/2509ca3c6f59080123c1a8a97125eb48414022618cec0e64eb1313727bfe/zope.interface-4.1.3.tar.gz";
775 url = "https://pypi.python.org/packages/9d/81/2509ca3c6f59080123c1a8a97125eb48414022618cec0e64eb1313727bfe/zope.interface-4.1.3.tar.gz";
802 md5 = "9ae3d24c0c7415deb249dd1a132f0f79";
776 md5 = "9ae3d24c0c7415deb249dd1a132f0f79";
803 };
777 };
804 meta = {
778 meta = {
805 license = [ pkgs.lib.licenses.zpt21 ];
779 license = [ pkgs.lib.licenses.zpt21 ];
806 };
780 };
807 };
781 };
808
782
809 ### Test requirements
783 ### Test requirements
810
784
811
785
812 }
786 }
@@ -1,43 +1,39 b''
1 ## core
1 ## core
2 setuptools==30.1.0
2 setuptools==30.1.0
3
3
4 Beaker==1.7.0
4 Beaker==1.7.0
5 configobj==5.0.6
5 configobj==5.0.6
6 decorator==4.0.11
6 decorator==4.0.11
7 dulwich==0.13.0
7 dulwich==0.13.0
8 hgsubversion==1.8.6
8 hgsubversion==1.8.6
9 infrae.cache==1.0.1
9 infrae.cache==1.0.1
10 mercurial==4.1.2
10 mercurial==4.1.2
11 msgpack-python==0.4.8
11 msgpack-python==0.4.8
12 pyramid-jinja2==2.5
12 pyramid-jinja2==2.5
13 pyramid==1.7.4
13 pyramid==1.7.4
14 pyramid-mako==1.0.2
14 pyramid-mako==1.0.2
15 repoze.lru==0.6
15 repoze.lru==0.6
16 simplejson==3.7.2
16 simplejson==3.7.2
17 subprocess32==3.2.6
17 subprocess32==3.2.6
18
18
19 # Custom subvertpy that is not available on pypi.
19 # Custom subvertpy that is not available on pypi.
20 https://code.rhodecode.com/upstream/subvertpy/archive/subvertpy-0.9.3.tar.gz?md5=4e49da2fe07608239cc9a80a7bb8f33c#egg=subvertpy==0.9.3
20 https://code.rhodecode.com/upstream/subvertpy/archive/subvertpy-0.9.3.tar.gz?md5=4e49da2fe07608239cc9a80a7bb8f33c#egg=subvertpy==0.9.3
21
21
22 six==1.9.0
22 six==1.9.0
23 translationstring==1.3
23 translationstring==1.3
24 WebOb==1.3.1
24 WebOb==1.3.1
25 wheel==0.29.0
25 wheel==0.29.0
26 zope.deprecation==4.1.2
26 zope.deprecation==4.1.2
27 zope.interface==4.1.3
27 zope.interface==4.1.3
28
28
29 ## debug
29 ## debug
30 ipdb==0.10.1
30 ipdb==0.10.1
31 ipython==5.1.0
31 ipython==5.1.0
32 # http servers
32 # http servers
33 gevent==1.1.2
33 gevent==1.1.2
34 greenlet==0.4.10
34 greenlet==0.4.10
35 gunicorn==19.6.0
35 gunicorn==19.6.0
36 waitress==1.0.1
36 waitress==1.0.1
37
37
38 # Pyro/Deprecated TODO(Marcink): remove in 4.7 release.
39 Pyro4==4.41
40 serpent==1.15
41
42 ## test related requirements
38 ## test related requirements
43 -r requirements_test.txt
39 -r requirements_test.txt
@@ -1,93 +1,87 b''
1 ################################################################################
1 ################################################################################
2 # RhodeCode VCSServer - configuration #
2 # RhodeCode VCSServer - configuration #
3 # #
3 # #
4 ################################################################################
4 ################################################################################
5
5
6 [DEFAULT]
6 [DEFAULT]
7 host = 127.0.0.1
7 host = 127.0.0.1
8 port = 9901
8 port = 9901
9 locale = en_US.UTF-8
9 locale = en_US.UTF-8
10 # number of worker threads, this should be set based on a formula threadpool=N*6
10 # number of worker threads, this should be set based on a formula threadpool=N*6
11 # where N is number of RhodeCode Enterprise workers, eg. running 2 instances
11 # where N is number of RhodeCode Enterprise workers, eg. running 2 instances
12 # 8 gunicorn workers each would be 2 * 8 * 6 = 96, threadpool_size = 96
12 # 8 gunicorn workers each would be 2 * 8 * 6 = 96, threadpool_size = 96
13 threadpool_size = 96
13 threadpool_size = 96
14 timeout = 0
14 timeout = 0
15
15
16 # cache regions, please don't change
16 # cache regions, please don't change
17 beaker.cache.regions = repo_object
17 beaker.cache.regions = repo_object
18 beaker.cache.repo_object.type = memorylru
18 beaker.cache.repo_object.type = memorylru
19 beaker.cache.repo_object.max_items = 100
19 beaker.cache.repo_object.max_items = 100
20 # cache auto-expires after N seconds
20 # cache auto-expires after N seconds
21 beaker.cache.repo_object.expire = 300
21 beaker.cache.repo_object.expire = 300
22 beaker.cache.repo_object.enabled = true
22 beaker.cache.repo_object.enabled = true
23
23
24
24
25 ################################
25 ################################
26 ### LOGGING CONFIGURATION ####
26 ### LOGGING CONFIGURATION ####
27 ################################
27 ################################
28 [loggers]
28 [loggers]
29 keys = root, vcsserver, pyro4, beaker
29 keys = root, vcsserver, beaker
30
30
31 [handlers]
31 [handlers]
32 keys = console
32 keys = console
33
33
34 [formatters]
34 [formatters]
35 keys = generic
35 keys = generic
36
36
37 #############
37 #############
38 ## LOGGERS ##
38 ## LOGGERS ##
39 #############
39 #############
40 [logger_root]
40 [logger_root]
41 level = NOTSET
41 level = NOTSET
42 handlers = console
42 handlers = console
43
43
44 [logger_vcsserver]
44 [logger_vcsserver]
45 level = DEBUG
45 level = DEBUG
46 handlers =
46 handlers =
47 qualname = vcsserver
47 qualname = vcsserver
48 propagate = 1
48 propagate = 1
49
49
50 [logger_beaker]
50 [logger_beaker]
51 level = DEBUG
51 level = DEBUG
52 handlers =
52 handlers =
53 qualname = beaker
53 qualname = beaker
54 propagate = 1
54 propagate = 1
55
55
56 [logger_pyro4]
57 level = DEBUG
58 handlers =
59 qualname = Pyro4
60 propagate = 1
61
62
56
63 ##############
57 ##############
64 ## HANDLERS ##
58 ## HANDLERS ##
65 ##############
59 ##############
66
60
67 [handler_console]
61 [handler_console]
68 class = StreamHandler
62 class = StreamHandler
69 args = (sys.stderr,)
63 args = (sys.stderr,)
70 level = INFO
64 level = INFO
71 formatter = generic
65 formatter = generic
72
66
73 [handler_file]
67 [handler_file]
74 class = FileHandler
68 class = FileHandler
75 args = ('vcsserver.log', 'a',)
69 args = ('vcsserver.log', 'a',)
76 level = DEBUG
70 level = DEBUG
77 formatter = generic
71 formatter = generic
78
72
79 [handler_file_rotating]
73 [handler_file_rotating]
80 class = logging.handlers.TimedRotatingFileHandler
74 class = logging.handlers.TimedRotatingFileHandler
81 # 'D', 5 - rotate every 5days
75 # 'D', 5 - rotate every 5days
82 # you can set 'h', 'midnight'
76 # you can set 'h', 'midnight'
83 args = ('vcsserver.log', 'D', 5, 10,)
77 args = ('vcsserver.log', 'D', 5, 10,)
84 level = DEBUG
78 level = DEBUG
85 formatter = generic
79 formatter = generic
86
80
87 ################
81 ################
88 ## FORMATTERS ##
82 ## FORMATTERS ##
89 ################
83 ################
90
84
91 [formatter_generic]
85 [formatter_generic]
92 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
86 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
93 datefmt = %Y-%m-%d %H:%M:%S
87 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,727 +1,727 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2017 RodeCode GmbH
2 # Copyright (C) 2014-2017 RodeCode GmbH
3 #
3 #
4 # This program is free software; you can redistribute it and/or modify
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
7 # (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18 import io
18 import io
19 import logging
19 import logging
20 import stat
20 import stat
21 import urllib
21 import urllib
22 import urllib2
22 import urllib2
23
23
24 from hgext import largefiles, rebase
24 from hgext import largefiles, rebase
25 from hgext.strip import strip as hgext_strip
25 from hgext.strip import strip as hgext_strip
26 from mercurial import commands
26 from mercurial import commands
27 from mercurial import unionrepo
27 from mercurial import unionrepo
28 from mercurial import verify
28 from mercurial import verify
29
29
30 from vcsserver import exceptions
30 from vcsserver import exceptions
31 from vcsserver.base import RepoFactory, obfuscate_qs, raise_from_original
31 from vcsserver.base import RepoFactory, obfuscate_qs, raise_from_original
32 from vcsserver.hgcompat import (
32 from vcsserver.hgcompat import (
33 archival, bin, clone, config as hgconfig, diffopts, hex,
33 archival, bin, clone, config as hgconfig, diffopts, hex,
34 hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler,
34 hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler,
35 httppeer, localrepository, match, memctx, exchange, memfilectx, nullrev,
35 httppeer, localrepository, match, memctx, exchange, memfilectx, nullrev,
36 patch, peer, revrange, ui, Abort, LookupError, RepoError, RepoLookupError,
36 patch, peer, revrange, ui, Abort, LookupError, RepoError, RepoLookupError,
37 InterventionRequired, RequirementError)
37 InterventionRequired, RequirementError)
38
38
39 log = logging.getLogger(__name__)
39 log = logging.getLogger(__name__)
40
40
41
41
42 def make_ui_from_config(repo_config):
42 def make_ui_from_config(repo_config):
43 baseui = ui.ui()
43 baseui = ui.ui()
44
44
45 # clean the baseui object
45 # clean the baseui object
46 baseui._ocfg = hgconfig.config()
46 baseui._ocfg = hgconfig.config()
47 baseui._ucfg = hgconfig.config()
47 baseui._ucfg = hgconfig.config()
48 baseui._tcfg = hgconfig.config()
48 baseui._tcfg = hgconfig.config()
49
49
50 for section, option, value in repo_config:
50 for section, option, value in repo_config:
51 baseui.setconfig(section, option, value)
51 baseui.setconfig(section, option, value)
52
52
53 # make our hgweb quiet so it doesn't print output
53 # make our hgweb quiet so it doesn't print output
54 baseui.setconfig('ui', 'quiet', 'true')
54 baseui.setconfig('ui', 'quiet', 'true')
55
55
56 # force mercurial to only use 1 thread, otherwise it may try to set a
56 # force mercurial to only use 1 thread, otherwise it may try to set a
57 # signal in a non-main thread, thus generating a ValueError.
57 # signal in a non-main thread, thus generating a ValueError.
58 baseui.setconfig('worker', 'numcpus', 1)
58 baseui.setconfig('worker', 'numcpus', 1)
59
59
60 # If there is no config for the largefiles extension, we explicitly disable
60 # If there is no config for the largefiles extension, we explicitly disable
61 # it here. This overrides settings from repositories hgrc file. Recent
61 # it here. This overrides settings from repositories hgrc file. Recent
62 # mercurial versions enable largefiles in hgrc on clone from largefile
62 # mercurial versions enable largefiles in hgrc on clone from largefile
63 # repo.
63 # repo.
64 if not baseui.hasconfig('extensions', 'largefiles'):
64 if not baseui.hasconfig('extensions', 'largefiles'):
65 log.debug('Explicitly disable largefiles extension for repo.')
65 log.debug('Explicitly disable largefiles extension for repo.')
66 baseui.setconfig('extensions', 'largefiles', '!')
66 baseui.setconfig('extensions', 'largefiles', '!')
67
67
68 return baseui
68 return baseui
69
69
70
70
71 def reraise_safe_exceptions(func):
71 def reraise_safe_exceptions(func):
72 """Decorator for converting mercurial exceptions to something neutral."""
72 """Decorator for converting mercurial exceptions to something neutral."""
73 def wrapper(*args, **kwargs):
73 def wrapper(*args, **kwargs):
74 try:
74 try:
75 return func(*args, **kwargs)
75 return func(*args, **kwargs)
76 except (Abort, InterventionRequired):
76 except (Abort, InterventionRequired):
77 raise_from_original(exceptions.AbortException)
77 raise_from_original(exceptions.AbortException)
78 except RepoLookupError:
78 except RepoLookupError:
79 raise_from_original(exceptions.LookupException)
79 raise_from_original(exceptions.LookupException)
80 except RequirementError:
80 except RequirementError:
81 raise_from_original(exceptions.RequirementException)
81 raise_from_original(exceptions.RequirementException)
82 except RepoError:
82 except RepoError:
83 raise_from_original(exceptions.VcsException)
83 raise_from_original(exceptions.VcsException)
84 except LookupError:
84 except LookupError:
85 raise_from_original(exceptions.LookupException)
85 raise_from_original(exceptions.LookupException)
86 except Exception as e:
86 except Exception as e:
87 if not hasattr(e, '_vcs_kind'):
87 if not hasattr(e, '_vcs_kind'):
88 log.exception("Unhandled exception in hg remote call")
88 log.exception("Unhandled exception in hg remote call")
89 raise_from_original(exceptions.UnhandledException)
89 raise_from_original(exceptions.UnhandledException)
90 raise
90 raise
91 return wrapper
91 return wrapper
92
92
93
93
94 class MercurialFactory(RepoFactory):
94 class MercurialFactory(RepoFactory):
95
95
96 def _create_config(self, config, hooks=True):
96 def _create_config(self, config, hooks=True):
97 if not hooks:
97 if not hooks:
98 hooks_to_clean = frozenset((
98 hooks_to_clean = frozenset((
99 'changegroup.repo_size', 'preoutgoing.pre_pull',
99 'changegroup.repo_size', 'preoutgoing.pre_pull',
100 'outgoing.pull_logger', 'prechangegroup.pre_push'))
100 'outgoing.pull_logger', 'prechangegroup.pre_push'))
101 new_config = []
101 new_config = []
102 for section, option, value in config:
102 for section, option, value in config:
103 if section == 'hooks' and option in hooks_to_clean:
103 if section == 'hooks' and option in hooks_to_clean:
104 continue
104 continue
105 new_config.append((section, option, value))
105 new_config.append((section, option, value))
106 config = new_config
106 config = new_config
107
107
108 baseui = make_ui_from_config(config)
108 baseui = make_ui_from_config(config)
109 return baseui
109 return baseui
110
110
111 def _create_repo(self, wire, create):
111 def _create_repo(self, wire, create):
112 baseui = self._create_config(wire["config"])
112 baseui = self._create_config(wire["config"])
113 return localrepository(baseui, wire["path"], create)
113 return localrepository(baseui, wire["path"], create)
114
114
115
115
116 class HgRemote(object):
116 class HgRemote(object):
117
117
118 def __init__(self, factory):
118 def __init__(self, factory):
119 self._factory = factory
119 self._factory = factory
120
120
121 self._bulk_methods = {
121 self._bulk_methods = {
122 "affected_files": self.ctx_files,
122 "affected_files": self.ctx_files,
123 "author": self.ctx_user,
123 "author": self.ctx_user,
124 "branch": self.ctx_branch,
124 "branch": self.ctx_branch,
125 "children": self.ctx_children,
125 "children": self.ctx_children,
126 "date": self.ctx_date,
126 "date": self.ctx_date,
127 "message": self.ctx_description,
127 "message": self.ctx_description,
128 "parents": self.ctx_parents,
128 "parents": self.ctx_parents,
129 "status": self.ctx_status,
129 "status": self.ctx_status,
130 "_file_paths": self.ctx_list,
130 "_file_paths": self.ctx_list,
131 }
131 }
132
132
133 @reraise_safe_exceptions
133 @reraise_safe_exceptions
134 def discover_hg_version(self):
134 def discover_hg_version(self):
135 from mercurial import util
135 from mercurial import util
136 return util.version()
136 return util.version()
137
137
138 @reraise_safe_exceptions
138 @reraise_safe_exceptions
139 def archive_repo(self, archive_path, mtime, file_info, kind):
139 def archive_repo(self, archive_path, mtime, file_info, kind):
140 if kind == "tgz":
140 if kind == "tgz":
141 archiver = archival.tarit(archive_path, mtime, "gz")
141 archiver = archival.tarit(archive_path, mtime, "gz")
142 elif kind == "tbz2":
142 elif kind == "tbz2":
143 archiver = archival.tarit(archive_path, mtime, "bz2")
143 archiver = archival.tarit(archive_path, mtime, "bz2")
144 elif kind == 'zip':
144 elif kind == 'zip':
145 archiver = archival.zipit(archive_path, mtime)
145 archiver = archival.zipit(archive_path, mtime)
146 else:
146 else:
147 raise exceptions.ArchiveException(
147 raise exceptions.ArchiveException(
148 'Remote does not support: "%s".' % kind)
148 'Remote does not support: "%s".' % kind)
149
149
150 for f_path, f_mode, f_is_link, f_content in file_info:
150 for f_path, f_mode, f_is_link, f_content in file_info:
151 archiver.addfile(f_path, f_mode, f_is_link, f_content)
151 archiver.addfile(f_path, f_mode, f_is_link, f_content)
152 archiver.done()
152 archiver.done()
153
153
154 @reraise_safe_exceptions
154 @reraise_safe_exceptions
155 def bookmarks(self, wire):
155 def bookmarks(self, wire):
156 repo = self._factory.repo(wire)
156 repo = self._factory.repo(wire)
157 return dict(repo._bookmarks)
157 return dict(repo._bookmarks)
158
158
159 @reraise_safe_exceptions
159 @reraise_safe_exceptions
160 def branches(self, wire, normal, closed):
160 def branches(self, wire, normal, closed):
161 repo = self._factory.repo(wire)
161 repo = self._factory.repo(wire)
162 iter_branches = repo.branchmap().iterbranches()
162 iter_branches = repo.branchmap().iterbranches()
163 bt = {}
163 bt = {}
164 for branch_name, _heads, tip, is_closed in iter_branches:
164 for branch_name, _heads, tip, is_closed in iter_branches:
165 if normal and not is_closed:
165 if normal and not is_closed:
166 bt[branch_name] = tip
166 bt[branch_name] = tip
167 if closed and is_closed:
167 if closed and is_closed:
168 bt[branch_name] = tip
168 bt[branch_name] = tip
169
169
170 return bt
170 return bt
171
171
172 @reraise_safe_exceptions
172 @reraise_safe_exceptions
173 def bulk_request(self, wire, rev, pre_load):
173 def bulk_request(self, wire, rev, pre_load):
174 result = {}
174 result = {}
175 for attr in pre_load:
175 for attr in pre_load:
176 try:
176 try:
177 method = self._bulk_methods[attr]
177 method = self._bulk_methods[attr]
178 result[attr] = method(wire, rev)
178 result[attr] = method(wire, rev)
179 except KeyError:
179 except KeyError:
180 raise exceptions.VcsException(
180 raise exceptions.VcsException(
181 'Unknown bulk attribute: "%s"' % attr)
181 'Unknown bulk attribute: "%s"' % attr)
182 return result
182 return result
183
183
184 @reraise_safe_exceptions
184 @reraise_safe_exceptions
185 def clone(self, wire, source, dest, update_after_clone=False, hooks=True):
185 def clone(self, wire, source, dest, update_after_clone=False, hooks=True):
186 baseui = self._factory._create_config(wire["config"], hooks=hooks)
186 baseui = self._factory._create_config(wire["config"], hooks=hooks)
187 clone(baseui, source, dest, noupdate=not update_after_clone)
187 clone(baseui, source, dest, noupdate=not update_after_clone)
188
188
189 @reraise_safe_exceptions
189 @reraise_safe_exceptions
190 def commitctx(
190 def commitctx(
191 self, wire, message, parents, commit_time, commit_timezone,
191 self, wire, message, parents, commit_time, commit_timezone,
192 user, files, extra, removed, updated):
192 user, files, extra, removed, updated):
193
193
194 def _filectxfn(_repo, memctx, path):
194 def _filectxfn(_repo, memctx, path):
195 """
195 """
196 Marks given path as added/changed/removed in a given _repo. This is
196 Marks given path as added/changed/removed in a given _repo. This is
197 for internal mercurial commit function.
197 for internal mercurial commit function.
198 """
198 """
199
199
200 # check if this path is removed
200 # check if this path is removed
201 if path in removed:
201 if path in removed:
202 # returning None is a way to mark node for removal
202 # returning None is a way to mark node for removal
203 return None
203 return None
204
204
205 # check if this path is added
205 # check if this path is added
206 for node in updated:
206 for node in updated:
207 if node['path'] == path:
207 if node['path'] == path:
208 return memfilectx(
208 return memfilectx(
209 _repo,
209 _repo,
210 path=node['path'],
210 path=node['path'],
211 data=node['content'],
211 data=node['content'],
212 islink=False,
212 islink=False,
213 isexec=bool(node['mode'] & stat.S_IXUSR),
213 isexec=bool(node['mode'] & stat.S_IXUSR),
214 copied=False,
214 copied=False,
215 memctx=memctx)
215 memctx=memctx)
216
216
217 raise exceptions.AbortException(
217 raise exceptions.AbortException(
218 "Given path haven't been marked as added, "
218 "Given path haven't been marked as added, "
219 "changed or removed (%s)" % path)
219 "changed or removed (%s)" % path)
220
220
221 repo = self._factory.repo(wire)
221 repo = self._factory.repo(wire)
222
222
223 commit_ctx = memctx(
223 commit_ctx = memctx(
224 repo=repo,
224 repo=repo,
225 parents=parents,
225 parents=parents,
226 text=message,
226 text=message,
227 files=files,
227 files=files,
228 filectxfn=_filectxfn,
228 filectxfn=_filectxfn,
229 user=user,
229 user=user,
230 date=(commit_time, commit_timezone),
230 date=(commit_time, commit_timezone),
231 extra=extra)
231 extra=extra)
232
232
233 n = repo.commitctx(commit_ctx)
233 n = repo.commitctx(commit_ctx)
234 new_id = hex(n)
234 new_id = hex(n)
235
235
236 return new_id
236 return new_id
237
237
238 @reraise_safe_exceptions
238 @reraise_safe_exceptions
239 def ctx_branch(self, wire, revision):
239 def ctx_branch(self, wire, revision):
240 repo = self._factory.repo(wire)
240 repo = self._factory.repo(wire)
241 ctx = repo[revision]
241 ctx = repo[revision]
242 return ctx.branch()
242 return ctx.branch()
243
243
244 @reraise_safe_exceptions
244 @reraise_safe_exceptions
245 def ctx_children(self, wire, revision):
245 def ctx_children(self, wire, revision):
246 repo = self._factory.repo(wire)
246 repo = self._factory.repo(wire)
247 ctx = repo[revision]
247 ctx = repo[revision]
248 return [child.rev() for child in ctx.children()]
248 return [child.rev() for child in ctx.children()]
249
249
250 @reraise_safe_exceptions
250 @reraise_safe_exceptions
251 def ctx_date(self, wire, revision):
251 def ctx_date(self, wire, revision):
252 repo = self._factory.repo(wire)
252 repo = self._factory.repo(wire)
253 ctx = repo[revision]
253 ctx = repo[revision]
254 return ctx.date()
254 return ctx.date()
255
255
256 @reraise_safe_exceptions
256 @reraise_safe_exceptions
257 def ctx_description(self, wire, revision):
257 def ctx_description(self, wire, revision):
258 repo = self._factory.repo(wire)
258 repo = self._factory.repo(wire)
259 ctx = repo[revision]
259 ctx = repo[revision]
260 return ctx.description()
260 return ctx.description()
261
261
262 @reraise_safe_exceptions
262 @reraise_safe_exceptions
263 def ctx_diff(
263 def ctx_diff(
264 self, wire, revision, git=True, ignore_whitespace=True, context=3):
264 self, wire, revision, git=True, ignore_whitespace=True, context=3):
265 repo = self._factory.repo(wire)
265 repo = self._factory.repo(wire)
266 ctx = repo[revision]
266 ctx = repo[revision]
267 result = ctx.diff(
267 result = ctx.diff(
268 git=git, ignore_whitespace=ignore_whitespace, context=context)
268 git=git, ignore_whitespace=ignore_whitespace, context=context)
269 return list(result)
269 return list(result)
270
270
271 @reraise_safe_exceptions
271 @reraise_safe_exceptions
272 def ctx_files(self, wire, revision):
272 def ctx_files(self, wire, revision):
273 repo = self._factory.repo(wire)
273 repo = self._factory.repo(wire)
274 ctx = repo[revision]
274 ctx = repo[revision]
275 return ctx.files()
275 return ctx.files()
276
276
277 @reraise_safe_exceptions
277 @reraise_safe_exceptions
278 def ctx_list(self, path, revision):
278 def ctx_list(self, path, revision):
279 repo = self._factory.repo(path)
279 repo = self._factory.repo(path)
280 ctx = repo[revision]
280 ctx = repo[revision]
281 return list(ctx)
281 return list(ctx)
282
282
283 @reraise_safe_exceptions
283 @reraise_safe_exceptions
284 def ctx_parents(self, wire, revision):
284 def ctx_parents(self, wire, revision):
285 repo = self._factory.repo(wire)
285 repo = self._factory.repo(wire)
286 ctx = repo[revision]
286 ctx = repo[revision]
287 return [parent.rev() for parent in ctx.parents()]
287 return [parent.rev() for parent in ctx.parents()]
288
288
289 @reraise_safe_exceptions
289 @reraise_safe_exceptions
290 def ctx_substate(self, wire, revision):
290 def ctx_substate(self, wire, revision):
291 repo = self._factory.repo(wire)
291 repo = self._factory.repo(wire)
292 ctx = repo[revision]
292 ctx = repo[revision]
293 return ctx.substate
293 return ctx.substate
294
294
295 @reraise_safe_exceptions
295 @reraise_safe_exceptions
296 def ctx_status(self, wire, revision):
296 def ctx_status(self, wire, revision):
297 repo = self._factory.repo(wire)
297 repo = self._factory.repo(wire)
298 ctx = repo[revision]
298 ctx = repo[revision]
299 status = repo[ctx.p1().node()].status(other=ctx.node())
299 status = repo[ctx.p1().node()].status(other=ctx.node())
300 # object of status (odd, custom named tuple in mercurial) is not
300 # object of status (odd, custom named tuple in mercurial) is not
301 # correctly serializable via Pyro, we make it a list, as the underling
301 # correctly serializable, we make it a list, as the underling
302 # API expects this to be a list
302 # API expects this to be a list
303 return list(status)
303 return list(status)
304
304
305 @reraise_safe_exceptions
305 @reraise_safe_exceptions
306 def ctx_user(self, wire, revision):
306 def ctx_user(self, wire, revision):
307 repo = self._factory.repo(wire)
307 repo = self._factory.repo(wire)
308 ctx = repo[revision]
308 ctx = repo[revision]
309 return ctx.user()
309 return ctx.user()
310
310
311 @reraise_safe_exceptions
311 @reraise_safe_exceptions
312 def check_url(self, url, config):
312 def check_url(self, url, config):
313 _proto = None
313 _proto = None
314 if '+' in url[:url.find('://')]:
314 if '+' in url[:url.find('://')]:
315 _proto = url[0:url.find('+')]
315 _proto = url[0:url.find('+')]
316 url = url[url.find('+') + 1:]
316 url = url[url.find('+') + 1:]
317 handlers = []
317 handlers = []
318 url_obj = url_parser(url)
318 url_obj = url_parser(url)
319 test_uri, authinfo = url_obj.authinfo()
319 test_uri, authinfo = url_obj.authinfo()
320 url_obj.passwd = '*****' if url_obj.passwd else url_obj.passwd
320 url_obj.passwd = '*****' if url_obj.passwd else url_obj.passwd
321 url_obj.query = obfuscate_qs(url_obj.query)
321 url_obj.query = obfuscate_qs(url_obj.query)
322
322
323 cleaned_uri = str(url_obj)
323 cleaned_uri = str(url_obj)
324 log.info("Checking URL for remote cloning/import: %s", cleaned_uri)
324 log.info("Checking URL for remote cloning/import: %s", cleaned_uri)
325
325
326 if authinfo:
326 if authinfo:
327 # create a password manager
327 # create a password manager
328 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
328 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
329 passmgr.add_password(*authinfo)
329 passmgr.add_password(*authinfo)
330
330
331 handlers.extend((httpbasicauthhandler(passmgr),
331 handlers.extend((httpbasicauthhandler(passmgr),
332 httpdigestauthhandler(passmgr)))
332 httpdigestauthhandler(passmgr)))
333
333
334 o = urllib2.build_opener(*handlers)
334 o = urllib2.build_opener(*handlers)
335 o.addheaders = [('Content-Type', 'application/mercurial-0.1'),
335 o.addheaders = [('Content-Type', 'application/mercurial-0.1'),
336 ('Accept', 'application/mercurial-0.1')]
336 ('Accept', 'application/mercurial-0.1')]
337
337
338 q = {"cmd": 'between'}
338 q = {"cmd": 'between'}
339 q.update({'pairs': "%s-%s" % ('0' * 40, '0' * 40)})
339 q.update({'pairs': "%s-%s" % ('0' * 40, '0' * 40)})
340 qs = '?%s' % urllib.urlencode(q)
340 qs = '?%s' % urllib.urlencode(q)
341 cu = "%s%s" % (test_uri, qs)
341 cu = "%s%s" % (test_uri, qs)
342 req = urllib2.Request(cu, None, {})
342 req = urllib2.Request(cu, None, {})
343
343
344 try:
344 try:
345 log.debug("Trying to open URL %s", cleaned_uri)
345 log.debug("Trying to open URL %s", cleaned_uri)
346 resp = o.open(req)
346 resp = o.open(req)
347 if resp.code != 200:
347 if resp.code != 200:
348 raise exceptions.URLError('Return Code is not 200')
348 raise exceptions.URLError('Return Code is not 200')
349 except Exception as e:
349 except Exception as e:
350 log.warning("URL cannot be opened: %s", cleaned_uri, exc_info=True)
350 log.warning("URL cannot be opened: %s", cleaned_uri, exc_info=True)
351 # means it cannot be cloned
351 # means it cannot be cloned
352 raise exceptions.URLError("[%s] org_exc: %s" % (cleaned_uri, e))
352 raise exceptions.URLError("[%s] org_exc: %s" % (cleaned_uri, e))
353
353
354 # now check if it's a proper hg repo, but don't do it for svn
354 # now check if it's a proper hg repo, but don't do it for svn
355 try:
355 try:
356 if _proto == 'svn':
356 if _proto == 'svn':
357 pass
357 pass
358 else:
358 else:
359 # check for pure hg repos
359 # check for pure hg repos
360 log.debug(
360 log.debug(
361 "Verifying if URL is a Mercurial repository: %s",
361 "Verifying if URL is a Mercurial repository: %s",
362 cleaned_uri)
362 cleaned_uri)
363 httppeer(make_ui_from_config(config), url).lookup('tip')
363 httppeer(make_ui_from_config(config), url).lookup('tip')
364 except Exception as e:
364 except Exception as e:
365 log.warning("URL is not a valid Mercurial repository: %s",
365 log.warning("URL is not a valid Mercurial repository: %s",
366 cleaned_uri)
366 cleaned_uri)
367 raise exceptions.URLError(
367 raise exceptions.URLError(
368 "url [%s] does not look like an hg repo org_exc: %s"
368 "url [%s] does not look like an hg repo org_exc: %s"
369 % (cleaned_uri, e))
369 % (cleaned_uri, e))
370
370
371 log.info("URL is a valid Mercurial repository: %s", cleaned_uri)
371 log.info("URL is a valid Mercurial repository: %s", cleaned_uri)
372 return True
372 return True
373
373
374 @reraise_safe_exceptions
374 @reraise_safe_exceptions
375 def diff(
375 def diff(
376 self, wire, rev1, rev2, file_filter, opt_git, opt_ignorews,
376 self, wire, rev1, rev2, file_filter, opt_git, opt_ignorews,
377 context):
377 context):
378 repo = self._factory.repo(wire)
378 repo = self._factory.repo(wire)
379
379
380 if file_filter:
380 if file_filter:
381 match_filter = match(file_filter[0], '', [file_filter[1]])
381 match_filter = match(file_filter[0], '', [file_filter[1]])
382 else:
382 else:
383 match_filter = file_filter
383 match_filter = file_filter
384 opts = diffopts(git=opt_git, ignorews=opt_ignorews, context=context)
384 opts = diffopts(git=opt_git, ignorews=opt_ignorews, context=context)
385
385
386 try:
386 try:
387 return "".join(patch.diff(
387 return "".join(patch.diff(
388 repo, node1=rev1, node2=rev2, match=match_filter, opts=opts))
388 repo, node1=rev1, node2=rev2, match=match_filter, opts=opts))
389 except RepoLookupError:
389 except RepoLookupError:
390 raise exceptions.LookupException()
390 raise exceptions.LookupException()
391
391
392 @reraise_safe_exceptions
392 @reraise_safe_exceptions
393 def file_history(self, wire, revision, path, limit):
393 def file_history(self, wire, revision, path, limit):
394 repo = self._factory.repo(wire)
394 repo = self._factory.repo(wire)
395
395
396 ctx = repo[revision]
396 ctx = repo[revision]
397 fctx = ctx.filectx(path)
397 fctx = ctx.filectx(path)
398
398
399 def history_iter():
399 def history_iter():
400 limit_rev = fctx.rev()
400 limit_rev = fctx.rev()
401 for obj in reversed(list(fctx.filelog())):
401 for obj in reversed(list(fctx.filelog())):
402 obj = fctx.filectx(obj)
402 obj = fctx.filectx(obj)
403 if limit_rev >= obj.rev():
403 if limit_rev >= obj.rev():
404 yield obj
404 yield obj
405
405
406 history = []
406 history = []
407 for cnt, obj in enumerate(history_iter()):
407 for cnt, obj in enumerate(history_iter()):
408 if limit and cnt >= limit:
408 if limit and cnt >= limit:
409 break
409 break
410 history.append(hex(obj.node()))
410 history.append(hex(obj.node()))
411
411
412 return [x for x in history]
412 return [x for x in history]
413
413
414 @reraise_safe_exceptions
414 @reraise_safe_exceptions
415 def file_history_untill(self, wire, revision, path, limit):
415 def file_history_untill(self, wire, revision, path, limit):
416 repo = self._factory.repo(wire)
416 repo = self._factory.repo(wire)
417 ctx = repo[revision]
417 ctx = repo[revision]
418 fctx = ctx.filectx(path)
418 fctx = ctx.filectx(path)
419
419
420 file_log = list(fctx.filelog())
420 file_log = list(fctx.filelog())
421 if limit:
421 if limit:
422 # Limit to the last n items
422 # Limit to the last n items
423 file_log = file_log[-limit:]
423 file_log = file_log[-limit:]
424
424
425 return [hex(fctx.filectx(cs).node()) for cs in reversed(file_log)]
425 return [hex(fctx.filectx(cs).node()) for cs in reversed(file_log)]
426
426
427 @reraise_safe_exceptions
427 @reraise_safe_exceptions
428 def fctx_annotate(self, wire, revision, path):
428 def fctx_annotate(self, wire, revision, path):
429 repo = self._factory.repo(wire)
429 repo = self._factory.repo(wire)
430 ctx = repo[revision]
430 ctx = repo[revision]
431 fctx = ctx.filectx(path)
431 fctx = ctx.filectx(path)
432
432
433 result = []
433 result = []
434 for i, annotate_data in enumerate(fctx.annotate()):
434 for i, annotate_data in enumerate(fctx.annotate()):
435 ln_no = i + 1
435 ln_no = i + 1
436 node_info, content = annotate_data
436 node_info, content = annotate_data
437 sha = hex(node_info[0].node())
437 sha = hex(node_info[0].node())
438 result.append((ln_no, sha, content))
438 result.append((ln_no, sha, content))
439 return result
439 return result
440
440
441 @reraise_safe_exceptions
441 @reraise_safe_exceptions
442 def fctx_data(self, wire, revision, path):
442 def fctx_data(self, wire, revision, path):
443 repo = self._factory.repo(wire)
443 repo = self._factory.repo(wire)
444 ctx = repo[revision]
444 ctx = repo[revision]
445 fctx = ctx.filectx(path)
445 fctx = ctx.filectx(path)
446 return fctx.data()
446 return fctx.data()
447
447
448 @reraise_safe_exceptions
448 @reraise_safe_exceptions
449 def fctx_flags(self, wire, revision, path):
449 def fctx_flags(self, wire, revision, path):
450 repo = self._factory.repo(wire)
450 repo = self._factory.repo(wire)
451 ctx = repo[revision]
451 ctx = repo[revision]
452 fctx = ctx.filectx(path)
452 fctx = ctx.filectx(path)
453 return fctx.flags()
453 return fctx.flags()
454
454
455 @reraise_safe_exceptions
455 @reraise_safe_exceptions
456 def fctx_size(self, wire, revision, path):
456 def fctx_size(self, wire, revision, path):
457 repo = self._factory.repo(wire)
457 repo = self._factory.repo(wire)
458 ctx = repo[revision]
458 ctx = repo[revision]
459 fctx = ctx.filectx(path)
459 fctx = ctx.filectx(path)
460 return fctx.size()
460 return fctx.size()
461
461
462 @reraise_safe_exceptions
462 @reraise_safe_exceptions
463 def get_all_commit_ids(self, wire, name):
463 def get_all_commit_ids(self, wire, name):
464 repo = self._factory.repo(wire)
464 repo = self._factory.repo(wire)
465 revs = repo.filtered(name).changelog.index
465 revs = repo.filtered(name).changelog.index
466 return map(lambda x: hex(x[7]), revs)[:-1]
466 return map(lambda x: hex(x[7]), revs)[:-1]
467
467
468 @reraise_safe_exceptions
468 @reraise_safe_exceptions
469 def get_config_value(self, wire, section, name, untrusted=False):
469 def get_config_value(self, wire, section, name, untrusted=False):
470 repo = self._factory.repo(wire)
470 repo = self._factory.repo(wire)
471 return repo.ui.config(section, name, untrusted=untrusted)
471 return repo.ui.config(section, name, untrusted=untrusted)
472
472
473 @reraise_safe_exceptions
473 @reraise_safe_exceptions
474 def get_config_bool(self, wire, section, name, untrusted=False):
474 def get_config_bool(self, wire, section, name, untrusted=False):
475 repo = self._factory.repo(wire)
475 repo = self._factory.repo(wire)
476 return repo.ui.configbool(section, name, untrusted=untrusted)
476 return repo.ui.configbool(section, name, untrusted=untrusted)
477
477
478 @reraise_safe_exceptions
478 @reraise_safe_exceptions
479 def get_config_list(self, wire, section, name, untrusted=False):
479 def get_config_list(self, wire, section, name, untrusted=False):
480 repo = self._factory.repo(wire)
480 repo = self._factory.repo(wire)
481 return repo.ui.configlist(section, name, untrusted=untrusted)
481 return repo.ui.configlist(section, name, untrusted=untrusted)
482
482
483 @reraise_safe_exceptions
483 @reraise_safe_exceptions
484 def is_large_file(self, wire, path):
484 def is_large_file(self, wire, path):
485 return largefiles.lfutil.isstandin(path)
485 return largefiles.lfutil.isstandin(path)
486
486
487 @reraise_safe_exceptions
487 @reraise_safe_exceptions
488 def in_largefiles_store(self, wire, sha):
488 def in_largefiles_store(self, wire, sha):
489 repo = self._factory.repo(wire)
489 repo = self._factory.repo(wire)
490 return largefiles.lfutil.instore(repo, sha)
490 return largefiles.lfutil.instore(repo, sha)
491
491
492 @reraise_safe_exceptions
492 @reraise_safe_exceptions
493 def in_user_cache(self, wire, sha):
493 def in_user_cache(self, wire, sha):
494 repo = self._factory.repo(wire)
494 repo = self._factory.repo(wire)
495 return largefiles.lfutil.inusercache(repo.ui, sha)
495 return largefiles.lfutil.inusercache(repo.ui, sha)
496
496
497 @reraise_safe_exceptions
497 @reraise_safe_exceptions
498 def store_path(self, wire, sha):
498 def store_path(self, wire, sha):
499 repo = self._factory.repo(wire)
499 repo = self._factory.repo(wire)
500 return largefiles.lfutil.storepath(repo, sha)
500 return largefiles.lfutil.storepath(repo, sha)
501
501
502 @reraise_safe_exceptions
502 @reraise_safe_exceptions
503 def link(self, wire, sha, path):
503 def link(self, wire, sha, path):
504 repo = self._factory.repo(wire)
504 repo = self._factory.repo(wire)
505 largefiles.lfutil.link(
505 largefiles.lfutil.link(
506 largefiles.lfutil.usercachepath(repo.ui, sha), path)
506 largefiles.lfutil.usercachepath(repo.ui, sha), path)
507
507
508 @reraise_safe_exceptions
508 @reraise_safe_exceptions
509 def localrepository(self, wire, create=False):
509 def localrepository(self, wire, create=False):
510 self._factory.repo(wire, create=create)
510 self._factory.repo(wire, create=create)
511
511
512 @reraise_safe_exceptions
512 @reraise_safe_exceptions
513 def lookup(self, wire, revision, both):
513 def lookup(self, wire, revision, both):
514 # TODO Paris: Ugly hack to "deserialize" long for msgpack
514 # TODO Paris: Ugly hack to "deserialize" long for msgpack
515 if isinstance(revision, float):
515 if isinstance(revision, float):
516 revision = long(revision)
516 revision = long(revision)
517 repo = self._factory.repo(wire)
517 repo = self._factory.repo(wire)
518 try:
518 try:
519 ctx = repo[revision]
519 ctx = repo[revision]
520 except RepoLookupError:
520 except RepoLookupError:
521 raise exceptions.LookupException(revision)
521 raise exceptions.LookupException(revision)
522 except LookupError as e:
522 except LookupError as e:
523 raise exceptions.LookupException(e.name)
523 raise exceptions.LookupException(e.name)
524
524
525 if not both:
525 if not both:
526 return ctx.hex()
526 return ctx.hex()
527
527
528 ctx = repo[ctx.hex()]
528 ctx = repo[ctx.hex()]
529 return ctx.hex(), ctx.rev()
529 return ctx.hex(), ctx.rev()
530
530
531 @reraise_safe_exceptions
531 @reraise_safe_exceptions
532 def pull(self, wire, url, commit_ids=None):
532 def pull(self, wire, url, commit_ids=None):
533 repo = self._factory.repo(wire)
533 repo = self._factory.repo(wire)
534 remote = peer(repo, {}, url)
534 remote = peer(repo, {}, url)
535 if commit_ids:
535 if commit_ids:
536 commit_ids = [bin(commit_id) for commit_id in commit_ids]
536 commit_ids = [bin(commit_id) for commit_id in commit_ids]
537
537
538 return exchange.pull(
538 return exchange.pull(
539 repo, remote, heads=commit_ids, force=None).cgresult
539 repo, remote, heads=commit_ids, force=None).cgresult
540
540
541 @reraise_safe_exceptions
541 @reraise_safe_exceptions
542 def revision(self, wire, rev):
542 def revision(self, wire, rev):
543 repo = self._factory.repo(wire)
543 repo = self._factory.repo(wire)
544 ctx = repo[rev]
544 ctx = repo[rev]
545 return ctx.rev()
545 return ctx.rev()
546
546
547 @reraise_safe_exceptions
547 @reraise_safe_exceptions
548 def rev_range(self, wire, filter):
548 def rev_range(self, wire, filter):
549 repo = self._factory.repo(wire)
549 repo = self._factory.repo(wire)
550 revisions = [rev for rev in revrange(repo, filter)]
550 revisions = [rev for rev in revrange(repo, filter)]
551 return revisions
551 return revisions
552
552
553 @reraise_safe_exceptions
553 @reraise_safe_exceptions
554 def rev_range_hash(self, wire, node):
554 def rev_range_hash(self, wire, node):
555 repo = self._factory.repo(wire)
555 repo = self._factory.repo(wire)
556
556
557 def get_revs(repo, rev_opt):
557 def get_revs(repo, rev_opt):
558 if rev_opt:
558 if rev_opt:
559 revs = revrange(repo, rev_opt)
559 revs = revrange(repo, rev_opt)
560 if len(revs) == 0:
560 if len(revs) == 0:
561 return (nullrev, nullrev)
561 return (nullrev, nullrev)
562 return max(revs), min(revs)
562 return max(revs), min(revs)
563 else:
563 else:
564 return len(repo) - 1, 0
564 return len(repo) - 1, 0
565
565
566 stop, start = get_revs(repo, [node + ':'])
566 stop, start = get_revs(repo, [node + ':'])
567 revs = [hex(repo[r].node()) for r in xrange(start, stop + 1)]
567 revs = [hex(repo[r].node()) for r in xrange(start, stop + 1)]
568 return revs
568 return revs
569
569
570 @reraise_safe_exceptions
570 @reraise_safe_exceptions
571 def revs_from_revspec(self, wire, rev_spec, *args, **kwargs):
571 def revs_from_revspec(self, wire, rev_spec, *args, **kwargs):
572 other_path = kwargs.pop('other_path', None)
572 other_path = kwargs.pop('other_path', None)
573
573
574 # case when we want to compare two independent repositories
574 # case when we want to compare two independent repositories
575 if other_path and other_path != wire["path"]:
575 if other_path and other_path != wire["path"]:
576 baseui = self._factory._create_config(wire["config"])
576 baseui = self._factory._create_config(wire["config"])
577 repo = unionrepo.unionrepository(baseui, other_path, wire["path"])
577 repo = unionrepo.unionrepository(baseui, other_path, wire["path"])
578 else:
578 else:
579 repo = self._factory.repo(wire)
579 repo = self._factory.repo(wire)
580 return list(repo.revs(rev_spec, *args))
580 return list(repo.revs(rev_spec, *args))
581
581
582 @reraise_safe_exceptions
582 @reraise_safe_exceptions
583 def strip(self, wire, revision, update, backup):
583 def strip(self, wire, revision, update, backup):
584 repo = self._factory.repo(wire)
584 repo = self._factory.repo(wire)
585 ctx = repo[revision]
585 ctx = repo[revision]
586 hgext_strip(
586 hgext_strip(
587 repo.baseui, repo, ctx.node(), update=update, backup=backup)
587 repo.baseui, repo, ctx.node(), update=update, backup=backup)
588
588
589 @reraise_safe_exceptions
589 @reraise_safe_exceptions
590 def verify(self, wire,):
590 def verify(self, wire,):
591 repo = self._factory.repo(wire)
591 repo = self._factory.repo(wire)
592 baseui = self._factory._create_config(wire['config'])
592 baseui = self._factory._create_config(wire['config'])
593 baseui.setconfig('ui', 'quiet', 'false')
593 baseui.setconfig('ui', 'quiet', 'false')
594 output = io.BytesIO()
594 output = io.BytesIO()
595
595
596 def write(data, **unused_kwargs):
596 def write(data, **unused_kwargs):
597 output.write(data)
597 output.write(data)
598 baseui.write = write
598 baseui.write = write
599
599
600 repo.ui = baseui
600 repo.ui = baseui
601 verify.verify(repo)
601 verify.verify(repo)
602 return output.getvalue()
602 return output.getvalue()
603
603
604 @reraise_safe_exceptions
604 @reraise_safe_exceptions
605 def tag(self, wire, name, revision, message, local, user,
605 def tag(self, wire, name, revision, message, local, user,
606 tag_time, tag_timezone):
606 tag_time, tag_timezone):
607 repo = self._factory.repo(wire)
607 repo = self._factory.repo(wire)
608 ctx = repo[revision]
608 ctx = repo[revision]
609 node = ctx.node()
609 node = ctx.node()
610
610
611 date = (tag_time, tag_timezone)
611 date = (tag_time, tag_timezone)
612 try:
612 try:
613 repo.tag(name, node, message, local, user, date)
613 repo.tag(name, node, message, local, user, date)
614 except Abort as e:
614 except Abort as e:
615 log.exception("Tag operation aborted")
615 log.exception("Tag operation aborted")
616 # Exception can contain unicode which we convert
616 # Exception can contain unicode which we convert
617 raise exceptions.AbortException(repr(e))
617 raise exceptions.AbortException(repr(e))
618
618
619 @reraise_safe_exceptions
619 @reraise_safe_exceptions
620 def tags(self, wire):
620 def tags(self, wire):
621 repo = self._factory.repo(wire)
621 repo = self._factory.repo(wire)
622 return repo.tags()
622 return repo.tags()
623
623
624 @reraise_safe_exceptions
624 @reraise_safe_exceptions
625 def update(self, wire, node=None, clean=False):
625 def update(self, wire, node=None, clean=False):
626 repo = self._factory.repo(wire)
626 repo = self._factory.repo(wire)
627 baseui = self._factory._create_config(wire['config'])
627 baseui = self._factory._create_config(wire['config'])
628 commands.update(baseui, repo, node=node, clean=clean)
628 commands.update(baseui, repo, node=node, clean=clean)
629
629
630 @reraise_safe_exceptions
630 @reraise_safe_exceptions
631 def identify(self, wire):
631 def identify(self, wire):
632 repo = self._factory.repo(wire)
632 repo = self._factory.repo(wire)
633 baseui = self._factory._create_config(wire['config'])
633 baseui = self._factory._create_config(wire['config'])
634 output = io.BytesIO()
634 output = io.BytesIO()
635 baseui.write = output.write
635 baseui.write = output.write
636 # This is required to get a full node id
636 # This is required to get a full node id
637 baseui.debugflag = True
637 baseui.debugflag = True
638 commands.identify(baseui, repo, id=True)
638 commands.identify(baseui, repo, id=True)
639
639
640 return output.getvalue()
640 return output.getvalue()
641
641
642 @reraise_safe_exceptions
642 @reraise_safe_exceptions
643 def pull_cmd(self, wire, source, bookmark=None, branch=None, revision=None,
643 def pull_cmd(self, wire, source, bookmark=None, branch=None, revision=None,
644 hooks=True):
644 hooks=True):
645 repo = self._factory.repo(wire)
645 repo = self._factory.repo(wire)
646 baseui = self._factory._create_config(wire['config'], hooks=hooks)
646 baseui = self._factory._create_config(wire['config'], hooks=hooks)
647
647
648 # Mercurial internally has a lot of logic that checks ONLY if
648 # Mercurial internally has a lot of logic that checks ONLY if
649 # option is defined, we just pass those if they are defined then
649 # option is defined, we just pass those if they are defined then
650 opts = {}
650 opts = {}
651 if bookmark:
651 if bookmark:
652 opts['bookmark'] = bookmark
652 opts['bookmark'] = bookmark
653 if branch:
653 if branch:
654 opts['branch'] = branch
654 opts['branch'] = branch
655 if revision:
655 if revision:
656 opts['rev'] = revision
656 opts['rev'] = revision
657
657
658 commands.pull(baseui, repo, source, **opts)
658 commands.pull(baseui, repo, source, **opts)
659
659
660 @reraise_safe_exceptions
660 @reraise_safe_exceptions
661 def heads(self, wire, branch=None):
661 def heads(self, wire, branch=None):
662 repo = self._factory.repo(wire)
662 repo = self._factory.repo(wire)
663 baseui = self._factory._create_config(wire['config'])
663 baseui = self._factory._create_config(wire['config'])
664 output = io.BytesIO()
664 output = io.BytesIO()
665
665
666 def write(data, **unused_kwargs):
666 def write(data, **unused_kwargs):
667 output.write(data)
667 output.write(data)
668
668
669 baseui.write = write
669 baseui.write = write
670 if branch:
670 if branch:
671 args = [branch]
671 args = [branch]
672 else:
672 else:
673 args = []
673 args = []
674 commands.heads(baseui, repo, template='{node} ', *args)
674 commands.heads(baseui, repo, template='{node} ', *args)
675
675
676 return output.getvalue()
676 return output.getvalue()
677
677
678 @reraise_safe_exceptions
678 @reraise_safe_exceptions
679 def ancestor(self, wire, revision1, revision2):
679 def ancestor(self, wire, revision1, revision2):
680 repo = self._factory.repo(wire)
680 repo = self._factory.repo(wire)
681 changelog = repo.changelog
681 changelog = repo.changelog
682 lookup = repo.lookup
682 lookup = repo.lookup
683 a = changelog.ancestor(lookup(revision1), lookup(revision2))
683 a = changelog.ancestor(lookup(revision1), lookup(revision2))
684 return hex(a)
684 return hex(a)
685
685
686 @reraise_safe_exceptions
686 @reraise_safe_exceptions
687 def push(self, wire, revisions, dest_path, hooks=True,
687 def push(self, wire, revisions, dest_path, hooks=True,
688 push_branches=False):
688 push_branches=False):
689 repo = self._factory.repo(wire)
689 repo = self._factory.repo(wire)
690 baseui = self._factory._create_config(wire['config'], hooks=hooks)
690 baseui = self._factory._create_config(wire['config'], hooks=hooks)
691 commands.push(baseui, repo, dest=dest_path, rev=revisions,
691 commands.push(baseui, repo, dest=dest_path, rev=revisions,
692 new_branch=push_branches)
692 new_branch=push_branches)
693
693
694 @reraise_safe_exceptions
694 @reraise_safe_exceptions
695 def merge(self, wire, revision):
695 def merge(self, wire, revision):
696 repo = self._factory.repo(wire)
696 repo = self._factory.repo(wire)
697 baseui = self._factory._create_config(wire['config'])
697 baseui = self._factory._create_config(wire['config'])
698 repo.ui.setconfig('ui', 'merge', 'internal:dump')
698 repo.ui.setconfig('ui', 'merge', 'internal:dump')
699
699
700 # In case of sub repositories are used mercurial prompts the user in
700 # In case of sub repositories are used mercurial prompts the user in
701 # case of merge conflicts or different sub repository sources. By
701 # case of merge conflicts or different sub repository sources. By
702 # setting the interactive flag to `False` mercurial doesn't prompt the
702 # setting the interactive flag to `False` mercurial doesn't prompt the
703 # used but instead uses a default value.
703 # used but instead uses a default value.
704 repo.ui.setconfig('ui', 'interactive', False)
704 repo.ui.setconfig('ui', 'interactive', False)
705
705
706 commands.merge(baseui, repo, rev=revision)
706 commands.merge(baseui, repo, rev=revision)
707
707
708 @reraise_safe_exceptions
708 @reraise_safe_exceptions
709 def commit(self, wire, message, username):
709 def commit(self, wire, message, username):
710 repo = self._factory.repo(wire)
710 repo = self._factory.repo(wire)
711 baseui = self._factory._create_config(wire['config'])
711 baseui = self._factory._create_config(wire['config'])
712 repo.ui.setconfig('ui', 'username', username)
712 repo.ui.setconfig('ui', 'username', username)
713 commands.commit(baseui, repo, message=message)
713 commands.commit(baseui, repo, message=message)
714
714
715 @reraise_safe_exceptions
715 @reraise_safe_exceptions
716 def rebase(self, wire, source=None, dest=None, abort=False):
716 def rebase(self, wire, source=None, dest=None, abort=False):
717 repo = self._factory.repo(wire)
717 repo = self._factory.repo(wire)
718 baseui = self._factory._create_config(wire['config'])
718 baseui = self._factory._create_config(wire['config'])
719 repo.ui.setconfig('ui', 'merge', 'internal:dump')
719 repo.ui.setconfig('ui', 'merge', 'internal:dump')
720 rebase.rebase(
720 rebase.rebase(
721 baseui, repo, base=source, dest=dest, abort=abort, keep=not abort)
721 baseui, repo, base=source, dest=dest, abort=abort, keep=not abort)
722
722
723 @reraise_safe_exceptions
723 @reraise_safe_exceptions
724 def bookmark(self, wire, bookmark, revision=None):
724 def bookmark(self, wire, bookmark, revision=None):
725 repo = self._factory.repo(wire)
725 repo = self._factory.repo(wire)
726 baseui = self._factory._create_config(wire['config'])
726 baseui = self._factory._create_config(wire['config'])
727 commands.bookmark(baseui, repo, bookmark, rev=revision, force=True)
727 commands.bookmark(baseui, repo, bookmark, rev=revision, force=True)
@@ -1,404 +1,390 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # RhodeCode VCSServer provides access to different vcs backends via network.
3 # RhodeCode VCSServer provides access to different vcs backends via network.
4 # Copyright (C) 2014-2017 RodeCode GmbH
4 # Copyright (C) 2014-2017 RodeCode GmbH
5 #
5 #
6 # This program is free software; you can redistribute it and/or modify
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
9 # (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software Foundation,
17 # along with this program; if not, write to the Free Software Foundation,
18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
19
20 import io
20 import io
21 import sys
21 import sys
22 import json
22 import json
23 import logging
23 import logging
24 import collections
24 import collections
25 import importlib
25 import importlib
26 import subprocess
26 import subprocess
27
27
28 from httplib import HTTPConnection
28 from httplib import HTTPConnection
29
29
30
30
31 import mercurial.scmutil
31 import mercurial.scmutil
32 import mercurial.node
32 import mercurial.node
33 import Pyro4
34 import simplejson as json
33 import simplejson as json
35
34
36 from vcsserver import exceptions
35 from vcsserver import exceptions
37
36
38 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
39
38
40
39
41 class HooksHttpClient(object):
40 class HooksHttpClient(object):
42 connection = None
41 connection = None
43
42
44 def __init__(self, hooks_uri):
43 def __init__(self, hooks_uri):
45 self.hooks_uri = hooks_uri
44 self.hooks_uri = hooks_uri
46
45
47 def __call__(self, method, extras):
46 def __call__(self, method, extras):
48 connection = HTTPConnection(self.hooks_uri)
47 connection = HTTPConnection(self.hooks_uri)
49 body = self._serialize(method, extras)
48 body = self._serialize(method, extras)
50 connection.request('POST', '/', body)
49 connection.request('POST', '/', body)
51 response = connection.getresponse()
50 response = connection.getresponse()
52 return json.loads(response.read())
51 return json.loads(response.read())
53
52
54 def _serialize(self, hook_name, extras):
53 def _serialize(self, hook_name, extras):
55 data = {
54 data = {
56 'method': hook_name,
55 'method': hook_name,
57 'extras': extras
56 'extras': extras
58 }
57 }
59 return json.dumps(data)
58 return json.dumps(data)
60
59
61
60
62 class HooksDummyClient(object):
61 class HooksDummyClient(object):
63 def __init__(self, hooks_module):
62 def __init__(self, hooks_module):
64 self._hooks_module = importlib.import_module(hooks_module)
63 self._hooks_module = importlib.import_module(hooks_module)
65
64
66 def __call__(self, hook_name, extras):
65 def __call__(self, hook_name, extras):
67 with self._hooks_module.Hooks() as hooks:
66 with self._hooks_module.Hooks() as hooks:
68 return getattr(hooks, hook_name)(extras)
67 return getattr(hooks, hook_name)(extras)
69
68
70
69
71 class HooksPyro4Client(object):
72 def __init__(self, hooks_uri):
73 self.hooks_uri = hooks_uri
74
75 def __call__(self, hook_name, extras):
76 with Pyro4.Proxy(self.hooks_uri) as hooks:
77 return getattr(hooks, hook_name)(extras)
78
79
80 class RemoteMessageWriter(object):
70 class RemoteMessageWriter(object):
81 """Writer base class."""
71 """Writer base class."""
82 def write(message):
72 def write(message):
83 raise NotImplementedError()
73 raise NotImplementedError()
84
74
85
75
86 class HgMessageWriter(RemoteMessageWriter):
76 class HgMessageWriter(RemoteMessageWriter):
87 """Writer that knows how to send messages to mercurial clients."""
77 """Writer that knows how to send messages to mercurial clients."""
88
78
89 def __init__(self, ui):
79 def __init__(self, ui):
90 self.ui = ui
80 self.ui = ui
91
81
92 def write(self, message):
82 def write(self, message):
93 # TODO: Check why the quiet flag is set by default.
83 # TODO: Check why the quiet flag is set by default.
94 old = self.ui.quiet
84 old = self.ui.quiet
95 self.ui.quiet = False
85 self.ui.quiet = False
96 self.ui.status(message.encode('utf-8'))
86 self.ui.status(message.encode('utf-8'))
97 self.ui.quiet = old
87 self.ui.quiet = old
98
88
99
89
100 class GitMessageWriter(RemoteMessageWriter):
90 class GitMessageWriter(RemoteMessageWriter):
101 """Writer that knows how to send messages to git clients."""
91 """Writer that knows how to send messages to git clients."""
102
92
103 def __init__(self, stdout=None):
93 def __init__(self, stdout=None):
104 self.stdout = stdout or sys.stdout
94 self.stdout = stdout or sys.stdout
105
95
106 def write(self, message):
96 def write(self, message):
107 self.stdout.write(message.encode('utf-8'))
97 self.stdout.write(message.encode('utf-8'))
108
98
109
99
110 def _handle_exception(result):
100 def _handle_exception(result):
111 exception_class = result.get('exception')
101 exception_class = result.get('exception')
112 exception_traceback = result.get('exception_traceback')
102 exception_traceback = result.get('exception_traceback')
113
103
114 if exception_traceback:
104 if exception_traceback:
115 log.error('Got traceback from remote call:%s', exception_traceback)
105 log.error('Got traceback from remote call:%s', exception_traceback)
116
106
117 if exception_class == 'HTTPLockedRC':
107 if exception_class == 'HTTPLockedRC':
118 raise exceptions.RepositoryLockedException(*result['exception_args'])
108 raise exceptions.RepositoryLockedException(*result['exception_args'])
119 elif exception_class == 'RepositoryError':
109 elif exception_class == 'RepositoryError':
120 raise exceptions.VcsException(*result['exception_args'])
110 raise exceptions.VcsException(*result['exception_args'])
121 elif exception_class:
111 elif exception_class:
122 raise Exception('Got remote exception "%s" with args "%s"' %
112 raise Exception('Got remote exception "%s" with args "%s"' %
123 (exception_class, result['exception_args']))
113 (exception_class, result['exception_args']))
124
114
125
115
126 def _get_hooks_client(extras):
116 def _get_hooks_client(extras):
127 if 'hooks_uri' in extras:
117 if 'hooks_uri' in extras:
128 protocol = extras.get('hooks_protocol')
118 protocol = extras.get('hooks_protocol')
129 return (
119 return HooksHttpClient(extras['hooks_uri'])
130 HooksHttpClient(extras['hooks_uri'])
131 if protocol == 'http'
132 else HooksPyro4Client(extras['hooks_uri'])
133 )
134 else:
120 else:
135 return HooksDummyClient(extras['hooks_module'])
121 return HooksDummyClient(extras['hooks_module'])
136
122
137
123
138 def _call_hook(hook_name, extras, writer):
124 def _call_hook(hook_name, extras, writer):
139 hooks = _get_hooks_client(extras)
125 hooks = _get_hooks_client(extras)
140 result = hooks(hook_name, extras)
126 result = hooks(hook_name, extras)
141 writer.write(result['output'])
127 writer.write(result['output'])
142 _handle_exception(result)
128 _handle_exception(result)
143
129
144 return result['status']
130 return result['status']
145
131
146
132
147 def _extras_from_ui(ui):
133 def _extras_from_ui(ui):
148 extras = json.loads(ui.config('rhodecode', 'RC_SCM_DATA'))
134 extras = json.loads(ui.config('rhodecode', 'RC_SCM_DATA'))
149 return extras
135 return extras
150
136
151
137
152 def repo_size(ui, repo, **kwargs):
138 def repo_size(ui, repo, **kwargs):
153 return _call_hook('repo_size', _extras_from_ui(ui), HgMessageWriter(ui))
139 return _call_hook('repo_size', _extras_from_ui(ui), HgMessageWriter(ui))
154
140
155
141
156 def pre_pull(ui, repo, **kwargs):
142 def pre_pull(ui, repo, **kwargs):
157 return _call_hook('pre_pull', _extras_from_ui(ui), HgMessageWriter(ui))
143 return _call_hook('pre_pull', _extras_from_ui(ui), HgMessageWriter(ui))
158
144
159
145
160 def post_pull(ui, repo, **kwargs):
146 def post_pull(ui, repo, **kwargs):
161 return _call_hook('post_pull', _extras_from_ui(ui), HgMessageWriter(ui))
147 return _call_hook('post_pull', _extras_from_ui(ui), HgMessageWriter(ui))
162
148
163
149
164 def pre_push(ui, repo, node=None, **kwargs):
150 def pre_push(ui, repo, node=None, **kwargs):
165 extras = _extras_from_ui(ui)
151 extras = _extras_from_ui(ui)
166
152
167 rev_data = []
153 rev_data = []
168 if node and kwargs.get('hooktype') == 'pretxnchangegroup':
154 if node and kwargs.get('hooktype') == 'pretxnchangegroup':
169 branches = collections.defaultdict(list)
155 branches = collections.defaultdict(list)
170 for commit_id, branch in _rev_range_hash(repo, node, with_branch=True):
156 for commit_id, branch in _rev_range_hash(repo, node, with_branch=True):
171 branches[branch].append(commit_id)
157 branches[branch].append(commit_id)
172
158
173 for branch, commits in branches.iteritems():
159 for branch, commits in branches.iteritems():
174 old_rev = kwargs.get('node_last') or commits[0]
160 old_rev = kwargs.get('node_last') or commits[0]
175 rev_data.append({
161 rev_data.append({
176 'old_rev': old_rev,
162 'old_rev': old_rev,
177 'new_rev': commits[-1],
163 'new_rev': commits[-1],
178 'ref': '',
164 'ref': '',
179 'type': 'branch',
165 'type': 'branch',
180 'name': branch,
166 'name': branch,
181 })
167 })
182
168
183 extras['commit_ids'] = rev_data
169 extras['commit_ids'] = rev_data
184 return _call_hook('pre_push', extras, HgMessageWriter(ui))
170 return _call_hook('pre_push', extras, HgMessageWriter(ui))
185
171
186
172
187 def _rev_range_hash(repo, node, with_branch=False):
173 def _rev_range_hash(repo, node, with_branch=False):
188
174
189 commits = []
175 commits = []
190 for rev in xrange(repo[node], len(repo)):
176 for rev in xrange(repo[node], len(repo)):
191 ctx = repo[rev]
177 ctx = repo[rev]
192 commit_id = mercurial.node.hex(ctx.node())
178 commit_id = mercurial.node.hex(ctx.node())
193 branch = ctx.branch()
179 branch = ctx.branch()
194 if with_branch:
180 if with_branch:
195 commits.append((commit_id, branch))
181 commits.append((commit_id, branch))
196 else:
182 else:
197 commits.append(commit_id)
183 commits.append(commit_id)
198
184
199 return commits
185 return commits
200
186
201
187
202 def post_push(ui, repo, node, **kwargs):
188 def post_push(ui, repo, node, **kwargs):
203 commit_ids = _rev_range_hash(repo, node)
189 commit_ids = _rev_range_hash(repo, node)
204
190
205 extras = _extras_from_ui(ui)
191 extras = _extras_from_ui(ui)
206 extras['commit_ids'] = commit_ids
192 extras['commit_ids'] = commit_ids
207
193
208 return _call_hook('post_push', extras, HgMessageWriter(ui))
194 return _call_hook('post_push', extras, HgMessageWriter(ui))
209
195
210
196
211 # backward compat
197 # backward compat
212 log_pull_action = post_pull
198 log_pull_action = post_pull
213
199
214 # backward compat
200 # backward compat
215 log_push_action = post_push
201 log_push_action = post_push
216
202
217
203
218 def handle_git_pre_receive(unused_repo_path, unused_revs, unused_env):
204 def handle_git_pre_receive(unused_repo_path, unused_revs, unused_env):
219 """
205 """
220 Old hook name: keep here for backward compatibility.
206 Old hook name: keep here for backward compatibility.
221
207
222 This is only required when the installed git hooks are not upgraded.
208 This is only required when the installed git hooks are not upgraded.
223 """
209 """
224 pass
210 pass
225
211
226
212
227 def handle_git_post_receive(unused_repo_path, unused_revs, unused_env):
213 def handle_git_post_receive(unused_repo_path, unused_revs, unused_env):
228 """
214 """
229 Old hook name: keep here for backward compatibility.
215 Old hook name: keep here for backward compatibility.
230
216
231 This is only required when the installed git hooks are not upgraded.
217 This is only required when the installed git hooks are not upgraded.
232 """
218 """
233 pass
219 pass
234
220
235
221
236 HookResponse = collections.namedtuple('HookResponse', ('status', 'output'))
222 HookResponse = collections.namedtuple('HookResponse', ('status', 'output'))
237
223
238
224
239 def git_pre_pull(extras):
225 def git_pre_pull(extras):
240 """
226 """
241 Pre pull hook.
227 Pre pull hook.
242
228
243 :param extras: dictionary containing the keys defined in simplevcs
229 :param extras: dictionary containing the keys defined in simplevcs
244 :type extras: dict
230 :type extras: dict
245
231
246 :return: status code of the hook. 0 for success.
232 :return: status code of the hook. 0 for success.
247 :rtype: int
233 :rtype: int
248 """
234 """
249 if 'pull' not in extras['hooks']:
235 if 'pull' not in extras['hooks']:
250 return HookResponse(0, '')
236 return HookResponse(0, '')
251
237
252 stdout = io.BytesIO()
238 stdout = io.BytesIO()
253 try:
239 try:
254 status = _call_hook('pre_pull', extras, GitMessageWriter(stdout))
240 status = _call_hook('pre_pull', extras, GitMessageWriter(stdout))
255 except Exception as error:
241 except Exception as error:
256 status = 128
242 status = 128
257 stdout.write('ERROR: %s\n' % str(error))
243 stdout.write('ERROR: %s\n' % str(error))
258
244
259 return HookResponse(status, stdout.getvalue())
245 return HookResponse(status, stdout.getvalue())
260
246
261
247
262 def git_post_pull(extras):
248 def git_post_pull(extras):
263 """
249 """
264 Post pull hook.
250 Post pull hook.
265
251
266 :param extras: dictionary containing the keys defined in simplevcs
252 :param extras: dictionary containing the keys defined in simplevcs
267 :type extras: dict
253 :type extras: dict
268
254
269 :return: status code of the hook. 0 for success.
255 :return: status code of the hook. 0 for success.
270 :rtype: int
256 :rtype: int
271 """
257 """
272 if 'pull' not in extras['hooks']:
258 if 'pull' not in extras['hooks']:
273 return HookResponse(0, '')
259 return HookResponse(0, '')
274
260
275 stdout = io.BytesIO()
261 stdout = io.BytesIO()
276 try:
262 try:
277 status = _call_hook('post_pull', extras, GitMessageWriter(stdout))
263 status = _call_hook('post_pull', extras, GitMessageWriter(stdout))
278 except Exception as error:
264 except Exception as error:
279 status = 128
265 status = 128
280 stdout.write('ERROR: %s\n' % error)
266 stdout.write('ERROR: %s\n' % error)
281
267
282 return HookResponse(status, stdout.getvalue())
268 return HookResponse(status, stdout.getvalue())
283
269
284
270
285 def _parse_git_ref_lines(revision_lines):
271 def _parse_git_ref_lines(revision_lines):
286 rev_data = []
272 rev_data = []
287 for revision_line in revision_lines or []:
273 for revision_line in revision_lines or []:
288 old_rev, new_rev, ref = revision_line.strip().split(' ')
274 old_rev, new_rev, ref = revision_line.strip().split(' ')
289 ref_data = ref.split('/', 2)
275 ref_data = ref.split('/', 2)
290 if ref_data[1] in ('tags', 'heads'):
276 if ref_data[1] in ('tags', 'heads'):
291 rev_data.append({
277 rev_data.append({
292 'old_rev': old_rev,
278 'old_rev': old_rev,
293 'new_rev': new_rev,
279 'new_rev': new_rev,
294 'ref': ref,
280 'ref': ref,
295 'type': ref_data[1],
281 'type': ref_data[1],
296 'name': ref_data[2],
282 'name': ref_data[2],
297 })
283 })
298 return rev_data
284 return rev_data
299
285
300
286
301 def git_pre_receive(unused_repo_path, revision_lines, env):
287 def git_pre_receive(unused_repo_path, revision_lines, env):
302 """
288 """
303 Pre push hook.
289 Pre push hook.
304
290
305 :param extras: dictionary containing the keys defined in simplevcs
291 :param extras: dictionary containing the keys defined in simplevcs
306 :type extras: dict
292 :type extras: dict
307
293
308 :return: status code of the hook. 0 for success.
294 :return: status code of the hook. 0 for success.
309 :rtype: int
295 :rtype: int
310 """
296 """
311 extras = json.loads(env['RC_SCM_DATA'])
297 extras = json.loads(env['RC_SCM_DATA'])
312 rev_data = _parse_git_ref_lines(revision_lines)
298 rev_data = _parse_git_ref_lines(revision_lines)
313 if 'push' not in extras['hooks']:
299 if 'push' not in extras['hooks']:
314 return 0
300 return 0
315 extras['commit_ids'] = rev_data
301 extras['commit_ids'] = rev_data
316 return _call_hook('pre_push', extras, GitMessageWriter())
302 return _call_hook('pre_push', extras, GitMessageWriter())
317
303
318
304
319 def _run_command(arguments):
305 def _run_command(arguments):
320 """
306 """
321 Run the specified command and return the stdout.
307 Run the specified command and return the stdout.
322
308
323 :param arguments: sequence of program arguments (including the program name)
309 :param arguments: sequence of program arguments (including the program name)
324 :type arguments: list[str]
310 :type arguments: list[str]
325 """
311 """
326 # TODO(skreft): refactor this method and all the other similar ones.
312 # TODO(skreft): refactor this method and all the other similar ones.
327 # Probably this should be using subprocessio.
313 # Probably this should be using subprocessio.
328 process = subprocess.Popen(
314 process = subprocess.Popen(
329 arguments, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
315 arguments, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
330 stdout, _ = process.communicate()
316 stdout, _ = process.communicate()
331
317
332 if process.returncode != 0:
318 if process.returncode != 0:
333 raise Exception(
319 raise Exception(
334 'Command %s exited with exit code %s' % (arguments,
320 'Command %s exited with exit code %s' % (arguments,
335 process.returncode))
321 process.returncode))
336
322
337 return stdout
323 return stdout
338
324
339
325
340 def git_post_receive(unused_repo_path, revision_lines, env):
326 def git_post_receive(unused_repo_path, revision_lines, env):
341 """
327 """
342 Post push hook.
328 Post push hook.
343
329
344 :param extras: dictionary containing the keys defined in simplevcs
330 :param extras: dictionary containing the keys defined in simplevcs
345 :type extras: dict
331 :type extras: dict
346
332
347 :return: status code of the hook. 0 for success.
333 :return: status code of the hook. 0 for success.
348 :rtype: int
334 :rtype: int
349 """
335 """
350 extras = json.loads(env['RC_SCM_DATA'])
336 extras = json.loads(env['RC_SCM_DATA'])
351 if 'push' not in extras['hooks']:
337 if 'push' not in extras['hooks']:
352 return 0
338 return 0
353
339
354 rev_data = _parse_git_ref_lines(revision_lines)
340 rev_data = _parse_git_ref_lines(revision_lines)
355
341
356 git_revs = []
342 git_revs = []
357
343
358 # N.B.(skreft): it is ok to just call git, as git before calling a
344 # N.B.(skreft): it is ok to just call git, as git before calling a
359 # subcommand sets the PATH environment variable so that it point to the
345 # subcommand sets the PATH environment variable so that it point to the
360 # correct version of the git executable.
346 # correct version of the git executable.
361 empty_commit_id = '0' * 40
347 empty_commit_id = '0' * 40
362 for push_ref in rev_data:
348 for push_ref in rev_data:
363 type_ = push_ref['type']
349 type_ = push_ref['type']
364 if type_ == 'heads':
350 if type_ == 'heads':
365 if push_ref['old_rev'] == empty_commit_id:
351 if push_ref['old_rev'] == empty_commit_id:
366
352
367 # Fix up head revision if needed
353 # Fix up head revision if needed
368 cmd = ['git', 'show', 'HEAD']
354 cmd = ['git', 'show', 'HEAD']
369 try:
355 try:
370 _run_command(cmd)
356 _run_command(cmd)
371 except Exception:
357 except Exception:
372 cmd = ['git', 'symbolic-ref', 'HEAD',
358 cmd = ['git', 'symbolic-ref', 'HEAD',
373 'refs/heads/%s' % push_ref['name']]
359 'refs/heads/%s' % push_ref['name']]
374 print("Setting default branch to %s" % push_ref['name'])
360 print("Setting default branch to %s" % push_ref['name'])
375 _run_command(cmd)
361 _run_command(cmd)
376
362
377 cmd = ['git', 'for-each-ref', '--format=%(refname)',
363 cmd = ['git', 'for-each-ref', '--format=%(refname)',
378 'refs/heads/*']
364 'refs/heads/*']
379 heads = _run_command(cmd)
365 heads = _run_command(cmd)
380 heads = heads.replace(push_ref['ref'], '')
366 heads = heads.replace(push_ref['ref'], '')
381 heads = ' '.join(head for head in heads.splitlines() if head)
367 heads = ' '.join(head for head in heads.splitlines() if head)
382 cmd = ['git', 'log', '--reverse', '--pretty=format:%H',
368 cmd = ['git', 'log', '--reverse', '--pretty=format:%H',
383 '--', push_ref['new_rev'], '--not', heads]
369 '--', push_ref['new_rev'], '--not', heads]
384 git_revs.extend(_run_command(cmd).splitlines())
370 git_revs.extend(_run_command(cmd).splitlines())
385 elif push_ref['new_rev'] == empty_commit_id:
371 elif push_ref['new_rev'] == empty_commit_id:
386 # delete branch case
372 # delete branch case
387 git_revs.append('delete_branch=>%s' % push_ref['name'])
373 git_revs.append('delete_branch=>%s' % push_ref['name'])
388 else:
374 else:
389 cmd = ['git', 'log',
375 cmd = ['git', 'log',
390 '{old_rev}..{new_rev}'.format(**push_ref),
376 '{old_rev}..{new_rev}'.format(**push_ref),
391 '--reverse', '--pretty=format:%H']
377 '--reverse', '--pretty=format:%H']
392 git_revs.extend(_run_command(cmd).splitlines())
378 git_revs.extend(_run_command(cmd).splitlines())
393 elif type_ == 'tags':
379 elif type_ == 'tags':
394 git_revs.append('tag=>%s' % push_ref['name'])
380 git_revs.append('tag=>%s' % push_ref['name'])
395
381
396 extras['commit_ids'] = git_revs
382 extras['commit_ids'] = git_revs
397
383
398 if 'repo_size' in extras['hooks']:
384 if 'repo_size' in extras['hooks']:
399 try:
385 try:
400 _call_hook('repo_size', extras, GitMessageWriter())
386 _call_hook('repo_size', extras, GitMessageWriter())
401 except:
387 except:
402 pass
388 pass
403
389
404 return _call_hook('post_push', extras, GitMessageWriter())
390 return _call_hook('post_push', extras, GitMessageWriter())
@@ -1,30 +1,19 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2017 RodeCode GmbH
2 # Copyright (C) 2014-2017 RodeCode GmbH
3 #
3 #
4 # This program is free software; you can redistribute it and/or modify
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
7 # (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18
19 PYRO_PORT = 9900
20
21 PYRO_GIT = 'git_remote'
22 PYRO_HG = 'hg_remote'
23 PYRO_SVN = 'svn_remote'
24 PYRO_VCSSERVER = 'vcs_server'
25 PYRO_GIT_REMOTE_WSGI = 'git_remote_wsgi'
26 PYRO_HG_REMOTE_WSGI = 'hg_remote_wsgi'
27
28 WIRE_ENCODING = 'UTF-8'
18 WIRE_ENCODING = 'UTF-8'
29
30 GIT_EXECUTABLE = 'git'
19 GIT_EXECUTABLE = 'git'
@@ -1,549 +1,239 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2017 RodeCode GmbH
2 # Copyright (C) 2014-2017 RodeCode GmbH
3 #
3 #
4 # This program is free software; you can redistribute it and/or modify
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
7 # (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18 import contextlib
18 import contextlib
19 import io
19 import io
20 import threading
20 import threading
21 from BaseHTTPServer import BaseHTTPRequestHandler
21 from BaseHTTPServer import BaseHTTPRequestHandler
22 from SocketServer import TCPServer
22 from SocketServer import TCPServer
23
23
24 import mercurial.ui
24 import mercurial.ui
25 import mock
25 import mock
26 import pytest
26 import pytest
27 import simplejson as json
27 import simplejson as json
28
28
29 from vcsserver import hooks
29 from vcsserver import hooks
30
30
31
31
32 class HooksStub(object):
33 """
34 Simulates a Proy4.Proxy object.
35
36 Will always return `result`, no matter which hook has been called on it.
37 """
38
39 def __init__(self, result):
40 self._result = result
41
42 def __call__(self, hooks_uri):
43 return self
44
45 def __enter__(self):
46 return self
47
48 def __exit__(self, exc_type, exc_value, traceback):
49 pass
50
51 def __getattr__(self, name):
52 return mock.Mock(return_value=self._result)
53
54
55 @contextlib.contextmanager
56 def mock_hook_response(
57 status=0, output='', exception=None, exception_args=None):
58 response = {
59 'status': status,
60 'output': output,
61 }
62 if exception:
63 response.update({
64 'exception': exception,
65 'exception_args': exception_args,
66 })
67
68 with mock.patch('Pyro4.Proxy', HooksStub(response)):
69 yield
70
71
72 def get_hg_ui(extras=None):
32 def get_hg_ui(extras=None):
73 """Create a Config object with a valid RC_SCM_DATA entry."""
33 """Create a Config object with a valid RC_SCM_DATA entry."""
74 extras = extras or {}
34 extras = extras or {}
75 required_extras = {
35 required_extras = {
76 'username': '',
36 'username': '',
77 'repository': '',
37 'repository': '',
78 'locked_by': '',
38 'locked_by': '',
79 'scm': '',
39 'scm': '',
80 'make_lock': '',
40 'make_lock': '',
81 'action': '',
41 'action': '',
82 'ip': '',
42 'ip': '',
83 'hooks_uri': 'fake_hooks_uri',
43 'hooks_uri': 'fake_hooks_uri',
84 }
44 }
85 required_extras.update(extras)
45 required_extras.update(extras)
86 hg_ui = mercurial.ui.ui()
46 hg_ui = mercurial.ui.ui()
87 hg_ui.setconfig('rhodecode', 'RC_SCM_DATA', json.dumps(required_extras))
47 hg_ui.setconfig('rhodecode', 'RC_SCM_DATA', json.dumps(required_extras))
88
48
89 return hg_ui
49 return hg_ui
90
50
91
51
92 def test_call_hook_no_error(capsys):
93 extras = {
94 'hooks_uri': 'fake_hook_uri',
95 }
96 expected_output = 'My mock outptut'
97 writer = mock.Mock()
98
99 with mock_hook_response(status=1, output=expected_output):
100 hooks._call_hook('hook_name', extras, writer)
101
102 out, err = capsys.readouterr()
103
104 writer.write.assert_called_with(expected_output)
105 assert err == ''
106
107
108 def test_call_hook_with_exception(capsys):
109 extras = {
110 'hooks_uri': 'fake_hook_uri',
111 }
112 expected_output = 'My mock outptut'
113 writer = mock.Mock()
114
115 with mock_hook_response(status=1, output=expected_output,
116 exception='TypeError',
117 exception_args=('Mock exception', )):
118 with pytest.raises(Exception) as excinfo:
119 hooks._call_hook('hook_name', extras, writer)
120
121 assert excinfo.type == Exception
122 assert 'Mock exception' in str(excinfo.value)
123
124 out, err = capsys.readouterr()
125
126 writer.write.assert_called_with(expected_output)
127 assert err == ''
128
129
130 def test_call_hook_with_locked_exception(capsys):
131 extras = {
132 'hooks_uri': 'fake_hook_uri',
133 }
134 expected_output = 'My mock outptut'
135 writer = mock.Mock()
136
137 with mock_hook_response(status=1, output=expected_output,
138 exception='HTTPLockedRC',
139 exception_args=('message',)):
140 with pytest.raises(Exception) as excinfo:
141 hooks._call_hook('hook_name', extras, writer)
142
143 assert excinfo.value._vcs_kind == 'repo_locked'
144 assert 'message' == str(excinfo.value)
145
146 out, err = capsys.readouterr()
147
148 writer.write.assert_called_with(expected_output)
149 assert err == ''
150
151
152 def test_call_hook_with_stdout():
153 extras = {
154 'hooks_uri': 'fake_hook_uri',
155 }
156 expected_output = 'My mock outptut'
157
158 stdout = io.BytesIO()
159 with mock_hook_response(status=1, output=expected_output):
160 hooks._call_hook('hook_name', extras, stdout)
161
162 assert stdout.getvalue() == expected_output
163
164
165 def test_repo_size():
166 hg_ui = get_hg_ui()
167
168 with mock_hook_response(status=1):
169 assert hooks.repo_size(hg_ui, None) == 1
170
171
172 def test_pre_pull():
173 hg_ui = get_hg_ui()
174
175 with mock_hook_response(status=1):
176 assert hooks.pre_pull(hg_ui, None) == 1
177
178
179 def test_post_pull():
180 hg_ui = get_hg_ui()
181
182 with mock_hook_response(status=1):
183 assert hooks.post_pull(hg_ui, None) == 1
184
185
186 def test_pre_push():
187 hg_ui = get_hg_ui()
188
189 with mock_hook_response(status=1):
190 assert hooks.pre_push(hg_ui, None) == 1
191
192
193 def test_post_push():
194 hg_ui = get_hg_ui()
195
196 with mock_hook_response(status=1):
197 with mock.patch('vcsserver.hooks._rev_range_hash', return_value=[]):
198 assert hooks.post_push(hg_ui, None, None) == 1
199
200
201 def test_git_pre_receive():
202 extras = {
203 'hooks': ['push'],
204 'hooks_uri': 'fake_hook_uri',
205 }
206 with mock_hook_response(status=1):
207 response = hooks.git_pre_receive(None, None,
208 {'RC_SCM_DATA': json.dumps(extras)})
209 assert response == 1
210
211
212 def test_git_pre_receive_is_disabled():
52 def test_git_pre_receive_is_disabled():
213 extras = {'hooks': ['pull']}
53 extras = {'hooks': ['pull']}
214 response = hooks.git_pre_receive(None, None,
54 response = hooks.git_pre_receive(None, None,
215 {'RC_SCM_DATA': json.dumps(extras)})
55 {'RC_SCM_DATA': json.dumps(extras)})
216
56
217 assert response == 0
57 assert response == 0
218
58
219
59
220 def test_git_post_receive_no_subprocess_call():
221 extras = {
222 'hooks': ['push'],
223 'hooks_uri': 'fake_hook_uri',
224 }
225 # Setting revision_lines to '' avoid all subprocess_calls
226 with mock_hook_response(status=1):
227 response = hooks.git_post_receive(None, '',
228 {'RC_SCM_DATA': json.dumps(extras)})
229 assert response == 1
230
231
232 def test_git_post_receive_is_disabled():
60 def test_git_post_receive_is_disabled():
233 extras = {'hooks': ['pull']}
61 extras = {'hooks': ['pull']}
234 response = hooks.git_post_receive(None, '',
62 response = hooks.git_post_receive(None, '',
235 {'RC_SCM_DATA': json.dumps(extras)})
63 {'RC_SCM_DATA': json.dumps(extras)})
236
64
237 assert response == 0
65 assert response == 0
238
66
239
67
240 def test_git_post_receive_calls_repo_size():
68 def test_git_post_receive_calls_repo_size():
241 extras = {'hooks': ['push', 'repo_size']}
69 extras = {'hooks': ['push', 'repo_size']}
242 with mock.patch.object(hooks, '_call_hook') as call_hook_mock:
70 with mock.patch.object(hooks, '_call_hook') as call_hook_mock:
243 hooks.git_post_receive(
71 hooks.git_post_receive(
244 None, '', {'RC_SCM_DATA': json.dumps(extras)})
72 None, '', {'RC_SCM_DATA': json.dumps(extras)})
245 extras.update({'commit_ids': []})
73 extras.update({'commit_ids': []})
246 expected_calls = [
74 expected_calls = [
247 mock.call('repo_size', extras, mock.ANY),
75 mock.call('repo_size', extras, mock.ANY),
248 mock.call('post_push', extras, mock.ANY),
76 mock.call('post_push', extras, mock.ANY),
249 ]
77 ]
250 assert call_hook_mock.call_args_list == expected_calls
78 assert call_hook_mock.call_args_list == expected_calls
251
79
252
80
253 def test_git_post_receive_does_not_call_disabled_repo_size():
81 def test_git_post_receive_does_not_call_disabled_repo_size():
254 extras = {'hooks': ['push']}
82 extras = {'hooks': ['push']}
255 with mock.patch.object(hooks, '_call_hook') as call_hook_mock:
83 with mock.patch.object(hooks, '_call_hook') as call_hook_mock:
256 hooks.git_post_receive(
84 hooks.git_post_receive(
257 None, '', {'RC_SCM_DATA': json.dumps(extras)})
85 None, '', {'RC_SCM_DATA': json.dumps(extras)})
258 extras.update({'commit_ids': []})
86 extras.update({'commit_ids': []})
259 expected_calls = [
87 expected_calls = [
260 mock.call('post_push', extras, mock.ANY)
88 mock.call('post_push', extras, mock.ANY)
261 ]
89 ]
262 assert call_hook_mock.call_args_list == expected_calls
90 assert call_hook_mock.call_args_list == expected_calls
263
91
264
92
265 def test_repo_size_exception_does_not_affect_git_post_receive():
93 def test_repo_size_exception_does_not_affect_git_post_receive():
266 extras = {'hooks': ['push', 'repo_size']}
94 extras = {'hooks': ['push', 'repo_size']}
267 status = 0
95 status = 0
268
96
269 def side_effect(name, *args, **kwargs):
97 def side_effect(name, *args, **kwargs):
270 if name == 'repo_size':
98 if name == 'repo_size':
271 raise Exception('Fake exception')
99 raise Exception('Fake exception')
272 else:
100 else:
273 return status
101 return status
274
102
275 with mock.patch.object(hooks, '_call_hook') as call_hook_mock:
103 with mock.patch.object(hooks, '_call_hook') as call_hook_mock:
276 call_hook_mock.side_effect = side_effect
104 call_hook_mock.side_effect = side_effect
277 result = hooks.git_post_receive(
105 result = hooks.git_post_receive(
278 None, '', {'RC_SCM_DATA': json.dumps(extras)})
106 None, '', {'RC_SCM_DATA': json.dumps(extras)})
279 assert result == status
107 assert result == status
280
108
281
109
282 @mock.patch('vcsserver.hooks._run_command')
283 def test_git_post_receive_first_commit_sub_branch(cmd_mock):
284 def cmd_mock_returns(args):
285 if args == ['git', 'show', 'HEAD']:
286 raise
287 if args == ['git', 'for-each-ref', '--format=%(refname)',
288 'refs/heads/*']:
289 return 'refs/heads/test-branch2/sub-branch'
290 if args == ['git', 'log', '--reverse', '--pretty=format:%H', '--',
291 '9695eef57205c17566a3ae543be187759b310bb7', '--not',
292 'refs/heads/test-branch2/sub-branch']:
293 return ''
294
295 cmd_mock.side_effect = cmd_mock_returns
296
297 extras = {
298 'hooks': ['push'],
299 'hooks_uri': 'fake_hook_uri'
300 }
301 rev_lines = ['0000000000000000000000000000000000000000 '
302 '9695eef57205c17566a3ae543be187759b310bb7 '
303 'refs/heads/feature/sub-branch\n']
304 with mock_hook_response(status=0):
305 response = hooks.git_post_receive(None, rev_lines,
306 {'RC_SCM_DATA': json.dumps(extras)})
307
308 calls = [
309 mock.call(['git', 'show', 'HEAD']),
310 mock.call(['git', 'symbolic-ref', 'HEAD',
311 'refs/heads/feature/sub-branch']),
312 ]
313 cmd_mock.assert_has_calls(calls, any_order=True)
314 assert response == 0
315
316
317 @mock.patch('vcsserver.hooks._run_command')
318 def test_git_post_receive_first_commit_revs(cmd_mock):
319 extras = {
320 'hooks': ['push'],
321 'hooks_uri': 'fake_hook_uri'
322 }
323 rev_lines = [
324 '0000000000000000000000000000000000000000 '
325 '9695eef57205c17566a3ae543be187759b310bb7 refs/heads/master\n']
326 with mock_hook_response(status=0):
327 response = hooks.git_post_receive(
328 None, rev_lines, {'RC_SCM_DATA': json.dumps(extras)})
329
330 calls = [
331 mock.call(['git', 'show', 'HEAD']),
332 mock.call(['git', 'for-each-ref', '--format=%(refname)',
333 'refs/heads/*']),
334 mock.call(['git', 'log', '--reverse', '--pretty=format:%H',
335 '--', '9695eef57205c17566a3ae543be187759b310bb7', '--not',
336 ''])
337 ]
338 cmd_mock.assert_has_calls(calls, any_order=True)
339
340 assert response == 0
341
342
343 def test_git_pre_pull():
344 extras = {
345 'hooks': ['pull'],
346 'hooks_uri': 'fake_hook_uri',
347 }
348 with mock_hook_response(status=1, output='foo'):
349 assert hooks.git_pre_pull(extras) == hooks.HookResponse(1, 'foo')
350
351
352 def test_git_pre_pull_exception_is_caught():
353 extras = {
354 'hooks': ['pull'],
355 'hooks_uri': 'fake_hook_uri',
356 }
357 with mock_hook_response(status=2, exception=Exception('foo')):
358 assert hooks.git_pre_pull(extras).status == 128
359
360
361 def test_git_pre_pull_is_disabled():
110 def test_git_pre_pull_is_disabled():
362 assert hooks.git_pre_pull({'hooks': ['push']}) == hooks.HookResponse(0, '')
111 assert hooks.git_pre_pull({'hooks': ['push']}) == hooks.HookResponse(0, '')
363
112
364
113
365 def test_git_post_pull():
366 extras = {
367 'hooks': ['pull'],
368 'hooks_uri': 'fake_hook_uri',
369 }
370 with mock_hook_response(status=1, output='foo'):
371 assert hooks.git_post_pull(extras) == hooks.HookResponse(1, 'foo')
372
373
374 def test_git_post_pull_exception_is_caught():
375 extras = {
376 'hooks': ['pull'],
377 'hooks_uri': 'fake_hook_uri',
378 }
379 with mock_hook_response(status=2, exception='Exception',
380 exception_args=('foo',)):
381 assert hooks.git_post_pull(extras).status == 128
382
383
384 def test_git_post_pull_is_disabled():
114 def test_git_post_pull_is_disabled():
385 assert (
115 assert (
386 hooks.git_post_pull({'hooks': ['push']}) == hooks.HookResponse(0, ''))
116 hooks.git_post_pull({'hooks': ['push']}) == hooks.HookResponse(0, ''))
387
117
388
118
389 class TestGetHooksClient(object):
119 class TestGetHooksClient(object):
390 def test_returns_pyro_client_when_protocol_matches(self):
391 hooks_uri = 'localhost:8000'
392 result = hooks._get_hooks_client({
393 'hooks_uri': hooks_uri,
394 'hooks_protocol': 'pyro4'
395 })
396 assert isinstance(result, hooks.HooksPyro4Client)
397 assert result.hooks_uri == hooks_uri
398
120
399 def test_returns_http_client_when_protocol_matches(self):
121 def test_returns_http_client_when_protocol_matches(self):
400 hooks_uri = 'localhost:8000'
122 hooks_uri = 'localhost:8000'
401 result = hooks._get_hooks_client({
123 result = hooks._get_hooks_client({
402 'hooks_uri': hooks_uri,
124 'hooks_uri': hooks_uri,
403 'hooks_protocol': 'http'
125 'hooks_protocol': 'http'
404 })
126 })
405 assert isinstance(result, hooks.HooksHttpClient)
127 assert isinstance(result, hooks.HooksHttpClient)
406 assert result.hooks_uri == hooks_uri
128 assert result.hooks_uri == hooks_uri
407
129
408 def test_returns_pyro4_client_when_no_protocol_is_specified(self):
409 hooks_uri = 'localhost:8000'
410 result = hooks._get_hooks_client({
411 'hooks_uri': hooks_uri
412 })
413 assert isinstance(result, hooks.HooksPyro4Client)
414 assert result.hooks_uri == hooks_uri
415
416 def test_returns_dummy_client_when_hooks_uri_not_specified(self):
130 def test_returns_dummy_client_when_hooks_uri_not_specified(self):
417 fake_module = mock.Mock()
131 fake_module = mock.Mock()
418 import_patcher = mock.patch.object(
132 import_patcher = mock.patch.object(
419 hooks.importlib, 'import_module', return_value=fake_module)
133 hooks.importlib, 'import_module', return_value=fake_module)
420 fake_module_name = 'fake.module'
134 fake_module_name = 'fake.module'
421 with import_patcher as import_mock:
135 with import_patcher as import_mock:
422 result = hooks._get_hooks_client(
136 result = hooks._get_hooks_client(
423 {'hooks_module': fake_module_name})
137 {'hooks_module': fake_module_name})
424
138
425 import_mock.assert_called_once_with(fake_module_name)
139 import_mock.assert_called_once_with(fake_module_name)
426 assert isinstance(result, hooks.HooksDummyClient)
140 assert isinstance(result, hooks.HooksDummyClient)
427 assert result._hooks_module == fake_module
141 assert result._hooks_module == fake_module
428
142
429
143
430 class TestHooksHttpClient(object):
144 class TestHooksHttpClient(object):
431 def test_init_sets_hooks_uri(self):
145 def test_init_sets_hooks_uri(self):
432 uri = 'localhost:3000'
146 uri = 'localhost:3000'
433 client = hooks.HooksHttpClient(uri)
147 client = hooks.HooksHttpClient(uri)
434 assert client.hooks_uri == uri
148 assert client.hooks_uri == uri
435
149
436 def test_serialize_returns_json_string(self):
150 def test_serialize_returns_json_string(self):
437 client = hooks.HooksHttpClient('localhost:3000')
151 client = hooks.HooksHttpClient('localhost:3000')
438 hook_name = 'test'
152 hook_name = 'test'
439 extras = {
153 extras = {
440 'first': 1,
154 'first': 1,
441 'second': 'two'
155 'second': 'two'
442 }
156 }
443 result = client._serialize(hook_name, extras)
157 result = client._serialize(hook_name, extras)
444 expected_result = json.dumps({
158 expected_result = json.dumps({
445 'method': hook_name,
159 'method': hook_name,
446 'extras': extras
160 'extras': extras
447 })
161 })
448 assert result == expected_result
162 assert result == expected_result
449
163
450 def test_call_queries_http_server(self, http_mirror):
164 def test_call_queries_http_server(self, http_mirror):
451 client = hooks.HooksHttpClient(http_mirror.uri)
165 client = hooks.HooksHttpClient(http_mirror.uri)
452 hook_name = 'test'
166 hook_name = 'test'
453 extras = {
167 extras = {
454 'first': 1,
168 'first': 1,
455 'second': 'two'
169 'second': 'two'
456 }
170 }
457 result = client(hook_name, extras)
171 result = client(hook_name, extras)
458 expected_result = {
172 expected_result = {
459 'method': hook_name,
173 'method': hook_name,
460 'extras': extras
174 'extras': extras
461 }
175 }
462 assert result == expected_result
176 assert result == expected_result
463
177
464
178
465 class TestHooksDummyClient(object):
179 class TestHooksDummyClient(object):
466 def test_init_imports_hooks_module(self):
180 def test_init_imports_hooks_module(self):
467 hooks_module_name = 'rhodecode.fake.module'
181 hooks_module_name = 'rhodecode.fake.module'
468 hooks_module = mock.MagicMock()
182 hooks_module = mock.MagicMock()
469
183
470 import_patcher = mock.patch.object(
184 import_patcher = mock.patch.object(
471 hooks.importlib, 'import_module', return_value=hooks_module)
185 hooks.importlib, 'import_module', return_value=hooks_module)
472 with import_patcher as import_mock:
186 with import_patcher as import_mock:
473 client = hooks.HooksDummyClient(hooks_module_name)
187 client = hooks.HooksDummyClient(hooks_module_name)
474 import_mock.assert_called_once_with(hooks_module_name)
188 import_mock.assert_called_once_with(hooks_module_name)
475 assert client._hooks_module == hooks_module
189 assert client._hooks_module == hooks_module
476
190
477 def test_call_returns_hook_result(self):
191 def test_call_returns_hook_result(self):
478 hooks_module_name = 'rhodecode.fake.module'
192 hooks_module_name = 'rhodecode.fake.module'
479 hooks_module = mock.MagicMock()
193 hooks_module = mock.MagicMock()
480 import_patcher = mock.patch.object(
194 import_patcher = mock.patch.object(
481 hooks.importlib, 'import_module', return_value=hooks_module)
195 hooks.importlib, 'import_module', return_value=hooks_module)
482 with import_patcher:
196 with import_patcher:
483 client = hooks.HooksDummyClient(hooks_module_name)
197 client = hooks.HooksDummyClient(hooks_module_name)
484
198
485 result = client('post_push', {})
199 result = client('post_push', {})
486 hooks_module.Hooks.assert_called_once_with()
200 hooks_module.Hooks.assert_called_once_with()
487 assert result == hooks_module.Hooks().__enter__().post_push()
201 assert result == hooks_module.Hooks().__enter__().post_push()
488
202
489
203
490 class TestHooksPyro4Client(object):
491 def test_init_sets_hooks_uri(self):
492 uri = 'localhost:3000'
493 client = hooks.HooksPyro4Client(uri)
494 assert client.hooks_uri == uri
495
496 def test_call_returns_hook_value(self):
497 hooks_uri = 'localhost:3000'
498 client = hooks.HooksPyro4Client(hooks_uri)
499 hooks_module = mock.Mock()
500 context_manager = mock.MagicMock()
501 context_manager.__enter__.return_value = hooks_module
502 pyro4_patcher = mock.patch.object(
503 hooks.Pyro4, 'Proxy', return_value=context_manager)
504 extras = {
505 'test': 'test'
506 }
507 with pyro4_patcher as pyro4_mock:
508 result = client('post_push', extras)
509 pyro4_mock.assert_called_once_with(hooks_uri)
510 hooks_module.post_push.assert_called_once_with(extras)
511 assert result == hooks_module.post_push.return_value
512
513
514 @pytest.fixture
204 @pytest.fixture
515 def http_mirror(request):
205 def http_mirror(request):
516 server = MirrorHttpServer()
206 server = MirrorHttpServer()
517 request.addfinalizer(server.stop)
207 request.addfinalizer(server.stop)
518 return server
208 return server
519
209
520
210
521 class MirrorHttpHandler(BaseHTTPRequestHandler):
211 class MirrorHttpHandler(BaseHTTPRequestHandler):
522 def do_POST(self):
212 def do_POST(self):
523 length = int(self.headers['Content-Length'])
213 length = int(self.headers['Content-Length'])
524 body = self.rfile.read(length).decode('utf-8')
214 body = self.rfile.read(length).decode('utf-8')
525 self.send_response(200)
215 self.send_response(200)
526 self.end_headers()
216 self.end_headers()
527 self.wfile.write(body)
217 self.wfile.write(body)
528
218
529
219
530 class MirrorHttpServer(object):
220 class MirrorHttpServer(object):
531 ip_address = '127.0.0.1'
221 ip_address = '127.0.0.1'
532 port = 0
222 port = 0
533
223
534 def __init__(self):
224 def __init__(self):
535 self._daemon = TCPServer((self.ip_address, 0), MirrorHttpHandler)
225 self._daemon = TCPServer((self.ip_address, 0), MirrorHttpHandler)
536 _, self.port = self._daemon.server_address
226 _, self.port = self._daemon.server_address
537 self._thread = threading.Thread(target=self._daemon.serve_forever)
227 self._thread = threading.Thread(target=self._daemon.serve_forever)
538 self._thread.daemon = True
228 self._thread.daemon = True
539 self._thread.start()
229 self._thread.start()
540
230
541 def stop(self):
231 def stop(self):
542 self._daemon.shutdown()
232 self._daemon.shutdown()
543 self._thread.join()
233 self._thread.join()
544 self._daemon = None
234 self._daemon = None
545 self._thread = None
235 self._thread = None
546
236
547 @property
237 @property
548 def uri(self):
238 def uri(self):
549 return '{}:{}'.format(self.ip_address, self.port)
239 return '{}:{}'.format(self.ip_address, self.port)
@@ -1,57 +1,57 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2017 RodeCode GmbH
2 # Copyright (C) 2014-2017 RodeCode GmbH
3 #
3 #
4 # This program is free software; you can redistribute it and/or modify
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
7 # (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18 import mock
18 import mock
19 import pytest
19 import pytest
20
20
21 from vcsserver import main
21 from vcsserver import http_main
22 from vcsserver.base import obfuscate_qs
22 from vcsserver.base import obfuscate_qs
23
23
24
24
25 @mock.patch('vcsserver.main.VcsServerCommand', mock.Mock())
25 @mock.patch('vcsserver.http_main.VCS', mock.Mock())
26 @mock.patch('vcsserver.hgpatches.patch_largefiles_capabilities')
26 @mock.patch('vcsserver.hgpatches.patch_largefiles_capabilities')
27 def test_applies_largefiles_patch(patch_largefiles_capabilities):
27 def test_applies_largefiles_patch(patch_largefiles_capabilities):
28 main.main([])
28 http_main.main([])
29 patch_largefiles_capabilities.assert_called_once_with()
29 patch_largefiles_capabilities.assert_called_once_with()
30
30
31
31
32 @mock.patch('vcsserver.main.VcsServerCommand', mock.Mock())
32 @mock.patch('vcsserver.http_main.VCS', mock.Mock())
33 @mock.patch('vcsserver.main.MercurialFactory', None)
33 @mock.patch('vcsserver.http_main.MercurialFactory', None)
34 @mock.patch(
34 @mock.patch(
35 'vcsserver.hgpatches.patch_largefiles_capabilities',
35 'vcsserver.hgpatches.patch_largefiles_capabilities',
36 mock.Mock(side_effect=Exception("Must not be called")))
36 mock.Mock(side_effect=Exception("Must not be called")))
37 def test_applies_largefiles_patch_only_if_mercurial_is_available():
37 def test_applies_largefiles_patch_only_if_mercurial_is_available():
38 main.main([])
38 http_main.main([])
39
39
40
40
41 @pytest.mark.parametrize('given, expected', [
41 @pytest.mark.parametrize('given, expected', [
42 ('bad', 'bad'),
42 ('bad', 'bad'),
43 ('query&foo=bar', 'query&foo=bar'),
43 ('query&foo=bar', 'query&foo=bar'),
44 ('equery&auth_token=bar', 'equery&auth_token=*****'),
44 ('equery&auth_token=bar', 'equery&auth_token=*****'),
45 ('a;b;c;query&foo=bar&auth_token=secret',
45 ('a;b;c;query&foo=bar&auth_token=secret',
46 'a&b&c&query&foo=bar&auth_token=*****'),
46 'a&b&c&query&foo=bar&auth_token=*****'),
47 ('', ''),
47 ('', ''),
48 (None, None),
48 (None, None),
49 ('foo=bar', 'foo=bar'),
49 ('foo=bar', 'foo=bar'),
50 ('auth_token=secret', 'auth_token=*****'),
50 ('auth_token=secret', 'auth_token=*****'),
51 ('auth_token=secret&api_key=secret2',
51 ('auth_token=secret&api_key=secret2',
52 'auth_token=*****&api_key=*****'),
52 'auth_token=*****&api_key=*****'),
53 ('auth_token=secret&api_key=secret2&param=value',
53 ('auth_token=secret&api_key=secret2&param=value',
54 'auth_token=*****&api_key=*****&param=value'),
54 'auth_token=*****&api_key=*****&param=value'),
55 ])
55 ])
56 def test_obfuscate_qs(given, expected):
56 def test_obfuscate_qs(given, expected):
57 assert expected == obfuscate_qs(given)
57 assert expected == obfuscate_qs(given)
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (508 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now